topchester-ai 0.69.0 → 0.71.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-CUjNKJTW.mjs";
2
+ import { t as runTopchesterCli } from "./cli-BKVU9tvf.mjs";
3
3
  //#region src/bin.ts
4
4
  await runTopchesterCli();
5
5
  //#endregion
@@ -761,7 +761,7 @@ const bashArgsSchema = z.object({
761
761
  const bashTool = defineTool({
762
762
  name: "bash",
763
763
  description: "Run an approval-gated shell command inside the workspace.",
764
- prompt: "bash: run an approval-gated shell command for terminal work that needs shell syntax, one-off user-requested commands, package manager commands, scripts, pipelines, redirects, or chaining. Prefer run_validator for tests, lint, typecheck, build, check, format-check, and smoke. To use it, reply with only JSON: {\"tool\":\"bash\",\"args\":{\"command\":\"printf hi | wc -c\",\"workdir\":\".\",\"timeout_ms\":120000,\"description\":\"count bytes\"}}",
764
+ prompt: "bash: run an approval-gated shell command for terminal work that needs shell syntax, one-off user-requested commands, package manager commands, scripts, pipelines, redirects, or chaining. Use run_validator, not bash, for tests and checks that fit strict validator shapes such as pnpm test, go test, cargo test, node --test, local npx tsx --test, lint, typecheck, build, check, format-check, and smoke. To use it, reply with only JSON: {\"tool\":\"bash\",\"args\":{\"command\":\"printf hi | wc -c\",\"workdir\":\".\",\"timeout_ms\":120000,\"description\":\"count bytes\"}}",
765
765
  argsSchema: bashArgsSchema,
766
766
  requiresExclusiveWorkspace: true,
767
767
  execute: async (context, args) => runBashCommand(context.workspaceRoot, args, {
@@ -4355,8 +4355,6 @@ const DANGEROUS_EXECUTABLES = new Set([
4355
4355
  "git",
4356
4356
  "kubectl",
4357
4357
  "mv",
4358
- "npx",
4359
- "pnpx",
4360
4358
  "rm",
4361
4359
  "rmdir",
4362
4360
  "scp",
@@ -4585,13 +4583,24 @@ async function findNearestPackageMetadata(workspaceRoot, cwd) {
4585
4583
  async function readPackageMetadata(path) {
4586
4584
  const raw = JSON.parse(await readFile(path, "utf8"));
4587
4585
  const scripts = Object.fromEntries(Object.entries(raw.scripts ?? {}).filter((entry) => typeof entry[1] === "string"));
4586
+ const dependencies = new Set([
4587
+ ...getPackageDependencyNames(raw.dependencies),
4588
+ ...getPackageDependencyNames(raw.devDependencies),
4589
+ ...getPackageDependencyNames(raw.optionalDependencies),
4590
+ ...getPackageDependencyNames(raw.peerDependencies)
4591
+ ]);
4588
4592
  return {
4589
4593
  path,
4590
4594
  dir: dirname(path),
4591
4595
  scripts,
4596
+ dependencies,
4592
4597
  packageManager: parsePackageManager(raw.packageManager) ?? await detectPackageManagerFromLockfiles(dirname(path))
4593
4598
  };
4594
4599
  }
4600
+ function getPackageDependencyNames(value) {
4601
+ if (!value || typeof value !== "object" || Array.isArray(value)) return [];
4602
+ return Object.keys(value);
4603
+ }
4595
4604
  function parsePackageManager(value) {
4596
4605
  if (typeof value !== "string") return;
4597
4606
  const name = value.split("@")[0];
@@ -4614,8 +4623,25 @@ async function detectPackageManagerFromLockfiles(dir) {
4614
4623
  }
4615
4624
  function classifyValidator(command, metadata) {
4616
4625
  if (isPackageManager(command.executable)) return classifyPackageManagerCommand(command, metadata);
4626
+ if (command.executable === "npx" || command.executable === "pnpx") return classifyPackageExecutorCommand(command, metadata);
4617
4627
  return classifyDirectValidator(command);
4618
4628
  }
4629
+ function classifyPackageExecutorCommand(command, metadata) {
4630
+ const args = command.args[0] === "--no-install" ? command.args.slice(1) : command.args;
4631
+ const executable = args[0];
4632
+ if (executable !== "tsx") return {
4633
+ allowed: false,
4634
+ reason: `command policy rejected '${command.executable}' because only local tsx validators are allowed.`
4635
+ };
4636
+ if (!metadata?.dependencies.has("tsx")) return {
4637
+ allowed: false,
4638
+ reason: `command policy rejected '${command.executable} tsx' because package.json does not declare tsx.`
4639
+ };
4640
+ return classifyDirectValidator({
4641
+ executable,
4642
+ args: args.slice(1)
4643
+ });
4644
+ }
4619
4645
  function classifyPackageManagerCommand(command, metadata) {
4620
4646
  const manager = command.executable;
4621
4647
  const firstArg = command.args[0];
@@ -4689,6 +4715,15 @@ function getPackageScriptName(manager, args) {
4689
4715
  }
4690
4716
  function classifyDirectValidator(command) {
4691
4717
  switch (command.executable) {
4718
+ case "go": return classifyGoValidator(command);
4719
+ case "cargo": return classifyCargoValidator(command);
4720
+ case "tsx": return command.args[0] === "--test" || command.args.includes("--test") ? {
4721
+ allowed: true,
4722
+ validator: "test"
4723
+ } : {
4724
+ allowed: false,
4725
+ reason: "command policy rejected 'tsx' because only 'tsx --test' is a validator."
4726
+ };
4692
4727
  case "vitest":
4693
4728
  case "jest":
4694
4729
  case "mocha": return {
@@ -4739,6 +4774,30 @@ function classifyDirectValidator(command) {
4739
4774
  reason: `command policy rejected '${command.executable}' because it is not a known validator.`
4740
4775
  };
4741
4776
  }
4777
+ function classifyGoValidator(command) {
4778
+ if (command.args[0] !== "test") return {
4779
+ allowed: false,
4780
+ reason: "command policy rejected 'go' because only 'go test' is a validator."
4781
+ };
4782
+ if (command.args.includes("-c") || command.args.some((arg) => arg.startsWith("-exec") || arg.startsWith("-toolexec"))) return {
4783
+ allowed: false,
4784
+ reason: "command policy rejected 'go test' because compile-only or custom tool execution flags are not allowed."
4785
+ };
4786
+ return {
4787
+ allowed: true,
4788
+ validator: "test"
4789
+ };
4790
+ }
4791
+ function classifyCargoValidator(command) {
4792
+ if (command.args[0] !== "test") return {
4793
+ allowed: false,
4794
+ reason: "command policy rejected 'cargo' because only 'cargo test' is a validator."
4795
+ };
4796
+ return {
4797
+ allowed: true,
4798
+ validator: "test"
4799
+ };
4800
+ }
4742
4801
  function classifyScriptName(scriptName) {
4743
4802
  if (scriptName === "test" || scriptName.startsWith("test:")) return "test";
4744
4803
  if (scriptName === "lint" || scriptName.startsWith("lint:")) return "lint";
@@ -4771,7 +4830,7 @@ const validatorKindSchema = z.preprocess((value) => value === "format" || value
4771
4830
  const runValidatorTool = defineTool({
4772
4831
  name: "run_validator",
4773
4832
  description: "Run a strictly validated test, lint, typecheck, build, check, or smoke command inside the workspace.",
4774
- prompt: "run_validator: run a strict verification command after edits, such as tests, lint, typecheck, build, check, format-check, or smoke; format means check-only commands such as pnpm format-check, not mutating formatter commands such as pnpm format; failed exits are useful evidence and should be inspected before retrying. To use it, reply with only JSON: {\"tool\":\"run_validator\",\"args\":{\"command\":\"pnpm test test/tools.test.ts\",\"validator\":\"test\",\"workdir\":\".\",\"timeout_ms\":120000}}",
4833
+ prompt: "run_validator: run a strict verification command after edits, such as pnpm test, go test ./..., cargo test, node --test, local npx tsx --test, lint, typecheck, build, check, format-check, or smoke; format means check-only commands such as pnpm format-check, not mutating formatter commands such as pnpm format; failed exits are useful evidence and should be inspected before retrying. To use it, reply with only JSON: {\"tool\":\"run_validator\",\"args\":{\"command\":\"pnpm test test/tools.test.ts\",\"validator\":\"test\",\"workdir\":\".\",\"timeout_ms\":120000}}",
4775
4834
  argsSchema: z.object({
4776
4835
  command: z.string().min(1).max(2e3),
4777
4836
  validator: validatorKindSchema.optional(),
@@ -5287,8 +5346,8 @@ function formatSkillSource$2(skill) {
5287
5346
  }
5288
5347
  const taskTool = defineTool({
5289
5348
  name: "task",
5290
- description: "Delegate read-only file/search/git research to a child agent. Do not use for shell commands, bash, Python/Node scripts, validators, edits, writes, or other execution work.",
5291
- prompt: "task: delegate read-only file/search/git research to a child agent. Do not use task for shell commands, bash, Python/Node scripts, validators, edits, writes, finish_task, or other execution work; use parent tools directly. To use it, reply with only JSON: {\"tool\":\"task\",\"args\":{\"description\":\"Inspect runtime event flow\",\"prompt\":\"Read the runtime and summarize how events are emitted.\",\"subagent_type\":\"explore\"}}",
5349
+ description: "Delegate read-only file/search/git research to a child agent. Do not use for shell commands, bash, Python/Node scripts, validators, edits, writes, tiny local inspections, or other execution work.",
5350
+ prompt: "task: delegate read-only file/search/git research to a child agent. Do not use task for shell commands, bash, Python/Node scripts, validators, edits, writes, finish_task, tiny local inspections, or other execution work; use parent tools directly. If the relevant workspace context is just a README plus a few obvious source files, inspect them directly with list_files/read_file instead of spawning a subagent. To use it, reply with only JSON: {\"tool\":\"task\",\"args\":{\"description\":\"Inspect runtime event flow\",\"prompt\":\"Read the runtime and summarize how events are emitted.\",\"subagent_type\":\"explore\"}}",
5292
5351
  argsSchema: z.object({
5293
5352
  description: z.string().min(1),
5294
5353
  prompt: z.string().min(1),
@@ -12666,6 +12725,7 @@ function getChatSystemPrompt(options = {}) {
12666
12725
  ] : [],
12667
12726
  ...canUseTool("inspect_command") ? ["- Do not use inspect_command for file creation or file mutation."] : [],
12668
12727
  ...canUseTool("edit_file") ? ["- Keep edit_file old_text small but unique. Do not include line labels or grep prefixes in old_text; use exact file text only."] : [],
12728
+ ...canUseTool("apply_patch") && canUseTool("write_file") && canUseTool("read_file") ? ["- If apply_patch/edit_file fails twice on the same file, stop retrying equivalent patches. Read the current file and, when the intended change is broad, use write_file overwrite:true with the current read_file hash to replace the whole file."] : [],
12669
12729
  ...canUseTool("edit_file") || canUseTool("write_file") ? ["- Use edit/write/patch tools when they are available and the user asks you to implement, fix, add, update, or refactor code."] : [],
12670
12730
  ...canUseTool("finish_task") ? ["- Use finish_task to complete implementation tasks after the requested work is actually done. Do not call finish_task to claim edits or validation that tool results did not confirm."] : [],
12671
12731
  ...canUseTool("inspect_command") || canUseTool("run_validator") ? ["- Use command/test tools when they are available and you need to inspect the environment or verify behavior."] : [],
@@ -16787,4 +16847,4 @@ function formatDryRunSyncStatus(status) {
16787
16847
  //#endregion
16788
16848
  export { runTopchesterCli as t };
16789
16849
 
16790
- //# sourceMappingURL=cli-CUjNKJTW.mjs.map
16850
+ //# sourceMappingURL=cli-BKVU9tvf.mjs.map