@wrongstack/tools 1.0.3 → 1.0.5

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 (112) hide show
  1. package/README.md +0 -6
  2. package/dist/_util.d.ts +18 -0
  3. package/dist/audit.js +4 -4
  4. package/dist/bash.js +2 -2
  5. package/dist/browser/index.d.ts +1 -1
  6. package/dist/browser/index.js +9 -1
  7. package/dist/browser/tools.d.ts +14 -0
  8. package/dist/builtin.d.ts +16 -13
  9. package/dist/builtin.js +41 -45
  10. package/dist/{chunk-AQ5YBURX.js → chunk-2IC5FRD7.js} +2 -2
  11. package/dist/{chunk-VU3QBYL4.js → chunk-2ZWQIVEW.js} +2 -2
  12. package/dist/{chunk-JDOO4P6Z.js → chunk-3F7HQ3KS.js} +2 -2
  13. package/dist/{chunk-DX5KZEMK.js → chunk-47GYABZW.js} +2 -2
  14. package/dist/{chunk-KYVOTHG7.js → chunk-4KI4HHID.js} +2 -2
  15. package/dist/{chunk-3JVSOBHU.js → chunk-54SIRJ6D.js} +4 -4
  16. package/dist/{chunk-X6KXNHUO.js → chunk-5BKQVP56.js} +22 -5
  17. package/dist/{chunk-SMARDKAC.js → chunk-5UA4TNJJ.js} +2 -2
  18. package/dist/{chunk-SOR7OCYP.js → chunk-6XYFYLN7.js} +23 -1
  19. package/dist/{chunk-VO6M2FVG.js → chunk-6ZRP5IKQ.js} +2 -2
  20. package/dist/{chunk-E2ZD4ERD.js → chunk-7EQ2LUXU.js} +3 -3
  21. package/dist/{chunk-6LCKF5KH.js → chunk-7PEZU5Y4.js} +1 -1
  22. package/dist/{chunk-7HL23T3T.js → chunk-BU6VUXWG.js} +2 -2
  23. package/dist/{chunk-KIQTABBJ.js → chunk-C64UUXTA.js} +3 -3
  24. package/dist/{chunk-PNLDTRC5.js → chunk-CYPYJIAF.js} +7 -7
  25. package/dist/{chunk-IRUEHGCR.js → chunk-D4HWMWGE.js} +3 -3
  26. package/dist/{chunk-CVNCSMVU.js → chunk-DOHU3XHS.js} +46 -6
  27. package/dist/{chunk-32XPUSY3.js → chunk-FRIUJ534.js} +3 -3
  28. package/dist/{chunk-AMURQAJX.js → chunk-G35NLPG5.js} +3 -3
  29. package/dist/{chunk-ZUFHAHTE.js → chunk-HKR56VNF.js} +15 -2
  30. package/dist/{chunk-ASEXQRA7.js → chunk-IMIHTHF7.js} +8 -6
  31. package/dist/{chunk-77MBK46T.js → chunk-IOOFLBVM.js} +3 -3
  32. package/dist/{chunk-3LS3FYEF.js → chunk-JK5WXW4S.js} +2 -2
  33. package/dist/{chunk-GU7QJ37F.js → chunk-JQ43NVFU.js} +2 -2
  34. package/dist/{chunk-YECHJJJF.js → chunk-K7Y2IWEB.js} +4 -4
  35. package/dist/{chunk-VZGPASGD.js → chunk-MG7CUN6R.js} +2 -2
  36. package/dist/{chunk-NOCU555K.js → chunk-NKOTOW6X.js} +3 -3
  37. package/dist/{chunk-YDTRKEYY.js → chunk-OBVXDVLE.js} +3 -3
  38. package/dist/{chunk-TYRVYBHW.js → chunk-OVFQC6FU.js} +235 -176
  39. package/dist/{chunk-VKAJMHVG.js → chunk-OZVGRDCM.js} +3 -3
  40. package/dist/{chunk-FC3X7GGJ.js → chunk-R36RWYXE.js} +3 -3
  41. package/dist/{chunk-Z34CUZCZ.js → chunk-S6E2AM4U.js} +3 -3
  42. package/dist/chunk-SIIOHBNY.js +38 -0
  43. package/dist/{chunk-4YKVHCQC.js → chunk-TGVQMKVH.js} +3 -3
  44. package/dist/{chunk-QU2VRCMM.js → chunk-TL5T4A4E.js} +3 -3
  45. package/dist/{chunk-6ZLRRC74.js → chunk-WBAPU3AB.js} +40 -2
  46. package/dist/{chunk-RV7BVTDG.js → chunk-WKXL5XHU.js} +2 -2
  47. package/dist/{chunk-2CTZW6JQ.js → chunk-XHSHNOAF.js} +12 -11
  48. package/dist/{chunk-24T5XIJU.js → chunk-YA2ZYCJY.js} +4 -4
  49. package/dist/{chunk-T7YVY2BV.js → chunk-YILT3CSO.js} +2 -2
  50. package/dist/{chunk-OUEH4I4X.js → chunk-YJQQ5F5J.js} +3 -3
  51. package/dist/{chunk-MIV2RU5B.js → chunk-ZETZHHV5.js} +3 -3
  52. package/dist/{chunk-4ERMPDHV.js → chunk-ZSW5KO5S.js} +21 -17
  53. package/dist/clarify.d.ts +18 -3
  54. package/dist/codebase-index/codebase-search-tool.d.ts +2 -3
  55. package/dist/codebase-index/gitignore.d.ts +1 -1
  56. package/dist/codebase-index/index.js +7 -7
  57. package/dist/codebase-index/parser-worker-script.js +1 -1
  58. package/dist/codebase-index/project-server-endpoint.d.ts +33 -0
  59. package/dist/codebase-index/project-server.js +6 -5
  60. package/dist/codebase-index/worker.js +3 -3
  61. package/dist/diff.js +2 -2
  62. package/dist/e2e.js +2 -2
  63. package/dist/edit.js +7 -7
  64. package/dist/exec.js +2 -2
  65. package/dist/fetch.js +2 -2
  66. package/dist/format.js +4 -4
  67. package/dist/git.js +2 -2
  68. package/dist/glob.js +3 -3
  69. package/dist/grep.js +3 -3
  70. package/dist/index.d.ts +2 -8
  71. package/dist/index.js +76 -117
  72. package/dist/install.js +4 -4
  73. package/dist/json.js +2 -2
  74. package/dist/kanban.js +2 -2
  75. package/dist/languages/index.js +2 -2
  76. package/dist/{legacy-bridge-WVQ4BHDI.js → legacy-bridge-XM2GV665.js} +4 -4
  77. package/dist/lint.js +4 -4
  78. package/dist/logs.js +2 -2
  79. package/dist/outdated.js +2 -2
  80. package/dist/pack.js +42 -46
  81. package/dist/{parser-dispatch-UQAB4E6V.js → parser-dispatch-HZDZSIYH.js} +2 -2
  82. package/dist/patch.js +7 -7
  83. package/dist/plan.js +4 -4
  84. package/dist/read-url-content.d.ts +17 -0
  85. package/dist/read.js +7 -7
  86. package/dist/replace.js +7 -7
  87. package/dist/session-kanban.js +1 -1
  88. package/dist/session-shell.d.ts +12 -0
  89. package/dist/session-shell.js +8 -0
  90. package/dist/task.js +4 -4
  91. package/dist/test.js +4 -4
  92. package/dist/todo.js +3 -3
  93. package/dist/tool-search.js +1 -1
  94. package/dist/tool-tier.d.ts +12 -2
  95. package/dist/tool-tier.js +43 -47
  96. package/dist/tree.js +2 -2
  97. package/dist/typecheck.js +4 -4
  98. package/dist/write.js +7 -7
  99. package/package.json +9 -21
  100. package/dist/batch-tool-use.d.ts +0 -24
  101. package/dist/batch-tool-use.js +0 -7
  102. package/dist/chunk-7ODZTPCU.js +0 -128
  103. package/dist/chunk-CHEK3ASV.js +0 -183
  104. package/dist/chunk-KLJZ4WV4.js +0 -213
  105. package/dist/chunk-VBF2YXUW.js +0 -203
  106. package/dist/document.d.ts +0 -25
  107. package/dist/document.js +0 -8
  108. package/dist/scaffold.d.ts +0 -23
  109. package/dist/scaffold.js +0 -10
  110. package/dist/set-working-dir.d.ts +0 -17
  111. package/dist/tool-help.d.ts +0 -21
  112. package/dist/tool-help.js +0 -7
