@wrongstack/tools 0.317.0 → 0.317.2

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 (109) hide show
  1. package/dist/_spawn-stream.d.ts +1 -1
  2. package/dist/audit.d.ts +37 -2
  3. package/dist/audit.js +4 -4
  4. package/dist/bash.js +1 -1
  5. package/dist/batch-tool-use.js +1 -1
  6. package/dist/browser/index.js +1 -1
  7. package/dist/browser/tools.d.ts +16 -1
  8. package/dist/builtin.js +43 -43
  9. package/dist/{chunk-SDLVH5RZ.js → chunk-3QQSBUXR.js} +6 -5
  10. package/dist/{chunk-K3WNSHUF.js → chunk-45JPRMC2.js} +62 -36
  11. package/dist/{chunk-EJWSCQ6D.js → chunk-4AEZIFOW.js} +6 -5
  12. package/dist/{chunk-PQKK5JH7.js → chunk-4E42D7UF.js} +2 -2
  13. package/dist/{chunk-JRJJX3L5.js → chunk-5WNDJHT6.js} +3 -2
  14. package/dist/{chunk-7EY5DCRO.js → chunk-5ZYEGP2P.js} +4 -4
  15. package/dist/{chunk-HPEO4EA7.js → chunk-6RR5VX6U.js} +35 -17
  16. package/dist/{chunk-QDQY7NQ2.js → chunk-A2PX7M7A.js} +5 -5
  17. package/dist/{chunk-JQRIR762.js → chunk-AK2K4KHR.js} +27 -19
  18. package/dist/{chunk-P7FYFZ6M.js → chunk-BANPF4LY.js} +11 -7
  19. package/dist/{chunk-RGISBZBD.js → chunk-CPSAF2AU.js} +3 -2
  20. package/dist/{chunk-BSLVR56S.js → chunk-CPVLVQYT.js} +6 -5
  21. package/dist/{chunk-VJNHFZ7J.js → chunk-CVALEVGA.js} +6 -5
  22. package/dist/{chunk-PY2IOS7C.js → chunk-CWALNI6K.js} +5 -5
  23. package/dist/{chunk-LIJQMYYX.js → chunk-ELFFQ4RU.js} +7 -3
  24. package/dist/{chunk-JNNVRHMV.js → chunk-FJEQZHZN.js} +8 -8
  25. package/dist/{chunk-S5CCLZL3.js → chunk-FRN7TIAA.js} +2 -2
  26. package/dist/{chunk-PCHQ6YRR.js → chunk-FYDKHXN7.js} +2 -2
  27. package/dist/{chunk-NKJW5GFO.js → chunk-H6AWAZ2Y.js} +3 -3
  28. package/dist/{chunk-IVWV2UM6.js → chunk-HTYEO67J.js} +6 -5
  29. package/dist/{chunk-UNSKG6DC.js → chunk-ICAXDRP6.js} +10 -15
  30. package/dist/{chunk-IYK7XGDZ.js → chunk-JJQB6R7Y.js} +7 -7
  31. package/dist/{chunk-LWKUTMD5.js → chunk-MRZOVQ5D.js} +6 -5
  32. package/dist/{chunk-YGG6X57C.js → chunk-NKX4SJ5R.js} +12 -9
  33. package/dist/{chunk-U4D5S3VQ.js → chunk-NWZ6XGBJ.js} +2 -1
  34. package/dist/{chunk-UKU2ZX4C.js → chunk-P7ZQ2FAJ.js} +27 -17
  35. package/dist/{chunk-4I4LWFOO.js → chunk-PQTONQ4P.js} +16 -11
  36. package/dist/{chunk-XGHMUZ77.js → chunk-RMB76PDS.js} +3 -3
  37. package/dist/{chunk-5OAOKALG.js → chunk-RUOMW2I6.js} +4 -3
  38. package/dist/{chunk-553IQUMO.js → chunk-S2JRYDYG.js} +7 -6
  39. package/dist/{chunk-OUBDL3WH.js → chunk-SOG7XIRF.js} +11 -8
  40. package/dist/{chunk-U6DZWHBA.js → chunk-TDLZIDCY.js} +9 -7
  41. package/dist/{chunk-TRDX25UH.js → chunk-TFEGJDH5.js} +293 -86
  42. package/dist/{chunk-AHHDWNXC.js → chunk-TKA4VEX2.js} +2 -2
  43. package/dist/{chunk-5H4GSJAI.js → chunk-UE3UBMCP.js} +7 -6
  44. package/dist/{chunk-IXMNTNW5.js → chunk-UKGMDCXT.js} +4 -3
  45. package/dist/{chunk-VGBUDLW4.js → chunk-UOXX4SQZ.js} +7 -6
  46. package/dist/{chunk-T2F4S7U4.js → chunk-WI3VDXHD.js} +18 -8
  47. package/dist/{chunk-O4MBV4AX.js → chunk-WJYXMB2R.js} +6 -5
  48. package/dist/{chunk-U4VAATKP.js → chunk-WXJY3BKV.js} +16 -6
  49. package/dist/{chunk-DR7JOQTC.js → chunk-X5K3U6GI.js} +3 -3
  50. package/dist/{chunk-DSEANA2W.js → chunk-XVGB6KYU.js} +37 -36
  51. package/dist/{chunk-TEBQ4VPZ.js → chunk-YOHO4DVT.js} +6 -5
  52. package/dist/{chunk-RXISBFR5.js → chunk-ZE6KLBUO.js} +5 -4
  53. package/dist/{chunk-22B7GE5T.js → chunk-ZHH3BEWU.js} +13 -12
  54. package/dist/codebase-index/bm25.d.ts +14 -1
  55. package/dist/codebase-index/index.js +8 -8
  56. package/dist/codebase-index/json-parser.d.ts +4 -0
  57. package/dist/codebase-index/parser-worker-script.js +2 -2
  58. package/dist/codebase-index/project-server.js +48 -9
  59. package/dist/codebase-index/worker.js +4 -4
  60. package/dist/codebase-index/writer-bulk-insert.d.ts +0 -1
  61. package/dist/codebase-index/writer-schema.d.ts +1 -1
  62. package/dist/codebase-index/writer.d.ts +38 -0
  63. package/dist/diff.js +1 -1
  64. package/dist/e2e.d.ts +40 -1
  65. package/dist/e2e.js +1 -1
  66. package/dist/edit.js +7 -7
  67. package/dist/exec.js +1 -1
  68. package/dist/fetch.js +1 -1
  69. package/dist/format.d.ts +42 -2
  70. package/dist/format.js +4 -4
  71. package/dist/git.d.ts +70 -1
  72. package/dist/git.js +1 -1
  73. package/dist/glob.js +3 -3
  74. package/dist/{go-parser-JXYKJHRC.js → go-parser-IKHW67WE.js} +2 -2
  75. package/dist/grep.js +3 -3
  76. package/dist/index.js +45 -45
  77. package/dist/install.d.ts +51 -2
  78. package/dist/install.js +4 -4
  79. package/dist/{json-parser-IBHZ4BZC.js → json-parser-2EOVP5MR.js} +81 -15
  80. package/dist/kanban.d.ts +19 -1
  81. package/dist/kanban.js +2 -2
  82. package/dist/languages/index.js +2 -2
  83. package/dist/{legacy-bridge-7M6QLUQN.js → legacy-bridge-SFNXIRAP.js} +4 -4
  84. package/dist/lint.js +4 -4
  85. package/dist/logs.js +1 -1
  86. package/dist/outdated.d.ts +25 -1
  87. package/dist/outdated.js +1 -1
  88. package/dist/pack.js +44 -44
  89. package/dist/{parser-dispatch-QH4XPGG6.js → parser-dispatch-X62UWXJS.js} +3 -3
  90. package/dist/patch.js +7 -7
  91. package/dist/plan.js +4 -4
  92. package/dist/{py-parser-IS4HKYMF.js → py-parser-TDXSQZBC.js} +2 -2
  93. package/dist/read.js +7 -7
  94. package/dist/replace.js +7 -7
  95. package/dist/{rs-parser-XHUUO2KZ.js → rs-parser-GIWPUA3T.js} +2 -2
  96. package/dist/scaffold.js +1 -1
  97. package/dist/search.js +1 -1
  98. package/dist/session-kanban.js +1 -1
  99. package/dist/task.js +4 -4
  100. package/dist/test.js +4 -4
  101. package/dist/todo.js +3 -3
  102. package/dist/tool-diff.js +1 -1
  103. package/dist/tool-tier.js +45 -45
  104. package/dist/tool-use.js +1 -1
  105. package/dist/{ts-parser-RCTYKSVI.js → ts-parser-7W26YB26.js} +2 -2
  106. package/dist/typecheck.js +4 -4
  107. package/dist/write.js +7 -7
  108. package/dist/{yaml-parser-4SAXV3PL.js → yaml-parser-RGBXEZE4.js} +2 -2
  109. package/package.json +5 -5
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-Q5JPPCZC.js";
4
4
  import {
5
5
  enqueueReindex
6
- } from "./chunk-QDQY7NQ2.js";
6
+ } from "./chunk-A2PX7M7A.js";
7
7
  import {
8
8
  isBinaryBuffer,
9
9
  safeResolveReal,
@@ -64,7 +64,7 @@ var replaceTool = {
64
64
  },
65
65
  required: ["pattern", "replacement", "files"]
66
66
  },
