@wrongstack/tools 0.318.0 → 0.319.1

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 (101) hide show
  1. package/dist/_edit-match.d.ts +1 -3
  2. package/dist/_util.d.ts +20 -0
  3. package/dist/audit.js +4 -4
  4. package/dist/bash.js +2 -2
  5. package/dist/builtin.d.ts +10 -0
  6. package/dist/builtin.js +46 -44
  7. package/dist/{chunk-TKA4VEX2.js → chunk-2OXHS3KZ.js} +17 -5
  8. package/dist/{chunk-X5K3U6GI.js → chunk-3M7LLN7W.js} +71 -7
  9. package/dist/{chunk-4AEZIFOW.js → chunk-5EUJF3WC.js} +36 -8
  10. package/dist/{chunk-CVALEVGA.js → chunk-64VIJPFV.js} +34 -13
  11. package/dist/{chunk-ZE6KLBUO.js → chunk-6AAOT4PW.js} +58 -10
  12. package/dist/{chunk-A6BRWIXN.js → chunk-6IEBD27U.js} +20 -5
  13. package/dist/{chunk-HTYEO67J.js → chunk-AKHYMB4V.js} +36 -12
  14. package/dist/{chunk-4E42D7UF.js → chunk-ATSKPZUK.js} +2 -2
  15. package/dist/{chunk-H6AWAZ2Y.js → chunk-B4HTSV6Z.js} +57 -6
  16. package/dist/{chunk-5ZYEGP2P.js → chunk-BK732J7I.js} +72 -27
  17. package/dist/{chunk-WI3VDXHD.js → chunk-BSJSNVGA.js} +108 -19
  18. package/dist/{chunk-UKGMDCXT.js → chunk-C2DQKVLO.js} +61 -28
  19. package/dist/{chunk-CIFAIIHI.js → chunk-CFLJFDYV.js} +100 -58
  20. package/dist/{chunk-JJQB6R7Y.js → chunk-CMOUCKGC.js} +6 -6
  21. package/dist/{chunk-MX25MTDJ.js → chunk-DC4KMPJO.js} +2 -2
  22. package/dist/{chunk-VZLX2JZG.js → chunk-DP6CXMJZ.js} +3 -3
  23. package/dist/{chunk-3QQSBUXR.js → chunk-EADULOZV.js} +36 -12
  24. package/dist/{chunk-6RNIFLG4.js → chunk-ELRRTWNP.js} +38 -6
  25. package/dist/{chunk-CPSAF2AU.js → chunk-FQNXYA6W.js} +45 -6
  26. package/dist/{chunk-ZZT45EHF.js → chunk-GMZYW52L.js} +3 -3
  27. package/dist/{chunk-ZLTFLC25.js → chunk-IIF5HIVF.js} +2 -2
  28. package/dist/{chunk-EMRGN4KM.js → chunk-IU4DV2PA.js} +18 -8
  29. package/dist/{chunk-AGUSOFNI.js → chunk-IWS56OY7.js} +30 -7
  30. package/dist/{chunk-MRZOVQ5D.js → chunk-IYKXK356.js} +98 -11
  31. package/dist/{chunk-6GZPSWP3.js → chunk-JDPQOR7C.js} +14 -7
  32. package/dist/{chunk-BLCSYKNN.js → chunk-KY4PXYSO.js} +10 -15
  33. package/dist/{chunk-WJYXMB2R.js → chunk-LOBRWKCR.js} +63 -14
  34. package/dist/{chunk-J5SKD6LN.js → chunk-MNP3GE7H.js} +38 -27
  35. package/dist/{chunk-S2GBLQ5S.js → chunk-O44IMQCN.js} +31 -7
  36. package/dist/{chunk-P7ZQ2FAJ.js → chunk-OG2BEUBY.js} +69 -34
  37. package/dist/{chunk-K23JNFE3.js → chunk-OTINMOKK.js} +233 -45
  38. package/dist/{chunk-PQTONQ4P.js → chunk-QPNYDH5B.js} +19 -5
  39. package/dist/{chunk-UE3UBMCP.js → chunk-RLMX75EM.js} +19 -8
  40. package/dist/{chunk-3U4H6ZRF.js → chunk-RNWUCZ2U.js} +53 -25
  41. package/dist/{chunk-YF3D5INN.js → chunk-RTZWBNTY.js} +121 -91
  42. package/dist/{chunk-SOG7XIRF.js → chunk-TTZOK6IY.js} +2 -2
  43. package/dist/{chunk-6GVXZCQV.js → chunk-UDVKRX5R.js} +2 -2
  44. package/dist/{chunk-CPVLVQYT.js → chunk-UQQS3VNT.js} +43 -9
  45. package/dist/{chunk-VB3MJGCV.js → chunk-VD2LV5WO.js} +82 -13
  46. package/dist/{chunk-5WNDJHT6.js → chunk-VPALDFYM.js} +2 -2
  47. package/dist/{chunk-FJEQZHZN.js → chunk-W2CECGTG.js} +24 -14
  48. package/dist/{chunk-CISOLTOP.js → chunk-X5FOFGXX.js} +72 -33
  49. package/dist/{chunk-CWALNI6K.js → chunk-X6KXNHUO.js} +1 -1
  50. package/dist/{chunk-EEOFQDT6.js → chunk-XRNN44QY.js} +46 -2
  51. package/dist/{chunk-EOOFNYIT.js → chunk-YOKD4GWJ.js} +67 -27
  52. package/dist/{chunk-D33S4RQG.js → chunk-ZUFHAHTE.js} +18 -6
  53. package/dist/codebase-index/generic-parser.d.ts +8 -1
  54. package/dist/codebase-index/index.js +9 -9
  55. package/dist/codebase-index/parser-worker-script.js +3 -3
  56. package/dist/codebase-index/project-server.js +5 -5
  57. package/dist/codebase-index/worker.js +4 -4
  58. package/dist/codebase-index/writer-refs.d.ts +1 -1
  59. package/dist/design.d.ts +1 -1
  60. package/dist/design.js +1 -1
  61. package/dist/diff.js +3 -2
  62. package/dist/document.js +2 -2
  63. package/dist/e2e.js +2 -2
  64. package/dist/edit.js +8 -8
  65. package/dist/exec.js +2 -2
  66. package/dist/fetch.js +2 -2
  67. package/dist/format.js +4 -4
  68. package/dist/{generic-parser-VUXDIAOZ.js → generic-parser-WFMIRHBX.js} +2 -2
  69. package/dist/git.js +2 -2
  70. package/dist/glob.js +2 -2
  71. package/dist/grep.d.ts +2 -0
  72. package/dist/grep.js +4 -2
  73. package/dist/index.js +46 -46
  74. package/dist/install.js +4 -4
  75. package/dist/json.js +2 -2
  76. package/dist/kanban-tool-types.d.ts +2 -0
  77. package/dist/kanban.js +2 -2
  78. package/dist/languages/index.js +2 -2
  79. package/dist/{legacy-bridge-SFNXIRAP.js → legacy-bridge-3T7SR4SK.js} +4 -4
  80. package/dist/lint.js +4 -4
  81. package/dist/logs.js +2 -2
  82. package/dist/outdated.js +4 -2
  83. package/dist/pack.js +45 -45
  84. package/dist/{parser-dispatch-X62UWXJS.js → parser-dispatch-QGC4HSP5.js} +4 -4
  85. package/dist/patch.js +8 -8
  86. package/dist/plan.js +4 -4
  87. package/dist/{py-parser-TDXSQZBC.js → py-parser-RFWG2HYI.js} +3 -3
  88. package/dist/read.js +8 -8
  89. package/dist/replace.js +9 -8
  90. package/dist/scaffold.js +2 -2
  91. package/dist/search.js +1 -1
  92. package/dist/session-kanban.js +1 -1
  93. package/dist/task.js +4 -4
  94. package/dist/test.js +4 -4
  95. package/dist/todo.js +3 -3
  96. package/dist/tool-tier.js +46 -46
  97. package/dist/{tree-sitter-parser-AIERW3YI.js → tree-sitter-parser-GILYQLS4.js} +2 -2
  98. package/dist/tree.js +2 -2
  99. package/dist/typecheck.js +4 -4
  100. package/dist/write.js +8 -8
  101. package/package.json +5 -5
