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
+18 -8
View File
@@ -1,10 +1,12 @@
/**
* @file Pipeline templates for lanes. A template is a plain JSON list of nodes
* (`server/data/pipelines/*.json` plus any override dropped in
* `DASHBOARD_PIPELINES_DIR`); this module resolves a lane's declared stage onto
* a node through per-node `aliases`, and derives the five render states the
* pipeline map draws. Pure functions — no DB, no I/O beyond the one-time
* template load, so it stays trivially testable.
* dropped in `DASHBOARD_PIPELINES_DIR` (`server/data/pipelines/` is read too,
* but AgentHub ships NO template any more — the pipeline feature is dormant
* until one is installed); this module resolves a lane's declared stage onto a
* node through per-node `aliases`, and derives the five render states the
* pipeline map draws. With no template, every lane is on an EMPTY `default`
* pipeline: no nodes, no states, progress 0. Pure functions — no DB, no I/O
* beyond the one-time template load, so it stays trivially testable.
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
*/
@@ -14,6 +16,14 @@ const path = require("node:path");
const DEFAULT_PIPELINE_ID = "default";
const BUILTIN_DIR = path.join(__dirname, "..", "data", "pipelines");
/** What every lane is on while no template is installed. */
const EMPTY_PIPELINE = Object.freeze({
id: DEFAULT_PIPELINE_ID,
name: "",
skill: "",
nodes: Object.freeze([]),
});
/** Load every template once. A malformed file is skipped, never fatal. */
function loadAll() {
const dirs = [BUILTIN_DIR];
@@ -77,10 +87,10 @@ function listPipelines() {
return [...templates().values()];
}
/** Never throws: an unknown id yields the default template. */
/** Never throws: an unknown id yields the default template, else the empty one. */
function getPipeline(id) {
const t = templates();
return t.get(id) || t.get(DEFAULT_PIPELINE_ID);
return t.get(id) || t.get(DEFAULT_PIPELINE_ID) || EMPTY_PIPELINE;
}
/** Index of the node matching `stage` by id or alias; -1 when unknown. */
@@ -138,7 +148,7 @@ function nodeStates(pipeline, lane) {
function progressPct(pipeline, lane) {
const i = phaseIdx(pipeline, lane.stage);
if (i < 0) return 0;
if (i < 0 || pipeline.nodes.length < 2) return 0;
return Math.round((i / (pipeline.nodes.length - 1)) * 100);
}