67
- async execute(input, ctx) {
67
+ async execute(input, ctx, opts) {
68
68
  if (!input?.pattern) {
69
69
  throw new ToolValidationError({
70
70
  message: "replace: pattern is required",
@@ -83,6 +83,8 @@ var replaceTool = {
83
83
  field: "files"
84
84
  });
85
85
  }
86
+ const signal = opts?.signal ?? ctx.signal;
87
+ signal?.throwIfAborted();
86
88
  const replaceAll = input.replace_all ?? true;
87
89
  const compiled = compileUserRegex(input.pattern, "g");
88
90
  if (!compiled.ok) {
@@ -103,6 +105,7 @@ var replaceTool = {
103
105
  let diffsOmitted = 0;
104
106
  let diffsTruncated = 0;
105
107
  for (const absPath of fileList) {
108
+ signal?.throwIfAborted();
106
109
  const lstat2 = await fs.lstat(absPath).catch((err) => {
107
110
  if (err.code === "ENOENT") return null;
108
111
  throw err;
@@ -226,25 +229,32 @@ function expandReplacement(template, match) {
226
229
  }
227
230
  return out;
228
231
  }
229
- function passesExtraGlob(extraGlob, name, full) {
232
+ function passesExtraGlob(extraGlob, name, full, base) {
230
233
  extraGlob.lastIndex = 0;
231
- const nameMatch = extraGlob.test(name);
234
+ if (extraGlob.test(name)) return true;
235
+ if (base) {
236
+ const rel = path.relative(base, full);
237
+ const posixRel = !rel || rel.startsWith("..") || path.isAbsolute(rel) ? full.split(path.sep).join("/") : rel.split(path.sep).join("/");
238
+ extraGlob.lastIndex = 0;
239
+ if (extraGlob.test(posixRel)) return true;
240
+ }
241
+ const posixFull = full.split(path.sep).join("/");
232
242
  extraGlob.lastIndex = 0;
233
- const fullMatch = extraGlob.test(full);
243
+ if (extraGlob.test(posixFull)) return true;
234
244
  extraGlob.lastIndex = 0;
235
- return nameMatch || fullMatch;
245
+ return extraGlob.test(full);
236
246
  }
237
247
  async function resolveFiles(filesInput, ctx, extraGlob) {
238
248
  const base = ctx.cwd;
239
- const normalized = filesInput.trim();
240
- if (normalized.startsWith("**/") || normalized.startsWith("*") || normalized.includes("**")) {
241
- return await globFiles(normalized, base, extraGlob);
242
- }
243
- const parts = normalized.split(",").map((s) => s.trim()).filter(Boolean);
249
+ const parts = filesInput.trim().split(",").map((s) => s.trim()).filter(Boolean);
244
250
  const resolved = [];
245
251
  for (const p of parts) {
252
+ if (p.includes("*") || p.includes("?")) {
253
+ resolved.push(...await globFiles(p, base, extraGlob));
254
+ continue;
255
+ }
246
256
  const absPath = await safeResolveReal(p, ctx);
247
- if (extraGlob && !passesExtraGlob(extraGlob, path.basename(absPath), absPath)) continue;
257
+ if (extraGlob && !passesExtraGlob(extraGlob, path.basename(absPath), absPath, base)) continue;
248
258
  const stat2 = await fs.stat(absPath).catch(() => null);
249
259
  if (stat2?.isFile()) {
250
260
  resolved.push(absPath);
@@ -259,7 +269,7 @@ async function globFiles(pattern, base, extraGlob) {
259
269
  const { promise } = spawnRgFind(pattern, base);
260
270
  const files = await promise;
261
271
  if (extraGlob) {
262
- return files.filter((f) => passesExtraGlob(extraGlob, path.basename(f), f));
272
+ return files.filter((f) => passesExtraGlob(extraGlob, path.basename(f), f, base));
263
273
  }
264
274
  return files;
265
275
  } catch {
@@ -290,6 +300,12 @@ function checkRg() {
290
300
  function spawnRgFind(pattern, base) {
291
301
  const args = ["--files", "--glob", pattern, base];
292
302
  const child = spawn("rg", args, {
303
+ // Anchored globs (`src/*.ts`) are matched by rg against paths relative to
304
+ // ITS cwd, not the search root. Without this the child inherits the
305
+ // process cwd, so `files: "src/*.ts"` silently matches nothing whenever
306
+ // the tool's base differs from the cwd of the host process and the native
307
+ // walker never engages (the rg call resolves, just empty).
308
+ cwd: base,
293
309
  signal: AbortSignal.timeout(3e4),
294
310
  env: buildChildEnv(),
295
311
  stdio: ["ignore", "pipe", "pipe"],
@@ -339,12 +355,14 @@ async function globNative(pattern, base, extraGlob) {
339
355
  await walk(full);
340
356
  } else if (e.isFile()) {
341
357
  const name = e.name;
342
- if (globRe.test(name) || globRe.test(full)) {
343
- if (extraGlob && !extraGlob.test(name) && !extraGlob.test(full)) continue;
358
+ const rel = path.relative(base, full).split(path.sep).join("/");
359
+ if (globRe.test(name) || globRe.test(rel) || globRe.test(full)) {
360
+ if (extraGlob && !passesExtraGlob(extraGlob, name, full, base)) {
361
+ continue;
362
+ }
344
363
  results.push(full);
345
364
  }
346
365
  globRe.lastIndex = 0;
347
- if (extraGlob) extraGlob.lastIndex = 0;
348
366
  }
349
367
  }
350
368
  };
@@ -356,4 +374,4 @@ export {
356
374
  replaceTool,
357
375
  __resetRgDetectionForTests
358
376
  };
359
- //# sourceMappingURL=chunk-HPEO4EA7.js.map
377
+ //# sourceMappingURL=chunk-6RR5VX6U.js.map
@@ -9,7 +9,7 @@ import {
9
9
  projectIndexServerBuildId,
10
10
  projectIndexServerEndpoint,
11
11
  projectIndexServerMetadataPath
12
- } from "./chunk-VGBUDLW4.js";
12
+ } from "./chunk-UOXX4SQZ.js";
13
13
  import {
14
14
  CircuitOpenError,
15
15
  IndexTimeoutError,
@@ -24,15 +24,15 @@ import {
24
24
  searchService,
25
25
  statsService,
26
26
  symbolGraphService
27
- } from "./chunk-TRDX25UH.js";
27
+ } from "./chunk-TFEGJDH5.js";
28
28
  import {
29
29
  isIndexablePath
30
- } from "./chunk-TEBQ4VPZ.js";
30
+ } from "./chunk-YOHO4DVT.js";
31
31
 
32
32
  // src/codebase-index/project-server-client-state.ts
33
33
  import * as fs from "node:fs";
34
34
  import { fileURLToPath } from "node:url";
35
- import { checkUnixSocketPath } from "@wrongstack/core/utils";
35
+ import { checkUnixSocketPath } from "@wrongstack/persistence";
36
36
  var CONNECT_ATTEMPT_TIMEOUT_MS = 750;
37
37
  var SERVER_START_TIMEOUT_MS = 1e4;
38
38
  var SERVER_CONTROL_TIMEOUT_MS = 5e3;
@@ -1269,4 +1269,4 @@ export {
1269
1269
  checkCodebaseIndexServerHealth,
1270
1270
  ensureCodebaseIndexServer
1271
1271
  };
1272
- //# sourceMappingURL=chunk-QDQY7NQ2.js.map
1272
+ //# sourceMappingURL=chunk-A2PX7M7A.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-EEOFQDT6.js";
4
4
  import {
5
5
  spawnStream
6
- } from "./chunk-22B7GE5T.js";
6
+ } from "./chunk-ZHH3BEWU.js";
7
7
  import {
8
8
  codebaseIndexStats,
9
9
  enqueueReindex,
@@ -13,7 +13,7 @@ import {
13
13
  outgoingCallsService,
14
14
  runStartupIndex,
15
15
  searchCodebaseIndex
16
- } from "./chunk-QDQY7NQ2.js";
16
+ } from "./chunk-A2PX7M7A.js";
17
17
  import {
18
18
  IndexTimeoutError,
19
19
  SCHEMA_VERSION,
@@ -21,12 +21,12 @@ import {
21
21
  indexCircuitBreaker,
22
22
  indexStorePool,
23
23
  resolveIndexDir
24
- } from "./chunk-TRDX25UH.js";
24
+ } from "./chunk-TFEGJDH5.js";
25
25
  import {
26
26
  EXT_TO_LANG,
27
27
  detectLang,
28
28
  isIndexablePath
29
- } from "./chunk-TEBQ4VPZ.js";
29
+ } from "./chunk-YOHO4DVT.js";
30
30
  import {
31
31
  normalizeCommandOutput
32
32
  } from "./chunk-D33S4RQG.js";
@@ -688,14 +688,15 @@ var codebaseAstReplaceTool = {
688
688
  },
689
689
  async execute(input, ctx) {
690
690
  try {
691
- const projectRoot = ctx.projectRoot;
691
+ const projectRoot = ctx.projectRoot ?? ctx.cwd ?? process.cwd();
692
692
  const result = await replaceSymbolInFile(input, projectRoot);
693
693
  return {
694
694
  status: "ok",
695
695
  file: path2.relative(projectRoot, result.file).replace(/\\/g, "/"),
696
696
  symbol: result.symbol,
697
697
  originalRange: result.originalRange,
698
- newRange: result.newRange
698
+ newRange: result.newRange,
699
+ violations: result.violations?.map((v) => `[${v.ruleId}] ${v.message}`)
699
700
  };
700
701
  } catch (err) {
701
702
  return {
@@ -750,7 +751,8 @@ var codebaseInvariantCheckTool = {
750
751
  let originalCode = input.originalCode;
751
752
  let lang = input.lang;
752
753
  if (!originalCode && input.file) {
753
- const resolved = path3.isAbsolute(input.file) ? input.file : path3.resolve(ctx.projectRoot, input.file);
754
+ const root = ctx.projectRoot ?? ctx.cwd ?? process.cwd();
755
+ const resolved = path3.isAbsolute(input.file) ? input.file : path3.resolve(root, input.file);
754
756
  originalCode = await fs2.readFile(resolved, "utf8");
755
757
  if (!lang) {
756
758
  lang = detectLang(resolved) ?? "ts";
@@ -822,7 +824,7 @@ var codebaseImpactAnalysisTool = {
822
824
  },
823
825
  async execute(input, ctx) {
824
826
  try {
825
- const projectRoot = ctx.projectRoot;
827
+ const projectRoot = ctx.projectRoot ?? ctx.cwd ?? process.cwd();
826
828
  const indexDir = codebaseIndexDirOverride(ctx);
827
829
  const limit = 200;
828
830
  const transitive = input.transitive ?? true;
@@ -1004,10 +1006,11 @@ var codebaseIncomingCallsTool = {
1004
1006
  }
1005
1007
  const limit = Math.max(1, Math.min(Math.trunc(input.limit ?? 50), 200));
1006
1008
  const transitive = input.transitive === true;
1009
+ const projectRoot = ctx.projectRoot ?? ctx.cwd ?? process.cwd();
1007
1010
  let serviced;
1008
1011
  try {
1009
1012
  serviced = await incomingCallsService({
1010
- projectRoot: ctx.projectRoot,
1013
+ projectRoot,
1011
1014
  indexDir: codebaseIndexDirOverride(ctx),
1012
1015
  symbol: input.symbol,
1013
1016
  file: input.file,
@@ -1164,6 +1167,8 @@ var codebaseSearchTool = {
1164
1167
  required: ["query"]
1165
1168
  },
1166
1169
  async execute(input, ctx, execOpts) {
1170
+ const signal = execOpts?.signal ?? ctx?.signal;
1171
+ signal?.throwIfAborted();
1167
1172
  const state = getIndexState();
1168
1173
  if (state.lastError) {
1169
1174
  const circuit = state.circuit;
@@ -1189,10 +1194,12 @@ var codebaseSearchTool = {
1189
1194
  lspKind: input.lspKind,
1190
1195
  limit
1191
1196
  },
1192
- { signal: execOpts?.signal }
1197
+ { signal }
1193
1198
  );
1194
1199
  } catch (err) {
1195
- if (execOpts?.signal?.aborted) throw err;
1200
+ if (signal?.aborted) {
1201
+ signal.throwIfAborted();
1202
+ }
1196
1203
  if (err.name === "IndexRefreshInProgressError") {
1197
1204
  return {
1198
1205
  results: [],
@@ -1370,10 +1377,11 @@ var codebaseOutgoingCallsTool = {
1370
1377
  }
1371
1378
  const limit = Math.max(1, Math.min(Math.trunc(input.limit ?? 50), 200));
1372
1379
  const transitive = input.transitive === true;
1380
+ const projectRoot = ctx.projectRoot ?? ctx.cwd ?? process.cwd();
1373
1381
  let serviced;
1374
1382
  try {
1375
1383
  serviced = await outgoingCallsService({
1376
- projectRoot: ctx.projectRoot,
1384
+ projectRoot,
1377
1385
  indexDir: codebaseIndexDirOverride(ctx),
1378
1386
  symbol: input.symbol,
1379
1387
  file: input.file,
@@ -1698,7 +1706,7 @@ async function extractTreeSitterSkeleton(content, lang, opts) {
1698
1706
  if (bodyNode) return;
1699
1707
  } else if (type === "class_definition" || type === "class_specifier" || type === "class_declaration" || type === "struct_specifier" || type === "interface_declaration" || type === "trait_item") {
1700
1708
  symbolCount++;
1701
- let nameNode = node.childForFieldName("name");
1709
+ const nameNode = node.childForFieldName("name");
1702
1710
  symbolRanges.push({
1703
1711
  name: nameNode ? nameNode.text : void 0,
1704
1712
  kind: type.includes("class") ? "class" : type.includes("struct") ? "struct" : type.includes("interface") ? "interface" : "trait",
@@ -1975,7 +1983,7 @@ var codebaseRepoMapTool = {
1975
1983
  },
1976
1984
  async execute(input, ctx) {
1977
1985
  try {
1978
- const projectRoot = ctx.projectRoot;
1986
+ const projectRoot = ctx.projectRoot ?? ctx.cwd ?? process.cwd();
1979
1987
  const result = await generateRepoMap({
1980
1988
  projectRoot,
1981
1989
  maxTokens: input.maxTokens,
@@ -2241,8 +2249,8 @@ var codebaseTargetedTestTool = {
2241
2249
  },
2242
2250
  additionalProperties: false
2243
2251
  },
2244
- async execute(input, ctx) {
2245
- const projectRoot = ctx.projectRoot;
2252
+ async execute(input, ctx, execOpts) {
2253
+ const projectRoot = ctx.projectRoot ?? ctx.cwd ?? process.cwd();
2246
2254
  const suitesSet = /* @__PURE__ */ new Set();
2247
2255
  try {
2248
2256
  if (input.testFiles) {
@@ -2294,7 +2302,7 @@ var codebaseTargetedTestTool = {
2294
2302
  runnerCmd = "go";
2295
2303
  runnerArgs = ["test", ...discoveredSuites];
2296
2304
  }
2297
- const signal = ctx.signal ?? new AbortController().signal;
2305
+ const signal = execOpts?.signal ?? ctx.signal ?? new AbortController().signal;
2298
2306
  const gen = spawnStream({
2299
2307
  cmd: runnerCmd,
2300
2308
  args: runnerArgs,
@@ -2376,7 +2384,7 @@ var deadCodeScanTool = {
2376
2384
  },
2377
2385
  async execute(input, ctx, _execOpts) {
2378
2386
  const startMs = Date.now();
2379
- const projectRoot = input.projectRoot ?? ctx.projectRoot;
2387
+ const projectRoot = input.projectRoot ?? ctx.projectRoot ?? ctx.cwd ?? process.cwd();
2380
2388
  const indexDir = input.indexDir ?? codebaseIndexDirOverride(ctx) ?? void 0;
2381
2389
  const result = runDeadCodeScan(projectRoot, {
2382
2390
  indexDir,
@@ -2827,4 +2835,4 @@ export {
2827
2835
  deadCodeScanTool,
2828
2836
  runDeadCodeScan
2829
2837
  };
2830
- //# sourceMappingURL=chunk-JQRIR762.js.map
2838
+ //# sourceMappingURL=chunk-AK2K4KHR.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-FQZOHLG3.js";
4
4
  import {
5
5
  enqueueReindex
6
- } from "./chunk-QDQY7NQ2.js";
6
+ } from "./chunk-A2PX7M7A.js";
7
7
  import {
8
8
  safeResolveReal,
9
9
  sha256hex,
@@ -54,20 +54,26 @@ var writeTool = {
54
54
  required: ["path", "content"]
55
55
  },
56
56
  async execute(input, ctx, opts) {
57
- return writeFile(input, ctx, opts?.signal);
57
+ const signal = opts?.signal ?? ctx?.signal;
58
+ return writeFile(input, ctx, signal);
58
59
  },
59
60
  async *executeStream(input, ctx, opts) {
61
+ const signal = opts?.signal ?? ctx?.signal;
62
+ signal?.throwIfAborted();
60
63
  const prepared = await prepareWrite(input, ctx);
64
+ signal?.throwIfAborted();
61
65
  if (!prepared.existed) {
62
66
  for (const line of input.content.split("\n")) {
67
+ signal?.throwIfAborted();
63
68
  yield { type: "partial_output", text: `${line}
64
69
  `, data: { livePreview: true } };
65
70
  }
66
71
  }
67
- yield { type: "final", output: await finishWrite(input, ctx, prepared, opts?.signal) };
72
+ yield { type: "final", output: await finishWrite(input, ctx, prepared, signal) };
68
73
  }
69
74
  };
70
75
  async function writeFile(input, ctx, signal) {
76
+ signal?.throwIfAborted();
71
77
  return finishWrite(input, ctx, await prepareWrite(input, ctx), signal);
72
78
  }
73
79
  async function prepareWrite(input, ctx) {
@@ -90,11 +96,9 @@ async function prepareWrite(input, ctx) {
90
96
  const stat2 = await fs.stat(absPath);
91
97
  existed = stat2.isFile();
92
98
  if (existed) {
99
+ prev = await fs.readFile(absPath, "utf8");
93
100
  if (!ctx.hasRead(absPath)) {
94
- prev = await fs.readFile(absPath, "utf8");
95
101
  ctx.recordRead(absPath, stat2.mtimeMs, "write", sha256hex(prev));
96
- } else {
97
- prev = await fs.readFile(absPath, "utf8");
98
102
  }
99
103
  }
100
104
  } catch (err) {
@@ -151,4 +155,4 @@ async function finishWrite(input, ctx, prepared, signal) {
151
155
  export {
152
156
  writeTool
153
157
  };
154
- //# sourceMappingURL=chunk-P7FYFZ6M.js.map
158
+ //# sourceMappingURL=chunk-BANPF4LY.js.map
@@ -50,6 +50,7 @@ var logsTool = {
50
50
  },
51
51
  async execute(input, ctx, opts) {
52
52
  const cwd = input.cwd ? await safeResolveReal(input.cwd, ctx) : ctx.cwd;
53
+ const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
53
54
  const lines = input.lines ?? 100;
54
55
  let filterRe = null;
55
56
  if (input.filter) {
@@ -60,7 +61,7 @@ var logsTool = {
60
61
  filterRe = compiled.regex;
61
62
  }
62
63
  if (input.service) {
63
- return await dockerLogs(input.service, lines, filterRe, cwd, opts.signal, input.since);
64
+ return await dockerLogs(input.service, lines, filterRe, cwd, signal, input.since);
64
65
  }
65
66
  if (input.path) {
66
67
  return await fileLogs(await safeResolveReal(input.path, ctx), lines, filterRe);
@@ -228,4 +229,4 @@ function parseLine(line) {
228
229
  export {
229
230
  logsTool
230
231
  };
231
- //# sourceMappingURL=chunk-RGISBZBD.js.map
232
+ //# sourceMappingURL=chunk-CPSAF2AU.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  tryLegacyCodeOperation
3
- } from "./chunk-PQKK5JH7.js";
3
+ } from "./chunk-4E42D7UF.js";
4
4
  import {
5
5
  spawnStream
6
- } from "./chunk-22B7GE5T.js";
6
+ } from "./chunk-ZHH3BEWU.js";
7
7
  import {
8
8
  normalizeCommandOutput,
9
9
  safeResolveReal
@@ -56,12 +56,13 @@ var testTool = {
56
56
  },
57
57
  async *executeStream(input, ctx, opts) {
58
58
  const cwd = input.cwd ? await safeResolveReal(input.cwd, ctx) : ctx.cwd;
59
+ const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
59
60
  const runner = input.runner ?? "auto";
60
61
  if (runner === "auto") {
61
62
  const bridge = await tryLegacyCodeOperation("test", {
62
63
  cwd,
63
64
  projectRoot: ctx.projectRoot,
64
- signal: opts.signal
65
+ signal
65
66
  });
66
67
  if (bridge?.run) {
67
68
  const run = bridge.run;
@@ -105,7 +106,7 @@ var testTool = {
105
106
  cmd: detected,
106
107
  args,
107
108
  cwd,
108
- signal: opts.signal,
109
+ signal,
109
110
  maxBytes: 2e5
110
111
  });
111
112
  const duration = Date.now() - start;
@@ -196,4 +197,4 @@ function parseResult(runner, result, duration) {
196
197
  export {
197
198
  testTool
198
199
  };
199
- //# sourceMappingURL=chunk-BSLVR56S.js.map
200
+ //# sourceMappingURL=chunk-CPVLVQYT.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  tryLegacyPackageOperation
3
- } from "./chunk-PQKK5JH7.js";
3
+ } from "./chunk-4E42D7UF.js";
4
4
  import {
5
5
  spawnStream
6
- } from "./chunk-22B7GE5T.js";
6
+ } from "./chunk-ZHH3BEWU.js";
7
7
  import {
8
8
  COMMAND_OUTPUT_MAX_BYTES,
9
9
  detectPackageManager,
@@ -61,10 +61,11 @@ var auditTool = {
61
61
  );
62
62
  }
63
63
  const cwd = input.cwd ? await safeResolveReal(input.cwd, ctx) : ctx.cwd;
64
+ const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
64
65
  const bridge = await tryLegacyPackageOperation("package-audit", {
65
66
  cwd,
66
67
  projectRoot: ctx.projectRoot,
67
- signal: opts.signal
68
+ signal
68
69
  });
69
70
  if (bridge?.outcome) {
70
71
  const outcome = bridge.outcome;
@@ -99,7 +100,7 @@ var auditTool = {
99
100
  cmd: manager,
100
101
  args,
101
102
  cwd,
102
- signal: opts.signal,
103
+ signal,
103
104
  maxBytes: 1e5
104
105
  });
105
106
  yield {
@@ -187,4 +188,4 @@ function extractAdvisories(data) {
187
188
  export {
188
189
  auditTool
189
190
  };
190
- //# sourceMappingURL=chunk-VJNHFZ7J.js.map
191
+ //# sourceMappingURL=chunk-CVALEVGA.js.map
@@ -910,7 +910,7 @@ async function rebindSessionKanbanTask(context) {
910
910
  return null;
911
911
  }
912
912
  if (!best) return null;
913
- context.setCurrentKanbanTask(best.taskId, best.boardId);
913
+ context.setCurrentKanbanTask?.(best.taskId, best.boardId);
914
914
  return { boardId: best.boardId, taskId: best.taskId };
915
915
  }
916
916
  var degradationReason;
@@ -937,15 +937,15 @@ async function hydrateSessionKanbanBoard(context, id) {
937
937
  fireAndForget("prune-session-boards", pruneSessionBoards(context.projectRoot));
938
938
  }
939
939
  let board = await ensureSessionKanbanBoard(context.projectRoot, id);
940
- if (context.todos.length) {
940
+ if (context.todos?.length) {
941
941
  board = await projectSessionTodosToKanban(context.projectRoot, context.todos, id);
942
942
  }
943
- const planPath = context.meta["plan.path"];
943
+ const planPath = context.meta?.["plan.path"];
944
944
  if (typeof planPath === "string" && planPath) {
945
945
  const plan = await loadPlan(planPath);
946
946
  if (plan) board = await projectSessionPlanToKanban(context.projectRoot, plan.items, id);
947
947
  }
948
- const taskPath = context.meta["task.path"];
948
+ const taskPath = context.meta?.["task.path"];
949
949
  if (typeof taskPath === "string" && taskPath) {
950
950
  const tasks = await loadTasks(taskPath);
951
951
  if (tasks) board = await projectSessionTasksToKanban(context.projectRoot, tasks.tasks, id);
@@ -997,4 +997,4 @@ export {
997
997
  applyManagedKanbanBoardToTodos2 as applyManagedKanbanBoardToTodos,
998
998
  applySessionKanbanTaskToSource2 as applySessionKanbanTaskToSource
999
999
  };
1000
- //# sourceMappingURL=chunk-PY2IOS7C.js.map
1000
+ //# sourceMappingURL=chunk-CWALNI6K.js.map
@@ -33,12 +33,16 @@ function compileGitignore(lines) {
33
33
  dirOnly
34
34
  });
35
35
  }
36
+ const hasNegation = rules.some((r) => r.negated);
36
37
  return (relPath, isDir) => {
37
- const p = relPath.replace(/\\/g, "/").replace(/^\/+/, "");
38
+ const p = relPath.includes("\\") || relPath.startsWith("/") ? relPath.replace(/\\/g, "/").replace(/^\/+/, "") : relPath;
38
39
  let ignored = false;
39
40
  for (const r of rules) {
40
41
  const re = r.dirOnly && !isDir ? r.under : r.eqOrUnder;
41
- if (re.test(p)) ignored = !r.negated;
42
+ if (re.test(p)) {
43
+ ignored = !r.negated;
44
+ if (!hasNegation && ignored) return true;
45
+ }
42
46
  }
43
47
  return ignored;
44
48
  };
@@ -56,4 +60,4 @@ async function loadGitignoreMatcher(projectRoot) {
56
60
  export {
57
61
  loadGitignoreMatcher
58
62
  };
59
- //# sourceMappingURL=chunk-LIJQMYYX.js.map
63
+ //# sourceMappingURL=chunk-ELFFQ4RU.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  applySessionKanbanTaskToSource,
3
3
  taskFileToSerializedGraph
4
- } from "./chunk-PY2IOS7C.js";
4
+ } from "./chunk-CWALNI6K.js";
5
5
 
6
6
  // src/kanban.ts
7
7
  import { stripLifecycleIssues as stripLifecycleIssues2 } from "@wrongstack/kanban";
@@ -156,7 +156,7 @@ async function requireBoard(projectRoot, boardId) {
156
156
  // src/kanban-board-actions.ts
157
157
  async function handleKanbanBoardAction(projectRoot, input, ctx) {
158
158
  const eventContext = {
159
- sessionId: ctx.eventSessionId(),
159
+ sessionId: ctx.eventSessionId?.() ?? ctx.session?.id ?? "default-session",
160
160
  ...ctx.agentId !== void 0 ? { actor: ctx.agentId } : {}
161
161
  };
162
162
  switch (input.action) {
@@ -575,7 +575,7 @@ function recordKanbanVerificationEvidence(ctx, report) {
575
575
  // src/kanban-decomposition-actions.ts
576
576
  async function handleKanbanDecompositionAction(projectRoot, input, ctx) {
577
577
  const eventContext = {
578
- sessionId: ctx.eventSessionId(),
578
+ sessionId: ctx.eventSessionId?.() ?? ctx.session?.id ?? "default-session",
579
579
  ...ctx.agentId !== void 0 ? { actor: ctx.agentId } : {}
580
580
  };
581
581
  switch (input.action) {
@@ -677,7 +677,7 @@ import {
677
677
  } from "@wrongstack/kanban";
678
678
  async function handleKanbanDetailAction(projectRoot, input, ctx) {
679
679
  const eventContext = {
680
- sessionId: ctx.eventSessionId(),
680
+ sessionId: ctx.eventSessionId?.() ?? ctx.session?.id ?? "default-session",
681
681
  ...ctx.agentId !== void 0 ? { actor: ctx.agentId } : {}
682
682
  };
683
683
  switch (input.action) {
@@ -1055,7 +1055,7 @@ async function syncContextTask(ctx, task, options = {}) {
1055
1055
  }
1056
1056
  async function handleKanbanLifecycleAction(projectRoot, input, ctx) {
1057
1057
  const eventContext = {
1058
- sessionId: ctx.eventSessionId(),
1058
+ sessionId: ctx.eventSessionId?.() ?? ctx.session?.id ?? "default-session",
1059
1059
  ...ctx.agentId !== void 0 ? { actor: ctx.agentId } : {}
1060
1060
  };
1061
1061
  switch (input.action) {
@@ -2069,7 +2069,7 @@ var kanbanTool = {
2069
2069
  icon: "task",
2070
2070
  timeoutMs: 3e4,
2071
2071
  inputSchema: KANBAN_INPUT_SCHEMA,
2072
- async execute(input, ctx) {
2072
+ async execute(input, ctx, _opts) {
2073
2073
  const projectRoot = ctx.projectRoot;
2074
2074
  if (!projectRoot) return fail("No project root is available.");
2075
2075
  const withPresence = createKanbanPresenceWrapper(projectRoot, input, ctx);
@@ -2085,7 +2085,7 @@ var kanbanTool = {
2085
2085
  projectRoot,
2086
2086
  input,
2087
2087
  input.author ?? input.agentId,
2088
- ctx.eventSessionId()
2088
+ ctx.eventSessionId?.() ?? ctx.session?.id ?? "default-session"
2089
2089
  );
2090
2090
  if (contractResult !== void 0) return contractResult;
2091
2091
  const detailResult = await handleKanbanDetailAction(projectRoot, input, ctx);
@@ -2108,4 +2108,4 @@ export {
2108
2108
  recordKanbanVerificationEvidence,
2109
2109
  kanbanTool
2110
2110
  };
2111
- //# sourceMappingURL=chunk-JNNVRHMV.js.map
2111
+ //# sourceMappingURL=chunk-FJEQZHZN.js.map
@@ -65,7 +65,7 @@ var toolUseTool = {
65
65
  executionMs: Date.now() - start
66
66
  };
67
67
  }
68
- const governedExecute = ctx.meta[GOVERNED_TOOL_EXECUTOR_META_KEY];
68
+ const governedExecute = ctx.meta?.[GOVERNED_TOOL_EXECUTOR_META_KEY];
69
69
  if (typeof governedExecute !== "function") {
70
70
  return {
71
71
  tool: input.tool,
@@ -96,4 +96,4 @@ var toolUseTool = {
96
96
  export {
97
97
  toolUseTool
98
98
  };
99
- //# sourceMappingURL=chunk-S5CCLZL3.js.map
99
+ //# sourceMappingURL=chunk-FRN7TIAA.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  builtinTools
3
- } from "./chunk-DSEANA2W.js";
3
+ } from "./chunk-XVGB6KYU.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-PCHQ6YRR.js.map
15
+ //# sourceMappingURL=chunk-FYDKHXN7.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  todoTool
3
- } from "./chunk-7EY5DCRO.js";
3
+ } from "./chunk-5ZYEGP2P.js";
4
4
  import {
5
5
  projectSessionPlanToKanban
6
- } from "./chunk-PY2IOS7C.js";
6
+ } from "./chunk-CWALNI6K.js";
7
7
 
8
8
  // src/plan.ts
9
9
  import { randomUUID } from "node:crypto";
@@ -363,4 +363,4 @@ function mkResult(plan, ok, message, todos) {
363
363
  export {
364
364
  planTool
365
365
  };
366
- //# sourceMappingURL=chunk-NKJW5GFO.js.map
366
+ //# sourceMappingURL=chunk-H6AWAZ2Y.js.map