@@ -0,0 +1,38 @@
1
+ import {
2
+ resolveWin32Command
3
+ } from "./chunk-5U5ULQX2.js";
4
+
5
+ // src/_session-shell.ts
6
+ function normalizeShell(value) {
7
+ const v = value?.trim().toLowerCase();
8
+ if (v === "cmd" || v === "cmd.exe") return "cmd";
9
+ if (v === "powershell" || v === "powershell.exe") return "powershell";
10
+ if (v === "pwsh" || v === "pwsh.exe") return "pwsh";
11
+ return void 0;
12
+ }
13
+ function resolveSessionShell(platform, env, deps = {}) {
14
+ if (platform !== "win32") return void 0;
15
+ const override = normalizeShell(env.get("WRONGSTACK_SHELL"));
16
+ if (override) return override;
17
+ const hasBinary = deps.hasBinary ?? ((bin) => resolveWin32Command(bin) !== bin);
18
+ if (hasBinary("pwsh.exe")) return "pwsh";
19
+ if (hasBinary("powershell.exe")) return "powershell";
20
+ return "cmd";
21
+ }
22
+ function ensureSessionShell(opts = {}) {
23
+ const env = opts.env ?? process.env;
24
+ const platform = opts.platform ?? process.platform;
25
+ if (platform !== "win32") return void 0;
26
+ const existing = normalizeShell(env["WRONGSTACK_SHELL"]);
27
+ if (existing) return existing;
28
+ const chosen = resolveSessionShell(platform, { get: (k) => env[k] }, { hasBinary: opts.hasBinary }) ?? "cmd";
29
+ env["WRONGSTACK_SHELL"] = chosen;
30
+ return chosen;
31
+ }
32
+
33
+ export {
34
+ normalizeShell,
35
+ resolveSessionShell,
36
+ ensureSessionShell
37
+ };
38
+ //# sourceMappingURL=chunk-SIIOHBNY.js.map
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  kanbanTool
3
- } from "./chunk-SMARDKAC.js";
3
+ } from "./chunk-5UA4TNJJ.js";
4
4
  import {
5
5
  applyManagedKanbanBoardToTodos,
6
6
  blockingTitles,
7
7
  mirrorSessionTodosToKanban,
8
8
  takeSessionMirrorFailure
9
- } from "./chunk-X6KXNHUO.js";
9
+ } from "./chunk-5BKQVP56.js";
10
10
 
