@wrongstack/tools 0.318.0 → 0.319.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/_edit-match.d.ts +1 -3
  2. package/dist/_util.d.ts +20 -0
  3. package/dist/audit.js +4 -4
  4. package/dist/bash.js +2 -2
  5. package/dist/builtin.d.ts +10 -0
  6. package/dist/builtin.js +46 -44
  7. package/dist/{chunk-TKA4VEX2.js → chunk-2OXHS3KZ.js} +17 -5
  8. package/dist/{chunk-X5K3U6GI.js → chunk-3M7LLN7W.js} +71 -7
  9. package/dist/{chunk-4AEZIFOW.js → chunk-5EUJF3WC.js} +36 -8
  10. package/dist/{chunk-CVALEVGA.js → chunk-64VIJPFV.js} +34 -13
  11. package/dist/{chunk-ZE6KLBUO.js → chunk-6AAOT4PW.js} +58 -10
  12. package/dist/{chunk-A6BRWIXN.js → chunk-6IEBD27U.js} +20 -5
  13. package/dist/{chunk-HTYEO67J.js → chunk-AKHYMB4V.js} +36 -12
  14. package/dist/{chunk-4E42D7UF.js → chunk-ATSKPZUK.js} +2 -2
  15. package/dist/{chunk-H6AWAZ2Y.js → chunk-B4HTSV6Z.js} +57 -6
  16. package/dist/{chunk-5ZYEGP2P.js → chunk-BK732J7I.js} +72 -27
  17. package/dist/{chunk-WI3VDXHD.js → chunk-BSJSNVGA.js} +108 -19
  18. package/dist/{chunk-UKGMDCXT.js → chunk-C2DQKVLO.js} +61 -28
  19. package/dist/{chunk-CIFAIIHI.js → chunk-CFLJFDYV.js} +100 -58
  20. package/dist/{chunk-JJQB6R7Y.js → chunk-CMOUCKGC.js} +6 -6
  21. package/dist/{chunk-MX25MTDJ.js → chunk-DC4KMPJO.js} +2 -2
  22. package/dist/{chunk-VZLX2JZG.js → chunk-DP6CXMJZ.js} +3 -3
  23. package/dist/{chunk-3QQSBUXR.js → chunk-EADULOZV.js} +36 -12
  24. package/dist/{chunk-6RNIFLG4.js → chunk-ELRRTWNP.js} +38 -6
  25. package/dist/{chunk-CPSAF2AU.js → chunk-FQNXYA6W.js} +45 -6
  26. package/dist/{chunk-ZZT45EHF.js → chunk-GMZYW52L.js} +3 -3
  27. package/dist/{chunk-ZLTFLC25.js → chunk-IIF5HIVF.js} +2 -2
  28. package/dist/{chunk-EMRGN4KM.js → chunk-IU4DV2PA.js} +18 -8
  29. package/dist/{chunk-AGUSOFNI.js → chunk-IWS56OY7.js} +30 -7
  30. package/dist/{chunk-MRZOVQ5D.js → chunk-IYKXK356.js} +98 -11
  31. package/dist/{chunk-6GZPSWP3.js → chunk-JDPQOR7C.js} +14 -7
  32. package/dist/{chunk-BLCSYKNN.js → chunk-KY4PXYSO.js} +10 -15
  33. package/dist/{chunk-WJYXMB2R.js → chunk-LOBRWKCR.js} +63 -14
  34. package/dist/{chunk-J5SKD6LN.js → chunk-MNP3GE7H.js} +38 -27
  35. package/dist/{chunk-S2GBLQ5S.js → chunk-O44IMQCN.js} +31 -7
  36. package/dist/{chunk-P7ZQ2FAJ.js → chunk-OG2BEUBY.js} +69 -34
  37. package/dist/{chunk-K23JNFE3.js → chunk-OTINMOKK.js} +233 -45
  38. package/dist/{chunk-PQTONQ4P.js → chunk-QPNYDH5B.js} +19 -5
  39. package/dist/{chunk-UE3UBMCP.js → chunk-RLMX75EM.js} +19 -8
  40. package/dist/{chunk-3U4H6ZRF.js → chunk-RNWUCZ2U.js} +53 -25
  41. package/dist/{chunk-YF3D5INN.js → chunk-RTZWBNTY.js} +121 -91
  42. package/dist/{chunk-SOG7XIRF.js → chunk-TTZOK6IY.js} +2 -2
  43. package/dist/{chunk-6GVXZCQV.js → chunk-UDVKRX5R.js} +2 -2
  44. package/dist/{chunk-CPVLVQYT.js → chunk-UQQS3VNT.js} +43 -9
  45. package/dist/{chunk-VB3MJGCV.js → chunk-VD2LV5WO.js} +82 -13
  46. package/dist/{chunk-5WNDJHT6.js → chunk-VPALDFYM.js} +2 -2
  47. package/dist/{chunk-FJEQZHZN.js → chunk-W2CECGTG.js} +24 -14
  48. package/dist/{chunk-CISOLTOP.js → chunk-X5FOFGXX.js} +72 -33
  49. package/dist/{chunk-CWALNI6K.js → chunk-X6KXNHUO.js} +1 -1
  50. package/dist/{chunk-EEOFQDT6.js → chunk-XRNN44QY.js} +46 -2
  51. package/dist/{chunk-EOOFNYIT.js → chunk-YOKD4GWJ.js} +67 -27
  52. package/dist/{chunk-D33S4RQG.js → chunk-ZUFHAHTE.js} +18 -6
  53. package/dist/codebase-index/generic-parser.d.ts +8 -1
  54. package/dist/codebase-index/index.js +9 -9
  55. package/dist/codebase-index/parser-worker-script.js +3 -3
  56. package/dist/codebase-index/project-server.js +5 -5
  57. package/dist/codebase-index/worker.js +4 -4
  58. package/dist/codebase-index/writer-refs.d.ts +1 -1
  59. package/dist/design.d.ts +1 -1
  60. package/dist/design.js +1 -1
  61. package/dist/diff.js +3 -2
  62. package/dist/document.js +2 -2
  63. package/dist/e2e.js +2 -2
  64. package/dist/edit.js +8 -8
  65. package/dist/exec.js +2 -2
  66. package/dist/fetch.js +2 -2
  67. package/dist/format.js +4 -4
  68. package/dist/{generic-parser-VUXDIAOZ.js → generic-parser-WFMIRHBX.js} +2 -2
  69. package/dist/git.js +2 -2
  70. package/dist/glob.js +2 -2
  71. package/dist/grep.d.ts +2 -0
  72. package/dist/grep.js +4 -2
  73. package/dist/index.js +46 -46
  74. package/dist/install.js +4 -4
  75. package/dist/json.js +2 -2
  76. package/dist/kanban-tool-types.d.ts +2 -0
  77. package/dist/kanban.js +2 -2
  78. package/dist/languages/index.js +2 -2
  79. package/dist/{legacy-bridge-SFNXIRAP.js → legacy-bridge-3T7SR4SK.js} +4 -4
  80. package/dist/lint.js +4 -4
  81. package/dist/logs.js +2 -2
  82. package/dist/outdated.js +4 -2
  83. package/dist/pack.js +45 -45
  84. package/dist/{parser-dispatch-X62UWXJS.js → parser-dispatch-QGC4HSP5.js} +4 -4
  85. package/dist/patch.js +8 -8
  86. package/dist/plan.js +4 -4
  87. package/dist/{py-parser-TDXSQZBC.js → py-parser-RFWG2HYI.js} +3 -3
  88. package/dist/read.js +8 -8
  89. package/dist/replace.js +9 -8
  90. package/dist/scaffold.js +2 -2
  91. package/dist/search.js +1 -1
  92. package/dist/session-kanban.js +1 -1
  93. package/dist/task.js +4 -4
  94. package/dist/test.js +4 -4
  95. package/dist/todo.js +3 -3
  96. package/dist/tool-tier.js +46 -46
  97. package/dist/{tree-sitter-parser-AIERW3YI.js → tree-sitter-parser-GILYQLS4.js} +2 -2
  98. package/dist/tree.js +2 -2
  99. package/dist/typecheck.js +4 -4
  100. package/dist/write.js +8 -8
  101. package/package.json +5 -5
