Complete port of the ~2000 LOC mosaic install wizard from v0. Migrates all 27 source files across the prompter, config, platform, template, runtime, skills, and stages subsystems to v1 ESM/NodeNext conventions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
83 lines
1.9 KiB
TypeScript
83 lines
1.9 KiB
TypeScript
import { execSync } from 'node:child_process';
|
|
import { platform } from 'node:os';
|
|
import type { RuntimeName } from '../types.js';
|
|
|
|
export interface RuntimeInfo {
|
|
name: RuntimeName;
|
|
label: string;
|
|
installed: boolean;
|
|
path?: string;
|
|
version?: string;
|
|
installHint: string;
|
|
}
|
|
|
|
const RUNTIME_DEFS: Record<
|
|
RuntimeName,
|
|
{ label: string; command: string; versionFlag: string; installHint: string }
|
|
> = {
|
|
claude: {
|
|
label: 'Claude Code',
|
|
command: 'claude',
|
|
versionFlag: '--version',
|
|
installHint: 'npm install -g @anthropic-ai/claude-code',
|
|
},
|
|
codex: {
|
|
label: 'Codex',
|
|
command: 'codex',
|
|
versionFlag: '--version',
|
|
installHint: 'npm install -g @openai/codex',
|
|
},
|
|
opencode: {
|
|
label: 'OpenCode',
|
|
command: 'opencode',
|
|
versionFlag: 'version',
|
|
installHint: 'See https://opencode.ai for install instructions',
|
|
},
|
|
};
|
|
|
|
export function detectRuntime(name: RuntimeName): RuntimeInfo {
|
|
const def = RUNTIME_DEFS[name];
|
|
const isWindows = platform() === 'win32';
|
|
const whichCmd = isWindows ? `where ${def.command} 2>nul` : `which ${def.command} 2>/dev/null`;
|
|
|
|
try {
|
|
const pathOutput =
|
|
execSync(whichCmd, {
|
|
encoding: 'utf-8',
|
|
timeout: 5000,
|
|
})
|
|
.trim()
|
|
.split('\n')[0] ?? '';
|
|
|
|
let version: string | undefined;
|
|
try {
|
|
version = execSync(`${def.command} ${def.versionFlag} 2>/dev/null`, {
|
|
encoding: 'utf-8',
|
|
timeout: 5000,
|
|
}).trim();
|
|
} catch {
|
|
// Version detection is optional
|
|
}
|
|
|
|
return {
|
|
name,
|
|
label: def.label,
|
|
installed: true,
|
|
path: pathOutput,
|
|
version,
|
|
installHint: def.installHint,
|
|
};
|
|
} catch {
|
|
return {
|
|
name,
|
|
label: def.label,
|
|
installed: false,
|
|
installHint: def.installHint,
|
|
};
|
|
}
|
|
}
|
|
|
|
export function getInstallInstructions(name: RuntimeName): string {
|
|
return RUNTIME_DEFS[name].installHint;
|
|
}
|