diff --git a/bin/ccam.js b/bin/ccam.js index 9ea982d..d592711 100755 --- a/bin/ccam.js +++ b/bin/ccam.js @@ -2074,6 +2074,20 @@ async function cmdFeatureActivate(args) { } /** `ccam feature show [] [--cwd path]` — one feature's saved pipeline. */ +/** `ccam lanes proof-link [] [--cwd path]` — converge the clone-root + * `proof/` onto `.playwright-mcp/proof` (idempotent). Never run automatically + * by anything else in this codebase; a session or hook calls it explicitly. */ +async function cmdLanesProofLink(args) { + const resolved = await resolveLaneArg(args); + if (!resolved) return; + const { linked } = await post(`/api/lanes/${resolved.laneId}/proof-link`); + console.log( + linked + ? `${c.green("✔")} linked proof/ -> .playwright-mcp/proof` + : "proof/ already linked, nothing to do" + ); +} + async function cmdFeatureShow(args) { const slug = args.find((arg) => !arg.startsWith("--")); if (!slug) { @@ -2250,6 +2264,11 @@ const COMMAND_GROUPS = [ ["lanes runtime", "[]", "Slot, ports, service health and the last boot error"], ["lanes logs", "[] [--tail N]", "Tail one of the lane's hook or service logs"], ["lanes hook", "[] [args…]", "Run a profile hook (ci-gate, e2e, migrate, …)"], + [ + "lanes proof-link", + "[]", + "Converge clone-root proof/ onto .playwright-mcp/proof (idempotent, never automatic)", + ], [ "lock status|acquire|release", "[] [--holder X] [--timeout N]", @@ -3067,6 +3086,7 @@ async function runCommand(argv) { if (["up", "down", "runtime", "logs", "hook"].includes(rest[0])) { return cmdLanesRuntime(rest[0], rest.slice(1)); } + if (rest[0] === "proof-link") return cmdLanesProofLink(rest.slice(1)); return cmdLanes(); case "lock": { const sub = rest[0];