@@ -56,17 +56,19 @@ var searchTool = {
56
56
  return final;
57
57
  },
58
58
  async *executeStream(input, ctx, opts) {
59
- if (!input?.query || input.query.trim() === "") {
59
+ if (!input?.query || typeof input.query !== "string" || input.query.trim() === "") {
60
60
  throw new ToolValidationError({
61
61
  message: "search: query is required and must be a non-empty string",
62
62
  field: "query"
63
63
  });
64
64
  }
65
65
  const signal = opts?.signal ?? ctx?.signal ?? new AbortController().signal;
66
- const num = Math.max(1, Math.min(input.num_results ?? DEFAULT_NUM, MAX_RESULTS));
66
+ const rawNum = typeof input.num_results === "number" && !Number.isNaN(input.num_results) ? input.num_results : DEFAULT_NUM;
67
+ const num = Math.max(1, Math.min(Math.floor(rawNum), MAX_RESULTS));
67
68
  const source = input.source ?? "duckduckgo";
68
69
  const skipCache = input.skip_cache ?? false;
69
- const cacheKey = `${source}:${input.query}`;
70
+ const normalizedQuery = input.query.trim().toLowerCase().replace(/\s+/g, " ");
71
+ const cacheKey = `${source}:${normalizedQuery}`;
70
72
  if (!skipCache) {
71
73
  const entry = cache.get(cacheKey);
72
74
  if (entry && Date.now() - entry.timestamp < CACHE_TTL_MS) {
@@ -426,11 +428,23 @@ function capSnippet(snippet) {
426
428
  return snippet.length > MAX_SNIPPET_CHARS ? `${snippet.slice(0, MAX_SNIPPET_CHARS - 1)}\u2026` : snippet;
427
429
  }
428
430
  function decodeHtmlEntities(text) {
429
- return text.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'");
431
+ return text.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&#x27;/gi, "'").replace(/&#039;/g, "'").replace(/&nbsp;/g, " ").replace(/&ndash;/g, "\u2013").replace(/&mdash;/g, "\u2014").replace(/&ldquo;|&rdquo;/g, '"').replace(/&lsquo;|&rsquo;/g, "'").replace(/&#(\d+);/g, (_, code) => {
432
+ try {
433
+ return String.fromCodePoint(Number(code));
434
+ } catch {
435
+ return _;
436
+ }
437
+ }).replace(/&#x([0-9a-f]+);/gi, (_, hex) => {
438
+ try {
439
+ return String.fromCodePoint(parseInt(hex, 16));
440
+ } catch {
441
+ return _;
442
+ }
443
+ });
430
444
  }
431
445
 
432
446
  export {
433
447
  searchTool,
434
448
  __clearSearchCache
435
449
  };
436
- //# sourceMappingURL=chunk-PQTONQ4P.js.map
450
+ //# sourceMappingURL=chunk-QPNYDH5B.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  tryLegacyPackageOperation
3
- } from "./chunk-4E42D7UF.js";
3
+ } from "./chunk-ATSKPZUK.js";
4
4
  import {
5
5
  spawnStream
6
6
  } from "./chunk-ZHH3BEWU.js";
