topchester-ai 0.28.0 → 0.29.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/cli.d.mts +7 -1
- package/dist/cli.mjs +112 -104
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.d.mts
CHANGED
package/dist/cli.mjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { cwd, stderr, stdout } from "node:process";
|
|
4
4
|
import { basename, delimiter, dirname, extname, isAbsolute, join, parse, relative, resolve, sep, win32 } from "node:path";
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
6
|
import { Command } from "commander";
|
|
6
7
|
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
|
|
7
8
|
import { generateText, streamText, tool } from "ai";
|
|
@@ -11,7 +12,6 @@ import { execFile, spawn } from "node:child_process";
|
|
|
11
12
|
import { constants, existsSync, mkdirSync, readFileSync, statSync } from "node:fs";
|
|
12
13
|
import { createHash, randomUUID } from "node:crypto";
|
|
13
14
|
import { parse as parse$1, parseDocument } from "yaml";
|
|
14
|
-
import { fileURLToPath } from "node:url";
|
|
15
15
|
import { homedir } from "node:os";
|
|
16
16
|
import pino from "pino";
|
|
17
17
|
import picomatch from "picomatch";
|
|
@@ -13413,104 +13413,112 @@ function defaultSelfUpdateRunner(command, args) {
|
|
|
13413
13413
|
}
|
|
13414
13414
|
//#endregion
|
|
13415
13415
|
//#region src/cli.ts
|
|
13416
|
-
|
|
13417
|
-
program
|
|
13418
|
-
|
|
13419
|
-
program.
|
|
13420
|
-
|
|
13421
|
-
|
|
13422
|
-
|
|
13423
|
-
|
|
13424
|
-
|
|
13425
|
-
|
|
13426
|
-
|
|
13427
|
-
|
|
13428
|
-
|
|
13429
|
-
|
|
13430
|
-
|
|
13431
|
-
|
|
13432
|
-
|
|
13416
|
+
async function runTopchesterCli(argv = process.argv, options = {}) {
|
|
13417
|
+
const program = createTopchesterProgram();
|
|
13418
|
+
if (options.exitOverride) program.exitOverride();
|
|
13419
|
+
await program.parseAsync(argv);
|
|
13420
|
+
}
|
|
13421
|
+
function createTopchesterProgram() {
|
|
13422
|
+
const program = new Command();
|
|
13423
|
+
program.name("topchester").description("KB-first terminal coding agent").version(getTopchesterVersion());
|
|
13424
|
+
program.option("-c, --config <path>", "explicit config file path").option("--workspace <path>", "workspace root", cwd()).option("--resume <session>", "resume a project session: latest or an exact session id").option("--dev <flag>", "enable a development flag", collectDevFlag, []);
|
|
13425
|
+
program.action(async () => {
|
|
13426
|
+
const context = createContextFromOptions(program);
|
|
13427
|
+
const options = program.opts();
|
|
13428
|
+
try {
|
|
13429
|
+
if (options.resume) {
|
|
13430
|
+
const loaded = await loadSession(context.workspaceRoot, options.resume);
|
|
13431
|
+
const session = await loadSessionForAppend(context.workspaceRoot, loaded.sessionId);
|
|
13432
|
+
const rehydrated = rehydrateSession(loaded.events);
|
|
13433
|
+
await new TopchesterTuiShell(context, void 0, {
|
|
13434
|
+
session,
|
|
13435
|
+
initialMessages: rehydrated.messages,
|
|
13436
|
+
initialTaskPlan: rehydrated.taskPlan
|
|
13437
|
+
}).render();
|
|
13438
|
+
return;
|
|
13439
|
+
}
|
|
13440
|
+
await new TopchesterTuiShell(context).render();
|
|
13441
|
+
} catch (error) {
|
|
13442
|
+
console.error(formatStartupError(error));
|
|
13443
|
+
process.exitCode = 1;
|
|
13433
13444
|
}
|
|
13434
|
-
|
|
13435
|
-
|
|
13436
|
-
|
|
13437
|
-
|
|
13438
|
-
|
|
13439
|
-
});
|
|
13440
|
-
program.command("
|
|
13441
|
-
|
|
13442
|
-
|
|
13443
|
-
|
|
13444
|
-
|
|
13445
|
-
|
|
13446
|
-
|
|
13447
|
-
|
|
13448
|
-
|
|
13449
|
-
|
|
13450
|
-
|
|
13451
|
-
|
|
13452
|
-
|
|
13453
|
-
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
|
|
13457
|
-
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
|
|
13461
|
-
|
|
13462
|
-
|
|
13463
|
-
|
|
13464
|
-
|
|
13465
|
-
|
|
13466
|
-
kbCommand.command("
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
});
|
|
13471
|
-
kbCommand.command("
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
|
|
13483
|
-
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
|
|
13487
|
-
|
|
13488
|
-
|
|
13489
|
-
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
});
|
|
13494
|
-
kbCommand.command("
|
|
13495
|
-
|
|
13496
|
-
|
|
13497
|
-
|
|
13498
|
-
});
|
|
13499
|
-
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
|
|
13503
|
-
})
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
|
|
13509
|
-
|
|
13510
|
-
|
|
13511
|
-
}
|
|
13512
|
-
});
|
|
13513
|
-
await program.parseAsync();
|
|
13445
|
+
});
|
|
13446
|
+
program.command("dev").description("start local development mode").action(() => {
|
|
13447
|
+
const context = createContextFromOptions(program);
|
|
13448
|
+
console.log("Topchester local dev mode");
|
|
13449
|
+
printStartupSummary(context);
|
|
13450
|
+
});
|
|
13451
|
+
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) => {
|
|
13452
|
+
const context = createContextFromOptions(program);
|
|
13453
|
+
const globalOptions = program.opts();
|
|
13454
|
+
try {
|
|
13455
|
+
await executeRunCommand(context, {
|
|
13456
|
+
prompt: promptParts.join(" "),
|
|
13457
|
+
model: options.model,
|
|
13458
|
+
timeoutMs: options.timeout,
|
|
13459
|
+
json: options.json,
|
|
13460
|
+
outputJson: options.outputJson,
|
|
13461
|
+
resume: globalOptions.resume
|
|
13462
|
+
});
|
|
13463
|
+
} catch (error) {
|
|
13464
|
+
console.error(formatStartupError(error));
|
|
13465
|
+
process.exitCode = 1;
|
|
13466
|
+
}
|
|
13467
|
+
});
|
|
13468
|
+
program.command("search").description("search compiled L1 knowledge entries").argument("<query...>", "search query").option("--limit <count>", "maximum number of matches", parsePositiveInteger).option("--json", "write full JSON search result to stdout").action(async (queryParts, options) => {
|
|
13469
|
+
await executeKbSearchCommand(program, queryParts, options);
|
|
13470
|
+
});
|
|
13471
|
+
const kbCommand = program.command("kb").description("knowledge base commands");
|
|
13472
|
+
kbCommand.command("init").description("initialize a project knowledge base").action(async () => {
|
|
13473
|
+
const context = createContextFromOptions(program);
|
|
13474
|
+
const result = await ui.progress("Preparing project knowledge folders...", (report) => initializeKnowledgeBase(context.workspaceRoot, { onProgress: (event) => report(event.message) }));
|
|
13475
|
+
console.log(formatKnowledgeInitResult(result).join("\n"));
|
|
13476
|
+
});
|
|
13477
|
+
kbCommand.command("dry-run").description("list project files that would be synced into the knowledge base").action(async () => {
|
|
13478
|
+
const context = createContextFromOptions(program);
|
|
13479
|
+
const result = await ui.spinner("Listing project files for KB sync...", () => dryRunKnowledgeCompile(context.workspaceRoot, { config: context.config }));
|
|
13480
|
+
console.log(formatKnowledgeCompileDryRunResult(result, { formatSyncStatus: formatDryRunSyncStatus }).join("\n"));
|
|
13481
|
+
});
|
|
13482
|
+
kbCommand.command("sync").description("sync project files into the knowledge base").option("--full", "sync all in-scope files and remove orphaned L1 entries").action(async (options) => {
|
|
13483
|
+
const context = createContextFromOptions(program);
|
|
13484
|
+
const result = await ui.progress(options.full ? "Syncing all L1 file entries..." : "Syncing non-clean L1 file entries...", (report) => syncKnowledgeBase(context.workspaceRoot, {
|
|
13485
|
+
model: context.modelGateway,
|
|
13486
|
+
requireModel: true,
|
|
13487
|
+
config: context.config,
|
|
13488
|
+
full: options.full,
|
|
13489
|
+
onProgress: (event) => report(event.message)
|
|
13490
|
+
}));
|
|
13491
|
+
console.log(formatKnowledgeSyncResult(result, { title: options.full ? "KB sync --full" : "KB sync" }).join("\n"));
|
|
13492
|
+
if (isPartialKnowledgeCompileResult(result)) process.exitCode = 2;
|
|
13493
|
+
});
|
|
13494
|
+
kbCommand.command("search").alias("query").description("search compiled L1 knowledge entries").argument("<query...>", "search query").option("--limit <count>", "maximum number of matches", parsePositiveInteger).option("--json", "write full JSON search result to stdout").action(async (queryParts, options) => {
|
|
13495
|
+
await executeKbSearchCommand(program, queryParts, options);
|
|
13496
|
+
});
|
|
13497
|
+
kbCommand.command("context").description("create an L1 context pack for a query").argument("<query...>", "context query").option("--limit <count>", "maximum number of relevant files", parsePositiveInteger).option("--min-score <score>", "minimum match score", parseNonNegativeNumber).option("--json", "write JSON context pack to stdout").option("--full-l1", "include full raw L1 entries in JSON output").action(async (queryParts, options) => {
|
|
13498
|
+
await executeKbContextCommand(program, queryParts, options);
|
|
13499
|
+
});
|
|
13500
|
+
kbCommand.command("reset").description("delete the local project knowledge base and cache").action(async () => {
|
|
13501
|
+
const context = createContextFromOptions(program);
|
|
13502
|
+
const result = await ui.progress("Resetting project knowledge base...", (report) => resetKnowledgeBase(context.workspaceRoot, { onProgress: (event) => report(event.message) }));
|
|
13503
|
+
console.log(formatKnowledgeResetResult(result).join("\n"));
|
|
13504
|
+
});
|
|
13505
|
+
kbCommand.command("status").description("show project files that are not current in the knowledge base").action(async () => {
|
|
13506
|
+
const context = createContextFromOptions(program);
|
|
13507
|
+
const result = await ui.spinner("Checking KB file status...", async () => filterNonCleanKnowledgeCompileResult(await dryRunKnowledgeCompile(context.workspaceRoot, { config: context.config })));
|
|
13508
|
+
console.log(formatKnowledgeCompileStatusResult(result, { formatSyncStatus: formatDryRunSyncStatus }).join("\n"));
|
|
13509
|
+
});
|
|
13510
|
+
program.command("update").alias("upgrade").description("update Topchester with the package manager that installed it").argument("[target]", "version or npm dist tag to install", "latest").action(async (target) => {
|
|
13511
|
+
try {
|
|
13512
|
+
const command = await runSelfUpdate({ target });
|
|
13513
|
+
console.log(formatSelfUpdateSuccess(command).join("\n"));
|
|
13514
|
+
} catch (error) {
|
|
13515
|
+
console.error(formatStartupError(error));
|
|
13516
|
+
process.exitCode = 1;
|
|
13517
|
+
}
|
|
13518
|
+
});
|
|
13519
|
+
return program;
|
|
13520
|
+
}
|
|
13521
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) await runTopchesterCli();
|
|
13514
13522
|
function printStartupSummary(context) {
|
|
13515
13523
|
const assignments = context.config.models?.assignments ?? {};
|
|
13516
13524
|
const providers = context.config.models?.providers ?? {};
|
|
@@ -13538,7 +13546,7 @@ function printStartupSummary(context) {
|
|
|
13538
13546
|
}
|
|
13539
13547
|
}
|
|
13540
13548
|
}
|
|
13541
|
-
function createContextFromOptions() {
|
|
13549
|
+
function createContextFromOptions(program) {
|
|
13542
13550
|
const options = program.opts();
|
|
13543
13551
|
return createAppContext({
|
|
13544
13552
|
workspaceRoot: options.workspace,
|
|
@@ -13546,8 +13554,8 @@ function createContextFromOptions() {
|
|
|
13546
13554
|
devFlags: options.dev
|
|
13547
13555
|
});
|
|
13548
13556
|
}
|
|
13549
|
-
async function executeKbSearchCommand(queryParts, options) {
|
|
13550
|
-
const context = createContextFromOptions();
|
|
13557
|
+
async function executeKbSearchCommand(program, queryParts, options) {
|
|
13558
|
+
const context = createContextFromOptions(program);
|
|
13551
13559
|
const query = queryParts.join(" ");
|
|
13552
13560
|
const result = options.json ? await searchL1Knowledge(context.workspaceRoot, query, { limit: options.limit }) : await ui.spinner("Searching L1 knowledge entries...", () => searchL1Knowledge(context.workspaceRoot, query, { limit: options.limit }));
|
|
13553
13561
|
if (options.json) {
|
|
@@ -13556,8 +13564,8 @@ async function executeKbSearchCommand(queryParts, options) {
|
|
|
13556
13564
|
}
|
|
13557
13565
|
console.log(formatL1KnowledgeSearchResult(result).join("\n"));
|
|
13558
13566
|
}
|
|
13559
|
-
async function executeKbContextCommand(queryParts, options) {
|
|
13560
|
-
const context = createContextFromOptions();
|
|
13567
|
+
async function executeKbContextCommand(program, queryParts, options) {
|
|
13568
|
+
const context = createContextFromOptions(program);
|
|
13561
13569
|
const query = queryParts.join(" ");
|
|
13562
13570
|
const contextPackOptions = {
|
|
13563
13571
|
limit: options.limit,
|
|
@@ -13595,6 +13603,6 @@ function formatDryRunSyncStatus(status) {
|
|
|
13595
13603
|
return ui.warn(status);
|
|
13596
13604
|
}
|
|
13597
13605
|
//#endregion
|
|
13598
|
-
export {};
|
|
13606
|
+
export { runTopchesterCli };
|
|
13599
13607
|
|
|
13600
13608
|
//# sourceMappingURL=cli.mjs.map
|