@wrongstack/tools 1.0.8 → 1.0.9

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 (135) hide show
  1. package/dist/_win32-resolve.d.ts +5 -0
  2. package/dist/audit.js +5 -5
  3. package/dist/bash.js +2 -2
  4. package/dist/browser/index.js +1 -1
  5. package/dist/builtin.js +41 -41
  6. package/dist/{chunk-N3OTTQNC.js → chunk-2OCAAFAT.js} +44 -25
  7. package/dist/{chunk-5MP76C72.js → chunk-2UVAIS5O.js} +24 -29
  8. package/dist/{chunk-SIIOHBNY.js → chunk-3RRK33YM.js} +2 -2
  9. package/dist/{chunk-M2W36JT7.js → chunk-4CE3RKEP.js} +6 -3
  10. package/dist/{chunk-QJARSK2G.js → chunk-4SUGLJLO.js} +11 -3
  11. package/dist/{chunk-AH7J5HWL.js → chunk-5RBUYFRV.js} +15 -7
  12. package/dist/{chunk-WKLUOXR4.js → chunk-7GOE2ZTZ.js} +2 -2
  13. package/dist/{chunk-O6AGFJBO.js → chunk-7V33PHT6.js} +49 -77
  14. package/dist/{chunk-CAF4L6KN.js → chunk-C3WP6ZOT.js} +36 -48
  15. package/dist/{chunk-KMXPP32M.js → chunk-C6ZOXNXV.js} +13 -3
  16. package/dist/{chunk-EGT5QLCB.js → chunk-D6RQZMZS.js} +123 -255
  17. package/dist/{chunk-S6CGSFLX.js → chunk-DBG7UQGK.js} +10 -3
  18. package/dist/{chunk-FI6SOIVE.js → chunk-DLZCOEVG.js} +21 -3
  19. package/dist/{chunk-NL45OWEO.js → chunk-DOAHONOS.js} +7 -12
  20. package/dist/{chunk-3LQJXJDM.js → chunk-E7A4SLKR.js} +2 -2
  21. package/dist/{chunk-JB5JLY7V.js → chunk-ENE22I5W.js} +387 -394
  22. package/dist/{chunk-SEONDNLN.js → chunk-G7CYW5EP.js} +2 -2
  23. package/dist/{chunk-MF6ZUBI7.js → chunk-HV7RWDCL.js} +3 -3
  24. package/dist/{chunk-TU6UVATU.js → chunk-HYHE4VNA.js} +3 -3
  25. package/dist/{chunk-HIRVCXLP.js → chunk-IE4KDAOB.js} +3 -3
  26. package/dist/{chunk-YA2ZYCJY.js → chunk-JPK2HHBK.js} +1 -1
  27. package/dist/{chunk-7E55DAFW.js → chunk-KHUCKLOR.js} +12 -7
  28. package/dist/{chunk-R3HIZVFS.js → chunk-KPDCKSN5.js} +23 -3
  29. package/dist/{chunk-B3MGJBFI.js → chunk-KS2OEZWV.js} +23 -47
  30. package/dist/{chunk-UI3ZJIG3.js → chunk-LKLIQUCW.js} +14 -8
  31. package/dist/{chunk-62OAECEQ.js → chunk-LLSFOUZF.js} +8 -8
  32. package/dist/{chunk-YZQSUL5G.js → chunk-M4ZHHCCW.js} +14 -6
  33. package/dist/{chunk-IXIS7RSG.js → chunk-MRXWOOOR.js} +29 -47
  34. package/dist/{chunk-C4DSQBTT.js → chunk-NEYUPZL6.js} +3 -3
  35. package/dist/{chunk-6XYFYLN7.js → chunk-O2MHULBO.js} +13 -8
  36. package/dist/{chunk-B62LKMWQ.js → chunk-OKZJJDOG.js} +86 -188
  37. package/dist/{chunk-HOFVYIPI.js → chunk-ON6ET5ER.js} +16 -1
  38. package/dist/{chunk-KF7GMVNU.js → chunk-OUERRFEM.js} +32 -11
  39. package/dist/{chunk-GNLHBDFO.js → chunk-OXO773CW.js} +127 -196
  40. package/dist/{chunk-GF4JHLCO.js → chunk-PWZUHZP7.js} +2 -2
  41. package/dist/{chunk-5KRKL3WD.js → chunk-QA37PFYL.js} +28 -67
  42. package/dist/{chunk-OGQMPX3J.js → chunk-QAWI3RSK.js} +37 -81
  43. package/dist/{chunk-ZMCV3XOV.js → chunk-SPNXDTCJ.js} +29 -63
  44. package/dist/{chunk-H2VB7GCR.js → chunk-ULI2J6TX.js} +27 -14
  45. package/dist/{chunk-EMA2XENR.js → chunk-UVYRQKPZ.js} +4 -3
  46. package/dist/{chunk-2NTHMZV3.js → chunk-VMJY6FYJ.js} +693 -276
  47. package/dist/{chunk-YUK3WLHJ.js → chunk-WEUEU53R.js} +2 -2
  48. package/dist/{chunk-ZOUG3KKS.js → chunk-XPVYZ2S6.js} +2 -2
  49. package/dist/{chunk-5U5ULQX2.js → chunk-XZLVJD56.js} +5 -1
  50. package/dist/{chunk-HCPSVK7J.js → chunk-YKSOSI2N.js} +47 -31
  51. package/dist/codebase-index/codebase-ast-replace-tool.d.ts +5 -6
  52. package/dist/codebase-index/codebase-context-tool.d.ts +4 -6
  53. package/dist/codebase-index/codebase-impact-analysis-tool.d.ts +1 -2
  54. package/dist/codebase-index/codebase-incoming-calls-tool.d.ts +0 -2
  55. package/dist/codebase-index/codebase-index-tool.d.ts +0 -2
  56. package/dist/codebase-index/codebase-invariant-check-tool.d.ts +1 -2
  57. package/dist/codebase-index/codebase-outgoing-calls-tool.d.ts +0 -2
  58. package/dist/codebase-index/codebase-repo-map-tool.d.ts +1 -2
  59. package/dist/codebase-index/codebase-search-tool.d.ts +1 -1
  60. package/dist/codebase-index/codebase-targeted-test-tool.d.ts +1 -2
  61. package/dist/codebase-index/index.js +8 -8
  62. package/dist/codebase-index/parser-worker-script.js +3 -3
  63. package/dist/codebase-index/project-server.js +5 -5
  64. package/dist/codebase-index/worker.js +4 -4
  65. package/dist/design.js +1 -1
  66. package/dist/diff.js +1 -1
  67. package/dist/edit.js +7 -7
  68. package/dist/exec.d.ts +7 -7
  69. package/dist/exec.js +2 -2
  70. package/dist/format.js +5 -5
  71. package/dist/git.js +1 -1
  72. package/dist/glob.js +1 -1
  73. package/dist/{go-parser-VDPRQEGM.js → go-parser-Z4H6SR3R.js} +6 -3
  74. package/dist/grep.js +1 -1
  75. package/dist/index.js +45 -45
  76. package/dist/install.js +5 -5
  77. package/dist/json.d.ts +0 -1
  78. package/dist/json.js +1 -1
  79. package/dist/kanban-presence.d.ts +6 -0
  80. package/dist/kanban-serializer.d.ts +9 -1
  81. package/dist/kanban-split-task-handler.d.ts +1 -1
  82. package/dist/kanban-tool-results.d.ts +57 -2
  83. package/dist/kanban-tool-types.d.ts +16 -5
  84. package/dist/kanban.d.ts +14 -0
  85. package/dist/kanban.js +9 -1
  86. package/dist/languages/index.js +3 -3
  87. package/dist/{legacy-bridge-4T4OTSQP.js → legacy-bridge-BPT2S2F4.js} +5 -5
  88. package/dist/lint.js +5 -5
  89. package/dist/logs.js +1 -1
  90. package/dist/mode.d.ts +3 -2
  91. package/dist/mode.js +1 -1
  92. package/dist/outdated.js +2 -2
  93. package/dist/pack.js +42 -42
  94. package/dist/{parser-dispatch-4E2SDQUO.js → parser-dispatch-WG4DNBHH.js} +4 -4
  95. package/dist/patch.js +7 -7
  96. package/dist/plan.d.ts +2 -1
  97. package/dist/plan.js +3 -3
  98. package/dist/{py-parser-MAW6DHFE.js → py-parser-4PFZYAJ7.js} +3 -3
  99. package/dist/read.js +7 -7
  100. package/dist/replace.js +7 -7
  101. package/dist/search.d.ts +0 -6
  102. package/dist/search.js +1 -1
  103. package/dist/security-ast-scan-tool.d.ts +1 -2
  104. package/dist/session-shell.js +2 -2
  105. package/dist/task.d.ts +2 -1
  106. package/dist/task.js +3 -3
  107. package/dist/test.d.ts +8 -1
  108. package/dist/test.js +5 -5
  109. package/dist/todo.js +2 -2
  110. package/dist/tool-search.d.ts +2 -0
  111. package/dist/tool-search.js +1 -1
  112. package/dist/tool-tier.js +43 -43
  113. package/dist/tool-use.d.ts +2 -2
  114. package/dist/tool-use.js +1 -1
  115. package/dist/tree.js +1 -1
  116. package/dist/typecheck.js +5 -5
  117. package/dist/wasm/bash/tree-sitter-bash.wasm +0 -0
  118. package/dist/wasm/c/tree-sitter-c.wasm +0 -0
  119. package/dist/wasm/c_sharp/tree-sitter-c_sharp.wasm +0 -0
  120. package/dist/wasm/checksums.json +16 -0
  121. package/dist/wasm/cpp/tree-sitter-cpp.wasm +0 -0
  122. package/dist/wasm/elixir/tree-sitter-elixir.wasm +0 -0
  123. package/dist/wasm/go/tree-sitter-go.wasm +0 -0
  124. package/dist/wasm/java/tree-sitter-java.wasm +0 -0
  125. package/dist/wasm/kotlin/tree-sitter-kotlin.wasm +0 -0
  126. package/dist/wasm/php/tree-sitter-php.wasm +0 -0
  127. package/dist/wasm/python/tree-sitter-python.wasm +0 -0
  128. package/dist/wasm/ruby/tree-sitter-ruby.wasm +0 -0
  129. package/dist/wasm/rust/tree-sitter-rust.wasm +0 -0
  130. package/dist/wasm/swift/tree-sitter-swift.wasm +0 -0
  131. package/dist/wasm/tree-sitter-runtime.wasm +0 -0
  132. package/dist/win32.d.ts +1 -1
  133. package/dist/win32.js +3 -1
  134. package/dist/write.js +7 -7
  135. package/package.json +10 -10
