@wrongstack/core 0.267.0 → 0.269.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/dist/{agent-bridge-STJ3JwwK.d.ts → agent-bridge-PcHQl_UQ.d.ts} +1 -1
- package/dist/{agent-subagent-runner-CzPGP3jA.d.ts → agent-subagent-runner-SHJW7t8q.d.ts} +8 -8
- package/dist/{brain-Cdg77tVN.d.ts → brain-BYcK__Ym.d.ts} +1 -1
- package/dist/{compactor-iMZ84CXq.d.ts → compactor-C2RKEBtC.d.ts} +1 -1
- package/dist/{config-Du3pYYln.d.ts → config-C_ae2k86.d.ts} +79 -2
- package/dist/{context-dT5Ueund.d.ts → context-Dp87Bcaq.d.ts} +47 -1
- package/dist/coordination/index.d.ts +62 -160
- package/dist/coordination/index.js +566 -149
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +26 -25
- package/dist/defaults/index.js +366 -137
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +72 -16
- package/dist/execution/index.js +267 -55
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/extension/index.d.ts +7 -6
- package/dist/global-mailbox-Bvrz1P3f.d.ts +664 -0
- package/dist/{goal-preamble-SulMTowG.d.ts → goal-preamble-CA_4yiGQ.d.ts} +9 -9
- package/dist/{goal-store-CABDwdFE.d.ts → goal-store-DhuJoUNG.d.ts} +1 -1
- package/dist/hq/index.d.ts +204 -0
- package/dist/hq/index.js +1931 -0
- package/dist/hq/index.js.map +1 -0
- package/dist/{index-DtCVWel4.d.ts → index-CZQ6Pwbs.d.ts} +8 -8
- package/dist/{index-Bms0m4oy.d.ts → index-W4VJCzHa.d.ts} +5 -5
- package/dist/{index-IEuxQd-E.d.ts → index-whDfTANu.d.ts} +2 -2
- package/dist/index.d.ts +46 -42
- package/dist/index.js +3472 -1651
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/infrastructure/index.js +48 -21
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +10 -9
- package/dist/{pipeline-BfD2k1rT.d.ts → mailbox-types-Ct2hJq0P.d.ts} +1 -244
- package/dist/{mcp-servers-C2cBTxUR.d.ts → mcp-servers-DJdZiRcv.d.ts} +10 -4
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +4 -3
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-BqGZNJQ-.d.ts → models-registry-C3a-2-Yd.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-B8R43uPz.d.ts → multi-agent-coordinator-CJSpTe5O.d.ts} +1 -1
- package/dist/{null-fleet-bus-CnXa5oTH.d.ts → null-fleet-bus-QVshIsDx.d.ts} +6 -6
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-DdNnw9BQ.d.ts → parallel-eternal-engine-D9y5Pkcc.d.ts} +9 -15
- package/dist/{path-resolver-COIMLCQL.d.ts → path-resolver-CnQ8SIfh.d.ts} +4 -3
- package/dist/{permission-B75JAi3-.d.ts → permission-CvYQNUqZ.d.ts} +1 -1
- package/dist/{permission-policy-DlR9eJAM.d.ts → permission-policy-D5Ss8j4B.d.ts} +2 -3
- package/dist/pipeline-l_zzFRh3.d.ts +245 -0
- package/dist/{plan-templates-DSIKCXZN.d.ts → plan-templates-NtPgyeJA.d.ts} +6 -5
- package/dist/{provider-model-resolve-BNRsNuJx.d.ts → provider-model-resolve-d5poT5y0.d.ts} +3 -3
- package/dist/{provider-runner-CX7iIvox.d.ts → provider-runner-gkctlQV_.d.ts} +3 -3
- package/dist/{retry-policy-BilV1ujH.d.ts → retry-policy-CtFhfwa8.d.ts} +1 -1
- package/dist/sdd/index.d.ts +9 -8
- package/dist/sdd/index.js +33 -3
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-gkvEZZfE.d.ts → secret-vault-BLsVmTIK.d.ts} +1 -1
- package/dist/security/index.d.ts +5 -5
- package/dist/security/index.js +39 -29
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-Bc7eWtT3.d.ts → selector-CXl2_y9W.d.ts} +1 -1
- package/dist/{session-event-bridge-D-araDEz.d.ts → session-event-bridge-Ccud20CC.d.ts} +1 -1
- package/dist/{session-reader-D7Dapswh.d.ts → session-reader-ZeXQmsmE.d.ts} +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/storage/index.d.ts +16 -12
- package/dist/storage/index.js +273 -100
- package/dist/storage/index.js.map +1 -1
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js +166 -31
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +22 -21
- package/dist/types/index.js +178 -70
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +22 -3
- package/dist/utils/index.js +197 -25
- package/dist/utils/index.js.map +1 -1
- package/package.json +5 -1
- package/skills/chimera/SKILL.md +1 -1
- package/skills/typescript-strict/SKILL.md +3 -3
- package/skills/typescript-strict/SKILL.save.md +1 -1
package/dist/defaults/index.js
CHANGED
|
@@ -331,6 +331,9 @@ function formatCtx(ctx) {
|
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
+
// src/storage/session-store.ts
|
|
335
|
+
init_atomic_write();
|
|
336
|
+
|
|
334
337
|
// src/utils/expect-defined.ts
|
|
335
338
|
function expectDefined(value, label) {
|
|
336
339
|
if (value === null || value === void 0) {
|
|
@@ -341,9 +344,6 @@ function expectDefined(value, label) {
|
|
|
341
344
|
return value;
|
|
342
345
|
}
|
|
343
346
|
|
|
344
|
-
// src/storage/session-store.ts
|
|
345
|
-
init_atomic_write();
|
|
346
|
-
|
|
347
347
|
// src/utils/message-invariants.ts
|
|
348
348
|
function repairToolUseAdjacency(messages) {
|
|
349
349
|
const removedToolUses = [];
|
|
@@ -406,7 +406,7 @@ function hasToolResult(msg) {
|
|
|
406
406
|
}
|
|
407
407
|
function toolUseIds(msg) {
|
|
408
408
|
const ids = /* @__PURE__ */ new Set();
|
|
409
|
-
if (
|
|
409
|
+
if (msg?.role !== "assistant") return ids;
|
|
410
410
|
for (const block of contentBlocks(msg)) {
|
|
411
411
|
if (block.type === "tool_use") ids.add(block.id);
|
|
412
412
|
}
|
|
@@ -414,7 +414,7 @@ function toolUseIds(msg) {
|
|
|
414
414
|
}
|
|
415
415
|
function toolResultIds(msg) {
|
|
416
416
|
const ids = /* @__PURE__ */ new Set();
|
|
417
|
-
if (
|
|
417
|
+
if (msg?.role !== "user") return ids;
|
|
418
418
|
for (const block of contentBlocks(msg)) {
|
|
419
419
|
if (block.type === "tool_result") ids.add(block.tool_use_id);
|
|
420
420
|
}
|
|
@@ -1088,6 +1088,41 @@ function truncate(s, max) {
|
|
|
1088
1088
|
return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;
|
|
1089
1089
|
}
|
|
1090
1090
|
|
|
1091
|
+
// src/utils/tool-subject.ts
|
|
1092
|
+
var GLOB_METACHARACTERS = /[*?[\]]/g;
|
|
1093
|
+
function escapeGlobSubject(value) {
|
|
1094
|
+
return value.replace(GLOB_METACHARACTERS, (char) => `\\${char}`);
|
|
1095
|
+
}
|
|
1096
|
+
function normalizePathSubject(value) {
|
|
1097
|
+
return escapeGlobSubject(value.replace(/\\/g, "/"));
|
|
1098
|
+
}
|
|
1099
|
+
function isPathSubjectKey(subjectKey) {
|
|
1100
|
+
return subjectKey === "path" || subjectKey === "file" || subjectKey === "files";
|
|
1101
|
+
}
|
|
1102
|
+
function subjectForToolInput(toolName, input, subjectKey) {
|
|
1103
|
+
if (!input || typeof input !== "object") return void 0;
|
|
1104
|
+
const obj = input;
|
|
1105
|
+
if (subjectKey) {
|
|
1106
|
+
const value = obj[subjectKey];
|
|
1107
|
+
if (typeof value === "string") {
|
|
1108
|
+
return isPathSubjectKey(subjectKey) ? normalizePathSubject(value) : escapeGlobSubject(value);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
if (toolName === "bash" && typeof obj.command === "string") {
|
|
1112
|
+
return escapeGlobSubject(obj.command);
|
|
1113
|
+
}
|
|
1114
|
+
if (typeof obj.path === "string") {
|
|
1115
|
+
return normalizePathSubject(obj.path);
|
|
1116
|
+
}
|
|
1117
|
+
if (typeof obj.url === "string") {
|
|
1118
|
+
return escapeGlobSubject(obj.url);
|
|
1119
|
+
}
|
|
1120
|
+
if (typeof obj.name === "string") {
|
|
1121
|
+
return escapeGlobSubject(obj.name);
|
|
1122
|
+
}
|
|
1123
|
+
return void 0;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1091
1126
|
// src/utils/tool-wire-compact.ts
|
|
1092
1127
|
var TOOL_DESCRIPTION_MAX_CHARS = 640;
|
|
1093
1128
|
var SCHEMA_DESCRIPTION_MAX_CHARS = 180;
|
|
@@ -1171,8 +1206,19 @@ function calState(key) {
|
|
|
1171
1206
|
return state;
|
|
1172
1207
|
}
|
|
1173
1208
|
var MIN_SAMPLES_FOR_CALIBRATION = 3;
|
|
1209
|
+
var MODEL_FAMILY_RATIO = {
|
|
1210
|
+
// Anthropic: ~3.8-4.0 chars/token depending on model
|
|
1211
|
+
claude: 3.8,
|
|
1212
|
+
// OpenAI: ~4.0 chars/token
|
|
1213
|
+
"gpt-4": 4,
|
|
1214
|
+
"gpt-3.5": 4,
|
|
1215
|
+
// Google: ~3.5 chars/token
|
|
1216
|
+
gemini: 3.5,
|
|
1217
|
+
// DeepSeek: ~3.5 chars/token
|
|
1218
|
+
deepseek: 3.5
|
|
1219
|
+
};
|
|
1174
1220
|
var ESTIMATE_CACHE = /* @__PURE__ */ new Map();
|
|
1175
|
-
var ESTIMATE_CACHE_MAX_SIZE =
|
|
1221
|
+
var ESTIMATE_CACHE_MAX_SIZE = 5e4;
|
|
1176
1222
|
function getCachedEstimate(key, compute) {
|
|
1177
1223
|
const existing = ESTIMATE_CACHE.get(key);
|
|
1178
1224
|
if (existing !== void 0) return existing;
|
|
@@ -1300,8 +1346,24 @@ function estimateRequestTokensCalibrated(messages, systemPrompt, tools, calibrat
|
|
|
1300
1346
|
total: Math.round(result.total * safeRatio)
|
|
1301
1347
|
};
|
|
1302
1348
|
}
|
|
1349
|
+
const fallbackRatio = getModelFamilyRatio(calibrationKey);
|
|
1350
|
+
if (fallbackRatio !== null) {
|
|
1351
|
+
return {
|
|
1352
|
+
messages: Math.round(result.messages * fallbackRatio),
|
|
1353
|
+
systemPrompt: Math.round(result.systemPrompt * fallbackRatio),
|
|
1354
|
+
tools: Math.round(result.tools * fallbackRatio),
|
|
1355
|
+
total: Math.round(result.total * fallbackRatio)
|
|
1356
|
+
};
|
|
1357
|
+
}
|
|
1303
1358
|
return result;
|
|
1304
1359
|
}
|
|
1360
|
+
function getModelFamilyRatio(calibrationKey) {
|
|
1361
|
+
const lower = calibrationKey.toLowerCase();
|
|
1362
|
+
for (const [family, ratio] of Object.entries(MODEL_FAMILY_RATIO)) {
|
|
1363
|
+
if (lower.includes(family)) return ratio / 3.5;
|
|
1364
|
+
}
|
|
1365
|
+
return null;
|
|
1366
|
+
}
|
|
1305
1367
|
|
|
1306
1368
|
// src/utils/tool-output-serializer.ts
|
|
1307
1369
|
var DEFAULT_LIST_LIMIT = 500;
|
|
@@ -1312,6 +1374,7 @@ var GREP_MATCHES_PER_FILE = 3;
|
|
|
1312
1374
|
var DIFF_INLINE_LINE_LIMIT = 260;
|
|
1313
1375
|
var DIFF_HUNK_LIMIT = 8;
|
|
1314
1376
|
var DIFF_HUNK_CONTEXT = 14;
|
|
1377
|
+
var GREP_LINE_RE = /^(.+?):(\d+):(.*)$/;
|
|
1315
1378
|
function createToolOutputSerializer(opts = {}) {
|
|
1316
1379
|
const capBytes = opts.perIterationOutputCapBytes ?? 1e5;
|
|
1317
1380
|
function serialize(value, context = {}) {
|
|
@@ -1697,7 +1760,7 @@ ${renderStringList(passthrough, "", 50)}`);
|
|
|
1697
1760
|
return sections.join("\n");
|
|
1698
1761
|
}
|
|
1699
1762
|
function parseGrepContentLine(line) {
|
|
1700
|
-
const match =
|
|
1763
|
+
const match = GREP_LINE_RE.exec(line);
|
|
1701
1764
|
if (!match?.[1] || !match[2]) return void 0;
|
|
1702
1765
|
return { file: match[1], line: match[2], text: match[3] ?? "" };
|
|
1703
1766
|
}
|
|
@@ -1715,22 +1778,20 @@ function compactDiff(diff) {
|
|
|
1715
1778
|
const hunks = lines.filter((line) => line.startsWith("@@")).length;
|
|
1716
1779
|
const added = lines.filter((line) => line.startsWith("+") && !line.startsWith("+++")).length;
|
|
1717
1780
|
const removed = lines.filter((line) => line.startsWith("-") && !line.startsWith("---")).length;
|
|
1718
|
-
const
|
|
1781
|
+
const intervals = [];
|
|
1719
1782
|
let hunkCount = 0;
|
|
1720
1783
|
for (let i = 0; i < lines.length; i++) {
|
|
1721
1784
|
const line = lines[i] ?? "";
|
|
1722
1785
|
if (line.startsWith("diff --git") || line.startsWith("--- ") || line.startsWith("+++ ")) {
|
|
1723
|
-
|
|
1786
|
+
intervals.push([i, i]);
|
|
1724
1787
|
continue;
|
|
1725
1788
|
}
|
|
1726
1789
|
if (!line.startsWith("@@")) continue;
|
|
1727
1790
|
if (hunkCount >= DIFF_HUNK_LIMIT) continue;
|
|
1728
1791
|
hunkCount++;
|
|
1729
|
-
|
|
1730
|
-
selected.add(j);
|
|
1731
|
-
}
|
|
1792
|
+
intervals.push([i, Math.min(lines.length - 1, i + DIFF_HUNK_CONTEXT)]);
|
|
1732
1793
|
}
|
|
1733
|
-
if (
|
|
1794
|
+
if (intervals.length === 0) {
|
|
1734
1795
|
return joinSections([
|
|
1735
1796
|
renderHeader("diff_summary", {
|
|
1736
1797
|
files: fileCount,
|
|
@@ -1743,17 +1804,29 @@ function compactDiff(diff) {
|
|
|
1743
1804
|
`[serializer omitted ${Math.max(0, lines.length - DIFF_INLINE_LINE_LIMIT)} diff line(s)]`
|
|
1744
1805
|
]);
|
|
1745
1806
|
}
|
|
1807
|
+
const merged = [intervals[0]];
|
|
1808
|
+
for (let i = 1; i < intervals.length; i++) {
|
|
1809
|
+
const last = merged[merged.length - 1];
|
|
1810
|
+
const current = intervals[i];
|
|
1811
|
+
if (current[0] <= last[1] + 1) {
|
|
1812
|
+
last[1] = Math.max(last[1], current[1]);
|
|
1813
|
+
} else {
|
|
1814
|
+
merged.push(current);
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1746
1817
|
const excerpt = [];
|
|
1747
|
-
let
|
|
1748
|
-
for (const
|
|
1749
|
-
if (
|
|
1750
|
-
const omitted =
|
|
1818
|
+
let prevLine = -1;
|
|
1819
|
+
for (const [start, end] of merged) {
|
|
1820
|
+
if (start > prevLine + 1) {
|
|
1821
|
+
const omitted = prevLine === -1 ? start : start - prevLine - 1;
|
|
1751
1822
|
excerpt.push(`[serializer omitted ${omitted} diff line(s)]`);
|
|
1752
1823
|
}
|
|
1753
|
-
|
|
1754
|
-
|
|
1824
|
+
for (let j = start; j <= end; j++) {
|
|
1825
|
+
excerpt.push(lines[j] ?? "");
|
|
1826
|
+
}
|
|
1827
|
+
prevLine = end;
|
|
1755
1828
|
}
|
|
1756
|
-
const trailing = lines.length -
|
|
1829
|
+
const trailing = lines.length - prevLine - 1;
|
|
1757
1830
|
if (trailing > 0) excerpt.push(`[serializer omitted ${trailing} trailing diff line(s)]`);
|
|
1758
1831
|
return joinSections([
|
|
1759
1832
|
renderHeader("diff_summary", {
|
|
@@ -2027,6 +2100,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2027
2100
|
* processes. When the limit is reached, the oldest entry is evicted.
|
|
2028
2101
|
*/
|
|
2029
2102
|
_loadCache = /* @__PURE__ */ new Map();
|
|
2103
|
+
_indexCache = null;
|
|
2030
2104
|
static LOAD_CACHE_MAX_ENTRIES = 50;
|
|
2031
2105
|
constructor(opts) {
|
|
2032
2106
|
this.dir = opts.dir;
|
|
@@ -2188,16 +2262,13 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2188
2262
|
let errorMsg;
|
|
2189
2263
|
let cacheHit = false;
|
|
2190
2264
|
try {
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
const s = await fsp2.stat(file);
|
|
2194
|
-
stat6 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
2195
|
-
} catch (err) {
|
|
2196
|
-
throw err;
|
|
2197
|
-
}
|
|
2265
|
+
const s = await fsp2.stat(file);
|
|
2266
|
+
const stat6 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
2198
2267
|
const cached = this._loadCache.get(id);
|
|
2199
2268
|
if (cached && cached.mtimeMs === stat6.mtimeMs && cached.size === stat6.size) {
|
|
2200
2269
|
cacheHit = true;
|
|
2270
|
+
this._loadCache.delete(id);
|
|
2271
|
+
this._loadCache.set(id, cached);
|
|
2201
2272
|
return cached.data;
|
|
2202
2273
|
}
|
|
2203
2274
|
const raw = await fsp2.readFile(file, "utf8");
|
|
@@ -2283,6 +2354,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2283
2354
|
await ensureDir(this.dir);
|
|
2284
2355
|
const line = JSON.stringify(summary) + "\n";
|
|
2285
2356
|
await fsp2.appendFile(this.indexFile, line, "utf8");
|
|
2357
|
+
this._indexCache = null;
|
|
2286
2358
|
this.indexAppendCount++;
|
|
2287
2359
|
if (this.indexAppendCount >= _DefaultSessionStore.COMPACT_EVERY) {
|
|
2288
2360
|
await this.compactIndex();
|
|
@@ -2297,6 +2369,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2297
2369
|
await ensureDir(this.dir);
|
|
2298
2370
|
const line = JSON.stringify({ action: "delete", id }) + "\n";
|
|
2299
2371
|
await fsp2.appendFile(this.indexFile, line, "utf8");
|
|
2372
|
+
this._indexCache = null;
|
|
2300
2373
|
this.indexAppendCount++;
|
|
2301
2374
|
} catch {
|
|
2302
2375
|
}
|
|
@@ -2316,6 +2389,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2316
2389
|
const lines = entries.map((s) => JSON.stringify(s)).join("\n") + "\n";
|
|
2317
2390
|
await fsp2.writeFile(tmp, lines, "utf8");
|
|
2318
2391
|
await fsp2.rename(tmp, this.indexFile);
|
|
2392
|
+
this._indexCache = null;
|
|
2319
2393
|
} catch (err) {
|
|
2320
2394
|
outcome = "failure";
|
|
2321
2395
|
errorMsg = toErrorMessage(err);
|
|
@@ -2329,10 +2403,22 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2329
2403
|
* Returns empty array when the index doesn't exist or is corrupt.
|
|
2330
2404
|
*/
|
|
2331
2405
|
async readIndex() {
|
|
2406
|
+
let stat6;
|
|
2407
|
+
try {
|
|
2408
|
+
const s = await fsp2.stat(this.indexFile);
|
|
2409
|
+
stat6 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
2410
|
+
} catch {
|
|
2411
|
+
this._indexCache = null;
|
|
2412
|
+
return [];
|
|
2413
|
+
}
|
|
2414
|
+
if (this._indexCache !== null && this._indexCache.mtimeMs === stat6.mtimeMs && this._indexCache.size === stat6.size) {
|
|
2415
|
+
return [...this._indexCache.summaries];
|
|
2416
|
+
}
|
|
2332
2417
|
let raw;
|
|
2333
2418
|
try {
|
|
2334
2419
|
raw = await fsp2.readFile(this.indexFile, "utf8");
|
|
2335
2420
|
} catch {
|
|
2421
|
+
this._indexCache = null;
|
|
2336
2422
|
return [];
|
|
2337
2423
|
}
|
|
2338
2424
|
const deleted = /* @__PURE__ */ new Set();
|
|
@@ -2352,7 +2438,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2352
2438
|
} catch {
|
|
2353
2439
|
}
|
|
2354
2440
|
}
|
|
2355
|
-
|
|
2441
|
+
const summaries = Array.from(seen.values());
|
|
2442
|
+
this._indexCache = { ...stat6, summaries };
|
|
2443
|
+
return [...summaries];
|
|
2356
2444
|
}
|
|
2357
2445
|
/**
|
|
2358
2446
|
* Rebuild the index from disk by scanning all sessions and writing a
|
|
@@ -2366,6 +2454,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2366
2454
|
const lines = valid.map((s) => JSON.stringify(s)).join("\n") + "\n";
|
|
2367
2455
|
await fsp2.writeFile(tmp, lines, "utf8");
|
|
2368
2456
|
await fsp2.rename(tmp, this.indexFile);
|
|
2457
|
+
this._indexCache = null;
|
|
2369
2458
|
return valid.length;
|
|
2370
2459
|
}
|
|
2371
2460
|
/** Recursively collect session IDs from date-shard subdirectories.
|
|
@@ -3065,6 +3154,12 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
3065
3154
|
files
|
|
3066
3155
|
});
|
|
3067
3156
|
}
|
|
3157
|
+
/**
|
|
3158
|
+
* Truncate the session file to the checkpoint with the given promptIndex,
|
|
3159
|
+
* removing all events that follow it. Uses a single-pass byte-offset scan
|
|
3160
|
+
* so post-checkpoint content is never read or parsed — O(1) memory instead
|
|
3161
|
+
* of O(N) JSON.parse calls over the full file.
|
|
3162
|
+
*/
|
|
3068
3163
|
async truncateToCheckpoint(targetPromptIndex) {
|
|
3069
3164
|
if (!this.filePath) return 0;
|
|
3070
3165
|
if (this.flushTimer) {
|
|
@@ -3073,51 +3168,118 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
3073
3168
|
}
|
|
3074
3169
|
await this.flushBuffer();
|
|
3075
3170
|
await this.writeChain;
|
|
3076
|
-
const
|
|
3077
|
-
|
|
3078
|
-
|
|
3171
|
+
const CHUNK_SIZE = 65536;
|
|
3172
|
+
let fd;
|
|
3173
|
+
let fileOffset = 0;
|
|
3174
|
+
let lineStartOffset = 0;
|
|
3175
|
+
let checkpointByteOffset = -1;
|
|
3079
3176
|
let removedCount = 0;
|
|
3080
|
-
let
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3177
|
+
let targetCheckpointSeen = false;
|
|
3178
|
+
try {
|
|
3179
|
+
fd = await fsp2.open(this.filePath, "r", 384);
|
|
3180
|
+
while (true) {
|
|
3181
|
+
const buf = Buffer.alloc(CHUNK_SIZE);
|
|
3182
|
+
const { bytesRead } = await fd.read(buf, 0, CHUNK_SIZE, fileOffset);
|
|
3183
|
+
if (bytesRead === 0) break;
|
|
3184
|
+
let chunkPos = 0;
|
|
3185
|
+
while (chunkPos < bytesRead) {
|
|
3186
|
+
const idx = buf.indexOf("\n", chunkPos);
|
|
3187
|
+
if (idx === -1) {
|
|
3188
|
+
lineStartOffset = fileOffset + chunkPos;
|
|
3189
|
+
break;
|
|
3190
|
+
}
|
|
3191
|
+
if (checkpointByteOffset !== -1) {
|
|
3192
|
+
removedCount++;
|
|
3193
|
+
} else {
|
|
3194
|
+
const lineBytes = buf.subarray(chunkPos, idx);
|
|
3195
|
+
const line = new TextDecoder("utf-8", { fatal: false }).decode(lineBytes);
|
|
3196
|
+
if (line.trim()) {
|
|
3197
|
+
try {
|
|
3198
|
+
const event = JSON.parse(line);
|
|
3199
|
+
if (event.type === "checkpoint") {
|
|
3200
|
+
if (event.promptIndex === targetPromptIndex) {
|
|
3201
|
+
checkpointByteOffset = lineStartOffset;
|
|
3202
|
+
targetCheckpointSeen = true;
|
|
3203
|
+
} else if (event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
|
|
3204
|
+
checkpointByteOffset = lineStartOffset;
|
|
3205
|
+
}
|
|
3206
|
+
} else if (targetCheckpointSeen && event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
|
|
3207
|
+
removedCount++;
|
|
3208
|
+
} else if (targetCheckpointSeen && event.promptIndex === void 0) {
|
|
3209
|
+
removedCount++;
|
|
3210
|
+
} else if (!targetCheckpointSeen && event.promptIndex === void 0) {
|
|
3211
|
+
removedCount++;
|
|
3212
|
+
} else if (!targetCheckpointSeen && event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
|
|
3213
|
+
removedCount++;
|
|
3214
|
+
}
|
|
3215
|
+
} catch {
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
chunkPos = idx + 1;
|
|
3220
|
+
lineStartOffset = fileOffset + chunkPos;
|
|
3098
3221
|
}
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
} else if (event.promptIndex === void 0) {
|
|
3103
|
-
if (!afterTarget || targetCheckpointLine === -1) {
|
|
3104
|
-
kept.push(line);
|
|
3105
|
-
} else {
|
|
3106
|
-
removedCount++;
|
|
3222
|
+
fileOffset += bytesRead;
|
|
3223
|
+
if (chunkPos >= bytesRead) {
|
|
3224
|
+
lineStartOffset = fileOffset;
|
|
3107
3225
|
}
|
|
3108
|
-
} else {
|
|
3109
|
-
kept.push(line);
|
|
3110
3226
|
}
|
|
3227
|
+
} finally {
|
|
3228
|
+
await fd?.close();
|
|
3111
3229
|
}
|
|
3112
|
-
|
|
3230
|
+
if (checkpointByteOffset === -1) return 0;
|
|
3231
|
+
await this.writeChain;
|
|
3232
|
+
await this.handle.close();
|
|
3113
3233
|
const tmpPath = `${this.filePath}.rewind.tmp`;
|
|
3114
|
-
await fsp2.
|
|
3234
|
+
const src = await fsp2.open(this.filePath, "r", 384);
|
|
3115
3235
|
try {
|
|
3116
|
-
await
|
|
3236
|
+
const statResult = await src.stat();
|
|
3237
|
+
const totalSize = statResult.size;
|
|
3238
|
+
const prefixBytes = checkpointByteOffset;
|
|
3239
|
+
let newlineAfterCheckpoint = prefixBytes;
|
|
3240
|
+
if (prefixBytes < totalSize) {
|
|
3241
|
+
const probeBuf = Buffer.alloc(Math.min(CHUNK_SIZE, totalSize - prefixBytes));
|
|
3242
|
+
const { bytesRead: probeRead } = await src.read(probeBuf, 0, probeBuf.length, prefixBytes);
|
|
3243
|
+
if (probeRead > 0) {
|
|
3244
|
+
const nl = probeBuf.indexOf("\n");
|
|
3245
|
+
newlineAfterCheckpoint = nl !== -1 ? prefixBytes + nl + 1 : totalSize;
|
|
3246
|
+
}
|
|
3247
|
+
} else {
|
|
3248
|
+
newlineAfterCheckpoint = totalSize;
|
|
3249
|
+
}
|
|
3250
|
+
const writeFd = await fsp2.open(tmpPath, "w", 384);
|
|
3251
|
+
try {
|
|
3252
|
+
let copied = 0;
|
|
3253
|
+
let readOffset = 0;
|
|
3254
|
+
while (readOffset < newlineAfterCheckpoint) {
|
|
3255
|
+
const toCopy = Math.min(CHUNK_SIZE, newlineAfterCheckpoint - readOffset);
|
|
3256
|
+
const copyBuf = Buffer.alloc(toCopy);
|
|
3257
|
+
const { bytesRead: r } = await src.read(copyBuf, 0, toCopy, readOffset);
|
|
3258
|
+
if (r === 0) break;
|
|
3259
|
+
await writeFd.write(copyBuf, 0, r);
|
|
3260
|
+
readOffset += r;
|
|
3261
|
+
copied += r;
|
|
3262
|
+
}
|
|
3263
|
+
const raw = await fsp2.readFile(this.filePath);
|
|
3264
|
+
const tail = raw.subarray(newlineAfterCheckpoint).toString("utf8");
|
|
3265
|
+
for (const line of tail.split("\n")) {
|
|
3266
|
+
if (!line.trim()) continue;
|
|
3267
|
+
try {
|
|
3268
|
+
JSON.parse(line);
|
|
3269
|
+
} catch {
|
|
3270
|
+
await writeFd.write(`${line}
|
|
3271
|
+
`, void 0, "utf8");
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3274
|
+
} finally {
|
|
3275
|
+
await writeFd.close();
|
|
3276
|
+
}
|
|
3277
|
+
await src.close();
|
|
3117
3278
|
await fsp2.rename(tmpPath, this.filePath);
|
|
3118
3279
|
this.handle = await fsp2.open(this.filePath, "a", 384);
|
|
3119
3280
|
} catch (err) {
|
|
3120
3281
|
await fsp2.unlink(tmpPath).catch(() => void 0);
|
|
3282
|
+
this.handle = await fsp2.open(this.filePath, "a", 384).catch(() => this.handle);
|
|
3121
3283
|
throw err;
|
|
3122
3284
|
}
|
|
3123
3285
|
await this.append({
|
|
@@ -3517,6 +3679,7 @@ var MEMORY_TYPE_LABELS = {
|
|
|
3517
3679
|
init_atomic_write();
|
|
3518
3680
|
var TYPE_PRIORITY_RE = /^\[(\w+)\|(\w+)\]\s+/;
|
|
3519
3681
|
var TAG_RE = /#([\w-]+)/g;
|
|
3682
|
+
var MAX_MEMORY_CONSOLIDATE_BACKUPS = 5;
|
|
3520
3683
|
function formatMetadata(entry) {
|
|
3521
3684
|
const parts = [];
|
|
3522
3685
|
if (entry.type && entry.priority) {
|
|
@@ -3709,6 +3872,7 @@ ${line}`;
|
|
|
3709
3872
|
const backup = `${file}.bak.${Date.now()}`;
|
|
3710
3873
|
try {
|
|
3711
3874
|
await fsp2.copyFile(file, backup);
|
|
3875
|
+
await pruneConsolidateBackups(file);
|
|
3712
3876
|
} catch {
|
|
3713
3877
|
}
|
|
3714
3878
|
try {
|
|
@@ -3719,6 +3883,20 @@ ${line}`;
|
|
|
3719
3883
|
return removed;
|
|
3720
3884
|
}
|
|
3721
3885
|
};
|
|
3886
|
+
async function pruneConsolidateBackups(file) {
|
|
3887
|
+
const dir = path4.dirname(file);
|
|
3888
|
+
const base = path4.basename(file);
|
|
3889
|
+
const prefix = `${base}.bak.`;
|
|
3890
|
+
const backups = (await fsp2.readdir(dir)).filter((name) => name.startsWith(prefix)).sort().reverse();
|
|
3891
|
+
await Promise.all(
|
|
3892
|
+
backups.slice(MAX_MEMORY_CONSOLIDATE_BACKUPS).map(async (name) => {
|
|
3893
|
+
try {
|
|
3894
|
+
await fsp2.unlink(path4.join(dir, name));
|
|
3895
|
+
} catch {
|
|
3896
|
+
}
|
|
3897
|
+
})
|
|
3898
|
+
);
|
|
3899
|
+
}
|
|
3722
3900
|
function parseEntries(raw, scope = "project-memory") {
|
|
3723
3901
|
const entries = [];
|
|
3724
3902
|
for (const line of raw.split("\n")) {
|
|
@@ -4898,15 +5076,19 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
4898
5076
|
plugins: true,
|
|
4899
5077
|
memory: true,
|
|
4900
5078
|
modelsRegistry: true,
|
|
4901
|
-
skills: true
|
|
5079
|
+
skills: true,
|
|
5080
|
+
tokenSavingMode: "off",
|
|
5081
|
+
allowOutsideProjectRoot: true
|
|
4902
5082
|
},
|
|
5083
|
+
mcpServers: {},
|
|
4903
5084
|
indexing: {
|
|
4904
5085
|
onSessionStart: true,
|
|
4905
5086
|
onEdit: true,
|
|
4906
5087
|
watchExternal: true,
|
|
4907
5088
|
debounceMs: 400
|
|
4908
5089
|
},
|
|
4909
|
-
session: { ...DEFAULT_SESSION_LOGGING_CONFIG }
|
|
5090
|
+
session: { ...DEFAULT_SESSION_LOGGING_CONFIG },
|
|
5091
|
+
autonomy: { autoProceedDelayMs: DEFAULT_AUTONOMY_CONFIG.autoProceedDelayMs }
|
|
4910
5092
|
};
|
|
4911
5093
|
function envBool(v) {
|
|
4912
5094
|
return !/^(0|false|no|off)$/i.test(v.trim());
|
|
@@ -5913,7 +6095,7 @@ function createSessionEventBridge(writer, level = "standard", options = {}) {
|
|
|
5913
6095
|
if (!shouldSample(event)) return;
|
|
5914
6096
|
try {
|
|
5915
6097
|
await target.append(event);
|
|
5916
|
-
} catch (
|
|
6098
|
+
} catch (_err) {
|
|
5917
6099
|
}
|
|
5918
6100
|
},
|
|
5919
6101
|
async appendBatch(events) {
|
|
@@ -6991,7 +7173,7 @@ var DefaultPermissionPolicy = class {
|
|
|
6991
7173
|
if (!this.loaded) await this.reload();
|
|
6992
7174
|
const namespaceEntry = this.findNamespaceEntry(tool.name);
|
|
6993
7175
|
const entry = this.policy[tool.name] ?? namespaceEntry;
|
|
6994
|
-
const subject =
|
|
7176
|
+
const subject = subjectForToolInput(tool.name, input, tool.subjectKey);
|
|
6995
7177
|
const cacheKey = `${tool.name}::${subject ?? tool.name}`;
|
|
6996
7178
|
if (tool.name !== "write") {
|
|
6997
7179
|
const cached = this._evalCache.get(cacheKey);
|
|
@@ -7173,32 +7355,6 @@ var DefaultPermissionPolicy = class {
|
|
|
7173
7355
|
this.sessionAllowed.set(`${rule.tool}::${rule.pattern}`, true);
|
|
7174
7356
|
this._evalCache.clear();
|
|
7175
7357
|
}
|
|
7176
|
-
subjectFor(toolName, input, subjectKey) {
|
|
7177
|
-
if (!input || typeof input !== "object") return void 0;
|
|
7178
|
-
const obj = input;
|
|
7179
|
-
const globChars = /[*?[\]]/g;
|
|
7180
|
-
const escapeGlob = (s) => s.replace(globChars, (c) => `\\${c}`);
|
|
7181
|
-
const normalizePath = (s) => escapeGlob(s.replace(/\\/g, "/"));
|
|
7182
|
-
if (subjectKey) {
|
|
7183
|
-
const v = obj[subjectKey];
|
|
7184
|
-
if (typeof v === "string") {
|
|
7185
|
-
return subjectKey === "path" || subjectKey === "file" || subjectKey === "files" ? normalizePath(v) : escapeGlob(v);
|
|
7186
|
-
}
|
|
7187
|
-
}
|
|
7188
|
-
if (toolName === "bash" && typeof obj.command === "string") {
|
|
7189
|
-
return escapeGlob(obj.command);
|
|
7190
|
-
}
|
|
7191
|
-
if (typeof obj.path === "string") {
|
|
7192
|
-
return normalizePath(obj.path);
|
|
7193
|
-
}
|
|
7194
|
-
if (typeof obj.url === "string") {
|
|
7195
|
-
return escapeGlob(obj.url);
|
|
7196
|
-
}
|
|
7197
|
-
if (typeof obj.name === "string") {
|
|
7198
|
-
return escapeGlob(obj.name);
|
|
7199
|
-
}
|
|
7200
|
-
return void 0;
|
|
7201
|
-
}
|
|
7202
7358
|
findNamespaceEntry(toolName) {
|
|
7203
7359
|
for (const { pattern, value } of this.wildcardEntries) {
|
|
7204
7360
|
if (matchGlob(pattern, toolName)) return value;
|
|
@@ -7221,12 +7377,13 @@ var AutoApprovePermissionPolicy = class _AutoApprovePermissionPolicy {
|
|
|
7221
7377
|
const caps = tool.capabilities ?? [];
|
|
7222
7378
|
const hasAllowedCap = caps.some((c) => this.allowedCapabilities.includes(c));
|
|
7223
7379
|
const isMcp = _AutoApprovePermissionPolicy.isMcpTool(tool.name);
|
|
7380
|
+
const mcpProxyAllowed = this.allowedCapabilities.includes(ToolCapabilities.MCP_PROXY);
|
|
7224
7381
|
const dangerousNotAllowed = getDangerousCapabilities(tool).filter(
|
|
7225
7382
|
(c) => !this.allowedCapabilities.includes(c)
|
|
7226
7383
|
);
|
|
7227
|
-
const blocked = tool.permission === "deny" || isMcp || !hasAllowedCap || dangerousNotAllowed.length > 0;
|
|
7384
|
+
const blocked = tool.permission === "deny" || isMcp && !mcpProxyAllowed || !hasAllowedCap || dangerousNotAllowed.length > 0;
|
|
7228
7385
|
if (blocked) {
|
|
7229
|
-
const reason = isMcp ? `MCP tool ${tool.name} is not auto-approved for subagents \u2014 ask the leader to allow
|
|
7386
|
+
const reason = isMcp && !mcpProxyAllowed ? `MCP tool ${tool.name} is not auto-approved for subagents \u2014 ask the leader to allow mcp.proxy explicitly` : tool.permission === "deny" ? "tool default deny" : dangerousNotAllowed.length > 0 ? `tool requires un-granted dangerous capability (needs: ${dangerousNotAllowed.join(", ")}, allowed: ${this.allowedCapabilities.join(", ")})` : `tool lacks allowed capability (has: ${caps.join(", ") || "none"}, allowed: ${this.allowedCapabilities.join(", ")})`;
|
|
7230
7387
|
return {
|
|
7231
7388
|
permission: "deny",
|
|
7232
7389
|
source: "subagent_guard",
|
|
@@ -9566,7 +9723,7 @@ ${errorDetails}`,
|
|
|
9566
9723
|
return { result, tool, durationMs: Date.now() - start };
|
|
9567
9724
|
}
|
|
9568
9725
|
} else {
|
|
9569
|
-
const suggestedPattern =
|
|
9726
|
+
const suggestedPattern = subjectForToolInput(tool.name, use.input, tool.subjectKey) ?? tool.name;
|
|
9570
9727
|
const pending = {
|
|
9571
9728
|
type: "tool_confirm_pending",
|
|
9572
9729
|
toolUseId: use.id,
|
|
@@ -9612,6 +9769,7 @@ ${post.additionalContext}`;
|
|
|
9612
9769
|
} catch (err) {
|
|
9613
9770
|
const msg = toErrorMessage(err);
|
|
9614
9771
|
const scrubbed = this.opts.secretScrubber.scrub(msg);
|
|
9772
|
+
const { category, retryable, detail } = classifyToolError(err);
|
|
9615
9773
|
this.opts.renderer?.writeToolResult(tool.name, scrubbed, true);
|
|
9616
9774
|
const result = {
|
|
9617
9775
|
type: "tool_result",
|
|
@@ -9622,6 +9780,9 @@ ${post.additionalContext}`;
|
|
|
9622
9780
|
budget = this.budgetForString(result.content, budget);
|
|
9623
9781
|
if (err instanceof Error) span?.recordError(err);
|
|
9624
9782
|
span?.setAttribute("tool.is_error", true);
|
|
9783
|
+
span?.setAttribute("tool.error_category", category);
|
|
9784
|
+
span?.setAttribute("tool.error_retryable", retryable);
|
|
9785
|
+
if (detail) span?.setAttribute("tool.error_detail", detail);
|
|
9625
9786
|
return { result, tool, durationMs: Date.now() - start };
|
|
9626
9787
|
} finally {
|
|
9627
9788
|
span?.end();
|
|
@@ -9633,6 +9794,9 @@ ${post.additionalContext}`;
|
|
|
9633
9794
|
} catch (err) {
|
|
9634
9795
|
const msg = toErrorMessage(err);
|
|
9635
9796
|
const scrubbed = this.opts.secretScrubber.scrub(msg);
|
|
9797
|
+
const { category, retryable, detail } = classifyToolError(err);
|
|
9798
|
+
const tool = this.registry.get(use.name);
|
|
9799
|
+
this.opts.renderer?.writeToolResult(tool?.name ?? use.name, scrubbed, true);
|
|
9636
9800
|
const result = {
|
|
9637
9801
|
type: "tool_result",
|
|
9638
9802
|
tool_use_id: use.id,
|
|
@@ -9640,7 +9804,7 @@ ${post.additionalContext}`;
|
|
|
9640
9804
|
is_error: true
|
|
9641
9805
|
};
|
|
9642
9806
|
budget = this.budgetForString(result.content, budget);
|
|
9643
|
-
return { result, tool
|
|
9807
|
+
return { result, tool, durationMs: 0 };
|
|
9644
9808
|
}
|
|
9645
9809
|
};
|
|
9646
9810
|
if (strategy === "sequential") {
|
|
@@ -9845,38 +10009,6 @@ ${excerpt}`;
|
|
|
9845
10009
|
budgetForString(content, budget) {
|
|
9846
10010
|
return Math.max(0, budget - Buffer.byteLength(content, "utf8"));
|
|
9847
10011
|
}
|
|
9848
|
-
/**
|
|
9849
|
-
* Compute the suggestedPattern string for a tool+input pair.
|
|
9850
|
-
* Matches the logic in DefaultPermissionPolicy so the TUI shows the
|
|
9851
|
-
* same subject that the trust file would use.
|
|
9852
|
-
*/
|
|
9853
|
-
subjectFor(toolName, input, subjectKey) {
|
|
9854
|
-
if (!input || typeof input !== "object") return void 0;
|
|
9855
|
-
const obj = input;
|
|
9856
|
-
const globChars = /[*?[\]]/g;
|
|
9857
|
-
const escapeGlob = (s) => s.replace(globChars, (c) => `\\${c}`);
|
|
9858
|
-
const normalizePath = (s) => escapeGlob(s.replace(/\\/g, "/"));
|
|
9859
|
-
if (subjectKey) {
|
|
9860
|
-
const v = obj[subjectKey];
|
|
9861
|
-
if (typeof v === "string") {
|
|
9862
|
-
const isPathKey = subjectKey === "path" || subjectKey === "file" || subjectKey === "files";
|
|
9863
|
-
return isPathKey ? normalizePath(v) : escapeGlob(v);
|
|
9864
|
-
}
|
|
9865
|
-
}
|
|
9866
|
-
if (toolName === "bash" && typeof obj.command === "string") {
|
|
9867
|
-
return escapeGlob(obj.command);
|
|
9868
|
-
}
|
|
9869
|
-
if (typeof obj.path === "string") {
|
|
9870
|
-
return normalizePath(obj.path);
|
|
9871
|
-
}
|
|
9872
|
-
if (typeof obj.url === "string") {
|
|
9873
|
-
return escapeGlob(obj.url);
|
|
9874
|
-
}
|
|
9875
|
-
if (typeof obj.name === "string") {
|
|
9876
|
-
return escapeGlob(obj.name);
|
|
9877
|
-
}
|
|
9878
|
-
return void 0;
|
|
9879
|
-
}
|
|
9880
10012
|
};
|
|
9881
10013
|
function clampTimeoutMs(timeoutMs, maxTimeoutMs) {
|
|
9882
10014
|
const fallback = 3e5;
|
|
@@ -9904,6 +10036,58 @@ function extractMalformedRaw(input) {
|
|
|
9904
10036
|
}
|
|
9905
10037
|
}
|
|
9906
10038
|
var TOOL_OUTPUT_ARTIFACT_THRESHOLD_BYTES = 64 * 1024;
|
|
10039
|
+
function classifyToolError(err) {
|
|
10040
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
10041
|
+
return { category: "fatal" /* FATAL */, retryable: false, detail: "aborted" };
|
|
10042
|
+
}
|
|
10043
|
+
if (err instanceof Error && "code" in err) {
|
|
10044
|
+
const code = err.code;
|
|
10045
|
+
switch (code) {
|
|
10046
|
+
case "ETIMEDOUT":
|
|
10047
|
+
case "ECONNRESET":
|
|
10048
|
+
case "ECONNREFUSED":
|
|
10049
|
+
case "ENETUNREACH":
|
|
10050
|
+
case "EHOSTUNREACH":
|
|
10051
|
+
return { category: "transient" /* TRANSIENT */, retryable: true, detail: code };
|
|
10052
|
+
case "ENOENT":
|
|
10053
|
+
case "ENOTDIR":
|
|
10054
|
+
return { category: "not_found" /* NOT_FOUND */, retryable: false, detail: code };
|
|
10055
|
+
case "EACCES":
|
|
10056
|
+
case "EPERM":
|
|
10057
|
+
return { category: "permission" /* PERMISSION */, retryable: false, detail: code };
|
|
10058
|
+
case "EBUSY":
|
|
10059
|
+
case "EMFILE":
|
|
10060
|
+
case "ENFILE":
|
|
10061
|
+
return { category: "transient" /* TRANSIENT */, retryable: true, detail: code };
|
|
10062
|
+
}
|
|
10063
|
+
}
|
|
10064
|
+
if (err instanceof Error && "response" in err) {
|
|
10065
|
+
const response = err.response;
|
|
10066
|
+
const status = response?.status;
|
|
10067
|
+
if (status !== void 0) {
|
|
10068
|
+
if (status === 429 || status === 503 || status === 502 || status === 504) {
|
|
10069
|
+
return { category: "transient" /* TRANSIENT */, retryable: true, detail: `HTTP ${status}` };
|
|
10070
|
+
}
|
|
10071
|
+
if (status === 404 || status === 410) {
|
|
10072
|
+
return { category: "not_found" /* NOT_FOUND */, retryable: false, detail: `HTTP ${status}` };
|
|
10073
|
+
}
|
|
10074
|
+
if (status === 401 || status === 403) {
|
|
10075
|
+
return { category: "permission" /* PERMISSION */, retryable: false, detail: `HTTP ${status}` };
|
|
10076
|
+
}
|
|
10077
|
+
if (status === 400) {
|
|
10078
|
+
return { category: "validation" /* VALIDATION */, retryable: false, detail: `HTTP ${status}` };
|
|
10079
|
+
}
|
|
10080
|
+
}
|
|
10081
|
+
}
|
|
10082
|
+
if (err instanceof Error && err.message.includes("validation")) {
|
|
10083
|
+
return { category: "validation" /* VALIDATION */, retryable: false, detail: "validation" };
|
|
10084
|
+
}
|
|
10085
|
+
return {
|
|
10086
|
+
category: "fatal" /* FATAL */,
|
|
10087
|
+
retryable: false,
|
|
10088
|
+
detail: err instanceof Error ? err.message.slice(0, 100) : String(err).slice(0, 100)
|
|
10089
|
+
};
|
|
10090
|
+
}
|
|
9907
10091
|
async function maybePersistLargeToolOutput(toolName, content, budget) {
|
|
9908
10092
|
const bytes = Buffer.byteLength(content, "utf8");
|
|
9909
10093
|
if (bytes <= Math.min(TOOL_OUTPUT_ARTIFACT_THRESHOLD_BYTES, Math.max(0, budget))) {
|
|
@@ -10846,8 +11030,8 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
10846
11030
|
await saveGoal(this.goalPath, abandoned, this.opts.events);
|
|
10847
11031
|
}
|
|
10848
11032
|
try {
|
|
10849
|
-
const { unlink:
|
|
10850
|
-
await
|
|
11033
|
+
const { unlink: unlink11 } = await import('fs/promises');
|
|
11034
|
+
await unlink11(this.goalPath);
|
|
10851
11035
|
} catch {
|
|
10852
11036
|
}
|
|
10853
11037
|
this.opts.onEternalStop?.();
|
|
@@ -11230,7 +11414,7 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
11230
11414
|
*/
|
|
11231
11415
|
_busRequestDecision(entry) {
|
|
11232
11416
|
const bus = this._events;
|
|
11233
|
-
if (!bus
|
|
11417
|
+
if (!bus?.hasListenerFor("budget.threshold_reached")) {
|
|
11234
11418
|
return Promise.resolve("stop");
|
|
11235
11419
|
}
|
|
11236
11420
|
return new Promise((resolve6) => {
|
|
@@ -13702,7 +13886,27 @@ Working rules:
|
|
|
13702
13886
|
id: "devops",
|
|
13703
13887
|
name: "DevOps",
|
|
13704
13888
|
role: "devops",
|
|
13705
|
-
tools: [
|
|
13889
|
+
tools: [
|
|
13890
|
+
...TOOLS.build,
|
|
13891
|
+
"mcp__ssh__ssh_list_servers",
|
|
13892
|
+
"mcp__ssh__ssh_connection_status",
|
|
13893
|
+
"mcp__ssh__ssh_execute",
|
|
13894
|
+
"mcp__ssh__ssh_execute_sudo",
|
|
13895
|
+
"mcp__ssh__ssh_upload",
|
|
13896
|
+
"mcp__ssh__ssh_download",
|
|
13897
|
+
"mcp__ssh__ssh_sync",
|
|
13898
|
+
"mcp__ssh__ssh_deploy",
|
|
13899
|
+
"mcp__ssh__ssh_health_check",
|
|
13900
|
+
"mcp__ssh__ssh_service_status",
|
|
13901
|
+
"mcp__ssh__ssh_process_manager",
|
|
13902
|
+
"mcp__ssh__ssh_tunnel",
|
|
13903
|
+
"mcp__ssh__ssh_backup_create",
|
|
13904
|
+
"mcp__ssh__ssh_backup_list",
|
|
13905
|
+
"mcp__ssh__ssh_backup_restore",
|
|
13906
|
+
"mcp__ssh__ssh_db_list",
|
|
13907
|
+
"mcp__ssh__ssh_db_query",
|
|
13908
|
+
"mcp__ssh__ssh_profile"
|
|
13909
|
+
],
|
|
13706
13910
|
prompt: `You are the DevOps agent. Your job is CI/CD, containerization, and
|
|
13707
13911
|
deployment configuration: make builds reproducible and deploys safe.
|
|
13708
13912
|
|
|
@@ -13711,6 +13915,7 @@ Scope:
|
|
|
13711
13915
|
- Write Dockerfiles/compose and optimize image size and layer caching
|
|
13712
13916
|
- Configure deployment (env, secrets handling, health checks, rollback)
|
|
13713
13917
|
- Diagnose flaky/broken pipelines
|
|
13918
|
+
- Use optional SSH MCP tools for remote hosts when the 'ssh' MCP server is enabled: list servers, run health checks, inspect services, transfer/deploy files, and open tunnels
|
|
13714
13919
|
|
|
13715
13920
|
Input format you accept:
|
|
13716
13921
|
{ "task": "ci | container | deploy | fix-pipeline", "platform": "github-actions | gitlab | docker | k8s", "target": "<what>" }
|
|
@@ -13725,7 +13930,8 @@ Working rules:
|
|
|
13725
13930
|
- Never hardcode secrets in config; reference the secret store
|
|
13726
13931
|
- Pin versions for reproducible builds; avoid floating :latest
|
|
13727
13932
|
- Every deploy path needs a rollback and a health check
|
|
13728
|
-
- Treat CI/CD changes as high-risk \u2014 explain blast radius before applying
|
|
13933
|
+
- Treat CI/CD changes as high-risk \u2014 explain blast radius before applying
|
|
13934
|
+
- For remote SSH work, start with ssh_list_servers / ssh_connection_status, prefer read-only checks first, and do not run destructive commands without explicit user approval`
|
|
13729
13935
|
},
|
|
13730
13936
|
budget: MEDIUM_BUDGET,
|
|
13731
13937
|
capability: {
|
|
@@ -13742,6 +13948,13 @@ Working rules:
|
|
|
13742
13948
|
"kubernetes",
|
|
13743
13949
|
"k8s",
|
|
13744
13950
|
"deploy",
|
|
13951
|
+
"ssh",
|
|
13952
|
+
"remote ssh",
|
|
13953
|
+
"remote server",
|
|
13954
|
+
"sftp",
|
|
13955
|
+
"tunnel",
|
|
13956
|
+
"bastion",
|
|
13957
|
+
"jump host",
|
|
13745
13958
|
"github actions",
|
|
13746
13959
|
"container"
|
|
13747
13960
|
]
|
|
@@ -15513,6 +15726,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
15513
15726
|
subagentId: result.subagentId,
|
|
15514
15727
|
taskId: result.taskId,
|
|
15515
15728
|
status: result.status,
|
|
15729
|
+
result: result.result,
|
|
15516
15730
|
iterations: result.iterations,
|
|
15517
15731
|
toolCalls: result.toolCalls,
|
|
15518
15732
|
durationMs: result.durationMs
|
|
@@ -19705,10 +19919,11 @@ var DefaultModelsRegistry = class {
|
|
|
19705
19919
|
capabilities: {
|
|
19706
19920
|
tools: model.tool_call ?? false,
|
|
19707
19921
|
vision: Boolean(model.modalities?.input?.includes("image")),
|
|
19708
|
-
reasoning: model.reasoning ??
|
|
19922
|
+
reasoning: model.reasoning ?? model.reasoningConfig !== void 0,
|
|
19709
19923
|
maxContext: model.limit?.context ?? 0,
|
|
19710
19924
|
maxOutput: model.limit?.output,
|
|
19711
|
-
knowledge: model.knowledge
|
|
19925
|
+
knowledge: model.knowledge,
|
|
19926
|
+
reasoningConfig: model.reasoningConfig
|
|
19712
19927
|
},
|
|
19713
19928
|
cost: model.cost
|
|
19714
19929
|
};
|
|
@@ -24025,6 +24240,19 @@ var miniMaxVisionServer = () => ({
|
|
|
24025
24240
|
allowedTools: ["understand_image"],
|
|
24026
24241
|
permission: "auto"
|
|
24027
24242
|
});
|
|
24243
|
+
var sshManagerServer = () => ({
|
|
24244
|
+
name: "ssh",
|
|
24245
|
+
description: "Remote SSH management \u2014 execute commands, transfer files, tunnels, health checks (mcp-ssh-manager)",
|
|
24246
|
+
transport: "stdio",
|
|
24247
|
+
command: "npx",
|
|
24248
|
+
args: ["-y", "mcp-ssh-manager"],
|
|
24249
|
+
env: {
|
|
24250
|
+
MCP_SSH_COMPACT_JSON: "true",
|
|
24251
|
+
MCP_SSH_DEFAULT_TIMEOUT: "120000"
|
|
24252
|
+
},
|
|
24253
|
+
permission: "confirm",
|
|
24254
|
+
requestTimeoutMs: 18e4
|
|
24255
|
+
});
|
|
24028
24256
|
var allServers = () => ({
|
|
24029
24257
|
filesystem: { ...filesystemServer(), enabled: false },
|
|
24030
24258
|
github: { ...githubServer(), enabled: false },
|
|
@@ -24038,9 +24266,10 @@ var allServers = () => ({
|
|
|
24038
24266
|
sentinel: { ...sentinelServer(), enabled: false },
|
|
24039
24267
|
"zai-vision": { ...zaiVisionServer(), enabled: false },
|
|
24040
24268
|
"minimax-vision": { ...miniMaxVisionServer(), enabled: false },
|
|
24041
|
-
playwright: { ...playwrightServer(), enabled: false }
|
|
24269
|
+
playwright: { ...playwrightServer(), enabled: false },
|
|
24270
|
+
ssh: { ...sshManagerServer(), enabled: false }
|
|
24042
24271
|
});
|
|
24043
24272
|
|
|
24044
|
-
export { AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, ConfigMigrationError, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPermissionPolicy, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionStore, DefaultSkillLoader, DefaultTaskStore, Director, DirectorStateCheckpoint, DoneConditionChecker, EternalAutonomyEngine, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FleetBus, FleetSpawnBudgetError, FleetUsageAggregator, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, IntelligentCompactor, LLMSelector, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, SddParallelRun, SddTaskDecomposer, SelectiveCompactor, SessionAnalyzer, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, ToolExecutor, addPlanItem, allServers, analyzeCriticalPath, applyRosterBudget, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, classifyFamily, clearPlan, composeDirectorPrompt, composeSubagentPrompt, context7Server, contextManagerTool, createAutoExecutor, createContextManagerTool, createDelegateTool, createMessage, createSessionEventBridge, createStrategyCompactor, decryptConfigSecrets, deriveTodosFromPlanItem, describeCatalogModel, dispatchAgent, emptyPlan, encryptConfigSecrets, everArtServer, filesystemServer, formatPlan, formatPlanTemplates, getAgentDefinition, getPlanTemplate, getTemplate, githubServer, googleMapsServer, listPlanTemplates, listTemplates, loadDirectorState, loadPlan, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeRollUpTool, makeSpawnTool, makeTerminateTool, migratePlaintextSecrets, miniMaxVisionServer, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, resolveAuditLevel, resolveProviderModelList, resolveSessionLoggingConfig, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, savePlan, saveTodosCheckpoint, scoreAgents, sentinelServer, setPlanItemStatus, slackServer, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, templateToMarkdown, wireMetricsToEvents, zaiVisionServer };
|
|
24273
|
+
export { AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, ConfigMigrationError, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPermissionPolicy, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionStore, DefaultSkillLoader, DefaultTaskStore, Director, DirectorStateCheckpoint, DoneConditionChecker, EternalAutonomyEngine, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FleetBus, FleetSpawnBudgetError, FleetUsageAggregator, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, IntelligentCompactor, LLMSelector, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, SddParallelRun, SddTaskDecomposer, SelectiveCompactor, SessionAnalyzer, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, ToolExecutor, addPlanItem, allServers, analyzeCriticalPath, applyRosterBudget, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, classifyFamily, clearPlan, composeDirectorPrompt, composeSubagentPrompt, context7Server, contextManagerTool, createAutoExecutor, createContextManagerTool, createDelegateTool, createMessage, createSessionEventBridge, createStrategyCompactor, decryptConfigSecrets, deriveTodosFromPlanItem, describeCatalogModel, dispatchAgent, emptyPlan, encryptConfigSecrets, everArtServer, filesystemServer, formatPlan, formatPlanTemplates, getAgentDefinition, getPlanTemplate, getTemplate, githubServer, googleMapsServer, listPlanTemplates, listTemplates, loadDirectorState, loadPlan, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeRollUpTool, makeSpawnTool, makeTerminateTool, migratePlaintextSecrets, miniMaxVisionServer, playwrightServer, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, resolveAuditLevel, resolveProviderModelList, resolveSessionLoggingConfig, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, savePlan, saveTodosCheckpoint, scoreAgents, sentinelServer, setPlanItemStatus, slackServer, sshManagerServer, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, templateToMarkdown, wireMetricsToEvents, zaiVisionServer };
|
|
24045
24274
|
//# sourceMappingURL=index.js.map
|
|
24046
24275
|
//# sourceMappingURL=index.js.map
|