feat(plugin): ship the repo's skills as ccam plugin skills

The repo root already IS the `ccam` plugin root (`"source": "./"`), so the
conventional `skills/` dir at the root is the plugin's skills dir — while
`.claude/skills/` only loaded for a session whose cwd was inside this
checkout. That is useless for a lane working in another repo, which is why
`ccam skills install` existed at all.

Move all seven skills to `skills/`: they now reach every plugin user as
`/ccam:<name>` (bare `/<name>` as an alias). `ccam skills install` stays as
the fallback for a plain checkout without the plugin, sourcing from the new
path.

Agents deliberately do NOT move. A plugin agent is addressed as
`ccam:qc-local`, which would break the `subagent_type: qc-local` references
in ship-feature-lane; `ccam lanes agents install` keeps writing them into the
lane's own `.claude/agents/`, the highest-priority agent source. MCP was
already plugin-shipped via `plugins/ccam/.mcp.json`.

Mechanical fallout: ~115 source files carry a doc-comment pointer to
`.claude/skills/file-headers/`, repointed to `skills/file-headers/`. The
generic Claude Code config-surface examples in openapi/cc-config (`.claude/
skills/code-reviewer`) describe any user's layout and are left alone.

Also fixes the two file-headers scripts, whose `ROOT=` climbed four levels
from `.claude/skills/file-headers/scripts/` and would have escaped the repo
from the new depth — it scanned sibling projects until corrected to three.

npm run test:server (1160 pass), test:client (422 pass), mcp:typecheck,
mcp:build + mcp:check-build all green.
This commit is contained in:
2026-08-21 17:17:33 +07:00
parent effdaf4ba8
commit b7c573f8d9
132 changed files with 157 additions and 133 deletions
+8 -4
View File
@@ -1074,15 +1074,19 @@ The **ship-feature-lane** skill is the ported Shipyard driving skill for autonom
**Every stage whose job is to judge the work runs in a fresh-context subagent, never in the driving session.** The plan debate (Stage 0b), unit tests (Stage 1b), the e2e run and its triage (Stage 3), code review (Stage 4), browser QC (Stage 6), the senior gate (Stage 7), and a re-triage of CI that stayed red after a fix (Stage 10) are each dispatched with the Agent tool to a subagent that starts with an empty context and receives only artifacts it can verify itself — working directory, lane spec, diff range, commands, and the other agents' reports verbatim, never the driving session's paraphrase of why a finding was fine. The stages the driving session keeps are the ones that *do* rather than judge: intake, implementation, the mechanical gates, publishing, the CI/PR watch, and applying every fix the judges ask for. `subagent_type: fork` is explicitly forbidden for these: a fork inherits the implementing session's context, so it inherits the belief that the code is already correct. The driving session implements and applies fixes; it never grades its own work. Stages 1b/3/4 use the generic `general-purpose`/`Code Reviewer` types (nothing to install); Stages 6/7 use the lane-installed `qc-local`/`senior-gate-reviewer` agents.
### Installing the skill (once per machine)
### Getting the skill (nothing to do, if you run the plugin)
`/ship-feature-lane` only works once Claude Code can discover the skill from *any* lane's working directory — Claude Code auto-discovers `.claude/skills/` only from the repo that owns it, and this skill lives in `ccam-lanes`' own checkout, not in any lane's repo. Install it globally first:
The skill lives in `skills/ship-feature-lane/`, and the repo root **is** the `ccam` plugin root (`"source": "./"`), so `skills/` is the plugin's own skills directory. Anyone with the `ccam` plugin installed already has it in every session, from any lane's working directory, as **`/ccam:ship-feature-lane`** — with the bare `/ship-feature-lane` working as an alias unless another skill or command claims that name.
Only a plain checkout without the plugin needs the fallback:
```bash
ccam skills install
```
Copies `.claude/skills/ship-feature-lane/` into `~/.claude/skills/ship-feature-lane/` (overwrites on reinstall — run it again after pulling an update to the skill). One-time per machine, same as `ccam lanes agents install` is one-time per lane.
Copies `skills/ship-feature-lane/` into `~/.claude/skills/ship-feature-lane/` (overwrites on reinstall — run it again after pulling an update to the skill), which restores the bare `/ship-feature-lane` name. One-time per machine, same as `ccam lanes agents install` is one-time per lane.
**Agents are the deliberate exception.** `qc-local` and `senior-gate-reviewer` are *not* shipped as plugin agents: a plugin agent is addressed as `ccam:qc-local`, and the skill dispatches them by the bare `subagent_type: qc-local`. `ccam lanes agents install` writes them into the lane's own `.claude/agents/`, which is also the highest-priority agent source — so the lane's copy wins over anything global.
### Invoking the skill
@@ -1106,7 +1110,7 @@ The skill frontloads all clarifying questions once, then runs unattended. The on
**Stages 6 and 7 are now unblocked** — run `ccam lanes agents install` once per lane (see "Installing the QC/gate agents" below) before a lane's first run through Stage 6. A lane that reaches Stage 6/7 without having installed the agents will fail to find the `qc-local`/`senior-gate-reviewer` subagent type; install and re-run.
See [the skill text](../.claude/skills/ship-feature-lane/SKILL.md) for the full pipeline definition.
See [the skill text](../skills/ship-feature-lane/SKILL.md) for the full pipeline definition.
### QC boot flag and profile integration
+15
View File
@@ -88,6 +88,21 @@ checkout unnecessary.
| The MCP tools | `plugins/ccam/.mcp.json`, pointing at the committed `mcp/build/index.js` |
| 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 |
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.
This is why `skills/` sits at the repo root instead of `.claude/skills/` — the
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.
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