#!/usr/bin/env node /** * Generates `src/cli/src/config/pi-extension.ts` which embeds the pi extension * sources (`mcpctl-pi.ts` + `mcp-http.ts`) as string constants, mirroring how * prime-agent's `/mcpctl` switcher is embedded (`prime-agent-extension.ts`). * * Embedding matters: `mcpctl config pi` must work from an installed binary * that has no access to the source tree. The installed extension files are this * exact embedded source, so what the CLI ships is always what pi runs. * * Regenerate after editing the extension sources: * npx tsx scripts/generate-pi-extension.ts */ import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'; import { dirname, join } from 'node:path'; const scriptsDir = import.meta.dirname; const root = join(scriptsDir, '..'); const piExtDir = join(root, 'src', 'pi-ext'); const MAIN = readFileSync(join(piExtDir, 'mcpctl-pi.ts'), 'utf-8'); const HTTP = readFileSync(join(piExtDir, 'mcp-http.ts'), 'utf-8'); function embed(src) { // JSON.stringify yields a quoted string literal we can inline directly. return JSON.stringify(src); } const out = `/** * Embedded source of the mcpctl pi extension — DO NOT EDIT BY HAND. * Generated by \`npx tsx scripts/generate-pi-extension.ts\` from * \`src/pi-ext/mcpctl-pi.ts\` and \`src/pi-ext/mcp-http.ts\`. * * \`mcpctl config pi\` writes these verbatim into ~/.pi/agent/extensions/mcpctl/ * (and registers them), so an installed binary with no source tree can still * provision a working pi integration. */ export const PI_EXTENSION_FILENAMES = ['mcpctl-pi.ts', 'mcp-http.ts'] as const; export const PI_EXTENSION_FILES: Record = { 'mcpctl-pi.ts': ${embed(MAIN)}, 'mcp-http.ts': ${embed(HTTP)}, }; `; mkdirSync(dirname(join(root, 'src', 'cli', 'src', 'config')), { recursive: true }); writeFileSync(join(root, 'src', 'cli', 'src', 'config', 'pi-extension.ts'), out); console.log('wrote src/cli/src/config/pi-extension.ts');