@wrongstack/tools 0.317.0 → 0.318.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) 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-YGG6X57C.js → chunk-3U4H6ZRF.js} +12 -9
  11. package/dist/{chunk-K3WNSHUF.js → chunk-45JPRMC2.js} +62 -36
  12. package/dist/{chunk-EJWSCQ6D.js → chunk-4AEZIFOW.js} +6 -5
  13. package/dist/{chunk-PQKK5JH7.js → chunk-4E42D7UF.js} +2 -2
  14. package/dist/{chunk-JRJJX3L5.js → chunk-5WNDJHT6.js} +3 -2
  15. package/dist/{chunk-7EY5DCRO.js → chunk-5ZYEGP2P.js} +4 -4
  16. package/dist/{chunk-VGBUDLW4.js → chunk-6GVXZCQV.js} +7 -6
  17. package/dist/{chunk-UNSKG6DC.js → chunk-6GZPSWP3.js} +10 -15
  18. package/dist/{chunk-5OAOKALG.js → chunk-AGUSOFNI.js} +4 -3
  19. package/dist/{chunk-TRDX25UH.js → chunk-BLCSYKNN.js} +293 -86
  20. package/dist/{chunk-U6DZWHBA.js → chunk-CIFAIIHI.js} +9 -7
  21. package/dist/{chunk-HPEO4EA7.js → chunk-CISOLTOP.js} +35 -17
  22. package/dist/{chunk-RGISBZBD.js → chunk-CPSAF2AU.js} +3 -2
  23. package/dist/{chunk-BSLVR56S.js → chunk-CPVLVQYT.js} +6 -5
  24. package/dist/{chunk-VJNHFZ7J.js → chunk-CVALEVGA.js} +6 -5
  25. package/dist/{chunk-PY2IOS7C.js → chunk-CWALNI6K.js} +5 -5
  26. package/dist/{chunk-LIJQMYYX.js → chunk-DTQ75VBC.js} +8 -3
  27. package/dist/{chunk-553IQUMO.js → chunk-EOOFNYIT.js} +7 -6
  28. package/dist/{chunk-JNNVRHMV.js → chunk-FJEQZHZN.js} +8 -8
  29. package/dist/{chunk-S5CCLZL3.js → chunk-FRN7TIAA.js} +2 -2
  30. package/dist/{chunk-NKJW5GFO.js → chunk-H6AWAZ2Y.js} +3 -3
  31. package/dist/{chunk-IVWV2UM6.js → chunk-HTYEO67J.js} +6 -5
  32. package/dist/{chunk-IYK7XGDZ.js → chunk-JJQB6R7Y.js} +7 -7
  33. package/dist/{chunk-DSEANA2W.js → chunk-K23JNFE3.js} +37 -36
  34. package/dist/{chunk-LWKUTMD5.js → chunk-MRZOVQ5D.js} +6 -5
  35. package/dist/{chunk-PCHQ6YRR.js → chunk-MX25MTDJ.js} +2 -2
  36. package/dist/{chunk-U4D5S3VQ.js → chunk-NWZ6XGBJ.js} +2 -1
  37. package/dist/{chunk-UKU2ZX4C.js → chunk-P7ZQ2FAJ.js} +27 -17
  38. package/dist/{chunk-4I4LWFOO.js → chunk-PQTONQ4P.js} +16 -11
  39. package/dist/{chunk-P7FYFZ6M.js → chunk-S2GBLQ5S.js} +11 -7
  40. package/dist/{chunk-OUBDL3WH.js → chunk-SOG7XIRF.js} +11 -8
  41. package/dist/{chunk-AHHDWNXC.js → chunk-TKA4VEX2.js} +2 -2
  42. package/dist/{chunk-5H4GSJAI.js → chunk-UE3UBMCP.js} +7 -6
  43. package/dist/{chunk-IXMNTNW5.js → chunk-UKGMDCXT.js} +4 -3
  44. package/dist/{chunk-QDQY7NQ2.js → chunk-VZLX2JZG.js} +5 -5
  45. package/dist/{chunk-T2F4S7U4.js → chunk-WI3VDXHD.js} +18 -8
  46. package/dist/{chunk-O4MBV4AX.js → chunk-WJYXMB2R.js} +6 -5
  47. package/dist/{chunk-U4VAATKP.js → chunk-WXJY3BKV.js} +16 -6
  48. package/dist/{chunk-DR7JOQTC.js → chunk-X5K3U6GI.js} +3 -3
  49. package/dist/{chunk-JQRIR762.js → chunk-YF3D5INN.js} +27 -19
  50. package/dist/{chunk-TEBQ4VPZ.js → chunk-YOHO4DVT.js} +6 -5
  51. package/dist/{chunk-RXISBFR5.js → chunk-ZE6KLBUO.js} +5 -4
  52. package/dist/{chunk-22B7GE5T.js → chunk-ZHH3BEWU.js} +13 -12
  53. package/dist/{chunk-XGHMUZ77.js → chunk-ZZT45EHF.js} +3 -3
  54. package/dist/codebase-index/bm25.d.ts +14 -1
  55. package/dist/codebase-index/index.d.ts +1 -0
  56. package/dist/codebase-index/index.js +13 -8
  57. package/dist/codebase-index/json-parser.d.ts +4 -0
  58. package/dist/codebase-index/parser-worker-script.js +2 -2
  59. package/dist/codebase-index/project-server.js +48 -9
  60. package/dist/codebase-index/worker.js +4 -4
  61. package/dist/codebase-index/writer-bulk-insert.d.ts +0 -1
  62. package/dist/codebase-index/writer-schema.d.ts +1 -1
  63. package/dist/codebase-index/writer.d.ts +38 -0
  64. package/dist/diff.js +1 -1
  65. package/dist/e2e.d.ts +40 -1
  66. package/dist/e2e.js +1 -1
  67. package/dist/edit.js +7 -7
  68. package/dist/exec.js +1 -1
  69. package/dist/fetch.js +1 -1
  70. package/dist/format.d.ts +42 -2
  71. package/dist/format.js +4 -4
  72. package/dist/git.d.ts +70 -1
  73. package/dist/git.js +1 -1
  74. package/dist/glob.js +3 -3
  75. package/dist/{go-parser-JXYKJHRC.js → go-parser-IKHW67WE.js} +2 -2
  76. package/dist/grep.js +3 -3
  77. package/dist/index.js +45 -45
  78. package/dist/install.d.ts +51 -2
  79. package/dist/install.js +4 -4
  80. package/dist/{json-parser-IBHZ4BZC.js → json-parser-2EOVP5MR.js} +81 -15
  81. package/dist/kanban.d.ts +19 -1
  82. package/dist/kanban.js +2 -2
  83. package/dist/languages/index.js +2 -2
  84. package/dist/{legacy-bridge-7M6QLUQN.js → legacy-bridge-SFNXIRAP.js} +4 -4
  85. package/dist/lint.js +4 -4
  86. package/dist/logs.js +1 -1
  87. package/dist/outdated.d.ts +25 -1
  88. package/dist/outdated.js +1 -1
  89. package/dist/pack.js +44 -44
  90. package/dist/{parser-dispatch-QH4XPGG6.js → parser-dispatch-X62UWXJS.js} +3 -3
  91. package/dist/patch.js +7 -7
  92. package/dist/plan.js +4 -4
  93. package/dist/{py-parser-IS4HKYMF.js → py-parser-TDXSQZBC.js} +2 -2
  94. package/dist/read.js +7 -7
  95. package/dist/replace.js +7 -7
  96. package/dist/{rs-parser-XHUUO2KZ.js → rs-parser-GIWPUA3T.js} +2 -2
  97. package/dist/scaffold.js +1 -1
  98. package/dist/search.js +1 -1
  99. package/dist/session-kanban.js +1 -1
  100. package/dist/task.js +4 -4
  101. package/dist/test.js +4 -4
  102. package/dist/todo.js +3 -3
  103. package/dist/tool-diff.js +1 -1
  104. package/dist/tool-tier.js +45 -45
  105. package/dist/tool-use.js +1 -1
  106. package/dist/{ts-parser-RCTYKSVI.js → ts-parser-7W26YB26.js} +2 -2
  107. package/dist/typecheck.js +4 -4
  108. package/dist/write.js +7 -7
  109. package/dist/{yaml-parser-4SAXV3PL.js → yaml-parser-RGBXEZE4.js} +2 -2
  110. package/package.json +5 -5
