Skip to content
Open
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
5 changes: 5 additions & 0 deletions .agents/external-skills.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,10 @@
"repo": "twostraws/SwiftData-Agent-Skill",
"path": "swiftdata-pro",
"ref": "922d989473a9914210b41529a1ac5636aff4b8c1"
},
"simple-english": {
"repo": "AminBlg/SimpleEnglish",
"path": "skills/simple-english",
"ref": "379728b51981b6d2ee1de0f201164483a9648972"
}
}
1 change: 1 addition & 0 deletions .agents/skills/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# External skills — fetched via ./sync-agents --install
/simple-english/
/swift-concurrency-pro/
/swift-testing-pro/
/swiftdata-pro/
Expand Down
82 changes: 41 additions & 41 deletions .agents/skills/github-workflow/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,86 +1,86 @@
---
name: github-workflow
description: Opens and maintains pull requests, handles review feedback, checks CI, and posts as the user via gh. Use when committing for push, opening or updating a PR, responding to review comments, or diagnosing CI failures.
description: Open and maintain pull requests. Handle review feedback. Check CI. Post as the user via gh. Use when you commit for push, open or update a PR, respond to review comments, or diagnose CI failures.
---

GitHub workflow for this repo. Read root [`AGENTS.md`](../../../AGENTS.md) first for
always-on commit and test invariants — this skill assumes those.
GitHub workflow for this repo. Read root [`AGENTS.md`](../../../AGENTS.md) first
for always-on commit and test invariants. This skill assumes those rules.

## Prerequisites

- Use the `gh` CLI for all GitHub interaction — PRs, issues, checks, releases,
review comments.
- **`./swiftformat --lint` and `./test` are part of "done".** Never push a red
tree.
- **Never commit on `main`.** Branch first and keep every commit for one piece
of work on that one branch.
- **Never commit on `main`.** Branch first. Keep every commit for one piece of
work on that one branch.

## Branch and push

- **Multi-step work lands one commit per step**, so history stays bisectable and
can land piecewise — including pure-groundwork steps, which say so in the body.
- **Commit when asked, or when working through a plan.** If it's unclear whether
a commit is wanted, make the change and ask rather than committing silently.
- **Multi-step work lands one commit per step.** History stays bisectable and
can land piecewise. Pure-groundwork steps say so in the body.
- **Commit when asked, or when working through a plan.** If it is unclear
whether a commit is wanted, make the change and ask. Do not commit silently.
- Push each commit as it lands once a PR is open.
- **When working through a plan, open a PR once the plan is complete** — push
the branch and open it ready-for-review rather than leaving finished work
- **When working through a plan, open a PR once the plan is complete.** Push
the branch and open it ready-for-review. Do not leave finished work
local-only.

## Opening a PR

