Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions cli/src/lib/mcp-build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,19 @@ function mcpDir(root: string | null): string | null {
return dir;
}

// On Windows npm/npx are .cmd shims, which CreateProcess cannot launch directly
// (ENOENT), so they need shell: true — but the shell re-splits arguments on
// spaces, so paths must be quoted before they reach it.
const needsShell = process.platform === 'win32';

function runTool(cmd: string, args: string[], opts: { cwd?: string } = {}) {
const finalArgs = needsShell ? args.map((a) => (/\s/.test(a) ? `"${a}"` : a)) : args;
return spawnSync(cmd, finalArgs, { ...opts, stdio: 'inherit', shell: needsShell });
}

/** Run an npm script in a directory, streaming output. Returns true on success. */
function npm(cwd: string, args: string[]): boolean {
const r = spawnSync('npm', args, { cwd, stdio: 'inherit' });
return r.status === 0;
return runTool('npm', args, { cwd }).status === 0;
}

/** Ensure node_modules is present in mcp/ before a codegen/build that needs it. */
Expand Down Expand Up @@ -73,7 +82,8 @@ function libExt(): string {
function opencvLibDir(root: string): string | null {
const candidates =
process.platform === 'darwin' ? [['Darwin', 'Release', 'macos', 'bin']] :
process.platform === 'win32' ? [['Windows', 'Release', 'x64', 'bin'], ['Windows', 'x64', 'vc17', 'bin']] :
// Must match the layout extract.ts writes: shared/opencv/Windows/x86_64/Release/bin
process.platform === 'win32' ? [['Windows', 'x86_64', 'Release', 'bin'], ['Windows', 'Release', 'x64', 'bin'], ['Windows', 'x64', 'vc17', 'bin']] :
[['Linux', 'Release', 'x64', 'lib'], ['Linux', 'Release', 'aarch64', 'lib']];
for (const rel of candidates) {
const p = join(root, 'shared', 'opencv', ...rel);
Expand Down Expand Up @@ -212,14 +222,14 @@ export async function packMcp(root: string | null): Promise<void> {

console.log(`${symbols.arrow} Installing production dependencies…`);
const install = existsSync(join(stage, 'package-lock.json'))
? spawnSync('npm', ['ci', '--omit=dev'], { cwd: stage, stdio: 'inherit' })
: spawnSync('npm', ['install', '--omit=dev'], { cwd: stage, stdio: 'inherit' });
? runTool('npm', ['ci', '--omit=dev'], { cwd: stage })
: runTool('npm', ['install', '--omit=dev'], { cwd: stage });
if (install.status !== 0) { fail('Production install failed (see output above).'); return; }

const out = join(dir, 'alpha-camera.mcpb');
if (existsSync(out)) rmSync(out);
console.log(`${symbols.arrow} Packing the MCP bundle…`);
const r = spawnSync('npx', ['--yes', '@anthropic-ai/mcpb', 'pack', stage, out], { stdio: 'inherit' });
const r = runTool('npx', ['--yes', '@anthropic-ai/mcpb', 'pack', stage, out]);
if (r.status !== 0 || !existsSync(out)) { fail('mcpb pack failed (see output above).'); return; }

printBlank();
Expand Down
Loading