@wrongstack/tools 0.297.0 → 0.298.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 (253) hide show
  1. package/dist/_spawn-stream.d.ts +2 -0
  2. package/dist/_util.d.ts +29 -1
  3. package/dist/audit.js +113 -65
  4. package/dist/bash.js +5 -4
  5. package/dist/batch-tool-use.js +70 -7
  6. package/dist/browser/index.js +31 -1
  7. package/dist/builtin.js +841 -351
  8. package/dist/codebase-index/index.js +68 -16
  9. package/dist/codebase-index/project-server-protocol.d.ts +26 -0
  10. package/dist/codebase-index/project-server.js +60 -16
  11. package/dist/codebase-index/worker.js +36 -13
  12. package/dist/codebase-index/writer-search-helpers.d.ts +16 -0
  13. package/dist/codebase-index/writer.d.ts +13 -1
  14. package/dist/design.d.ts +1 -1
  15. package/dist/design.js +4 -3
  16. package/dist/diff.js +11 -1
  17. package/dist/e2e.js +9 -6
  18. package/dist/edit.js +9 -6
  19. package/dist/exec.js +560 -529
  20. package/dist/format.js +116 -65
  21. package/dist/git.js +22 -2
  22. package/dist/glob.js +11 -5
  23. package/dist/grep.js +160 -104
  24. package/dist/index.js +792 -290
  25. package/dist/install.js +120 -68
  26. package/dist/json.js +64 -18
  27. package/dist/kanban-board-inputs.d.ts +21 -4
  28. package/dist/kanban.js +20 -5
  29. package/dist/languages/index.js +128 -71
  30. package/dist/lint.js +113 -65
  31. package/dist/outdated.js +86 -26
  32. package/dist/pack.js +841 -351
  33. package/dist/patch.js +11 -1
  34. package/dist/plan.js +32 -10
  35. package/dist/read.js +77 -23
  36. package/dist/replace.js +11 -3
  37. package/dist/scaffold.js +9 -6
  38. package/dist/session-kanban.js +21 -5
  39. package/dist/task.js +3 -1
  40. package/dist/test.js +113 -65
  41. package/dist/todo.js +3 -1
  42. package/dist/tool-tier.js +841 -351
  43. package/dist/tool-use.d.ts +1 -1
  44. package/dist/tool-use.js +28 -4
  45. package/dist/tree.d.ts +1 -0
  46. package/dist/tree.js +44 -8
  47. package/dist/typecheck.js +113 -65
  48. package/dist/write.js +9 -6
  49. package/package.json +5 -4
  50. package/dist/_concurrency.d.ts.map +0 -1
  51. package/dist/_danger-detect.d.ts.map +0 -1
  52. package/dist/_edit-match.d.ts.map +0 -1
  53. package/dist/_env.d.ts.map +0 -1
  54. package/dist/_fetch-guard.d.ts.map +0 -1
  55. package/dist/_output-spool.d.ts.map +0 -1
  56. package/dist/_redact-command.d.ts.map +0 -1
  57. package/dist/_regex.d.ts.map +0 -1
  58. package/dist/_session-shell.d.ts.map +0 -1
  59. package/dist/_shell-pick.d.ts.map +0 -1
  60. package/dist/_spawn-stream.d.ts.map +0 -1
  61. package/dist/_syntax-check.d.ts.map +0 -1
  62. package/dist/_util.d.ts.map +0 -1
  63. package/dist/_win32-resolve.d.ts.map +0 -1
  64. package/dist/audit.d.ts.map +0 -1
  65. package/dist/audit.js.map +0 -7
  66. package/dist/auto-proceed-loop-guard.d.ts.map +0 -1
  67. package/dist/auto-proceed-loop-guard.js.map +0 -7
  68. package/dist/bash-kill-guard.d.ts.map +0 -1
  69. package/dist/bash.d.ts.map +0 -1
  70. package/dist/bash.js.map +0 -7
  71. package/dist/batch-tool-use.d.ts.map +0 -1
  72. package/dist/batch-tool-use.js.map +0 -7
  73. package/dist/browser/artifacts.d.ts.map +0 -1
  74. package/dist/browser/index.d.ts.map +0 -1
  75. package/dist/browser/index.js.map +0 -7
  76. package/dist/browser/manager.d.ts.map +0 -1
  77. package/dist/browser/network-guard-proxy.d.ts.map +0 -1
  78. package/dist/browser/security.d.ts.map +0 -1
  79. package/dist/browser/tools.d.ts.map +0 -1
  80. package/dist/browser/types.d.ts.map +0 -1
  81. package/dist/builtin.d.ts.map +0 -1
  82. package/dist/builtin.js.map +0 -7
  83. package/dist/circuit-breaker.d.ts.map +0 -1
  84. package/dist/circuit-breaker.js.map +0 -7
  85. package/dist/codebase-index/background-indexer.d.ts.map +0 -1
  86. package/dist/codebase-index/bm25.d.ts.map +0 -1
  87. package/dist/codebase-index/circuit-breaker.d.ts.map +0 -1
  88. package/dist/codebase-index/codebase-index-tool.d.ts.map +0 -1
  89. package/dist/codebase-index/codebase-search-tool.d.ts.map +0 -1
  90. package/dist/codebase-index/codebase-stats-tool.d.ts.map +0 -1
  91. package/dist/codebase-index/dead-code-scan.d.ts.map +0 -1
  92. package/dist/codebase-index/generic-parser.d.ts.map +0 -1
  93. package/dist/codebase-index/gitignore.d.ts.map +0 -1
  94. package/dist/codebase-index/go-parser.d.ts.map +0 -1
  95. package/dist/codebase-index/index-service.d.ts.map +0 -1
  96. package/dist/codebase-index/index.d.ts.map +0 -1
  97. package/dist/codebase-index/index.js.map +0 -7
  98. package/dist/codebase-index/indexer.d.ts.map +0 -1
  99. package/dist/codebase-index/json-parser.d.ts.map +0 -1
  100. package/dist/codebase-index/languages.d.ts.map +0 -1
  101. package/dist/codebase-index/lsp-kind.d.ts.map +0 -1
  102. package/dist/codebase-index/parser-dispatch.d.ts.map +0 -1
  103. package/dist/codebase-index/project-server-cache.d.ts.map +0 -1
  104. package/dist/codebase-index/project-server-client.d.ts.map +0 -1
  105. package/dist/codebase-index/project-server-endpoint.d.ts.map +0 -1
  106. package/dist/codebase-index/project-server-protocol.d.ts.map +0 -1
  107. package/dist/codebase-index/project-server.d.ts.map +0 -1
  108. package/dist/codebase-index/project-server.js.map +0 -7
  109. package/dist/codebase-index/py-parser.d.ts.map +0 -1
  110. package/dist/codebase-index/refs-extractor.d.ts.map +0 -1
  111. package/dist/codebase-index/rs-parser.d.ts.map +0 -1
  112. package/dist/codebase-index/schema.d.ts.map +0 -1
  113. package/dist/codebase-index/spawn-gate.d.ts.map +0 -1
  114. package/dist/codebase-index/sqlite-runtime.d.ts.map +0 -1
  115. package/dist/codebase-index/ts-parser.d.ts.map +0 -1
  116. package/dist/codebase-index/worker-protocol.d.ts.map +0 -1
  117. package/dist/codebase-index/worker.d.ts.map +0 -1
  118. package/dist/codebase-index/worker.js.map +0 -7
  119. package/dist/codebase-index/writer-admin.d.ts.map +0 -1
  120. package/dist/codebase-index/writer-bulk-insert.d.ts.map +0 -1
  121. package/dist/codebase-index/writer-graph-helpers.d.ts.map +0 -1
  122. package/dist/codebase-index/writer-graph-reader.d.ts.map +0 -1
  123. package/dist/codebase-index/writer-helpers.d.ts.map +0 -1
  124. package/dist/codebase-index/writer-pragmas.d.ts.map +0 -1
  125. package/dist/codebase-index/writer-ref-mapper.d.ts.map +0 -1
  126. package/dist/codebase-index/writer-schema.d.ts.map +0 -1
  127. package/dist/codebase-index/writer-search-helpers.d.ts.map +0 -1
  128. package/dist/codebase-index/writer-store-pool.d.ts.map +0 -1
  129. package/dist/codebase-index/writer.d.ts.map +0 -1
  130. package/dist/codebase-index/yaml-parser.d.ts.map +0 -1
  131. package/dist/design.d.ts.map +0 -1
  132. package/dist/design.js.map +0 -7
  133. package/dist/diff.d.ts.map +0 -1
  134. package/dist/diff.js.map +0 -7
  135. package/dist/document.d.ts.map +0 -1
  136. package/dist/document.js.map +0 -7
  137. package/dist/e2e.d.ts.map +0 -1
  138. package/dist/e2e.js.map +0 -7
  139. package/dist/edit.d.ts.map +0 -1
  140. package/dist/edit.js.map +0 -7
  141. package/dist/exec-kill-guard.d.ts.map +0 -1
  142. package/dist/exec.d.ts.map +0 -1
  143. package/dist/exec.js.map +0 -7
  144. package/dist/fetch.d.ts.map +0 -1
  145. package/dist/fetch.js.map +0 -7
  146. package/dist/format.d.ts.map +0 -1
  147. package/dist/format.js.map +0 -7
  148. package/dist/git.d.ts.map +0 -1
  149. package/dist/git.js.map +0 -7
  150. package/dist/glob.d.ts.map +0 -1
  151. package/dist/glob.js.map +0 -7
  152. package/dist/grep.d.ts.map +0 -1
  153. package/dist/grep.js.map +0 -7
  154. package/dist/index.d.ts.map +0 -1
  155. package/dist/index.js.map +0 -7
  156. package/dist/install.d.ts.map +0 -1
  157. package/dist/install.js.map +0 -7
  158. package/dist/json.d.ts.map +0 -1
  159. package/dist/json.js.map +0 -7
  160. package/dist/kanban-board-inputs.d.ts.map +0 -1
  161. package/dist/kanban-decomposition-actions.d.ts.map +0 -1
  162. package/dist/kanban-detail-actions.d.ts.map +0 -1
  163. package/dist/kanban-evidence-bridge.d.ts.map +0 -1
  164. package/dist/kanban-presence.d.ts.map +0 -1
  165. package/dist/kanban-split-task-handler.d.ts.map +0 -1
  166. package/dist/kanban-task-inputs.d.ts.map +0 -1
  167. package/dist/kanban-tool-results.d.ts.map +0 -1
  168. package/dist/kanban-tool-schema.d.ts.map +0 -1
  169. package/dist/kanban-tool-types.d.ts.map +0 -1
  170. package/dist/kanban.d.ts.map +0 -1
  171. package/dist/kanban.js.map +0 -7
  172. package/dist/languages/detect.d.ts.map +0 -1
  173. package/dist/languages/diagnostics.d.ts.map +0 -1
  174. package/dist/languages/execute-tool.d.ts.map +0 -1
  175. package/dist/languages/execute.d.ts.map +0 -1
  176. package/dist/languages/index.d.ts.map +0 -1
  177. package/dist/languages/index.js.map +0 -7
  178. package/dist/languages/legacy-bridge.d.ts.map +0 -1
  179. package/dist/languages/package-tool.d.ts.map +0 -1
  180. package/dist/languages/plan.d.ts.map +0 -1
  181. package/dist/languages/profile-helpers.d.ts.map +0 -1
  182. package/dist/languages/profiles/additional.d.ts.map +0 -1
  183. package/dist/languages/profiles/primary.d.ts.map +0 -1
  184. package/dist/languages/registry.d.ts.map +0 -1
  185. package/dist/languages/tool.d.ts.map +0 -1
  186. package/dist/languages/types.d.ts.map +0 -1
  187. package/dist/lint.d.ts.map +0 -1
  188. package/dist/lint.js.map +0 -7
  189. package/dist/logs.d.ts.map +0 -1
  190. package/dist/logs.js.map +0 -7
  191. package/dist/memory.d.ts.map +0 -1
  192. package/dist/memory.js.map +0 -7
  193. package/dist/mode.d.ts.map +0 -1
  194. package/dist/mode.js.map +0 -7
  195. package/dist/next-steps.d.ts.map +0 -1
  196. package/dist/next-steps.js.map +0 -7
  197. package/dist/outdated.d.ts.map +0 -1
  198. package/dist/outdated.js.map +0 -7
  199. package/dist/pack.d.ts.map +0 -1
  200. package/dist/pack.js.map +0 -7
  201. package/dist/patch.d.ts.map +0 -1
  202. package/dist/patch.js.map +0 -7
  203. package/dist/plan.d.ts.map +0 -1
  204. package/dist/plan.js.map +0 -7
  205. package/dist/process-guardian.d.ts.map +0 -1
  206. package/dist/process-registry-persistent.d.ts.map +0 -1
  207. package/dist/process-registry.d.ts.map +0 -1
  208. package/dist/process-registry.js.map +0 -7
  209. package/dist/ps-slash.d.ts.map +0 -1
  210. package/dist/ps-slash.js.map +0 -7
  211. package/dist/read.d.ts.map +0 -1
  212. package/dist/read.js.map +0 -7
  213. package/dist/replace.d.ts.map +0 -1
  214. package/dist/replace.js.map +0 -7
  215. package/dist/scaffold.d.ts.map +0 -1
  216. package/dist/scaffold.js.map +0 -7
  217. package/dist/search.d.ts.map +0 -1
  218. package/dist/search.js.map +0 -7
  219. package/dist/session-kanban.d.ts.map +0 -1
  220. package/dist/session-kanban.js.map +0 -7
  221. package/dist/set-working-dir.d.ts.map +0 -1
  222. package/dist/skill.d.ts.map +0 -1
  223. package/dist/skill.js.map +0 -7
  224. package/dist/spawn-background.d.ts.map +0 -1
  225. package/dist/task.d.ts.map +0 -1
  226. package/dist/task.js.map +0 -7
  227. package/dist/test.d.ts.map +0 -1
  228. package/dist/test.js.map +0 -7
  229. package/dist/todo.d.ts.map +0 -1
  230. package/dist/todo.js.map +0 -7
  231. package/dist/tool-diff.d.ts.map +0 -1
  232. package/dist/tool-diff.js.map +0 -7
  233. package/dist/tool-help.d.ts.map +0 -1
  234. package/dist/tool-help.js.map +0 -7
  235. package/dist/tool-icon-map.d.ts.map +0 -1
  236. package/dist/tool-icons.d.ts.map +0 -1
  237. package/dist/tool-icons.js.map +0 -7
  238. package/dist/tool-search.d.ts.map +0 -1
  239. package/dist/tool-search.js.map +0 -7
  240. package/dist/tool-summary.d.ts.map +0 -1
  241. package/dist/tool-summary.js.map +0 -7
  242. package/dist/tool-tier.d.ts.map +0 -1
  243. package/dist/tool-tier.js.map +0 -7
  244. package/dist/tool-use.d.ts.map +0 -1
  245. package/dist/tool-use.js.map +0 -7
  246. package/dist/tree.d.ts.map +0 -1
  247. package/dist/tree.js.map +0 -7
  248. package/dist/typecheck.d.ts.map +0 -1
  249. package/dist/typecheck.js.map +0 -7
  250. package/dist/win32.d.ts.map +0 -1
  251. package/dist/win32.js.map +0 -7
  252. package/dist/write.d.ts.map +0 -1
  253. package/dist/write.js.map +0 -7
