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
54 changes: 30 additions & 24 deletions .claude/skills/implement-feature/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ Implement features using architecture-first design, TDD, rich domain models, and
• Register the route in RESTRoutes.swift
• Verify _links is populated for the parent resource

4. FEATURE DOC
• Write docs/features/<feature>.md from the actual implementation
4. DOCS
• docs/features/<feature>/README.md (user-facing, ≤200 lines), one CHANGELOG line, make docs
```

## Phase 0: Architecture Design (MANDATORY)
Expand Down Expand Up @@ -335,26 +335,32 @@ Per CLAUDE.md, **a feature is not complete until it is reachable via REST.** Ste
}
```

6. Add a REST test in `Tests/ASCCommandTests/Commands/Web/RESTRoutesTests.swift` that calls `execute(repo:affordanceMode: .rest)` and asserts `_links` + the resolved REST path.
6. **Advertise the resource** from `APIRoot.structuredAffordances` (`Sources/Domain/Shared/APIRoot.swift`) when it is a new top-level resource, so `GET /api/v1` lists it.

7. **Smoke-test the live server.** Build (`swift build`), restart (`asc web-server`), and `curl` the parent resource — confirm `_links` for each item points at the new endpoint.
7. Add a REST test in `Tests/ASCCommandTests/Commands/Web/RESTRoutesTests.swift` that calls `execute(repo:affordanceMode: .rest)` and asserts `_links` + the resolved REST path.

### Phase 5: Feature doc
8. **Smoke-test the live server.** Build (`swift build`), restart (`asc web-server`), and `curl` the parent resource — confirm `_links` for each item points at the new endpoint.

Write `docs/features/<feature>.md` from the actual implementation. The doc is derived from code — read the files, then write. Never write from memory.
**REST rules:**
- CLI flag and REST query-param names match: `--expired-only` ↔ `?expired-only=true`, both calling the same repository method.
- Helpers in `RESTRoutes.swift`: `restFormat(items)` (REST twin of `formatAgentItems(…, affordanceMode: .rest)`) and `jsonError(message, status:)` (from `Infrastructure/Web/ASCWebServer.swift`).
- `RESTPathResolver` maps affordance actions to HTTP: `list`/`get` → GET, `create`/`add` → POST to the parent's collection, `update` → PATCH, `delete`/`remove` → DELETE, anything else (e.g. `submit`) → POST `…/{id}/{action}`.
- Controllers are structs with dependencies injected at init; repositories are constructed once in `RESTRoutes.configure`, never per request.

Structure:
1. **CLI Usage** — one section per command, with flags table + examples + table-output sample
2. **REST Endpoints** — path table + query-param mapping + curl example
3. **Typical Workflow** — end-to-end bash script showing the happy path
4. **Architecture** — three-layer ASCII diagram + dependency note
5. **Domain Models** — every public struct/enum/protocol with fields, computed properties, and affordances
6. **File Map** — `Sources/` and `Tests/` trees + wiring files table (must list the REST controller)
7. **API Reference** — endpoint → SDK call → repository method table
8. **Testing** — one representative test snippet + `swift test` command
9. **Extending** — natural next steps with stub code
### Phase 5: Docs

Use `docs/features/screenshots.md` as the canonical reference example.
Docs follow `docs/documentation-design/README.md`: each fact has one home, and nothing repeats `--help` or the source.

1. **`docs/features/<feature>/README.md`** — user-facing, ≤200 lines, written from the actual implementation (read the code, never write from memory):
- frontmatter `description:` — one sentence, what + "Use when …", ≤250 chars (it becomes the docs index row)
- Quick start → Workflows → REST (paths + query-param mapping) → Gotchas → See also
- **No** flag tables (`docs/commands.md` is generated), architecture, domain model listings, file maps or test snippets. Non-obvious reasons (Apple caps, multi-call workarounds) go in Gotchas as one-liners.
- A topic that doesn't fit goes into `docs/features/<feature>/<topic>.md` next to the README.
- Example: `docs/features/testflight/README.md`.
2. **`CHANGELOG.md`** — one bullet under `[Unreleased]`, ≤300 chars: starts with what the user types, says the effect (not the implementation), ends with `→ [docs](docs/features/<feature>/README.md)` and the PR link. Implementation detail goes in the PR.
3. **`make docs`** — regenerates `docs/commands.md` and the `docs/README.md` index. Never edit those by hand.
4. **README.md** — only if the feature is a new row in its "What It Covers" table.
5. `make check-docs` — no broken links, within budgets.

---