@@ -34,24 +34,34 @@ import { toErrorMessage } from "@wrongstack/core/utils/error";
34
34
  // src/_danger-detect.ts
35
35
  var argHas = (args, value) => args.includes(value);
36
36
  var argMatches = (args, re) => args.some((a) => re.test(a));
37
- var hasShortFlags = (args, letters) => {
37
+ var flagLetters = (args) => {
38
38
  const seen = /* @__PURE__ */ new Set();
39
39
  for (const a of args) {
40
- if (!/^-[a-zA-Z]+$/.test(a)) continue;
41
- for (const ch of a.slice(1)) seen.add(ch);
40
+ if (/^-[a-zA-Z]+$/.test(a)) {
41
+ for (const ch of a.slice(1)) seen.add(ch);
42
+ } else if (a === "--recursive") {
43
+ seen.add("r");
44
+ } else if (a === "--force") {
45
+ seen.add("f");
46
+ }
42
47
  }
43
- return letters.split("").every((l) => seen.has(l));
48
+ return seen;
44
49
  };
45
50
  var RULES = [
46
51
  // ----- rm / rmdir: recursive force delete (any path) -----
47
52
  // Note: BLOCKED_ARG_PATTERNS already hard-denies root/home/glob paths,
48
53
  // but `rm -rf ./build` is a normal dev workflow that the user might
49
54
  // want to do intentionally. We downgrade it to 'destructive' so the
50
- // confirm prompt can approve.
55
+ // confirm prompt can approve. Short clusters, GNU long forms
56
+ // (`--recursive --force`), and mixed shapes all classify identically.
51
57
  {
52
58
  id: "rm-recursive",
53
59
  level: "destructive",
54
- test: (cmd, args) => (cmd === "rm" || cmd === "rmdir") && hasShortFlags(args, "rf"),
60
+ test: (cmd, args) => {
61
+ if (cmd !== "rm" && cmd !== "rmdir") return false;
62
+ const letters = flagLetters(args);
63
+ return letters.has("r") && letters.has("f");
64
+ },
55
65
  reason: "recursive force-delete"
56
66
  },
57
67
  // ----- Windows PowerShell Remove-Item: -Recurse -Force -----
@@ -1541,7 +1551,7 @@ var execTool = {
1541
1551
  danger
1542
1552
  };
1543
1553
  }
1544
- const signal = opts.signal;
1554
+ const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
1545
1555
  return runCommand(cmd, args, cwd, timeout, signal, ctx.session?.id, danger);
1546
1556
  }
