diff --git a/docs-ai/063-agent-workflows/release-plan.md b/docs-ai/063-agent-workflows/release-plan.md index 35bd4f46..6a7b7071 100644 --- a/docs-ai/063-agent-workflows/release-plan.md +++ b/docs-ai/063-agent-workflows/release-plan.md @@ -30,6 +30,9 @@ user-facing surface may merge before "their" release and stay dormant. Three rel | --- | --- | --- | --- | --- | | 1 | **C0** Settings IA: `Section("Agents")` with Profiles (renamed) + Command Line Tool (from Advanced); no Workflows page yet | 063 | — | CLI install lives with Agents | | 1 | **A1** `prowl create pane` (#699) + anchored split primitive | 063 | 060 | CLI can split | +| 1 | **065-S0/K1** skill-target spike; `embed-skills` + `ProwlSkills` registry | 065 | — | skills ship in the bundle; D1 prerequisite | +| 2 | **065-K2** shared `SymlinkInstaller` + `prowl skills list\|install\|uninstall\|path` | 065 | 065-K1 | one command installs Prowl's skills into agent skill folders | +| 3 | **065-K3** Agent Skills section on Settings › Command Line Tool | 065 | 065-K2 | GUI users install skills without a terminal | | 2 | **A2** profile launch boundary + `create tab\|pane --profile

--prompt -` + `profiles list` | 063 | A1 | CLI launches a profile with a kickoff prompt and gets the pane back | | 2 | **S1** signal bus + `ObservedAgentState` multicast observer + `prowl agents signal` | 064 | — | layer-0 signals for every runtime | | 3 | **S2** `prowl agents wait` (`source`/`confidence`, `--include-screen`) + `agents` `signals` field + skill rubric | 064 | S1 | no hand-written polling; heuristic results are labelled | @@ -37,7 +40,7 @@ user-facing surface may merge before "their" release and stay dormant. Three rel User-visible result: onevcat's daily CLI-driven orchestration is first-class (`create pane --profile --prompt -` → `agents wait` → `send`). Docs: `docs/components/cli.md`, -`agent-detection.md`, `settings.md`, `prowl-cli` skill. Parallelism: C0 ∥ A1, A2 ∥ S1. +`agent-detection.md`, `settings.md`, `prowl-cli` skill. Parallelism: C0 ∥ A1 ∥ 065-K1, A2 ∥ S1. ### R2 — Agent Workflows diff --git a/docs-ai/065-bundled-agent-skills/000-plan.md b/docs-ai/065-bundled-agent-skills/000-plan.md index 2ba9e69f..00318dac 100644 --- a/docs-ai/065-bundled-agent-skills/000-plan.md +++ b/docs-ai/065-bundled-agent-skills/000-plan.md @@ -31,15 +31,17 @@ user onboarding, not agent enablement; this entry is the missing piece. 2. **`prowl skills`** — list, install, uninstall, path — links bundled skills into agent skill folders (user scope: `~/.claude/skills`, `~/.codex/skills`, `~/.agents/skills`; project scope: the matching folders under a repository root) so updates propagate automatically. -3. **Settings › Agents › Skills** — per-skill rows with per-target install status and - Install/Remove actions, mirroring the Command Line Tool install row (same tri-state idea). +3. **Settings › Agents › Command Line Tool › Agent Skills** — a section on the existing + page listing the user-facing skills with per-target install status and Install/Remove + actions, mirroring the CLI install row above it. 4. **One locator** (`ProwlSkills`) for 063: `skill(id:)` resolves to the bundled directory so workflows and kickoff prompts can reference skills without any install step. **Non-goals (V1):** managing third-party or user-authored skills (this is Prowl's own skills -only, not a general skills manager); copy mode (symlink only — see open questions); silently -installing into an agent without a user action; editing skills in-app; Settings UI for -project scope (CLI only in V1). +only, not a general skills manager); copy mode (symlink only — see open questions); writing +into an agent's skill folder without an explicit user action (no auto-linking of new skills +after an update); editing skills in-app; Settings UI for project scope (CLI only in V1); +touching git state in the user's repositories. ## Design / Approach @@ -49,9 +51,12 @@ project scope (CLI only in V1). exactly like `Resources/docs`. Text resources only — signing/notarization unchanged. **Registry (`ProwlSkills`, in `ProwlCLIShared` = `supacode/CLIService/Shared`).** -`BundledSkill { id (directory name), name, description, directoryURL }` parsed from -`SKILL.md` frontmatter (a minimal YAML subset: `name:`, `description:` including the `>-` -folded block `prowl-cli` already uses — no YAML dependency). `bundled(resourcesURL:)` lists +`BundledSkill { id (directory name), name, description, audience, directoryURL }` parsed +from `SKILL.md` frontmatter — a minimal YAML subset (`name:`, `description:` including the +`>-` folded block `prowl-cli` already uses, and a `metadata:` map), no YAML dependency. +`audience` comes from `metadata.prowl-install`: `user` (default when absent — installable +into agent skill folders) or `workflow` (063-D2/D3 role skills: materialized into a run +directory by the runner, never offered for global install). `bundled(resourcesURL:)` lists skills; the app passes `Bundle.main.resourceURL`, the CLI resolves its own executable (`/usr/local/bin/prowl` → symlink → `Prowl.app/Contents/Resources/prowl-cli/prowl`, so `../skills` is a sibling); `PROWL_SKILLS_DIR` overrides for SwiftPM dev builds and tests. @@ -59,80 +64,113 @@ Not run from a bundle and no override → `BUNDLE_NOT_FOUND`. **Install targets (declarative, verified per runtime).** `SkillInstallTarget { id, displayName, userDirectory, projectDirectory?, runtimes }`. V1 table — entries marked -*verify* are confirmed (dir, symlink following) by spike S0 before K2 builds on them: +*verify* are confirmed (directory, symlink following) by spike S0 before K2 builds on them: | Target id | User dir | Project dir | Read by | | --- | --- | --- | --- | -| `claude` | `~/.claude/skills` | `.claude/skills` | Claude Code | -| `codex` | `~/.codex/skills` | *verify* | Codex | +| `claude` | `~/.claude/skills` | `.claude/skills` | Claude Code (follows symlinked skill directories — this repo's `.claude/skills/prowl-cli` link loads) | +| `codex` | `~/.codex/skills` | *verify* | Codex (follows a symlinked skills root; per-directory symlink *verify*) | | `agents` | `~/.agents/skills` | `.agents/skills` | cross-agent convention (agentskills.io); *verify* which installed runtimes honour it | Other `AgentProfileRuntime` cases (gemini, copilot, cursor, opencode, amp, droid, …) join the table as their skill directories are verified; unknown ones stay out rather than guessed. A user target counts as *detected* when its parent (`~/.claude`, `~/.codex`, `~/.agents`) -exists; undetected targets are listed but never chosen by default. - -**Install semantics.** `install` = `ln -s /skills/ /` (directory -symlink; creates `` if missing). Status mirrors `CLIInstallClient`: +exists; undetected targets are listed but never chosen by default, and an explicit +`--target` creates the directory. + +**Install semantics (decided 2026-08-22, see Alternatives).** The link points straight at +the bundle: `ln -s /Contents/Resources/skills/ /` (directory +symlink; creates `` if missing). The symlink install/verify logic is extracted +from `CLIInstallClient` (`supacode/Clients/CLIInstall/CLIInstallClient.swift`) into a shared +`SymlinkInstaller` used by both the CLI install and skills, with one status enum: `notInstalled` / `installed(path)` (symlink → this bundle) / `installedDifferentSource(path)` -(symlink elsewhere — e.g. a Debug build in DerivedData — or a real directory) / `broken(path)` -(dangling symlink: the app moved or was removed; offer Repair). `uninstall` refuses anything -that is not a symlink we recognise, like the CLI uninstall does. No admin rights needed. -Project scope: `--scope project` with `--path ` or the cwd's git root; the CLI prints a -note that a committed symlink carries a machine-specific absolute path (git hygiene is the -user's call — see open questions). +(symlink elsewhere — e.g. a Debug build in DerivedData — or a real directory) / +`broken(path)` (dangling symlink: the app moved or was removed). Conflict rules mirror the +CLI: an existing symlink is replaced (this doubles as Repair for `broken`), a real +file/directory is refused (`INSTALL_CONFLICT`); `uninstall` removes only symlinks. No admin +rights needed. Granularity is skill × target: every link is one explicit action, in the CLI +and in Settings; a skill added by an app update simply shows as Not installed. +Project scope: `--scope project` with `--path ` or the cwd's git root; the CLI prints +one note that the link carries a machine-specific absolute path and that `.git/info/exclude` +is the user's call — Prowl never edits git state. **CLI (per 060's four-layer rule: parser → contract → `docs/components/cli.md` → skill).** ``` -prowl skills list [--json] # skills × targets with status -prowl skills install ... | --all [--target ]... [--scope user|project] [--path

] -prowl skills uninstall ... | --all [--target ]... [--scope user|project] [--path ] -prowl skills path # bundled directory, for scripts and workflows +prowl skills list [--json] # skills × targets with status; workflow-audience skills tagged +prowl skills install [...] [--target ]... [--scope user|project] [--path ] +prowl skills uninstall [...] [--target ]... [--scope user|project] [--path ] +prowl skills path # bundled directory, for scripts and workflows (any audience) ``` -Plural `skills` matches `agents` and the planned `profiles`. `install` without `--target` -uses all detected user targets; without `--scope` uses `user`. Local-only: never opens the -socket or launches the app (the app need not be running). JSON `schema_version` -`prowl.cli.skills.v1`; errors `SKILL_NOT_FOUND`, `TARGET_NOT_FOUND`, `INSTALL_CONFLICT` -(non-symlink exists), `BUNDLE_NOT_FOUND`. Contract file -`docs-ai/013-prowl-cli/contracts/skills.md`; `prowl-cli` skill gains one line telling an -agent that `prowl skills install prowl-cli` keeps it current. - -**Settings.** `SettingsSection.skills` and `SkillsSettingsView` under the Agents group -(order: Profiles, Skills, Command Line Tool; 063-D1 inserts Workflows after Profiles). -`SkillsFeature` (TCA) owns `skills`, `targets`, `statuses[skill][target]`, `alert`; -`SkillInstallClient` dependency wraps the shared installer (`bundledSkills`, `targets`, -`status`, `install`, `uninstall`) with a temp-directory test value. Rows: name + description, -one status chip per detected target with Install/Remove (Repair for `broken`), Reveal bundled -skill in Finder, Copy path. `AppFeature.setSelection(.skills)` initialises/clears the state -like `.profiles`. The Command Line Tool page stays CLI-only. +Plural `skills` matches `agents` and the planned `profiles`. `install` without skills = every +`user`-audience skill; without `--target` = all detected user targets; without `--scope` = +`user`. Naming a `workflow`-audience skill in `install` is an error. Local-only: never opens +the socket or launches the app. JSON `schema_version` `prowl.cli.skills.v1`; errors +`SKILL_NOT_FOUND`, `SKILL_NOT_INSTALLABLE`, `TARGET_NOT_FOUND`, `INSTALL_CONFLICT`, +`BUNDLE_NOT_FOUND`. Contract file `docs-ai/013-prowl-cli/contracts/skills.md`; `prowl-cli` +skill gains one line telling an agent that `prowl skills install prowl-cli` keeps it current. + +**Settings.** No new sidebar item: the Command Line Tool page +(`supacode/Features/Settings/Views/CommandLineToolSettingsView.swift`) gains an **Agent +Skills** section under Installation and Connection, listing `user`-audience skills only +(`workflow`-audience skills belong to 063-D1's Workflows page). Row = name + description + +one status chip per detected target with Install/Remove (Repair for `broken`) + Reveal +bundled skill. State lives in an `AgentSkillsFeature` child of `SettingsFeature`, +initialised when `.commandLineTool` is selected (as `.profiles` initialises `agentProfiles` +in `AppFeature.setSelection`), backed by a `SkillInstallClient` dependency over the shared +installer with a temp-directory test value. Sidebar label stays “Command Line Tool” until +063-D1 reviews the Agents group as a whole. **063 integration.** `embed-skills` and the registry move here from 063-D1; D1 depends on K1 and uses `ProwlSkills.skill(id:)` to materialize `skill:` references and to build its “ask your agent” prompt. D1–D3 skills appear in `prowl skills` and Settings by being added to -`skills/`; no per-skill code. +`skills/` with the right `metadata.prowl-install`; no per-skill code. ## Slices +Release placement: S0 and K1 ship in 063's R1 in parallel with A1 (K1 is small and D1 +depends on it); K2 and K3 follow inside R1 so the R1 user can `prowl skills install`. + | Slice | Contents | Depends | | --- | --- | --- | -| **S0** spike | Verify the target table: directories, symlinked skill directories honoured by Claude Code and Codex, `.agents/skills` readers. Record results in this plan. | — | -| **K1** | `embed-skills`, `Resources/skills` folder reference, `ProwlSkills` registry + frontmatter parser, tests; 063 plan cross-link. | — | -| **K2** | `prowl skills list\|install\|uninstall\|path`, shared installer + status model, contract, `cli.md`, `prowl-cli` skill line, smoke + integration tests (temp dirs, `PROWL_SKILLS_DIR`). | S0, K1 | -| **K3** | Settings › Agents › Skills page, `SkillsFeature` + `SkillInstallClient`, reducer tests, `docs/components/settings.md`. | K2 | +| **S0** spike | Verify the target table: Codex per-directory symlink following and project dir, `.agents/skills` readers among installed runtimes, how each runtime treats a dangling symlink. Use a temporary `CODEX_HOME` / project, never the user's live skill folders. Record results in this plan. | — | +| **K1** | `embed-skills`, `Resources/skills` folder reference, `ProwlSkills` registry + frontmatter parser (incl. `metadata.prowl-install`), tests; 063 plan cross-link. | — | +| **K2** | Shared `SymlinkInstaller` extracted from `CLIInstallClient`, `prowl skills list\|install\|uninstall\|path`, contract, `cli.md`, `prowl-cli` skill line, smoke + integration tests (temp dirs, `PROWL_SKILLS_DIR`). | S0, K1 | +| **K3** | Agent Skills section on the Command Line Tool page, `AgentSkillsFeature` + `SkillInstallClient`, reducer tests, `docs/components/settings.md`. | K2 | ## Alternatives & decisions -- **Symlink vs copy** — symlink: one source of truth that follows app updates, and it is - what the CLI install already does. Copy stays an open question for dotfile-sync users. +Decisions below were taken in the 2026-08-22 plan review (#712): + +- **Link target: bundle directly vs an app-maintained indirection** + (`~/Library/Application Support/com.onevcat.prowl/skills` → current bundle). Direct: its + failure modes (app moved, Debug-vs-Release source, dangling links) are the same set the + `/usr/local/bin/prowl` symlink has carried without trouble; the indirection only buys + self-healing after an app move, at the cost of a launch-time write, a two-hop status check, + and a second mental model. Synced dotfiles (onevcat's `~/.claude/skills` and + `~/.codex/skills` are symlinks into a synced folder) resolve on any Mac with Prowl at + `/Applications`, which is the common case. Indirection stays an upgrade path if moves + break installs in practice. +- **Project scope and git: note only vs auto `.git/info/exclude` vs no project scope.** Note + only: Prowl is a per-user app and project scope is a personal preference, so its git + hygiene is the user's; auto-editing `.git/info/exclude` surprises users and must find the + main repo's `.git` under worktrees. +- **Audience: flat vs frontmatter `metadata.prowl-install` vs directory split.** Frontmatter: + audience is the skill's own property; it keeps one registry root for 063's `skill:` + resolution and lets a bare `prowl skills install` mean “install Prowl's skills”. +- **Settings: dedicated Skills page vs a section on Command Line Tool.** Section: with only + `user`-audience skills shown (two by 063-D3), a page would be thin, the CLI page was + thinner still, and “install the tool → how it connects → teach your agent to use it” + reads as one story. +- **Granularity: skill × target vs per-target toggle with auto-linking of new skills.** + Skill × target: one explicit action per link, same shape as the CLI; auto-linking would + write into agent folders without a user action and fight Debug/Release builds. +- **Symlink vs copy** — symlink; copy stays an open question for users whose runtime + refuses symlinks. - **CLI reads the bundle next to itself vs asks the app over the socket** — local: works with the app closed and adds no protocol surface; `PROWL_SKILLS_DIR` covers dev/tests. -- **Separate Skills page vs a section on Command Line Tool** — separate page: the list - grows to four skills × several targets by 063-D3, and the CLI page should stay about the - CLI. - **Registry in `ProwlCLIShared` vs app-only** — shared: the CLI and the workflow runner both need it; Foundation-only, no new dependency. -- **Prowl's skills only vs a general skills manager** — Prowl's only; general managers - (`npx skills`, per-runtime marketplaces) exist and are not this app's job. +- **Prowl's skills only vs a general skills manager** — Prowl's only. - **Naming** — `prowl skills` (plural), consistent with `agents` / `profiles`. ## Risks @@ -145,26 +183,27 @@ K1 and uses `ProwlSkills.skill(id:)` to materialize `skill:` references and to b runtimes are omitted, never guessed. - Project-scope symlinks leak absolute paths into a repo if committed → CLI note; no git mutation by Prowl. +- Synced skill folders carry the link to other Macs → resolves wherever Prowl is at the + same path; otherwise `broken` until Prowl is installed there. ## Verification -- Unit: frontmatter parser (plain and `>-` descriptions), status tri-state + `broken` over - temp directories, uninstall refusing real directories, CLI bundle resolution through a - symlinked executable. +- Unit: frontmatter parser (plain and `>-` descriptions, `metadata.prowl-install`), status + tri-state + `broken` over temp directories, symlink replacement and real-directory refusal, + CLI bundle resolution through a symlinked executable, `install` refusing + `workflow`-audience skills. - `make test-cli-smoke` (parsing) and `make test-cli-integration` (filesystem round trip in a - temp `PROWL_SKILLS_DIR`, no socket needed); reducer tests for `SkillsFeature`. + temp `PROWL_SKILLS_DIR`, no socket needed); reducer tests for `AgentSkillsFeature`; the + existing CLI install tests keep passing on the extracted `SymlinkInstaller`. - `make check`, `make build-app`; release archive contains `Contents/Resources/skills/`. -- Manual: `prowl skills install prowl-cli`, start Claude Code and Codex in a fresh shell, the - skill is listed and triggers. +- Manual: `prowl skills install`, start Claude Code and Codex in a fresh shell, `prowl-cli` + is listed and triggers; Settings shows the same status as `prowl skills list`. ## Open questions -- Copy mode (`--copy`) in V1 or later? Needed only if S0 finds a symlink-averse runtime or - users sync dotfiles across machines. -- Project scope git hygiene: leave to the user (CLI note) or offer `.git/info/exclude`? -- Should the Command Line Tool install success alert nudge “install the prowl-cli skill”? +- Copy mode (`--copy`) in V1 or later? Needed only if S0 finds a symlink-averse runtime. - Should 063-D1's Workflows “ask your agent” prompt instruct `prowl skills install` first? -- Settings project-scope UI (per-repository Skills section in Repo Settings) — V2 if asked. +- Settings project-scope UI (per-repository section in Repo Settings) — V2 if asked. ## Amendments diff --git a/docs-ai/README.md b/docs-ai/README.md index 35e1b899..9e5095f4 100644 --- a/docs-ai/README.md +++ b/docs-ai/README.md @@ -119,4 +119,4 @@ agent-facing manual for that). | 062 | [workspace-child-diff](062-workspace-child-diff/000-plan.md) | 2026-08-19 | Per-repository diff for workspace children via unified DiffTarget routing | | 063 | [agent-workflows](063-agent-workflows/000-plan.md) | 2026-08-21 | Agent Workflows: YAML-declared, profile-bound multi-agent orchestration (runner, `prowl workflow` CLI, status center, built-in handoff/adversarial review); successor to 047's fixed handoff flow | | 064 | [agent-completion-signals](064-agent-completion-signals/000-plan.md) | 2026-08-22 | Layered agent signal bus (cooperative / launch-scoped hooks / transcript+process+OSC / heuristic), `prowl agents signal` + `agents wait` with source/confidence, per-runtime hook research | -| 065 | [bundled-agent-skills](065-bundled-agent-skills/000-plan.md) | 2026-08-22 | Bundle Prowl's official agent skills into the app, `prowl skills` install/uninstall via symlinks into agent skill folders, Settings › Agents › Skills page, shared registry for 063 | +| 065 | [bundled-agent-skills](065-bundled-agent-skills/000-plan.md) | 2026-08-22 | Bundle Prowl's official agent skills into the app, `prowl skills` install/uninstall via symlinks into agent skill folders, Agent Skills section on Settings › Command Line Tool, shared registry for 063 |