package/dist/grep.js CHANGED
@@ -1,10 +1,14 @@
1
1
  // src/grep.ts
2
- import { expectDefined } from "@wrongstack/core/utils";
3
2
  import { spawn } from "node:child_process";
4
3
  import * as fs2 from "node:fs/promises";
5
4
  import * as path3 from "node:path";
6
5
  import { ToolValidationError } from "@wrongstack/core/types";
7
- import { buildChildEnv, compileGlob as compileGlob2, DEFAULT_WALK_IGNORE_DIRS } from "@wrongstack/core/utils";
6
+ import {
7
+ buildChildEnv,
8
+ compileGlob as compileGlob2,
9
+ DEFAULT_WALK_IGNORE_DIRS,
10
+ expectDefined
11
+ } from "@wrongstack/core/utils";
8
12
 
9
13
  // src/_concurrency.ts
10
14
  async function mapWithConcurrency(items, limit, fn) {
@@ -68,9 +72,41 @@ function capSubject(line) {
68
72
  return line.length > MAX_SUBJECT_LEN ? line.slice(0, MAX_SUBJECT_LEN) : line;
69
73
  }
70
74
 
75
+ // src/_util.ts
76
+ import * as path from "node:path";
77
+ import * as Core from "@wrongstack/core/utils";
78
+ function resolvePath(input, ctx) {
79
+ return path.isAbsolute(input) ? path.normalize(input) : path.resolve(ctx.workingDir ?? ctx.cwd, input);
80
+ }
81
+ function allowedRoots(ctx) {
82
+ return [path.resolve(ctx.projectRoot), path.resolve(Core.wstackGlobalRoot())];
83
+ }
84
+ function isInsideAny(target, roots) {
85
+ return roots.some((root) => {
86
+ const rel = path.relative(root, target);
87
+ return rel === "" || !rel.startsWith("..") && !path.isAbsolute(rel);
88
+ });
89
+ }
90
+ function ensureInsideRoot(absPath, ctx) {
91
+ const target = path.resolve(absPath);
92
+ if (ctx.allowOutsideProjectRoot) return target;
93
+ if (isInsideAny(target, allowedRoots(ctx))) return target;
94
+ throw new Error(`Path "${absPath}" is outside project root "${path.resolve(ctx.projectRoot)}"`);
95
+ }
96
+ function safeResolve(input, ctx) {
97
+ return ensureInsideRoot(resolvePath(input, ctx), ctx);
98
+ }
99
+ function isBinaryBuffer(buf) {
100
+ const len = Math.min(buf.length, 8192);
101
+ for (let i = 0; i < len; i++) {
102
+ if (buf[i] === 0) return true;
103
+ }
104
+ return false;
105
+ }
106
+
71
107
  // src/codebase-index/gitignore.ts
72
108
  import * as fs from "node:fs/promises";
73
- import * as path from "node:path";
109
+ import * as path2 from "node:path";
74
110
  import { compileGlob } from "@wrongstack/core/utils";
75
111
  function globBody(glob) {
76
112
  return compileGlob(glob).source.replace(/^\^/, "").replace(/\$$/, "");
@@ -116,50 +152,20 @@ function compileGitignore(lines) {
116
152
  async function loadGitignoreMatcher(projectRoot) {
117
153
  let lines = [];
118
154
  try {
119
- const raw = await fs.readFile(path.join(projectRoot, ".gitignore"), "utf8");
155
+ const raw = await fs.readFile(path2.join(projectRoot, ".gitignore"), "utf8");
120
156
  lines = raw.split("\n");
121
157
  } catch {
122
158
  }
123
159
  return compileGitignore(lines);
124
160
  }
125
161
 
126
- // src/_util.ts
127
- import * as path2 from "node:path";
128
- import * as Core from "@wrongstack/core/utils";
129
- function resolvePath(input, ctx) {
130
- return path2.isAbsolute(input) ? path2.normalize(input) : path2.resolve(ctx.workingDir ?? ctx.cwd, input);
131
- }
132
- function allowedRoots(ctx) {
133
- return [path2.resolve(ctx.projectRoot), path2.resolve(Core.wstackGlobalRoot())];
134
- }
135
- function isInsideAny(target, roots) {
136
- return roots.some((root) => {
137
- const rel = path2.relative(root, target);
138
- return rel === "" || !rel.startsWith("..") && !path2.isAbsolute(rel);
139
- });
140
- }
141
- function ensureInsideRoot(absPath, ctx) {
142
- const target = path2.resolve(absPath);
143
- if (ctx.allowOutsideProjectRoot) return target;
144
- if (isInsideAny(target, allowedRoots(ctx))) return target;
145
- throw new Error(`Path "${absPath}" is outside project root "${path2.resolve(ctx.projectRoot)}"`);
146
- }
147
- function safeResolve(input, ctx) {
148
- return ensureInsideRoot(resolvePath(input, ctx), ctx);
149
- }
150
- function isBinaryBuffer(buf) {
151
- const len = Math.min(buf.length, 8192);
152
- for (let i = 0; i < len; i++) {
153
- if (buf[i] === 0) return true;
154
- }
155
- return false;
156
- }
157
-
158
162
  // src/grep.ts
159
163
  var DEFAULT_IGNORE = DEFAULT_WALK_IGNORE_DIRS;
160
164
  var NATIVE_SCAN_CONCURRENCY = 32;
161
165
  var NATIVE_READ_CHUNK_BYTES = 64 * 1024;
162
166
  var NATIVE_MAX_FILE_BYTES = 1e6;
167
+ var RG_MAX_QUEUE_CHUNKS = 128;
168
+ var RG_MAX_QUEUE_CHARS = 8 * 1024 * 1024;
163
169
  var grepTool = {
164
170
  name: "grep",
165
171
  category: "Search",
@@ -287,9 +293,19 @@ async function* runRgStream(input, base, mode, limit, signal) {
287
293
  const FLUSH_AT = 16;
288
294
  const MAX_BUF_BYTES = 1e6;
289
295
  let bufOverflow = false;
290
- const child = spawn("rg", args, { signal, env: buildChildEnv(), stdio: ["ignore", "pipe", "pipe"], windowsHide: true });
296
+ const child = spawn("rg", args, {
297
+ signal,
298
+ env: buildChildEnv(),
299
+ // rg diagnostics are not part of the tool result. Ignoring stderr avoids
300
+ // an unread pipe filling up and pinning the child when rg reports many
301
+ // filesystem errors.
302
+ stdio: ["ignore", "pipe", "ignore"],
303
+ windowsHide: true
304
+ });
291
305
  const queue = [];
306
+ let queuedChars = 0;
292
307
  let waiter;
308
+ let paused = false;
293
309
  const wake = () => {
294
310
  if (waiter) {
295
311
  const w = waiter;
@@ -297,93 +313,133 @@ async function* runRgStream(input, base, mode, limit, signal) {
297
313
  w();
298
314
  }
299
315
  };
300
- child.stdout?.on("data", (c) => {
301
- queue.push({ kind: "out", data: c.toString() });
316
+ const pauseIfFlooded = () => {
317
+ if (paused || queue.length < RG_MAX_QUEUE_CHUNKS && queuedChars < RG_MAX_QUEUE_CHARS)
318
+ return;
319
+ paused = true;
320
+ child.stdout?.pause();
321
+ };
322
+ const resumeIfDrained = () => {
323
+ if (!paused || queue.length >= RG_MAX_QUEUE_CHUNKS || queuedChars >= RG_MAX_QUEUE_CHARS)
324
+ return;
325
+ paused = false;
326
+ child.stdout?.resume();
327
+ };
328
+ const onStdoutData = (c) => {
329
+ const data = c.toString();
330
+ queue.push({ kind: "out", data });
331
+ queuedChars += data.length;
302
332
  wake();
303
- });
304
- child.on("error", (e) => {
333
+ pauseIfFlooded();
334
+ };
335
+ const onError = (e) => {
305
336
  queue.push({ kind: "error", data: e.message });
306
337
  wake();
307
- });
308
- child.on("close", () => {
338
+ };
339
+ const onClose = () => {
309
340
  queue.push({ kind: "close", data: "" });
310
341
  wake();
311
- });
342
+ };
343
+ child.stdout?.on("data", onStdoutData);
344
+ child.on("error", onError);
345
+ child.on("close", onClose);
312
346
  let pendingBatch = [];
313
347
  let errored = false;
314
- for (; ; ) {
315
- while (queue.length === 0) {
316
- await new Promise((r) => {
317
- waiter = r;
318
- });
319
- }
320
- const c = expectDefined(queue.shift());
321
- if (c.kind === "error") {
322
- errored = true;
323
- continue;
324
- }
325
- if (c.kind === "close") break;
326
- buf += c.data;
327
- if (buf.length > MAX_BUF_BYTES && !bufOverflow) {
328
- bufOverflow = true;
329
- buf = buf.slice(-MAX_BUF_BYTES);
330
- try {
331
- child.kill("SIGTERM");
332
- } catch {
348
+ let closed = false;
349
+ try {
350
+ for (; ; ) {
351
+ while (queue.length === 0) {
352
+ await new Promise((r) => {
353
+ waiter = r;
354
+ });
355
+ }
356
+ const c = expectDefined(queue.shift());
357
+ queuedChars = Math.max(0, queuedChars - c.data.length);
358
+ resumeIfDrained();
359
+ if (c.kind === "error") {
360
+ errored = true;
361
+ continue;
362
+ }
363
+ if (c.kind === "close") {
364
+ closed = true;
365
+ break;
366
+ }
367
+ buf += c.data;
368
+ if (buf.length > MAX_BUF_BYTES && !bufOverflow) {
369
+ bufOverflow = true;
370
+ buf = buf.slice(-MAX_BUF_BYTES);
371
+ try {
372
+ child.kill("SIGTERM");
373
+ } catch {
374
+ }
375
+ }
376
+ const idx = buf.lastIndexOf("\n");
377
+ if (idx === -1) continue;
378
+ const ready = buf.slice(0, idx);
379
+ buf = buf.slice(idx + 1);
380
+ for (const line of ready.split("\n")) {
381
+ if (!line) continue;
382
+ totalLines++;
383
+ if (mode === "count") totalCount += parseRgCountLine(line);
384
+ if (matches.length < limit) {
385
+ matches.push(line);
386
+ pendingBatch.push(line);
387
+ batchSinceFlush++;
388
+ }
389
+ }
390
+ if (batchSinceFlush >= FLUSH_AT) {
391
+ yield {
392
+ type: "partial_output",
393
+ text: pendingBatch.join("\n"),
394
+ data: { matches_so_far: matches.length }
395
+ };
396
+ pendingBatch = [];
397
+ batchSinceFlush = 0;
333
398
  }
334
399
  }
335
- const idx = buf.lastIndexOf("\n");
336
- if (idx === -1) continue;
337
- const ready = buf.slice(0, idx);
338
- buf = buf.slice(idx + 1);
339
- for (const line of ready.split("\n")) {
340
- if (!line) continue;
341
- totalLines++;
342
- if (mode === "count") totalCount += parseRgCountLine(line);
343
- if (matches.length < limit) {
344
- matches.push(line);
345
- pendingBatch.push(line);
346
- batchSinceFlush++;
400
+ if (buf.trim()) {
401
+ for (const line of buf.split("\n")) {
402
+ if (!line) continue;
403
+ totalLines++;
404
+ if (mode === "count") totalCount += parseRgCountLine(line);
405
+ if (matches.length < limit) {
406
+ matches.push(line);
407
+ pendingBatch.push(line);
408
+ }
347
409
  }
348
410
  }
349
- if (batchSinceFlush >= FLUSH_AT) {
411
+ if (pendingBatch.length > 0) {
350
412
  yield {
351
413
  type: "partial_output",
352
414
  text: pendingBatch.join("\n"),
353
415
  data: { matches_so_far: matches.length }
354
416
  };
355
- pendingBatch = [];
356
- batchSinceFlush = 0;
357
417
  }
358
- }
359
- if (buf.trim()) {
360
- for (const line of buf.split("\n")) {
361
- if (!line) continue;
362
- totalLines++;
363
- if (mode === "count") totalCount += parseRgCountLine(line);
364
- if (matches.length < limit) {
365
- matches.push(line);
366
- pendingBatch.push(line);
367
- }
368
- }
369
- }
370
- if (pendingBatch.length > 0) {
418
+ if (errored) throw new Error("rg: spawn error");
371
419
  yield {
372
- type: "partial_output",
373
- text: pendingBatch.join("\n"),
374
- data: { matches_so_far: matches.length }
420
+ type: "final",
421
+ output: {
422
+ matches,
423
+ count: mode === "count" ? totalCount : totalLines,
424
+ truncated: totalLines > limit || bufOverflow,
425
+ used: "rg"
426
+ }
375
427
  };
376
- }
377
- if (errored) throw new Error("rg: spawn error");
378
- yield {
379
- type: "final",
380
- output: {
381
- matches,
382
- count: mode === "count" ? totalCount : totalLines,
383
- truncated: totalLines > limit || bufOverflow,
384
- used: "rg"
428
+ } finally {
429
+ child.stdout?.off("data", onStdoutData);
430
+ child.off("error", onError);
431
+ child.off("close", onClose);
432
+ child.stdout?.destroy();
433
+ queue.length = 0;
434
+ queuedChars = 0;
435
+ waiter = void 0;
436
+ if (!closed && child.exitCode === null) {
437
+ try {
438
+ child.kill("SIGTERM");
439
+ } catch {
440
+ }
385
441
  }
386
- };
442
+ }
387
443
  }
388
444
  function parseRgCountLine(line) {
389
445
  const idx = line.lastIndexOf(":");