1547
1557
  };
@@ -1720,4 +1730,4 @@ export {
1720
1730
  getExecAllowlist,
1721
1731
  execTool
1722
1732
  };
1723
- //# sourceMappingURL=chunk-T2F4S7U4.js.map
1733
+ //# sourceMappingURL=chunk-WI3VDXHD.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
@@ -48,12 +48,13 @@ var lintTool = {
48
48
  },
49
49
  async *executeStream(input, ctx, opts) {
50
50
  const cwd = input.cwd ? await safeResolveReal(input.cwd, ctx) : ctx.cwd;
51
+ const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
51
52
  const linter = input.linter ?? "auto";
52
53
  if (linter === "auto" && !input.files) {
53
54
  const bridge = await tryLegacyCodeOperation("lint", {
54
55
  cwd,
55
56
  projectRoot: ctx.projectRoot,
56
- signal: opts.signal
57
+ signal
57
58
  });
58
59
  if (bridge?.run) {
59
60
  const run = bridge.run;
@@ -96,7 +97,7 @@ var lintTool = {
96
97
  args.push("--", ...files.map((f) => f.trim()));
97
98
  }
98
99
  const cmd = detected === "biome" ? "biome" : detected;
99
- const result = yield* spawnStream({ cmd, args, cwd, signal: opts.signal, maxBytes: 1e5 });
100
+ const result = yield* spawnStream({ cmd, args, cwd, signal, maxBytes: 1e5 });
100
101
  const errors = [...result.stdout.matchAll(/\berror\b/gi)].length;
101
102
  const warnings = [...result.stdout.matchAll(/\bwarning\b/gi)].length;
102
103
  yield {
@@ -131,4 +132,4 @@ async function detectLinter(cwd) {
131
132
  export {
132
133
  lintTool
133
134
  };
134
- //# sourceMappingURL=chunk-O4MBV4AX.js.map
135
+ //# sourceMappingURL=chunk-WJYXMB2R.js.map
@@ -99,14 +99,23 @@ var batchToolUseTool = {
99
99
  let succeeded = 0;
100
100
  let failed = 0;
101
101
  if (input.parallel !== false) {
102
+ let stopRequested = false;
102
103
  const allResults = await mapWithConcurrency(
103
104
  input.calls,
104
105
  MAX_PARALLEL_BATCH_CALLS,
105
- (call) => executeSingle(call, ctx, governedExecute)
106
+ async (call) => {
107
+ const result = await executeSingle(call, ctx, governedExecute);
108
+ if (input.stop_on_error && !result.success) stopRequested = true;
109
+ return result;
110
+ },
111
+ () => stopRequested
112
+ );
113
+ const executed = allResults.filter(
114
+ (r) => r !== void 0
106
115
  );
107
- results.push(...allResults);
108
- succeeded = allResults.filter((r) => r.success).length;
109
- failed = allResults.filter((r) => !r.success).length;
116
+ results.push(...executed);
117
+ succeeded = executed.filter((r) => r.success).length;
118
+ failed = executed.filter((r) => !r.success).length;
110
119
  } else {
111
120
  for (const call of input.calls) {
112
121
  const result = await executeSingle(call, ctx, governedExecute);
@@ -128,11 +137,12 @@ var batchToolUseTool = {
128
137
  };
129
138
  }
130
139
  };
131
- async function mapWithConcurrency(items, limit, run) {
140
+ async function mapWithConcurrency(items, limit, run, shouldStop) {
132
141
  const results = new Array(items.length);
133
142
  let nextIndex = 0;
134
143
  const worker = async () => {
135
144
  while (nextIndex < items.length) {
145
+ if (shouldStop?.()) return;
136
146
  const index = nextIndex++;
137
147
  results[index] = await run(items[index]);
138
148
  }
@@ -190,4 +200,4 @@ async function executeSingle(call, ctx, governedExecute) {
190
200
  export {
191
201
  batchToolUseTool
192
202
  };
193
- //# sourceMappingURL=chunk-U4VAATKP.js.map
203
+ //# sourceMappingURL=chunk-WXJY3BKV.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
  mirrorSessionTasksToKanban
6
- } from "./chunk-PY2IOS7C.js";
6
+ } from "./chunk-CWALNI6K.js";
7
7
 
8
8
  // src/task.ts
9
9
  import { randomUUID } from "node:crypto";
@@ -517,4 +517,4 @@ ${formatTaskList(file.tasks)}` : file.tasks.length > 0 ? formatTaskList(file.tas
517
517
  export {
518
518
  taskTool
519
519
  };
520
- //# sourceMappingURL=chunk-DR7JOQTC.js.map
520
+ //# sourceMappingURL=chunk-X5K3U6GI.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-VZLX2JZG.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-BLCSYKNN.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-YF3D5INN.js.map
@@ -1,5 +1,4 @@
1
1
  // src/codebase-index/languages.ts
2
- import * as path from "node:path";
3
2
  var EXT_TO_LANG = {
4
3
  // TypeScript / JavaScript (first-class TS compiler API)
5
4
  ".ts": "ts",
@@ -88,15 +87,17 @@ var SPECIAL_FILENAMES = {
88
87
  justfile: "other"
89
88
  };
90
89
  function detectLang(file) {
91
- const base = path.basename(file);
90
+ const lastSlash = Math.max(file.lastIndexOf("/"), file.lastIndexOf("\\"));
91
+ const base = lastSlash === -1 ? file : file.slice(lastSlash + 1);
92
92
  const lowerBase = base.toLowerCase();
93
93
  if (lowerBase.endsWith(".d.ts") || lowerBase.endsWith(".d.mts") || lowerBase.endsWith(".d.cts")) {
94
94
  return "ts";
95
95
  }
96
96
  const special = SPECIAL_FILENAMES[lowerBase];
97
97
  if (special) return special;
98
- const ext = path.extname(base).toLowerCase();
99
- if (!ext) return null;
98
+ const dot = lowerBase.lastIndexOf(".");
99
+ if (dot <= 0) return null;
100
+ const ext = lowerBase.slice(dot);
100
101
  return EXT_TO_LANG[ext] ?? null;
101
102
  }
102
103
  function isIndexablePath(file) {
@@ -160,4 +161,4 @@ export {
160
161
  LANG_FAMILY_ENTRIES,
161
162
  languageFamily
162
163
  };
163
- //# sourceMappingURL=chunk-TEBQ4VPZ.js.map
164
+ //# sourceMappingURL=chunk-YOHO4DVT.js.map
@@ -116,6 +116,7 @@ var gitTool = {
116
116
  };
117
117
  }
118
118
  const args = buildArgs(input);
119
+ const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
119
120
  let safetyWarning;
120
121
  if (input.command === "commit") {
121
122
  try {
@@ -123,7 +124,7 @@ var gitTool = {
123
124
  cwd: ctx.cwd,
124
125
  projectRoot: ctx.projectRoot,
125
126
  sessionId: ctx.session?.id,
126
- signal: opts.signal
127
+ signal
127
128
  });
128
129
  if (report.warning) {
129
130
  const scopeNote = input.files ? "" : "\nNote: this commit has no explicit `files` list, so it will include ALL staged changes. Pass `files` to scope the commit to only what you changed.";
@@ -135,7 +136,7 @@ var gitTool = {
135
136
  let stagedDiff;
136
137
  if (input.command === "commit" && !input.dry_run) {
137
138
  try {
138
- const diffResult = await runGit(["diff", "--cached"], gitDir, opts.signal);
139
+ const diffResult = await runGit(["diff", "--cached"], gitDir, signal);
139
140
  if (diffResult.exitCode === 0) {
140
141
  const MAX_DIFF = 2e4;
141
142
  stagedDiff = diffResult.stdout.length > MAX_DIFF ? diffResult.stdout.slice(0, MAX_DIFF) + "\n\n... (diff truncated)" : diffResult.stdout;
@@ -143,7 +144,7 @@ var gitTool = {
143
144
  } catch {
144
145
  }
145
146
  }
146
- const result = await runGit(args, gitDir, opts.signal);
147
+ const result = await runGit(args, gitDir, signal);
147
148
  if (stagedDiff !== void 0) result.diff = stagedDiff;
148
149
  if (safetyWarning !== void 0) result.warning = safetyWarning;
149
150
  return result;
@@ -312,4 +313,4 @@ function runGit(args, cwd, signal) {
312
313
  export {
313
314
  gitTool
314
315
  };
315
- //# sourceMappingURL=chunk-RXISBFR5.js.map
316
+ //# sourceMappingURL=chunk-ZE6KLBUO.js.map
@@ -21,6 +21,7 @@ import {
21
21
  import { buildChildEnv } from "@wrongstack/core/utils";
22
22
  var isWin = process.platform === "win32";
23
23
  async function* spawnStream(opts) {
24
+ const signal = opts.signal;
24
25
  const max = opts.maxBytes ?? 999999999;
25
26
  const flushAt = opts.flushBytes ?? 4 * 1024;
26
27
  const maxQueue = opts.maxQueueSize ?? 500;
@@ -42,7 +43,7 @@ async function* spawnStream(opts) {
42
43
  env: buildChildEnv(),
43
44
  stdio: ["ignore", "pipe", "pipe"],
44
45
  windowsHide: true,
45
- ...isWin ? {} : { signal: opts.signal },
46
+ ...isWin || !signal ? {} : { signal },
46
47
  ...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {}
47
48
  });
48
49
  const registry = getProcessRegistry();
@@ -134,13 +135,13 @@ async function* spawnStream(opts) {
134
135
  queuedBytes += bytes;
135
136
  wake();
136
137
  });
137
- const completeTelemetry = (code, signal, timedOut = false) => {
138
+ const completeTelemetry = (code, signal2, timedOut = false) => {
138
139
  if (telemetryCompleted) return;
139
140
  telemetryCompleted = true;
140
141
  emitProcessCompleted({
141
142
  ...pid !== void 0 ? { pid } : {},
142
143
  exitCode: code,
143
- ...signal ? { signal } : {},
144
+ ...signal2 ? { signal: signal2 } : {},
144
145
  durationMs: Date.now() - processStartedAt,
145
146
  stdoutBytes,
146
147
  stderrBytes,
@@ -148,16 +149,16 @@ async function* spawnStream(opts) {
148
149
  endedAt: (/* @__PURE__ */ new Date()).toISOString()
149
150
  });
150
151
  };
151
- child.on("close", (code, signal) => {
152
+ child.on("close", (code, signal2) => {
152
153
  if (typeof pid === "number") registry.unregister(pid);
153
- const exitCode2 = code ?? (signal ? 1 : 0);
154
- completeTelemetry(exitCode2, signal ?? void 0);
154
+ const exitCode2 = code ?? (signal2 ? 1 : 0);
155
+ completeTelemetry(exitCode2, signal2 ?? void 0);
155
156
  queue.push({
156
157
  kind: "close",
157
158
  data: "",
158
159
  bytes: 0,
159
160
  code: exitCode2,
160
- ...signal ? { signal } : {}
161
+ ...signal2 ? { signal: signal2 } : {}
161
162
  });
162
163
  wake();
163
164
  });
@@ -174,9 +175,9 @@ async function* spawnStream(opts) {
174
175
  completeTelemetry(124, "SIGKILL", true);
175
176
  wake();
176
177
  };
177
- if (isWin) {
178
- if (opts.signal.aborted) onAbort();
179
- else opts.signal.addEventListener("abort", onAbort, { once: true });
178
+ if (isWin && signal) {
179
+ if (signal.aborted) onAbort();
180
+ else signal.addEventListener("abort", onAbort, { once: true });
180
181
  }
181
182
  let exitCode = 0;
182
183
  let spawnFailed = false;
@@ -222,7 +223,7 @@ async function* spawnStream(opts) {
222
223
  };
223
224
  } finally {
224
225
  spool.finalize();
225
- if (isWin) opts.signal.removeEventListener("abort", onAbort);
226
+ if (isWin && signal) signal.removeEventListener("abort", onAbort);
226
227
  child.stdout?.off("data", onOut);
227
228
  child.stderr?.off("data", onErr);
228
229
  child.stdout?.destroy();
@@ -257,4 +258,4 @@ function utf8Prefix(text, maxBytes) {
257
258
  export {
258
259
  spawnStream
259
260
  };
260
- //# sourceMappingURL=chunk-22B7GE5T.js.map
261
+ //# sourceMappingURL=chunk-ZHH3BEWU.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  builtinToolsPack
3
- } from "./chunk-PCHQ6YRR.js";
3
+ } from "./chunk-MX25MTDJ.js";
4
4
  import {
5
5
  TIER1_TOOLS,
6
6
  TIER2_TOOLS
7
- } from "./chunk-DSEANA2W.js";
7
+ } from "./chunk-K23JNFE3.js";
8
8
 
9
9
  // src/tool-tier.ts
10
10
  function toolNameSet(tools) {
@@ -51,4 +51,4 @@ export {
51
51
  selectBuiltinToolsForTier,
52
52
  registerBuiltinToolTier
53
53
  };
54
- //# sourceMappingURL=chunk-XGHMUZ77.js.map
54
+ //# sourceMappingURL=chunk-ZZT45EHF.js.map
@@ -21,11 +21,24 @@ interface IndexableDoc {
21
21
  id: number;
22
22
  text: string;
23
23
  }
24
+ /**
25
+ * Max chars of `signature` fed to the FTS index (P1, 2026-08-30).
26
+ *
27
+ * `signature` stores the full printed declaration — often including the whole
28
+ * function body, because `ts-parser`'s getSignature uses `printer.printNode`
29
+ * (capped at 500 chars). Measured on the live 131k-row index: ts+tsx signature
30
+ * text was ~70% of all trigram FTS input, and capping to the declaration
31
+ * header cut FTS size 47% and insert time 20-32%. Only the FTS *input* is
32
+ * capped; the stored `signature` column (display, embeddings fallback) is
33
+ * untouched.
34
+ */
35
+ export declare const FTS_SIGNATURE_MAX_CHARS = 300;
24
36
  /**
25
37
  * Build indexable text for BM25 from a symbol's fields.
26
38
  * The name is split into camelCase/SnakeCase words so that queries
27
39
  * like "complex" match "complexOperation". The verbatim name is
28
- * also included for exact-match queries.
40
+ * also included for exact-match queries. The signature contributes
41
+ * only its declaration header (see {@link ftsSignature}).
29
42
  */
30
43
  export declare function buildIndexableText(name: string, signature: string, docComment: string): string;
31
44
  export declare function buildBm25Index(docs: IndexableDoc[]): Bm25Index;
@@ -35,6 +35,7 @@ export { extractDirectorySkeleton, extractFileSkeleton, type FileSkeletonResult,
35
35
  export { deadCodeScanTool, runDeadCodeScan } from './dead-code-scan.js';
36
36
  export type { DeadCodeScanInput, DeadCodeScanOutput, DeadFile, DeadPackage, DeadSymbol, } from './dead-code-scan.js';
37
37
  export { runIndexer } from './indexer.js';
38
+ export { compileGitignore, loadGitignoreMatcher, type IgnoreMatcher, } from './gitignore.js';
38
39
  export { detectLang, INDEXABLE_EXTENSIONS, isIndexablePath } from './languages.js';
39
40
  export { internalKindToLspKind, lspKindToInternalKind, } from './lsp-kind.js';
40
41
  export type { ProjectIndexServerClientHealth, ProjectIndexServerConnectionState, ProjectIndexServerConnectionStatus, } from './project-server-client.js';
@@ -18,9 +18,9 @@ import {
18
18
  polyglotInvariantEngine,
19
19
  replaceSymbolInFile,
20
20
  runDeadCodeScan
21
- } from "../chunk-JQRIR762.js";
21
+ } from "../chunk-YF3D5INN.js";
22
22
  import "../chunk-EEOFQDT6.js";
23
- import "../chunk-22B7GE5T.js";
23
+ import "../chunk-ZHH3BEWU.js";
24
24
  import "../chunk-2VSZC6QM.js";
25
25
  import "../chunk-3PVYQFRQ.js";
26
26
  import "../chunk-HFXSNKCV.js";
@@ -45,11 +45,11 @@ import {
45
45
  shutdownCodebaseIndexHost,
46
46
  shutdownCodebaseIndexServer,
47
47
  symbolGraphService
48
- } from "../chunk-QDQY7NQ2.js";
48
+ } from "../chunk-VZLX2JZG.js";
49
49
  import {
50
50
  projectIndexServerEndpoint,
51
51
  projectIndexServerMetadataPath
52
- } from "../chunk-VGBUDLW4.js";
52
+ } from "../chunk-6GVXZCQV.js";
53
53
  import {
54
54
  CircuitOpenError,
55
55
  IndexCircuitBreaker,
@@ -66,8 +66,8 @@ import {
66
66
  resolveIndexDir,
67
67
  runIndexer,
68
68
  tokenise
69
- } from "../chunk-TRDX25UH.js";
70
- import "../chunk-IYK7XGDZ.js";
69
+ } from "../chunk-BLCSYKNN.js";
70
+ import "../chunk-JJQB6R7Y.js";
71
71
  import "../chunk-ZLTFLC25.js";
72
72
  import "../chunk-A6BRWIXN.js";
73
73
  import "../chunk-UCYQTZ7F.js";
@@ -75,8 +75,11 @@ import {
75
75
  INDEXABLE_EXTENSIONS,
76
76
  detectLang,
77
77
  isIndexablePath
78
- } from "../chunk-TEBQ4VPZ.js";
79
- import "../chunk-LIJQMYYX.js";
78
+ } from "../chunk-YOHO4DVT.js";
79
+ import {
80
+ compileGitignore,
81
+ loadGitignoreMatcher
82
+ } from "../chunk-DTQ75VBC.js";
80
83
  import "../chunk-V43EQ6VR.js";
81
84
  import "../chunk-D33S4RQG.js";
82
85
  export {
@@ -104,6 +107,7 @@ export {
104
107
  codebaseSkeletonTool,
105
108
  codebaseStatsTool,
106
109
  codebaseTargetedTestTool,
110
+ compileGitignore,
107
111
  deadCodeScanTool,
108
112
  detectLang,
109
113
  enqueueReindex,
@@ -120,6 +124,7 @@ export {
120
124
  isIndexableFile,
121
125
  isIndexablePath,
122
126
  isIndexing,
127
+ loadGitignoreMatcher,
123
128
  lspKindToInternalKind,
124
129
  onIndexStateChange,
125
130
  outgoingCallsService,
@@ -1,8 +1,12 @@
1
1
  import type { FileSymbols, SymbolLang } from './schema.js';
2
+ /** Soft cap per file (mirrors the 500 caps in generic-parser / tree-sitter,
3
+ * raised because top-level-only extraction yields far fewer candidates). */
4
+ export declare const JSON_MAX_SYMBOLS_DEFAULT = 1000;
2
5
  export declare function parseSymbols(opts: {
3
6
  file: string;
4
7
  content: string;
5
8
  lang: SymbolLang;
9
+ maxSymbols?: number | undefined;
6
10
  }): FileSymbols;
7
11
  export { detectLang } from './languages.js';
8
12
  //# sourceMappingURL=json-parser.d.ts.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  parseFilesContent
3
- } from "../chunk-IYK7XGDZ.js";
3
+ } from "../chunk-JJQB6R7Y.js";
4
4
  import "../chunk-ZLTFLC25.js";
5
5
  import "../chunk-A6BRWIXN.js";
6
6
  import "../chunk-UCYQTZ7F.js";
7
- import "../chunk-TEBQ4VPZ.js";
7
+ import "../chunk-YOHO4DVT.js";
8
8
  import "../chunk-V43EQ6VR.js";
9
9
 
10
10
  // src/codebase-index/parser-worker-script.ts