- **Open PRs ready-for-review, not draft.**
- Check for a PR template (`.github/PULL_REQUEST_TEMPLATE.md` or similar) and
use it for the body.
- Check for a PR template (`.github/PULL_REQUEST_TEMPLATE.md` or similar). Use
it for the body.
- Describe the **end state**, not a changelog of the conversation.
- **Explain what the diff doesn't show** — motivation, trade-offs, or follow-ups
that aren't obvious from the code alone.
- **Flag lines that warrant extra scrutiny** — leave a PR review comment on
anything a reviewer should look at closely (subtle behavior changes,
- **Explain what the diff does not show** — motivation, trade-offs, or
follow-ups that are not obvious from the code alone.
- **Flag lines that warrant extra scrutiny.** Leave a PR review comment on
anything a reviewer must look at closely (subtle behavior changes,
incomplete migrations, assumptions about `main`).

## Keeping a PR current

- Push each commit as it lands.
- Refresh the title/body once the branch outgrows them — fold into any human
edits rather than overwriting them.
- Refresh the title/body once the branch outgrows them. Fold into any human
edits. Do not overwrite them.

## Merging main and other branches

When bringing `main` or another branch into yours — because CI failed, before
When you bring `main` or another branch into yours — because CI failed, before
a long review, or to pick up a dependency:

- **Resolve git-reported conflicts** — the `<<<<` / `>>>>` markers; don't leave
- **Resolve git-reported conflicts** — the `<<<<` / `>>>>` markers. Do not leave
conflict markers or half-resolved hunks.
- **Check for logical conflicts too** — changes on both sides can compose cleanly
- **Check for logical conflicts too.** Changes on both sides can compose cleanly
in git but still clash in behavior: a renamed symbol your branch still
references, a relocated test helper, an updated signature your call sites don't
match, a new invariant your code violates, duplicate registrations. Re-read
the merged result and run `./test` (at least the affected tier) after merging
— a clean merge is not proof the branch still makes sense.
- **CI merges `main` into the branch before it runs**, so green-locally /
red-on-CI usually means `main` moved rather than that you broke something.
Merge the latest `main` in locally and rebuild before digging further.
references, a relocated test helper, an updated signature your call sites do
not match, a new invariant your code violates, duplicate registrations.
Re-read the merged result. Run `./test` (at least the affected tier) after
merging. A clean merge is not proof the branch still makes sense.
- **CI merges `main` into the branch before it runs.** Green locally and red on
CI usually means `main` moved. It does not mean you broke something. Merge
the latest `main` in locally and rebuild before you dig further.

## Review comments

- **Don't act on review comments the user hasn't pointed you at.** Summarize
what's there and ask which to take on; reading them to write that summary is
- **Do not act on review comments the user has not pointed you at.** Summarize
what is there and ask which to take on. Reading them to write that summary is
expected.
- **One commit per review issue** — each distinct piece of feedback gets its
own commit, unless several items fit together logically or address similar
issues (then one commit for the group is fine). Either way, fixes stay
bisectable and the reply can name the commit that resolved it.
- When a commit resolves one, reply to it naming the commit.
- Anything deliberately not addressed gets filed in the area's
[`TODOs.md`](../../../TODOs.md) — never dropped.
- **One commit per review issue.** Each distinct piece of feedback gets its own
commit, unless several items fit together logically or address similar issues
(then one commit for the group is fine). Either way, fixes stay bisectable
and the reply can name the commit that resolved it.
- When a commit resolves one, reply to it and name the commit.
- If you deliberately do not address something, file it in the area's
[`TODOs.md`](../../../TODOs.md). Never drop it.

## CI

- **Don't block the conversation polling CI.** Report what's running and hand
the turn back; delegate a genuine watch to a background subagent.
- **Do not block the conversation polling CI.** Report what is running and hand
the turn back. Delegate a genuine watch to a background subagent.

## Posting under the user's identity

Anything posted as the user — PR replies, issue comments, review responses —
opens with a line marking it AI-generated, e.g. `> _Posted by an AI agent on
$USER's behalf._`. No exception for short or purely factual comments.
$USER's behalf._` No exception for short or purely factual comments.
64 changes: 37 additions & 27 deletions .agents/skills/running-tests/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,57 @@
---
name: running-tests
description: Runs the test suite via ./test, picks the right tier, and manages the per-checkout simulator. Use when running tests, choosing a test scope, debugging simulator launch failures, or reviewing snapshot diffs.
description: Run tests with ./test. Pick a tier. Manage the per-checkout simulator. Use when you run tests, pick scope, debug simulator failures, or review snapshot diffs.
---

How to run tests in this repo. Read root [`AGENTS.md`](../../../AGENTS.md) for
always-on rules: **use [`./test`](../../../test)** — never hand-roll `tuist test`
or `xcodebuild`; **`./swiftformat --lint` and `./test` are part of "done".**
Canonical flag list: `./test --help`. Rationale for `./test` over alternatives:
header comment in [`test`](../../../test).
always-on rules.

**Use [`./test`](../../../test).** Do not hand-roll `tuist test` or
`xcodebuild`.

**`./swiftformat --lint` and `./test` are part of "done".**

Read `./test --help` for the canonical flag list.

Read the header comment in [`test`](../../../test) for why `./test` replaces
alternatives.

## Pick a tier

Pick the **narrowest tier that covers the change**:
Pick the narrowest tier that covers the change.

| Tier | Command | When |
|------|---------|------|
| Affected | `./test` | Default — bundles touched by your diff against `origin/main` |
| One bundle | `./test WhereCoreTests` | You know exactly what you touched |
| Unit suite | `./test --all` | Change spans modules; before a wide commit |
| Unit suite | `./test --all` | Change spans modules. Run before a wide commit. |
| Image suite | `./test --snapshots` | Triggers below |
| Everything | `./test --everything` | Full revalidation; what CI runs |
| Everything | `./test --everything` | Full revalidation. This is what CI runs. |

Examples:

- Edited `WhereCore` only → `./test` (or `./test WhereCoreTests` if you want to be explicit)
- Edited `WhereCore` + `WhereUI` → `./test` or `./test --all` before committing
- Changed a stylesheet token that renders → `./test --snapshots` (or `./test` if the graph already pulls snapshots in)

Compare against a ref other than `origin/main`: `./test --base REF`.
If you compare against a ref other than `origin/main`, run `./test --base REF`.

## Snapshots

**Opt-in, not part of "done" by default.** Run `./test --snapshots` when the
change touches a **view or its appearance**, a **stylesheet token**, a **string
that renders**, **`SnapshotKit` / `SnapshotKitTesting`**, or a **reference
image**. `./test` with no arguments already includes image bundles when the
dependency graph says they're affected.
dependency graph says they are affected.

- **`--review`** — how each differing reference differs (pixel count, max delta,
changed region); use to tell a broken render from antialiasing drift
changed region). Use this to tell a broken render from antialiasing drift.
- **`--timings`** — where capture time went per phase
- **`--record MODE`** — re-record references: `all`, `failed`, `missing`, or
`never` (default). Fix the view first; re-record only when the render is
correct
`never` (default). Fix the view first. Re-record only when the render is
correct.

