refactor(lanes): drop the workflow skills and Superpowers link; pipelines go dormant

The plugin stops shipping its workflow layer:
- skills/ship-feature and skills/ship-feature-lane, the 18 stage/ship slash
  commands (plugin.json keeps agenthub-doctor/update/open), and all four
  agents/ (qc-local, senior-gate-reviewer, backend-reviewer, frontend-reviewer).
- CLI `agenthub skills install`, `agenthub lanes agents install`,
  `agenthub ship-full|ship-quick`; routes POST /api/skills/install and
  POST /api/lanes/:id/agents/install; the Settings button, the lane Tools
  menu item and the Add-lane setup step that called them.
- The Superpowers auto-install: server/lib/skill-plugins.js, the bootstrap's
  autoInstallSkillPlugins / skillPluginsSettled gate and the doctor row.

Pipelines are kept but dormant: server/data/pipelines/ is deleted, so no
template ships. `default` resolves to EMPTY_PIPELINE (no nodes, progress 0),
createLane still accepts it, POST /api/lanes/:id/stage answers 400
ENOPIPELINE, and the Workspace hides the stage timer, pickers, PipelineMap
and strip stage chip for a lane with no nodes. A template dropped into
DASHBOARD_PIPELINES_DIR turns it all back on. The server suite loads its
templates from server/__tests__/fixtures/pipelines/.

Docs: CLAUDE.md (marker, retired rules), README(.vi), INSTALL, ARCHITECTURE,
docs/LANES|PLUGINS|CLI|API, agenthub-introduction.html.
This commit is contained in:
2026-09-28 17:44:27 +07:00
parent 3c238bc5c4
commit 2b8f83d2dd
72 changed files with 325 additions and 3305 deletions
+13 -21
View File
@@ -53,7 +53,6 @@ const {
const { runGitAction } = require("../lib/git-ops");
const { withLaneLock } = require("../lib/lane-lock");
const { checkSync, mergeSync, continueSync } = require("../lib/lane-sync");
const { installAgents } = require("../lib/lane-agents");
const { syncMcp } = require("../lib/lane-mcp");
const { HOOKS, runHook, resolveProfile, isIntegrationEnabled } = require("../lib/lane-profile");
const { slotDirs } = require("../lib/lane-slots");
@@ -510,6 +509,19 @@ router.post("/:id/stage", sameOriginGuard, (req, res) => {
const requested = req.body && req.body.stage;
if (requested !== undefined && requested !== null && requested !== "") {
const pipeline = getPipeline(current.pipeline);
// No template installed: the pipeline feature is dormant, so there is no
// stage to declare — say so instead of listing zero nodes.
if (!pipeline.nodes.length) {
return res.status(400).json({
error: {
code: "ENOPIPELINE",
message:
"no pipeline template is installed, so this lane has no stages to declare " +
"(drop a template into DASHBOARD_PIPELINES_DIR to turn stages on)",
stages: [],
},
});
}
if (phaseIdx(pipeline, requested) === -1) {
return res.status(400).json({
error: {
@@ -631,26 +643,6 @@ router.post("/:id/proof-link", sameOriginGuard, (req, res) => {
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 } });
}
});
/**
* Give this lane the same MCP servers as its source repo — relocates the
* source repo's already-configured mcpServers (from ~/.claude.json) into
-28
View File
@@ -1,28 +0,0 @@
/**
* @file Machine-wide (not lane-scoped) skill installation.
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
*/
const { Router } = require("express");
const path = require("node:path");
const { installShipFeatureLaneSkill } = require("../lib/skills-install");
const { sameOriginGuard } = require("./run");
const router = Router();
/** This server's own checkout root — server/routes/skills.js is two levels
* under it (server/routes/), same computation bin/agenthub.js's REPO_ROOT
* already does from its own location. */
const REPO_ROOT = path.resolve(__dirname, "..", "..");
router.post("/install", sameOriginGuard, (req, res) => {
try {
res.json(installShipFeatureLaneSkill({ repoRoot: REPO_ROOT }));
} catch (err) {
if (err.code === "ENOSKILLSRC") {
return res.status(400).json({ error: { code: err.code, message: err.message } });
}
res.status(500).json({ error: { code: err.code || "ERUNTIME", message: err.message } });
}
});
module.exports = router;