@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.
- package/README.md +126 -176
- package/dist/cjs/mcp/prompts.d.ts +10 -1
- package/dist/cjs/mcp/prompts.d.ts.map +1 -1
- package/dist/cjs/mcp/prompts.js +25 -73
- package/dist/cjs/mcp/prompts.js.map +1 -1
- package/dist/cjs/mcp/tool-profiles.d.ts +10 -1
- package/dist/cjs/mcp/tool-profiles.d.ts.map +1 -1
- package/dist/cjs/mcp/tool-profiles.js +12 -3
- package/dist/cjs/mcp/tool-profiles.js.map +1 -1
- package/dist/cjs/mcp/tools.d.ts.map +1 -1
- package/dist/cjs/mcp/tools.js +122 -28
- package/dist/cjs/mcp/tools.js.map +1 -1
- package/dist/cjs/mcp/utils.d.ts.map +1 -1
- package/dist/cjs/mcp/utils.js +19 -6
- package/dist/cjs/mcp/utils.js.map +1 -1
- package/dist/cjs/security/SemanticScrubber.d.ts +2 -0
- package/dist/cjs/security/SemanticScrubber.d.ts.map +1 -1
- package/dist/cjs/security/SemanticScrubber.js +53 -13
- package/dist/cjs/security/SemanticScrubber.js.map +1 -1
- package/dist/cjs/utils/ContextSqueezer.d.ts.map +1 -1
- package/dist/cjs/utils/ContextSqueezer.js +55 -22
- package/dist/cjs/utils/ContextSqueezer.js.map +1 -1
- package/dist/cjs/utils/FileOutline.d.ts +22 -0
- package/dist/cjs/utils/FileOutline.d.ts.map +1 -0
- package/dist/cjs/utils/FileOutline.js +55 -0
- package/dist/cjs/utils/FileOutline.js.map +1 -0
- package/dist/cjs/utils/LineNumberMap.d.ts +29 -0
- package/dist/cjs/utils/LineNumberMap.d.ts.map +1 -0
- package/dist/cjs/utils/LineNumberMap.js +98 -0
- package/dist/cjs/utils/LineNumberMap.js.map +1 -0
- package/dist/cjs/utils/PatchMatcher.d.ts +2 -0
- package/dist/cjs/utils/PatchMatcher.d.ts.map +1 -1
- package/dist/cjs/utils/PatchMatcher.js +9 -1
- package/dist/cjs/utils/PatchMatcher.js.map +1 -1
- package/dist/cjs/utils/ReadWorkspaceCache.d.ts +16 -3
- package/dist/cjs/utils/ReadWorkspaceCache.d.ts.map +1 -1
- package/dist/cjs/utils/ReadWorkspaceCache.js +20 -8
- package/dist/cjs/utils/ReadWorkspaceCache.js.map +1 -1
- package/dist/esm/mcp/prompts.d.ts +10 -1
- package/dist/esm/mcp/prompts.d.ts.map +1 -1
- package/dist/esm/mcp/prompts.js +25 -73
- package/dist/esm/mcp/prompts.js.map +1 -1
- package/dist/esm/mcp/tool-profiles.d.ts +10 -1
- package/dist/esm/mcp/tool-profiles.d.ts.map +1 -1
- package/dist/esm/mcp/tool-profiles.js +12 -3
- package/dist/esm/mcp/tool-profiles.js.map +1 -1
- package/dist/esm/mcp/tools.d.ts.map +1 -1
- package/dist/esm/mcp/tools.js +122 -28
- package/dist/esm/mcp/tools.js.map +1 -1
- package/dist/esm/mcp/utils.d.ts.map +1 -1
- package/dist/esm/mcp/utils.js +19 -6
- package/dist/esm/mcp/utils.js.map +1 -1
- package/dist/esm/security/SemanticScrubber.d.ts +2 -0
- package/dist/esm/security/SemanticScrubber.d.ts.map +1 -1
- package/dist/esm/security/SemanticScrubber.js +53 -13
- package/dist/esm/security/SemanticScrubber.js.map +1 -1
- package/dist/esm/utils/ContextSqueezer.d.ts.map +1 -1
- package/dist/esm/utils/ContextSqueezer.js +55 -22
- package/dist/esm/utils/ContextSqueezer.js.map +1 -1
- package/dist/esm/utils/FileOutline.d.ts +22 -0
- package/dist/esm/utils/FileOutline.d.ts.map +1 -0
- package/dist/esm/utils/FileOutline.js +51 -0
- package/dist/esm/utils/FileOutline.js.map +1 -0
- package/dist/esm/utils/LineNumberMap.d.ts +29 -0
- package/dist/esm/utils/LineNumberMap.d.ts.map +1 -0
- package/dist/esm/utils/LineNumberMap.js +93 -0
- package/dist/esm/utils/LineNumberMap.js.map +1 -0
- package/dist/esm/utils/PatchMatcher.d.ts +2 -0
- package/dist/esm/utils/PatchMatcher.d.ts.map +1 -1
- package/dist/esm/utils/PatchMatcher.js +9 -1
- package/dist/esm/utils/PatchMatcher.js.map +1 -1
- package/dist/esm/utils/ReadWorkspaceCache.d.ts +16 -3
- package/dist/esm/utils/ReadWorkspaceCache.d.ts.map +1 -1
- package/dist/esm/utils/ReadWorkspaceCache.js +19 -8
- package/dist/esm/utils/ReadWorkspaceCache.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-profiles.js","sourceRoot":"","sources":["../../../src/mcp/tool-profiles.ts"],"names":[],"mappings":";;;;;;
|
|
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;
|
|
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"}
|
package/dist/cjs/mcp/tools.js
CHANGED
|
@@ -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.
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
1529
|
-
|
|
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
|
|
1584
|
-
const
|
|
1585
|
-
if (!filePath || !
|
|
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
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
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:
|
|
1771
|
+
timeout: timeoutMs,
|
|
1677
1772
|
maxBuffer: 20 * 1024 * 1024,
|
|
1678
1773
|
env: { ...process.env },
|
|
1679
1774
|
});
|
|
1680
|
-
|
|
1681
|
-
|
|
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
|
-
|
|
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
|
}
|