feat(cli): route runtime commands and add bd diagnostics to status
This commit is contained in:
parent
654c8eb4c8
commit
34c2b7f4eb
5 changed files with 78 additions and 3 deletions
|
|
@ -5,7 +5,14 @@ const { spawnSync } = require('node:child_process');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
|
|
||||||
const cliPath = path.resolve(__dirname, '../src/cli/beadboard-cli.ts');
|
const cliPath = path.resolve(__dirname, '../src/cli/beadboard-cli.ts');
|
||||||
const result = spawnSync(process.execPath, ['--import', 'tsx', cliPath, ...process.argv.slice(2)], {
|
const launcherPath = path.resolve(__dirname, '../install/beadboard.mjs');
|
||||||
|
const command = process.argv[2] || 'help';
|
||||||
|
const launcherCommands = new Set(['start', 'open', 'status']);
|
||||||
|
const targetArgs = launcherCommands.has(command)
|
||||||
|
? [launcherPath, ...process.argv.slice(2)]
|
||||||
|
: ['--import', 'tsx', cliPath, ...process.argv.slice(2)];
|
||||||
|
|
||||||
|
const result = spawnSync(process.execPath, targetArgs, {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,43 @@ function getPort() {
|
||||||
return Number.isFinite(value) ? value : 3000;
|
return Number.isFinite(value) ? value : 3000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function splitPathVariable(value) {
|
||||||
|
if (!value) return [];
|
||||||
|
return value.split(path.delimiter).map((entry) => entry.trim()).filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveBdPath() {
|
||||||
|
const pathEntries = splitPathVariable(process.env.PATH || '');
|
||||||
|
const candidates =
|
||||||
|
process.platform === 'win32'
|
||||||
|
? ['bd.cmd', 'bd.exe', 'bd.ps1', 'bd.bat', 'bd']
|
||||||
|
: ['bd'];
|
||||||
|
for (const dir of pathEntries) {
|
||||||
|
for (const candidate of candidates) {
|
||||||
|
const fullPath = path.join(dir, candidate);
|
||||||
|
if (fs.existsSync(fullPath)) {
|
||||||
|
return fullPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBdDiagnostics() {
|
||||||
|
const beadsDir = path.resolve(process.cwd(), '.beads');
|
||||||
|
const dbPath = path.join(beadsDir, 'beads.db');
|
||||||
|
const bdPath = resolveBdPath();
|
||||||
|
return {
|
||||||
|
available: Boolean(bdPath),
|
||||||
|
path: bdPath,
|
||||||
|
project: {
|
||||||
|
cwd: process.cwd(),
|
||||||
|
hasBeadsDir: fs.existsSync(beadsDir),
|
||||||
|
hasBeadsDb: fs.existsSync(dbPath),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function statusRequest(port) {
|
function statusRequest(port) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const req = http.get(
|
const req = http.get(
|
||||||
|
|
@ -140,6 +177,7 @@ async function main() {
|
||||||
runtimeRoot: runtime.runtimeRoot,
|
runtimeRoot: runtime.runtimeRoot,
|
||||||
installMode: runtime.installMode,
|
installMode: runtime.installMode,
|
||||||
shimTarget: runtime.shimTarget,
|
shimTarget: runtime.shimTarget,
|
||||||
|
bd: getBdDiagnostics(),
|
||||||
};
|
};
|
||||||
output(payload, json);
|
output(payload, json);
|
||||||
process.exit(probe.running ? 0 : 1);
|
process.exit(probe.running ? 0 : 1);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"test": "node --test tests/bootstrap.test.mjs && node --import tsx --test tests/components/shared/base-card.test.tsx && node --import tsx --test tests/components/shared/agent-avatar.test.tsx && node --import tsx --test tests/components/sessions/sessions-header.test.ts && node --import tsx --test tests/components/sessions/agent-station-logic.test.ts && node --import tsx --test tests/lib/parser.test.ts && node --import tsx --test tests/lib/pathing.test.ts && node --import tsx --test tests/components/shared/left-panel.test.tsx && node --import tsx --test tests/components/shared/top-bar.test.tsx && node --import tsx --test tests/components/shared/mobile-nav.test.tsx && node --import tsx --test tests/components/swarm/swarm-card.test.tsx && node --import tsx --test tests/hooks/url-state-integration.test.ts && node --import tsx --test tests/hooks/use-graph-analysis.test.ts && node --import tsx --test tests/components/graph/smart-dag.test.tsx && node --import tsx --test tests/components/unified-shell.test.tsx && node --import tsx --test tests/components/blocked-triage-modal.test.tsx && node --import tsx --test tests/components/graph/graph-node-labels.test.tsx && node --import tsx --test tests/components/graph/graph-node-assign.test.tsx && node --import tsx --test tests/components/graph/graph-node-conversation.test.tsx && node --import tsx --test tests/lib/coord-schema.test.ts && node --import tsx --test tests/lib/install-manifest.test.ts && node --import tsx --test tests/lib/runtime-manager.test.ts && node --import tsx --test tests/lib/coord-events.test.ts && node --import tsx --test tests/api/coord-events-route.test.ts && node --import tsx --test tests/lib/coord-projections-inbox.test.ts && node --import tsx --test tests/lib/coord-projections-reservations.test.ts && node --import tsx --test tests/components/sessions/conversation-drawer-coord.test.tsx && node --import tsx --test tests/scripts/beadboard-launcher.test.ts && node --import tsx --test tests/scripts/beadboard-launcher-runtime.test.ts && node --import tsx --test tests/scripts/install-wrappers-contract.test.ts && node --import tsx --test tests/scripts/install-sh-smoke.test.ts && node --import tsx --test tests/scripts/install-legacy-migration.test.ts && node --import tsx --test tests/scripts/installer-ci-contract.test.ts && node --import tsx --test tests/docs/installer-quickstart-contract.test.ts && node --import tsx --test tests/docs/runtime-manager-adr-contract.test.ts && node --import tsx --test tests/cli/beadboard-cli.test.ts && node --import tsx --test tests/skills/beadboard-driver/resolve-bb.test.ts && node --import tsx --test tests/skills/beadboard-driver/session-preflight.test.ts && node --import tsx --test tests/skills/beadboard-driver/generate-agent-name.test.ts && node --import tsx --test tests/skills/beadboard-driver/readiness-report.test.ts && node --import tsx --test tests/skills/beadboard-driver/skill-local-runner.test.ts && node --import tsx --test tests/skills/beadboard-driver/diagnose-env.test.ts && node --import tsx --test tests/skills/beadboard-driver/heal-common-issues.test.ts && node --import tsx --test tests/lib/epic-graph.test.ts && node --import tsx --test tests/components/shared/left-panel-filtering.test.ts && node --import tsx --test tests/hooks/use-beads-subscription-contract.test.ts && node --import tsx --test tests/components/graph/dependency-graph-hide-closed-contract.test.ts && node --import tsx --test tests/components/shared/unified-shell-hide-closed-contract.test.ts",
|
"test": "node --test tests/bootstrap.test.mjs && node --import tsx --test tests/components/shared/base-card.test.tsx && node --import tsx --test tests/components/shared/agent-avatar.test.tsx && node --import tsx --test tests/components/sessions/sessions-header.test.ts && node --import tsx --test tests/components/sessions/agent-station-logic.test.ts && node --import tsx --test tests/lib/parser.test.ts && node --import tsx --test tests/lib/pathing.test.ts && node --import tsx --test tests/components/shared/left-panel.test.tsx && node --import tsx --test tests/components/shared/top-bar.test.tsx && node --import tsx --test tests/components/shared/mobile-nav.test.tsx && node --import tsx --test tests/components/swarm/swarm-card.test.tsx && node --import tsx --test tests/hooks/url-state-integration.test.ts && node --import tsx --test tests/hooks/use-graph-analysis.test.ts && node --import tsx --test tests/components/graph/smart-dag.test.tsx && node --import tsx --test tests/components/unified-shell.test.tsx && node --import tsx --test tests/components/blocked-triage-modal.test.tsx && node --import tsx --test tests/components/graph/graph-node-labels.test.tsx && node --import tsx --test tests/components/graph/graph-node-assign.test.tsx && node --import tsx --test tests/components/graph/graph-node-conversation.test.tsx && node --import tsx --test tests/lib/coord-schema.test.ts && node --import tsx --test tests/lib/install-manifest.test.ts && node --import tsx --test tests/lib/runtime-manager.test.ts && node --import tsx --test tests/lib/coord-events.test.ts && node --import tsx --test tests/api/coord-events-route.test.ts && node --import tsx --test tests/lib/coord-projections-inbox.test.ts && node --import tsx --test tests/lib/coord-projections-reservations.test.ts && node --import tsx --test tests/components/sessions/conversation-drawer-coord.test.tsx && node --import tsx --test tests/scripts/beadboard-launcher.test.ts && node --import tsx --test tests/scripts/beadboard-launcher-runtime.test.ts && node --import tsx --test tests/scripts/install-wrappers-contract.test.ts && node --import tsx --test tests/scripts/install-sh-smoke.test.ts && node --import tsx --test tests/scripts/install-legacy-migration.test.ts && node --import tsx --test tests/scripts/installer-ci-contract.test.ts && node --import tsx --test tests/docs/installer-quickstart-contract.test.ts && node --import tsx --test tests/docs/runtime-manager-adr-contract.test.ts && node --import tsx --test tests/cli/beadboard-cli.test.ts && node --import tsx --test tests/cli/beadboard-bin-routing.test.ts && node --import tsx --test tests/skills/beadboard-driver/resolve-bb.test.ts && node --import tsx --test tests/skills/beadboard-driver/session-preflight.test.ts && node --import tsx --test tests/skills/beadboard-driver/generate-agent-name.test.ts && node --import tsx --test tests/skills/beadboard-driver/readiness-report.test.ts && node --import tsx --test tests/skills/beadboard-driver/skill-local-runner.test.ts && node --import tsx --test tests/skills/beadboard-driver/diagnose-env.test.ts && node --import tsx --test tests/skills/beadboard-driver/heal-common-issues.test.ts && node --import tsx --test tests/lib/epic-graph.test.ts && node --import tsx --test tests/components/shared/left-panel-filtering.test.ts && node --import tsx --test tests/hooks/use-beads-subscription-contract.test.ts && node --import tsx --test tests/components/graph/dependency-graph-hide-closed-contract.test.ts && node --import tsx --test tests/components/shared/unified-shell-hide-closed-contract.test.ts",
|
||||||
"video": "remotion preview src/video/index.ts",
|
"video": "remotion preview src/video/index.ts",
|
||||||
"video:render": "remotion render src/video/index.ts Main out/video.mp4",
|
"video:render": "remotion render src/video/index.ts Main out/video.mp4",
|
||||||
"video:thumbnail": "remotion still src/video/index.ts Main out/thumbnail.png --frame=60"
|
"video:thumbnail": "remotion still src/video/index.ts Main out/thumbnail.png --frame=60"
|
||||||
|
|
|
||||||
20
tests/cli/beadboard-bin-routing.test.ts
Normal file
20
tests/cli/beadboard-bin-routing.test.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { execFile } from 'node:child_process';
|
||||||
|
import { promisify } from 'node:util';
|
||||||
|
|
||||||
|
const execFileAsync = promisify(execFile);
|
||||||
|
const binPath = path.resolve('bin/beadboard.js');
|
||||||
|
|
||||||
|
test('bin routes status --json to launcher runtime command', async () => {
|
||||||
|
try {
|
||||||
|
const { stdout } = await execFileAsync(process.execPath, [binPath, 'status', '--json']);
|
||||||
|
const payload = JSON.parse(stdout);
|
||||||
|
assert.equal(payload.command, 'status');
|
||||||
|
} catch (error) {
|
||||||
|
const stdout = (error as { stdout?: string }).stdout || '';
|
||||||
|
const payload = stdout ? JSON.parse(stdout) : null;
|
||||||
|
assert.equal(payload?.command, 'status');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -8,8 +8,18 @@ const execFileAsync = promisify(execFile);
|
||||||
const launcherPath = path.resolve('install/beadboard.mjs');
|
const launcherPath = path.resolve('install/beadboard.mjs');
|
||||||
|
|
||||||
test('status --json reports runtime root and install mode', async () => {
|
test('status --json reports runtime root and install mode', async () => {
|
||||||
const { stdout } = await execFileAsync(process.execPath, [launcherPath, 'status', '--json']);
|
let stdout = '';
|
||||||
|
try {
|
||||||
|
({ stdout } = await execFileAsync(process.execPath, [launcherPath, 'status', '--json']));
|
||||||
|
} catch (error) {
|
||||||
|
stdout = (error as { stdout?: string }).stdout || '';
|
||||||
|
}
|
||||||
const payload = JSON.parse(stdout);
|
const payload = JSON.parse(stdout);
|
||||||
assert.ok(payload.runtimeRoot);
|
assert.ok(payload.runtimeRoot);
|
||||||
assert.ok(payload.installMode);
|
assert.ok(payload.installMode);
|
||||||
|
assert.ok(payload.bd);
|
||||||
|
assert.equal(typeof payload.bd.available, 'boolean');
|
||||||
|
assert.ok('path' in payload.bd);
|
||||||
|
assert.ok(payload.bd.project);
|
||||||
|
assert.equal(typeof payload.bd.project.hasBeadsDir, 'boolean');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue