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
@@ -42,7 +42,7 @@ const LIVENESS_DOT: Record<Lane["liveness"], string> = {
* recordDetection refuses any detection that isn't strictly ahead.
*/
function detectionLeads(lane: Lane): boolean {
if (!lane.detected_stage) return false;
if (!lane.detected_stage || !lane.pipeline_nodes.length) return false;
const nodes = lane.pipeline_nodes;
return (
nodes.findIndex((n) => n.id === lane.detected_stage) >=
@@ -116,9 +116,9 @@ export default function LaneStripCard({
<span className="shrink-0 text-[10px] font-semibold tracking-widest text-fg-muted">
#{lane.id}
</span>
{/* Only claude lanes carry a pipeline; the others show their CLI's
tag in place of the stage chip. */}
{lane.tool !== "claude" ? (
{/* Only claude lanes carry a pipeline, and only while a template is
installed; the others show their CLI's tag in place of the stage chip. */}
{lane.tool !== "claude" || lane.pipeline_nodes.length === 0 ? (
<span className="shrink-0 rounded border border-border bg-surface-2 px-1.5 py-0.5 text-[10px] text-fg-muted">
{LANE_TOOL_LABEL[lane.tool]}
</span>