11
11
  // src/todo.ts
12
12
  import {
@@ -487,4 +487,4 @@ var todoTool = {
487
487
  export {
488
488
  todoTool
489
489
  };
490
- //# sourceMappingURL=chunk-4YKVHCQC.js.map
490
+ //# sourceMappingURL=chunk-TGVQMKVH.js.map
@@ -3,12 +3,12 @@ import {
3
3
  } from "./chunk-MSOAX3GC.js";
4
4
  import {
5
5
  enqueueReindex
6
- } from "./chunk-CVNCSMVU.js";
6
+ } from "./chunk-DOHU3XHS.js";
7
7
  import {
8
8
  safeResolveReal,
9
9
  sha256hex,
10
10
  truncateDiffPayload
11
- } from "./chunk-ZUFHAHTE.js";
11
+ } from "./chunk-HKR56VNF.js";
12
12
 
13
13
  // src/write.ts
14
14
  import * as fs from "node:fs/promises";
@@ -179,4 +179,4 @@ async function finishWrite(input, ctx, prepared, signal) {
179
179
  export {
180
180
  writeTool
181
181
  };
182
- //# sourceMappingURL=chunk-QU2VRCMM.js.map
182
+ //# sourceMappingURL=chunk-TL5T4A4E.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveIndexDir
3
- } from "./chunk-3JVSOBHU.js";
3
+ } from "./chunk-54SIRJ6D.js";
4
4
 
5
5
  // src/codebase-index/project-server-endpoint.ts
6
6
  import { createHash } from "node:crypto";
@@ -10,6 +10,8 @@ import * as path from "node:path";
10
10
  import { fileURLToPath } from "node:url";
11
11
  var PROJECT_INDEX_SERVER_PROTOCOL_VERSION = 1;
12
12
  var PROJECT_INDEX_SERVER_METADATA_FILE = "server.json";
13
+ var PROJECT_INDEX_SERVER_STDERR_FILE = "server.err.log";
14
+ var PROJECT_INDEX_SERVER_STDERR_MAX_BYTES = 64 * 1024;
13
15
  var PROJECT_INDEX_SERVER_SOCKET_DIR = `wsci-v${PROJECT_INDEX_SERVER_PROTOCOL_VERSION}`;
14
16
  var buildIdCache;
15
17
  function projectIndexServerBuildId(entrypoint) {
@@ -49,6 +51,38 @@ function projectIndexServerMetadataPath(projectRoot, indexDir) {
49
51
  PROJECT_INDEX_SERVER_METADATA_FILE
50
52
  );
51
53
  }
54
+ function projectIndexServerStderrPath(projectRoot, indexDir) {
55
+ return path.join(
56
+ path.resolve(resolveIndexDir(projectRoot, indexDir)),
57
+ PROJECT_INDEX_SERVER_STDERR_FILE
58
+ );
59
+ }
60
+ function readProjectIndexServerStderrTail(path_, maxLines = 4) {
61
+ let raw;
62
+ try {
63
+ const { size } = fs.statSync(path_);
64
+ const start = Math.max(0, size - PROJECT_INDEX_SERVER_STDERR_MAX_BYTES);
65
+ const fd = fs.openSync(path_, "r");
66
+ try {
67
+ const length = size - start;
68
+ if (length <= 0) return null;
69
+ const buffer = Buffer.alloc(length);
70
+ fs.readSync(fd, buffer, 0, length, start);
71
+ raw = buffer.toString("utf8");
72
+ } finally {
73
+ fs.closeSync(fd);
74
+ }
75
+ } catch {
76
+ return null;
77
+ }
78
+ const lines = raw.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
79
+ if (lines.length === 0) return null;
80
+ return lines.slice(-maxLines).join(" | ");
81
+ }
82
+ var PROJECT_INDEX_SERVER_CLOSED_MESSAGE = "codebase-index server connection closed";
83
+ function formatProjectIndexServerCloseError(tail) {
84
+ return tail ? `${PROJECT_INDEX_SERVER_CLOSED_MESSAGE} (server stderr: ${tail})` : PROJECT_INDEX_SERVER_CLOSED_MESSAGE;
85
+ }
52
86
 
53
87
  // src/codebase-index/binary-frame.ts
54
88
  import { decode, encode } from "@msgpack/msgpack";
@@ -114,10 +148,14 @@ export {
114
148
  encodeBinaryFrame,
115
149
  decodeBinaryFrame,
116
150
  PROJECT_INDEX_SERVER_PROTOCOL_VERSION,
151
+ PROJECT_INDEX_SERVER_STDERR_MAX_BYTES,
117
152
  projectIndexServerBuildId,
118
153
  projectIndexServerEndpoint,
119
154
  projectIndexServerMetadataPath,
155
+ projectIndexServerStderrPath,
156
+ readProjectIndexServerStderrTail,
157
+ formatProjectIndexServerCloseError,
120
158
  PROJECT_INDEX_SERVER_MAX_FRAME_CHARS,
121
159
  encodeProjectServerMessage
122
160
  };
