Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -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<Any>` 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`.
59 changes: 59 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
@@ -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<Any>` | Namespace form used for pure backported types that are not tied to a wrapped view, such as `Backport<Any>.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.
5 changes: 5 additions & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
@@ -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`.
35 changes: 35 additions & 0 deletions docs/agents/domain.md
Original file line number Diff line number Diff line change
@@ -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.
31 changes: 31 additions & 0 deletions docs/agents/issue-tracker.md
Original file line number Diff line number Diff line change
@@ -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 <number> --comments`
- List issues: `gh issue list --state open --json number,title,body,labels,comments`
- Comment on an issue: `gh issue comment <number> --body "..."`
- Apply or remove labels: `gh issue edit <number> --add-label "..."` / `--remove-label "..."`
- Close an issue: `gh issue close <number> --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 <number> --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.
17 changes: 17 additions & 0 deletions docs/agents/triage-labels.md
Original file line number Diff line number Diff line change
@@ -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`.
38 changes: 38 additions & 0 deletions skills/swiftui-backports/SKILL.md
Original file line number Diff line number Diff line change
@@ -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 "<NativeAPI>|<TypeName>" <SwiftUIBackports checkout>`
- 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<Any>.Foo`
- Environment: `backportFoo`

5. If no match, say no backport found. Pick other compat path.

## Example

```swift
sheetContent
.backport.presentationDetents([.medium, .large])
```
Loading