@wrongstack/tools 1.0.8 → 1.0.10

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.
Files changed (136) hide show
  1. package/dist/_win32-resolve.d.ts +5 -0
  2. package/dist/audit.js +5 -5
  3. package/dist/bash-kill-guard.d.ts +6 -4
  4. package/dist/bash.js +2 -2
  5. package/dist/browser/index.js +1 -1
  6. package/dist/builtin.js +41 -41
  7. package/dist/{chunk-N3OTTQNC.js → chunk-2OCAAFAT.js} +44 -25
  8. package/dist/{chunk-5MP76C72.js → chunk-2UVAIS5O.js} +24 -29
  9. package/dist/{chunk-SIIOHBNY.js → chunk-3RRK33YM.js} +2 -2
  10. package/dist/{chunk-M2W36JT7.js → chunk-4CE3RKEP.js} +6 -3
  11. package/dist/{chunk-QJARSK2G.js → chunk-4SUGLJLO.js} +11 -3
  12. package/dist/{chunk-AH7J5HWL.js → chunk-5RBUYFRV.js} +15 -7
  13. package/dist/{chunk-GNLHBDFO.js → chunk-6I6RXQFG.js} +127 -196
  14. package/dist/{chunk-WKLUOXR4.js → chunk-7GOE2ZTZ.js} +2 -2
  15. package/dist/{chunk-O6AGFJBO.js → chunk-7V33PHT6.js} +49 -77
  16. package/dist/{chunk-CAF4L6KN.js → chunk-C3WP6ZOT.js} +36 -48
  17. package/dist/{chunk-KMXPP32M.js → chunk-C6ZOXNXV.js} +13 -3
  18. package/dist/{chunk-EGT5QLCB.js → chunk-D6RQZMZS.js} +123 -255
  19. package/dist/{chunk-S6CGSFLX.js → chunk-DBG7UQGK.js} +10 -3
  20. package/dist/{chunk-FI6SOIVE.js → chunk-DLZCOEVG.js} +21 -3
  21. package/dist/{chunk-NL45OWEO.js → chunk-DOAHONOS.js} +7 -12
  22. package/dist/{chunk-3LQJXJDM.js → chunk-E7A4SLKR.js} +2 -2
  23. package/dist/{chunk-JB5JLY7V.js → chunk-ENE22I5W.js} +387 -394
  24. package/dist/{chunk-5KRKL3WD.js → chunk-FCSUBTUJ.js} +112 -119
  25. package/dist/{chunk-YUK3WLHJ.js → chunk-FVSMTEO3.js} +2 -2
  26. package/dist/{chunk-SEONDNLN.js → chunk-G7CYW5EP.js} +2 -2
  27. package/dist/{chunk-TU6UVATU.js → chunk-HYHE4VNA.js} +3 -3
  28. package/dist/{chunk-HIRVCXLP.js → chunk-IE4KDAOB.js} +3 -3
  29. package/dist/{chunk-YA2ZYCJY.js → chunk-JPK2HHBK.js} +1 -1
  30. package/dist/{chunk-7E55DAFW.js → chunk-KHUCKLOR.js} +12 -7
  31. package/dist/{chunk-R3HIZVFS.js → chunk-KPDCKSN5.js} +23 -3
  32. package/dist/{chunk-B3MGJBFI.js → chunk-KS2OEZWV.js} +23 -47
  33. package/dist/{chunk-UI3ZJIG3.js → chunk-LKLIQUCW.js} +14 -8
  34. package/dist/{chunk-62OAECEQ.js → chunk-LLSFOUZF.js} +8 -8
  35. package/dist/{chunk-YZQSUL5G.js → chunk-M4ZHHCCW.js} +14 -6
  36. package/dist/{chunk-IXIS7RSG.js → chunk-MRXWOOOR.js} +29 -47
  37. package/dist/{chunk-C4DSQBTT.js → chunk-NEYUPZL6.js} +3 -3
  38. package/dist/{chunk-6XYFYLN7.js → chunk-O2MHULBO.js} +13 -8
  39. package/dist/{chunk-B62LKMWQ.js → chunk-OKZJJDOG.js} +86 -188
  40. package/dist/{chunk-HOFVYIPI.js → chunk-ON6ET5ER.js} +16 -1
  41. package/dist/{chunk-KF7GMVNU.js → chunk-OUERRFEM.js} +32 -11
  42. package/dist/{chunk-GF4JHLCO.js → chunk-PWZUHZP7.js} +2 -2
  43. package/dist/{chunk-OGQMPX3J.js → chunk-QAWI3RSK.js} +37 -81
  44. package/dist/{chunk-ZMCV3XOV.js → chunk-SPNXDTCJ.js} +29 -63
  45. package/dist/{chunk-H2VB7GCR.js → chunk-ULI2J6TX.js} +27 -14
  46. package/dist/{chunk-EMA2XENR.js → chunk-UVYRQKPZ.js} +4 -3
  47. package/dist/{chunk-MF6ZUBI7.js → chunk-V25Q6TQ7.js} +3 -3
  48. package/dist/{chunk-2NTHMZV3.js → chunk-VMJY6FYJ.js} +693 -276
  49. package/dist/{chunk-ZOUG3KKS.js → chunk-XPVYZ2S6.js} +2 -2
  50. package/dist/{chunk-5U5ULQX2.js → chunk-XZLVJD56.js} +5 -1
  51. package/dist/{chunk-HCPSVK7J.js → chunk-YKSOSI2N.js} +47 -31
  52. package/dist/codebase-index/codebase-ast-replace-tool.d.ts +5 -6
  53. package/dist/codebase-index/codebase-context-tool.d.ts +4 -6
  54. package/dist/codebase-index/codebase-impact-analysis-tool.d.ts +1 -2
  55. package/dist/codebase-index/codebase-incoming-calls-tool.d.ts +0 -2
  56. package/dist/codebase-index/codebase-index-tool.d.ts +0 -2
  57. package/dist/codebase-index/codebase-invariant-check-tool.d.ts +1 -2
  58. package/dist/codebase-index/codebase-outgoing-calls-tool.d.ts +0 -2
  59. package/dist/codebase-index/codebase-repo-map-tool.d.ts +1 -2
  60. package/dist/codebase-index/codebase-search-tool.d.ts +1 -1
  61. package/dist/codebase-index/codebase-targeted-test-tool.d.ts +1 -2
  62. package/dist/codebase-index/index.js +8 -8
  63. package/dist/codebase-index/parser-worker-script.js +3 -3
  64. package/dist/codebase-index/project-server.js +5 -5
  65. package/dist/codebase-index/worker.js +4 -4
  66. package/dist/design.js +1 -1
  67. package/dist/diff.js +1 -1
  68. package/dist/edit.js +7 -7
  69. package/dist/exec.d.ts +7 -7
  70. package/dist/exec.js +2 -2
  71. package/dist/format.js +5 -5
  72. package/dist/git.js +1 -1
  73. package/dist/glob.js +1 -1
  74. package/dist/{go-parser-VDPRQEGM.js → go-parser-Z4H6SR3R.js} +6 -3
  75. package/dist/grep.js +1 -1
  76. package/dist/index.js +45 -45
  77. package/dist/install.js +5 -5
  78. package/dist/json.d.ts +0 -1
  79. package/dist/json.js +1 -1
  80. package/dist/kanban-presence.d.ts +6 -0
  81. package/dist/kanban-serializer.d.ts +9 -1
  82. package/dist/kanban-split-task-handler.d.ts +1 -1
  83. package/dist/kanban-tool-results.d.ts +57 -2
  84. package/dist/kanban-tool-types.d.ts +16 -5
  85. package/dist/kanban.d.ts +14 -0
  86. package/dist/kanban.js +9 -1
  87. package/dist/languages/index.js +3 -3
  88. package/dist/{legacy-bridge-4T4OTSQP.js → legacy-bridge-BPT2S2F4.js} +5 -5
  89. package/dist/lint.js +5 -5
  90. package/dist/logs.js +1 -1
  91. package/dist/mode.d.ts +3 -2
  92. package/dist/mode.js +1 -1
  93. package/dist/outdated.js +2 -2
  94. package/dist/pack.js +42 -42
  95. package/dist/{parser-dispatch-4E2SDQUO.js → parser-dispatch-WG4DNBHH.js} +4 -4
  96. package/dist/patch.js +7 -7
  97. package/dist/plan.d.ts +2 -1
  98. package/dist/plan.js +3 -3
  99. package/dist/{py-parser-MAW6DHFE.js → py-parser-4PFZYAJ7.js} +3 -3
  100. package/dist/read.js +7 -7
  101. package/dist/replace.js +7 -7
  102. package/dist/search.d.ts +0 -6
  103. package/dist/search.js +1 -1
  104. package/dist/security-ast-scan-tool.d.ts +1 -2
  105. package/dist/session-shell.js +2 -2
  106. package/dist/task.d.ts +2 -1
  107. package/dist/task.js +3 -3
  108. package/dist/test.d.ts +8 -1
  109. package/dist/test.js +5 -5
  110. package/dist/todo.js +2 -2
  111. package/dist/tool-search.d.ts +2 -0
  112. package/dist/tool-search.js +1 -1
  113. package/dist/tool-tier.js +43 -43
  114. package/dist/tool-use.d.ts +2 -2
  115. package/dist/tool-use.js +1 -1
  116. package/dist/tree.js +1 -1
  117. package/dist/typecheck.js +5 -5
  118. package/dist/wasm/bash/tree-sitter-bash.wasm +0 -0
  119. package/dist/wasm/c/tree-sitter-c.wasm +0 -0
  120. package/dist/wasm/c_sharp/tree-sitter-c_sharp.wasm +0 -0
  121. package/dist/wasm/checksums.json +16 -0
  122. package/dist/wasm/cpp/tree-sitter-cpp.wasm +0 -0
  123. package/dist/wasm/elixir/tree-sitter-elixir.wasm +0 -0
  124. package/dist/wasm/go/tree-sitter-go.wasm +0 -0
  125. package/dist/wasm/java/tree-sitter-java.wasm +0 -0
  126. package/dist/wasm/kotlin/tree-sitter-kotlin.wasm +0 -0
  127. package/dist/wasm/php/tree-sitter-php.wasm +0 -0
  128. package/dist/wasm/python/tree-sitter-python.wasm +0 -0
  129. package/dist/wasm/ruby/tree-sitter-ruby.wasm +0 -0
  130. package/dist/wasm/rust/tree-sitter-rust.wasm +0 -0
  131. package/dist/wasm/swift/tree-sitter-swift.wasm +0 -0
  132. package/dist/wasm/tree-sitter-runtime.wasm +0 -0
  133. package/dist/win32.d.ts +1 -1
  134. package/dist/win32.js +3 -1
  135. package/dist/write.js +7 -7
  136. package/package.json +10 -10
