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 CHANGED
@@ -1 +1,7 @@
1
- export { };
1
+ //#region src/cli.d.ts
2
+ declare function runTopchesterCli(argv?: string[], options?: {
3
+ exitOverride?: boolean;
4
+ }): Promise<void>;
5
+ //#endregion
6
+ export { runTopchesterCli };
7
+ //# sourceMappingURL=cli.d.mts.map
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
- const program = new Command();
13417
- program.name("topchester").description("KB-first terminal coding agent").version(getTopchesterVersion());
13418
- 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, []);
13419
- program.action(async () => {
13420
- const context = createContextFromOptions();
13421
- const options = program.opts();
13422
- try {
13423
- if (options.resume) {
13424
- const loaded = await loadSession(context.workspaceRoot, options.resume);
13425
- const session = await loadSessionForAppend(context.workspaceRoot, loaded.sessionId);
13426
- const rehydrated = rehydrateSession(loaded.events);
13427
- await new TopchesterTuiShell(context, void 0, {
13428
- session,
13429
- initialMessages: rehydrated.messages,
13430
- initialTaskPlan: rehydrated.taskPlan
13431
- }).render();
13432
- return;
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
- await new TopchesterTuiShell(context).render();
13435
- } catch (error) {
13436
- console.error(formatStartupError(error));
13437
- process.exitCode = 1;
13438
- }
13439
- });
13440
- program.command("dev").description("start local development mode").action(() => {
13441
- const context = createContextFromOptions();
13442
- console.log("Topchester local dev mode");
13443
- printStartupSummary(context);
13444
- });
13445
- 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) => {
13446
- const context = createContextFromOptions();
13447
- const globalOptions = program.opts();
13448
- try {
13449
- await executeRunCommand(context, {
13450
- prompt: promptParts.join(" "),
13451
- model: options.model,
13452
- timeoutMs: options.timeout,
13453
- json: options.json,
13454
- outputJson: options.outputJson,
13455
- resume: globalOptions.resume
13456
- });
13457
- } catch (error) {
13458
- console.error(formatStartupError(error));
13459
- process.exitCode = 1;
13460
- }
13461
- });
13462
- 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) => {
13463
- await executeKbSearchCommand(queryParts, options);
13464
- });
13465
- const kbCommand = program.command("kb").description("knowledge base commands");
13466
- kbCommand.command("init").description("initialize a project knowledge base").action(async () => {
13467
- const context = createContextFromOptions();
13468
- const result = await ui.progress("Preparing project knowledge folders...", (report) => initializeKnowledgeBase(context.workspaceRoot, { onProgress: (event) => report(event.message) }));
13469
- console.log(formatKnowledgeInitResult(result).join("\n"));
13470
- });
13471
- kbCommand.command("dry-run").description("list project files that would be synced into the knowledge base").action(async () => {
13472
- const context = createContextFromOptions();
13473
- const result = await ui.spinner("Listing project files for KB sync...", () => dryRunKnowledgeCompile(context.workspaceRoot, { config: context.config }));
13474
- console.log(formatKnowledgeCompileDryRunResult(result, { formatSyncStatus: formatDryRunSyncStatus }).join("\n"));
13475
- });
13476
- 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) => {
13477
- const context = createContextFromOptions();
13478
- const result = await ui.progress(options.full ? "Syncing all L1 file entries..." : "Syncing non-clean L1 file entries...", (report) => syncKnowledgeBase(context.workspaceRoot, {
13479
- model: context.modelGateway,
13480
- requireModel: true,
13481
- config: context.config,
13482
- full: options.full,
13483
- onProgress: (event) => report(event.message)
13484
- }));
13485
- console.log(formatKnowledgeSyncResult(result, { title: options.full ? "KB sync --full" : "KB sync" }).join("\n"));
13486
- if (isPartialKnowledgeCompileResult(result)) process.exitCode = 2;
13487
- });
13488
- 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) => {
13489
- await executeKbSearchCommand(queryParts, options);
13490
- });
13491
- 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) => {
13492
- await executeKbContextCommand(queryParts, options);
13493
- });
13494
- kbCommand.command("reset").description("delete the local project knowledge base and cache").action(async () => {
13495
- const context = createContextFromOptions();
13496
- const result = await ui.progress("Resetting project knowledge base...", (report) => resetKnowledgeBase(context.workspaceRoot, { onProgress: (event) => report(event.message) }));
13497
- console.log(formatKnowledgeResetResult(result).join("\n"));
13498
- });
13499
- kbCommand.command("status").description("show project files that are not current in the knowledge base").action(async () => {
13500
- const context = createContextFromOptions();
13501
- const result = await ui.spinner("Checking KB file status...", async () => filterNonCleanKnowledgeCompileResult(await dryRunKnowledgeCompile(context.workspaceRoot, { config: context.config })));
13502
- console.log(formatKnowledgeCompileStatusResult(result, { formatSyncStatus: formatDryRunSyncStatus }).join("\n"));
13503
- });
13504
- 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) => {
13505
- try {
13506
- const command = await runSelfUpdate({ target });
13507
- console.log(formatSelfUpdateSuccess(command).join("\n"));
13508
- } catch (error) {
13509
- console.error(formatStartupError(error));
13510
- process.exitCode = 1;
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