topchester-ai 0.60.0 → 0.62.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"));
|
|
@@ -9140,6 +9174,17 @@ const messagePayloadSchema = z.object({
|
|
|
9140
9174
|
text: z.string(),
|
|
9141
9175
|
meta: jsonValueSchema.optional()
|
|
9142
9176
|
});
|
|
9177
|
+
const permissionAutoApprovedPayloadSchema = z.object({
|
|
9178
|
+
kind: z.literal("permission_auto_approved"),
|
|
9179
|
+
permissionMode: z.literal("bash"),
|
|
9180
|
+
approvalMode: z.literal("auto_allow"),
|
|
9181
|
+
toolName: z.string(),
|
|
9182
|
+
command: z.string(),
|
|
9183
|
+
workdir: z.string(),
|
|
9184
|
+
reason: z.string(),
|
|
9185
|
+
label: z.string(),
|
|
9186
|
+
toolCallId: z.string().optional()
|
|
9187
|
+
});
|
|
9143
9188
|
const toolCallPayloadSchema = z.object({
|
|
9144
9189
|
kind: z.literal("tool_call"),
|
|
9145
9190
|
label: z.string(),
|
|
@@ -9217,6 +9262,7 @@ const subagentFailedPayloadSchema = subagentLifecycleBasePayloadSchema.extend({
|
|
|
9217
9262
|
});
|
|
9218
9263
|
const sessionEventPayloadSchema = z.discriminatedUnion("kind", [
|
|
9219
9264
|
messagePayloadSchema,
|
|
9265
|
+
permissionAutoApprovedPayloadSchema,
|
|
9220
9266
|
toolCallPayloadSchema,
|
|
9221
9267
|
hookStatusPayloadSchema,
|
|
9222
9268
|
taskPlanPayloadSchema,
|
|
@@ -9469,6 +9515,7 @@ function rehydrateSession(events) {
|
|
|
9469
9515
|
});
|
|
9470
9516
|
if (event.role === "user") visibleOnlyActionValues = /* @__PURE__ */ new Set();
|
|
9471
9517
|
break;
|
|
9518
|
+
case "permission_auto_approved": break;
|
|
9472
9519
|
case "tool_call":
|
|
9473
9520
|
messages.push(toolCallMessage(event.call, event.label, void 0, event.diff));
|
|
9474
9521
|
break;
|
|
@@ -10192,6 +10239,14 @@ const agentEvent = {
|
|
|
10192
10239
|
meta
|
|
10193
10240
|
};
|
|
10194
10241
|
},
|
|
10242
|
+
permissionAutoApproved(options) {
|
|
10243
|
+
return {
|
|
10244
|
+
type: "permission_auto_approved",
|
|
10245
|
+
approvalMode: "auto_allow",
|
|
10246
|
+
label: `auto-approved ${options.permissionMode} permission: ${options.command}`,
|
|
10247
|
+
...options
|
|
10248
|
+
};
|
|
10249
|
+
},
|
|
10195
10250
|
toolCall(call, label, diff) {
|
|
10196
10251
|
return diff === void 0 ? {
|
|
10197
10252
|
type: "tool_call",
|
|
@@ -12220,6 +12275,17 @@ function runtimeEventToSessionPayload(event) {
|
|
|
12220
12275
|
text: event.text,
|
|
12221
12276
|
...event.meta === void 0 ? {} : { meta: event.meta }
|
|
12222
12277
|
};
|
|
12278
|
+
case "permission_auto_approved": return {
|
|
12279
|
+
kind: "permission_auto_approved",
|
|
12280
|
+
permissionMode: event.permissionMode,
|
|
12281
|
+
approvalMode: event.approvalMode,
|
|
12282
|
+
toolName: event.toolName,
|
|
12283
|
+
command: event.command,
|
|
12284
|
+
workdir: event.workdir,
|
|
12285
|
+
reason: event.reason,
|
|
12286
|
+
label: event.label,
|
|
12287
|
+
...event.toolCallId === void 0 ? {} : { toolCallId: event.toolCallId }
|
|
12288
|
+
};
|
|
12223
12289
|
case "tool_call": return {
|
|
12224
12290
|
kind: "tool_call",
|
|
12225
12291
|
label: event.label,
|
|
@@ -13514,7 +13580,13 @@ var TopchesterAgentRuntime = class TopchesterAgentRuntime {
|
|
|
13514
13580
|
approvedCommands,
|
|
13515
13581
|
events: []
|
|
13516
13582
|
};
|
|
13517
|
-
if (!isBashApprovalRequired(decision)
|
|
13583
|
+
if (!isBashApprovalRequired(decision)) return {
|
|
13584
|
+
cancelled: false,
|
|
13585
|
+
approvedCommands,
|
|
13586
|
+
events: []
|
|
13587
|
+
};
|
|
13588
|
+
const approvalMode = options.userApprovalMode ?? "interactive";
|
|
13589
|
+
if (approvalMode !== "auto_allow" && !options.requestBashApproval) return {
|
|
13518
13590
|
cancelled: false,
|
|
13519
13591
|
approvedCommands,
|
|
13520
13592
|
events: []
|
|
@@ -13525,7 +13597,11 @@ var TopchesterAgentRuntime = class TopchesterAgentRuntime {
|
|
|
13525
13597
|
permission_mode: "bash",
|
|
13526
13598
|
command,
|
|
13527
13599
|
workdir: parsed.data.workdir,
|
|
13528
|
-
reason: decision.reason
|
|
13600
|
+
reason: decision.reason,
|
|
13601
|
+
...approvalMode === "auto_allow" ? {
|
|
13602
|
+
approval_mode: "auto_allow",
|
|
13603
|
+
auto_approved: true
|
|
13604
|
+
} : {}
|
|
13529
13605
|
}), {
|
|
13530
13606
|
toolName: call.tool,
|
|
13531
13607
|
abortSignal
|
|
@@ -13542,6 +13618,36 @@ var TopchesterAgentRuntime = class TopchesterAgentRuntime {
|
|
|
13542
13618
|
reason: actionRequiredHook.blocked.message,
|
|
13543
13619
|
events
|
|
13544
13620
|
};
|
|
13621
|
+
if (approvalMode === "auto_allow") {
|
|
13622
|
+
const event = agentEvent.permissionAutoApproved({
|
|
13623
|
+
permissionMode: "bash",
|
|
13624
|
+
toolName: call.tool,
|
|
13625
|
+
...toolCallId === void 0 ? {} : { toolCallId },
|
|
13626
|
+
command,
|
|
13627
|
+
workdir: parsed.data.workdir,
|
|
13628
|
+
reason: decision.reason
|
|
13629
|
+
});
|
|
13630
|
+
this.context.logger.info({
|
|
13631
|
+
event: "permission_auto_approved",
|
|
13632
|
+
approvalMode: "auto_allow",
|
|
13633
|
+
permissionMode: "bash",
|
|
13634
|
+
toolName: call.tool,
|
|
13635
|
+
toolCallId,
|
|
13636
|
+
command,
|
|
13637
|
+
workdir: parsed.data.workdir,
|
|
13638
|
+
reason: decision.reason
|
|
13639
|
+
}, "permission request auto-approved");
|
|
13640
|
+
return {
|
|
13641
|
+
cancelled: false,
|
|
13642
|
+
approvedCommands: [...approvedCommands, command],
|
|
13643
|
+
events: [...events, event]
|
|
13644
|
+
};
|
|
13645
|
+
}
|
|
13646
|
+
if (!options.requestBashApproval) return {
|
|
13647
|
+
cancelled: false,
|
|
13648
|
+
approvedCommands,
|
|
13649
|
+
events
|
|
13650
|
+
};
|
|
13545
13651
|
const approval = await options.requestBashApproval({
|
|
13546
13652
|
command,
|
|
13547
13653
|
workdir: parsed.data.workdir,
|
|
@@ -13704,6 +13810,7 @@ function createInstructionContextEvents(sources, persistedKeys) {
|
|
|
13704
13810
|
function renderRuntimeEvent(event) {
|
|
13705
13811
|
switch (event.type) {
|
|
13706
13812
|
case "message": return [event.role === "assistant" ? agentMessage(event.text, event.meta) : systemMessage(event.text)];
|
|
13813
|
+
case "permission_auto_approved": return [systemMessage(event.label)];
|
|
13707
13814
|
case "tool_call": return [toolCallMessage(event.call, event.label, void 0, event.diff)];
|
|
13708
13815
|
case "hook_status": return [hookStatusMessage(event.label, event.eventName, event.statusMessage)];
|
|
13709
13816
|
case "knowledge_status": return [systemMessage([`KB status: ${formatKnowledgePathStatus(event.status)}${formatKbPathSource(event.status)}`, event.guidance].filter(Boolean).join("\n"))];
|
|
@@ -15238,11 +15345,13 @@ async function executeRunCommand(context, options) {
|
|
|
15238
15345
|
promptLength: options.prompt.length,
|
|
15239
15346
|
json: Boolean(options.json),
|
|
15240
15347
|
outputJson: options.outputJson,
|
|
15241
|
-
timeoutMs
|
|
15348
|
+
timeoutMs,
|
|
15349
|
+
dangerouslyAutoApprove: Boolean(options.dangerouslyAutoApprove)
|
|
15242
15350
|
}, "run started");
|
|
15243
15351
|
pushJson(jsonEvents, runId, session.sessionId, "run.started", {
|
|
15244
15352
|
workspaceRoot: runContext.workspaceRoot,
|
|
15245
|
-
timeoutMs
|
|
15353
|
+
timeoutMs,
|
|
15354
|
+
dangerouslyAutoApprove: Boolean(options.dangerouslyAutoApprove)
|
|
15246
15355
|
});
|
|
15247
15356
|
try {
|
|
15248
15357
|
if (!options.resume) await persistStartupMessages(session, runContext);
|
|
@@ -15297,7 +15406,10 @@ async function executeRunCommand(context, options) {
|
|
|
15297
15406
|
text: options.prompt,
|
|
15298
15407
|
inputType: "prompt"
|
|
15299
15408
|
});
|
|
15300
|
-
for await (const event of runtime.submitMessageStream(conversation, options.prompt, abortController.signal, {
|
|
15409
|
+
for await (const event of runtime.submitMessageStream(conversation, options.prompt, abortController.signal, {
|
|
15410
|
+
session,
|
|
15411
|
+
userApprovalMode: options.dangerouslyAutoApprove ? "auto_allow" : "interactive"
|
|
15412
|
+
})) await applyRuntimeEvent({
|
|
15301
15413
|
event,
|
|
15302
15414
|
session,
|
|
15303
15415
|
jsonEvents,
|
|
@@ -15378,6 +15490,10 @@ function printPlainEvent(event) {
|
|
|
15378
15490
|
console.log(event.text);
|
|
15379
15491
|
return;
|
|
15380
15492
|
}
|
|
15493
|
+
if (event.type === "permission_auto_approved") {
|
|
15494
|
+
console.log(event.label);
|
|
15495
|
+
return;
|
|
15496
|
+
}
|
|
15381
15497
|
if (event.type === "tool_call") {
|
|
15382
15498
|
console.log(event.label);
|
|
15383
15499
|
return;
|
|
@@ -15729,7 +15845,26 @@ function createTopchesterProgram() {
|
|
|
15729
15845
|
process.exitCode = 1;
|
|
15730
15846
|
}
|
|
15731
15847
|
});
|
|
15732
|
-
program.command("
|
|
15848
|
+
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) => {
|
|
15849
|
+
try {
|
|
15850
|
+
const [command, ...args] = commandParts;
|
|
15851
|
+
if (!command) throw new Error("Usage: topchester mcp add <server-name> -- <stdio server-command>");
|
|
15852
|
+
const result = await addMcpStdioServerConfig(getWritableConfigPathFromProgram(program), {
|
|
15853
|
+
serverName,
|
|
15854
|
+
command,
|
|
15855
|
+
args,
|
|
15856
|
+
env: options.env
|
|
15857
|
+
});
|
|
15858
|
+
console.log(`${result.replaced ? "Updated" : "Added"} MCP stdio server "${result.serverName}".`);
|
|
15859
|
+
console.log(`config: ${result.path}`);
|
|
15860
|
+
console.log(`command: ${[result.command, ...result.args].join(" ")}`);
|
|
15861
|
+
if (Object.keys(result.env).length > 0) console.log(`env: ${Object.keys(result.env).join(", ")}`);
|
|
15862
|
+
} catch (error) {
|
|
15863
|
+
console.error(formatStartupError(error));
|
|
15864
|
+
process.exitCode = 1;
|
|
15865
|
+
}
|
|
15866
|
+
});
|
|
15867
|
+
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").option("--dangerously-auto-approve", "auto-approve prompt-gated tool calls for this non-interactive run").action(async (promptParts, options) => {
|
|
15733
15868
|
const context = createContextFromOptions(program);
|
|
15734
15869
|
const globalOptions = program.opts();
|
|
15735
15870
|
try {
|
|
@@ -15739,7 +15874,8 @@ function createTopchesterProgram() {
|
|
|
15739
15874
|
timeoutMs: options.timeout,
|
|
15740
15875
|
json: options.json,
|
|
15741
15876
|
outputJson: options.outputJson,
|
|
15742
|
-
resume: globalOptions.resume
|
|
15877
|
+
resume: globalOptions.resume,
|
|
15878
|
+
dangerouslyAutoApprove: options.dangerouslyAutoApprove
|
|
15743
15879
|
});
|
|
15744
15880
|
} catch (error) {
|
|
15745
15881
|
console.error(formatStartupError(error));
|
|
@@ -15876,6 +16012,17 @@ function formatAuthLoginHelp() {
|
|
|
15876
16012
|
" Topchester prints a browser URL and one-time code, waits for approval, then stores tokens in the global auth store."
|
|
15877
16013
|
].join("\n");
|
|
15878
16014
|
}
|
|
16015
|
+
function formatMcpAddHelp() {
|
|
16016
|
+
return [
|
|
16017
|
+
"",
|
|
16018
|
+
ui.label("Examples:"),
|
|
16019
|
+
" topchester mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem .",
|
|
16020
|
+
" topchester mcp add github --env GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxx -- npx -y @modelcontextprotocol/server-github",
|
|
16021
|
+
"",
|
|
16022
|
+
ui.label("What happens:"),
|
|
16023
|
+
" Writes to --config when provided, otherwise to the global user config."
|
|
16024
|
+
].join("\n");
|
|
16025
|
+
}
|
|
15879
16026
|
function formatAuthLoginUsageError(reason) {
|
|
15880
16027
|
return [
|
|
15881
16028
|
ui.error(reason),
|
|
@@ -15950,6 +16097,10 @@ function getContextOptionsFromProgram(program) {
|
|
|
15950
16097
|
devFlags: options.dev
|
|
15951
16098
|
};
|
|
15952
16099
|
}
|
|
16100
|
+
function getWritableConfigPathFromProgram(program) {
|
|
16101
|
+
const options = program.opts();
|
|
16102
|
+
return options.config ? isAbsolute(options.config) ? options.config : resolve(cwd(), options.config) : getGlobalTopchesterConfigPath();
|
|
16103
|
+
}
|
|
15953
16104
|
async function executeKbSearchCommand(program, queryParts, options) {
|
|
15954
16105
|
const context = createContextFromOptions(program);
|
|
15955
16106
|
const query = queryParts.join(" ");
|
|
@@ -15983,6 +16134,16 @@ function formatStartupError(error) {
|
|
|
15983
16134
|
function collectDevFlag(flag, flags) {
|
|
15984
16135
|
return [...flags, flag];
|
|
15985
16136
|
}
|
|
16137
|
+
function collectEnvPair(raw, env) {
|
|
16138
|
+
const separatorIndex = raw.indexOf("=");
|
|
16139
|
+
if (separatorIndex <= 0) throw new Error("Environment entries must be in KEY=VALUE form.");
|
|
16140
|
+
const key = raw.slice(0, separatorIndex).trim();
|
|
16141
|
+
if (!key) throw new Error("Environment entries must be in KEY=VALUE form.");
|
|
16142
|
+
return {
|
|
16143
|
+
...env,
|
|
16144
|
+
[key]: raw.slice(separatorIndex + 1)
|
|
16145
|
+
};
|
|
16146
|
+
}
|
|
15986
16147
|
function parsePositiveInteger(value) {
|
|
15987
16148
|
const parsed = Number(value);
|
|
15988
16149
|
if (!Number.isInteger(parsed) || parsed <= 0) throw new Error("Expected a positive integer.");
|
|
@@ -16004,4 +16165,4 @@ function formatDryRunSyncStatus(status) {
|
|
|
16004
16165
|
//#endregion
|
|
16005
16166
|
export { runTopchesterCli as t };
|
|
16006
16167
|
|
|
16007
|
-
//# sourceMappingURL=cli-
|
|
16168
|
+
//# sourceMappingURL=cli-DfwFfA-w.mjs.map
|