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:
@@ -161,10 +161,6 @@ function fastPathOk(rt = runtimeDir()) {
|
||||
if (state.pluginRoot !== PLUGIN_ROOT) return false;
|
||||
if (state.depsHash !== depsHash()) return false;
|
||||
if (!fs.existsSync(path.join(rt, "node_modules"))) return false;
|
||||
// A machine can be fully set up and still be missing the plugins the
|
||||
// pipelines drive. Reading one recorded flag keeps this hot path cheap — the
|
||||
// actual check (manifest + every user SKILL.md) runs once, in the worker.
|
||||
if (!state.skillPluginsSettled) return false;
|
||||
// A live server says nothing about whether it will come back. When our unit
|
||||
// still names a previous plugin cache directory, everything looks healthy
|
||||
// until the next reboot — and then the dashboard is simply gone, from a path
|
||||
@@ -500,46 +496,6 @@ function log(rt, line) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the plugins AgentHub's pipelines drive but this machine cannot resolve —
|
||||
* today `superpowers`, which `/agenthub:ship-feature(-lane)` calls step by step. A
|
||||
* fresh `agenthub` install otherwise runs those skills partway and fails at the
|
||||
* first call with no warning beforehand.
|
||||
*
|
||||
* Off by setting `AGENTHUB_AUTO_INSTALL_PLUGINS` to `0`, `false` or `off`; that
|
||||
* leaves `/agenthub-doctor`'s WARN row as the only notice, which is the right
|
||||
* behaviour for anyone who wants to choose their own plugins.
|
||||
*
|
||||
* One-shot: the outcome is recorded in the runtime state and the fast path
|
||||
* takes it into account, so a machine with no network does not re-attempt a
|
||||
* clone on every session. `/agenthub-update` (`--force`) retries.
|
||||
*
|
||||
* Best-effort throughout. Nothing here may throw or block: the dashboard,
|
||||
* hooks and CLI all work without these plugins.
|
||||
*
|
||||
* @returns {"off"|"nothing-missing"|"installed"|"failed"|"error"} or the previously
|
||||
* recorded outcome when this run had nothing to settle.
|
||||
*/
|
||||
function autoInstallSkillPlugins(rt, { force = false } = {}) {
|
||||
const flag = process.env.AGENTHUB_AUTO_INSTALL_PLUGINS;
|
||||
if (flag === "0" || flag === "false" || flag === "off") return "off";
|
||||
// Return the PREVIOUS outcome, not a marker: writeState records whatever this
|
||||
// returns, and overwriting "installed" with "already-settled" would lose the
|
||||
// only record of what actually happened.
|
||||
const settled = readState(rt)?.skillPluginsSettled;
|
||||
if (!force && settled) return settled;
|
||||
|
||||
try {
|
||||
const { autoInstallSkillPlugins: install } = require("../server/lib/skill-plugins");
|
||||
const summary = install((line) => log(rt, line));
|
||||
if (!summary.attempted.length) return "nothing-missing";
|
||||
return summary.failed.length ? "failed" : "installed";
|
||||
} catch (err) {
|
||||
log(rt, `skill-plugin auto-install skipped: ${err.message}`);
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------ plugin-cache pruning */
|
||||
|
||||
/** How many retired builds to leave behind, newest first, as a rollback cushion. */
|
||||
@@ -814,21 +770,12 @@ function bootstrap(rt = runtimeDir(), { force = false } = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Last, and deliberately so: it clones from the network, and nothing above
|
||||
// may wait on it. Runs here rather than in the foreground pass because this
|
||||
// whole function is already detached from the 10 s SessionStart hook.
|
||||
const skillPlugins = autoInstallSkillPlugins(rt, { force });
|
||||
|
||||
writeState(
|
||||
{
|
||||
pluginVersion: pluginVersion(),
|
||||
depsHash: wantDeps,
|
||||
pluginRoot: PLUGIN_ROOT,
|
||||
claudeHome: getClaudeHome(),
|
||||
// Settles the fast path: whatever the outcome, the next SessionStart
|
||||
// must not spawn a worker just to retry a network clone. Cleared by
|
||||
// `/agenthub-update` (force), which is the retry.
|
||||
skillPluginsSettled: skillPlugins,
|
||||
updatedAt: new Date().toISOString(),
|
||||
},
|
||||
rt
|
||||
@@ -930,6 +877,5 @@ module.exports = {
|
||||
livePids,
|
||||
stopDashboard,
|
||||
startDashboard,
|
||||
autoInstallSkillPlugins,
|
||||
bootstrap,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user