diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..95da5ca8 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,38 @@ +# AGENTS.md + +When talking to Shaps, sacrifice grammar for concision. + +## First Reads + +Before code work, read `CONTEXT.md`. It defines project terms, API-shape expectations, availability rules, and release policy. If an ADR exists under `docs/adr/` for the area you touch, read it too. + +## Project Rules + +- This is a SwiftPM library, not an app. +- Main target is `SwiftUIBackports`. +- Preserve Apple SwiftUI API parity for backports: names, overloads, behavior, docs, and availability should match native APIs where practical. +- Prefer `.backport` modifiers for view/transition APIs and `Backport` for pure namespace types. +- Keep UIKit/AppKit bridge details internal/private unless public API parity demands exposure. +- Use `@available` and `#if os(...)` deliberately. Minimum floors are iOS 13, tvOS 13, watchOS 6, macOS 10.15. +- Do not move deprecated APIs casually. Deprecation shims are source-compatibility promises. +- PRs need exactly one release label: `release:major` or `release:minor`. + +## Verification + +- Prefer `swift build` for package-level validation. +- If changing platform-specific bridges, also reason through unsupported platforms and compile gates. +- If adding public API, include header docs matching the style of neighboring files. + +## Agent skills + +### Issue tracker + +Issues and PRDs live in GitHub Issues for `shaps80/SwiftUIBackports`. See `docs/agents/issue-tracker.md`. + +### Triage labels + +Triage labels use the default five-role vocabulary; missing GitHub labels should be created before automated triage. See `docs/agents/triage-labels.md`. + +### Domain docs + +Single-context repo: root `CONTEXT.md` plus optional ADRs under `docs/adr/`. See `docs/agents/domain.md`. diff --git a/CONTEXT.md b/CONTEXT.md new file mode 100644 index 00000000..7e92eaa4 --- /dev/null +++ b/CONTEXT.md @@ -0,0 +1,59 @@ +# SwiftUIBackports Context + +SwiftUIBackports is a Swift Package Manager library that provides SwiftUI API backports for older Apple platform versions. The goal is API familiarity: callers should use names, shape, and behavior that match Apple's SwiftUI APIs wherever practical, while implementations bridge onto older platform primitives. + +## Glossary + +| Term | Meaning | +| --- | --- | +| Backport | A compatibility implementation of a newer SwiftUI API for older supported OS versions. Prefer API parity over novel behavior. | +| `Backport` namespace | The generic namespace type supplied by `SwiftBackports`. This package extends it with SwiftUI APIs. | +| `.backport` | The discovery point for view and transition modifiers, e.g. `view.backport.presentationDetents(...)`. | +| `Backport` | Namespace form used for pure backported types that are not tied to a wrapped view, such as `Backport.PresentationDetent`. | +| API parity | Matching Apple's public API names, overloads, documentation intent, and availability as closely as this package can. | +| Additional API | Functionality that is not an Apple API match. Keep it separate and named clearly so it does not blur API parity. | +| Environment backport | A backported environment value. These usually use a `backport` prefix because environment values cannot always sit naturally under `.backport`. | +| Shared backport | A backport under `Sources/SwiftUIBackports/Shared`, intended for multiple Apple platforms unless guarded otherwise. | +| Platform-specific backport | A backport under a platform folder such as `iOS`, used where behavior depends on UIKit/AppKit or only exists on that platform family. | +| Representable bridge | A `UIViewRepresentable`, `UIViewControllerRepresentable`, `NSViewRepresentable`, or controller/view wrapper used to reach platform APIs behind a SwiftUI surface. | +| Availability fence | `@available` and `#if os(...)` gating that keeps APIs visible on the intended platform/version set and directs users to Apple's native APIs after deprecation. | +| Deprecation shim | A compatibility surface kept only to move users toward a renamed API, a different package, or Apple's native API. | +| Minimum platform floor | Package support floor: iOS 13, tvOS 13, watchOS 6, macOS 10.15. | +| Native API | The official Apple SwiftUI API being mirrored. When a native API is available, deprecation should point users there. | +| Demo project | Separate repository, `SwiftUIBackportsDemo`, used for demonstrations rather than source ownership in this package. | +| Release label | Pull requests must carry exactly one of `release:major` or `release:minor` for release automation. Both labels already exist on GitHub. | + +## Project Shape + +- Package target: `SwiftUIBackports`. +- Main source root: `Sources/SwiftUIBackports`. +- Public namespace entry: `Sources/SwiftUIBackports/Backport.swift`. +- Shared APIs live under `Sources/SwiftUIBackports/Shared`. +- iOS-specific APIs live under `Sources/SwiftUIBackports/iOS`. +- Internal helpers live under `Sources/SwiftUIBackports/Internal`. +- Deprecated/moved surfaces live under `Sources/SwiftUIBackports/Deprecations`. +- Privacy manifest lives at `Sources/SwiftUIBackports/Resources/PrivacyInfo.xcprivacy`. + +## Design Rules + +- Prefer Apple's API spelling and overload shape. Do not invent alternate names for parity APIs. +- Keep compatibility implementation details private unless public API parity requires exposure. +- Use `@available` to communicate native API replacement versions and unsupported platform cases. +- Gate UIKit/AppKit implementation with compile-time checks so non-owning platforms keep compiling. +- Keep old OS behavior graceful. If an underlying platform feature does not exist, preserve the SwiftUI call surface and no-op or degrade only when that matches project precedent. +- Public docs should read like SwiftUI docs. Existing files often mirror Apple documentation for consistency. +- Avoid adding dependencies unless they are necessary for a backport and fit SwiftPM library use. + +## Build And Release + +- Swift tools version: 5.7. +- Swift language mode: Swift 5. +- Dependency: `SwiftBackports` from `https://github.com/shaps80/SwiftBackports`. +- Documentation plugin: `swift-docc-plugin`. +- Release automation requires PRs to have exactly one release label: `release:major` or `release:minor`. +- Merged release-labeled PRs to `main` create and push the next semantic version tag. + +## Open Questions + +- Test strategy is not documented in-repo yet. +- Triage labels beyond `wontfix` are not currently present in GitHub labels. diff --git a/docs/adr/README.md b/docs/adr/README.md new file mode 100644 index 00000000..d17867a1 --- /dev/null +++ b/docs/adr/README.md @@ -0,0 +1,5 @@ +# ADRs + +Architecture Decision Records for project-level decisions. + +Add ADRs here when a decision should constrain future agent or maintainer work. Use short, numbered filenames, for example `0001-keep-backports-under-backport-namespace.md`. diff --git a/docs/agents/domain.md b/docs/agents/domain.md new file mode 100644 index 00000000..11ba804f --- /dev/null +++ b/docs/agents/domain.md @@ -0,0 +1,35 @@ +# Domain Docs + +How engineering skills should consume this repo's domain documentation. + +## Before Exploring, Read These + +- `CONTEXT.md` at the repo root. +- Relevant ADRs under `docs/adr/`, if present. + +If these files do not exist or no ADR matches the task area, proceed silently. + +## File Structure + +This is a single-context repo: + +```text +/ +|-- CONTEXT.md +|-- AGENTS.md +|-- docs/ +| |-- agents/ +| `-- adr/ +`-- Sources/ + `-- SwiftUIBackports/ +``` + +## Use Glossary Vocabulary + +When output names a project concept, use the term as defined in `CONTEXT.md`. Do not drift to synonyms where the glossary has a preferred term. + +If the needed concept is missing from the glossary, note the gap and add it only when the term is stable enough to help future work. + +## Flag ADR Conflicts + +If proposed work contradicts an ADR, surface the conflict explicitly before implementing. diff --git a/docs/agents/issue-tracker.md b/docs/agents/issue-tracker.md new file mode 100644 index 00000000..a10691ca --- /dev/null +++ b/docs/agents/issue-tracker.md @@ -0,0 +1,31 @@ +# Issue Tracker: GitHub + +Issues and PRDs for this repo live as GitHub issues in `shaps80/SwiftUIBackports`. Use the `gh` CLI for operations when connector tools are not already handling GitHub work. + +## Conventions + +- Create an issue: `gh issue create --title "..." --body "..."` +- Read an issue: `gh issue view --comments` +- List issues: `gh issue list --state open --json number,title,body,labels,comments` +- Comment on an issue: `gh issue comment --body "..."` +- Apply or remove labels: `gh issue edit --add-label "..."` / `--remove-label "..."` +- Close an issue: `gh issue close --comment "..."` + +Infer the repo from `git remote -v`; `gh` does this automatically inside the clone. + +## When A Skill Says "Publish To The Issue Tracker" + +Create a GitHub issue. + +## When A Skill Says "Fetch The Relevant Ticket" + +Run `gh issue view --comments`. + +## Release Labels + +Pull requests must have exactly one of: + +- `release:major` +- `release:minor` + +The GitHub Actions release label check fails if neither or both are present. diff --git a/docs/agents/triage-labels.md b/docs/agents/triage-labels.md new file mode 100644 index 00000000..42f5f2fe --- /dev/null +++ b/docs/agents/triage-labels.md @@ -0,0 +1,17 @@ +# Triage Labels + +The skills speak in terms of five canonical triage roles. This file maps those roles to the actual label strings used in this repo's issue tracker. + +| Label in skills | Label in tracker | Meaning | +| --- | --- | --- | +| `needs-triage` | `needs-triage` | Maintainer needs to evaluate this issue. | +| `needs-info` | `needs-info` | Waiting on reporter for more information. | +| `ready-for-agent` | `ready-for-agent` | Fully specified, ready for an AFK agent. | +| `ready-for-human` | `ready-for-human` | Requires human implementation. | +| `wontfix` | `wontfix` | Will not be actioned. | + +When a skill mentions a role, use the corresponding tracker label from this table. + +As of setup, GitHub only has `wontfix` from this table. Create the missing labels before running automated triage that applies them. + +Release labels are separate from triage labels: `release:major` and `release:minor`. diff --git a/skills/swiftui-backports/SKILL.md b/skills/swiftui-backports/SKILL.md new file mode 100644 index 00000000..83c239ad --- /dev/null +++ b/skills/swiftui-backports/SKILL.md @@ -0,0 +1,38 @@ +--- +name: swiftui-backports +description: Find SwiftUIBackports replacements for SwiftUI APIs unavailable on project deployment target. Use for Swift/SwiftUI availability errors, old iOS/tvOS/watchOS/macOS targets, or new SwiftUI APIs in projects that include or may add SwiftUIBackports. +--- + +# SwiftUI Backports + +When SwiftUI API newer than deployment target, check `SwiftUIBackports` before hand-rolling or raising target. + +## Workflow + +1. Confirm availability issue. + - Read diagnostic / `@available`. + - Find deployment target in `Package.swift`, `.xcodeproj/project.pbxproj`, `.xcconfig`, target settings. + +2. Check dep exists. + - `rg -n "SwiftUIBackports|SwiftBackports" Package.swift Package.resolved .` + - Check `.build/checkouts/SwiftUIBackports`, `.swiftpm/checkouts`, `SourcePackages/checkouts`. + - If absent, propose `https://github.com/shaps80/SwiftUIBackports`; do not add unless asked. + +3. Search actual dep source. + - `rg -n "|" ` + - Read matching file. Confirm platform/version gates. + - Do not rely on static API indexes; installed package source is source of truth. + +4. Use normal spelling. + - View modifiers: `.backport.foo(...)` + - Types/views: `Backport.Foo` or `Backport.Foo` + - Environment: `backportFoo` + +5. If no match, say no backport found. Pick other compat path. + +## Example + +```swift +sheetContent + .backport.presentationDetents([.medium, .large]) +```