@@ -74,9 +74,7 @@ export declare function adjustIndent(newLf: string, fromIndent: string, toIndent
74
74
  };
75
75
  /**
76
76
  * Best-effort locator for the no-match error: find the window whose trimmed
77
- * lines are most similar to the needle (cheap common-prefix scoring — this
78
- * runs on the failure path where the needle by definition doesn't match, so
79
- * precision matters less than never being slow). Returns the 1-based line
77
+ * lines are most similar to the needle. Returns the 1-based line
80
78
  * and a short snippet the model can use to correct itself without re-reading.
81
79
  */
82
80
  export declare function nearestMatchHint(fileLf: string, oldLf: string): {
package/dist/_util.d.ts CHANGED
@@ -69,6 +69,19 @@ export declare function resolveRealInsideRoot(absPath: string, ctx: Context): Pr
69
69
  * caller then opened.
70
70
  */
71
71
  export declare function safeResolveReal(input: string, ctx: Context): Promise<string>;
72
+ /**
73
+ * Project-root-relative variant of {@link safeResolveReal} for the codebase
74
+ * tools whose documented input contract is "relative to projectRoot or
75
+ * absolute" (codebase-skeleton, security-ast-scan, codebase-invariant-check,
76
+ * codebase-ast-replace). The sibling file tools (edit/grep/glob/…) resolve
77
+ * relative input against the session cwd — that is THEIR contract; these four
78
+ * always resolved against the project root and their schemas say so. Routing
79
+ * them through plain safeResolveReal silently changed that: with a nested
80
+ * workingDir (worktrees, set_working_dir) a relative input resolved to the
81
+ * wrong file. Containment is still enforced exactly as in safeResolveReal
82
+ * (realpath + allowOutsideProjectRoot honored).
83
+ */
84
+ export declare function safeResolveProjectPath(input: string, ctx: Context): Promise<string>;
72
85
  /**
73
86
  * Truncate a diff (or similar text payload) to `maxBytes`, cutting at a line
74
87
  * boundary and appending an explicit marker. Used by the mutating file tools
@@ -79,6 +92,13 @@ export declare function truncateDiffPayload(diff: string, maxBytes: number): {
79
92
  text: string;
80
93
  truncated: boolean;
81
94
  };
95
+ /**
96
+ * Truncate to `max` UTF-8 bytes keeping BOTH ends, appending a marker that
97
+ * reports the true omitted byte count. Like `truncateHeadTail` and
98
+ * `truncateDiffPayload`, marker room is reserved from the budget and both
99
+ * slices are cut byte-accurately (not by UTF-16 code unit), so the result
100
+ * never exceeds `max` — the contract `fetchTool`'s `maxOutputBytes` relies on.
101
+ */
82
102
  export declare function truncateMiddle(s: string, max: number): string;
83
103
  export declare function isBinaryBuffer(buf: Buffer): boolean;
84
104
  /** Unified byte cap for all command tool output fed to the model. */
package/dist/audit.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  auditTool
3
- } from "./chunk-CVALEVGA.js";
4
- import "./chunk-4E42D7UF.js";
5
- import "./chunk-SOG7XIRF.js";
3
+ } from "./chunk-64VIJPFV.js";
4
+ import "./chunk-ATSKPZUK.js";
5
+ import "./chunk-TTZOK6IY.js";
6
6
  import "./chunk-ZHH3BEWU.js";