Don't parallelize the image suite — see
Do not parallelize the image suite. See
[`Shared/SnapshotKitTesting/AGENTS.md`](../../../Shared/SnapshotKitTesting/AGENTS.md).

## Iterate faster
Expand All @@ -57,30 +64,33 @@ After a green build:
```

`--only` takes a full xcodebuild test identifier — bundle, suite, or
`Bundle/Suite/testName()`. Repeatable for several tests.
`Bundle/Suite/testName()`. Repeat this for several tests.

## When tests fail

- Swift Testing's headline is often contentless ("Issue recorded"); read the
- Swift Testing's headline is often contentless ("Issue recorded"). Read the
**`↳` block** below it for the real reason, path, and snapshot paths.
- Snapshot mismatch → `./test --snapshots --review` on the failing reference.
- Green locally / red on CI → merge latest `main` and re-run before debugging
(see [`github-workflow`](../github-workflow/SKILL.md)).
- If a snapshot mismatches, run `./test --snapshots --review` on the failing
reference.
- If tests are green locally and red on CI, merge latest `main` and re-run
before you debug (see [`github-workflow`](../github-workflow/SKILL.md)).

## Simulator

`./test` resolves a UDID via [`./simulator`](../../../simulator) — don't pass a
device *name* to `simctl` or hand-roll a `-destination`.
`./test` resolves a UDID via [`./simulator`](../../../simulator). Do not pass a
device *name* to `simctl`. Do not hand-roll a `-destination`.

- **First `./simulator` run in a checkout** creates and boots a device — budget
a couple of minutes for the first boot.
- **The first `./simulator` run in a checkout** creates and boots a device.
Budget a couple of minutes for the first boot.
- **Launch failures that look like test failures** (suites that do run are
green):
- `Application failed preflight checks (Busy)`
- `Mach error -308 — server died` / `crashed with signal kill before
establishing connection`
→ wedged or contended device → `./simulator --recreate`, then re-run `./test`.
- Deeper ops (`--list`, `--prune`, `--device` / `--os`): `./simulator --help`.
→ If the device is wedged or contended, run `./simulator --recreate`. Then
re-run `./test`.
- For deeper ops (`--list`, `--prune`, `--device` / `--os`), read
`./simulator --help`.

Raw one-off `xcodebuild` (rare):

Expand All @@ -91,8 +101,8 @@ Raw one-off `xcodebuild` (rare):
## Environment

- **macOS + Xcode required** for `./test`.
- **Linux cloud agents** — `./swiftformat --lint` and `./sync-agents` only; no
simulator or test runs. Full validation matches CI on macOS.
- **Linux cloud agents** — run `./swiftformat --lint` and `./sync-agents` only.
You cannot run the simulator or tests. Full validation matches CI on macOS.

## Full macOS validation (matches CI)

Expand Down
Loading
Loading