@nxuss/lemma 1.8.0 → 1.9.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 (76) hide show
  1. package/README.md +126 -176
  2. package/dist/cjs/mcp/prompts.d.ts +10 -1
  3. package/dist/cjs/mcp/prompts.d.ts.map +1 -1
  4. package/dist/cjs/mcp/prompts.js +25 -73
  5. package/dist/cjs/mcp/prompts.js.map +1 -1
  6. package/dist/cjs/mcp/tool-profiles.d.ts +10 -1
  7. package/dist/cjs/mcp/tool-profiles.d.ts.map +1 -1
  8. package/dist/cjs/mcp/tool-profiles.js +12 -3
  9. package/dist/cjs/mcp/tool-profiles.js.map +1 -1
  10. package/dist/cjs/mcp/tools.d.ts.map +1 -1
  11. package/dist/cjs/mcp/tools.js +122 -28
  12. package/dist/cjs/mcp/tools.js.map +1 -1
  13. package/dist/cjs/mcp/utils.d.ts.map +1 -1
  14. package/dist/cjs/mcp/utils.js +19 -6
  15. package/dist/cjs/mcp/utils.js.map +1 -1
  16. package/dist/cjs/security/SemanticScrubber.d.ts +2 -0
  17. package/dist/cjs/security/SemanticScrubber.d.ts.map +1 -1
  18. package/dist/cjs/security/SemanticScrubber.js +53 -13
  19. package/dist/cjs/security/SemanticScrubber.js.map +1 -1
  20. package/dist/cjs/utils/ContextSqueezer.d.ts.map +1 -1
  21. package/dist/cjs/utils/ContextSqueezer.js +55 -22
  22. package/dist/cjs/utils/ContextSqueezer.js.map +1 -1
  23. package/dist/cjs/utils/FileOutline.d.ts +22 -0
  24. package/dist/cjs/utils/FileOutline.d.ts.map +1 -0
  25. package/dist/cjs/utils/FileOutline.js +55 -0
  26. package/dist/cjs/utils/FileOutline.js.map +1 -0
  27. package/dist/cjs/utils/LineNumberMap.d.ts +29 -0
  28. package/dist/cjs/utils/LineNumberMap.d.ts.map +1 -0
  29. package/dist/cjs/utils/LineNumberMap.js +98 -0
  30. package/dist/cjs/utils/LineNumberMap.js.map +1 -0
  31. package/dist/cjs/utils/PatchMatcher.d.ts +2 -0
  32. package/dist/cjs/utils/PatchMatcher.d.ts.map +1 -1
  33. package/dist/cjs/utils/PatchMatcher.js +9 -1
  34. package/dist/cjs/utils/PatchMatcher.js.map +1 -1
  35. package/dist/cjs/utils/ReadWorkspaceCache.d.ts +16 -3
  36. package/dist/cjs/utils/ReadWorkspaceCache.d.ts.map +1 -1
  37. package/dist/cjs/utils/ReadWorkspaceCache.js +20 -8
  38. package/dist/cjs/utils/ReadWorkspaceCache.js.map +1 -1
  39. package/dist/esm/mcp/prompts.d.ts +10 -1
  40. package/dist/esm/mcp/prompts.d.ts.map +1 -1
  41. package/dist/esm/mcp/prompts.js +25 -73
  42. package/dist/esm/mcp/prompts.js.map +1 -1
  43. package/dist/esm/mcp/tool-profiles.d.ts +10 -1
  44. package/dist/esm/mcp/tool-profiles.d.ts.map +1 -1
  45. package/dist/esm/mcp/tool-profiles.js +12 -3
  46. package/dist/esm/mcp/tool-profiles.js.map +1 -1
  47. package/dist/esm/mcp/tools.d.ts.map +1 -1
  48. package/dist/esm/mcp/tools.js +122 -28
  49. package/dist/esm/mcp/tools.js.map +1 -1
  50. package/dist/esm/mcp/utils.d.ts.map +1 -1
  51. package/dist/esm/mcp/utils.js +19 -6
  52. package/dist/esm/mcp/utils.js.map +1 -1
  53. package/dist/esm/security/SemanticScrubber.d.ts +2 -0
  54. package/dist/esm/security/SemanticScrubber.d.ts.map +1 -1
  55. package/dist/esm/security/SemanticScrubber.js +53 -13
  56. package/dist/esm/security/SemanticScrubber.js.map +1 -1
  57. package/dist/esm/utils/ContextSqueezer.d.ts.map +1 -1
  58. package/dist/esm/utils/ContextSqueezer.js +55 -22
  59. package/dist/esm/utils/ContextSqueezer.js.map +1 -1
  60. package/dist/esm/utils/FileOutline.d.ts +22 -0
  61. package/dist/esm/utils/FileOutline.d.ts.map +1 -0
  62. package/dist/esm/utils/FileOutline.js +51 -0
  63. package/dist/esm/utils/FileOutline.js.map +1 -0
  64. package/dist/esm/utils/LineNumberMap.d.ts +29 -0
  65. package/dist/esm/utils/LineNumberMap.d.ts.map +1 -0
  66. package/dist/esm/utils/LineNumberMap.js +93 -0
  67. package/dist/esm/utils/LineNumberMap.js.map +1 -0
  68. package/dist/esm/utils/PatchMatcher.d.ts +2 -0
  69. package/dist/esm/utils/PatchMatcher.d.ts.map +1 -1
  70. package/dist/esm/utils/PatchMatcher.js +9 -1
  71. package/dist/esm/utils/PatchMatcher.js.map +1 -1
  72. package/dist/esm/utils/ReadWorkspaceCache.d.ts +16 -3
  73. package/dist/esm/utils/ReadWorkspaceCache.d.ts.map +1 -1
  74. package/dist/esm/utils/ReadWorkspaceCache.js +19 -8
  75. package/dist/esm/utils/ReadWorkspaceCache.js.map +1 -1
  76. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"tool-profiles.js","sourceRoot":"","sources":["../../../src/mcp/tool-profiles.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-profiles.js","sourceRoot":"","sources":["../../../src/mcp/tool-profiles.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAwjCnE,oFAAoF;AACpF,wBAAgB,kBAAkB,IAAI,MAAM,CAM3C;AAED,oEAAoE;AACpE,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD;AAED,iEAAiE;AACjE,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,IAAI;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAQA;AAqHD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAqCD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAC1C,IAAI,CAwEN"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AA0kCnE,oFAAoF;AACpF,wBAAgB,kBAAkB,IAAI,MAAM,CAM3C;AAED,oEAAoE;AACpE,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD;AAED,iEAAiE;AACjE,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,IAAI;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAQA;AAqHD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAqCD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAC1C,IAAI,CAwEN"}
@@ -81,6 +81,8 @@ const CommandOutputDistiller_1 = require("../utils/CommandOutputDistiller");
81
81
  const PatchMatcher_1 = require("../utils/PatchMatcher");
82
82
  const WorkspaceSearch_1 = require("../utils/WorkspaceSearch");
83
83
  const ReadWorkspaceCache_1 = require("../utils/ReadWorkspaceCache");
84
+ const LineNumberMap_1 = require("../utils/LineNumberMap");
85
+ const FileOutline_1 = require("../utils/FileOutline");
84
86
  const SearchCache_1 = require("../utils/SearchCache");
85
87
  // ── Pro License Gate ──────────────────────────────────────────────────────────
86
88
  const LICENSE_FILE = path_1.default.join(os_1.default.homedir(), '.lemma-cache', 'license.json');
@@ -206,13 +208,16 @@ const toolDefinitions = [
206
208
  },
207
209
  {
208
210
  name: "read_workspace_file",
209
- description: "Read a file inside the workspace. Automatically compresses comments/whitespace and scrubs API keys. If this exact file (same compact mode) was already read this session and hasn't changed on disk, returns a short UNCHANGED marker instead of resending the full content — reuse your existing copy. Pass force:true to always get the full content.",
211
+ description: "Read a file inside the workspace. Compresses comments/whitespace and scrubs API keys. Every line carries its REAL line number in the original file (compression removes lines, it never renumbers them), so you can cite file:line and patch precisely without re-reading. The header lists which imports were compressed away. Use offset/limit to read a line range of a large file. If this exact view was already read this session and hasn't changed on disk, returns an UNCHANGED marker plus a symbol outline — reuse your copy, or pass force:true if it's no longer in your context.",
210
212
  inputSchema: {
211
213
  type: "object",
212
214
  properties: {
213
215
  filePath: { type: "string", description: "Path relative to the project root" },
214
216
  compact: { type: "boolean", description: "Whether to compress comments and whitespace", default: true },
215
217
  force: { type: "boolean", description: "Bypass the unchanged-file short-circuit and always return full content", default: false },
218
+ lineNumbers: { type: "boolean", description: "Prefix each line with its real line number in the original file", default: true },
219
+ offset: { type: "number", description: "First line to read (1-indexed). Omit to start at the beginning." },
220
+ limit: { type: "number", description: "How many lines to read from offset. Omit to read to the end." },
216
221
  },
217
222
  required: ["filePath"],
218
223
  },
@@ -256,7 +261,7 @@ const toolDefinitions = [
256
261
  },
257
262
  {
258
263
  name: "run_workspace_command",
259
- description: "Execute a bash command in the workspace root (15s timeout). Captures both stdout and stderr. Long test/build/lint output is distilled deterministically — for jest, vitest and tsc it returns the failing tests or diagnostics with their locations and reasons, dropping code frames and node_modules stack frames; anything else falls back to head/tail plus error-matching lines. The complete output is always stored first and the reply carries a handle: nothing is lost, use output_region to retrieve any part verbatim. Pass raw:true to skip distillation.",
264
+ description: "Execute a bash command in the workspace root. Default timeout 120s — raise it with timeoutMs for a full test or build run (max 600s). Captures both stdout and stderr, and returns whatever was produced even if the command times out. Long test/build/lint output is distilled deterministically — for jest, vitest and tsc it returns the failing tests or diagnostics with their locations and reasons, dropping code frames and node_modules stack frames; anything else falls back to head/tail plus error-matching lines. The complete output is always stored first and the reply carries a handle: nothing is lost, use output_region to retrieve any part verbatim. Pass raw:true to skip distillation.",
260
265
  inputSchema: {
261
266
  type: "object",
262
267
  properties: {
@@ -266,6 +271,11 @@ const toolDefinitions = [
266
271
  description: "Return the complete untouched output instead of the distilled view",
267
272
  default: false,
268
273
  },
274
+ timeoutMs: {
275
+ type: "number",
276
+ description: "Milliseconds before the command is killed (default 120000, max 600000)",
277
+ default: 120000,
278
+ },
269
279
  },
270
280
  required: ["command"],
271
281
  },
@@ -1087,7 +1097,15 @@ const allToolDefinitions = [
1087
1097
  ];
1088
1098
  // Narrow what gets advertised to what this project can actually use. Hidden tools stay
1089
1099
  // registered in `toolHandlers` and callable — both directly and through `lemma_toolbox`.
1090
- const _toolSurface = (0, tool_profiles_1.resolveToolSurface)(allToolDefinitions, process.cwd());
1100
+ //
1101
+ // The entitlement filter matters as much as the project filter: without it a free session
1102
+ // advertised the full core surface — read, search, patch, run, AST — and refused fourteen of
1103
+ // those twenty tools at call time. That is the worst of both, paying the per-turn schema cost
1104
+ // for capabilities the session cannot use. They remain listed in `lemma_toolbox`, so the
1105
+ // capability is still discoverable and the upgrade path is still visible.
1106
+ const _toolSurface = (0, tool_profiles_1.resolveToolSurface)(allToolDefinitions, process.cwd(), {
1107
+ isEntitled: (name) => isProUser() || FREE_TOOLS.has(name),
1108
+ });
1091
1109
  const toolDefinitionsArray = _toolSurface.advertised;
1092
1110
  const hiddenToolDefinitions = _toolSurface.hidden;
1093
1111
  /** Serialized size of every tool schema sent to the client, for cost accounting. */
@@ -1480,14 +1498,28 @@ async function handleReadWorkspaceFile(args) {
1480
1498
  const filePath = args?.filePath;
1481
1499
  const compact = args?.compact !== false;
1482
1500
  const force = !!args?.force;
1501
+ const lineNumbers = args?.lineNumbers !== false;
1502
+ const offset = typeof args?.offset === "number" && args.offset > 0 ? Math.floor(args.offset) : undefined;
1503
+ const limit = typeof args?.limit === "number" && args.limit > 0 ? Math.floor(args.limit) : undefined;
1483
1504
  if (!filePath)
1484
1505
  throw new Error("filePath is required");
1485
1506
  const workspaceRoot = process.cwd();
1486
1507
  try {
1487
1508
  const { resolved } = (0, utils_1.safeResolvePath)(workspaceRoot, filePath);
1488
- let content = fs_1.default.readFileSync(resolved, "utf8");
1509
+ const fullContent = fs_1.default.readFileSync(resolved, "utf8");
1510
+ const view = { compact, lineNumbers, offset, limit };
1511
+ // The range is applied to the original file, before any compression: `offset` means the
1512
+ // line the user would see in an editor, not a position in the squeezed output.
1513
+ const allLines = fullContent.split("\n");
1514
+ const startIndex = offset ? Math.min(offset - 1, allLines.length) : 0;
1515
+ const endIndex = limit ? Math.min(startIndex + limit, allLines.length) : allLines.length;
1516
+ const ranged = offset || limit ? allLines.slice(startIndex, endIndex).join("\n") : fullContent;
1517
+ const rangeHeader = offset || limit
1518
+ ? `[lines ${startIndex + 1}-${endIndex} of ${allLines.length} in ${filePath}]\n`
1519
+ : "";
1520
+ let content = ranged;
1489
1521
  const originalSize = content.length;
1490
- const dedup = (0, ReadWorkspaceCache_1.checkAlreadySent)(resolved, compact, content);
1522
+ const dedup = (0, ReadWorkspaceCache_1.checkAlreadySent)(resolved, view, content);
1491
1523
  if (!force && dedup.unchanged) {
1492
1524
  (0, reportSavings_1.reportSavings)({
1493
1525
  source: "contextSqueeze",
@@ -1496,17 +1528,32 @@ async function handleReadWorkspaceFile(args) {
1496
1528
  toolName: "read_workspace_file",
1497
1529
  filePath,
1498
1530
  });
1531
+ // A hash alone is not actionable: the model's context may have been compacted since,
1532
+ // in which case it no longer holds the copy this marker tells it to reuse. The outline
1533
+ // costs ~50 tokens and is enough to either locate what it needs or decide to re-fetch.
1534
+ const outline = (0, FileOutline_1.formatOutline)((0, FileOutline_1.fileOutline)(content), allLines.length);
1499
1535
  return {
1500
1536
  content: [
1501
1537
  {
1502
1538
  type: "text",
1503
- text: `UNCHANGED: ${filePath} is identical to what you already read this session (hash ${dedup.hash.slice(0, 12)}) — reuse your existing copy. Pass force:true to re-fetch anyway.`,
1539
+ text: [
1540
+ `UNCHANGED: ${filePath} is identical to what you already read this session (hash ${dedup.hash.slice(0, 12)}) — reuse your existing copy.`,
1541
+ `If it is no longer in your context, re-fetch with force:true. Structure:`,
1542
+ outline,
1543
+ ].join("\n"),
1504
1544
  },
1505
1545
  ],
1506
1546
  };
1507
1547
  }
1548
+ // Line numbers are computed against the pre-squeeze text and carried through, so a
1549
+ // compressed read still reports the position the code actually occupies on disk.
1550
+ let numbers = null;
1508
1551
  if (compact) {
1509
- content = (0, ContextSqueezer_1.squeezeCode)(content);
1552
+ const squeezed = (0, ContextSqueezer_1.squeezeCode)(content);
1553
+ if (lineNumbers) {
1554
+ numbers = (0, LineNumberMap_1.mapSqueezedToOriginal)(content, squeezed).map((n) => (n === null ? null : n + startIndex));
1555
+ }
1556
+ content = squeezed;
1510
1557
  if (content.length < originalSize) {
1511
1558
  (0, reportSavings_1.reportSavings)({
1512
1559
  source: "contextSqueeze",
@@ -1517,16 +1564,26 @@ async function handleReadWorkspaceFile(args) {
1517
1564
  });
1518
1565
  }
1519
1566
  }
1567
+ else if (lineNumbers) {
1568
+ numbers = (0, LineNumberMap_1.sequentialNumbers)(content, startIndex + 1);
1569
+ }
1520
1570
  try {
1521
1571
  const scrubber = new SemanticScrubber_1.SemanticScrubber();
1522
1572
  const { maskedPrompt } = scrubber.mask(content);
1573
+ // Masking must not change the line count, or every number after a masked secret would
1574
+ // be off. If it ever does, drop the gutter rather than print numbers that lie.
1575
+ if (numbers && maskedPrompt.split("\n").length !== content.split("\n").length) {
1576
+ numbers = null;
1577
+ }
1523
1578
  content = maskedPrompt;
1524
1579
  }
1525
1580
  catch (err) {
1526
1581
  (0, utils_1.logWarn)("read_workspace_file", "SemanticScrubber failed, returning raw content");
1527
1582
  }
1528
- (0, ReadWorkspaceCache_1.recordSent)(resolved, compact, dedup.hash);
1529
- return { content: [{ type: "text", text: content }] };
1583
+ if (numbers)
1584
+ content = (0, LineNumberMap_1.withLineNumbers)(content, numbers);
1585
+ (0, ReadWorkspaceCache_1.recordSent)(resolved, view, dedup.hash);
1586
+ return { content: [{ type: "text", text: rangeHeader + content }] };
1530
1587
  }
1531
1588
  catch (err) {
1532
1589
  (0, utils_1.logError)("read_workspace_file", err);
@@ -1578,13 +1635,35 @@ async function handleCreateWorkspaceFile(args) {
1578
1635
  return { content: [{ type: "text", text: `Error creating file: ${err.message}` }] };
1579
1636
  }
1580
1637
  }
1638
+ /**
1639
+ * `read_workspace_file` now returns a "123| code" gutter, which makes it easy to paste a block
1640
+ * back into a patch with the numbers still attached. That block matches nothing on disk, so the
1641
+ * patch fails for a reason that has nothing to do with the edit. Strip the gutter when *every*
1642
+ * non-empty line carries one — a uniform prefix is a gutter; a lone "12| " inside real code is
1643
+ * not, and must be left alone.
1644
+ */
1645
+ function stripLineNumberGutter(text) {
1646
+ const lines = text.split("\n");
1647
+ const nonEmpty = lines.filter((l) => l.trim().length > 0);
1648
+ if (nonEmpty.length === 0)
1649
+ return text;
1650
+ const GUTTER = /^\s*\d+\|\s?/;
1651
+ if (!nonEmpty.every((l) => GUTTER.test(l)))
1652
+ return text;
1653
+ return lines.map((l) => l.replace(GUTTER, "")).join("\n");
1654
+ }
1581
1655
  async function handleApplyWorkspacePatch(args) {
1582
1656
  const filePath = args?.filePath;
1583
- const searchContent = args?.searchContent;
1584
- const replaceContent = args?.replaceContent;
1585
- if (!filePath || !searchContent || replaceContent === undefined) {
1657
+ const rawSearch = args?.searchContent;
1658
+ const rawReplace = args?.replaceContent;
1659
+ if (!filePath || !rawSearch || rawReplace === undefined) {
1586
1660
  throw new Error("filePath, searchContent, and replaceContent are required");
1587
1661
  }
1662
+ const searchContent = stripLineNumberGutter(rawSearch);
1663
+ // Only strip the replacement's gutter when the search block had one too: that pairing means
1664
+ // the model was working from a numbered read. Stripping unconditionally would mangle a
1665
+ // replacement that legitimately contains "1| " (a table, a doc block).
1666
+ const replaceContent = searchContent !== rawSearch ? stripLineNumberGutter(rawReplace) : rawReplace;
1588
1667
  const workspaceRoot = process.cwd();
1589
1668
  try {
1590
1669
  const { resolved } = (0, utils_1.safeResolvePath)(workspaceRoot, filePath);
@@ -1624,10 +1703,19 @@ async function handleApplyWorkspacePatch(args) {
1624
1703
  };
1625
1704
  }
1626
1705
  const match = matchResult[0];
1627
- const contentLines = originalContent.split("\n");
1628
- const finalReplace = match.strategy === "exact" ? replaceContent : (0, PatchMatcher_1.reindentReplacement)(replaceContent, searchContent, contentLines[match.startLine]);
1629
- const updatedLines = [...contentLines.slice(0, match.startLine), ...finalReplace.split("\n"), ...contentLines.slice(match.endLine + 1)];
1630
- fs_1.default.writeFileSync(resolved, updatedLines.join("\n"), "utf8");
1706
+ let updatedContent;
1707
+ if (match.strategy === "exact" && match.charStart !== undefined && match.charEnd !== undefined) {
1708
+ // Splice by character offset the search block may be a mid-line fragment, and
1709
+ // a whole-line splice would discard everything else sharing that line.
1710
+ updatedContent = originalContent.slice(0, match.charStart) + replaceContent + originalContent.slice(match.charEnd);
1711
+ }
1712
+ else {
1713
+ const contentLines = originalContent.split("\n");
1714
+ const finalReplace = (0, PatchMatcher_1.reindentReplacement)(replaceContent, searchContent, contentLines[match.startLine]);
1715
+ const updatedLines = [...contentLines.slice(0, match.startLine), ...finalReplace.split("\n"), ...contentLines.slice(match.endLine + 1)];
1716
+ updatedContent = updatedLines.join("\n");
1717
+ }
1718
+ fs_1.default.writeFileSync(resolved, updatedContent, "utf8");
1631
1719
  const note = match.strategy === "exact" ? "" : ` (matched via ${match.strategy}, score ${match.score.toFixed(2)})`;
1632
1720
  return { content: [{ type: "text", text: `Success: Patch successfully applied to ${filePath}${note}` }] };
1633
1721
  }
@@ -1669,32 +1757,38 @@ async function handleRunWorkspaceCommand(args) {
1669
1757
  // stdio is overridden, which silently dropped the output of every tool that reports on
1670
1758
  // stderr (jest and tsc both do) on a successful run. It also gives us stdout, stderr and
1671
1759
  // the exit code through one code path instead of a throw-on-failure split.
1760
+ // 15s was below the runtime of the commands this tool exists for: a real `npm test` or
1761
+ // `tsc --noEmit` always tripped it, so the distillation pipeline never ran on the output
1762
+ // it was built for and the call was pure overhead before falling back to a plain shell.
1763
+ const DEFAULT_TIMEOUT_MS = 120000;
1764
+ const MAX_TIMEOUT_MS = 600000;
1765
+ const requested = typeof args?.timeoutMs === "number" && args.timeoutMs > 0 ? args.timeoutMs : DEFAULT_TIMEOUT_MS;
1766
+ const timeoutMs = Math.min(Math.floor(requested), MAX_TIMEOUT_MS);
1672
1767
  const result = (0, child_process_1.spawnSync)(command, {
1673
1768
  cwd: workspaceRoot,
1674
1769
  shell: true,
1675
1770
  encoding: "utf8",
1676
- timeout: 15000,
1771
+ timeout: timeoutMs,
1677
1772
  maxBuffer: 20 * 1024 * 1024,
1678
1773
  env: { ...process.env },
1679
1774
  });
1680
- if (result.error) {
1681
- const timedOut = result.error.code === "ETIMEDOUT";
1775
+ const timedOut = !!result.error && result.error.code === "ETIMEDOUT";
1776
+ if (result.error && !timedOut) {
1682
1777
  return {
1683
- content: [
1684
- {
1685
- type: "text",
1686
- text: timedOut
1687
- ? `Command timed out after 15s: ${command}`
1688
- : `Command could not be executed: ${result.error.message}`,
1689
- },
1690
- ],
1778
+ content: [{ type: "text", text: `Command could not be executed: ${result.error.message}` }],
1691
1779
  };
1692
1780
  }
1693
1781
  const stdout = result.stdout || "";
1694
1782
  const stderr = result.stderr || "";
1695
1783
  const combined = [stdout, stderr].filter((s) => s.trim().length > 0).join("\n");
1696
1784
  const status = result.status ?? 0;
1697
- const header = status === 0 ? "Command completed successfully." : `Command failed with exit code ${status}.`;
1785
+ // A timed-out run still produced output, and that partial output is normally where the
1786
+ // failure is. Discarding it forced the whole command to be re-run somewhere else.
1787
+ const header = timedOut
1788
+ ? `Command timed out after ${Math.round(timeoutMs / 1000)}s (killed): ${command}\nOutput produced before the kill is below — it may be incomplete. Re-run with a higher timeoutMs if it was still making progress.`
1789
+ : status === 0
1790
+ ? "Command completed successfully."
1791
+ : `Command failed with exit code ${status}.`;
1698
1792
  if (!combined.trim()) {
1699
1793
  return { content: [{ type: "text", text: `${header}\n\n(no output)` }] };
1700
1794
  }