7
7
  import "./chunk-2VSZC6QM.js";
8
8
  import "./chunk-3PVYQFRQ.js";
9
9
  import "./chunk-HFXSNKCV.js";
10
10
  import "./chunk-V43EQ6VR.js";
11
- import "./chunk-D33S4RQG.js";
11
+ import "./chunk-ZUFHAHTE.js";
12
12
  export {
13
13
  auditTool
14
14
  };
package/dist/bash.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  bashTool
3
- } from "./chunk-HTYEO67J.js";
3
+ } from "./chunk-AKHYMB4V.js";
4
4
  import "./chunk-BTSFTGIL.js";
5
5
  import "./chunk-NKNOBUBU.js";
6
6
  import "./chunk-2VSZC6QM.js";
7
7
  import "./chunk-3PVYQFRQ.js";
8
8
  import "./chunk-HFXSNKCV.js";
9
9
  import "./chunk-V43EQ6VR.js";
10
- import "./chunk-D33S4RQG.js";
10
+ import "./chunk-ZUFHAHTE.js";
11
11
  export {
12
12
  bashTool
13
13
  };
package/dist/builtin.d.ts CHANGED
@@ -1,4 +1,13 @@
1
1
  import type { Tool } from '@wrongstack/core/types';
2
+ /**
3
+ * Provider-facing descriptions for every built-in tool.
4
+ *
5
+ * Keep these decision-oriented: state the primary job, the appropriate time
6
+ * to use the tool, and any important boundary. This is deliberately kept next
7
+ * to the canonical catalog so tools discovered lazily receive the same useful
8
+ * guidance as directly exposed tools.
9
+ */
10
+ export declare const BUILTIN_TOOL_DESCRIPTIONS: Readonly<Record<string, string>>;
2
11
  /**
3
12
  * Non-essential tools that can be omitted in token-saving mode to reduce
4
13
  * per-request token consumption. Each tool definition adds ~50-200 tokens
@@ -55,5 +64,6 @@ export declare const TIER2_TOOLS: Tool[];
55
64
  * tokens while keeping all core capabilities available.
56
65
  */
57
66
  export declare const TIER3_TOOLS: Tool[];
67
+ /** The executable catalog always exposes the reviewed description above. */
58
68
  export declare const builtinTools: Tool[];
59
69
  //# sourceMappingURL=builtin.d.ts.map
