diff --git a/server/routes/lanes.js b/server/routes/lanes.js index 99afd3c..38ae4a3 100644 --- a/server/routes/lanes.js +++ b/server/routes/lanes.js @@ -46,6 +46,7 @@ const { resetLaneData, removeLaneData, } = require("../lib/lane-runtime"); +const { reapOrphanMcp, capOversizedLogs } = require("../lib/lane-gc"); const router = Router(); const MAX_WORKTREE_DIRECTORY_ATTEMPTS = 50; @@ -174,6 +175,23 @@ router.post("/ensure", sameOriginGuard, (req, res) => { } }); +/** + * Machine-wide housekeeping — not scoped to one lane. Reaps orphaned + * Playwright MCP processes and caps oversized hook logs across every lane + * on this machine. See server/lib/lane-gc.js for what "orphaned" and + * "oversized" mean. + */ +router.post("/gc", sameOriginGuard, (req, res) => { + const dryRun = req.body?.dryRun === true; + try { + const reaped = reapOrphanMcp({ dryRun }); + const capped = capOversizedLogs({ dryRun }); + res.json({ reaped, capped }); + } catch (err) { + res.status(500).json({ error: { code: err.code || "ERUNTIME", message: err.message } }); + } +}); + router.get("/:id", (req, res) => { const lane = lanesLib.getLane(req.params.id); if (!lane) return res.status(404).json({ error: { code: "ENOLANE", message: "lane not found" } });