@@ -8,7 +8,7 @@ import {
8
8
  detectPackageManager,
9
9
  normalizeCommandOutput,
10
10
  safeResolveReal
11
- } from "./chunk-D33S4RQG.js";
11
+ } from "./chunk-ZUFHAHTE.js";
12
12
 
13
13
  // src/install.ts
14
14
  import { join } from "node:path";
@@ -16,6 +16,7 @@ import {
16
16
  detectEcosystem as detectPackageEcosystem,
17
17
  recordPackageAction
18
18
  } from "@wrongstack/core/coordination";
19
+ import { ToolValidationError } from "@wrongstack/core/types";
19
20
  var installTool = {
20
21
  name: "install",
21
22
  category: "Package Management",
@@ -74,8 +75,17 @@ var installTool = {
74
75
  async *executeStream(input, ctx, opts) {
75
76
  const cwd = input.cwd ? await safeResolveReal(input.cwd, ctx) : ctx.cwd;
76
77
  const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
78
+ signal.throwIfAborted();
79
+ const VALID_SAVES = /* @__PURE__ */ new Set(["dependency", "dev", "optional"]);
80
+ if (input.save !== void 0 && !VALID_SAVES.has(input.save)) {
81
+ throw new ToolValidationError({
82
+ message: `install: invalid save option "${input.save}". Allowed: dependency, dev, optional`,
83
+ field: "save"
84
+ });
85
+ }
77
86
  if (!input.global) {
78
- const pkgList2 = input.packages ? Array.isArray(input.packages) ? input.packages : input.packages.split(",").map((p) => p.trim()) : [];
87
+ const rawList2 = input.packages ? (Array.isArray(input.packages) ? input.packages : input.packages.split(",")).map((p) => p.trim()).filter(Boolean) : [];
88
+ const pkgList2 = Array.from(new Set(rawList2));
79
89
  const bridge = await tryLegacyPackageOperation(
80
90
  "package-install",
81
91
  {
@@ -107,9 +117,8 @@ var installTool = {
107
117
  yield { type: "log", text: `Resolving with ${pkgManager}\u2026`, data: { phase: "resolve" } };
108
118
  const globalFlag = input.global ? ["-g"] : [];
109
119
  const ignoreScripts = input.lifecycleScripts !== true;
110
- const pkgList = input.packages ? (Array.isArray(input.packages) ? input.packages : input.packages.split(",")).map(
111
- (p) => p.trim()
112
- ) : [];
120
+ const rawList = input.packages ? (Array.isArray(input.packages) ? input.packages : input.packages.split(",")).map((p) => p.trim()).filter(Boolean) : [];
121
+ const pkgList = Array.from(new Set(rawList));
113
122
  const PKG_NAME_RE = /^(?:@[a-z0-9._-]+\/)?[a-z0-9._-]+(?:@[a-z0-9^~><=*.+-]+)?$/i;
114
123
  for (const pkg of pkgList) {
115
124
  if (!PKG_NAME_RE.test(pkg) || pkg.startsWith("-") || pkg.length > 200) {
@@ -166,10 +175,12 @@ var installTool = {
166
175
  signal,
167
176
  maxBytes: 1e5
168
177
  });
178
+ const rawOutput = result.stdout && result.stderr ? `${result.stdout}
179
+ ${result.stderr}` : result.stdout || result.stderr || result.error || "";
169
180
  const output = {
170
181
  packages: pkgList,
171
182
  exit_code: result.exitCode,
172
- output: normalizeCommandOutput(result.stdout || result.stderr || result.error || ""),
183
+ output: normalizeCommandOutput(rawOutput),
173
184
  dry_run: args.includes("--dry-run"),
174
185
  truncated: result.truncated
175
186
  };
@@ -221,4 +232,4 @@ function resolveManifestPath(cwd, pkgManager) {
221
232
  export {
222
233
  installTool
223
234
  };
224
- //# sourceMappingURL=chunk-UE3UBMCP.js.map
235
+ //# sourceMappingURL=chunk-RLMX75EM.js.map
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  getIndexState,
3
3
  searchCodebaseIndex
4
- } from "./chunk-VZLX2JZG.js";
4
+ } from "./chunk-DP6CXMJZ.js";
5
5
  import {
6
6
  codebaseIndexDirOverride
7
- } from "./chunk-BLCSYKNN.js";
7
+ } from "./chunk-KY4PXYSO.js";
8
8
  import {
9
9
  isBinaryBuffer,
10
10
  safeResolveReal,
11
11
  sha256hex
12
- } from "./chunk-D33S4RQG.js";
12
+ } from "./chunk-ZUFHAHTE.js";
13
13
 
14
14
  // src/read.ts
15
15
  import * as fs from "node:fs/promises";
@@ -113,8 +113,8 @@ var readTool = {
113
113
  const limit = Math.max(0, Math.min(input.limit ?? 2e3, 5e3));
114
114
  const prior = getReadRangeRecord(ctx, absPath);
115
115
  const requestedEnd = prior ? Math.min(offset + limit - 1, prior.totalLines) : offset + limit - 1;
116
- if (input.mode !== "summary" && limit > 0 && prior && coversRange(prior, stat2.mtimeMs, offset, requestedEnd)) {
117
- ctx.recordRead(absPath, stat2.mtimeMs);
116
+ if (input.mode !== "summary" && limit > 0 && prior && offset <= requestedEnd && coversRange(prior, stat2.mtimeMs, stat2.size, offset, requestedEnd)) {
117
+ ctx.recordRead(absPath, stat2.mtimeMs, "user", ctx.lastReadHash?.(absPath));
118
118
  const symResult2 = shouldIncludeSymbols ? await fetchSymbolsForFile(absPath, ctx, signal) : void 0;
119
119
  return {
120
120
  text: `[unchanged since previous read: "${input.path}" mtime=${Math.round(stat2.mtimeMs)}; requested lines ${offset}-${requestedEnd} were already shown. Use offset/limit for a new range if needed.]`,
@@ -142,13 +142,14 @@ var readTool = {
142
142
  const total = allLines.length;
143
143
  if (input.mode === "summary") {
144
144
  ctx.recordRead(absPath, stat2.mtimeMs, "user", contentHash);
145
- rememberReadRange(ctx, absPath, stat2.mtimeMs, total, 1, Math.min(total, 200));
145
+ rememberReadRange(ctx, absPath, stat2.mtimeMs, stat2.size, total, 1, Math.min(total, 200));
146
146
  const symResult2 = shouldIncludeSymbols ? await fetchSymbolsForFile(absPath, ctx, signal) : void 0;
147
+ const summary = summarizeFile(input.path, stat2.size, allLines);
147
148
  return {
148
- text: summarizeFile(input.path, stat2.size, allLines),
149
+ text: summary.text,
149
150
  total_lines: total,
150
151
  encoding: "utf8",
151
- truncated: total > 200,
152
+ truncated: summary.truncated,
152
153
  note: mergeSymbolNote(
153
154
  "Summary mode returned compact structure instead of full file content.",
154
155
  symResult2?.note
@@ -158,7 +159,7 @@ var readTool = {
158
159
  }
159
160
  if (limit === 0) {
160
161
  ctx.recordRead(absPath, stat2.mtimeMs, "user", contentHash);
161
- rememberReadRange(ctx, absPath, stat2.mtimeMs, total, 1, 0);
162
+ rememberReadRange(ctx, absPath, stat2.mtimeMs, stat2.size, total, 1, 0);
162
163
  const symResult2 = shouldIncludeSymbols ? await fetchSymbolsForFile(absPath, ctx, signal) : void 0;
163
164
  return {
164
165
  text: "",
@@ -171,7 +172,6 @@ var readTool = {
171
172
  }
172
173
  if (offset > total) {
173
174
  ctx.recordRead(absPath, stat2.mtimeMs, "user", contentHash);
174
- rememberReadRange(ctx, absPath, stat2.mtimeMs, total, total + 1, total + 1);
175
175
  const symResult2 = shouldIncludeSymbols ? await fetchSymbolsForFile(absPath, ctx, signal) : void 0;
176
176
  return {
177
177
  text: `[offset ${offset} is past end of file "${input.path}" \u2014 file has ${total} line(s). Do not retry this offset.]`,
@@ -184,10 +184,26 @@ var readTool = {
184
184
  }
185
185
  const slice = allLines.slice(offset - 1, offset - 1 + limit);
186
186
  const truncated = offset - 1 + slice.length < total;
187
- const width = String(offset + slice.length - 1).length;
188
- const numbered = slice.map((line, i) => `${String(offset + i).padStart(width, " ")}\u2192${line}`).join("\n");
187
+ const sliceCount = slice.length;
188
+ const width = String(offset + sliceCount - 1).length;
189
+ const parts = new Array(sliceCount);
190
+ for (let i = 0; i < sliceCount; i++) {
191
+ const numStr = String(offset + i);
192
+ const padLen = width - numStr.length;
193
+ const pad = padLen > 0 ? " ".repeat(padLen) : "";
194
+ parts[i] = `${pad}${numStr}\u2192${slice[i]}`;
195
+ }
196
+ const numbered = parts.join("\n");
189
197
  ctx.recordRead(absPath, stat2.mtimeMs, "user", contentHash);
190
- rememberReadRange(ctx, absPath, stat2.mtimeMs, total, offset, offset + slice.length - 1);
198
+ rememberReadRange(
199
+ ctx,
200
+ absPath,
201
+ stat2.mtimeMs,
202
+ stat2.size,
203
+ total,
204
+ offset,
205
+ offset + slice.length - 1
206
+ );
191
207
  const symResult = shouldIncludeSymbols ? await fetchSymbolsForFile(absPath, ctx, signal) : void 0;
192
208
  return {
193
209
  text: numbered,
@@ -208,7 +224,7 @@ async function fetchSymbolsForFile(absPath, ctx, signal) {
208
224
  projectRoot: ctx.projectRoot,
209
225
  indexDir: codebaseIndexDirOverride(ctx),
210
226
  query: "",
211
- file: absPath,
227
+ file: absPath.replace(/\\/g, "/"),
212
228
  limit: 500
213
229
  },
214
230
  { signal }
@@ -248,20 +264,23 @@ function getReadRanges(ctx) {
248
264
  function getReadRangeRecord(ctx, absPath) {
249
265
  return getReadRanges(ctx)[absPath];
250
266
  }
251
- function rememberReadRange(ctx, absPath, mtimeMs, totalLines, start, end) {
267
+ var MTIME_TOLERANCE_MS = process.platform === "win32" ? 2e3 : 1;
268
+ function rememberReadRange(ctx, absPath, mtimeMs, size, totalLines, start, end) {
252
269
  if (end < start) return;
253
270
  const ranges = getReadRanges(ctx);
254
271
  const prior = ranges[absPath];
255
- const nextRanges = prior && Math.abs(prior.mtimeMs - mtimeMs) <= 1 ? prior.ranges.slice() : [];
272
+ const nextRanges = prior && prior.size === size && Math.abs(prior.mtimeMs - mtimeMs) <= MTIME_TOLERANCE_MS ? prior.ranges.slice() : [];
256
273
  nextRanges.push({ start, end });
257
274
  ranges[absPath] = {
258
275
  mtimeMs,
276
+ size,
259
277
  totalLines,
260
278
  ranges: mergeRanges(nextRanges)
261
279
  };
262
280
  }
263
- function coversRange(record, mtimeMs, start, end) {
264
- if (Math.abs(record.mtimeMs - mtimeMs) > 1) return false;
281
+ function coversRange(record, mtimeMs, size, start, end) {
282
+ if (record.size !== void 0 && record.size !== size) return false;
283
+ if (Math.abs(record.mtimeMs - mtimeMs) > MTIME_TOLERANCE_MS) return false;
265
284
  return record.ranges.some((range) => range.start <= start && range.end >= end);
266
285
  }
267
286
  function mergeRanges(ranges) {
@@ -278,21 +297,30 @@ function mergeRanges(ranges) {
278
297
  return merged;
279
298
  }
280
299
  function summarizeFile(filePath, bytes, lines) {
281
- const interesting = lines.map((line, index) => ({ line: line.trim(), number: index + 1 })).filter(
282
- ({ line }) => /^(import\s|export\s|class\s|interface\s|type\s|function\s|const\s+\w+\s*=|let\s+\w+\s*=|var\s+\w+\s*=|def\s+|async\s+function\s)/.test(
283
- line
284
- )
285
- ).slice(0, 80).map(({ line, number }) => `${number}: ${line}`);
286
- return [
300
+ const interesting = [];
301
+ const symbolRegex = /^(import\s|export\s|class\s|interface\s|type\s|function\s|const\s+\w+\s*=|let\s+\w+\s*=|var\s+\w+\s*=|def\s+|async\s+(?:def|function)\s|func\s+|fn\s+|pub\s+(?:fn|struct|enum|trait|type|const)\s+|struct\s+|enum\s+|impl\s+)/;
302
+ let truncated = false;
303
+ for (let i = 0; i < lines.length; i++) {
304
+ if (interesting.length >= 80) {
305
+ truncated = true;
306
+ break;
307
+ }
308
+ const trimmed = lines[i].trim();
309
+ if (symbolRegex.test(trimmed)) {
310
+ interesting.push(`${i + 1}: ${trimmed}`);
311
+ }
312
+ }
313
+ const text = [
287
314
  `summary: ${filePath}`,
288
315
  `bytes=${bytes}`,
289
316
  `total_lines=${lines.length}`,
290
317
  interesting.length > 0 ? `symbols/imports:
291
318
  ${interesting.join("\n")}` : "symbols/imports: (none detected)"
292
319
  ].join("\n");
320
+ return { text, truncated };
293
321
  }
294
322
 
295
323
  export {
296
324
  readTool
297
325
  };
298
- //# sourceMappingURL=chunk-3U4H6ZRF.js.map
326
+ //# sourceMappingURL=chunk-RNWUCZ2U.js.map