package/dist/builtin.js CHANGED
@@ -1,74 +1,76 @@
1
1
  import {
2
+ BUILTIN_TOOL_DESCRIPTIONS,
2
3
  OFF_ONLY_TOOLS,
3
4
  OPTIONAL_TOOLS,
4
5
  TIER1_TOOLS,
5
6
  TIER2_TOOLS,
6
7
  TIER3_TOOLS,
7
8
  builtinTools
8
- } from "./chunk-K23JNFE3.js";
9
- import "./chunk-5WNDJHT6.js";
10
- import "./chunk-YF3D5INN.js";
11
- import "./chunk-EEOFQDT6.js";
12
- import "./chunk-H6AWAZ2Y.js";
13
- import "./chunk-X5K3U6GI.js";
9
+ } from "./chunk-OTINMOKK.js";
10
+ import "./chunk-VPALDFYM.js";
11
+ import "./chunk-RTZWBNTY.js";
12
+ import "./chunk-XRNN44QY.js";
13
+ import "./chunk-B4HTSV6Z.js";
14
+ import "./chunk-3M7LLN7W.js";
14
15
  import "./chunk-RJZQWEMS.js";
15
16
  import "./chunk-FRN7TIAA.js";
16
17
  import "./chunk-WXJY3BKV.js";
17
18
  import "./chunk-QBV725YG.js";
18
- import "./chunk-6RNIFLG4.js";
19
- import "./chunk-CPVLVQYT.js";
20
- import "./chunk-UE3UBMCP.js";
21
- import "./chunk-CVALEVGA.js";
22
- import "./chunk-MRZOVQ5D.js";
23
- import "./chunk-CPSAF2AU.js";
24
- import "./chunk-EMRGN4KM.js";
25
- import "./chunk-TKA4VEX2.js";
26
- import "./chunk-ZE6KLBUO.js";
27
- import "./chunk-AGUSOFNI.js";
28
- import "./chunk-VB3MJGCV.js";
29
- import "./chunk-P7ZQ2FAJ.js";
30
- import "./chunk-J5SKD6LN.js";
31
- import "./chunk-WJYXMB2R.js";
32
- import "./chunk-3QQSBUXR.js";
33
- import "./chunk-4AEZIFOW.js";
34
- import "./chunk-4E42D7UF.js";
35
- import "./chunk-SOG7XIRF.js";
19
+ import "./chunk-ELRRTWNP.js";
20
+ import "./chunk-UQQS3VNT.js";
21
+ import "./chunk-RLMX75EM.js";
22
+ import "./chunk-64VIJPFV.js";
23
+ import "./chunk-IYKXK356.js";
24
+ import "./chunk-FQNXYA6W.js";
25
+ import "./chunk-IU4DV2PA.js";
26
+ import "./chunk-2OXHS3KZ.js";
27
+ import "./chunk-6AAOT4PW.js";
28
+ import "./chunk-IWS56OY7.js";
29
+ import "./chunk-VD2LV5WO.js";
30
+ import "./chunk-OG2BEUBY.js";
31
+ import "./chunk-MNP3GE7H.js";
32
+ import "./chunk-LOBRWKCR.js";
33
+ import "./chunk-EADULOZV.js";
34
+ import "./chunk-5EUJF3WC.js";
35
+ import "./chunk-ATSKPZUK.js";
36
+ import "./chunk-TTZOK6IY.js";
36
37
  import "./chunk-ZHH3BEWU.js";
37
- import "./chunk-CISOLTOP.js";
38
- import "./chunk-6GZPSWP3.js";
39
- import "./chunk-EOOFNYIT.js";
38
+ import "./chunk-X5FOFGXX.js";
39
+ import "./chunk-JDPQOR7C.js";
40
+ import "./chunk-YOKD4GWJ.js";
40
41
  import "./chunk-Q5JPPCZC.js";
41
42
  import "./chunk-NWZ6XGBJ.js";
42
- import "./chunk-HTYEO67J.js";
43
- import "./chunk-WI3VDXHD.js";
43
+ import "./chunk-AKHYMB4V.js";
44
+ import "./chunk-BSJSNVGA.js";
44
45
  import "./chunk-BTSFTGIL.js";
45
46
  import "./chunk-NKNOBUBU.js";
46
47
  import "./chunk-2VSZC6QM.js";
47
48
  import "./chunk-3PVYQFRQ.js";
48
49
  import "./chunk-HFXSNKCV.js";
49
- import "./chunk-UKGMDCXT.js";
50
- import "./chunk-PQTONQ4P.js";
50
+ import "./chunk-C2DQKVLO.js";
51
+ import "./chunk-QPNYDH5B.js";
51
52
  import "./chunk-NBDZMMG2.js";
52
- import "./chunk-5ZYEGP2P.js";
53
- import "./chunk-FJEQZHZN.js";
54
- import "./chunk-CWALNI6K.js";
53
+ import "./chunk-BK732J7I.js";
54
+ import "./chunk-W2CECGTG.js";
55
+ import "./chunk-X6KXNHUO.js";
55
56
  import "./chunk-45JPRMC2.js";