123
- //# sourceMappingURL=chunk-6ZLRRC74.js.map
161
+ //# sourceMappingURL=chunk-WBAPU3AB.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  safeResolveReal
3
- } from "./chunk-ZUFHAHTE.js";
3
+ } from "./chunk-HKR56VNF.js";
4
4
 
5
5
  // src/e2e.ts
6
6
  import { open, readdir } from "node:fs/promises";
@@ -422,4 +422,4 @@ export {
422
422
  discoverE2EProjects,
423
423
  e2ePlanTool
424
424
  };
425
- //# sourceMappingURL=chunk-RV7BVTDG.js.map
425
+ //# sourceMappingURL=chunk-WKXL5XHU.js.map
@@ -1,10 +1,13 @@
1
1
  // src/codebase-index/gitignore.ts
2
2
  import * as fs from "node:fs/promises";
3
3
  import * as path from "node:path";
4
- import { compileGlob } from "@wrongstack/core/utils";
5
- function globBody(glob) {
6
- return compileGlob(glob).source.replace(/^\^/, "").replace(/\$$/, "");
7
- }
4
+ import {
5
+ compileGlobMatcher
6
+ } from "@wrongstack/core/utils";
7
+ var START_ANCHORED = (index) => index === 0;
8
+ var START_ANY_SEGMENT = (index, input) => index === 0 || input[index - 1] === "/";
9
+ var END_EQ_OR_UNDER = (index, input) => index === input.length || input[index] === "/";
10
+ var END_UNDER = (index, input) => index < input.length && input[index] === "/";
8
11
  function compileGitignore(lines) {
9
12
  const rules = [];
10
13
  for (const raw of lines) {
@@ -24,11 +27,9 @@ function compileGitignore(lines) {
24
27
  if (!line) continue;
25
28
  const anchored = line.startsWith("/") || line.includes("/");
26
29
  if (line.startsWith("/")) line = line.slice(1);
27
- const body = globBody(line);
28
- const prefix = anchored ? "^" : "(?:^|.*/)";
29
30
  rules.push({
30
- eqOrUnder: new RegExp(`${prefix}${body}(?:/.*)?$`),
31
- under: new RegExp(`${prefix}${body}/.*$`),
31
+ matcher: compileGlobMatcher(line),
32
+ isStart: anchored ? START_ANCHORED : START_ANY_SEGMENT,
32
33
  negated,
33
34
  dirOnly
34
35
  });
@@ -38,8 +39,8 @@ function compileGitignore(lines) {
38
39
  const p = relPath.replace(/\\/g, "/").replace(/^\.\//, "").replace(/^\/+/, "");
39
40
  let ignored = false;
40
41
  for (const r of rules) {
41
- const re = r.dirOnly && !isDir ? r.under : r.eqOrUnder;
42
- if (re.test(p)) {
42
+ const isEnd = r.dirOnly && !isDir ? END_UNDER : END_EQ_OR_UNDER;
43
+ if (r.matcher.testSpan(p, r.isStart, isEnd)) {
43
44
  ignored = !r.negated;
44
45
  if (!hasNegation && ignored) return true;
45
46
  }
@@ -61,4 +62,4 @@ export {
61
62
  compileGitignore,
62
63
  loadGitignoreMatcher
63
64
  };
64
- //# sourceMappingURL=chunk-2CTZW6JQ.js.map
65
+ //# sourceMappingURL=chunk-XHSHNOAF.js.map
@@ -2,8 +2,8 @@
2
2
  var toolSearchTool = {
3
3
  name: "tool_search",
4
4
  category: "Meta",
5
- description: "Search the catalog of available tools by name or description. Use this to discover which tool to use for a task. For the full schema and usage details of a specific tool, use `tool_help` instead.",
6
- usageHint: "SELF-DISCOVERY TOOL:\n\n- Use when you need to find the right tool for a job.\n- `query` searches names and descriptions.\n- You can filter by `tags` (category), `permission`, or `mutating`.\n- Once you find the right tool name, use `tool_help` with that name for full schema details.\nCall this before guessing tool names. It helps you discover the best tool for the current situation.",
5
+ description: "Search the catalog of available tools by name or description. Use this to discover which tool to use for a task, including tools whose schemas were withheld from this request to save tokens.",
6
+ usageHint: "SELF-DISCOVERY TOOL:\n\n- Use when you need to find the right tool for a job.\n- `query` searches names and descriptions.\n- You can filter by `tags` (category), `permission`, or `mutating`.\n- The catalog searched here is the full registry, not just the tools listed in this request.\n- Once you find the right tool name, invoke it with `tool_use`.\nCall this before concluding a capability is unavailable.",
7
7
  permission: "auto",
8
8
  mutating: false,
9
9
  timeoutMs: 1e3,
@@ -68,7 +68,7 @@ var toolSearchTool = {
68
68
  mutating: t.mutating
69
69
  }));
70
70
  const totalAvailable = tools.length;
71
- const hint = results.length === 0 && query ? `No tools matched "${input.query}". Use tool-help (without arguments) to see all ${totalAvailable} available tools.` : void 0;
71
+ const hint = results.length === 0 && query ? `No tools matched "${input.query}". ${totalAvailable} tools are available; call tool_search with no query to list them all.` : void 0;
72
72
  return {
73
73
  tools: results,
74
74
  total: filtered.length,
@@ -82,4 +82,4 @@ var toolSearchTool = {
82
82
  export {
83
83
  toolSearchTool
84
84
  };
85
- //# sourceMappingURL=chunk-24T5XIJU.js.map
85
+ //# sourceMappingURL=chunk-YA2ZYCJY.js.map
@@ -20,7 +20,7 @@ import {
20
20
  COMMAND_OUTPUT_MAX_BYTES,
21
21
  normalizeCommandOutput,
22
22
  safeResolveReal
23
- } from "./chunk-ZUFHAHTE.js";
23
+ } from "./chunk-HKR56VNF.js";
24
24
 
25
25
  // src/exec.ts
26
26
  import { spawn } from "node:child_process";
@@ -1835,4 +1835,4 @@ export {
1835
1835
  getExecAllowlist,
1836
1836
  execTool
1837
1837
  };
1838
- //# sourceMappingURL=chunk-T7YVY2BV.js.map
1838
+ //# sourceMappingURL=chunk-YILT3CSO.js.map
@@ -11,7 +11,7 @@ import {
11
11
  detectPackageManager,
12
12
  normalizeCommandOutput,
13
13
  safeResolveReal
14
- } from "./chunk-ZUFHAHTE.js";
14
+ } from "./chunk-HKR56VNF.js";
15
15
 
16
16
  // src/outdated.ts
17
17
  import { spawn } from "node:child_process";
@@ -66,7 +66,7 @@ var outdatedTool = {
66
66
  const manager = await detectPackageManager(cwd, ctx.projectRoot);
67
67
  if (manager === "npm") {
68
68
  try {
69
- const { detectNonJsEcosystem } = await import("./legacy-bridge-WVQ4BHDI.js");
69
+ const { detectNonJsEcosystem } = await import("./legacy-bridge-XM2GV665.js");
70
70
  const nonJs = await detectNonJsEcosystem(cwd, ctx.projectRoot);
71
71
  if (nonJs) {
72
72
  const { planLanguageOperation, executePackagePlan } = await import("./languages/index.js");
@@ -282,4 +282,4 @@ Note: exit code 1 from \`outdated\` means outdated packages were found (expected
282
282
  export {
283
283
  outdatedTool
284
284
  };
285
- //# sourceMappingURL=chunk-OUEH4I4X.js.map
285
+ //# sourceMappingURL=chunk-YJQQ5F5J.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  tryLegacyPackageOperation
3
- } from "./chunk-GU7QJ37F.js";
3
+ } from "./chunk-JQ43NVFU.js";
4
4
  import {
5
5
  spawnStream
6
6
  } from "./chunk-EMA2XENR.js";
@@ -8,7 +8,7 @@ import {
8
8
  detectPackageManager,
9
9
  normalizeCommandOutput,
10
10
  safeResolveReal
11
- } from "./chunk-ZUFHAHTE.js";
11
+ } from "./chunk-HKR56VNF.js";
12
12
 
13
13
  // src/install.ts
14
14
  import { join } from "node:path";
@@ -253,4 +253,4 @@ function resolveManifestPath(cwd, pkgManager) {
253
253
  export {
254
254
  installTool
255
255
  };
256
- //# sourceMappingURL=chunk-MIV2RU5B.js.map
256
+ //# sourceMappingURL=chunk-ZETZHHV5.js.map
@@ -7,11 +7,12 @@ import {
7
7
  } from "./chunk-ZBMANLYH.js";
8
8
  import {
9
9
  loadGitignoreMatcher
10
- } from "./chunk-2CTZW6JQ.js";
10
+ } from "./chunk-XHSHNOAF.js";
11
11
  import {
12
12
  isBinaryBuffer,
13
+ makeRootRelativizer,
13
14
  safeResolveReal
14
- } from "./chunk-ZUFHAHTE.js";
15
+ } from "./chunk-HKR56VNF.js";
15
16
 
16
17
  // src/grep.ts
17
18
  import { spawn } from "node:child_process";
@@ -34,7 +35,7 @@ var grepTool = {
34
35
  name: "grep",
35
36
  category: "Search",
36
37
  description: "Search exact file contents using a regular expression. Use index-backed `codebase-search` first for symbol or concept discovery when it is live. Prefers ripgrep for speed and features when available.",
37
- usageHint: 'EXACT-TEXT AND REGEX SEARCH:\n\n- When `codebase-search` is live, use it first for symbols and concepts; use `grep` for exact text, regexes, unsupported content, and concrete usage sites.\n- `pattern` is a regular expression.\n- Use `output_mode: "content"` (default) to get matching lines with context.\n- Use `"files_with_matches"` when you only need the list of files.\n- Use `"count"` for quick statistics.\n- `glob` and `path` let you narrow the search scope significantly.\n- Always prefer this over `bash grep` when searching code.',
38
+ usageHint: 'EXACT-TEXT AND REGEX SEARCH:\n\n- When `codebase-search` is live, use it first for symbols and concepts; use `grep` for exact text, regexes, unsupported content, and concrete usage sites.\n- `pattern` is a regular expression.\n- Use `output_mode: "content"` (default) to get matching lines with context.\n- Use `"files_with_matches"` when you only need the list of files.\n- Use `"count"` for quick statistics.\n- `glob` and `path` let you narrow the search scope significantly.\n- Always prefer this over `bash grep` when searching code.\n- Result paths are relative to the project root.',
38
39
  selection: {
39
40
  doNotUseWhen: "you only need to locate files by name or path pattern.",
40
41
  useInstead: ["glob"]
@@ -109,16 +110,17 @@ var grepTool = {
109
110
  });
110
111
  }
111
112
  const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
113
+ const relativize = makeRootRelativizer(ctx.cwd);
112
114
  const rgAvailable = await detectRg();
113
115
  if (rgAvailable) {
114
116
  try {
115
- yield* runRgStream(input, base, mode, limit, signal);
117
+ yield* runRgStream(input, base, mode, limit, signal, relativize);
116
118
  return;
117
119
  } catch {
118
120
  }
119
121
  }
120
122
  yield { type: "log", text: "Falling back to native grep\u2026" };
121
- const out = await runNative(input, base, mode, limit, signal);
123
+ const out = await runNative(input, base, mode, limit, signal, relativize);
122
124
  yield { type: "final", output: out };
123
125
  }
124
126
  };
@@ -146,7 +148,7 @@ function detectRg() {
146
148
  });
147
149
  return rgAvailabilityCache;
148
150
  }
149
- async function* runRgStream(input, base, mode, limit, signal) {
151
+ async function* runRgStream(input, base, mode, limit, signal, relativize) {
150
152
  if (signal.aborted) {
151
153
  yield {
152
154
  type: "final",
@@ -281,8 +283,9 @@ async function* runRgStream(input, base, mode, limit, signal) {
281
283
  totalLines++;
282
284
  if (mode === "count") totalCount += parseRgCountLine(line);
283
285
  if (matches.length < limit) {
284
- matches.push(line);
285
- pendingBatch.push(line);
286
+ const shortened = relativize(line);
287
+ matches.push(shortened);
288
+ pendingBatch.push(shortened);
286
289
  batchSinceFlush++;
287
290
  }
288
291
  }
@@ -302,8 +305,9 @@ async function* runRgStream(input, base, mode, limit, signal) {
302
305
  totalLines++;
303
306
  if (mode === "count") totalCount += parseRgCountLine(line);
304
307
  if (matches.length < limit) {
305
- matches.push(line);
306
- pendingBatch.push(line);
308
+ const shortened = relativize(line);
309
+ matches.push(shortened);
310
+ pendingBatch.push(shortened);
307
311
  }
308
312
  }
309
313
  }
@@ -349,7 +353,7 @@ function parseRgCountLine(line) {
349
353
  const n = Number.parseInt(line.slice(idx + 1), 10);
350
354
  return Number.isFinite(n) ? n : 0;
351
355
  }
352
- async function runNative(input, base, mode, limit, signal) {
356
+ async function runNative(input, base, mode, limit, signal, relativize) {
353
357
  if (signal.aborted) {
354
358
  return {
355
359
  matches: [],
@@ -423,9 +427,9 @@ async function runNative(input, base, mode, limit, signal) {
423
427
  fileHits++;
424
428
  total++;
425
429
  if (mode === "content") {
426
- if (matches.length < limit) matches.push(`${full}:${lineNumber}:${ln}`);
430
+ if (matches.length < limit) matches.push(`${relativize(full)}:${lineNumber}:${ln}`);
427
431
  } else if (mode === "files_with_matches") {
428
- if (fileHits === 1 && matches.length < limit) matches.push(full);
432
+ if (fileHits === 1 && matches.length < limit) matches.push(relativize(full));
429
433
  break;
430
434
  }
431
435
  if (countOnlyFirstHit || mode === "content" && matches.length >= limit) {
@@ -443,16 +447,16 @@ async function runNative(input, base, mode, limit, signal) {
443
447
  fileHits++;
444
448
  total++;
445
449
  if (mode === "content") {
446
- if (matches.length < limit) matches.push(`${full}:${lineNumber}:${ln}`);
450
+ if (matches.length < limit) matches.push(`${relativize(full)}:${lineNumber}:${ln}`);
447
451
  } else if (mode === "files_with_matches") {
448
- if (matches.length < limit) matches.push(full);
452
+ if (matches.length < limit) matches.push(relativize(full));
449
453
  }
450
454
  }
451
455
  }
452
456
  if (fileHits > 0) {
453
457
  if (mode === "count") {
454
458
  if (matches.length < limit) {
455
- matches.push(`${full}:${fileHits}`);
459
+ matches.push(`${relativize(full)}:${fileHits}`);
456
460
  } else {
457
461
  countTruncated = true;
458
462
  }
@@ -522,4 +526,4 @@ export {
522
526
  __resetRgDetectionForTests,
523
527
  __setRgAvailableForTests
524
528
  };
525
- //# sourceMappingURL=chunk-4ERMPDHV.js.map
529
+ //# sourceMappingURL=chunk-ZSW5KO5S.js.map
package/dist/clarify.d.ts CHANGED
@@ -3,29 +3,44 @@
3
3
  *
4
4
  * Prompts the user with structured, multiple-choice questions when architectural,
5
5
  * database schema, API contract, or domain logic assumptions are underspecified.
6
- * Prevents silent misaligned migrations, breaking changes, and refactoring re-work.
6
+ * Bridges clarify + ask_question into a single unified interactive tool
7
+ * functioning consistently across CLI, TUI, and WebUI.
7
8
  */
8
9
  import type { Tool } from '@wrongstack/core/types';
9
- export interface ClarifyQuestionInput {
10
+ export interface ClarifyQuestionItem {
10
11
  /** The core decision or question to clarify with the user. */
11
12
  question: string;
12
13
  /** Context or explanation of why this decision matters (e.g. index performance, validation). */
13
14
  context?: string | undefined;
14
- /** 2 to 4 structured, distinct choices for the user to select. */
15
+ /** 2 to 6 structured, distinct choices for the user to select. */
15
16
  options: string[];
16
17
  /** The option recommended by the assistant based on best practices. */
17
18
  recommendedOption?: string | undefined;
18
19
  /** Whether the user can select multiple options simultaneously. */
19
20
  isMultiSelect?: boolean | undefined;
21
+ /** Snake-case alias for isMultiSelect (Antigravity compatibility). */
22
+ is_multi_select?: boolean | undefined;
20
23
  /** Allow write-in custom responses in addition to options (default: true). */
21
24
  allowCustomResponse?: boolean | undefined;
22
25
  }
26
+ export interface ClarifyQuestionInput extends Partial<ClarifyQuestionItem> {
27
+ /** Batch questions list (Antigravity ask_question parity). */
28
+ questions?: ClarifyQuestionItem[] | undefined;
29
+ }
23
30
  export type ClarifyInput = ClarifyQuestionInput;
31
+ export interface ClarifyAnswerItem {
32
+ question: string;
33
+ selectedOptions: string[];
34
+ customResponse?: string | undefined;
35
+ }
24
36
  export interface ClarifyOutput {
25
37
  status: 'answered' | 'auto_decided' | 'skipped';
38
+ /** Primary / single question (for backward compatibility). */
26
39
  question: string;
27
40
  selectedOptions: string[];
28
41
  customResponse?: string | undefined;
42
+ /** Complete list of answers when clarifying one or more questions. */
43
+ answers?: ClarifyAnswerItem[] | undefined;
29
44
  decisionSummary: string;
30
45
  error?: string | undefined;
31
46
  }
@@ -35,9 +35,8 @@ export interface CodebaseSearchInput {
35
35
  limit?: number | undefined;
36
36
  lspKind?: number | undefined;
37
37
  /**
38
- * When true, hints that LSP-based search should be preferred over the index.
39
- * The built-in tool ignores this (index-only), but when the LSP plugin is
40
- * active it intercepts the tool and provides live LSP workspaceSymbol results.
38
+ * Deprecated compatibility hint. The built-in tool is index-only; the LSP
39
+ * plugin exposes live workspace-symbol search as `codebase-lsp-search`.
41
40
  */
42
41
  preferLsp?: boolean | undefined;
43
42
  }
@@ -4,7 +4,7 @@
4
4
  * Supports the parts of the gitignore spec that matter for skipping source
5
5
  * files: comments / blanks, `!` negation (last match wins), trailing-slash
6
6
  * directory-only rules, leading-slash / embedded-slash anchoring, and the
7
- * `*` / `**` / `?` / `[...]` globs (via core's {@link compileGlob}).
7
+ * `*` / `**` / `?` / `[...]` globs (via core's {@link compileGlobMatcher}).
8
8
  *
9
9
  * Only the project-root `.gitignore` is read. Nested `.gitignore` files are not
10
10
  * walked — the common build/dependency dirs that would live deeper are already
@@ -51,7 +51,7 @@ import {
51
51
  setContextQueryEmbedder,
52
52
  writeAtlas,
53
53
  writeProjectAtlas
54
- } from "../chunk-PNLDTRC5.js";
54
+ } from "../chunk-CYPYJIAF.js";
55
55
  import "../chunk-XRNN44QY.js";
56
56
  import "../chunk-EMA2XENR.js";
57
57
  import "../chunk-SCMRM6NL.js";
@@ -78,11 +78,11 @@ import {
78
78
  shutdownCodebaseIndexHost,
79
79
  shutdownCodebaseIndexServer,
80
80
  symbolGraphService
81
- } from "../chunk-CVNCSMVU.js";
81
+ } from "../chunk-DOHU3XHS.js";
82
82
  import {
83
83
  projectIndexServerEndpoint,
84
84
  projectIndexServerMetadataPath
85
- } from "../chunk-6ZLRRC74.js";
85
+ } from "../chunk-WBAPU3AB.js";
86
86
  import {
87
87
  CONCEPT_RELATIONS,
88
88
  CONTRADICTED_VISIBILITY_WEIGHT,
@@ -122,8 +122,8 @@ import {
122
122
  shouldRefreshRanks,
123
123
  toSymbolRankRows,
124
124
  tokenise
125
- } from "../chunk-3JVSOBHU.js";
126
- import "../chunk-6LCKF5KH.js";
125
+ } from "../chunk-54SIRJ6D.js";
126
+ import "../chunk-7PEZU5Y4.js";
127
127
  import "../chunk-REWOZIA4.js";
128
128
  import "../chunk-6IEBD27U.js";
129
129
  import {
@@ -138,9 +138,9 @@ import {
138
138
  import {
139
139
  compileGitignore,
140
140
  loadGitignoreMatcher
141
- } from "../chunk-2CTZW6JQ.js";
141
+ } from "../chunk-XHSHNOAF.js";
142
142
  import "../chunk-5U5ULQX2.js";
143
- import "../chunk-ZUFHAHTE.js";
143
+ import "../chunk-HKR56VNF.js";
144
144
  export {
145
145
  ATLAS_DIR,
146
146
  ATLAS_FILE_LIMIT,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseFilesContent
3
- } from "../chunk-6LCKF5KH.js";
3
+ } from "../chunk-7PEZU5Y4.js";
4
4
  import "../chunk-REWOZIA4.js";
5
5
  import "../chunk-6IEBD27U.js";
6
6
  import "../chunk-ZKC5UNGD.js";
@@ -1,4 +1,6 @@
1
1
  export declare const PROJECT_INDEX_SERVER_PROTOCOL_VERSION = 1;
2
+ /** Keep only the tail; a daemon that crash-loops must not fill the disk. */
3
+ export declare const PROJECT_INDEX_SERVER_STDERR_MAX_BYTES: number;
2
4
  /**
3
5
  * Content identity for the actual server artifact.
4
6
  *
@@ -33,4 +35,35 @@ export declare function projectIndexServerKey(projectRoot: string, indexDir?: st
33
35
  */
34
36
  export declare function projectIndexServerEndpoint(projectRoot: string, indexDir?: string): string;
35
37
  export declare function projectIndexServerMetadataPath(projectRoot: string, indexDir?: string): string;
38
+ /**
39
+ * Where a detached daemon's stderr is kept.
40
+ *
41
+ * The daemon used to be spawned with `stdio: 'ignore'`, so when it died the
42
+ * only trace was the client's `codebase-index server connection closed` —
43
+ * a message that names the symptom and no cause. Node writes an uncaught
44
+ * exception's stack to stderr before exiting, and V8 writes its fatal
45
+ * out-of-memory message there too (which no JS handler can intercept), so
46
+ * keeping the stream is what makes a dead daemon explain itself.
47
+ */
48
+ export declare function projectIndexServerStderrPath(projectRoot: string, indexDir?: string): string;
49
+ /**
50
+ * The tail of a daemon's stderr, condensed to one line for an error message.
51
+ *
52
+ * Returns null when there is nothing useful: no file, an empty one, or only
53
+ * whitespace. Reads at most the last `PROJECT_INDEX_SERVER_STDERR_MAX_BYTES`
54
+ * so a large file cannot be pulled into memory here.
55
+ */
56
+ export declare function readProjectIndexServerStderrTail(path_: string, maxLines?: number): string | null;
57
+ /** The base close message. Kept as a PREFIX so existing substring matchers
58
+ * (and anyone grepping logs for it) keep working when a reason is appended. */
59
+ export declare const PROJECT_INDEX_SERVER_CLOSED_MESSAGE = "codebase-index server connection closed";
60
+ /**
61
+ * Compose the error a closed connection rejects with.
62
+ *
63
+ * A closed socket has two very different causes — an orderly shutdown and the
64
+ * daemon dying — and they used to be reported identically. When the daemon
65
+ * left something on stderr, that text is the whole difference between a
66
+ * failure someone can act on and one that reads as a flake.
67
+ */
68
+ export declare function formatProjectIndexServerCloseError(tail: string | null): string;
36
69
  //# sourceMappingURL=project-server-endpoint.d.ts.map
@@ -10,7 +10,7 @@ import {
10
10
  projectIndexServerBuildId,
11
11
  projectIndexServerEndpoint,
12
12
  projectIndexServerMetadataPath
13
- } from "../chunk-6ZLRRC74.js";
13
+ } from "../chunk-WBAPU3AB.js";
14
14
  import {
15
15
  contextService,
16
16
  fileGraphService,
@@ -24,8 +24,8 @@ import {
24
24
  statsService,
25
25
  symbolGraphService,
26
26
  vectorSearchService
27
- } from "../chunk-3JVSOBHU.js";
28
- import "../chunk-6LCKF5KH.js";
27
+ } from "../chunk-54SIRJ6D.js";
28
+ import "../chunk-7PEZU5Y4.js";
29
29
  import "../chunk-REWOZIA4.js";
30
30
  import "../chunk-6IEBD27U.js";
31
31
  import {
@@ -34,7 +34,7 @@ import {
34
34
  import {
35
35
  isIndexablePath
36
36
  } from "../chunk-YOHO4DVT.js";
37
- import "../chunk-2CTZW6JQ.js";
37
+ import "../chunk-XHSHNOAF.js";
38
38
  import "../chunk-5U5ULQX2.js";
39
39
 
40
40
  // src/codebase-index/project-server.ts
@@ -44,6 +44,7 @@ import * as net from "node:net";
44
44
  import * as path3 from "node:path";
45
45
  import { startSharedHeapWatchdog, useDaemonPerfDefaults } from "@wrongstack/core/utils";
46
46
  import { bindProjectEndpoint } from "@wrongstack/persistence";
47
+ import { timingSafeTokenEqual } from "@wrongstack/primitives";
47
48
 
48
49
  // src/codebase-index/project-server-framing.ts
49
50
  var MAX_CLIENT_WRITE_BUFFER_BYTES = 8 * 1024 * 1024;
@@ -890,7 +891,7 @@ async function handleMessage(state, message) {
890
891
  state.cancel.get(message.id)?.();
891
892
  return;
892
893
  }
893
- if (message.authToken !== authToken) {
894
+ if (!timingSafeTokenEqual(message.authToken, authToken)) {
894
895
  send(state, {
895
896
  type: "response",
896
897
  id: message.id,