feat(lanes): add ccam lanes gc — orphan MCP reap + log capping (E, F3c)
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.
This commit is contained in:
+38
@@ -1541,6 +1541,36 @@ function cmdSkillsInstall() {
|
||||
console.log(`${c.green("✔")} installed ship-feature-lane skill -> ${dest}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* `ccam lanes gc [--dry-run]` — reap orphaned Playwright MCP processes
|
||||
* (owning session died) and cap oversized hook logs, across every lane on
|
||||
* this machine. Machine-wide, not one lane's; pure local process/file
|
||||
* action, no HTTP round-trip.
|
||||
*/
|
||||
function cmdLanesGc(args) {
|
||||
const dryRun = args.includes("--dry-run");
|
||||
const laneGc = require(path.join(REPO_ROOT, "server", "lib", "lane-gc.js"));
|
||||
|
||||
const reaped = laneGc.reapOrphanMcp({ dryRun });
|
||||
if (reaped.length) {
|
||||
console.log(
|
||||
`${dryRun ? "would reap" : "reaped"} ${reaped.length} orphaned MCP process(es): ${reaped.join(", ")}`
|
||||
);
|
||||
} else {
|
||||
console.log("no orphaned MCP processes found");
|
||||
}
|
||||
|
||||
const capped = laneGc.capOversizedLogs({ dryRun });
|
||||
if (capped.length) {
|
||||
for (const { path: logPath, sizeBefore } of capped) {
|
||||
const mb = (sizeBefore / (1024 * 1024)).toFixed(1);
|
||||
console.log(`${dryRun ? "would cap" : "capped"} ${logPath} (${mb}MB -> 2MB)`);
|
||||
}
|
||||
} else {
|
||||
console.log("no oversized logs found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `ccam lanes profile init <repo>` — detect a Node.js project and scaffold
|
||||
* `.ccam/profile/`. Pure filesystem action against the SOURCE repo; does not
|
||||
@@ -2433,6 +2463,11 @@ const COMMAND_GROUPS = [
|
||||
"<name> [<id>]",
|
||||
"Check whether a named integration (tracker, dev_qc, ci_wait) is on for this lane — exit 0/1",
|
||||
],
|
||||
[
|
||||
"lanes gc",
|
||||
"[--dry-run]",
|
||||
"Reap orphaned Playwright MCP processes + cap oversized hook logs, across every lane",
|
||||
],
|
||||
[
|
||||
"skills install",
|
||||
"",
|
||||
@@ -3265,6 +3300,9 @@ async function runCommand(argv) {
|
||||
if (rest[0] === "integration") {
|
||||
return cmdLanesIntegration(rest.slice(1));
|
||||
}
|
||||
if (rest[0] === "gc") {
|
||||
return cmdLanesGc(rest.slice(1));
|
||||
}
|
||||
return cmdLanes();
|
||||
case "skills": {
|
||||
if (rest[0] === "install") return cmdSkillsInstall();
|
||||
|
||||
Reference in New Issue
Block a user