56
- import "./chunk-3U4H6ZRF.js";
57
- import "./chunk-S2GBLQ5S.js";
58
- import "./chunk-CIFAIIHI.js";
57
+ import "./chunk-RNWUCZ2U.js";
58
+ import "./chunk-O44IMQCN.js";
59
+ import "./chunk-CFLJFDYV.js";
59
60
  import "./chunk-FQZOHLG3.js";
60
- import "./chunk-VZLX2JZG.js";
61
- import "./chunk-6GVXZCQV.js";
62
- import "./chunk-BLCSYKNN.js";
63
- import "./chunk-JJQB6R7Y.js";
64
- import "./chunk-ZLTFLC25.js";
65
- import "./chunk-A6BRWIXN.js";
61
+ import "./chunk-DP6CXMJZ.js";
62
+ import "./chunk-UDVKRX5R.js";
63
+ import "./chunk-KY4PXYSO.js";
64
+ import "./chunk-CMOUCKGC.js";
65
+ import "./chunk-IIF5HIVF.js";
66
+ import "./chunk-6IEBD27U.js";
66
67
  import "./chunk-UCYQTZ7F.js";
67
68
  import "./chunk-YOHO4DVT.js";
68
69
  import "./chunk-DTQ75VBC.js";
69
70
  import "./chunk-V43EQ6VR.js";
70
- import "./chunk-D33S4RQG.js";
71
+ import "./chunk-ZUFHAHTE.js";
71
72
  export {
73
+ BUILTIN_TOOL_DESCRIPTIONS,
72
74
  OFF_ONLY_TOOLS,
73
75
  OPTIONAL_TOOLS,
74
76
  TIER1_TOOLS,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  safeResolveReal
3
- } from "./chunk-D33S4RQG.js";
3
+ } from "./chunk-ZUFHAHTE.js";
4
4
 
5
5
  // src/scaffold.ts
6
6
  import * as fs from "node:fs/promises";
@@ -132,13 +132,23 @@ var scaffoldTool = {
132
132
  },
133
133
  required: ["template", "name"]
134
134
  },
