feat(plugin): ship the agents from a single root agents/ directory

Move .claude/agents/ and server/data/agent-templates/ship-feature-lane/
into one agents/ at the repo root — which IS the plugin root, so all five
agents now ship with the ccam plugin as ccam:<name>, the same way skills
already do.

The two pipeline agents were byte-identical copies in both places; that
duplication is gone. `ccam lanes agents install` now reads them straight
from agents/, so the per-lane copy in <lane>/.claude/agents/ still gives
the bare `subagent_type: qc-local` the ship-feature-lane skill prefers.
Skill and docs record both names: bare inside a lane, ccam: as fallback.
This commit is contained in:
2026-08-21 17:30:04 +07:00
parent b7c573f8d9
commit 510f015fdf
13 changed files with 27 additions and 19 deletions
+10 -6
View File
@@ -89,6 +89,7 @@ checkout unnecessary.
| The dashboard UI (`/run` and every other client route) | built into the runtime dir by the bootstrap, so it works the moment `claude` starts |
| `/ccam-doctor`, `/ccam-update`, `/ccam-open` | `plugins/ccam/commands/` |
| The skills (`ship-feature-lane`, `ship-feature`, `repo-onboarding`, `debug-live-issue`, `mcp-operations`, `update-project-docs`, `file-headers`) | `skills/` at the repo root — which IS the plugin root, so they are auto-discovered as plugin skills |
| The agents (`qc-local`, `senior-gate-reviewer`, `backend-reviewer`, `frontend-reviewer`, `mcp-reviewer`) | `agents/` at the repo root, auto-discovered the same way — exposed as `ccam:<name>` |
Plugin skills are namespaced: they are invoked as `/ccam:<name>`, with the bare
`/<name>` working as an alias unless another skill or command claims that name.
@@ -97,12 +98,15 @@ latter only loads for a session whose cwd is inside this checkout, which is
useless for a lane working in a different repo. `ccam skills install` survives
as the fallback for a plain checkout without the plugin.
**Agents are deliberately not shipped this way.** `.claude/agents/` stays
repo-local, and the lane agents (`qc-local`, `senior-gate-reviewer`) are
installed per-lane by `ccam lanes agents install`. A plugin agent would be
addressed as `ccam:qc-local`, breaking the `subagent_type: qc-local` references
in the pipeline skill; the per-lane copy also lands in the highest-priority
agent source.
**The agents ship the same way, from the same files.** `agents/` at the repo
root holds all five (`qc-local`, `senior-gate-reviewer`, `backend-reviewer`,
`frontend-reviewer`, `mcp-reviewer`), so the plugin exposes them as
`ccam:<name>`. `ccam lanes agents install` copies `qc-local` +
`senior-gate-reviewer` from that same directory into a lane's own
`.claude/agents/` — the highest-priority agent source — which is what makes the
bare `subagent_type: qc-local` in the pipeline skill resolve there. One source
file, two ways to reach it; the skill names the bare form first and falls back
to the `ccam:` form.
Because the plugin ships the hooks itself, `npm run install-hooks` is not needed
for plugin users — and must not be run alongside it. Events carry no id, so two