- Repo mode adopts a directory as-is via /lanes/ensure (no worktree, no
branch fields) - the right choice for a main repo you want stage
detection on. Worktree mode (default) keeps the existing provisioning
flow but now requires a manually-typed branch name instead of deriving
one from the title.
- POST /lanes/worktree accepts an optional `branch`, validated via
`git check-ref-format --branch`; omitting it preserves the CLI's
existing auto-derived-branch behavior.
- New GET /lanes/browse lists a directory's immediate subdirectories,
backing a small folder-browse modal on both path fields - browsers
cannot expose an absolute path from a native picker, so this is
server-backed instead, consistent with the tool's local-first model.
Adopting the main repo as its own lane now gets stage detection
(cwd matches, same as any other lane), and its card lists every
managed-worktree lane provisioned from it with a jump-to link.
Also add the two missing Skill-tool detect rules (implement, ship)
so detection covers all four Superpowers workflow phases, not just
plan/review.
POST /worktree answers with 202 before the background git worktree
add finishes, so profileInit/agentsInstall/mcpSync were racing the
lane's own directory into existence and mostly failing. Poll
GET /api/lanes/:id until provisioning leaves "provisioning" first.
The 3s auto-close timer closed before a user reasonably had time to
look at the setup results, making the feature appear to do nothing.
Require an explicit dismiss (Cancel/X) instead.
The three setup calls (profile/agents/mcp) fired after worktree
creation but their outcome was only logged to the console. Keep the
modal open with a ✓/✗ summary for a few seconds (or until dismissed)
so the user actually sees what happened, matching the original F5 design.
3 tasks: POST /:id/profile/init route (wraps already-built
lane-detect.js), AddLaneModal.tsx wiring (Promise.allSettled over
profile-init + agents-install + mcp-sync, none blocking lane creation
or each other) + client API method + tests, and docs.
One click instead of four: after AddLaneModal creates a worktree lane,
fire profile-init + agents-install + mcp-sync in parallel
(Promise.allSettled, best-effort — none of the three blocks lane
creation or each other). Needs one new route (POST
/:id/profile/init, wrapping already-built lane-detect.js) since
profile-init was CLI-only until now.
LaneCard gets agents-install/mcp-sync buttons, integration status
badges, and a sync-base --check button (read-only preflight only — no
merge button, that stays a session/skill action). Settings gets
skills-install and housekeeping (gc) buttons, machine-wide. Two new
routes needed (POST /api/skills/install, POST /api/lanes/gc) since
those two primitives were CLI-only until now.
Ports the two pieces of Shipyard's lane-gc.sh that match CCAM's actual
architecture: kill Playwright MCP processes reparented to pid 1 (owning
session died), cap hook logs over 10MB back to their last 2MB in place.
Drops auto-removing stale worktrees by age (conflicts with the
never-automatic-destroy rule), state archiving, and scratch-debris
sweep (different storage architecture / files CCAM doesn't generate) —
see docs/superpowers/specs/2026-08-05-lane-gc-design.md.
Scopes lane-gc.sh down to the two pieces that match CCAM's actual
architecture (orphan Playwright MCP reap, oversized-log capping).
Drops auto-removing stale worktrees by age — that's exactly the kind
of automatic destructive action this repo's own CLAUDE.md forbids
(destroy always goes through the three-check guard, never automatic).
State archiving and scratch-debris sweep don't apply either (different
storage architecture; CCAM doesn't generate those files).
Copies .claude/skills/ship-feature-lane/ into ~/.claude/skills/, so
/ship-feature-lane is discoverable from a session running inside any
lane's own working directory — not just inside this repo, which is
where it lived until now (Claude Code only auto-discovers .claude/
directories from the repo that owns them). Pure filesystem action,
same self-location REPO_ROOT already gives lanes profile init.
Found auditing E1-F3a for Shipyard parity: .claude/skills/ship-feature-lane/
only exists inside ccam-lanes' own repo, never installed globally, so
/ship-feature-lane is unreachable from its actual intended invocation
context (a session inside some OTHER lane's repo). Shipyard's own
install-claude-assets.sh solves this for its bundled skills the same way.
3 tasks: isIntegrationEnabled in lane-profile.js (reuses parseEnvFile),
the route + CLI, and wiring SKILL.md's hardcoded-off Setup text to the
real check (still no-op behaviorally — no ticketer/dev-qc agent exists
to act on an enabled toggle yet, but the check itself is now honest).
Scopes down F3 to just the generic <name>_ENABLED toggle-check primitive
(ccam lanes integration <name>) — ticketer/dev-qc agents stay deferred,
same reasoning E3 already used for qc-local's credential gap: no tracker/
dev-QC MCP configured anywhere, no per-lane credential source to consume.
4 tasks: the lane-mcp.js sync core (relocate + pin + seed profiles, no
permission/settings writes per the design spec's scope decision), the
route, the CLI, and docs.
Scopes the first of F's four pieces to .mcp.json relocation + Chromium
profile seeding only. Drops Shipyard's permission/auto-approval writes
(no existing CCAM pattern for a backend command granting permissions,
and the rules named agents not in scope: pr-reviewer has no driving
skill to port, ticketer is a later task) and the node-version wrapper
(environment-specific workaround, no evidence this repo needs it).
Two gaps found via audit against Shipyard's source:
1. Stage 6/7 still said "this agent does not exist yet" and told a
driving session to treat any lane reaching those stages as blocked —
stale since E3 shipped qc-local + senior-gate-reviewer. Replaced with
an unconditional launch plus a one-time "ccam lanes agents install"
preflight note in Setup.
2. Stage 12's conflict-resolution path called `ccam lanes sync-base`
directly on any CONFLICTING PR, with no check that the PR's base is
actually `development` first. Shipyard's original has this guard
(its own "legacy main-based PR" case) — ported here in general form:
never auto-merge into a PR whose base drifted from `development`.
Root cause: the catch block only fell through to the auto-commit path when
`unmergedFiles().length && MERGE_HEAD exists` — but a merge rerere resolved
completely has ZERO unmerged files (git already staged the resolution), so
that guard was always false and the raw git error was rethrown instead.
Found via an audit against the Shipyard source this was ported from.
Fixed by checking MERGE_HEAD first (unconditionally — its absence means the
merge never started, a real failure), then branching on whether any files
are still unmerged. Added a real rerere fixture test (teach a resolution,
recreate the identical conflict, confirm mergeSync auto-commits) — the
existing test suite had no coverage for this path.
5 tasks: the two ported agent templates (every Shipyard placeholder/script
reference resolved at port time), the lane-agents.js install core (git-dir
vs git-common-dir correctness verified against a real worktree fixture,
same lesson E2 already learned for info/attributes), the route, the CLI,
and docs.
Scopes the third of E's remaining pieces to the two agents the current
skill text actually invokes (Stage 6/7). ticketer/dev-qc (F-gated) and
pr-reviewer (unreferenced) stay out of scope; per-lane credential
embedding is deferred pending a seed-account system this repo doesn't
have yet.
5 tasks: MIGRATIONS_DIR/GENERATED_MERGE_PATHS profile declarations, the
lane-sync.js git core (check/merge/continue, ported against a real
bare-origin fixture mirroring lane-sync-dev.sh's own test suite, plus a
dedicated git-worktree fixture to catch the git-dir vs git-common-dir
distinction MERGE_HEAD/info-attributes depend on), the sync-base route,
the CLI subcommand, and the SKILL.md/docs edits that turn three "if it
exists yet" conditionals into real instructions.