135
- async execute(input, ctx) {
135
+ async execute(input, ctx, _opts) {
136
+ const signal = _opts?.signal ?? ctx?.signal;
137
+ signal?.throwIfAborted();
136
138
  const cwd = input.cwd ? await safeResolveReal(input.cwd, ctx) : ctx.cwd;
137
139
  const name = input.name;
138
140
  const vars = { name, ...input.vars };
139
141
  const builtIn = BUILT_IN_TEMPLATES[input.template];
140
142
  if (builtIn) {
141
- return await handleBuiltIn(name, builtIn.files, cwd, ctx, input.dry_run ?? false, vars);
143
+ return await handleBuiltIn(
144
+ name,
145
+ builtIn.files,
146
+ cwd,
147
+ ctx,
148
+ input.dry_run ?? false,
149
+ vars,
150
+ signal
151
+ );
142
152
  }
143
153
  return {
144
154
  template: input.template,
@@ -150,10 +160,11 @@ var scaffoldTool = {
150
160
  };
151
161
  }
152
162
  };
153
- async function handleBuiltIn(name, templateFiles, cwd, ctx, dryRun, vars) {
163
+ async function handleBuiltIn(name, templateFiles, cwd, ctx, dryRun, vars, signal) {
154
164
  const files = [];
155
165
  let filesCreated = 0;
156
166
  for (const [filePath, content] of Object.entries(templateFiles)) {
167
+ if (signal?.aborted) break;
157
168
  const resolvedPath = substituteVars(filePath, name, vars);
158
169
  const joinedPath = path.join(cwd, resolvedPath);
159
170
  const root = path.resolve(ctx.projectRoot ?? ctx.cwd ?? process.cwd());
@@ -189,6 +200,7 @@ function substituteVars(content, name, vars) {
189
200
  result = result.replace(/\{\{name\}\}/g, () => kebab);
190
201
  result = result.replace(/\{\{Name\}\}/g, () => pascal);
191
202
  for (const [k, v] of Object.entries(vars)) {
203
+ if (k === "name" || k === "Name") continue;
192
204
  result = result.replace(new RegExp(`\\{\\{${escapeRegexLiteral(k)}\\}\\}`, "g"), () => v);
193
205
  }
194
206
  return result;
@@ -197,4 +209,4 @@ function substituteVars(content, name, vars) {
197
209
  export {
198
210
  scaffoldTool
199
211
  };
200
- //# sourceMappingURL=chunk-TKA4VEX2.js.map
212
+ //# sourceMappingURL=chunk-2OXHS3KZ.js.map
@@ -1,13 +1,20 @@
1
1
  import {
2
2
  todoTool
3
- } from "./chunk-5ZYEGP2P.js";
3
+ } from "./chunk-BK732J7I.js";
4
4
  import {
5
5
  mirrorSessionTasksToKanban
6
- } from "./chunk-CWALNI6K.js";
6
+ } from "./chunk-X6KXNHUO.js";
7
7
 
8
8
  // src/task.ts
9
9
  import { randomUUID } from "node:crypto";
10
- import { addPlanItem, formatPlan, mutatePlan, mutateTasks } from "@wrongstack/core/storage";
10
+ import {
11
+ addPlanItem,
12
+ formatPlan,
13
+ loadTasks,
14
+ mutatePlan,
15
+ mutateTasks
16
+ } from "@wrongstack/core/storage";
17
+ import { ToolValidationError } from "@wrongstack/core/types";
11
18
  import { computeTaskItemProgress, formatTaskList } from "@wrongstack/core/utils";
12
19
  function findTaskIndex(tasks, query) {
13
20
  const asNum = Number.parseInt(query, 10);
@@ -119,8 +126,34 @@ var taskTool = {
119
126
  },
120
127
  required: ["action"]
121
128
  },
122
- async execute(input, ctx) {
123
- const sessionTaskPath = ctx.meta["task.path"];
129
+ async execute(input, ctx, _opts) {
130
+ const signal = _opts?.signal ?? ctx?.signal;
131
+ signal?.throwIfAborted();
132
+ const VALID_ACTIONS = /* @__PURE__ */ new Set([
133
+ "replace",
134
+ "add",
135
+ "status",
136
+ "show",
137
+ "promote",
138
+ "planify"
139
+ ]);
140
+ if (!input?.action || !VALID_ACTIONS.has(input.action)) {
141
+ return {
142
+ ok: false,
143
+ message: `Unknown action "${input?.action}". Use replace | add | status | show | promote | planify.`,
144
+ count: 0,
145
+ completed: 0,
146
+ inProgress: 0
147
+ };
148
+ }
149
+ if (input.scope !== void 0 && input.scope !== "session" && input.scope !== "project") {
150
+ throw new ToolValidationError({
151
+ message: `task: invalid scope "${input.scope}". Allowed: session, project`,
152
+ field: "scope"
153
+ });
154
+ }
155
+ const meta = ctx.meta ??= {};
156
+ const sessionTaskPath = meta["task.path"];
124
157
  let taskPath;
125
158
  if (input.scope === "project") {
126
159
  if (typeof sessionTaskPath === "string") {
@@ -143,6 +176,19 @@ var taskTool = {
143
176
  };
144
177
  }
145
178
  const sessionId = ctx.session?.id ?? "unknown";
179
+ if (input.action === "show") {
180
+ meta["task.path.resolved"] = taskPath;
181
+ const file2 = await loadTasks(taskPath) ?? { version: 1, tasks: [] };
182
+ const p2 = computeTaskItemProgress(file2.tasks);
183
+ const summary2 = file2.tasks.length > 0 ? formatTaskList(file2.tasks) : "No tasks.";
184
+ return {
185
+ ok: true,
186
+ message: summary2,
187
+ count: file2.tasks.length,
188
+ completed: p2.completed,
189
+ inProgress: p2.inProgress
190
+ };
191
+ }
146
192
  let early = null;
147
193
  const promoteMeta = { count: 0, title: "" };
148
194
  const planifyMeta = { title: "", details: "" };
@@ -198,6 +244,7 @@ var taskTool = {
198
244
  };
199
245
  return f;
200
246
  }
247
+ const taskStatusById = new Map(input.tasks.map((t) => [t.id, t.status]));
201
248
  for (const t of input.tasks) {
202
249
  if (t.dependsOn && t.dependsOn.length > 0) {
203
250
  const missing = t.dependsOn.filter((d) => !newIds.has(d));
@@ -214,7 +261,7 @@ var taskTool = {
214
261
  }
215
262
  if (t.status === "in_progress" || t.status === "completed") {
216
263
  const unmet = (t.dependsOn ?? []).filter(
217
- (dependencyId) => input.tasks?.find((candidate) => candidate.id === dependencyId)?.status !== "completed"
264
+ (dependencyId) => taskStatusById.get(dependencyId) !== "completed"
218
265
  );
219
266
  if (unmet.length > 0) {
220
267
  early = {
@@ -280,6 +327,14 @@ var taskTool = {
280
327
  break;
281
328
  }
282
329
  case "status": {
330
+ const VALID_TASK_STATUSES = /* @__PURE__ */ new Set([
331
+ "pending",
332
+ "in_progress",
333
+ "blocked",
334
+ "failed",
335
+ "review",
336
+ "completed"
337
+ ]);
283
338
  if (!input.id || !input.status) {
284
339
  early = {
285
340
  ok: false,
@@ -290,6 +345,15 @@ var taskTool = {
290
345
  };
291
346
  return f;
292
347
  }
348
+ if (!VALID_TASK_STATUSES.has(input.status)) {
349
+ early = {
350
+ ok: false,
351
+ message: `action=status requires valid status ('pending' | 'in_progress' | 'blocked' | 'failed' | 'review' | 'completed'), got "${input.status}".`,
352
+ count: f.tasks.length,
353
+ ...computeTaskItemProgress(f.tasks)
354
+ };
355
+ return f;
356
+ }
293
357
  const task = f.tasks.find((t) => t.id === input.id);
294
358
  if (!task) {
295
359
  early = {
@@ -517,4 +581,4 @@ ${formatTaskList(file.tasks)}` : file.tasks.length > 0 ? formatTaskList(file.tas
517
581
  export {
518
582
  taskTool
519
583
  };
520
- //# sourceMappingURL=chunk-X5K3U6GI.js.map
584
+ //# sourceMappingURL=chunk-3M7LLN7W.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  tryLegacyCodeOperation
3
- } from "./chunk-4E42D7UF.js";
3
+ } from "./chunk-ATSKPZUK.js";
4
4
  import {
5
5
  spawnStream
6
6
  } from "./chunk-ZHH3BEWU.js";
@@ -8,10 +8,11 @@ import {
8
8
  detectPackageManager,
9
9
  normalizeCommandOutput,
10
10
  safeResolveReal
11
- } from "./chunk-D33S4RQG.js";
11
+ } from "./chunk-ZUFHAHTE.js";
12
12
 
13
13
  // src/typecheck.ts
14
14
  import * as path from "node:path";
15
+ import { ToolValidationError } from "@wrongstack/core/types";
15
16
  var typecheckTool = {
16
17
  name: "typecheck",
17
18
  category: "Code Quality",
@@ -50,6 +51,21 @@ var typecheckTool = {
50
51
  async *executeStream(input, ctx, opts) {
51
52
  const cwd = input.cwd ? await safeResolveReal(input.cwd, ctx) : ctx.cwd;
52
53
  const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
54
+ signal.throwIfAborted();
55
+ if (input.all && input.project !== void 0) {
56
+ throw new ToolValidationError({
57
+ message: 'typecheck: cannot specify both "all: true" and "project"',
58
+ field: "project"
59
+ });
60
+ }
61
+ if (input.project !== void 0) {
62
+ if (typeof input.project !== "string" || !input.project.trim()) {
63
+ throw new ToolValidationError({
64
+ message: 'typecheck: "project" must be a non-empty string path',
65
+ field: "project"
66
+ });
67
+ }
68
+ }
53
69
  const bridge = await tryLegacyCodeOperation("semantic", {
54
70
  cwd,
55
71
  projectRoot: ctx.projectRoot,
@@ -86,7 +102,7 @@ var typecheckTool = {
86
102
  cmdArgs = ["tsc", ...tscArgs];
87
103
  }
88
104
  } else {
89
- const tsconfig = input.project ? await safeResolveReal(input.project, ctx) : await findTsConfig(cwd);
105
+ const tsconfig = input.project ? await safeResolveReal(input.project.trim(), ctx) : await findTsConfig(cwd);
90
106
  const tscArgs = ["--noEmit"];
91
107
  if (input.strict) tscArgs.push("--strict");
92
108
  if (tsconfig) tscArgs.push("--project", tsconfig);
@@ -104,8 +120,13 @@ var typecheckTool = {
104
120
  });
105
121
  const combined = `${result.stdout}
106
122
  ${result.stderr}`;
107
- const errors = [...combined.matchAll(/^.*\berror TS\d+:/gm)].length;
108
- const warnings = [...combined.matchAll(/^.*\bwarning TS\d+:/gm)].length;
123
+ let errors = [...combined.matchAll(/^.*\berror TS\d+:/gmi)].length;
124
+ const warnings = [...combined.matchAll(/^.*\bwarning TS\d+:/gmi)].length;
125
+ if (errors === 0 && result.exitCode !== 0) {
126
+ errors = 1;
127
+ }
128
+ const rawOutput = result.stdout && result.stderr ? `${result.stdout}
129
+ ${result.stderr}` : result.stdout || result.stderr || result.error || "";
109
130
  yield {
110
131
  type: "final",
111
132
  output: {
@@ -113,7 +134,7 @@ ${result.stderr}`;
113
134
  exit_code: result.exitCode,
114
135
  errors,
115
136
  warnings,
116
- output: normalizeCommandOutput(result.stdout || result.stderr || result.error || ""),
137
+ output: normalizeCommandOutput(rawOutput),
117
138
  truncated: result.truncated
118
139
  }
119
140
  };
@@ -121,7 +142,14 @@ ${result.stderr}`;
121
142
  };
122
143
  async function findTsConfig(cwd) {
123
144
  const { stat } = await import("node:fs/promises");
124
- const candidates = ["tsconfig.json", "tsconfig.base.json"];
145
+ const candidates = [
146
+ "tsconfig.json",
147
+ "tsconfig.base.json",
148
+ "tsconfig.build.json",
149
+ "tsconfig.app.json",
150
+ "tsconfig.node.json",
151
+ "tsconfig.lib.json"
152
+ ];
125
153
  for (const f of candidates) {
126
154
  try {
127
155
  const s = await stat(path.join(cwd, f));
@@ -135,4 +163,4 @@ async function findTsConfig(cwd) {
135
163
  export {
136
164
  typecheckTool
137
165
  };
138
- //# sourceMappingURL=chunk-4AEZIFOW.js.map
166
+ //# sourceMappingURL=chunk-5EUJF3WC.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  tryLegacyPackageOperation
3
- } from "./chunk-4E42D7UF.js";
3
+ } from "./chunk-ATSKPZUK.js";
4
4
  import {
5
5
  spawnStream
6
6
  } from "./chunk-ZHH3BEWU.js";
@@ -9,9 +9,10 @@ import {
9
9
  detectPackageManager,
10
10
  normalizeCommandOutput,
11
11
  safeResolveReal
12
- } from "./chunk-D33S4RQG.js";
12
+ } from "./chunk-ZUFHAHTE.js";
13
13
 
14
14
  // src/audit.ts
15
+ import { ToolValidationError } from "@wrongstack/core/types";
15
16
  var SEVERITY_RANK = {
16
17
  info: 0,
17
18
  low: 1,
@@ -56,12 +57,21 @@ var auditTool = {
56
57
  },
57
58
  async *executeStream(input, ctx, opts) {
58
59
  if (input.fix === true) {
59
- throw new Error(
60
- "audit: `fix: true` is not supported \u2014 this tool is read-only (mutating: false). To remediate vulnerabilities, upgrade the affected packages with the `install` tool (or `language_package` for non-JS ecosystems)."
61
- );
60
+ throw new ToolValidationError({
61
+ message: "audit: `fix: true` is not supported \u2014 this tool is read-only (mutating: false). To remediate vulnerabilities, upgrade the affected packages with the `install` tool (or `language_package` for non-JS ecosystems).",
62
+ field: "fix"
63
+ });
64
+ }
65
+ const VALID_LEVELS = /* @__PURE__ */ new Set(["low", "moderate", "high", "critical"]);
66
+ if (input.level !== void 0 && !VALID_LEVELS.has(input.level)) {
67
+ throw new ToolValidationError({
68
+ message: `audit: invalid severity level "${input.level}". Allowed: low, moderate, high, critical`,
69
+ field: "level"
70
+ });
62
71
  }
63
72
  const cwd = input.cwd ? await safeResolveReal(input.cwd, ctx) : ctx.cwd;
64
73
  const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
74
+ signal.throwIfAborted();
65
75
  const bridge = await tryLegacyPackageOperation("package-audit", {
66
76
  cwd,
67
77
  projectRoot: ctx.projectRoot,
@@ -173,13 +183,24 @@ function extractAdvisories(data) {
173
183
  for (const [pkg, value] of Object.entries(vulns)) {
174
184
  const vuln = value ?? {};
175
185
  const via = Array.isArray(vuln["via"]) ? vuln["via"] : [];
176
- const detail = via.find((v) => !!v && typeof v === "object");
177
- advisories.push({
178
- severity: typeof vuln["severity"] === "string" ? vuln["severity"] : "unknown",
179
- package: pkg,
180
- title: detail && typeof detail["title"] === "string" ? detail["title"] : "Unknown vulnerability",
181
- url: detail && typeof detail["url"] === "string" ? detail["url"] : ""
182
- });
186
+ const details = via.filter((v) => !!v && typeof v === "object");
187
+ if (details.length > 0) {
188
+ for (const detail of details) {
189
+ advisories.push({
190
+ severity: typeof detail["severity"] === "string" ? detail["severity"] : typeof vuln["severity"] === "string" ? vuln["severity"] : "unknown",
191
+ package: pkg,
192
+ title: typeof detail["title"] === "string" ? detail["title"] : "Unknown vulnerability",
193
+ url: typeof detail["url"] === "string" ? detail["url"] : ""
194
+ });
195
+ }
196
+ } else {
197
+ advisories.push({
198
+ severity: typeof vuln["severity"] === "string" ? vuln["severity"] : "unknown",
199
+ package: pkg,
200
+ title: "Unknown vulnerability",
201
+ url: ""
202
+ });
203
+ }
183
204
  }
184
205
  }
185
206
  return advisories;
@@ -188,4 +209,4 @@ function extractAdvisories(data) {
188
209
  export {
189
210
  auditTool
190
211
  };
191
- //# sourceMappingURL=chunk-CVALEVGA.js.map
212
+ //# sourceMappingURL=chunk-64VIJPFV.js.map