topchester-ai 0.60.0 → 0.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as runTopchesterCli } from "./cli-BCDXfYWi.mjs";
2
+ import { t as runTopchesterCli } from "./cli-YPKTdpQH.mjs";
3
3
  //#region src/bin.ts
4
4
  await runTopchesterCli();
5
5
  //#endregion
@@ -6555,6 +6555,37 @@ async function addProjectBashAllowExactRule(workspaceRoot, command) {
6555
6555
  allowExact
6556
6556
  };
6557
6557
  }
6558
+ async function addMcpStdioServerConfig(configPath, options) {
6559
+ const serverName = options.serverName.trim();
6560
+ if (!isValidMcpServerName(serverName)) throw new Error(`invalid MCP server name "${options.serverName}" (use letters, numbers, "-", "_")`);
6561
+ const command = options.command.trim();
6562
+ if (!command) throw new Error("MCP stdio command is required.");
6563
+ const config = readConfigObject(configPath);
6564
+ const mcp = ensurePlainObjectProperty(config, "mcp");
6565
+ const replaced = mcp[serverName] !== void 0;
6566
+ const env = options.env ?? {};
6567
+ const server = {
6568
+ type: "stdio",
6569
+ command,
6570
+ args: options.args ?? [],
6571
+ ...Object.keys(env).length > 0 ? { env } : {}
6572
+ };
6573
+ mcp[serverName] = server;
6574
+ mkdirSync(dirname(configPath), {
6575
+ recursive: true,
6576
+ mode: 448
6577
+ });
6578
+ parseConfigFile(configPath, config);
6579
+ await writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`);
6580
+ return {
6581
+ path: configPath,
6582
+ serverName,
6583
+ command,
6584
+ args: server.args,
6585
+ env,
6586
+ replaced
6587
+ };
6588
+ }
6558
6589
  function readProjectConfigObject(configPath) {
6559
6590
  return readConfigObject(configPath);
6560
6591
  }
@@ -6592,6 +6623,9 @@ function ensureStringArrayProperty(parent, key) {
6592
6623
  if (!Array.isArray(value) || !value.every((entry) => typeof entry === "string")) throw new Error(`Invalid Topchester config property '${key}': expected a string array.`);
6593
6624
  return value;
6594
6625
  }
6626
+ function isValidMcpServerName(name) {
6627
+ return name.length > 0 && /^[A-Za-z0-9_-]+$/u.test(name);
6628
+ }
6595
6629
  function readConfigFile(path) {
6596
6630
  try {
6597
6631
  return parseJsonc(readFileSync(path, "utf8"));
@@ -15729,6 +15763,25 @@ function createTopchesterProgram() {
15729
15763
  process.exitCode = 1;
15730
15764
  }
15731
15765
  });
15766
+ program.command("mcp").description("manage MCP servers").command("add").usage("[options] <server-name> -- <stdio server-command>").description("add or replace a stdio MCP server").argument("<server-name>", "server name").argument("<command...>", "stdio server command after --").option("--env <KEY=VALUE>", "environment variable for the server process", collectEnvPair, {}).addHelpText("after", formatMcpAddHelp).action(async (serverName, commandParts, options) => {
15767
+ try {
15768
+ const [command, ...args] = commandParts;
15769
+ if (!command) throw new Error("Usage: topchester mcp add <server-name> -- <stdio server-command>");
15770
+ const result = await addMcpStdioServerConfig(getWritableConfigPathFromProgram(program), {
15771
+ serverName,
15772
+ command,
15773
+ args,
15774
+ env: options.env
15775
+ });
15776
+ console.log(`${result.replaced ? "Updated" : "Added"} MCP stdio server "${result.serverName}".`);
15777
+ console.log(`config: ${result.path}`);
15778
+ console.log(`command: ${[result.command, ...result.args].join(" ")}`);
15779
+ if (Object.keys(result.env).length > 0) console.log(`env: ${Object.keys(result.env).join(", ")}`);
15780
+ } catch (error) {
15781
+ console.error(formatStartupError(error));
15782
+ process.exitCode = 1;
15783
+ }
15784
+ });
15732
15785
  program.command("run").description("run one prompt or slash command without opening the TUI").argument("<prompt...>", "prompt text or slash command").option("--model <model>", "override the agent.primary model for this run").option("--timeout <ms>", "timeout for the run in milliseconds", parsePositiveInteger).option("--json", "write JSONL run events to stdout").option("--output-json <path>", "write JSONL run events to a file").action(async (promptParts, options) => {
15733
15786
  const context = createContextFromOptions(program);
15734
15787
  const globalOptions = program.opts();
@@ -15876,6 +15929,17 @@ function formatAuthLoginHelp() {
15876
15929
  " Topchester prints a browser URL and one-time code, waits for approval, then stores tokens in the global auth store."
15877
15930
  ].join("\n");
15878
15931
  }
15932
+ function formatMcpAddHelp() {
15933
+ return [
15934
+ "",
15935
+ ui.label("Examples:"),
15936
+ " topchester mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem .",
15937
+ " topchester mcp add github --env GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxx -- npx -y @modelcontextprotocol/server-github",
15938
+ "",
15939
+ ui.label("What happens:"),
15940
+ " Writes to --config when provided, otherwise to the global user config."
15941
+ ].join("\n");
15942
+ }
15879
15943
  function formatAuthLoginUsageError(reason) {
15880
15944
  return [
15881
15945
  ui.error(reason),
@@ -15950,6 +16014,10 @@ function getContextOptionsFromProgram(program) {
15950
16014
  devFlags: options.dev
15951
16015
  };
15952
16016
  }
16017
+ function getWritableConfigPathFromProgram(program) {
16018
+ const options = program.opts();
16019
+ return options.config ? isAbsolute(options.config) ? options.config : resolve(cwd(), options.config) : getGlobalTopchesterConfigPath();
16020
+ }
15953
16021
  async function executeKbSearchCommand(program, queryParts, options) {
15954
16022
  const context = createContextFromOptions(program);
15955
16023
  const query = queryParts.join(" ");
@@ -15983,6 +16051,16 @@ function formatStartupError(error) {
15983
16051
  function collectDevFlag(flag, flags) {
15984
16052
  return [...flags, flag];
15985
16053
  }
16054
+ function collectEnvPair(raw, env) {
16055
+ const separatorIndex = raw.indexOf("=");
16056
+ if (separatorIndex <= 0) throw new Error("Environment entries must be in KEY=VALUE form.");
16057
+ const key = raw.slice(0, separatorIndex).trim();
16058
+ if (!key) throw new Error("Environment entries must be in KEY=VALUE form.");
16059
+ return {
16060
+ ...env,
16061
+ [key]: raw.slice(separatorIndex + 1)
16062
+ };
16063
+ }
15986
16064
  function parsePositiveInteger(value) {
15987
16065
  const parsed = Number(value);
15988
16066
  if (!Number.isInteger(parsed) || parsed <= 0) throw new Error("Expected a positive integer.");
@@ -16004,4 +16082,4 @@ function formatDryRunSyncStatus(status) {
16004
16082
  //#endregion
16005
16083
  export { runTopchesterCli as t };
16006
16084
 
16007
- //# sourceMappingURL=cli-BCDXfYWi.mjs.map
16085
+ //# sourceMappingURL=cli-YPKTdpQH.mjs.map