feat(lanes): add POST /:id/agents/install route (E3)

This commit is contained in:
2026-08-05 12:42:27 +07:00
parent 4134b3d307
commit 3fb70a3fc1
+21
View File
@@ -33,6 +33,7 @@ const {
} = require("../lib/worktree"); } = require("../lib/worktree");
const { withLaneLock } = require("../lib/lane-lock"); const { withLaneLock } = require("../lib/lane-lock");
const { checkSync, mergeSync, continueSync } = require("../lib/lane-sync"); const { checkSync, mergeSync, continueSync } = require("../lib/lane-sync");
const { installAgents } = require("../lib/lane-agents");
const { HOOKS, runHook, resolveProfile } = require("../lib/lane-profile"); const { HOOKS, runHook, resolveProfile } = require("../lib/lane-profile");
const { slotDirs } = require("../lib/lane-slots"); const { slotDirs } = require("../lib/lane-slots");
const { const {
@@ -328,6 +329,26 @@ router.post("/:id/proof-link", sameOriginGuard, (req, res) => {
res.json(proofLib.ensureProofLink(lane)); res.json(proofLib.ensureProofLink(lane));
}); });
/**
* Install the ship-feature-lane pipeline's agent templates (qc-local,
* senior-gate-reviewer) into this lane's own .claude/agents/. Static file
* copy — no templating, no credentials to inject (this repo has no
* seed-account system yet; see the E3 design spec's Decisions table).
* Never automatic, same as proof-link: a session calls this explicitly.
*/
router.post("/:id/agents/install", sameOriginGuard, async (req, res) => {
const lane = lanesLib.getLane(req.params.id);
if (!lane) return res.status(404).json({ error: { code: "ENOLANE", message: "lane not found" } });
try {
res.json(await installAgents(lane));
} catch (err) {
if (err.code === "ENOTGITREPO") {
return res.status(400).json({ error: { code: err.code, message: err.message } });
}
res.status(500).json({ error: { code: err.code || "ERUNTIME", message: err.message } });
}
});
/** /**
* A lane's working-copy facts: branch, short HEAD, that commit's subject, and * A lane's working-copy facts: branch, short HEAD, that commit's subject, and
* the uncommitted counts. Read-only, so no same-origin guard — that guard * the uncommitted counts. Read-only, so no same-origin guard — that guard