Expand Down Expand Up @@ -415,14 +421,14 @@ Use `docs/features/screenshots.md` as the canonical reference example.
### Phase 4: REST exposure
- [ ] Controller added under `Sources/ASCCommand/Commands/Web/Controllers/`
- [ ] Wired in `Sources/ASCCommand/Commands/Web/RESTRoutes.swift`
- [ ] New top-level resource advertised in `APIRoot.structuredAffordances`
- [ ] REST query-param names match the CLI flags
- [ ] REST test in `RESTRoutesTests.swift` — calls `execute(repo:affordanceMode: .rest)`, asserts `"_links"` + resolved path
- [ ] **Smoke-tested live server** — restarted and curl'd the parent resource; `_links` confirms the new endpoint URL

### Phase 5: Feature Doc
- [ ] `docs/features/<feature>.md` written from actual code (read files first)
- [ ] CLI commands documented with flags table + examples
- [ ] **REST Endpoints section** with path table + query-param mapping + curl example
- [ ] Domain models section matches actual struct fields
- [ ] File map reflects actual directory structure (must list REST controller)
- [ ] API reference table complete
### Phase 5: Docs
- [ ] `docs/features/<feature>/README.md` with `description`, written from actual code, ≤200 lines
- [ ] **REST section** with path table + query-param mapping
- [ ] No flag tables, architecture, domain listings or file maps
- [ ] `make docs` run; `make check-docs` clean for the new files
- [ ] CHANGELOG.md entry under `[Unreleased]`
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- [Command Tree](#command-tree)
- [Agent-First Output Flow](#agent-first-output-flow)
- [Component Tables](#component-tables)
- [Files Checklist](#files-checklist)
- [Files to Create/Modify](#files-to-createmodify)

---

Expand Down
8 changes: 4 additions & 4 deletions .claude/skills/improvement/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ Make improvements to existing functionality using TDD and rich domain design.
┌─────────────────────────────────────────────────────────────┐
│ 4. UPDATE FEATURE DOC (if public surface changed) │
├─────────────────────────────────────────────────────────────┤
│ • Update docs/features/<feature>.md to match new behavior │
│ • Only required when CLI flags, domain model fields, │
│ affordances, or architecture changed │
│ • Update docs/features/<feature>/README.md if usage, │
│ REST, or gotchas changed (flags: just run `make docs`) │
│ • One CHANGELOG line under [Unreleased] │
│ • Derive from code — read files, then write │
└─────────────────────────────────────────────────────────────┘
```
Expand Down Expand Up @@ -191,4 +191,4 @@ swift test # Must remain all green
- [ ] Improvement implemented
- [ ] New test PASSES
- [ ] All existing tests still pass (`swift test`)
- [ ] `docs/features/<feature>.md` updated if CLI flags, domain model fields, affordances, or architecture changed
- [ ] `docs/features/<feature>/README.md` updated if usage, REST or gotchas changed; `make docs` if flags changed; one CHANGELOG line
19 changes: 19 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ env:
SWIFT_VERSION: "6.2"

jobs:
docs:
name: Docs
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Check links, budgets and changelog
run: python3 scripts/check-docs.py --strict

- name: Changelog release scripts
run: scripts/test-changelog-release.sh

test:
name: Build & Test
runs-on: macos-15
Expand All @@ -30,6 +43,12 @@ jobs:
- name: Build
run: swift build -c release

- name: Generated docs are up to date
run: |
python3 scripts/gen-docs.py .build/release/asc
git diff --exit-code docs/commands.md docs/README.md \
|| { echo "::error::Run 'make docs' and commit docs/commands.md and docs/README.md"; exit 1; }

- name: Test with coverage
run: swift test --enable-code-coverage

Expand Down
19 changes: 1 addition & 18 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,26 +97,9 @@ jobs:
run: |
VERSION="${{ steps.version.outputs.version }}"
./scripts/promote-changelog.sh "$VERSION" "$(date +%Y-%m-%d)"
# Sync fallback release notes into the newly promoted [VERSION] section
if [ "${{ steps.changelog.outputs.used_fallback }}" = "true" ]; then
awk -v ver="$VERSION" '
$0 ~ ("^## \\[" ver "\\] - ") { in_ver=1; print; next }
in_ver && /[^[:space:]]/ && !/^---$/ { has_content=1 }
in_ver && /^---$/ {
if (!has_content) {
print "### Changed"
print "- Bug fixes and improvements."
print ""
}
in_ver=0
}
in_ver && /^## \[/ { in_ver=0 }
{ print }
' CHANGELOG.md > CHANGELOG.tmp && mv CHANGELOG.tmp CHANGELOG.md
fi
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add CHANGELOG.md
git add CHANGELOG.md docs/changelog
git diff --cached --quiet \
&& echo "No CHANGELOG changes to commit" \
|| git commit -m "chore(changelog): promote [Unreleased] to v${{ steps.version.outputs.version }}"
Expand Down
Loading
Loading