diff --git a/docs-ai/063-agent-workflows/release-plan.md b/docs-ai/063-agent-workflows/release-plan.md index b7d774dd..a4ca4873 100644 --- a/docs-ai/063-agent-workflows/release-plan.md +++ b/docs-ai/063-agent-workflows/release-plan.md @@ -37,11 +37,12 @@ user-facing surface may merge before "their" release and stay dormant. Three rel | S3 wave 1 | Complete | Merged in #721/#723/#725/#728; S3c plan [064.010](../064-agent-completion-signals/010-s3c-plan.md), record [064.011](../064-agent-completion-signals/011-s3c-action.md) | | 065-S0/K1 | Merged | #729; [065.003](../065-bundled-agent-skills/003-k1-bundle-registry.md) | | 065-K2 | Merged | #730; [065.004](../065-bundled-agent-skills/004-k2-skill-installer-cli.md) | -| 065-K3 | In progress | `feat/bundled-skills-k3`; Agent Skills section on Settings › Command Line Tool; closes 065 | +| 065-K3 | In review | PR to fill in; [065.005](../065-bundled-agent-skills/005-k3-settings-agent-skills.md); closes 065 | A2 completes 063's R1 implementation work, and S1/S2/S3 wave 1 are on `main`. The remaining R1 work is 065 bundled skill distribution: S0, K1 (#729), and K2 (#730) are merged; K3, the -Settings section, is in progress and closes 065. +Settings section, is implemented and in review — once it merges, 065 and R1's implementation +work are complete. #### S3 wave 1 PR breakdown @@ -124,6 +125,10 @@ R3+: V2 / S5 rest; delete HANDOFF_RETIRED stubs ## Change log +- 2026-08-28 — 065-K3 implemented on `feat/bundled-skills-k3` and opened for review: the Agent + Skills section on Settings › Agents › Command Line Tool; 065's action log + ([065.001](../065-bundled-agent-skills/001-action.md)) summarizes K1–K3. Record: + [065.005](../065-bundled-agent-skills/005-k3-settings-agent-skills.md). - 2026-08-28 — 065-K2 merged in #730 after four review rounds and a real-environment check. K3 (Agent Skills section on Settings › Command Line Tool) started on `feat/bundled-skills-k3`; it is the last 065 slice and the last open R1 item. diff --git a/docs-ai/065-bundled-agent-skills/000-plan.md b/docs-ai/065-bundled-agent-skills/000-plan.md index 44612884..f0696efd 100644 --- a/docs-ai/065-bundled-agent-skills/000-plan.md +++ b/docs-ai/065-bundled-agent-skills/000-plan.md @@ -2,7 +2,7 @@ | | | | --- | --- | -| **Status** | In progress — S0, K1, and K2 complete (#729, #730 merged); K3 in progress | +| **Status** | Implemented — S0, K1 (#729), K2 (#730), and K3 complete; see [001-action.md](001-action.md) | | **Anchor date** | 2026-08-22 | | **Primary PRs** | #712 (plan); #729 (K1); #730 (K2); K3 to fill in | | **Related** | [063-agent-workflows](../063-agent-workflows/000-plan.md) (D1 `skill:` materialization, D1–D3 new skills), [060-prowl-cli-targeting-and-contract-governance](../060-prowl-cli-targeting-and-contract-governance/000-plan.md) (four-layer CLI rule), [013-prowl-cli](../013-prowl-cli/000-plan.md), `docs/components/cli.md`, `skills/prowl-cli/SKILL.md` | @@ -139,7 +139,7 @@ depends on it); K2 and K3 follow inside R1 so the R1 user can `prowl skills inst | **S0** spike | **Complete** — verified Codex per-directory links and `.codex/skills`, mapped installed `.agents/skills` readers, and confirmed dangling links do not block discovery. Copy mode stays out of K2. See [002-s0-skill-targets.md](002-s0-skill-targets.md). | — | | **K1** | **Complete (#729)** — `embed-skills`, `Resources/skills` folder reference, Foundation-only `ProwlSkills` registry + typed errors and frontmatter parser, CLI bundle resolution, tests. See [003-k1-bundle-registry.md](003-k1-bundle-registry.md). | — | | **K2** | **Complete (#730)** — shared `SymlinkInstaller` extracted from `CLIInstallClient`, declarative targets, `prowl skills list\|install\|uninstall\|path`, contract, schema, `cli.md`, `prowl-cli` skill line, unit + integration tests (temp dirs, `PROWL_SKILLS_DIR`). See [004-k2-skill-installer-cli.md](004-k2-skill-installer-cli.md). | S0, K1 | -| **K3** | Agent Skills section on the Command Line Tool page, `AgentSkillsFeature` + `SkillInstallClient`, reducer tests, `docs/components/settings.md`. | K2 | +| **K3** | **Complete** — `SkillInstallClient`, `AgentSkillsFeature`, and the Agent Skills section on the Command Line Tool page (skill × detected target chips with Install / Remove / Repair / Replace, Reveal, empty states), reducer and client tests over temporary roots, `docs/components/settings.md`. See [005-k3-settings-agent-skills.md](005-k3-settings-agent-skills.md). | K2 | ## Alternatives & decisions @@ -214,6 +214,11 @@ Decisions below were taken in the 2026-08-22 plan review (#712): ## Amendments +- Updated 2026-08-28: Implemented and verified K3: the Command Line Tool page gained the Agent + Skills section over a `SkillInstallClient` dependency and an `AgentSkillsFeature` child; every + action recomputes all chips so aliased targets stay consistent; success is a toast, failure an + alert. 065 is complete — see [005-k3-settings-agent-skills.md](005-k3-settings-agent-skills.md) + and [001-action.md](001-action.md). - Updated 2026-08-27: Implemented and verified K2: one shared symlink installer with a `broken` status now backs both the CLI installer and skill links; `prowl skills` is local-only with the four contract layers; project scope prints its Git-hygiene note once and diff --git a/docs-ai/065-bundled-agent-skills/001-action.md b/docs-ai/065-bundled-agent-skills/001-action.md new file mode 100644 index 00000000..8363217a --- /dev/null +++ b/docs-ai/065-bundled-agent-skills/001-action.md @@ -0,0 +1,70 @@ +# 065 — Bundled Agent Skills: Action Log + +## Timeline + +| Date | Change | Ref | +| --- | --- | --- | +| 2026-08-22 | Plan reviewed and accepted: bundle Prowl's own skills, direct bundle symlinks, skill × target granularity, `prowl skills`, Agent Skills section on the Command Line Tool page. | #712, [000-plan.md](000-plan.md) | +| 2026-08-27 | S0 verified the `claude` / `codex` / `agents` targets against installed runtimes in temporary homes: directory symlinks are followed, dangling links do not block discovery, copy mode stays deferred. | [002-s0-skill-targets.md](002-s0-skill-targets.md) | +| 2026-08-27 | K1 merged: `embed-skills` staging, `Resources/skills` folder reference, Foundation-only `ProwlSkills` registry with the frontmatter parser and `metadata.prowl-install` audience, CLI bundle resolution, typed errors. | #729, [003-k1-bundle-registry.md](003-k1-bundle-registry.md) | +| 2026-08-27 | K2 merged after four review rounds and an owner-authorized real-environment check: shared `SymlinkInstaller` (extracted from `CLIInstallClient`, adds `broken`), declarative `SkillInstallTarget`, `ProwlSkillInstaller`, local-only `prowl skills list\|install\|uninstall\|path` with contract, schema, manual, and skill line; aliased targets handled by re-reading each slot. | #730, [004-k2-skill-installer-cli.md](004-k2-skill-installer-cli.md) | +| 2026-08-28 | K3: `SkillInstallClient`, `AgentSkillsFeature`, and the Agent Skills section on Settings › Agents › Command Line Tool; `settings.md` / `cli.md` updated; 065 complete. | PR to fill in, [005-k3-settings-agent-skills.md](005-k3-settings-agent-skills.md) | + +## Outcome & current state (as of 2026-08-28) + +- **Bundle.** `make build-app` / `test` / `archive` stage `skills/` into `Resources/skills/` + (ignored, `rsync --delete`), which the Xcode project embeds as a folder reference, so the + shipped app carries `Contents/Resources/skills//SKILL.md`. Today the only bundled skill is + `prowl-cli` (`user` audience); 063's D1–D3 skills join by being added to `skills/` with the right + `metadata.prowl-install`. +- **Registry.** `ProwlSkills` (`supacode/CLIService/Shared/ProwlSkills.swift`, part of + `ProwlCLIShared` and compiled into the app) parses `name`, plain or `>-` `description`, and the + strictly nested `metadata.prowl-install` audience; `bundled(resourcesURL:)` serves the app, + `bundledForCLI(executableURL:environment:)` resolves the CLI's own bundle or `PROWL_SKILLS_DIR`, + and `skill(id:)` is the locator 063 uses. +- **Installer.** `SymlinkInstaller` (`SymlinkInstaller.swift`) owns one link slot with the + statuses `notInstalled` / `installed(path:)` / `installedDifferentSource(path:destination:)` / + `broken(path:destination:)`; it replaces live or dangling symlinks, refuses real files and + directories, and removes symlinks only. `CLIInstallClient` delegates to it for + `/usr/local/bin/prowl`. `SkillInstallTarget.all` (`SkillInstallTarget.swift`) declares + `claude`, `codex`, and `agents` with user and project directories and the parent-exists + detection rule; `ProwlSkillInstaller` composes skill × target × scope into a slot and enforces + the project-boundary rule. +- **CLI.** `prowl skills` (`ProwlCLI/Skills/`) is local-only, contract `prowl.cli.skills.v1` + (`docs-ai/013-prowl-cli/contracts/skills.md`, `cli-output-schema.json`, + `docs/components/cli.md`, one line in `skills/prowl-cli/SKILL.md`). +- **Settings.** `SkillInstallClient` (`supacode/Clients/SkillInstall/`), `AgentSkillsFeature` + (`supacode/Features/Settings/Reducer/`), and `AgentSkillsSectionView` (`.../Views/`) add the + Agent Skills section to `CommandLineToolSettingsView`. `AppFeature.setSelection(.commandLineTool)` + creates the child state; every action recomputes all chips; results surface as toasts and + failures as an alert. `docs/components/settings.md` documents the section. +- **Tests.** Registry, installer, target, executor, parser, schema, and integration tests under + `ProwlCLITests/` (temporary roots, `PROWL_SKILLS_DIR`, temporary `HOME`); `CLIInstallClientTests`, + `SkillInstallClientTests`, `AgentSkillsFeatureTests`, `AppFeatureSettingsSelectionTests`, and + `AppFeatureAgentSkillsTests` under `supacodeTests/` (temporary bundle and home via + `SkillInstallFixture`). No test reads or writes `~/.claude`, `~/.codex`, or `~/.agents`. + +## Deviations from plan + +- `SkillInstallTarget` has no `runtimes` field and `projectDirectory` is not optional: the + reader labels for `agents` live in the contract and manual rather than in code, and all three + targets have a project directory. +- `installedDifferentSource` and `broken` carry a `destination` (added in K2's review round 2) + so the CLI and Settings can name the other build or the vanished location. +- The CLI re-reads each slot immediately before acting on it (K2 real-environment fix for + aliased `~/.claude/skills` / `~/.codex/skills`), and Settings recomputes every chip after each + action for the same reason; neither was in the plan. +- Project scope follows repository-controlled symlinks only inside the repository + (`INSTALL_CONFLICT` otherwise), an explicit `--path` resolves to its Git root, and a bare + `install` with no detected target fails with `TARGET_NOT_FOUND` — all K2 review additions. +- Settings reports a successful link with a toast only (the chip changes state); the plan's + "mirroring the CLI install row" did not decide this, and a modal per link would be noise. +- The section shows detected targets only, as planned, but the "no target detected" state adds an + explicit pointer to `prowl skills install --target …` since Settings never creates folders. + +## Open questions + +- Copy mode (`--copy`) remains deferred until a supported runtime demonstrably refuses directory + symlinks. +- Whether 063-D1's Workflows "ask your agent" prompt should run `prowl skills install` first. +- Settings UI for project scope (per-repository section) — V2 if asked. diff --git a/docs-ai/065-bundled-agent-skills/005-k3-settings-agent-skills.md b/docs-ai/065-bundled-agent-skills/005-k3-settings-agent-skills.md new file mode 100644 index 00000000..8c144b4b --- /dev/null +++ b/docs-ai/065-bundled-agent-skills/005-k3-settings-agent-skills.md @@ -0,0 +1,94 @@ +# 065.005 — Agent Skills Section on the Command Line Tool Page (K3) + +## Context + +K2 (#730) gave the `prowl` CLI status, install, and uninstall for every bundled skill × target +link, but a user who never opens a terminal still had no way to see that Prowl ships skills or +to link them. K3 is the last 065 slice: the Settings › Agents › Command Line Tool page gains an +**Agent Skills** section that exposes exactly the CLI's user-scope actions, backed by the same +shared installer so both surfaces always report the same status. + +## Change + +- `SkillInstallClient` (`supacode/Clients/SkillInstall/`) is the TCA dependency over the shared + installer, shaped like `CLIInstallClient`: `bundledSkills()`, `status(skill, target)`, + `install(skill, target)`, `uninstall(skill, target)`, `revealSkill(skill)`. `liveValue` reads + `Bundle.main.resourceURL` and the user's home; `live(resourcesURL:userRoot:)` builds the same + client over any roots so tests run against a temporary bundle and home, and `testValue` is an + inert stub. `SymlinkInstallError` maps to `SkillInstallError.message` the way `CLIInstallError` + does: a real file or directory is reported as occupying the slot and never deleted. +- `AgentSkillsFeature` (`supacode/Features/Settings/Reducer/`) is a child of `SettingsFeature` + (`agentSkills: State?`), created by `AppFeature.setSelection(.commandLineTool)` and cleared + on every other section, exactly like `agentProfiles` for `.profiles`. `.task` loads the + `user`-audience skills and one `SkillLink` per **detected** target (`SkillTargetStatus.detected`); + `installLink` covers Install, Repair, and Replace (all replace the slot with a link to this + bundle), `removeLink` removes a symlink only, `revealSkillButtonTapped` opens the bundled + folder in Finder. Every completion — success or failure — recomputes all rows and chips, because + aliased targets (`~/.claude/skills` and `~/.codex/skills` symlinked to one folder) share one + physical link. A failure sets an "Agent Skills Error" alert on the child and delegates a + warning toast; a success delegates a success toast (`AppFeature` maps + `agentSkills(.delegate(.linkChanged))` to `repositories.showToast`). +- `AgentSkillsSectionView` renders under Installation and Connection: one row per skill (name, + id when it differs, description limited to three lines with the full text as a tooltip, + Reveal), and one chip per detected target with the status wording of `prowl skills list` + (Installed / Not installed / Linked elsewhere `→ destination` / Real file or directory / Broken + link `→ destination`) and one action button (Remove / Install / Replace / — / Repair). A real + file or directory shows only "Prowl never deletes it; remove it manually to link here." Empty + states: the bundle could not be read (message from `ProwlSkillsError`), no installable skills, + and no detected target (points at `prowl skills install --target claude|codex|agents`). Every + button carries a tooltip; chips show their link path on hover. +- Docs: `docs/components/settings.md` gains an Agent Skills section (statuses, actions, aliased + targets, empty states) and `docs/components/cli.md` notes that Settings offers the same + user-scope actions with the same status as `prowl skills list`. + +## Decisions and boundaries + +- Success feedback is a toast plus the chip's own state change; only failures raise a modal + alert. The CLI-install row alerts on success as well, but a per-link modal for up to three + chips per skill would be noise, and the toast path is the same `AppFeature` mechanism. +- Detection and status come from the client's `SkillTargetStatus`, so the reducer never reads + the home directory itself and undetected targets are simply absent (the CLI's `--target` + creates them). Workflow-audience skills are filtered in the reducer, not the client, because + the audience rule belongs to this surface. +- Load and status refresh are synchronous in the reducer (a handful of `lstat` calls plus one + frontmatter parse), matching the CLI-install row's synchronous `installationStatus`; only + install/uninstall run as effects. +- Not in K3: project scope, copy mode, third-party skills, auto-linking after updates, new + targets, changes to the shared installer or the CLI contract. `ProwlCLIShared` is untouched. + +## Verification + +- TDD RED: 25 missing-symbol errors for `SkillInstallClientTests` before the client existed; + 21 for the `AppFeature` selection and toast tests before the wiring existed. GREEN: 11 client + tests (all four statuses, foreign-link destination, install/replace/repair, conflict refused + with the directory intact, uninstall of links only, aliased targets) and 10 `TestStore` tests + (`user`-only rows, detected-only chips, install/remove/repair/replace transitions with full + refresh, aliased refresh, conflict alert, bundle missing, reveal, unknown ids ignored), all + over temporary roots; the `AppFeature` selection tests cover `agentSkills` creation and + clearing and the toast mapping. +- `make check` passed (strict swift-format, SwiftLint, 44 script tests); `make build-app` + passed with zero warnings and the Debug app bundles `Contents/Resources/skills/prowl-cli/SKILL.md` + identical to the source; `make build-cli`, `make test-cli-unit` (129) and + `make test-cli-integration` (102) passed unchanged. +- `make test`: 2,643 main app tests passed; one deferred-Ghostty-surface test + (`WorktreeTerminalStateAgentProfileTests/deferredProfileAppliesFontSizeAdjustmentAfterSurfaceCreation`) + failed with `.surfaceCreationFailed` while the display was asleep (`pmset -g log`) and passed + when re-run with the display awake; the suite was re-run under `caffeinate` (see the PR for + the final count). +- Visual: a copy of the Debug app launched with `CFFIXED_USER_HOME` (Foundation ignores a bare + `HOME` override) and a dedicated `PROWL_CLI_SOCKET`, so its settings, home, and skill folders + lived in a temporary directory. Screenshots of Settings › Agents › Command Line Tool show the + section in every state: Not installed × 2 with `codex` undetected; Installed / Real file or + directory / Broken link `→ /Volumes/Old/…` with Remove / no button / Repair; Linked elsewhere + `→ …/DerivedData/…` with Replace; aliased `claude` + `codex` both Installed from one link; and + the no-target explanation. The Mac was locked during the run, so button clicks could not be + delivered to the isolated instance; the action path is covered by the `TestStore` tests over + the live client. The live `~/.claude/skills`, `~/.codex/skills`, and `~/.agents` were neither + read as inputs nor modified. + +## Refs + +- Slice: 065-K3 +- Branch: `feat/bundled-skills-k3` +- PR: to fill in +- Depends on: [004-k2-skill-installer-cli.md](004-k2-skill-installer-cli.md)