@@ -14,7 +14,7 @@ import {
14
14
  } from "./chunk-HDYUBRMF.js";
15
15
  import {
16
16
  resolvePowerShell
17
- } from "./chunk-5U5ULQX2.js";
17
+ } from "./chunk-XZLVJD56.js";
18
18
  import {
19
19
  normalizeCommandOutput
20
20
  } from "./chunk-2IAEJRLT.js";
@@ -185,6 +185,34 @@ function isKillRelatedCommand(cmd) {
185
185
  if (SCRIPT_KILL_RE_POSIX.test(normalized)) return true;
186
186
  return false;
187
187
  }
188
+ function parsePosixKillTargets(normalized, command) {
189
+ const tokens = normalized.split(" ");
190
+ if (tokens[0]?.toLowerCase() !== "kill") return null;
191
+ let i = 1;
192
+ let signal = "TERM";
193
+ const first = tokens[i];
194
+ if (first !== void 0 && /^-[sn]$/i.test(first)) {
195
+ const value = tokens[i + 1];
196
+ if (!value || !/^[a-zA-Z0-9]+$/.test(value)) return null;
197
+ signal = value.toUpperCase();
198
+ i += 2;
199
+ } else if (first !== void 0 && first !== "--" && /^-[a-zA-Z0-9]+$/.test(first) && tokens.length - i >= 2) {
200
+ signal = first.slice(1).toUpperCase();
201
+ i += 1;
202
+ }
203
+ if (tokens[i] === "--") i += 1;
204
+ const targets = tokens.slice(i);
205
+ if (targets.length === 0 || !targets.every((t) => /^-?\d+$/.test(t))) return null;
206
+ const pids = targets.map((t) => Number.parseInt(t.replace(/^-/, ""), 10));
207
+ return {
208
+ pid: pids[0],
209
+ ...pids.length > 1 ? { pids } : {},
210
+ signal,
211
+ isGroupKill: targets.some((t) => t.startsWith("-")),
212
+ isAllKill: false,
213
+ originalCommand: command
214
+ };
215
+ }
188
216
  function parseKillCommand(command) {
189
217
  const normalized = command.replace(/\s+/g, " ").trim();
190
218
  if (isWin) {
@@ -241,27 +269,8 @@ function parseKillCommand(command) {
241
269
  originalCommand: command
242
270
  };
243
271
  }
244
- const killSignalOptionMatch = normalized.match(/^kill\s+-s\s+([a-zA-Z0-9]+)\s+(\d+)$/i);
245
- if (killSignalOptionMatch?.[1] && killSignalOptionMatch[2]) {
246
- return {
247
- pid: parseInt(killSignalOptionMatch[2], 10),
248
- signal: killSignalOptionMatch[1].toUpperCase(),
249
- isGroupKill: false,
250
- isAllKill: false,
251
- originalCommand: command
252
- };
253
- }
254
- const killPosixMatch = normalized.match(/^kill\s+(?:(-[a-zA-Z0-9]+)\s+)?(\d+)$/);
255
- if (killPosixMatch?.[2]) {
256
- const sig = killPosixMatch[1] ? killPosixMatch[1].slice(1).toUpperCase() : "TERM";
257
- return {
258
- pid: parseInt(killPosixMatch[2], 10),
259
- signal: sig,
260
- isGroupKill: false,
261
- isAllKill: false,
262
- originalCommand: command
263
- };
264
- }
272
+ const gitBashKill = parsePosixKillTargets(normalized, command);
273
+ if (gitBashKill) return gitBashKill;
265
274
  const stopProcNameMatch = normalized.match(
266
275
  /^(?:stop-process|kill)\s+-(?:name|n)\s+(?:['"]([a-zA-Z0-9_.-]+)['"]|([a-zA-Z0-9_.-]+))(?:\s|$)/i
267
276
  );
@@ -324,33 +333,8 @@ function parseKillCommand(command) {
324
333
  }
325
334
  return null;
326
335
  }
327
- const signalOptionMatch = normalized.match(/^kill\s+-s\s+([a-zA-Z0-9]+)\s+(\d+|-?\d+)$/i);
328
- if (signalOptionMatch?.[1] && signalOptionMatch[2]) {
329
- const pidOrGroup = signalOptionMatch[2];
330
- const isGroupKill = pidOrGroup.startsWith("-");
331
- return {
332
- pid: parseInt(isGroupKill ? pidOrGroup.slice(1) : pidOrGroup, 10),
333
- signal: signalOptionMatch[1].toUpperCase(),
334
- isGroupKill,
335
- isAllKill: false,
336
- originalCommand: command
337
- };
338
- }
339
- const simpleMatch = normalized.match(/^kill\s+(?:(-[a-zA-Z0-9]+)\s+)?(\d+|-?\d+)$/);
340
- if (simpleMatch) {
341
- const signal = simpleMatch[1] ?? "-TERM";
342
- const pidOrGroup = simpleMatch[2];
343
- if (!pidOrGroup) return null;
344
- const isGroupKill = pidOrGroup.startsWith("-");
345
- const pid = isGroupKill ? parseInt(pidOrGroup.slice(1), 10) : parseInt(pidOrGroup, 10);
346
- return {
347
- pid,
348
- signal: signal.slice(1),
349
- isGroupKill,
350
- isAllKill: false,
351
- originalCommand: command
352
- };
353
- }
336
+ const posixKill = parsePosixKillTargets(normalized, command);
337
+ if (posixKill) return posixKill;
354
338
  const pkillMatch = normalized.match(/^pkill\s+(?:(-[a-zA-Z]+)\s+)?(.+)$/);
355
339
  if (pkillMatch?.[2]) {
356
340
  const name = pkillMatch[2];
@@ -429,14 +413,60 @@ async function isKillProtected(kill) {
429
413
  const protectedPids = await registry.getAllProtectedPids();
430
414
  return protectedPids.length > 0;
431
415
  }
432
- if (kill.pid !== void 0) {
433
- if (await registry.shouldBlockKill(kill.pid)) return true;
434
- if (kill.pid === process.pid || kill.pid === process.ppid) return true;
435
- return false;
416
+ const targets = kill.pids ?? (kill.pid !== void 0 ? [kill.pid] : []);
417
+ for (const pid of targets) {
418
+ if (await registry.shouldBlockKill(pid)) return true;
419
+ if (pid === process.pid || pid === process.ppid) return true;
436
420
  }
437
421
  return false;
438
422
  }
439
423
  async function checkAndBlockKillCommand(command) {
424
+ const whole = await checkSingleCommand(command);
425
+ if (whole.blocked) return whole;
426
+ const segments = splitShellSequence(command);
427
+ if (segments.length > 1) {
428
+ for (const segment of segments) {
429
+ const result = await checkSingleCommand(segment);
430
+ if (result.blocked) return result;
431
+ }
432
+ }
433
+ return { blocked: false };
434
+ }
435
+ function splitShellSequence(command) {
436
+ const segments = [];
437
+ let current = "";
438
+ let quote = null;
439
+ for (let i = 0; i < command.length; i++) {
440
+ const ch = command[i];
441
+ const next = command[i + 1];
442
+ if (quote) {
443
+ if (ch === quote) quote = null;
444
+ current += ch;
445
+ continue;
446
+ }
447
+ if (ch === "\\" && next !== void 0) {
448
+ current += ch + next;
449
+ i++;
450
+ continue;
451
+ }
452
+ if (ch === '"' || ch === "'") {
453
+ quote = ch;
454
+ current += ch;
455
+ continue;
456
+ }
457
+ const isSeparator = ch === ";" || ch === "\n" || ch === "\r" || ch === "|" && next === "|" || ch === "&" && command[i - 1] !== ">" && next !== ">";
458
+ if (isSeparator) {
459
+ if ((ch === "|" || ch === "&") && next === ch) i++;
460
+ if (current.trim()) segments.push(current.trim());
461
+ current = "";
462
+ continue;
463
+ }
464
+ current += ch;
465
+ }
466
+ if (current.trim()) segments.push(current.trim());
467
+ return segments;
468
+ }
469
+ async function checkSingleCommand(command) {
440
470
  const normalized = command.replace(/\s+/g, " ").trim();
441
471
  const killCmd = extractKillCommand(normalized) || (isKillRelatedCommand(normalized) ? normalized : null);
442
472
  if (!killCmd) {
@@ -462,6 +492,8 @@ async function checkAndBlockKillCommand(command) {
462
492
  let target;
463
493
  if (parsed.name) {
464
494
  target = `process name "${parsed.name}"`;
495
+ } else if (parsed.pids && parsed.pids.length > 1) {
496
+ target = `PIDs ${parsed.pids.join(", ")}`;
465
497
  } else if (parsed.pid !== void 0) {
466
498
  target = `PID ${parsed.pid}`;
467
499
  } else {
@@ -549,31 +581,15 @@ var bashTool = {
549
581
  const registry = getProcessRegistry();
550
582
  const bypassBreaker = !!input.background;
551
583
  if (!registry.beforeCall(bypassBreaker)) {
552
- yield {
553
- type: "final",
554
- output: {
555
- output: "",
556
- exit_code: 1,
557
- timed_out: false,
558
- pid: null,
559
- error: "bash: circuit breaker open \u2014 too many consecutive failures or slow calls. Use /kill to inspect or /kill reset to recover."
560
- }
561
- };
562
- return;
584
+ throw new Error(
585
+ "bash: circuit breaker open \u2014 too many consecutive failures or slow calls. Use /kill to inspect or /kill reset to recover."
586
+ );
563
587
  }
564
588
  const killCheck = await checkAndBlockKillCommand(input.command);
565
589
  if (killCheck.blocked) {
566
- yield {
567
- type: "final",
568
- output: {
569
- output: "",
570
- exit_code: 1,
571
- timed_out: false,
572
- pid: null,
573
- error: killCheck.reason || "Kill command blocked: targets a protected WrongStack process."
574
- }
575
- };
576
- return;
590
+ throw new Error(
591
+ `bash: ${killCheck.reason || "Kill command blocked: targets a protected WrongStack process."}`
592
+ );
577
593
  }
578
594
  const PIPE_TO_SHELL_PATTERN = /\|\s*(?:sudo\s+)?(sh|bash|ksh|zsh|fish|cmd|powershell|pwsh)(?:\.exe)?\b/i;
579
595
  const pipeToShellNote = PIPE_TO_SHELL_PATTERN.test(input.command) ? "\n\n[wrongstack] Caution: this command pipes output into a shell interpreter (pipe-to-shell). Piped content executes as arbitrary code \u2014 review the source before trusting the result, and prefer downloading to a file and inspecting it first." : "";
@@ -654,17 +670,9 @@ var bashTool = {
654
670
  timedOut: false,
655
671
  endedAt: (/* @__PURE__ */ new Date()).toISOString()
656
672
  });
657
- yield {
658
- type: "final",
659
- output: {
660
- output: "",
661
- exit_code: 1,
662
- timed_out: false,
663
- pid: null,
664
- error: `spawn failed: ${err instanceof Error ? err.message : String(err)}`
665
- }
666
- };
667
- return;
673
+ throw new Error(`bash: spawn failed: ${err instanceof Error ? err.message : String(err)}`, {
674
+ cause: err
675
+ });
668
676
  }
669
677
  const pid2 = child2.pid;
670
678
  const stdoutBytes2 = 0;
@@ -723,17 +731,7 @@ var bashTool = {
723
731
  });
724
732
  if (typeof pid2 !== "number") {
725
733
  completeBackground(1);
726
- yield {
727
- type: "final",
728
- output: {
729
- output: "",
730
- exit_code: 1,
731
- timed_out: false,
732
- pid: null,
733
- error: "Failed to launch background process: invalid PID"
734
- }
735
- };
736
- return;
734
+ throw new Error("bash: failed to launch background process: invalid PID");
737
735
  }
738
736
  child2.unref();
739
737
  yield {
@@ -785,17 +783,9 @@ var bashTool = {
785
783
  timedOut: false,
786
784
  endedAt: (/* @__PURE__ */ new Date()).toISOString()
787
785
  });
788
- yield {
789
- type: "final",
790
- output: {
791
- output: "",
792
- exit_code: 1,
793
- timed_out: false,
794
- pid: null,
795
- error: `spawn failed: ${err instanceof Error ? err.message : String(err)}`
796
- }
797
- };
798
- return;
786
+ throw new Error(`bash: spawn failed: ${err instanceof Error ? err.message : String(err)}`, {
787
+ cause: err
788
+ });
799
789
  }
800
790
  const pid = child.pid;
801
791
  let stdoutBytes = 0;
@@ -982,16 +972,6 @@ var bashTool = {
982
972
  yield { type: "partial_output", text: remainder };
983
973
  }
984
974
  const spooled = spool.finalize();
985
- yield {
986
- type: "final",
987
- output: {
988
- output: normalizeCommandOutput(buf) + (spooled ? spoolNote(spooled) : "") + pipeToShellNote,
989
- exit_code: isAbort ? 124 : 1,
990
- timed_out: isAbort,
991
- pid: pid ?? null,
992
- error: isAbort ? "Command aborted by user or signal" : c.err.message
993
- }
994
- };
995
975
  ctx.recordSideEffect?.({
996
976
  toolUseId: `bash-${Date.now()}`,
997
977
  toolName: "bash",
@@ -1000,6 +980,19 @@ var bashTool = {
1000
980
  outcome: isAbort ? "aborted" : `error (${c.err.message})`,
1001
981
  risk: "shell"
1002
982
  });
983
+ if (!isAbort) {
984
+ throw new Error(`bash: process error: ${c.err.message}`, { cause: c.err });
985
+ }
986
+ yield {
987
+ type: "final",
988
+ output: {
989
+ output: normalizeCommandOutput(buf) + (spooled ? spoolNote(spooled) : "") + pipeToShellNote,
990
+ exit_code: 124,
991
+ timed_out: true,
992
+ pid: pid ?? null,
993
+ error: "Command aborted by user or signal"
994
+ }
995
+ };
1003
996
  return;
1004
997
  }
1005
998
  if (c.kind === "end") {
@@ -1093,4 +1086,4 @@ export {
1093
1086
  checkAndBlockKillCommand,
1094
1087
  bashTool
1095
1088
  };
1096
- //# sourceMappingURL=chunk-5KRKL3WD.js.map
1089
+ //# sourceMappingURL=chunk-FCSUBTUJ.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  builtinTools
3
- } from "./chunk-GNLHBDFO.js";
3
+ } from "./chunk-6I6RXQFG.js";
4
4
 
5
5
  // src/pack.ts
6
6
  var builtinToolsPack = {
@@ -12,4 +12,4 @@ var builtinToolsPack = {
12
12
  export {
13
13
  builtinToolsPack
14
14
  };
15
- //# sourceMappingURL=chunk-YUK3WLHJ.js.map
15
+ //# sourceMappingURL=chunk-FVSMTEO3.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  spawnStream
3
- } from "./chunk-EMA2XENR.js";
3
+ } from "./chunk-UVYRQKPZ.js";
4
4
  import {
5
5
  normalizeCommandOutput,
6
6
  safeResolveReal
@@ -3515,4 +3515,4 @@ export {
3515
3515
  languagePackageTool,
3516
3516
  languageInfoTool
3517
3517
  };
3518
- //# sourceMappingURL=chunk-SEONDNLN.js.map
3518
+ //# sourceMappingURL=chunk-G7CYW5EP.js.map
@@ -13,7 +13,7 @@ import {
13
13
  projectIndexServerMetadataPath,
14
14
  projectIndexServerStderrPath,
15
15
  readProjectIndexServerStderrTail
16
- } from "./chunk-ZOUG3KKS.js";
16
+ } from "./chunk-XPVYZ2S6.js";
17
17
  import {
18
18
  CircuitOpenError,
19
19
  IndexTimeoutError,
@@ -28,7 +28,7 @@ import {
28
28
  searchService,
29
29
  statsService,
30
30
  symbolGraphService
31
- } from "./chunk-C4DSQBTT.js";
31
+ } from "./chunk-NEYUPZL6.js";
32
32
  import {
33
33
  recordIpcPending
34
34
  } from "./chunk-ZKC5UNGD.js";
@@ -1352,4 +1352,4 @@ export {
1352
1352
  checkCodebaseIndexServerHealth,
1353
1353
  ensureCodebaseIndexServer
1354
1354
  };
1355
- //# sourceMappingURL=chunk-TU6UVATU.js.map
1355
+ //# sourceMappingURL=chunk-HYHE4VNA.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  getIndexState,
3
3
  searchCodebaseIndex
4
- } from "./chunk-TU6UVATU.js";
4
+ } from "./chunk-HYHE4VNA.js";
5
5
  import {
6
6
  codebaseIndexDirOverride
7
- } from "./chunk-C4DSQBTT.js";
7
+ } from "./chunk-NEYUPZL6.js";
8
8
  import {
9
9
  isBinaryBuffer,
10
10
  safeResolveReal,
@@ -340,4 +340,4 @@ ${interesting.join("\n")}` : "symbols/imports: (none detected)"
340
340
  export {
341
341
  readTool
342
342
  };
343
- //# sourceMappingURL=chunk-HIRVCXLP.js.map
343
+ //# sourceMappingURL=chunk-IE4KDAOB.js.map
@@ -82,4 +82,4 @@ var toolSearchTool = {
82
82
  export {
83
83
  toolSearchTool
84
84
  };
85
- //# sourceMappingURL=chunk-YA2ZYCJY.js.map
85
+ //# sourceMappingURL=chunk-JPK2HHBK.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolvePythonBinary
3
- } from "./chunk-M2W36JT7.js";
3
+ } from "./chunk-4CE3RKEP.js";
4
4
  import {
5
5
  parseParserBatchOutput,
6
6
  recordParserSubprocess,
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-ZKC5UNGD.js";
9
9
  import {
10
10
  resolveWin32Command
11
- } from "./chunk-5U5ULQX2.js";
11
+ } from "./chunk-XZLVJD56.js";
12
12
 
13
13
  // src/codebase-index/import-extractor.ts
14
14
  var IMPORT_MAX_FILE_CHARS = 512 * 1024;
@@ -140,6 +140,7 @@ import * as fsSync from "node:fs";
140
140
  import * as fs from "node:fs/promises";
141
141
  import * as os from "node:os";
142
142
  import * as path from "node:path";
143
+ import { StringDecoder } from "node:string_decoder";
143
144
  var MAX_BATCH_FILES = 100;
144
145
  var MAX_BATCH_BYTES = 8 * 1024 * 1024;
145
146
  function chunkBatchFiles(files) {
@@ -665,15 +666,19 @@ function runToolchainChild(binary, args, stdinPayload, timeoutMs) {
665
666
  }, timeoutMs);
666
667
  timer.unref?.();
667
668
  proc.on("error", () => finish(null));
669
+ const stdoutDecoder = new StringDecoder("utf8");
668
670
  proc.stdout?.on("data", (chunk) => {
669
- stdout += chunk.toString();
671
+ stdout += stdoutDecoder.write(chunk);
670
672
  });
671
673
  proc.stderr?.resume();
672
674
  proc.stdin?.on("error", () => {
673
675
  });
674
676
  proc.stdin?.write(stdinPayload);
675
677
  proc.stdin?.end();
676
- proc.on("close", (code) => finish({ code, stdout }));
678
+ proc.on("close", (code) => {
679
+ stdout += stdoutDecoder.end();
680
+ finish({ code, stdout });
681
+ });
677
682
  });
678
683
  }
679
684
  async function runGoBatch(files, goBinary) {
@@ -830,11 +835,11 @@ async function dispatch(file, content, lang) {
830
835
  return parseSymbols({ file, content, lang });
831
836
  }
832
837
  case "go": {
833
- const { parseSymbols } = await import("./go-parser-VDPRQEGM.js");
838
+ const { parseSymbols } = await import("./go-parser-Z4H6SR3R.js");
834
839
  return parseSymbols({ file, content, lang: "go" });
835
840
  }
836
841
  case "py": {
837
- const { parseSymbols } = await import("./py-parser-MAW6DHFE.js");
842
+ const { parseSymbols } = await import("./py-parser-4PFZYAJ7.js");
838
843
  return parseSymbols({ file, content, lang: "py" });
839
844
  }
840
845
  case "rs": {
@@ -891,4 +896,4 @@ export {
891
896
  parseFileContent,
892
897
  parseFilesContent
893
898
  };
894
- //# sourceMappingURL=chunk-7E55DAFW.js.map
899
+ //# sourceMappingURL=chunk-KHUCKLOR.js.map
@@ -1,15 +1,17 @@
1
1
  import {
2
2
  tryLegacyCodeOperation
3
- } from "./chunk-3LQJXJDM.js";
3
+ } from "./chunk-E7A4SLKR.js";
4
4
  import {
5
5
  spawnStream
6
- } from "./chunk-EMA2XENR.js";
6
+ } from "./chunk-UVYRQKPZ.js";
7
7
  import {
8
+ ensureInsideRoot,
8
9
  normalizeCommandOutput,
9
10
  safeResolveReal
10
11
  } from "./chunk-2IAEJRLT.js";
11
12
 
12
13
  // src/lint.ts
14
+ import * as path from "node:path";
13
15
  import { ToolValidationError } from "@wrongstack/core/types";
14
16
  var lintTool = {
15
17
  name: "lint",
@@ -67,6 +69,11 @@ var lintTool = {
67
69
  });
68
70
  if (bridge?.run) {
69
71
  const run = bridge.run;
72
+ if (run.status === "unavailable" || run.status === "cancelled" || run.status === "timed_out") {
73
+ throw new Error(
74
+ `lint: ${bridge.language} lint did not run (${run.status})${run.error ? `: ${run.error}` : ""}`
75
+ );
76
+ }
70
77
  yield {
71
78
  type: "final",
72
79
  output: {
@@ -108,6 +115,16 @@ var lintTool = {
108
115
  });
109
116
  }
110
117
  }
118
+ for (const f of files) {
119
+ try {
120
+ ensureInsideRoot(path.resolve(cwd, f), ctx);
121
+ } catch (err) {
122
+ throw new ToolValidationError({
123
+ message: `lint: file "${f}" ${err.message}`,
124
+ field: "files"
125
+ });
126
+ }
127
+ }
111
128
  const args = [];
112
129
  if (detected === "eslint") {
113
130
  if (input.fix) args.push("--fix");
@@ -119,6 +136,9 @@ var lintTool = {
119
136
  }
120
137
  const cmd = detected === "biome" ? "biome" : detected;
121
138
  const result = yield* spawnStream({ cmd, args, cwd, signal, maxBytes: 1e5 });
139
+ if (result.error) {
140
+ throw new Error(`lint: could not run ${cmd}: ${result.error}`);
141
+ }
122
142
  const combined = `${result.stdout}
123
143
  ${result.stderr}`;
124
144
  let errors = 0;
@@ -189,4 +209,4 @@ async function detectLinter(cwd) {
189
209
  export {
190
210
  lintTool
191
211
  };
192
- //# sourceMappingURL=chunk-R3HIZVFS.js.map
212
+ //# sourceMappingURL=chunk-KPDCKSN5.js.map
@@ -1,6 +1,7 @@
1
1
  // src/tool-use.ts
2
2
  import {
3
- GOVERNED_TOOL_EXECUTOR_META_KEY
3
+ GOVERNED_TOOL_EXECUTOR_META_KEY,
4
+ ToolValidationError
4
5
  } from "@wrongstack/core/types";
5
6
  var toolUseTool = {
6
7
  name: "tool_use",
@@ -33,67 +34,42 @@ var toolUseTool = {
33
34
  async execute(input, ctx) {
34
35
  const start = Date.now();
35
36
  if (!input?.tool) {
36
- return {
37
- tool: "unknown",
38
- success: false,
39
- error: "tool_use: tool name is required",
40
- executionMs: 0
41
- };
37
+ throw new ToolValidationError({ message: "tool_use: tool name is required", field: "tool" });
42
38
  }
43
39
  const tool = (ctx.catalogTools ?? ctx.tools).find((t) => t.name === input.tool);
44
40
  if (!tool) {
45
- return {
46
- tool: input.tool,
47
- success: false,
48
- error: `tool_use: tool "${input.tool}" not found`,
49
- executionMs: Date.now() - start
50
- };
41
+ throw new ToolValidationError({
42
+ message: `tool_use: tool "${input.tool}" not found`,
43
+ field: "tool"
44
+ });
51
45
  }
52
46
  if (tool.name === toolUseTool.name) {
53
- return {
54
- tool: input.tool,
55
- success: false,
56
- error: "tool_use: recursive meta-tool execution is not allowed",
57
- executionMs: Date.now() - start
58
- };
47
+ throw new ToolValidationError({
48
+ message: "tool_use: recursive meta-tool execution is not allowed",
49
+ field: "tool"
50
+ });
59
51
  }
60
52
  if (tool.permission === "deny") {
61
- return {
62
- tool: input.tool,
63
- success: false,
64
- error: `tool_use: tool "${input.tool}" is denied by policy`,
65
- executionMs: Date.now() - start
66
- };
53
+ throw new Error(`tool_use: tool "${input.tool}" is denied by policy`);
67
54
  }
68
55
  const governedExecute = ctx.meta?.[GOVERNED_TOOL_EXECUTOR_META_KEY];
69
56
  if (typeof governedExecute !== "function") {
70
- return {
71
- tool: input.tool,
72
- success: false,
73
- error: "tool_use: governed nested execution is unavailable; call the tool directly",
74
- executionMs: Date.now() - start
75
- };
57
+ throw new Error("tool_use: governed nested execution is unavailable; call the tool directly");
76
58
  }
77
- try {
78
- const result = await governedExecute(input.tool, input.input ?? {});
79
- return {
80
- tool: input.tool,
81
- success: result.success,
82
- ...result.success ? { result: result.result } : { error: result.error ?? "nested tool failed" },
83
- executionMs: Date.now() - start
84
- };
85
- } catch (e) {
86
- return {
87
- tool: input.tool,
88
- success: false,
89
- error: e instanceof Error ? e.message : String(e),
90
- executionMs: Date.now() - start
91
- };
59
+ const result = await governedExecute(input.tool, input.input ?? {});
60
+ if (!result.success) {
61
+ throw new Error(`tool_use: "${input.tool}" failed: ${result.error ?? "nested tool failed"}`);
92
62
  }
63
+ return {
64
+ tool: input.tool,
65
+ success: true,
66
+ result: result.result,
67
+ executionMs: Date.now() - start
68
+ };
93
69
  }
94
70
  };
95
71
 
96
72
  export {
97
73
  toolUseTool
98
74
  };
99
- //# sourceMappingURL=chunk-B3MGJBFI.js.map
75
+ //# sourceMappingURL=chunk-KS2OEZWV.js.map
@@ -1,4 +1,5 @@
1
1
  // src/mode.ts
2
+ import { ToolValidationError } from "@wrongstack/core/types";
2
3
  function modeFamily(mode) {
3
4
  if (mode.tags?.includes("lite")) return "lite";
4
5
  if (mode.tags?.includes("deep")) return "deep";
@@ -63,11 +64,17 @@ function createModeTool(modeStore) {
63
64
  }
64
65
  case "set": {
65
66
  if (!input.mode) {
66
- return { action: "set", success: false, message: "mode is required for action=set" };
67
+ throw new ToolValidationError({
68
+ message: "mode: mode is required for action=set",
69
+ field: "mode"
70
+ });
67
71
  }
68
72
  const mode = await modeStore.getMode(input.mode);
69
73
  if (!mode) {
70
- return { action: "set", success: false, message: `Mode "${input.mode}" not found` };
74
+ throw new ToolValidationError({
75
+ message: `mode: Mode "${input.mode}" not found \u2014 use action=list to see available modes`,
76
+ field: "mode"
77
+ });
71
78
  }
72
79
  await modeStore.setActiveMode(input.mode);
73
80
  return {
@@ -88,11 +95,10 @@ ${mode.description}`
88
95
  };
89
96
  }
90
97
  default:
91
- return {
92
- action: input.action,
93
- success: false,
94
- message: `Unknown action "${input.action}"`
95
- };
98
+ throw new ToolValidationError({
99
+ message: `mode: Unknown action "${input?.action}". Allowed: get, list, set, clear`,
100
+ field: "action"
101
+ });
96
102
  }
97
103
  }
98
104
  };
@@ -101,4 +107,4 @@ ${mode.description}`
101
107
  export {
102
108
  createModeTool
103
109
  };
104
- //# sourceMappingURL=chunk-UI3ZJIG3.js.map
110
+ //# sourceMappingURL=chunk-LKLIQUCW.js.map