@@ -14,8 +14,9 @@ import {
14
14
  } from "./chunk-HDYUBRMF.js";
15
15
  import {
16
16
  buildWin32CmdShimInvocation,
17
+ isWinCmdShim,
17
18
  resolveWin32Command
18
- } from "./chunk-5U5ULQX2.js";
19
+ } from "./chunk-XZLVJD56.js";
19
20
  import {
20
21
  COMMAND_OUTPUT_MAX_BYTES,
21
22
  normalizeCommandOutput,
@@ -1473,7 +1474,6 @@ function validateArgs(cmd, args) {
1473
1474
  }
1474
1475
  return null;
1475
1476
  }
1476
- var SAFE_DANGER = { level: "safe", reasons: [] };
1477
1477
  var execTool = {
1478
1478
  name: "exec",
1479
1479
  category: "Shell",
@@ -1526,43 +1526,23 @@ var execTool = {
1526
1526
  },
1527
1527
  required: ["command"]
1528
1528
  },
1529
+ // Refusals (breaker, allowlist, blocked args, kill guard, cwd containment)
1530
+ // and launch failures THROW: a returned `allowed: false` / `exitCode: 1`
1531
+ // payload was recorded by the executor as a successful call. Non-zero
1532
+ // exits, timeouts and aborts remain data (the command did run).
1529
1533
  async execute(input, ctx, opts) {
1530
1534
  const registry = getProcessRegistry();
1531
1535
  if (!registry.canProceed) {
1532
- return {
1533
- command: input.command,
1534
- args: input.args ?? [],
1535
- stdout: "",
1536
- stderr: "Circuit breaker is open \u2014 too many consecutive failures. Use /kill reset to recover.",
1537
- exitCode: 1,
1538
- truncated: false,
1539
- allowed: false,
1540
- danger: SAFE_DANGER
1541
- };
1536
+ throw new Error(
1537
+ "exec: circuit breaker is open \u2014 too many consecutive failures. Use /kill reset to recover."
1538
+ );
1542
1539
  }
1543
- const cmd = input.command.trim();
1544
- if (!cmd)
1545
- return {
1546
- command: cmd,
1547
- args: [],
1548
- stdout: "",
1549
- stderr: "Empty command",
1550
- exitCode: 1,
1551
- truncated: false,
1552
- allowed: false,
1553
- danger: SAFE_DANGER
1554
- };
1540
+ const cmd = (input.command ?? "").trim();
1541
+ if (!cmd) throw new Error("exec: empty command");
1555
1542
  if (!isExecCommandAllowed(cmd)) {
1556
- return {
1557
- command: cmd,
1558
- args: input.args ?? [],
1559
- stdout: "",
1560
- stderr: `Command "${cmd}" not in allowlist. Add it to your active profile config (~/.wrongstack/profiles/<name>/config.json) under "tools": { "exec": { "allow": ["${cmd}"] } }, or use the bash tool for one-off arbitrary commands.`,
1561
- exitCode: 1,
1562
- truncated: false,
1563
- allowed: false,
1564
- danger: SAFE_DANGER
1565
- };
1543
+ throw new Error(
1544
+ `exec: command "${cmd}" not in allowlist. Add it to your active profile config (~/.wrongstack/profiles/<name>/config.json) under "tools": { "exec": { "allow": ["${cmd}"] } }, or use the bash tool for one-off arbitrary commands.`
1545
+ );
1566
1546
  }
1567
1547
  const args = (input.args ?? []).slice(0, MAX_ARGS);
1568
1548
  const rawTimeout = typeof input.timeout === "number" && !Number.isNaN(input.timeout) ? input.timeout : DEFAULT_TIMEOUT_MS;
@@ -1570,45 +1550,22 @@ var execTool = {
1570
1550
  const danger = detectDanger(cmd, args, dangerBypass);
1571
1551
  const killCheck = await checkExecKillCommand(cmd, args);
1572
1552
  if (killCheck.blocked) {
1573
- return {
1574
- command: cmd,
1575
- args,
1576
- stdout: "",
1577
- stderr: killCheck.reason ?? "Kill command blocked: targets a protected WrongStack process.",
1578
- exitCode: 1,
1579
- truncated: false,
1580
- allowed: false,
1581
- danger
1582
- };
1553
+ throw new Error(
1554
+ `exec: ${killCheck.reason ?? "Kill command blocked: targets a protected WrongStack process."}`
1555
+ );
1583
1556
  }
1584
1557
  const argError = validateArgs(cmd, args);
1585
1558
  if (argError) {
1586
- return {
1587
- command: cmd,
1588
- args,
1589
- stdout: "",
1590
- stderr: argError,
1591
- exitCode: 1,
1592
- truncated: false,
1593
- allowed: false,
1594
- danger
1595
- };
1559
+ throw new Error(`exec: ${argError}`);
1596
1560
  }
1597
1561
  const defaultCwd = ctx.workingDir ?? ctx.cwd;
1598
1562
  let cwd;
1599
1563
  try {
1600
1564
  cwd = input.cwd ? await safeResolveReal(input.cwd, ctx) : await safeResolveReal(defaultCwd, ctx);
1601
- } catch {
1602
- return {
1603
- command: cmd,
1604
- args,
1605
- stdout: "",
1606
- stderr: `cwd "${input.cwd ?? defaultCwd}" resolves outside project root`,
1607
- exitCode: 1,
1608
- truncated: false,
1609
- allowed: false,
1610
- danger
1611
- };
1565
+ } catch (err) {
1566
+ throw new Error(`exec: cwd "${input.cwd ?? defaultCwd}" resolves outside project root`, {
1567
+ cause: err
1568
+ });
1612
1569
  }
1613
1570
  const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
1614
1571
  if (signal.aborted) {
@@ -1638,7 +1595,7 @@ var execTool = {
1638
1595
  }
1639
1596
  };
1640
1597
  function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
1641
- return new Promise((resolve) => {
1598
+ return new Promise((resolve, reject) => {
1642
1599
  let stdout = "";
1643
1600
  let stderr = "";
1644
1601
  let killed = false;
@@ -1648,6 +1605,11 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
1648
1605
  resolvedOnce.value = true;
1649
1606
  resolve(result);
1650
1607
  };
1608
+ const fail = (err) => {
1609
+ if (resolvedOnce.value) return;
1610
+ resolvedOnce.value = true;
1611
+ reject(err);
1612
+ };
1651
1613
  const startedAt = Date.now();
1652
1614
  let stdoutBytes = 0;
1653
1615
  let stderrBytes = 0;
@@ -1685,7 +1647,7 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
1685
1647
  let child;
1686
1648
  try {
1687
1649
  const resolved = resolveWin32Command(cmd);
1688
- const needsShell = isWin2 && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
1650
+ const needsShell = isWin2 && isWinCmdShim(resolved);
1689
1651
  const shim = needsShell ? buildWin32CmdShimInvocation(resolved, args) : null;
1690
1652
  const spawnCmd = shim?.command ?? resolved;
1691
1653
  const spawnArgs = shim?.args ?? args;
@@ -1709,16 +1671,7 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
1709
1671
  startedAt: new Date(startedAt).toISOString()
1710
1672
  });
1711
1673
  emitCompletedOnce(1, void 0);
1712
- finish({
1713
- command: cmd,
1714
- args,
1715
- stdout: "",
1716
- stderr: `spawn failed: ${toErrorMessage(err)}`,
1717
- exitCode: 1,
1718
- truncated: false,
1719
- allowed: true,
1720
- danger
1721
- });
1674
+ fail(new Error(`exec: spawn failed: ${toErrorMessage(err)}`, { cause: err }));
1722
1675
  return;
1723
1676
  }
1724
1677
  emitProcessStarted({
@@ -1740,19 +1693,22 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
1740
1693
  };
1741
1694
  child.on("error", (err) => {
1742
1695
  const isAbort = err && err.code === "ABORT_ERR";
1743
- const stderrText = isAbort ? `Aborted: ${err.message}` : err.message;
1744
1696
  if (timer !== void 0) clearTimeout(timer);
1745
1697
  if (isWin2) signal.removeEventListener("abort", onAbort);
1746
1698
  if (typeof pid === "number") registry.unregister(pid);
1747
1699
  registry.afterCall(Date.now() - startedAt, true);
1748
1700
  spool.finalize();
1749
1701
  emitCompletedOnce(isAbort ? 124 : 1, child.pid, isAbort ? "ABORT" : void 0);
1702
+ if (!isAbort) {
1703
+ fail(new Error(`exec: process error: ${err.message}`, { cause: err }));
1704
+ return;
1705
+ }
1750
1706
  finish({
1751
1707
  command: cmd,
1752
1708
  args,
1753
1709
  stdout: normalizeCommandOutput(stdout),
1754
- stderr: stderrText,
1755
- exitCode: isAbort ? 124 : 1,
1710
+ stderr: `Aborted: ${err.message}`,
1711
+ exitCode: 124,
1756
1712
  truncated: Buffer.byteLength(stdout, "utf8") > COMMAND_OUTPUT_MAX_BYTES,
1757
1713
  allowed: true,
1758
1714
  danger
@@ -1846,4 +1802,4 @@ export {
1846
1802
  getExecAllowlist,
1847
1803
  execTool
1848
1804
  };
1849
- //# sourceMappingURL=chunk-OGQMPX3J.js.map
1805
+ //# sourceMappingURL=chunk-QAWI3RSK.js.map
@@ -110,29 +110,18 @@ var gitTool = {
110
110
  });
111
111
  }
112
112
  if (input.command === "commit" && !input.message) {
113
- return {
114
- command: "commit",
115
- stdout: "",
116
- stderr: "git commit requires a message (-m flag)",
117
- exitCode: 1,
118
- truncated: false
119
- };
113
+ throw new ToolValidationError({
114
+ message: "git: commit requires a message",
115
+ field: "message"
116
+ });
120
117
  }
121
- const branchGuard = validateBranchInput(input);
122
- if (branchGuard) return branchGuard;
118
+ assertSafeBranch(input);
123
119
  if (input.command === "worktree") {
124
- const guard = validateWorktreeInput(input, ctx.projectRoot);
125
- if (guard) return guard;
120
+ assertSafeWorktreeInput(input, ctx.projectRoot);
126
121
  }
127
122
  const gitDir = findGitDir(ctx.cwd, ctx.projectRoot);
128
123
  if (!gitDir) {
129
- return {
130
- command: input.command,
131
- stdout: "",
132
- stderr: "Not in a git repository (within project root)",
133
- exitCode: 128,
134
- truncated: false
135
- };
124
+ throw new Error(`git: Not in a git repository (within project root ${ctx.projectRoot})`);
136
125
  }
137
126
  const args = buildArgs(input);
138
127
  const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
@@ -169,37 +158,32 @@ var gitTool = {
169
158
  return result;
170
159
  }
171
160
  };
172
- function validateBranchInput(input) {
161
+ function assertSafeBranch(input) {
173
162
  const branch = input.branch;
174
- if (branch === void 0) return null;
175
- if (!branch.startsWith("-") && !branch.includes(" --")) return null;
176
- return {
177
- command: input.command,
178
- stdout: "",
179
- stderr: `unsafe branch name (parsed as a git option): ${branch}`,
180
- exitCode: 1,
181
- truncated: false
182
- };
183
- }
184
- function validateWorktreeInput(input, projectRoot) {
185
- const reject = (stderr) => ({
186
- command: "worktree",
187
- stdout: "",
188
- stderr,
189
- exitCode: 1,
190
- truncated: false
163
+ if (branch === void 0) return;
164
+ if (!branch.startsWith("-") && !branch.includes(" --")) return;
165
+ throw new ToolValidationError({
166
+ message: `git: unsafe branch name (parsed as a git option): ${branch}`,
167
+ field: "branch"
191
168
  });
169
+ }
170
+ function assertSafeWorktreeInput(input, projectRoot) {
171
+ const reject = (message) => {
172
+ throw new ToolValidationError({ message: `git: ${message}`, field: "worktreePath" });
173
+ };
192
174
  if (input.worktreePath?.startsWith("-")) {
193
- return reject(`unsafe worktree path: ${input.worktreePath}`);
175
+ reject(`unsafe worktree path: ${input.worktreePath}`);
176
+ }
177
+ if (input.worktreeAction === "add" && !input.worktreePath) {
178
+ reject("worktree add requires worktreePath");
194
179
  }
195
180
  if ((input.worktreeAction === "add" || input.worktreeAction === "remove") && input.worktreePath) {
196
181
  const root = resolve(projectRoot);
197
182
  const abs = resolve(root, input.worktreePath);
198
183
  if (abs !== root && !abs.startsWith(root + sep)) {
199
- return reject(`unsafe worktree path (escapes project root): ${input.worktreePath}`);
184
+ reject(`unsafe worktree path (escapes project root): ${input.worktreePath}`);
200
185
  }
201
186
  }
202
- return null;
203
187
  }
204
188
  function findGitDir(cwd, projectRoot) {
205
189
  const root = projectRoot;
@@ -296,15 +280,9 @@ function buildArgs(input) {
296
280
  }
297
281
  function runGit(args, cwd, signal) {
298
282
  if (signal.aborted) {
299
- return Promise.resolve({
300
- command: args[0],
301
- stdout: "",
302
- stderr: "Aborted",
303
- exitCode: 124,
304
- truncated: false
305
- });
283
+ return Promise.reject(signal.reason ?? new Error("git: aborted"));
306
284
  }
307
- return new Promise((resolve2) => {
285
+ return new Promise((resolve2, reject) => {
308
286
  let stdout = "";
309
287
  let stderr = "";
310
288
  let stdoutBytes = 0;
@@ -333,21 +311,9 @@ function runGit(args, cwd, signal) {
333
311
  }
334
312
  });
335
313
  child.on("error", (err) => {
336
- const stdoutTail = stdoutDecoder.end();
337
- if (stdoutTail && stdout.length < MAX_OUTPUT) {
338
- stdout += stdoutTail.slice(0, MAX_OUTPUT - stdout.length);
339
- }
340
- const stderrTail = stderrDecoder.end();
341
- if (stderrTail && stderr.length < MAX_OUTPUT) {
342
- stderr += stderrTail.slice(0, MAX_OUTPUT - stderr.length);
343
- }
344
- resolve2({
345
- command: args[0],
346
- stdout: normalizeCommandOutput(stdout),
347
- stderr: err.message,
348
- exitCode: 1,
349
- truncated: stdoutBytes > MAX_OUTPUT || Buffer.byteLength(stdout, "utf8") > COMMAND_OUTPUT_MAX_BYTES
350
- });
314
+ reject(
315
+ err.code === "ABORT_ERR" ? err : new Error(`git: could not run git ${args[0] ?? ""}: ${err.message}`, { cause: err })
316
+ );
351
317
  });
352
318
  child.on("close", (code) => {
353
319
  const stdoutTail = stdoutDecoder.end();
@@ -373,4 +339,4 @@ function runGit(args, cwd, signal) {
373
339
  export {
374
340
  gitTool
375
341
  };
376
- //# sourceMappingURL=chunk-ZMCV3XOV.js.map
342
+ //# sourceMappingURL=chunk-SPNXDTCJ.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  tryLegacyPackageOperation
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
8
  detectPackageManager,
9
9
  normalizeCommandOutput,
@@ -119,6 +119,11 @@ var installTool = {
119
119
  if (bridge?.outcome) {
120
120
  const outcome = bridge.outcome;
121
121
  const run = outcome.run;
122
+ if (outcome.status !== "passed") {
123
+ throw new Error(
124
+ `install: ${bridge.language} package install ${outcome.status}${run?.exitCode != null ? ` (exit ${run.exitCode})` : ""}${run?.error ? `: ${run.error}` : ""}${failureTail(run?.output ?? "")}`
125
+ );
126
+ }
122
127
  yield {
123
128
  type: "final",
124
129
  output: {
@@ -143,17 +148,10 @@ var installTool = {
143
148
  const PKG_NAME_RE = /^(?:@[a-z0-9._-]+\/)?[a-z0-9._-]+(?:@[a-z0-9^~><=*.+-]+)?$/i;
144
149
  for (const pkg of pkgList) {
145
150
  if (!PKG_NAME_RE.test(pkg) || pkg.startsWith("-") || pkg.length > 200) {
146
- yield {
147
- type: "final",
148
- output: {
149
- packages: pkgList,
150
- exit_code: 1,
151
- output: `Invalid package name "${pkg}". Names must match ${PKG_NAME_RE} and not start with "-".`,
152
- dry_run: Boolean(input.dry_run),
153
- truncated: false
154
- }
155
- };
156
- return;
151
+ throw new ToolValidationError({
152
+ message: `install: Invalid package name "${pkg}". Names must match ${PKG_NAME_RE} and not start with "-".`,
153
+ field: "packages"
154
+ });
157
155
  }
158
156
  }
159
157
  const hasPkgs = pkgList.length > 0;
@@ -196,6 +194,9 @@ var installTool = {
196
194
  signal,
197
195
  maxBytes: 1e5
198
196
  });
197
+ if (result.error) {
198
+ throw new Error(`install: could not run ${pkgManager}: ${result.error}`);
199
+ }
199
200
  const rawOutput = result.stdout && result.stderr ? `${result.stdout}
200
201
  ${result.stderr}` : result.stdout || result.stderr || result.error || "";
201
202
  const output = {
@@ -235,9 +236,21 @@ ${result.stderr}` : result.stdout || result.stderr || result.error || "";
235
236
  outcome: output.dry_run ? "dry run" : result.exitCode === 0 ? `installed ${pkgList.length || "all"} packages` : `failed (exit ${result.exitCode})`,
236
237
  risk: "package"
237
238
  });
239
+ if (result.exitCode !== 0) {
240
+ throw new Error(
241
+ `install: ${pkgManager} ${args.filter((a) => !a.startsWith("-")).join(" ")} failed (exit ${result.exitCode})${failureTail(output.output)}`
242
+ );
243
+ }
238
244
  yield { type: "final", output };
239
245
  }
240
246
  };
247
+ function failureTail(output) {
248
+ const trimmed = output.trim();
249
+ if (!trimmed) return "";
250
+ const MAX = 4e3;
251
+ return `:
252
+ ${trimmed.length > MAX ? `\u2026${trimmed.slice(-MAX)}` : trimmed}`;
253
+ }
241
254
  function resolveManifestPath(cwd, pkgManager) {
242
255
  switch (pkgManager) {
243
256
  case "pnpm":
@@ -253,4 +266,4 @@ function resolveManifestPath(cwd, pkgManager) {
253
266
  export {
254
267
  installTool
255
268
  };
256
- //# sourceMappingURL=chunk-H2VB7GCR.js.map
269
+ //# sourceMappingURL=chunk-ULI2J6TX.js.map
@@ -8,8 +8,9 @@ import {
8
8
  } from "./chunk-HDYUBRMF.js";
9
9
  import {
10
10
  buildWin32CmdShimInvocation,
11
+ isWinCmdShim,
11
12
  resolveWin32Command
12
- } from "./chunk-5U5ULQX2.js";
13
+ } from "./chunk-XZLVJD56.js";
13
14
 
14
15
  // src/_spawn-stream.ts
15
16
  import { spawn } from "node:child_process";
@@ -35,7 +36,7 @@ async function* spawnStream(opts) {
35
36
  let error;
36
37
  const spool = createOutputSpool({ tool: opts.cmd, thresholdBytes: max });
37
38
  const resolved = resolveWin32Command(opts.cmd);
38
- const needsShell = isWin && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
39
+ const needsShell = isWin && isWinCmdShim(resolved);
39
40
  const shim = needsShell ? buildWin32CmdShimInvocation(resolved, opts.args) : null;
40
41
  const cmd = shim?.command ?? resolved;
41
42
  const args = shim?.args ?? opts.args;
@@ -285,4 +286,4 @@ function utf8Prefix(text, maxBytes) {
285
286
  export {
286
287
  spawnStream
287
288
  };
288
- //# sourceMappingURL=chunk-EMA2XENR.js.map
289
+ //# sourceMappingURL=chunk-UVYRQKPZ.js.map