feat(installer): add runtime manager core library
This commit is contained in:
parent
a3ca82bb5a
commit
0f33a653d3
3 changed files with 56 additions and 1 deletions
|
|
@ -9,7 +9,7 @@
|
|||
"start": "next start",
|
||||
"lint": "eslint .",
|
||||
"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/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",
|
||||
"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/install-wrappers-contract.test.ts && node --import tsx --test tests/scripts/install-sh-smoke.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/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: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"
|
||||
|
|
|
|||
41
src/lib/runtime-manager.ts
Normal file
41
src/lib/runtime-manager.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import path from 'node:path';
|
||||
|
||||
const SEMVER_PATTERN = /^v?\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;
|
||||
|
||||
function ensureNonEmpty(value: string, field: string): string {
|
||||
const normalized = value.trim();
|
||||
if (!normalized) {
|
||||
throw new Error(`${field} must be a non-empty string`);
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
export function normalizeVersion(version: string): string {
|
||||
const normalized = ensureNonEmpty(version, 'version');
|
||||
if (!SEMVER_PATTERN.test(normalized)) {
|
||||
throw new Error(`version must be semver-compatible: ${version}`);
|
||||
}
|
||||
return normalized.startsWith('v') ? normalized.slice(1) : normalized;
|
||||
}
|
||||
|
||||
export function resolveInstallHome(env: NodeJS.ProcessEnv): string {
|
||||
const home = env.BB_INSTALL_HOME ?? env.HOME ?? env.USERPROFILE;
|
||||
return ensureNonEmpty(home ?? '', 'install home');
|
||||
}
|
||||
|
||||
export function getRuntimePaths(home: string, version: string) {
|
||||
const installHome = ensureNonEmpty(home, 'home');
|
||||
const normalizedVersion = normalizeVersion(version);
|
||||
const beadboardHome = path.join(installHome, '.beadboard');
|
||||
const runtimeBase = path.join(beadboardHome, 'runtime');
|
||||
|
||||
return {
|
||||
installHome,
|
||||
beadboardHome,
|
||||
runtimeBase,
|
||||
runtimeRoot: path.join(runtimeBase, normalizedVersion),
|
||||
runtimeCurrentMetadata: path.join(runtimeBase, 'current.json'),
|
||||
shimDir: path.join(beadboardHome, 'bin'),
|
||||
shimNames: ['bb', 'beadboard'] as const,
|
||||
};
|
||||
}
|
||||
14
tests/lib/runtime-manager.test.ts
Normal file
14
tests/lib/runtime-manager.test.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { getRuntimePaths, normalizeVersion } from '../../src/lib/runtime-manager';
|
||||
|
||||
test('normalizeVersion supports semver and rejects empty', () => {
|
||||
assert.equal(normalizeVersion('1.2.3'), '1.2.3');
|
||||
assert.throws(() => normalizeVersion(''));
|
||||
});
|
||||
|
||||
test('getRuntimePaths builds ~/.beadboard/runtime/<version> layout', () => {
|
||||
const p = getRuntimePaths('/tmp/home', '1.2.3');
|
||||
assert.match(p.runtimeRoot, /runtime\/1\.2\.3$/);
|
||||
assert.match(p.shimDir, /\.beadboard\/bin$/);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue