Files
mcpctl/scripts/generate-prime-agent-extension.ts
Michal a9fcd83ed8
Some checks failed
CI/CD / lint (pull_request) Successful in 1m11s
CI/CD / test (pull_request) Successful in 1m24s
CI/CD / typecheck (pull_request) Successful in 3m20s
CI/CD / smoke (pull_request) Failing after 2m1s
CI/CD / build (pull_request) Successful in 2m37s
CI/CD / publish (pull_request) Has been skipped
refactor(prime-agent): extract the /mcpctl switcher to typechecked source; pi --dry-run; docs
The prime-agent switcher existed only as a 275-line string literal inside
prime-agent-extension.ts, so nothing typechecked or linted it — the exact gap
that let a wrong ctx.ui.select() option shape ship in the pi extension. It now
lives at src/prime-agent-ext/mcpctl-switch.ts with a generator, a tsconfig
checking it against the real @earendil-works/pi-coding-agent types, eslint
coverage and an embed-freshness test, matching pi and opencode.

The extraction was verified byte-identical before any edit, so the behaviour
shipped today is exactly what was captured. Linting it then found six problems
in code nothing had ever checked: object-truthiness null guards, a nullable
string conditional and a missing return type. All behaviour-preserving to fix,
but exactly the class of thing that ships silently when nothing is looking.

Also:

  - `config pi` gains --dry-run, the last agent without it.
  - The SessionStart hook installer now drops untagged duplicates of its own
    exact command — rows left behind before the marker existed, or by a suite
    that used to write into a real ~/.claude. Invisible in the UI; they just run
    the sync twice per session. A hook the user wrote is never touched, even one
    calling `mcpctl skills sync` with different flags.
  - docs/claude-integration.md and docs/prime-agent-extension.md, the two
    integrations that had no page.

prime-agent deliberately keeps its per-project MCP entry name rather than the
constant `mcpctl` claude and opencode now use: its switcher already unmounts the
previous project, so it never accumulates entries, and re-keying auth.json from
mcp:<project> to mcp:mcpctl would give up per-project token caching and needs a
migration. Documented as its own change rather than folded in here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-09 19:20:36 +01:00

42 lines
1.9 KiB
JavaScript

#!/usr/bin/env node
/**
* Generates `src/cli/src/config/prime-agent-extension.ts`, which embeds the
* prime-agent `/mcpctl` switcher as a string constant — the same arrangement
* the pi and opencode extensions use.
*
* The switcher used to live *only* as that string literal, with no source file
* behind it, so nothing typechecked or linted it. Now `src/prime-agent-ext/`
* holds the real source and this script produces the embed, so the file the CLI
* writes into ~/.prime/agent/extensions/ is always exactly what was checked.
*
* Regenerate after editing the extension source:
* npx tsx scripts/generate-prime-agent-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 extDir = join(root, 'src', 'prime-agent-ext');
const SOURCE = readFileSync(join(extDir, 'mcpctl-switch.ts'), 'utf-8');
const out = `/**
* The source of the \`/mcpctl\` project-switcher extension, exported as a string
* so \`mcpctl config prime-agent\` can install it into prime-agent's auto-
* discovered extensions directory (\`~/.prime/agent/extensions/\`).
*
* DO NOT EDIT BY HAND. Generated by
* \`npx tsx scripts/generate-prime-agent-extension.ts\` from
* \`src/prime-agent-ext/mcpctl-switch.ts\` — edit that instead, so the change is
* typechecked before it ships. The installed file is this exact source
* (verbatim), so the extension the CLI writes is always the one that ran.
*/
export const MCPCTL_SWITCH_EXTENSION_FILENAME = 'mcpctl-switch.ts';
export const MCPCTL_SWITCH_EXTENSION = ${JSON.stringify(SOURCE)};
`;
mkdirSync(dirname(join(root, 'src', 'cli', 'src', 'config')), { recursive: true });
writeFileSync(join(root, 'src', 'cli', 'src', 'config', 'prime-agent-extension.ts'), out);
console.log('wrote src/cli/src/config/prime-agent-extension.ts');