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
|
@@ -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-
|
|
16085
|
+
//# sourceMappingURL=cli-YPKTdpQH.mjs.map
|