@wrongstack/core 0.89.1 → 0.89.3
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-B8F2ORwg.d.ts → agent-bridge-DbVe1dHT.d.ts} +1 -1
- package/dist/{agent-subagent-runner-CQaLFNnA.d.ts → agent-subagent-runner-C6eqID1t.d.ts} +433 -433
- package/dist/{events-DzyLtja6.d.ts → brain-s9DyD_Vf.d.ts} +179 -92
- package/dist/{compactor-CJq7LQev.d.ts → compactor-DXLxLcmU.d.ts} +2 -2
- package/dist/{config-_DZ7dN-T.d.ts → config-84VaZpH6.d.ts} +45 -38
- package/dist/{context-ToHAp4-U.d.ts → context-CNRYfhUv.d.ts} +1 -1
- package/dist/coordination/index.d.ts +16 -17
- package/dist/coordination/index.js +25 -37
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +31 -33
- package/dist/defaults/index.js +476 -206
- package/dist/defaults/index.js.map +1 -1
- package/dist/{director-state-CgIc30qi.d.ts → director-state-BfeCUbmk.d.ts} +1 -1
- package/dist/execution/index.d.ts +18 -19
- package/dist/execution/index.js +23 -45
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +9 -10
- package/dist/extension/index.js +8 -6
- package/dist/extension/index.js.map +1 -1
- package/dist/{index-Ca_lOmKl.d.ts → index-CqrroYcU.d.ts} +13 -15
- package/dist/{index-Dx-CnrDN.d.ts → index-D3Nax3YU.d.ts} +9 -10
- package/dist/index.d.ts +184 -174
- package/dist/index.js +973 -349
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +9 -9
- package/dist/infrastructure/index.js +4 -2
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +14 -16
- package/dist/kernel/index.js.map +1 -1
- package/dist/{logger-B72yyPc6.d.ts → logger-B63L5bTg.d.ts} +1 -1
- package/dist/{logger-C_27pj9i.d.ts → logger-B9J5puGM.d.ts} +1 -1
- package/dist/{mcp-servers-Dck3T85_.d.ts → mcp-servers-D3E5ixAR.d.ts} +3 -3
- package/dist/{mode-CHo2XtHs.d.ts → mode-ARA3HrkY.d.ts} +1 -1
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +8 -6
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-Be3osGt5.d.ts → models-registry-B6_KfS65.d.ts} +1 -1
- package/dist/{models-registry-Boz639EI.d.ts → models-registry-DU64QxQa.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-Da9nd8Ic.d.ts → multi-agent-coordinator-DHNrjPaA.d.ts} +2 -2
- package/dist/{null-fleet-bus-CHJOXv3t.d.ts → null-fleet-bus-BzzciAc4.d.ts} +32 -31
- package/dist/observability/index.d.ts +3 -3
- package/dist/{observability-CoSNZdhX.d.ts → observability-D-HZN_mF.d.ts} +1 -1
- package/dist/{parallel-eternal-engine-DyMCj2Pw.d.ts → parallel-eternal-engine-CTpcrb9O.d.ts} +33 -33
- package/dist/{path-resolver-TjBlRKyH.d.ts → path-resolver-B7hgMAVe.d.ts} +3 -3
- package/dist/{permission-14CChMmO.d.ts → permission-BDv7z0mk.d.ts} +7 -2
- package/dist/{permission-policy-gW5htOo1.d.ts → permission-policy-dF74EpDp.d.ts} +2 -2
- package/dist/{system-prompt-C0rLCeyn.d.ts → pipeline-C1Ad9OjI.d.ts} +73 -73
- package/dist/{plan-templates-D9UhwoGh.d.ts → plan-templates-CNphsz0n.d.ts} +79 -11
- package/dist/{provider-runner-BEPWwkxH.d.ts → provider-runner-cqvlB_oS.d.ts} +5 -5
- package/dist/{retry-policy-DSu6O6rD.d.ts → retry-policy-BcmuT_V0.d.ts} +2 -2
- package/dist/sdd/index.d.ts +12 -33
- package/dist/sdd/index.js +21 -31
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-scrubber-yGBFQYju.d.ts → secret-vault-DrOhc2i5.d.ts} +7 -7
- package/dist/security/index.d.ts +4 -5
- package/dist/security/index.js +4 -2
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-11-fm95U.d.ts → selector-C7wcdqMA.d.ts} +1 -1
- package/dist/{session-event-bridge-D0u-x576.d.ts → session-event-bridge-IVzs2GpE.d.ts} +1 -1
- package/dist/{session-reader-BQU-toaN.d.ts → session-reader-DDz1Ek4V.d.ts} +2 -2
- package/dist/{skill-BJeF2DwY.d.ts → skill-BJxzIyyN.d.ts} +1 -1
- package/dist/skills/index.d.ts +1 -1
- package/dist/skills/index.js +3 -9
- package/dist/skills/index.js.map +1 -1
- package/dist/storage/index.d.ts +132 -12
- package/dist/storage/index.js +834 -159
- package/dist/storage/index.js.map +1 -1
- package/dist/{task-graph-CikNdRTG.d.ts → task-graph-DJBqO0EY.d.ts} +1 -1
- package/dist/types/index.d.ts +25 -27
- package/dist/types/index.js +19 -31
- package/dist/types/index.js.map +1 -1
- package/dist/utils/expect-defined.d.ts +7 -0
- package/dist/utils/expect-defined.js +11 -0
- package/dist/utils/expect-defined.js.map +1 -0
- package/dist/utils/index.d.ts +6 -20
- package/dist/utils/index.js +11 -41
- package/dist/utils/index.js.map +1 -1
- package/dist/{wstack-paths-BQMvEllz.d.ts → wstack-paths-_lqjzErq.d.ts} +1 -1
- package/package.json +5 -1
- package/dist/memory-CEXuo7sz.d.ts +0 -16
- package/dist/secret-scrubber-3MHDDAtm.d.ts +0 -6
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import * as path6 from 'path';
|
|
|
6
6
|
import { join, extname, relative, isAbsolute, resolve, sep } from 'path';
|
|
7
7
|
import * as fs2 from 'fs';
|
|
8
8
|
import * as os7 from 'os';
|
|
9
|
+
import { hostname } from 'os';
|
|
9
10
|
import { execFile, spawn } from 'child_process';
|
|
10
11
|
import { promisify } from 'util';
|
|
11
12
|
import { EventEmitter } from 'events';
|
|
@@ -15,12 +16,6 @@ import { pipeline } from 'stream/promises';
|
|
|
15
16
|
|
|
16
17
|
var __defProp = Object.defineProperty;
|
|
17
18
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
18
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
19
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
20
|
-
}) : x)(function(x) {
|
|
21
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
22
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
23
|
-
});
|
|
24
19
|
var __esm = (fn, res) => function __init() {
|
|
25
20
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
26
21
|
};
|
|
@@ -1713,13 +1708,25 @@ function round4(n) {
|
|
|
1713
1708
|
return Math.round(n * 1e4) / 1e4;
|
|
1714
1709
|
}
|
|
1715
1710
|
|
|
1716
|
-
// src/
|
|
1717
|
-
|
|
1711
|
+
// src/types/memory.ts
|
|
1712
|
+
var MEMORY_TYPE_LABELS = {
|
|
1713
|
+
fact: "Fact",
|
|
1714
|
+
decision: "Decision",
|
|
1715
|
+
convention: "Convention",
|
|
1716
|
+
preference: "Preference",
|
|
1717
|
+
reference: "Reference",
|
|
1718
|
+
anti_pattern: "Anti-pattern"
|
|
1719
|
+
};
|
|
1720
|
+
|
|
1721
|
+
// src/utils/expect-defined.ts
|
|
1722
|
+
function expectDefined(value, label) {
|
|
1718
1723
|
if (value === null || value === void 0) {
|
|
1719
|
-
throw new Error("Expected value to be defined");
|
|
1724
|
+
throw new Error(label ? `Expected ${label} to be defined` : "Expected value to be defined");
|
|
1720
1725
|
}
|
|
1721
1726
|
return value;
|
|
1722
1727
|
}
|
|
1728
|
+
|
|
1729
|
+
// src/utils/token-estimate.ts
|
|
1723
1730
|
var RoughTokenEstimate = (text, charsPerToken = 3.5) => Math.max(1, Math.ceil(text.length / charsPerToken));
|
|
1724
1731
|
var _cal = {
|
|
1725
1732
|
ratio: 1,
|
|
@@ -1853,12 +1860,6 @@ function resetCalibration() {
|
|
|
1853
1860
|
}
|
|
1854
1861
|
|
|
1855
1862
|
// src/utils/message-invariants.ts
|
|
1856
|
-
function expectDefined2(value) {
|
|
1857
|
-
if (value === null || value === void 0) {
|
|
1858
|
-
throw new Error("Expected value to be defined");
|
|
1859
|
-
}
|
|
1860
|
-
return value;
|
|
1861
|
-
}
|
|
1862
1863
|
function repairToolUseAdjacency(messages) {
|
|
1863
1864
|
const removedToolUses = [];
|
|
1864
1865
|
const removedToolResults = [];
|
|
@@ -1866,7 +1867,7 @@ function repairToolUseAdjacency(messages) {
|
|
|
1866
1867
|
let changed = false;
|
|
1867
1868
|
const out = [];
|
|
1868
1869
|
for (let i = 0; i < messages.length; i++) {
|
|
1869
|
-
const original =
|
|
1870
|
+
const original = expectDefined(messages[i]);
|
|
1870
1871
|
let msg = original;
|
|
1871
1872
|
if (hasToolUse(msg)) {
|
|
1872
1873
|
const nextIds = toolResultIds(messages[i + 1]);
|
|
@@ -3024,12 +3025,6 @@ Remember: your job is to make the user a better developer, not just to complete
|
|
|
3024
3025
|
];
|
|
3025
3026
|
|
|
3026
3027
|
// src/types/context-window.ts
|
|
3027
|
-
function expectDefined3(value) {
|
|
3028
|
-
if (value === null || value === void 0) {
|
|
3029
|
-
throw new Error("Expected value to be defined");
|
|
3030
|
-
}
|
|
3031
|
-
return value;
|
|
3032
|
-
}
|
|
3033
3028
|
var DEFAULT_CONTEXT_WINDOW_MODE_ID = "balanced";
|
|
3034
3029
|
var CONTEXT_WINDOW_MODES = Object.freeze([
|
|
3035
3030
|
{
|
|
@@ -3086,7 +3081,7 @@ function isContextWindowModeId(id) {
|
|
|
3086
3081
|
}
|
|
3087
3082
|
function resolveContextWindowPolicy(config = {}, overrideMode) {
|
|
3088
3083
|
const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;
|
|
3089
|
-
const mode = getContextWindowMode(requested) ??
|
|
3084
|
+
const mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));
|
|
3090
3085
|
if (mode.id !== DEFAULT_CONTEXT_WINDOW_MODE_ID) {
|
|
3091
3086
|
return mode;
|
|
3092
3087
|
}
|
|
@@ -3566,12 +3561,6 @@ function sizeSignals(toolName, content) {
|
|
|
3566
3561
|
}
|
|
3567
3562
|
|
|
3568
3563
|
// src/execution/tool-executor.ts
|
|
3569
|
-
function expectDefined4(value) {
|
|
3570
|
-
if (value === null || value === void 0) {
|
|
3571
|
-
throw new Error("Expected value to be defined");
|
|
3572
|
-
}
|
|
3573
|
-
return value;
|
|
3574
|
-
}
|
|
3575
3564
|
var ToolExecutor = class {
|
|
3576
3565
|
constructor(registry, opts) {
|
|
3577
3566
|
this.registry = registry;
|
|
@@ -3978,7 +3967,7 @@ function hasMalformedArguments(input) {
|
|
|
3978
3967
|
function extractMalformedRaw(input) {
|
|
3979
3968
|
if (!hasMalformedArguments(input)) return void 0;
|
|
3980
3969
|
const obj = input;
|
|
3981
|
-
const value = obj[
|
|
3970
|
+
const value = obj[expectDefined(Object.keys(obj)[0])];
|
|
3982
3971
|
if (value === void 0 || value === null) return void 0;
|
|
3983
3972
|
if (typeof value === "string") return value;
|
|
3984
3973
|
try {
|
|
@@ -4025,12 +4014,6 @@ function compileUserRegex(pattern, flags) {
|
|
|
4025
4014
|
}
|
|
4026
4015
|
|
|
4027
4016
|
// src/storage/session-reader.ts
|
|
4028
|
-
function expectDefined5(value) {
|
|
4029
|
-
if (value === null || value === void 0) {
|
|
4030
|
-
throw new Error("Expected value to be defined");
|
|
4031
|
-
}
|
|
4032
|
-
return value;
|
|
4033
|
-
}
|
|
4034
4017
|
var DefaultSessionReader = class {
|
|
4035
4018
|
store;
|
|
4036
4019
|
constructor(opts) {
|
|
@@ -4092,7 +4075,7 @@ var DefaultSessionReader = class {
|
|
|
4092
4075
|
continue;
|
|
4093
4076
|
}
|
|
4094
4077
|
for (let i = 0; i < data.events.length; i++) {
|
|
4095
|
-
const ev =
|
|
4078
|
+
const ev = expectDefined(data.events[i]);
|
|
4096
4079
|
if (allowedTypes && !allowedTypes.has(ev.type)) continue;
|
|
4097
4080
|
const text = eventText(ev);
|
|
4098
4081
|
if (text === null) continue;
|
|
@@ -4460,12 +4443,6 @@ function formatTodosList(todos) {
|
|
|
4460
4443
|
}
|
|
4461
4444
|
|
|
4462
4445
|
// src/utils/glob-match.ts
|
|
4463
|
-
function expectDefined6(value) {
|
|
4464
|
-
if (value === null || value === void 0) {
|
|
4465
|
-
throw new Error("Expected value to be defined");
|
|
4466
|
-
}
|
|
4467
|
-
return value;
|
|
4468
|
-
}
|
|
4469
4446
|
function escapeRegex(s) {
|
|
4470
4447
|
return s.replace(/[.+^${}()|\\]/g, "\\$&");
|
|
4471
4448
|
}
|
|
@@ -4477,7 +4454,7 @@ function getCachedGlob(pattern) {
|
|
|
4477
4454
|
if (COMPILED_GLOB_CACHE.size >= CACHE_MAX_SIZE) {
|
|
4478
4455
|
const keys = [...COMPILED_GLOB_CACHE.keys()];
|
|
4479
4456
|
for (let i = 0; i < Math.floor(CACHE_MAX_SIZE / 4); i++) {
|
|
4480
|
-
COMPILED_GLOB_CACHE.delete(
|
|
4457
|
+
COMPILED_GLOB_CACHE.delete(expectDefined(keys[i]));
|
|
4481
4458
|
}
|
|
4482
4459
|
}
|
|
4483
4460
|
const re = compileGlob(pattern);
|
|
@@ -4837,20 +4814,6 @@ function buildChildEnv(optsOrSessionId) {
|
|
|
4837
4814
|
function sleep(ms) {
|
|
4838
4815
|
return new Promise((resolve13) => setTimeout(resolve13, ms));
|
|
4839
4816
|
}
|
|
4840
|
-
|
|
4841
|
-
// src/utils/expect-defined.ts
|
|
4842
|
-
function expectDefined7(value) {
|
|
4843
|
-
if (value === null || value === void 0) {
|
|
4844
|
-
throw new Error("Expected value to be defined");
|
|
4845
|
-
}
|
|
4846
|
-
return value;
|
|
4847
|
-
}
|
|
4848
|
-
function expectDefined8(value) {
|
|
4849
|
-
if (value === null || value === void 0) {
|
|
4850
|
-
throw new Error("Expected value to be defined");
|
|
4851
|
-
}
|
|
4852
|
-
return value;
|
|
4853
|
-
}
|
|
4854
4817
|
var GLOB_CHARS = /* @__PURE__ */ new Set(["*", "?", "["]);
|
|
4855
4818
|
var IS_WINDOWS = process.platform === "win32";
|
|
4856
4819
|
var SEP = IS_WINDOWS ? "\\" : "/";
|
|
@@ -4864,7 +4827,7 @@ function globToRegex(pat) {
|
|
|
4864
4827
|
let i = 0;
|
|
4865
4828
|
let re = "^";
|
|
4866
4829
|
while (i < pat.length) {
|
|
4867
|
-
const c =
|
|
4830
|
+
const c = expectDefined(pat[i]);
|
|
4868
4831
|
if (c === "*") {
|
|
4869
4832
|
if (pat[i + 1] === "*") {
|
|
4870
4833
|
re += ".*";
|
|
@@ -4903,7 +4866,7 @@ function globToRegex(pat) {
|
|
|
4903
4866
|
}
|
|
4904
4867
|
function baseDir(pat) {
|
|
4905
4868
|
let i = pat.length - 1;
|
|
4906
|
-
while (i >= 0 && !GLOB_CHARS.has(
|
|
4869
|
+
while (i >= 0 && !GLOB_CHARS.has(expectDefined(pat[i])) && pat[i] !== SEP && pat[i] !== "/") i--;
|
|
4907
4870
|
const cut = i >= 0 ? pat.lastIndexOf(SEP, i) : pat.lastIndexOf("/", i);
|
|
4908
4871
|
return cut < 0 ? "." : pat.slice(0, cut);
|
|
4909
4872
|
}
|
|
@@ -4968,12 +4931,6 @@ async function expandGlob(pattern) {
|
|
|
4968
4931
|
}
|
|
4969
4932
|
|
|
4970
4933
|
// src/utils/json-repair.ts
|
|
4971
|
-
function expectDefined9(value) {
|
|
4972
|
-
if (value === null || value === void 0) {
|
|
4973
|
-
throw new Error("Expected value to be defined");
|
|
4974
|
-
}
|
|
4975
|
-
return value;
|
|
4976
|
-
}
|
|
4977
4934
|
function completePartialObject(s) {
|
|
4978
4935
|
if (!s.trim().startsWith("{")) return s;
|
|
4979
4936
|
if (tryParse(s).ok) return s;
|
|
@@ -4985,7 +4942,7 @@ function completePartialObject(s) {
|
|
|
4985
4942
|
let contentEnd = 0;
|
|
4986
4943
|
let stringBraceDepth = 0;
|
|
4987
4944
|
for (let i = 0; i < s.length; i++) {
|
|
4988
|
-
const ch =
|
|
4945
|
+
const ch = expectDefined(s[i]);
|
|
4989
4946
|
if (inString) {
|
|
4990
4947
|
contentEnd = i + 1;
|
|
4991
4948
|
if (escaped) {
|
|
@@ -5081,12 +5038,6 @@ function mergeCustomModelDefs(providerCustomModels, configModels) {
|
|
|
5081
5038
|
|
|
5082
5039
|
// src/storage/session-store.ts
|
|
5083
5040
|
init_atomic_write();
|
|
5084
|
-
function expectDefined10(value) {
|
|
5085
|
-
if (value === null || value === void 0) {
|
|
5086
|
-
throw new Error("Expected value to be defined");
|
|
5087
|
-
}
|
|
5088
|
-
return value;
|
|
5089
|
-
}
|
|
5090
5041
|
function sanitizeModel(model) {
|
|
5091
5042
|
return model.replace(/[^a-zA-Z0-9_-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 40);
|
|
5092
5043
|
}
|
|
@@ -5797,7 +5748,7 @@ var FileSessionWriter = class {
|
|
|
5797
5748
|
let targetCheckpointLine = -1;
|
|
5798
5749
|
let afterTarget = false;
|
|
5799
5750
|
for (let i = 0; i < lines.length; i++) {
|
|
5800
|
-
const line =
|
|
5751
|
+
const line = expectDefined(lines[i]);
|
|
5801
5752
|
if (!line.trim()) continue;
|
|
5802
5753
|
let event;
|
|
5803
5754
|
try {
|
|
@@ -6092,12 +6043,224 @@ function mergeAdjacentText(blocks) {
|
|
|
6092
6043
|
}
|
|
6093
6044
|
return out;
|
|
6094
6045
|
}
|
|
6046
|
+
init_atomic_write();
|
|
6047
|
+
var TYPE_PRIORITY_RE = /^\[(\w+)\|(\w+)\]\s+/;
|
|
6048
|
+
var TAG_RE = /#([\w-]+)/g;
|
|
6049
|
+
function formatMetadata(entry) {
|
|
6050
|
+
const parts = [];
|
|
6051
|
+
if (entry.type && entry.priority) {
|
|
6052
|
+
parts.push(`[${entry.type}|${entry.priority}]`);
|
|
6053
|
+
} else if (entry.type) {
|
|
6054
|
+
parts.push(`[${entry.type}]`);
|
|
6055
|
+
} else if (entry.priority) {
|
|
6056
|
+
parts.push(`[${entry.priority}]`);
|
|
6057
|
+
}
|
|
6058
|
+
if (entry.tags && entry.tags.length > 0) {
|
|
6059
|
+
parts.push(entry.tags.map((t2) => `#${t2}`).join(" "));
|
|
6060
|
+
}
|
|
6061
|
+
return parts.length > 0 ? ` ${parts.join(" ")}` : "";
|
|
6062
|
+
}
|
|
6063
|
+
function lineToEntry(line, scope) {
|
|
6064
|
+
const trimmed = line.trim();
|
|
6065
|
+
if (!trimmed.startsWith("- [")) return null;
|
|
6066
|
+
const tsMatch = trimmed.match(/^-\s*\[([^\]]+)\]/);
|
|
6067
|
+
if (!tsMatch) return null;
|
|
6068
|
+
const ts = tsMatch[1] ?? "";
|
|
6069
|
+
let rest = trimmed.slice(tsMatch[0].length).trim();
|
|
6070
|
+
let type;
|
|
6071
|
+
let priority;
|
|
6072
|
+
const tpMatch = rest.match(TYPE_PRIORITY_RE);
|
|
6073
|
+
if (tpMatch) {
|
|
6074
|
+
const a = tpMatch[1] ?? "";
|
|
6075
|
+
const b = tpMatch[2] ?? "";
|
|
6076
|
+
if (isMemoryType(a)) {
|
|
6077
|
+
type = a;
|
|
6078
|
+
priority = isPriority(b) ? b : void 0;
|
|
6079
|
+
} else if (isPriority(a)) {
|
|
6080
|
+
priority = a;
|
|
6081
|
+
}
|
|
6082
|
+
rest = rest.slice(tpMatch[0].length).trim();
|
|
6083
|
+
}
|
|
6084
|
+
const idMatch = rest.match(/^mem_\d+_\w+\s+/);
|
|
6085
|
+
let text;
|
|
6086
|
+
if (idMatch) {
|
|
6087
|
+
text = rest.slice(idMatch[0].length).trim();
|
|
6088
|
+
} else {
|
|
6089
|
+
text = rest.trim();
|
|
6090
|
+
}
|
|
6091
|
+
const tags = [];
|
|
6092
|
+
let tagMatch;
|
|
6093
|
+
TAG_RE.lastIndex = 0;
|
|
6094
|
+
while ((tagMatch = TAG_RE.exec(text)) !== null) {
|
|
6095
|
+
tags.push(tagMatch[1] ?? "");
|
|
6096
|
+
}
|
|
6097
|
+
const cleanText = text.replace(TAG_RE, "").replace(/\s{2,}/g, " ").trim();
|
|
6098
|
+
if (!cleanText) return null;
|
|
6099
|
+
return {
|
|
6100
|
+
scope,
|
|
6101
|
+
text: cleanText,
|
|
6102
|
+
ts,
|
|
6103
|
+
type,
|
|
6104
|
+
priority,
|
|
6105
|
+
tags: tags.length > 0 ? tags : void 0
|
|
6106
|
+
};
|
|
6107
|
+
}
|
|
6108
|
+
function isMemoryType(s) {
|
|
6109
|
+
return s in MEMORY_TYPE_LABELS;
|
|
6110
|
+
}
|
|
6111
|
+
function isPriority(s) {
|
|
6112
|
+
return s === "critical" || s === "high" || s === "medium" || s === "low";
|
|
6113
|
+
}
|
|
6114
|
+
var FileMemoryBackend = class {
|
|
6115
|
+
kind = "file";
|
|
6116
|
+
files;
|
|
6117
|
+
constructor(opts) {
|
|
6118
|
+
this.files = {
|
|
6119
|
+
"project-agents": opts.paths.inProjectAgentsFile,
|
|
6120
|
+
"project-memory": opts.paths.projectMemory,
|
|
6121
|
+
"user-memory": opts.paths.globalMemory
|
|
6122
|
+
};
|
|
6123
|
+
}
|
|
6124
|
+
resolveFile(filePath, scope) {
|
|
6125
|
+
return filePath || this.files[scope];
|
|
6126
|
+
}
|
|
6127
|
+
async remember(scope, entry, filePath) {
|
|
6128
|
+
const file = this.resolveFile(filePath, scope);
|
|
6129
|
+
await ensureDir(path6.dirname(file));
|
|
6130
|
+
let existing = "";
|
|
6131
|
+
try {
|
|
6132
|
+
existing = await fsp3.readFile(file, "utf8");
|
|
6133
|
+
} catch {
|
|
6134
|
+
}
|
|
6135
|
+
const id = `mem_${Date.now()}_${randomUUID().slice(0, 8)}`;
|
|
6136
|
+
const meta = formatMetadata(entry);
|
|
6137
|
+
const line = `
|
|
6138
|
+
- [${entry.ts}] ${id}${meta} ${entry.text.replace(/\n/g, " ")}
|
|
6139
|
+
`;
|
|
6140
|
+
const next = existing.trim() ? existing.replace(/\n+$/, "") + line : `# WrongStack Memory
|
|
6141
|
+
${line}`;
|
|
6142
|
+
await atomicWrite(file, next);
|
|
6143
|
+
}
|
|
6144
|
+
async forget(scope, query, filePath) {
|
|
6145
|
+
const file = this.resolveFile(filePath, scope);
|
|
6146
|
+
let existing;
|
|
6147
|
+
try {
|
|
6148
|
+
existing = await fsp3.readFile(file, "utf8");
|
|
6149
|
+
} catch {
|
|
6150
|
+
return 0;
|
|
6151
|
+
}
|
|
6152
|
+
const needle = query.toLowerCase();
|
|
6153
|
+
const idMatcher = /mem_\d+_\w+/;
|
|
6154
|
+
let removed = 0;
|
|
6155
|
+
const lines = existing.split("\n").filter((line) => {
|
|
6156
|
+
const trimmed = line.trim();
|
|
6157
|
+
if (!trimmed.startsWith("- ")) return true;
|
|
6158
|
+
if (idMatcher.test(query)) {
|
|
6159
|
+
const entryIdMatch = /mem_\d+_\w+/.exec(trimmed);
|
|
6160
|
+
if (entryIdMatch && entryIdMatch[0] === query) {
|
|
6161
|
+
removed++;
|
|
6162
|
+
return false;
|
|
6163
|
+
}
|
|
6164
|
+
}
|
|
6165
|
+
if (trimmed.toLowerCase().includes(needle)) {
|
|
6166
|
+
removed++;
|
|
6167
|
+
return false;
|
|
6168
|
+
}
|
|
6169
|
+
return true;
|
|
6170
|
+
});
|
|
6171
|
+
if (removed > 0) {
|
|
6172
|
+
if (lines.length === 0 || lines.length === 1 && !lines[0]?.trim()) {
|
|
6173
|
+
await atomicWrite(file, "");
|
|
6174
|
+
} else {
|
|
6175
|
+
await atomicWrite(file, lines.join("\n"));
|
|
6176
|
+
}
|
|
6177
|
+
}
|
|
6178
|
+
return removed;
|
|
6179
|
+
}
|
|
6180
|
+
async readAll(scope, filePath) {
|
|
6181
|
+
const file = this.resolveFile(filePath, scope);
|
|
6182
|
+
try {
|
|
6183
|
+
return await fsp3.readFile(file, "utf8");
|
|
6184
|
+
} catch {
|
|
6185
|
+
return "";
|
|
6186
|
+
}
|
|
6187
|
+
}
|
|
6188
|
+
async list(scope, filePath, limit) {
|
|
6189
|
+
const raw = await this.readAll(scope, filePath);
|
|
6190
|
+
if (!raw.trim()) return [];
|
|
6191
|
+
const entries = parseEntries(raw, scope);
|
|
6192
|
+
return limit ? entries.slice(0, limit) : entries;
|
|
6193
|
+
}
|
|
6194
|
+
async search(scope, query, filePath, limit) {
|
|
6195
|
+
const entries = await this.list(scope, filePath);
|
|
6196
|
+
const needle = query.toLowerCase().split(/\s+/);
|
|
6197
|
+
const scored = entries.map((e) => {
|
|
6198
|
+
const words = e.text.toLowerCase().split(/\s+/);
|
|
6199
|
+
let score = 0;
|
|
6200
|
+
for (const n of needle) {
|
|
6201
|
+
if (words.some((w) => w.includes(n))) score += 1;
|
|
6202
|
+
if (e.tags?.some((t2) => t2.toLowerCase().includes(n))) score += 2;
|
|
6203
|
+
}
|
|
6204
|
+
return { entry: e, score };
|
|
6205
|
+
});
|
|
6206
|
+
scored.sort((a, b) => b.score - a.score);
|
|
6207
|
+
const matched = scored.filter((s) => s.score > 0).map((s) => s.entry);
|
|
6208
|
+
return limit ? matched.slice(0, limit) : matched;
|
|
6209
|
+
}
|
|
6210
|
+
async clear(scope, filePath) {
|
|
6211
|
+
const file = this.resolveFile(filePath, scope);
|
|
6212
|
+
await atomicWrite(file, "");
|
|
6213
|
+
}
|
|
6214
|
+
async consolidate(scope, filePath) {
|
|
6215
|
+
const file = this.resolveFile(filePath, scope);
|
|
6216
|
+
let existing;
|
|
6217
|
+
try {
|
|
6218
|
+
existing = await fsp3.readFile(file, "utf8");
|
|
6219
|
+
} catch {
|
|
6220
|
+
return 0;
|
|
6221
|
+
}
|
|
6222
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6223
|
+
let removed = 0;
|
|
6224
|
+
const lines = existing.split("\n").filter((line) => {
|
|
6225
|
+
const trimmed = line.trim();
|
|
6226
|
+
if (!trimmed.startsWith("- ")) return true;
|
|
6227
|
+
const norm = trimmed.replace(/\[[^\]]+\]/g, "").replace(/\bmem_\d+_\w+\s*/, "").replace(/#[\w-]+/g, "").replace(/\s+/g, " ").trim().toLowerCase();
|
|
6228
|
+
if (seen.has(norm)) {
|
|
6229
|
+
removed++;
|
|
6230
|
+
return false;
|
|
6231
|
+
}
|
|
6232
|
+
seen.add(norm);
|
|
6233
|
+
return true;
|
|
6234
|
+
});
|
|
6235
|
+
const next = lines.join("\n");
|
|
6236
|
+
const backup = `${file}.bak.${Date.now()}`;
|
|
6237
|
+
try {
|
|
6238
|
+
await fsp3.copyFile(file, backup);
|
|
6239
|
+
} catch {
|
|
6240
|
+
}
|
|
6241
|
+
try {
|
|
6242
|
+
await atomicWrite(file, next);
|
|
6243
|
+
} catch {
|
|
6244
|
+
return 0;
|
|
6245
|
+
}
|
|
6246
|
+
return removed;
|
|
6247
|
+
}
|
|
6248
|
+
};
|
|
6249
|
+
function parseEntries(raw, scope = "project-memory") {
|
|
6250
|
+
const entries = [];
|
|
6251
|
+
for (const line of raw.split("\n")) {
|
|
6252
|
+
const entry = lineToEntry(line, scope);
|
|
6253
|
+
if (entry) entries.push(entry);
|
|
6254
|
+
}
|
|
6255
|
+
return entries.reverse();
|
|
6256
|
+
}
|
|
6095
6257
|
|
|
6096
6258
|
// src/storage/memory-store.ts
|
|
6097
|
-
init_atomic_write();
|
|
6098
6259
|
var MAX_BYTES_TOTAL = 32e3;
|
|
6099
6260
|
var DefaultMemoryStore = class {
|
|
6100
6261
|
files;
|
|
6262
|
+
events;
|
|
6263
|
+
backend;
|
|
6101
6264
|
/**
|
|
6102
6265
|
* Per-scope serialization queue. `remember` / `forget` / `consolidate` /
|
|
6103
6266
|
* `clear` are read-modify-write against a single file; without a lock,
|
|
@@ -6114,12 +6277,29 @@ var DefaultMemoryStore = class {
|
|
|
6114
6277
|
writeChain = /* @__PURE__ */ new Map();
|
|
6115
6278
|
/** Last write error per scope — surfaced as warnings on the next readAll(). */
|
|
6116
6279
|
writeErrors = /* @__PURE__ */ new Map();
|
|
6280
|
+
/**
|
|
6281
|
+
* When the global root is a temporary directory (opencode, CI sandboxes),
|
|
6282
|
+
* memory files are also mirrored to the project tree so they survive
|
|
6283
|
+
* session cleanup. The primary path stays in the temp root for isolation;
|
|
6284
|
+
* this backup ensures memory is never lost.
|
|
6285
|
+
*/
|
|
6286
|
+
persistBackup;
|
|
6287
|
+
backupDir;
|
|
6117
6288
|
constructor(opts) {
|
|
6118
6289
|
this.files = {
|
|
6119
6290
|
"project-agents": opts.paths.inProjectAgentsFile,
|
|
6120
6291
|
"project-memory": opts.paths.projectMemory,
|
|
6121
6292
|
"user-memory": opts.paths.globalMemory
|
|
6122
6293
|
};
|
|
6294
|
+
this.events = opts.events;
|
|
6295
|
+
this.backend = opts.backend ?? new FileMemoryBackend({ paths: opts.paths });
|
|
6296
|
+
const root = opts.paths.globalRoot.toLowerCase();
|
|
6297
|
+
this.persistBackup = /[/\\](tmp|temp|cache)[/\\]/.test(root);
|
|
6298
|
+
this.backupDir = this.persistBackup ? opts.paths.inProjectAgentsFile.replace(/AGENTS\.md$/, "memory-persist") : "";
|
|
6299
|
+
}
|
|
6300
|
+
/** Expose the backend for plugin introspection and advanced queries. */
|
|
6301
|
+
getBackend() {
|
|
6302
|
+
return this.backend;
|
|
6123
6303
|
}
|
|
6124
6304
|
async runSerialized(scope, work) {
|
|
6125
6305
|
const prior = this.writeChain.get(scope) ?? Promise.resolve();
|
|
@@ -6146,7 +6326,7 @@ var DefaultMemoryStore = class {
|
|
|
6146
6326
|
if (writeErr2) {
|
|
6147
6327
|
parts.push(`> \u26A0\uFE0F Memory write error (${labelOf(scope)}): ${writeErr2.message}`);
|
|
6148
6328
|
}
|
|
6149
|
-
const body = await this.
|
|
6329
|
+
const body = await this.backend.readAll(scope, this.files[scope]);
|
|
6150
6330
|
if (body.trim()) parts.push(`## ${labelOf(scope)}
|
|
6151
6331
|
|
|
6152
6332
|
${body.trim()}`);
|
|
@@ -6154,117 +6334,214 @@ ${body.trim()}`);
|
|
|
6154
6334
|
return parts.join("\n\n");
|
|
6155
6335
|
}
|
|
6156
6336
|
async read(scope) {
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6337
|
+
return this.backend.readAll(scope, this.files[scope]);
|
|
6338
|
+
}
|
|
6339
|
+
/**
|
|
6340
|
+
* List entries from a scope, newest first. Delegates to the backend
|
|
6341
|
+
* so graph/semantic backends can return enriched or filtered results.
|
|
6342
|
+
*/
|
|
6343
|
+
async list(scope = "project-memory", limit) {
|
|
6344
|
+
return this.backend.list(scope, this.files[scope], limit);
|
|
6345
|
+
}
|
|
6346
|
+
/**
|
|
6347
|
+
* Find memories related to the given text via graph traversal.
|
|
6348
|
+
* Falls back to content search when no graph backend is available.
|
|
6349
|
+
*/
|
|
6350
|
+
async findRelated(text, scope = "project-memory", limit = 5) {
|
|
6351
|
+
if (this.backend.findRelated) {
|
|
6352
|
+
return this.backend.findRelated(scope, this.files[scope], text, limit);
|
|
6161
6353
|
}
|
|
6354
|
+
return this.search(text, scope, limit);
|
|
6355
|
+
}
|
|
6356
|
+
async search(query, scope = "project-memory", limit) {
|
|
6357
|
+
return this.backend.search(scope, query, this.files[scope], limit);
|
|
6162
6358
|
}
|
|
6163
|
-
async remember(text, scope = "project-memory") {
|
|
6359
|
+
async remember(text, scope = "project-memory", metadata) {
|
|
6360
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
6164
6361
|
return this.runSerialized(scope, async () => {
|
|
6165
|
-
const
|
|
6166
|
-
await
|
|
6167
|
-
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
`;
|
|
6177
|
-
const next = existing.trim() ? existing.replace(/\n+$/, "") + entry : `# WrongStack Memory
|
|
6178
|
-
${entry}`;
|
|
6179
|
-
await atomicWrite(file, next);
|
|
6180
|
-
const buf = Buffer.byteLength(next, "utf8");
|
|
6181
|
-
if (buf > MAX_BYTES_TOTAL) {
|
|
6182
|
-
await this.consolidateUnsafe(scope);
|
|
6362
|
+
const entry = { scope, text, ts, ...metadata };
|
|
6363
|
+
await this.backend.remember(scope, entry, this.files[scope]);
|
|
6364
|
+
const raw = await this.backend.readAll(scope, this.files[scope]);
|
|
6365
|
+
if (Buffer.byteLength(raw, "utf8") > MAX_BYTES_TOTAL) {
|
|
6366
|
+
const removed = await this.backend.consolidate(scope, this.files[scope]);
|
|
6367
|
+
if (removed > 0) {
|
|
6368
|
+
this.events?.emit("memory.consolidated", {
|
|
6369
|
+
scope,
|
|
6370
|
+
removed
|
|
6371
|
+
});
|
|
6372
|
+
}
|
|
6183
6373
|
}
|
|
6374
|
+
await this.mirrorBackup(scope);
|
|
6375
|
+
this.events?.emit("memory.remembered", {
|
|
6376
|
+
scope,
|
|
6377
|
+
text,
|
|
6378
|
+
ts,
|
|
6379
|
+
type: entry.type,
|
|
6380
|
+
tags: entry.tags,
|
|
6381
|
+
priority: entry.priority
|
|
6382
|
+
});
|
|
6184
6383
|
});
|
|
6185
6384
|
}
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
const
|
|
6198
|
-
const
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
const
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
if (
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6385
|
+
/**
|
|
6386
|
+
* Score and rank memories by relevance to the current context.
|
|
6387
|
+
* Returns entries with score >= MIN_RELEVANCE_SCORE, sorted highest first.
|
|
6388
|
+
*/
|
|
6389
|
+
async scoreRelevant(ctx, scope = "project-memory", limit = 8) {
|
|
6390
|
+
const all = await this.list(scope);
|
|
6391
|
+
if (all.length === 0) return [];
|
|
6392
|
+
const taskWords = ctx.currentTask.toLowerCase().split(/\s+/).filter((w) => w.length > 2);
|
|
6393
|
+
const skillWords = (ctx.activeSkills ?? []).flatMap((s) => s.split("-"));
|
|
6394
|
+
const toolWords = (ctx.toolNames ?? []).flatMap((t2) => t2.toLowerCase().split("_"));
|
|
6395
|
+
const now = Date.now();
|
|
6396
|
+
const scored = [];
|
|
6397
|
+
for (const entry of all) {
|
|
6398
|
+
let score = 0;
|
|
6399
|
+
const reasons = [];
|
|
6400
|
+
const textLower = entry.text.toLowerCase();
|
|
6401
|
+
const tagsLower = (entry.tags ?? []).map((t2) => t2.toLowerCase());
|
|
6402
|
+
let taskHits = 0;
|
|
6403
|
+
for (const w of taskWords) {
|
|
6404
|
+
if (textLower.includes(w)) {
|
|
6405
|
+
taskHits++;
|
|
6406
|
+
score += 2;
|
|
6407
|
+
}
|
|
6408
|
+
if (tagsLower.some((t2) => t2.includes(w))) {
|
|
6409
|
+
taskHits++;
|
|
6410
|
+
score += 3;
|
|
6212
6411
|
}
|
|
6213
6412
|
}
|
|
6214
|
-
if (
|
|
6215
|
-
|
|
6216
|
-
|
|
6413
|
+
if (taskHits > 0) reasons.push(`task match (${taskHits})`);
|
|
6414
|
+
let skillHits = 0;
|
|
6415
|
+
for (const w of skillWords) {
|
|
6416
|
+
if (w.length > 2 && (textLower.includes(w) || tagsLower.some((t2) => t2.includes(w)))) {
|
|
6417
|
+
skillHits++;
|
|
6418
|
+
}
|
|
6419
|
+
}
|
|
6420
|
+
score += skillHits;
|
|
6421
|
+
if (skillHits > 0) reasons.push(`skill match (${skillHits})`);
|
|
6422
|
+
for (const w of toolWords) {
|
|
6423
|
+
if (w.length > 2 && (textLower.includes(w) || tagsLower.some((t2) => t2.includes(w)))) {
|
|
6424
|
+
score += 1;
|
|
6425
|
+
reasons.push(`tool mention: ${w}`);
|
|
6426
|
+
}
|
|
6427
|
+
}
|
|
6428
|
+
switch (entry.priority) {
|
|
6429
|
+
case "critical":
|
|
6430
|
+
score += 5;
|
|
6431
|
+
reasons.push("critical");
|
|
6432
|
+
break;
|
|
6433
|
+
case "high":
|
|
6434
|
+
score += 3;
|
|
6435
|
+
reasons.push("high priority");
|
|
6436
|
+
break;
|
|
6437
|
+
case "medium":
|
|
6438
|
+
score += 1;
|
|
6439
|
+
break;
|
|
6440
|
+
case "low":
|
|
6441
|
+
score -= 2;
|
|
6442
|
+
reasons.push("low priority");
|
|
6443
|
+
break;
|
|
6444
|
+
}
|
|
6445
|
+
switch (entry.type) {
|
|
6446
|
+
case "decision":
|
|
6447
|
+
score += 2;
|
|
6448
|
+
reasons.push("decision");
|
|
6449
|
+
break;
|
|
6450
|
+
case "convention":
|
|
6451
|
+
score += 2;
|
|
6452
|
+
reasons.push("convention");
|
|
6453
|
+
break;
|
|
6454
|
+
case "anti_pattern":
|
|
6455
|
+
score += 3;
|
|
6456
|
+
reasons.push("anti-pattern");
|
|
6457
|
+
break;
|
|
6458
|
+
case "preference":
|
|
6459
|
+
score += 1;
|
|
6460
|
+
reasons.push("preference");
|
|
6461
|
+
break;
|
|
6462
|
+
}
|
|
6463
|
+
const ageDays = (now - new Date(entry.ts).getTime()) / (1e3 * 60 * 60 * 24);
|
|
6464
|
+
if (ageDays < 1) score += 1;
|
|
6465
|
+
else if (ageDays > 30) score -= 1;
|
|
6466
|
+
if (entry.confidence !== void 0 && entry.confidence < 0.5) {
|
|
6467
|
+
score -= 2;
|
|
6468
|
+
reasons.push("low confidence");
|
|
6469
|
+
}
|
|
6470
|
+
if (entry.lastAccessed) {
|
|
6471
|
+
const hoursSinceAccess = (now - new Date(entry.lastAccessed).getTime()) / (1e3 * 60 * 60);
|
|
6472
|
+
if (hoursSinceAccess < 1) score -= 1;
|
|
6473
|
+
}
|
|
6474
|
+
if (score > 0) {
|
|
6475
|
+
scored.push({
|
|
6476
|
+
...entry,
|
|
6477
|
+
score,
|
|
6478
|
+
matchReason: reasons.join(", ") || "keyword match"
|
|
6479
|
+
});
|
|
6217
6480
|
}
|
|
6218
|
-
return true;
|
|
6219
|
-
});
|
|
6220
|
-
if (removed > 0) {
|
|
6221
|
-
await atomicWrite(file, lines.join("\n"));
|
|
6222
6481
|
}
|
|
6223
|
-
|
|
6482
|
+
scored.sort((a, b) => b.score - a.score);
|
|
6483
|
+
const threshold = 2;
|
|
6484
|
+
const relevant = scored.filter(
|
|
6485
|
+
(s) => s.score >= threshold || s.priority === "critical" || s.priority === "high"
|
|
6486
|
+
);
|
|
6487
|
+
return relevant.slice(0, Math.min(limit, 15));
|
|
6224
6488
|
}
|
|
6225
|
-
async
|
|
6226
|
-
return this.runSerialized(scope, async () =>
|
|
6489
|
+
async forget(query, scope = "project-memory") {
|
|
6490
|
+
return this.runSerialized(scope, async () => {
|
|
6491
|
+
const removed = await this.backend.forget(scope, query, this.files[scope]);
|
|
6492
|
+
if (removed > 0) {
|
|
6493
|
+
this.events?.emit("memory.forgotten", {
|
|
6494
|
+
scope,
|
|
6495
|
+
query,
|
|
6496
|
+
removed
|
|
6497
|
+
});
|
|
6498
|
+
await this.mirrorBackup(scope);
|
|
6499
|
+
}
|
|
6500
|
+
return removed;
|
|
6501
|
+
});
|
|
6227
6502
|
}
|
|
6228
|
-
async
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
const trimmed = line.trim();
|
|
6239
|
-
if (!trimmed.startsWith("- ")) return true;
|
|
6240
|
-
const norm = trimmed.replace(/\[[^\]]+\]/, "").replace(/\bmem_\d+_\w+\s*/, "").trim().toLowerCase();
|
|
6241
|
-
if (seen.has(norm)) return false;
|
|
6242
|
-
seen.add(norm);
|
|
6243
|
-
return true;
|
|
6503
|
+
async consolidate(scope) {
|
|
6504
|
+
return this.runSerialized(scope, async () => {
|
|
6505
|
+
const removed = await this.backend.consolidate(scope, this.files[scope]);
|
|
6506
|
+
if (removed > 0) {
|
|
6507
|
+
this.events?.emit("memory.consolidated", {
|
|
6508
|
+
scope,
|
|
6509
|
+
removed
|
|
6510
|
+
});
|
|
6511
|
+
await this.mirrorBackup(scope);
|
|
6512
|
+
}
|
|
6244
6513
|
});
|
|
6245
|
-
const next = lines.join("\n");
|
|
6246
|
-
const backup = `${file}.bak.${Date.now()}`;
|
|
6247
|
-
try {
|
|
6248
|
-
await fsp3.copyFile(file, backup);
|
|
6249
|
-
} catch {
|
|
6250
|
-
}
|
|
6251
|
-
try {
|
|
6252
|
-
await atomicWrite(file, next);
|
|
6253
|
-
} catch {
|
|
6254
|
-
return;
|
|
6255
|
-
}
|
|
6256
6514
|
}
|
|
6257
6515
|
async clear(scope) {
|
|
6258
6516
|
if (scope) {
|
|
6259
|
-
await this.runSerialized(scope, async () =>
|
|
6517
|
+
await this.runSerialized(scope, async () => {
|
|
6518
|
+
await this.backend.clear(scope, this.files[scope]);
|
|
6519
|
+
this.events?.emit("memory.cleared", { scope });
|
|
6520
|
+
await this.mirrorBackup(scope);
|
|
6521
|
+
});
|
|
6260
6522
|
return;
|
|
6261
6523
|
}
|
|
6262
6524
|
await Promise.all(
|
|
6263
6525
|
["project-agents", "project-memory", "user-memory"].map(
|
|
6264
|
-
(s) => this.runSerialized(s, async () =>
|
|
6526
|
+
(s) => this.runSerialized(s, async () => {
|
|
6527
|
+
await this.backend.clear(s, this.files[s]);
|
|
6528
|
+
this.events?.emit("memory.cleared", { scope: s });
|
|
6529
|
+
await this.mirrorBackup(s);
|
|
6530
|
+
})
|
|
6265
6531
|
)
|
|
6266
6532
|
);
|
|
6267
6533
|
}
|
|
6534
|
+
/** Mirror current memory content to the persistent backup directory. */
|
|
6535
|
+
async mirrorBackup(scope) {
|
|
6536
|
+
if (!this.persistBackup || scope === "project-agents") return;
|
|
6537
|
+
try {
|
|
6538
|
+
const content = await this.backend.readAll(scope, this.files[scope]);
|
|
6539
|
+
const { writeFile: writeFile11, mkdir: mkdir17 } = await import('fs/promises');
|
|
6540
|
+
await mkdir17(this.backupDir, { recursive: true });
|
|
6541
|
+
await writeFile11(`${this.backupDir}/${scope}.md`, content, "utf8");
|
|
6542
|
+
} catch {
|
|
6543
|
+
}
|
|
6544
|
+
}
|
|
6268
6545
|
};
|
|
6269
6546
|
function labelOf(scope) {
|
|
6270
6547
|
switch (scope) {
|
|
@@ -7085,7 +7362,10 @@ function attachTodosCheckpoint(state, filePath, sessionId) {
|
|
|
7085
7362
|
let pending = null;
|
|
7086
7363
|
let writeChain = Promise.resolve();
|
|
7087
7364
|
const enqueueWrite = (todos) => {
|
|
7088
|
-
writeChain = writeChain.then(() => saveTodosCheckpoint(filePath, sessionId, todos))
|
|
7365
|
+
writeChain = writeChain.then(() => saveTodosCheckpoint(filePath, sessionId, todos)).catch((err) => {
|
|
7366
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
7367
|
+
console.error(`[TodosCheckpoint] save failed for session ${sessionId}: ${msg}`);
|
|
7368
|
+
});
|
|
7089
7369
|
return writeChain;
|
|
7090
7370
|
};
|
|
7091
7371
|
const flush = () => {
|
|
@@ -7389,7 +7669,7 @@ async function acquireDirectorStateLock(lockPath, processId = process.pid) {
|
|
|
7389
7669
|
}
|
|
7390
7670
|
const lock = {
|
|
7391
7671
|
pid: processId,
|
|
7392
|
-
hostname:
|
|
7672
|
+
hostname: hostname(),
|
|
7393
7673
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7394
7674
|
};
|
|
7395
7675
|
await atomicWrite(lockPath, JSON.stringify(lock), { mode: 384 });
|
|
@@ -8611,12 +8891,6 @@ var IntelligentCompactor = class {
|
|
|
8611
8891
|
};
|
|
8612
8892
|
|
|
8613
8893
|
// src/models/llm-selector.ts
|
|
8614
|
-
function expectDefined11(value) {
|
|
8615
|
-
if (value === null || value === void 0) {
|
|
8616
|
-
throw new Error("Expected value to be defined");
|
|
8617
|
-
}
|
|
8618
|
-
return value;
|
|
8619
|
-
}
|
|
8620
8894
|
var DEFAULT_SYSTEM_PROMPT = `You are a context pruning assistant. Given a conversation history and a token budget, decide which message ranges are worth keeping verbatim and which should be collapsed into summaries.
|
|
8621
8895
|
|
|
8622
8896
|
Output a JSON object with this structure:
|
|
@@ -8657,7 +8931,7 @@ function formatMessages(messages, maxChars = 8e3) {
|
|
|
8657
8931
|
const lines = [];
|
|
8658
8932
|
let used = 0;
|
|
8659
8933
|
for (let i = 0; i < messages.length; i++) {
|
|
8660
|
-
const m =
|
|
8934
|
+
const m = expectDefined(messages[i]);
|
|
8661
8935
|
const role = m.role.padEnd(10, " ");
|
|
8662
8936
|
let text;
|
|
8663
8937
|
if (typeof m.content === "string") {
|
|
@@ -8722,7 +8996,7 @@ IMPORTANT: Total conversation (${totalTokens} tokens) exceeds budget (${effectiv
|
|
|
8722
8996
|
let tokenCount = 0;
|
|
8723
8997
|
let startIdx = 0;
|
|
8724
8998
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
8725
|
-
const m =
|
|
8999
|
+
const m = expectDefined(messages[i]);
|
|
8726
9000
|
const cost = typeof m.content === "string" ? Math.ceil(m.content.length / 4) : m.content.reduce(
|
|
8727
9001
|
(acc, b) => acc + (b.type === "text" ? Math.ceil(b.text.length / 4) : Math.ceil(JSON.stringify(b).length / 4)),
|
|
8728
9002
|
0
|
|
@@ -10010,8 +10284,8 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
10010
10284
|
await saveGoal(this.goalPath, abandoned);
|
|
10011
10285
|
}
|
|
10012
10286
|
try {
|
|
10013
|
-
const { unlink:
|
|
10014
|
-
await
|
|
10287
|
+
const { unlink: unlink14 } = await import('fs/promises');
|
|
10288
|
+
await unlink14(this.goalPath);
|
|
10015
10289
|
} catch {
|
|
10016
10290
|
}
|
|
10017
10291
|
this.opts.onEternalStop?.();
|
|
@@ -10390,15 +10664,7 @@ function makeAgentSubagentRunner(opts) {
|
|
|
10390
10664
|
let budgetError = null;
|
|
10391
10665
|
const onBudgetError = (err) => {
|
|
10392
10666
|
if (err instanceof BudgetThresholdSignal) {
|
|
10393
|
-
|
|
10394
|
-
if (decision === "stop") {
|
|
10395
|
-
budgetError = new BudgetExceededError(err.kind, err.limit, err.used);
|
|
10396
|
-
aborter.abort();
|
|
10397
|
-
}
|
|
10398
|
-
}).catch(() => {
|
|
10399
|
-
budgetError = new BudgetExceededError(err.kind, err.limit, err.used);
|
|
10400
|
-
aborter.abort();
|
|
10401
|
-
});
|
|
10667
|
+
budgetError = err;
|
|
10402
10668
|
return;
|
|
10403
10669
|
}
|
|
10404
10670
|
aborter.abort();
|
|
@@ -10506,15 +10772,23 @@ function makeAgentSubagentRunner(opts) {
|
|
|
10506
10772
|
}
|
|
10507
10773
|
if (budgetError) {
|
|
10508
10774
|
if ("decision" in budgetError) {
|
|
10509
|
-
|
|
10510
|
-
|
|
10775
|
+
try {
|
|
10776
|
+
const decision = await budgetError.decision;
|
|
10777
|
+
if (decision === "stop") {
|
|
10778
|
+
budgetError = new BudgetExceededError(
|
|
10779
|
+
budgetError.kind,
|
|
10780
|
+
budgetError.limit,
|
|
10781
|
+
budgetError.used
|
|
10782
|
+
);
|
|
10783
|
+
} else {
|
|
10784
|
+
budgetError = null;
|
|
10785
|
+
}
|
|
10786
|
+
} catch {
|
|
10511
10787
|
budgetError = new BudgetExceededError(
|
|
10512
10788
|
budgetError.kind,
|
|
10513
10789
|
budgetError.limit,
|
|
10514
10790
|
budgetError.used
|
|
10515
10791
|
);
|
|
10516
|
-
} else {
|
|
10517
|
-
budgetError = null;
|
|
10518
10792
|
}
|
|
10519
10793
|
}
|
|
10520
10794
|
if (budgetError) throw budgetError;
|
|
@@ -14010,12 +14284,6 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
14010
14284
|
};
|
|
14011
14285
|
|
|
14012
14286
|
// src/execution/parallel-eternal-engine.ts
|
|
14013
|
-
function expectDefined12(value) {
|
|
14014
|
-
if (value === null || value === void 0) {
|
|
14015
|
-
throw new Error("Expected value to be defined");
|
|
14016
|
-
}
|
|
14017
|
-
return value;
|
|
14018
|
-
}
|
|
14019
14287
|
var GOAL_COMPLETE_MARKER2 = /^\s*\[goal[_\s-]?complete\]\s*$/im;
|
|
14020
14288
|
var ParallelEternalEngine = class {
|
|
14021
14289
|
constructor(opts) {
|
|
@@ -14171,7 +14439,7 @@ var ParallelEternalEngine = class {
|
|
|
14171
14439
|
// Fan-out
|
|
14172
14440
|
// -------------------------------------------------------------------------
|
|
14173
14441
|
async fanOut(goal, tasks) {
|
|
14174
|
-
const coordinator =
|
|
14442
|
+
const coordinator = expectDefined(this.coordinator);
|
|
14175
14443
|
const slotCount = Math.min(this.slots, tasks.length);
|
|
14176
14444
|
const routes = this.dispatchEnabled ? await Promise.all(
|
|
14177
14445
|
tasks.slice(0, slotCount).map(
|
|
@@ -14203,7 +14471,7 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
14203
14471
|
const routeInfo = [];
|
|
14204
14472
|
const spawnPromises = [];
|
|
14205
14473
|
for (let i = 0; i < slotCount; i++) {
|
|
14206
|
-
const task =
|
|
14474
|
+
const task = expectDefined(tasks[i]);
|
|
14207
14475
|
const route = routes[i] ?? null;
|
|
14208
14476
|
const subagentId = `parallel-${this.iterations}-${i}`;
|
|
14209
14477
|
const taskId = randomUUID();
|
|
@@ -14562,6 +14830,7 @@ var CollabSession = class extends EventEmitter {
|
|
|
14562
14830
|
settled = false;
|
|
14563
14831
|
timeoutMs;
|
|
14564
14832
|
cancelled = false;
|
|
14833
|
+
_raceResolved = false;
|
|
14565
14834
|
alerts = [];
|
|
14566
14835
|
snapshotWarnings = [];
|
|
14567
14836
|
/** Tracks tool call counts per subagent for progress-based timeout decisions. */
|
|
@@ -14658,7 +14927,7 @@ var CollabSession = class extends EventEmitter {
|
|
|
14658
14927
|
* Safe to call multiple times (idempotent after first call).
|
|
14659
14928
|
*/
|
|
14660
14929
|
cancel(reason = "Director cancelled collab session") {
|
|
14661
|
-
if (this.
|
|
14930
|
+
if (this.cancelled) return;
|
|
14662
14931
|
this.cancelled = true;
|
|
14663
14932
|
if (this._timeoutTimer) {
|
|
14664
14933
|
clearTimeout(this._timeoutTimer);
|
|
@@ -14696,6 +14965,7 @@ var CollabSession = class extends EventEmitter {
|
|
|
14696
14965
|
this.subagentIds.set("critic", criticId);
|
|
14697
14966
|
const timeout = new Promise((_, reject) => {
|
|
14698
14967
|
this._timeoutTimer = setTimeout(() => {
|
|
14968
|
+
if (this._raceResolved) return;
|
|
14699
14969
|
this.cancel("Session-level timeout reached");
|
|
14700
14970
|
reject(new Error(`CollabSession timed out after ${this.timeoutMs}ms`));
|
|
14701
14971
|
}, this.timeoutMs);
|
|
@@ -14711,6 +14981,7 @@ var CollabSession = class extends EventEmitter {
|
|
|
14711
14981
|
timeout
|
|
14712
14982
|
]);
|
|
14713
14983
|
} catch (err) {
|
|
14984
|
+
this._raceResolved = true;
|
|
14714
14985
|
if (this._timeoutTimer) {
|
|
14715
14986
|
clearTimeout(this._timeoutTimer);
|
|
14716
14987
|
this._timeoutTimer = void 0;
|
|
@@ -14725,6 +14996,7 @@ var CollabSession = class extends EventEmitter {
|
|
|
14725
14996
|
}
|
|
14726
14997
|
this.snapshotWarnings = await this.checkSnapshotFreshness();
|
|
14727
14998
|
const report = this.assembleReport();
|
|
14999
|
+
this._raceResolved = true;
|
|
14728
15000
|
this.cleanup();
|
|
14729
15001
|
this.emit("session.done", report);
|
|
14730
15002
|
return report;
|
|
@@ -18790,12 +19062,6 @@ var TaskGraphStore = class {
|
|
|
18790
19062
|
};
|
|
18791
19063
|
|
|
18792
19064
|
// src/sdd/spec-builder.ts
|
|
18793
|
-
function expectDefined13(value) {
|
|
18794
|
-
if (value === null || value === void 0) {
|
|
18795
|
-
throw new Error("Expected value to be defined");
|
|
18796
|
-
}
|
|
18797
|
-
return value;
|
|
18798
|
-
}
|
|
18799
19065
|
function buildQuestioningPrompt(session, min, max) {
|
|
18800
19066
|
const answered = session.answers.length;
|
|
18801
19067
|
const remaining = Math.max(0, min - answered);
|
|
@@ -18841,7 +19107,7 @@ function buildQuestioningPrompt(session, min, max) {
|
|
|
18841
19107
|
if (answered > 0) {
|
|
18842
19108
|
lines.push("", "**Conversation so far:**");
|
|
18843
19109
|
for (let i = 0; i < answered; i++) {
|
|
18844
|
-
const a =
|
|
19110
|
+
const a = expectDefined(session.answers[i]);
|
|
18845
19111
|
lines.push(``, `Q${i + 1}: ${a.question}`, `A${i + 1}: ${a.answer}`);
|
|
18846
19112
|
}
|
|
18847
19113
|
}
|
|
@@ -19583,12 +19849,6 @@ function truncate2(str, maxLen) {
|
|
|
19583
19849
|
}
|
|
19584
19850
|
|
|
19585
19851
|
// src/sdd/critical-path.ts
|
|
19586
|
-
function expectDefined14(value) {
|
|
19587
|
-
if (value === null || value === void 0) {
|
|
19588
|
-
throw new Error("Expected value to be defined");
|
|
19589
|
-
}
|
|
19590
|
-
return value;
|
|
19591
|
-
}
|
|
19592
19852
|
function analyzeCriticalPath(graph) {
|
|
19593
19853
|
const nodes = Array.from(graph.nodes.values());
|
|
19594
19854
|
const topoOrder = topologicalSort(graph);
|
|
@@ -19664,7 +19924,7 @@ function getTransitiveBlocked(_graph, taskId, blocksMap) {
|
|
|
19664
19924
|
const visited = /* @__PURE__ */ new Set();
|
|
19665
19925
|
const queue = [taskId];
|
|
19666
19926
|
while (queue.length > 0) {
|
|
19667
|
-
const current =
|
|
19927
|
+
const current = expectDefined(queue.shift());
|
|
19668
19928
|
const blocked = blocksMap.get(current);
|
|
19669
19929
|
if (!blocked) continue;
|
|
19670
19930
|
for (const id of blocked) {
|
|
@@ -19710,7 +19970,7 @@ function computeCriticalPath(graph, _topoOrder, blockedByMap) {
|
|
|
19710
19970
|
if (!changed) break;
|
|
19711
19971
|
}
|
|
19712
19972
|
let maxDist = 0;
|
|
19713
|
-
let maxId =
|
|
19973
|
+
let maxId = expectDefined(allIds[0]);
|
|
19714
19974
|
for (const id of allIds) {
|
|
19715
19975
|
const d = dist.get(id) ?? 0;
|
|
19716
19976
|
if (d > maxDist) {
|
|
@@ -20179,12 +20439,6 @@ var SddTaskDecomposer = class {
|
|
|
20179
20439
|
return nodes.some((n) => n.status === "blocked");
|
|
20180
20440
|
}
|
|
20181
20441
|
};
|
|
20182
|
-
function expectDefined15(value) {
|
|
20183
|
-
if (value === null || value === void 0) {
|
|
20184
|
-
throw new Error("Expected value to be defined");
|
|
20185
|
-
}
|
|
20186
|
-
return value;
|
|
20187
|
-
}
|
|
20188
20442
|
var SddParallelRun = class {
|
|
20189
20443
|
constructor(opts) {
|
|
20190
20444
|
this.opts = opts;
|
|
@@ -20333,8 +20587,8 @@ var SddParallelRun = class {
|
|
|
20333
20587
|
const successCount = results.filter((r) => r.status === "success").length;
|
|
20334
20588
|
const failCount = results.length - successCount;
|
|
20335
20589
|
for (let i = 0; i < results.length; i++) {
|
|
20336
|
-
const result =
|
|
20337
|
-
const taskId =
|
|
20590
|
+
const result = expectDefined(results[i]);
|
|
20591
|
+
const taskId = expectDefined(taskIds[i]);
|
|
20338
20592
|
if (result.status === "success") {
|
|
20339
20593
|
this.opts.tracker.updateNodeStatus(taskId, "completed");
|
|
20340
20594
|
} else {
|
|
@@ -21441,12 +21695,6 @@ var allServers = () => ({
|
|
|
21441
21695
|
"zai-vision": { ...zaiVisionServer(), enabled: false },
|
|
21442
21696
|
"minimax-vision": { ...miniMaxVisionServer(), enabled: false }
|
|
21443
21697
|
});
|
|
21444
|
-
function expectDefined16(value) {
|
|
21445
|
-
if (value === null || value === void 0) {
|
|
21446
|
-
throw new Error("Expected value to be defined");
|
|
21447
|
-
}
|
|
21448
|
-
return value;
|
|
21449
|
-
}
|
|
21450
21698
|
function parseSkillRef(input) {
|
|
21451
21699
|
const trimmed = input.trim().replace(/^https?:\/\/github\.com\//, "").replace(/\.git$/, "");
|
|
21452
21700
|
const atIdx = trimmed.indexOf("@");
|
|
@@ -21463,7 +21711,7 @@ function parseSkillRef(input) {
|
|
|
21463
21711
|
if (parts.length < 2) {
|
|
21464
21712
|
throw new Error(`Invalid skill reference "${input}". Expected format: user/repo or user/repo@ref`);
|
|
21465
21713
|
}
|
|
21466
|
-
return { owner:
|
|
21714
|
+
return { owner: expectDefined(parts[0]), repo: expectDefined(parts[1]), ref };
|
|
21467
21715
|
}
|
|
21468
21716
|
var MAX_TARBALL_SIZE = 50 * 1024 * 1024;
|
|
21469
21717
|
async function downloadGitHubTarball(parsed) {
|
|
@@ -21632,12 +21880,6 @@ var SkillManifestStore = class {
|
|
|
21632
21880
|
};
|
|
21633
21881
|
|
|
21634
21882
|
// src/skills/skill-installer.ts
|
|
21635
|
-
function expectDefined17(value) {
|
|
21636
|
-
if (value === null || value === void 0) {
|
|
21637
|
-
throw new Error("Expected value to be defined");
|
|
21638
|
-
}
|
|
21639
|
-
return value;
|
|
21640
|
-
}
|
|
21641
21883
|
var MAX_SKILL_FILE_SIZE = 100 * 1024;
|
|
21642
21884
|
var SkillInstaller = class {
|
|
21643
21885
|
opts;
|
|
@@ -21762,7 +22004,7 @@ var SkillInstaller = class {
|
|
|
21762
22004
|
bySource.get(key)?.push(entry);
|
|
21763
22005
|
}
|
|
21764
22006
|
for (const [, entries] of bySource) {
|
|
21765
|
-
const first =
|
|
22007
|
+
const first = expectDefined(entries[0]);
|
|
21766
22008
|
const scope = first.scope;
|
|
21767
22009
|
const isGlobal = scope === "user";
|
|
21768
22010
|
try {
|
|
@@ -21929,15 +22171,387 @@ async function collectFiles(dir, baseDir2) {
|
|
|
21929
22171
|
}
|
|
21930
22172
|
return results;
|
|
21931
22173
|
}
|
|
22174
|
+
var GraphMemoryBackend = class {
|
|
22175
|
+
kind = "graph";
|
|
22176
|
+
file;
|
|
22177
|
+
graphFile;
|
|
22178
|
+
// In-memory graph state — lazily loaded, saved on mutation.
|
|
22179
|
+
nodes = /* @__PURE__ */ new Map();
|
|
22180
|
+
edges = [];
|
|
22181
|
+
loadedScope = null;
|
|
22182
|
+
loaded = false;
|
|
22183
|
+
constructor(opts) {
|
|
22184
|
+
this.file = new FileMemoryBackend({ paths: opts.paths });
|
|
22185
|
+
this.graphFile = opts.graphPath ?? `${opts.paths.projectDir}/memory-graph.json`;
|
|
22186
|
+
}
|
|
22187
|
+
// ── Backend interface ──────────────────────────────────────────────
|
|
22188
|
+
async remember(scope, entry, filePath) {
|
|
22189
|
+
await this.file.remember(scope, entry, filePath);
|
|
22190
|
+
await this.loadGraph(scope);
|
|
22191
|
+
const nodeId = this.nodeId(entry);
|
|
22192
|
+
const existing = this.nodes.get(nodeId);
|
|
22193
|
+
if (existing) {
|
|
22194
|
+
existing.count++;
|
|
22195
|
+
existing.entry = entry;
|
|
22196
|
+
existing.type = entry.type;
|
|
22197
|
+
existing.tags = entry.tags;
|
|
22198
|
+
existing.priority = entry.priority;
|
|
22199
|
+
} else {
|
|
22200
|
+
this.nodes.set(nodeId, {
|
|
22201
|
+
id: nodeId,
|
|
22202
|
+
entry,
|
|
22203
|
+
firstSeen: entry.ts,
|
|
22204
|
+
count: 1,
|
|
22205
|
+
type: entry.type,
|
|
22206
|
+
tags: entry.tags,
|
|
22207
|
+
priority: entry.priority
|
|
22208
|
+
});
|
|
22209
|
+
for (const [, other] of this.nodes) {
|
|
22210
|
+
if (other.id === nodeId) continue;
|
|
22211
|
+
const sim = wordOverlap(entry.text, other.entry.text);
|
|
22212
|
+
const tagSim = sharedTags(entry.tags ?? [], other.tags ?? []);
|
|
22213
|
+
const weight = Math.max(sim, tagSim * 0.5);
|
|
22214
|
+
if (weight > 0.15) {
|
|
22215
|
+
this.edges.push({
|
|
22216
|
+
from: nodeId,
|
|
22217
|
+
to: other.id,
|
|
22218
|
+
relation: sim >= tagSim ? "similar" : "same_turn",
|
|
22219
|
+
weight,
|
|
22220
|
+
ts: entry.ts
|
|
22221
|
+
});
|
|
22222
|
+
}
|
|
22223
|
+
}
|
|
22224
|
+
}
|
|
22225
|
+
await this.saveGraph(scope);
|
|
22226
|
+
}
|
|
22227
|
+
async forget(scope, query, filePath) {
|
|
22228
|
+
const removed = await this.file.forget(scope, query, filePath);
|
|
22229
|
+
if (removed > 0) {
|
|
22230
|
+
await this.loadGraph(scope);
|
|
22231
|
+
const n = query.toLowerCase();
|
|
22232
|
+
const toRemove = [];
|
|
22233
|
+
for (const [id, node] of this.nodes) {
|
|
22234
|
+
if (node.entry.text.toLowerCase().includes(n)) {
|
|
22235
|
+
toRemove.push(id);
|
|
22236
|
+
}
|
|
22237
|
+
}
|
|
22238
|
+
for (const id of toRemove) this.nodes.delete(id);
|
|
22239
|
+
this.edges = this.edges.filter((e) => !toRemove.includes(e.from) && !toRemove.includes(e.to));
|
|
22240
|
+
await this.saveGraph(scope);
|
|
22241
|
+
}
|
|
22242
|
+
return removed;
|
|
22243
|
+
}
|
|
22244
|
+
async readAll(scope, filePath) {
|
|
22245
|
+
return this.file.readAll(scope, filePath);
|
|
22246
|
+
}
|
|
22247
|
+
async list(scope, filePath, limit) {
|
|
22248
|
+
await this.loadGraph(scope);
|
|
22249
|
+
const fileEntries = await this.file.list(scope, filePath);
|
|
22250
|
+
const nodeMap = new Map(this.nodes.entries());
|
|
22251
|
+
const enriched = fileEntries.map((fe) => {
|
|
22252
|
+
const nodeId = this.nodeId(fe);
|
|
22253
|
+
const node = nodeMap.get(nodeId);
|
|
22254
|
+
if (node) {
|
|
22255
|
+
return {
|
|
22256
|
+
...fe,
|
|
22257
|
+
type: node.type ?? fe.type,
|
|
22258
|
+
tags: node.tags ?? fe.tags,
|
|
22259
|
+
priority: node.priority ?? fe.priority
|
|
22260
|
+
};
|
|
22261
|
+
}
|
|
22262
|
+
return fe;
|
|
22263
|
+
});
|
|
22264
|
+
const fileIds = new Set(fileEntries.map((e) => this.nodeId(e)));
|
|
22265
|
+
for (const [id, node] of this.nodes) {
|
|
22266
|
+
if (!fileIds.has(id)) {
|
|
22267
|
+
enriched.push(node.entry);
|
|
22268
|
+
}
|
|
22269
|
+
}
|
|
22270
|
+
enriched.sort((a, b) => b.ts.localeCompare(a.ts));
|
|
22271
|
+
return limit ? enriched.slice(0, limit) : enriched;
|
|
22272
|
+
}
|
|
22273
|
+
async search(scope, query, filePath, limit) {
|
|
22274
|
+
await this.loadGraph(scope);
|
|
22275
|
+
const needle = query.toLowerCase().split(/\s+/);
|
|
22276
|
+
const all = await this.list(scope, filePath);
|
|
22277
|
+
const scored = all.map((entry) => {
|
|
22278
|
+
const words = entry.text.toLowerCase().split(/\s+/);
|
|
22279
|
+
let score = 0;
|
|
22280
|
+
for (const n of needle) {
|
|
22281
|
+
if (words.some((w) => w.includes(n))) score += 1;
|
|
22282
|
+
if (entry.tags?.some((t2) => t2.toLowerCase().includes(n))) score += 2;
|
|
22283
|
+
}
|
|
22284
|
+
const node = this.nodes.get(this.nodeId(entry));
|
|
22285
|
+
if (node) {
|
|
22286
|
+
if (node.priority === "critical") score += 3;
|
|
22287
|
+
else if (node.priority === "high") score += 2;
|
|
22288
|
+
score += node.count * 0.5;
|
|
22289
|
+
}
|
|
22290
|
+
return { entry, score };
|
|
22291
|
+
});
|
|
22292
|
+
scored.sort((a, b) => b.score - a.score);
|
|
22293
|
+
const matched = scored.filter((s) => s.score > 0).map((s) => s.entry);
|
|
22294
|
+
return limit ? matched.slice(0, limit) : matched;
|
|
22295
|
+
}
|
|
22296
|
+
async clear(scope, filePath) {
|
|
22297
|
+
await this.file.clear(scope, filePath);
|
|
22298
|
+
this.nodes.clear();
|
|
22299
|
+
this.edges = [];
|
|
22300
|
+
this.loadedScope = scope;
|
|
22301
|
+
this.loaded = true;
|
|
22302
|
+
try {
|
|
22303
|
+
await fsp3.unlink(this.graphFile);
|
|
22304
|
+
} catch {
|
|
22305
|
+
}
|
|
22306
|
+
}
|
|
22307
|
+
async consolidate(scope, filePath) {
|
|
22308
|
+
return this.file.consolidate(scope, filePath);
|
|
22309
|
+
}
|
|
22310
|
+
// ── Graph-specific queries ─────────────────────────────────────────
|
|
22311
|
+
/**
|
|
22312
|
+
* Find memories related to the given entry, ordered by edge weight.
|
|
22313
|
+
*/
|
|
22314
|
+
async findRelated(scope, _filePath, entryText, limit = 5) {
|
|
22315
|
+
await this.loadGraph(scope);
|
|
22316
|
+
const targetId = this.nodeId({ scope, text: entryText, ts: "" });
|
|
22317
|
+
const related = this.edges.filter((e) => e.from === targetId || e.to === targetId).sort((a, b) => b.weight - a.weight).slice(0, limit);
|
|
22318
|
+
const result = [];
|
|
22319
|
+
for (const edge of related) {
|
|
22320
|
+
const otherId = edge.from === targetId ? edge.to : edge.from;
|
|
22321
|
+
const node = this.nodes.get(otherId);
|
|
22322
|
+
if (node) result.push(node.entry);
|
|
22323
|
+
}
|
|
22324
|
+
return result;
|
|
22325
|
+
}
|
|
22326
|
+
/**
|
|
22327
|
+
* Get all edges for visualization or traversal.
|
|
22328
|
+
*/
|
|
22329
|
+
getGraph() {
|
|
22330
|
+
return {
|
|
22331
|
+
nodes: [...this.nodes.values()],
|
|
22332
|
+
edges: [...this.edges]
|
|
22333
|
+
};
|
|
22334
|
+
}
|
|
22335
|
+
// ── Persistence ────────────────────────────────────────────────────
|
|
22336
|
+
nodeId(entry) {
|
|
22337
|
+
const norm = entry.text.toLowerCase().trim().replace(/\s+/g, " ");
|
|
22338
|
+
return `${entry.scope ?? "mem"}::${simpleHash(norm)}`;
|
|
22339
|
+
}
|
|
22340
|
+
async loadGraph(scope) {
|
|
22341
|
+
if (this.loaded && this.loadedScope === scope) return;
|
|
22342
|
+
try {
|
|
22343
|
+
const raw = await fsp3.readFile(this.graphFile, "utf8");
|
|
22344
|
+
const data = JSON.parse(raw);
|
|
22345
|
+
this.nodes = new Map(data.nodes);
|
|
22346
|
+
this.edges = data.edges;
|
|
22347
|
+
} catch {
|
|
22348
|
+
this.nodes = /* @__PURE__ */ new Map();
|
|
22349
|
+
this.edges = [];
|
|
22350
|
+
}
|
|
22351
|
+
this.loadedScope = scope;
|
|
22352
|
+
this.loaded = true;
|
|
22353
|
+
}
|
|
22354
|
+
async saveGraph(scope) {
|
|
22355
|
+
this.loadedScope = scope;
|
|
22356
|
+
this.loaded = true;
|
|
22357
|
+
try {
|
|
22358
|
+
const data = {
|
|
22359
|
+
nodes: [...this.nodes.entries()],
|
|
22360
|
+
edges: this.edges
|
|
22361
|
+
};
|
|
22362
|
+
await fsp3.mkdir(
|
|
22363
|
+
this.graphFile.substring(0, this.graphFile.lastIndexOf("/")),
|
|
22364
|
+
{ recursive: true }
|
|
22365
|
+
);
|
|
22366
|
+
const tmp = `${this.graphFile}.tmp`;
|
|
22367
|
+
await fsp3.writeFile(tmp, JSON.stringify(data));
|
|
22368
|
+
await fsp3.rename(tmp, this.graphFile);
|
|
22369
|
+
} catch {
|
|
22370
|
+
}
|
|
22371
|
+
}
|
|
22372
|
+
};
|
|
22373
|
+
function wordOverlap(a, b) {
|
|
22374
|
+
const wordsA = new Set(a.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
|
|
22375
|
+
const wordsB = new Set(b.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
|
|
22376
|
+
if (wordsA.size === 0 || wordsB.size === 0) return 0;
|
|
22377
|
+
let intersection = 0;
|
|
22378
|
+
for (const w of wordsA) {
|
|
22379
|
+
if (wordsB.has(w)) intersection++;
|
|
22380
|
+
}
|
|
22381
|
+
return intersection / Math.max(wordsA.size, wordsB.size);
|
|
22382
|
+
}
|
|
22383
|
+
function sharedTags(a, b) {
|
|
22384
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
22385
|
+
const setB = new Set(b);
|
|
22386
|
+
let shared = 0;
|
|
22387
|
+
for (const t2 of a) if (setB.has(t2)) shared++;
|
|
22388
|
+
return shared / Math.max(a.length, b.length);
|
|
22389
|
+
}
|
|
22390
|
+
function simpleHash(s) {
|
|
22391
|
+
let h = 0;
|
|
22392
|
+
for (let i = 0; i < s.length; i++) {
|
|
22393
|
+
h = (h << 5) - h + s.charCodeAt(i) | 0;
|
|
22394
|
+
}
|
|
22395
|
+
return Math.abs(h).toString(36);
|
|
22396
|
+
}
|
|
22397
|
+
|
|
22398
|
+
// src/storage/memory-consolidator.ts
|
|
22399
|
+
function buildConsolidationPrompt(finalText, iterations, existingEntries) {
|
|
22400
|
+
const existingBlock = existingEntries.length > 0 ? `
|
|
22401
|
+
|
|
22402
|
+
Existing memory entries:
|
|
22403
|
+
${existingEntries.map((e) => `- [${e.ts.slice(0, 10)}] ${e.text}`).join("\n")}` : "";
|
|
22404
|
+
return `You are a memory consolidator. Review the following session summary and decide what key facts, conventions, decisions, or learnings should be persisted to long-term memory.
|
|
22405
|
+
|
|
22406
|
+
Session summary (${iterations} iterations):
|
|
22407
|
+
${finalText.slice(0, 3e3)}${existingBlock}
|
|
22408
|
+
|
|
22409
|
+
Return a JSON object with an "operations" array. Each operation must have an "action" field:
|
|
22410
|
+
- "add": create a new memory entry. Include "text", and optionally "type", "tags", "priority".
|
|
22411
|
+
- "edit": replace an existing entry. Include "query" (to match) and "text" (replacement).
|
|
22412
|
+
- "delete": remove an entry. Include "query" (to match).
|
|
22413
|
+
|
|
22414
|
+
Memory types:
|
|
22415
|
+
- "fact": Objective truth about the project (e.g. "uses pnpm workspaces")
|
|
22416
|
+
- "decision": A choice that was made (e.g. "decided to use biome over eslint")
|
|
22417
|
+
- "convention": A recurring pattern or standard (e.g. "commit messages use conventional format")
|
|
22418
|
+
- "preference": User or team preference (e.g. "prefers short variable names")
|
|
22419
|
+
- "reference": Pointer to a file or location (e.g. "auth logic in packages/core/src/auth/")
|
|
22420
|
+
- "anti_pattern": Something to avoid (e.g. "never use any in TypeScript")
|
|
22421
|
+
|
|
22422
|
+
Priority levels:
|
|
22423
|
+
- "critical": Must always be known (e.g. security constraints)
|
|
22424
|
+
- "high": Important for most tasks
|
|
22425
|
+
- "medium": Useful context
|
|
22426
|
+
- "low": Nice to know
|
|
22427
|
+
|
|
22428
|
+
Rules:
|
|
22429
|
+
- Only persist facts likely useful across multiple future sessions.
|
|
22430
|
+
- Do NOT persist task progress, temporary state, or one-off observations.
|
|
22431
|
+
- Prefer "add" over "edit" unless the existing entry is clearly outdated.
|
|
22432
|
+
- Assign a type and priority to every "add" operation.
|
|
22433
|
+
- Use 1-3 hashtag tags for each entry (e.g. #typescript #build).
|
|
22434
|
+
- Be concise \u2014 each memory entry should be one clear sentence.
|
|
22435
|
+
|
|
22436
|
+
Return ONLY valid JSON, no markdown, no explanation:
|
|
22437
|
+
{
|
|
22438
|
+
"operations": [
|
|
22439
|
+
{
|
|
22440
|
+
"action": "add",
|
|
22441
|
+
"text": "Project uses pnpm workspaces with TypeScript strict mode",
|
|
22442
|
+
"type": "convention",
|
|
22443
|
+
"priority": "high",
|
|
22444
|
+
"tags": ["pnpm", "typescript", "build"]
|
|
22445
|
+
},
|
|
22446
|
+
{
|
|
22447
|
+
"action": "edit",
|
|
22448
|
+
"query": "pnpm",
|
|
22449
|
+
"text": "Project uses pnpm v9+ with ESM-only modules",
|
|
22450
|
+
"type": "fact",
|
|
22451
|
+
"priority": "medium"
|
|
22452
|
+
},
|
|
22453
|
+
{ "action": "delete", "query": "outdated convention" }
|
|
22454
|
+
]
|
|
22455
|
+
}`;
|
|
22456
|
+
}
|
|
22457
|
+
var SessionMemoryConsolidator = class {
|
|
22458
|
+
name = "session-memory-consolidator";
|
|
22459
|
+
owner = "core";
|
|
22460
|
+
memoryStore;
|
|
22461
|
+
provider;
|
|
22462
|
+
model;
|
|
22463
|
+
minIterations;
|
|
22464
|
+
maxExistingEntries;
|
|
22465
|
+
constructor(opts) {
|
|
22466
|
+
this.memoryStore = opts.memoryStore;
|
|
22467
|
+
this.provider = opts.provider;
|
|
22468
|
+
this.model = opts.model;
|
|
22469
|
+
this.minIterations = opts.minIterations ?? 2;
|
|
22470
|
+
this.maxExistingEntries = opts.maxExistingEntries ?? 15;
|
|
22471
|
+
}
|
|
22472
|
+
afterRun = async (ctx, result) => {
|
|
22473
|
+
if (result.status !== "done") return;
|
|
22474
|
+
if (!result.finalText || result.finalText.trim().length < 20) return;
|
|
22475
|
+
if (result.iterations < this.minIterations) return;
|
|
22476
|
+
const provider = this.provider ?? ctx.provider;
|
|
22477
|
+
if (!provider || !provider.complete) return;
|
|
22478
|
+
try {
|
|
22479
|
+
const existingEntries = await this.memoryStore.list("project-memory", this.maxExistingEntries);
|
|
22480
|
+
const prompt = buildConsolidationPrompt(
|
|
22481
|
+
result.finalText,
|
|
22482
|
+
result.iterations,
|
|
22483
|
+
existingEntries
|
|
22484
|
+
);
|
|
22485
|
+
const signal = AbortSignal.timeout(15e3);
|
|
22486
|
+
const response = await provider.complete(
|
|
22487
|
+
{
|
|
22488
|
+
model: this.model ?? ctx.model,
|
|
22489
|
+
system: [{ type: "text", text: prompt }],
|
|
22490
|
+
messages: [
|
|
22491
|
+
{ role: "user", content: "Review the session and return memory operations as JSON." }
|
|
22492
|
+
],
|
|
22493
|
+
maxTokens: 500
|
|
22494
|
+
},
|
|
22495
|
+
{ signal }
|
|
22496
|
+
);
|
|
22497
|
+
const text = response.content.filter((b) => b.type === "text").map((b) => b.text).join("").trim();
|
|
22498
|
+
if (!text) return;
|
|
22499
|
+
const jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
22500
|
+
if (!jsonMatch) return;
|
|
22501
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
22502
|
+
if (!Array.isArray(parsed.operations) || parsed.operations.length === 0) return;
|
|
22503
|
+
let added = 0;
|
|
22504
|
+
let edited = 0;
|
|
22505
|
+
let deleted = 0;
|
|
22506
|
+
for (const op of parsed.operations) {
|
|
22507
|
+
switch (op.action) {
|
|
22508
|
+
case "add": {
|
|
22509
|
+
if (op.text && op.text.trim()) {
|
|
22510
|
+
await this.memoryStore.remember(op.text.trim(), void 0, {
|
|
22511
|
+
type: op.type,
|
|
22512
|
+
tags: op.tags,
|
|
22513
|
+
priority: op.priority
|
|
22514
|
+
});
|
|
22515
|
+
added++;
|
|
22516
|
+
}
|
|
22517
|
+
break;
|
|
22518
|
+
}
|
|
22519
|
+
case "edit": {
|
|
22520
|
+
if (op.query && op.text && op.text.trim()) {
|
|
22521
|
+
await this.memoryStore.forget(op.query);
|
|
22522
|
+
await this.memoryStore.remember(op.text.trim(), void 0, {
|
|
22523
|
+
type: op.type,
|
|
22524
|
+
tags: op.tags,
|
|
22525
|
+
priority: op.priority
|
|
22526
|
+
});
|
|
22527
|
+
edited++;
|
|
22528
|
+
}
|
|
22529
|
+
break;
|
|
22530
|
+
}
|
|
22531
|
+
case "delete": {
|
|
22532
|
+
if (op.query) {
|
|
22533
|
+
const n = await this.memoryStore.forget(op.query);
|
|
22534
|
+
deleted += n;
|
|
22535
|
+
}
|
|
22536
|
+
break;
|
|
22537
|
+
}
|
|
22538
|
+
}
|
|
22539
|
+
}
|
|
22540
|
+
if (added > 0 || edited > 0 || deleted > 0) {
|
|
22541
|
+
const parts = [];
|
|
22542
|
+
if (added) parts.push(`${added} added`);
|
|
22543
|
+
if (edited) parts.push(`${edited} edited`);
|
|
22544
|
+
if (deleted) parts.push(`${deleted} deleted`);
|
|
22545
|
+
process.stderr.write(`[memory] Session consolidation: ${parts.join(", ")}
|
|
22546
|
+
`);
|
|
22547
|
+
}
|
|
22548
|
+
} catch {
|
|
22549
|
+
}
|
|
22550
|
+
};
|
|
22551
|
+
};
|
|
21932
22552
|
|
|
21933
22553
|
// src/storage/annotations-store.ts
|
|
21934
22554
|
init_atomic_write();
|
|
21935
|
-
function expectDefined18(value) {
|
|
21936
|
-
if (value === null || value === void 0) {
|
|
21937
|
-
throw new Error("Expected value to be defined");
|
|
21938
|
-
}
|
|
21939
|
-
return value;
|
|
21940
|
-
}
|
|
21941
22555
|
var FILE_VERSION = 1;
|
|
21942
22556
|
var MAX_TEXT_LENGTH = 2e3;
|
|
21943
22557
|
var MAX_ANNOTATIONS = 1e3;
|
|
@@ -22030,7 +22644,7 @@ var AnnotationsStore = class {
|
|
|
22030
22644
|
return;
|
|
22031
22645
|
}
|
|
22032
22646
|
const next = {
|
|
22033
|
-
...
|
|
22647
|
+
...expectDefined(all[idx]),
|
|
22034
22648
|
resolved: true,
|
|
22035
22649
|
resolvedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22036
22650
|
resolvedBy: input.resolvedBy
|
|
@@ -22268,12 +22882,6 @@ var ReplayLogStore = class {
|
|
|
22268
22882
|
return next;
|
|
22269
22883
|
}
|
|
22270
22884
|
};
|
|
22271
|
-
function expectDefined19(value) {
|
|
22272
|
-
if (value === null || value === void 0) {
|
|
22273
|
-
throw new Error("Expected value to be defined");
|
|
22274
|
-
}
|
|
22275
|
-
return value;
|
|
22276
|
-
}
|
|
22277
22885
|
var SessionRecovery = class {
|
|
22278
22886
|
constructor(dir) {
|
|
22279
22887
|
this.dir = dir;
|
|
@@ -22314,7 +22922,7 @@ var SessionRecovery = class {
|
|
|
22314
22922
|
const lines = raw.split("\n").filter((l) => l.trim());
|
|
22315
22923
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
22316
22924
|
try {
|
|
22317
|
-
const ev = JSON.parse(
|
|
22925
|
+
const ev = JSON.parse(expectDefined(lines[i]));
|
|
22318
22926
|
if (ev.type === "in_flight_start") {
|
|
22319
22927
|
return {
|
|
22320
22928
|
sessionId,
|
|
@@ -22367,12 +22975,12 @@ var SessionRecovery = class {
|
|
|
22367
22975
|
let lastCheckpointIdx = -1;
|
|
22368
22976
|
for (let i = 0; i < events.length; i++) {
|
|
22369
22977
|
if (events[i]?.type === "checkpoint") {
|
|
22370
|
-
lastCheckpoint =
|
|
22978
|
+
lastCheckpoint = expectDefined(events[i]);
|
|
22371
22979
|
lastCheckpointIdx = i;
|
|
22372
22980
|
}
|
|
22373
22981
|
}
|
|
22374
22982
|
const pendingEvents = lastCheckpointIdx >= 0 ? events.slice(lastCheckpointIdx + 1) : events;
|
|
22375
|
-
const lastEv =
|
|
22983
|
+
const lastEv = expectDefined(events[events.length - 1]);
|
|
22376
22984
|
const inFlightStart = lastEv.type === "in_flight_start" ? lastEv : null;
|
|
22377
22985
|
const context = inFlightStart && inFlightStart.type === "in_flight_start" ? inFlightStart.context : null;
|
|
22378
22986
|
return {
|
|
@@ -22418,12 +23026,6 @@ var SessionRecovery = class {
|
|
|
22418
23026
|
|
|
22419
23027
|
// src/storage/tool-audit-log.ts
|
|
22420
23028
|
init_atomic_write();
|
|
22421
|
-
function expectDefined20(value) {
|
|
22422
|
-
if (value === null || value === void 0) {
|
|
22423
|
-
throw new Error("Expected value to be defined");
|
|
22424
|
-
}
|
|
22425
|
-
return value;
|
|
22426
|
-
}
|
|
22427
23029
|
var GENESIS_PREV = "0".repeat(64);
|
|
22428
23030
|
var DEFAULT_FSYNC_EVERY = 100;
|
|
22429
23031
|
var ToolAuditLog = class {
|
|
@@ -22504,7 +23106,7 @@ var ToolAuditLog = class {
|
|
|
22504
23106
|
}
|
|
22505
23107
|
let prevHash = GENESIS_PREV;
|
|
22506
23108
|
for (let i = 0; i < entries.length; i++) {
|
|
22507
|
-
const e =
|
|
23109
|
+
const e = expectDefined(entries[i]);
|
|
22508
23110
|
if (e.prevHash !== prevHash) {
|
|
22509
23111
|
return {
|
|
22510
23112
|
ok: false,
|
|
@@ -22624,12 +23226,6 @@ function sortKeys2(value) {
|
|
|
22624
23226
|
|
|
22625
23227
|
// src/storage/session-rewinder.ts
|
|
22626
23228
|
init_atomic_write();
|
|
22627
|
-
function expectDefined21(value) {
|
|
22628
|
-
if (value === null || value === void 0) {
|
|
22629
|
-
throw new Error("Expected value to be defined");
|
|
22630
|
-
}
|
|
22631
|
-
return value;
|
|
22632
|
-
}
|
|
22633
23229
|
var DefaultSessionRewinder = class {
|
|
22634
23230
|
constructor(sessionsDir, projectRoot) {
|
|
22635
23231
|
this.sessionsDir = sessionsDir;
|
|
@@ -22668,7 +23264,7 @@ var DefaultSessionRewinder = class {
|
|
|
22668
23264
|
const events = parseEvents(raw);
|
|
22669
23265
|
let targetIdx = -1;
|
|
22670
23266
|
for (let i = 0; i < events.length; i++) {
|
|
22671
|
-
const event =
|
|
23267
|
+
const event = expectDefined(events[i]);
|
|
22672
23268
|
if (event.type === "checkpoint") {
|
|
22673
23269
|
const checkpointEvent = event;
|
|
22674
23270
|
if (checkpointEvent.promptIndex === checkpointIndex) {
|
|
@@ -22682,7 +23278,7 @@ var DefaultSessionRewinder = class {
|
|
|
22682
23278
|
}
|
|
22683
23279
|
const snapshotsToRevert = [];
|
|
22684
23280
|
for (let i = targetIdx + 1; i < events.length; i++) {
|
|
22685
|
-
const event =
|
|
23281
|
+
const event = expectDefined(events[i]);
|
|
22686
23282
|
if (event.type === "checkpoint") {
|
|
22687
23283
|
break;
|
|
22688
23284
|
}
|
|
@@ -22864,12 +23460,6 @@ var DefaultPromptStore = class {
|
|
|
22864
23460
|
};
|
|
22865
23461
|
}
|
|
22866
23462
|
};
|
|
22867
|
-
function expectDefined22(value) {
|
|
22868
|
-
if (value === null || value === void 0) {
|
|
22869
|
-
throw new Error("Expected value to be defined");
|
|
22870
|
-
}
|
|
22871
|
-
return value;
|
|
22872
|
-
}
|
|
22873
23463
|
var ALL_SYNC_CATEGORIES = ["settings", "skills", "prompts", "memory", "history"];
|
|
22874
23464
|
var CloudSync = class {
|
|
22875
23465
|
constructor(paths, getConfig, setConfig) {
|
|
@@ -22912,8 +23502,8 @@ var CloudSync = class {
|
|
|
22912
23502
|
const cfg = this.getConfig();
|
|
22913
23503
|
if (!cfg?.enabled) return { ok: false, action: "push", categories: [], message: "Not enabled." };
|
|
22914
23504
|
const parts = cfg.repo.split("/");
|
|
22915
|
-
const owner =
|
|
22916
|
-
const repoName =
|
|
23505
|
+
const owner = expectDefined(parts[0]);
|
|
23506
|
+
const repoName = expectDefined(parts[1]);
|
|
22917
23507
|
const branch = "main";
|
|
22918
23508
|
const baseTreeSha = this.state?.sha;
|
|
22919
23509
|
const { treeEntries, rev } = await this.buildLocalTree(cfg.categories);
|
|
@@ -22965,8 +23555,8 @@ var CloudSync = class {
|
|
|
22965
23555
|
const cfg = this.getConfig();
|
|
22966
23556
|
if (!cfg?.enabled) return { ok: false, action: "pull", categories: [], message: "Not enabled." };
|
|
22967
23557
|
const pullParts = cfg.repo.split("/");
|
|
22968
|
-
const owner =
|
|
22969
|
-
const repoName =
|
|
23558
|
+
const owner = expectDefined(pullParts[0]);
|
|
23559
|
+
const repoName = expectDefined(pullParts[1]);
|
|
22970
23560
|
const branchData = await this.getRef(token, owner, repoName, "main");
|
|
22971
23561
|
const currentSha = branchData.object.sha;
|
|
22972
23562
|
const commitData = await this.getCommit(token, owner, repoName, currentSha);
|
|
@@ -24064,8 +24654,8 @@ var ReportGenerator = class {
|
|
|
24064
24654
|
try {
|
|
24065
24655
|
await stat(this.options.outputDir);
|
|
24066
24656
|
} catch {
|
|
24067
|
-
const { mkdir:
|
|
24068
|
-
await
|
|
24657
|
+
const { mkdir: mkdir17 } = await import('fs/promises');
|
|
24658
|
+
await mkdir17(this.options.outputDir, { recursive: true });
|
|
24069
24659
|
}
|
|
24070
24660
|
}
|
|
24071
24661
|
generateMarkdown(result) {
|
|
@@ -24312,12 +24902,6 @@ var defaultGitignoreUpdater = new GitignoreUpdater();
|
|
|
24312
24902
|
|
|
24313
24903
|
// src/security-scanner/orchestrator.ts
|
|
24314
24904
|
init_atomic_write();
|
|
24315
|
-
function expectDefined23(value) {
|
|
24316
|
-
if (value === null || value === void 0) {
|
|
24317
|
-
throw new Error("Expected value to be defined");
|
|
24318
|
-
}
|
|
24319
|
-
return value;
|
|
24320
|
-
}
|
|
24321
24905
|
var SecurityScannerOrchestrator = class {
|
|
24322
24906
|
constructor(retryPolicy, errorHandler) {
|
|
24323
24907
|
this.retryPolicy = retryPolicy;
|
|
@@ -24367,7 +24951,7 @@ var SecurityScannerOrchestrator = class {
|
|
|
24367
24951
|
if (detectionResult.detectedStacks.length === 0) {
|
|
24368
24952
|
throw new Error(`No supported tech stack detected in ${projectRoot}`);
|
|
24369
24953
|
}
|
|
24370
|
-
const techStack =
|
|
24954
|
+
const techStack = expectDefined(detectionResult.detectedStacks[0]);
|
|
24371
24955
|
const generatedSkill = await this.generateSkillLLM(provider, model, projectRoot, techStack);
|
|
24372
24956
|
const scanResult = await this.scanWithLLM(provider, model, projectRoot, generatedSkill, techStack, options);
|
|
24373
24957
|
const synthesizedReport = await this.synthesizeReportLLM(provider, model, projectRoot, techStack, scanResult);
|
|
@@ -24448,7 +25032,7 @@ Return ONLY the JSON object, no markdown, no explanation.`;
|
|
|
24448
25032
|
const text = response.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
24449
25033
|
const jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
24450
25034
|
if (jsonMatch) {
|
|
24451
|
-
const sanitized = sanitizeJsonString(
|
|
25035
|
+
const sanitized = sanitizeJsonString(expectDefined(jsonMatch[0])) || expectDefined(jsonMatch[0]);
|
|
24452
25036
|
const skillData = JSON.parse(sanitized);
|
|
24453
25037
|
return {
|
|
24454
25038
|
name: skillData.name || `security-scanner-${techStack.stack}`,
|
|
@@ -24568,7 +25152,7 @@ Return ONLY the JSON array. If no issues found, return [].`;
|
|
|
24568
25152
|
const text = response.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
24569
25153
|
const jsonMatch = text.match(/\[[\s\S]*\]/);
|
|
24570
25154
|
if (jsonMatch) {
|
|
24571
|
-
const sanitized = sanitizeJsonString(
|
|
25155
|
+
const sanitized = sanitizeJsonString(expectDefined(jsonMatch[0])) || expectDefined(jsonMatch[0]);
|
|
24572
25156
|
const parsed = JSON.parse(sanitized);
|
|
24573
25157
|
return parsed.map((item, idx) => ({
|
|
24574
25158
|
id: `llm-finding-${idx}-${Date.now()}`,
|
|
@@ -24808,7 +25392,7 @@ ${dirs.join(", ")}`);
|
|
|
24808
25392
|
if (detectionResult.detectedStacks.length === 0) {
|
|
24809
25393
|
throw new Error(`No supported tech stack detected in ${projectRoot}`);
|
|
24810
25394
|
}
|
|
24811
|
-
const techStack =
|
|
25395
|
+
const techStack = expectDefined(detectionResult.detectedStacks[0]);
|
|
24812
25396
|
return {
|
|
24813
25397
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24814
25398
|
projectRoot,
|
|
@@ -24997,16 +25581,16 @@ Use \`/security report <number>\` to view a specific report.` };
|
|
|
24997
25581
|
}
|
|
24998
25582
|
const index = Number.parseInt(reportId, 10) - 1;
|
|
24999
25583
|
if (!Number.isNaN(index) && reports[index]) {
|
|
25000
|
-
const { readFile:
|
|
25001
|
-
const content = await
|
|
25584
|
+
const { readFile: readFile39 } = await import('fs/promises');
|
|
25585
|
+
const content = await readFile39(join(reportsDir, reports[index]), "utf-8");
|
|
25002
25586
|
return { message: `# Security Report
|
|
25003
25587
|
|
|
25004
25588
|
${content}` };
|
|
25005
25589
|
}
|
|
25006
25590
|
const match = reports.find((r) => r.includes(reportId));
|
|
25007
25591
|
if (match) {
|
|
25008
|
-
const { readFile:
|
|
25009
|
-
const content = await
|
|
25592
|
+
const { readFile: readFile39 } = await import('fs/promises');
|
|
25593
|
+
const content = await readFile39(join(reportsDir, match), "utf-8");
|
|
25010
25594
|
return { message: `# Security Report
|
|
25011
25595
|
|
|
25012
25596
|
${content}` };
|
|
@@ -25416,12 +26000,6 @@ var FleetManager = class {
|
|
|
25416
26000
|
this.usage.dispose();
|
|
25417
26001
|
}
|
|
25418
26002
|
};
|
|
25419
|
-
function expectDefined24(value) {
|
|
25420
|
-
if (value === null || value === void 0) {
|
|
25421
|
-
throw new Error("Expected value to be defined");
|
|
25422
|
-
}
|
|
25423
|
-
return value;
|
|
25424
|
-
}
|
|
25425
26003
|
function createMcpControlTool(opts) {
|
|
25426
26004
|
const { getConfig, configPath, registry } = opts;
|
|
25427
26005
|
const inputSchema = {
|
|
@@ -25573,7 +26151,7 @@ async function runDisable(name, deps) {
|
|
|
25573
26151
|
const mcpServers = {
|
|
25574
26152
|
...full.mcpServers ?? {}
|
|
25575
26153
|
};
|
|
25576
|
-
const existing =
|
|
26154
|
+
const existing = expectDefined(mcpServers[name]);
|
|
25577
26155
|
mcpServers[name] = { ...existing, enabled: false };
|
|
25578
26156
|
full.mcpServers = mcpServers;
|
|
25579
26157
|
await writeConfig(deps.configPath, full);
|
|
@@ -25644,12 +26222,6 @@ function badge(state) {
|
|
|
25644
26222
|
}
|
|
25645
26223
|
|
|
25646
26224
|
// src/extension/registry.ts
|
|
25647
|
-
function expectDefined25(value) {
|
|
25648
|
-
if (value === null || value === void 0) {
|
|
25649
|
-
throw new Error("Expected value to be defined");
|
|
25650
|
-
}
|
|
25651
|
-
return value;
|
|
25652
|
-
}
|
|
25653
26225
|
var ExtensionRegistry = class {
|
|
25654
26226
|
extensions = [];
|
|
25655
26227
|
promptContributors = [];
|
|
@@ -25815,7 +26387,7 @@ var ExtensionRegistry = class {
|
|
|
25815
26387
|
* default runner, each subsequent wrapper wraps the previous.
|
|
25816
26388
|
*/
|
|
25817
26389
|
wrapProviderRunner(inner) {
|
|
25818
|
-
const wrappers = this.extensions.filter((e) => e.wrapProviderRunner).map((e) => ({ name: e.name, wrap:
|
|
26390
|
+
const wrappers = this.extensions.filter((e) => e.wrapProviderRunner).map((e) => ({ name: e.name, wrap: expectDefined(e.wrapProviderRunner) }));
|
|
25819
26391
|
if (wrappers.length === 0) return inner;
|
|
25820
26392
|
let composed = inner;
|
|
25821
26393
|
for (let i = wrappers.length - 1; i >= 0; i--) {
|
|
@@ -26832,6 +27404,7 @@ async function bootConfig(options = {}) {
|
|
|
26832
27404
|
await fsp3.mkdir(wpaths.projectDir, { recursive: true });
|
|
26833
27405
|
await fsp3.mkdir(wpaths.projectSessions, { recursive: true });
|
|
26834
27406
|
await writeProjectMeta(wpaths, projectRoot);
|
|
27407
|
+
await ensureGitignore(projectRoot);
|
|
26835
27408
|
cleanupStaleProjects(wpaths).catch(() => {
|
|
26836
27409
|
});
|
|
26837
27410
|
const vault = new DefaultSecretVault({ keyFile: wpaths.secretsKey });
|
|
@@ -26907,6 +27480,22 @@ async function writeProjectMeta(paths, projectRoot) {
|
|
|
26907
27480
|
} catch {
|
|
26908
27481
|
}
|
|
26909
27482
|
}
|
|
27483
|
+
var GITIGNORE_ENTRY = ".wrongstack/\n";
|
|
27484
|
+
async function ensureGitignore(projectRoot) {
|
|
27485
|
+
const gitignorePath = path6.join(projectRoot, ".gitignore");
|
|
27486
|
+
try {
|
|
27487
|
+
let content = "";
|
|
27488
|
+
try {
|
|
27489
|
+
content = await fsp3.readFile(gitignorePath, "utf8");
|
|
27490
|
+
} catch {
|
|
27491
|
+
}
|
|
27492
|
+
if (!content.includes(".wrongstack")) {
|
|
27493
|
+
const updated = content ? content.endsWith("\n") ? content + GITIGNORE_ENTRY : content + "\n" + GITIGNORE_ENTRY : GITIGNORE_ENTRY;
|
|
27494
|
+
await fsp3.writeFile(gitignorePath, updated, "utf8");
|
|
27495
|
+
}
|
|
27496
|
+
} catch {
|
|
27497
|
+
}
|
|
27498
|
+
}
|
|
26910
27499
|
async function cleanupStaleProjects(wpaths) {
|
|
26911
27500
|
const projectsRoot = path6.dirname(wpaths.projectDir);
|
|
26912
27501
|
let entries;
|
|
@@ -27344,7 +27933,10 @@ var DefaultSystemPromptBuilder = class {
|
|
|
27344
27933
|
skillCache;
|
|
27345
27934
|
/** Cached full skill bodies (after frontmatter), built once per session. */
|
|
27346
27935
|
skillBodyCache;
|
|
27936
|
+
/** Tools from last build — used for memory relevance scoring. */
|
|
27937
|
+
_lastBuildTools;
|
|
27347
27938
|
async build(ctx) {
|
|
27939
|
+
this._lastBuildTools = ctx.tools;
|
|
27348
27940
|
if (this.opts.skillLoader && !this.skillCache) {
|
|
27349
27941
|
try {
|
|
27350
27942
|
const entries = await this.opts.skillLoader.listEntries();
|
|
@@ -27648,10 +28240,31 @@ summarize it, and let the tool result hold only the summary.`);
|
|
|
27648
28240
|
const parts = [];
|
|
27649
28241
|
if (this.opts.memoryStore) {
|
|
27650
28242
|
try {
|
|
27651
|
-
|
|
27652
|
-
|
|
28243
|
+
if (this.opts.memoryStore.scoreRelevant) {
|
|
28244
|
+
const toolNames = this._lastBuildTools?.map((t2) => t2.name) ?? [];
|
|
28245
|
+
const scored = await this.opts.memoryStore.scoreRelevant(
|
|
28246
|
+
{
|
|
28247
|
+
currentTask: "",
|
|
28248
|
+
toolNames
|
|
28249
|
+
},
|
|
28250
|
+
"project-memory",
|
|
28251
|
+
8
|
|
28252
|
+
);
|
|
28253
|
+
if (scored.length > 0) {
|
|
28254
|
+
const lines = ["# Relevant Memory"];
|
|
28255
|
+
for (const e of scored) {
|
|
28256
|
+
const badge2 = e.type ? `[\`${e.type.replace("_", "-")}\`] ` : "";
|
|
28257
|
+
const priorityMark = e.priority === "critical" ? "\u26A1" : e.priority === "high" ? "\u25B2" : "";
|
|
28258
|
+
lines.push(`- ${priorityMark}${badge2}${e.text}${e.tags ? ` \`#${e.tags.join(" #")}\`` : ""}`);
|
|
28259
|
+
}
|
|
28260
|
+
parts.push(lines.join("\n"));
|
|
28261
|
+
}
|
|
28262
|
+
} else {
|
|
28263
|
+
const mem = await this.opts.memoryStore.readAll();
|
|
28264
|
+
if (mem.trim()) parts.push(`# Project Memory
|
|
27653
28265
|
|
|
27654
28266
|
${mem}`);
|
|
28267
|
+
}
|
|
27655
28268
|
} catch {
|
|
27656
28269
|
}
|
|
27657
28270
|
}
|
|
@@ -28538,20 +29151,28 @@ function wrapApiForCapabilityCheck(plugin, api, log, enforce = false) {
|
|
|
28538
29151
|
}
|
|
28539
29152
|
|
|
28540
29153
|
// src/execution/prompt-enhancer.ts
|
|
28541
|
-
var ENHANCER_SYSTEM_PROMPT = `You are a request refiner embedded in a coding agent. Your ONLY job is to rewrite the user's message into
|
|
29154
|
+
var ENHANCER_SYSTEM_PROMPT = `You are a request refiner embedded in a coding agent. Your ONLY job is to rewrite the user's message into clearer, unambiguous instructions that the coding agent can act on confidently.
|
|
28542
29155
|
|
|
28543
29156
|
Rules:
|
|
28544
29157
|
- Preserve the user's intent and scope EXACTLY. Do not add new requirements, features, constraints, or steps the user did not ask for. Do not remove anything they did ask for.
|
|
28545
29158
|
- Do NOT answer, solve, or perform the request. Only restate it more clearly.
|
|
28546
29159
|
- Keep all concrete details verbatim: file paths, identifiers, code, error text, numbers, names, URLs.
|
|
28547
29160
|
- Resolve obvious ambiguity by making the implied subject explicit, not by inventing specifics. If something is genuinely unspecified, leave it general rather than guessing.
|
|
28548
|
-
- Be concise: one tight instruction (a few sentences at most). No preamble, no explanation, no quotes, no markdown headers.
|
|
29161
|
+
- Be concise: one tight instruction per version (a few sentences at most). No preamble, no explanation, no quotes, no markdown headers.
|
|
28549
29162
|
- If the message is already clear and complete, return it essentially unchanged.
|
|
28550
|
-
|
|
29163
|
+
|
|
29164
|
+
You MUST output TWO versions of the refined request, separated by a line containing only "---".
|
|
29165
|
+
- First version: refined in the SAME LANGUAGE the user wrote in (if Turkish \u2192 Turkish, if Spanish \u2192 Spanish, etc.).
|
|
29166
|
+
- Second version: refined in ENGLISH (translate the intent into clear English while preserving all concrete details).
|
|
29167
|
+
|
|
29168
|
+
Output format:
|
|
29169
|
+
<refined in user's language>
|
|
29170
|
+
---
|
|
29171
|
+
<refined in English>
|
|
28551
29172
|
|
|
28552
29173
|
When earlier conversation turns are provided, they are CONTEXT ONLY. Use them to resolve references in the user's latest message \u2014 "it", "that", "the same", "the other one", "this file", "again" \u2014 so the refined instruction is self-contained. Refine ONLY the user's latest message; do not answer it, do not act on or restate earlier turns, and do not summarize the conversation.
|
|
28553
29174
|
|
|
28554
|
-
Output ONLY the
|
|
29175
|
+
Output ONLY the two versions separated by "---" \u2014 nothing else.`;
|
|
28555
29176
|
var AFFIRMATION_RE = /^(y|n|yes|no|yep|nope|ok|okay|sure|go|go ahead|continue|proceed|stop|cancel|done|next|skip|retry|again|please do|do it)\b[.! ]*$/i;
|
|
28556
29177
|
function shouldEnhance(text) {
|
|
28557
29178
|
const t2 = text.trim();
|
|
@@ -28598,12 +29219,23 @@ async function enhanceUserPrompt(opts) {
|
|
|
28598
29219
|
const signal = opts.signal ? AbortSignal.any([opts.signal, timer.signal]) : timer.signal;
|
|
28599
29220
|
try {
|
|
28600
29221
|
const res = await provider.complete(req, { signal });
|
|
28601
|
-
const
|
|
28602
|
-
if (!
|
|
29222
|
+
const raw = res.content.filter(isTextBlock).map((b) => b.text).join("\n").trim();
|
|
29223
|
+
if (!raw) {
|
|
28603
29224
|
opts.onError?.("model returned no text");
|
|
28604
29225
|
return null;
|
|
28605
29226
|
}
|
|
28606
|
-
|
|
29227
|
+
const sepIdx = raw.indexOf("\n---\n");
|
|
29228
|
+
if (sepIdx === -1) {
|
|
29229
|
+
opts.onError?.("model did not produce two versions");
|
|
29230
|
+
return { refined: raw, english: raw };
|
|
29231
|
+
}
|
|
29232
|
+
const refined = raw.slice(0, sepIdx).trim();
|
|
29233
|
+
const english = raw.slice(sepIdx + 5).trim();
|
|
29234
|
+
if (!refined || !english) {
|
|
29235
|
+
opts.onError?.("one or both versions empty");
|
|
29236
|
+
return null;
|
|
29237
|
+
}
|
|
29238
|
+
return { refined, english };
|
|
28607
29239
|
} catch (err) {
|
|
28608
29240
|
if (opts.signal?.aborted) return null;
|
|
28609
29241
|
if (timer.signal.aborted) {
|
|
@@ -28706,8 +29338,8 @@ var PhaseGraphBuilder = class _PhaseGraphBuilder {
|
|
|
28706
29338
|
return graph;
|
|
28707
29339
|
}
|
|
28708
29340
|
/**
|
|
28709
|
-
*
|
|
28710
|
-
*
|
|
29341
|
+
* Create phases from an existing TaskGraph.
|
|
29342
|
+
* Groups tasks into phases by priority and type.
|
|
28711
29343
|
*/
|
|
28712
29344
|
static fromTaskGraph(taskGraph, options) {
|
|
28713
29345
|
const tasksPerPhase = options.tasksPerPhase ?? 5;
|
|
@@ -28785,8 +29417,8 @@ var PhaseOrchestrator = class {
|
|
|
28785
29417
|
}
|
|
28786
29418
|
// ─── Lifecycle ────────────────────────────────────────────────────────────
|
|
28787
29419
|
/**
|
|
28788
|
-
*
|
|
28789
|
-
*
|
|
29420
|
+
* Start the full phase flow.
|
|
29421
|
+
* In autonomous mode, starts root phases and automatically starts the next phase when they finish.
|
|
28790
29422
|
*/
|
|
28791
29423
|
async start() {
|
|
28792
29424
|
this.stopped = false;
|
|
@@ -28813,17 +29445,17 @@ var PhaseOrchestrator = class {
|
|
|
28813
29445
|
this.tickInterval = setInterval(() => this.tick(), 1e3);
|
|
28814
29446
|
}
|
|
28815
29447
|
}
|
|
28816
|
-
/**
|
|
29448
|
+
/** Wait for all pending phase merges, dependency-ordered and globally serialized. */
|
|
28817
29449
|
async drainMerges() {
|
|
28818
29450
|
await Promise.allSettled([...this.phaseMergePromise.values()]);
|
|
28819
29451
|
await this.mergeQueue.catch(() => {
|
|
28820
29452
|
});
|
|
28821
29453
|
}
|
|
28822
|
-
/**
|
|
29454
|
+
/** Pause: active phases continue, but no new phase starts. */
|
|
28823
29455
|
pause() {
|
|
28824
29456
|
this.paused = true;
|
|
28825
29457
|
}
|
|
28826
|
-
/**
|
|
29458
|
+
/** Resume: new phases may start again. */
|
|
28827
29459
|
resume() {
|
|
28828
29460
|
this.paused = false;
|
|
28829
29461
|
this.tick().catch((err) => {
|
|
@@ -28833,7 +29465,7 @@ var PhaseOrchestrator = class {
|
|
|
28833
29465
|
);
|
|
28834
29466
|
});
|
|
28835
29467
|
}
|
|
28836
|
-
/**
|
|
29468
|
+
/** Stop completely, including active phases. */
|
|
28837
29469
|
stop() {
|
|
28838
29470
|
this.stopped = true;
|
|
28839
29471
|
if (this.tickInterval) {
|
|
@@ -29031,7 +29663,10 @@ var PhaseOrchestrator = class {
|
|
|
29031
29663
|
const depPromises = phase.dependsOn.map((d) => this.phaseMergePromise.get(d)).filter((p) => Boolean(p));
|
|
29032
29664
|
const merged = (async () => {
|
|
29033
29665
|
await Promise.allSettled(depPromises);
|
|
29034
|
-
this.mergeQueue = this.mergeQueue.then(() => this.mergeOne(phase, handle))
|
|
29666
|
+
this.mergeQueue = this.mergeQueue.then(() => this.mergeOne(phase, handle)).catch((err) => {
|
|
29667
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
29668
|
+
console.error(`[PhaseOrchestrator] mergeOne failed for phase ${phase.id}: ${msg}`);
|
|
29669
|
+
});
|
|
29035
29670
|
await this.mergeQueue;
|
|
29036
29671
|
})();
|
|
29037
29672
|
this.phaseMergePromise.set(phase.id, merged);
|
|
@@ -29583,14 +30218,14 @@ var AutoPhasePlanner = class {
|
|
|
29583
30218
|
this.opts = opts;
|
|
29584
30219
|
}
|
|
29585
30220
|
opts;
|
|
29586
|
-
/**
|
|
30221
|
+
/** Convert the goal into a phase-and-todo plan. */
|
|
29587
30222
|
async plan() {
|
|
29588
30223
|
const prompt = this.buildPrompt();
|
|
29589
30224
|
const raw = await this.opts.runOnce(prompt);
|
|
29590
30225
|
const phases = this.parse(raw);
|
|
29591
30226
|
return { phases, raw, parseFailed: phases.length === 0 };
|
|
29592
30227
|
}
|
|
29593
|
-
/**
|
|
30228
|
+
/** Instruction prompt for the plan the model should produce. */
|
|
29594
30229
|
buildPrompt() {
|
|
29595
30230
|
const minP = this.opts.minPhases ?? 3;
|
|
29596
30231
|
const maxP = this.opts.maxPhases ?? 8;
|
|
@@ -29638,7 +30273,7 @@ ${ctx}
|
|
|
29638
30273
|
"```"
|
|
29639
30274
|
].filter((l) => l !== "").join("\n");
|
|
29640
30275
|
}
|
|
29641
|
-
/**
|
|
30276
|
+
/** Extract JSON from raw output, validate it, and convert it to PhaseTemplate[]. */
|
|
29642
30277
|
parse(raw) {
|
|
29643
30278
|
const json = extractJSONArray(raw);
|
|
29644
30279
|
if (!json) return [];
|
|
@@ -30378,7 +31013,8 @@ ${check.stderr}`);
|
|
|
30378
31013
|
const child = spawn(this.gitBin, args, {
|
|
30379
31014
|
cwd,
|
|
30380
31015
|
env: buildChildEnv(),
|
|
30381
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
31016
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
31017
|
+
signal: AbortSignal.timeout(3e4)
|
|
30382
31018
|
});
|
|
30383
31019
|
child.stdout?.on("data", (c) => {
|
|
30384
31020
|
stdout += c.toString();
|
|
@@ -30746,12 +31382,6 @@ var ReplayProviderRunner = class {
|
|
|
30746
31382
|
};
|
|
30747
31383
|
|
|
30748
31384
|
// src/plugins/prompts-plugin.ts
|
|
30749
|
-
function expectDefined26(value) {
|
|
30750
|
-
if (value === null || value === void 0) {
|
|
30751
|
-
throw new Error("Expected value to be defined");
|
|
30752
|
-
}
|
|
30753
|
-
return value;
|
|
30754
|
-
}
|
|
30755
31385
|
function createPromptsPlugin(opts) {
|
|
30756
31386
|
let store = null;
|
|
30757
31387
|
return {
|
|
@@ -30805,7 +31435,7 @@ ${lines.join("\n")}
|
|
|
30805
31435
|
if (!restJoined) return { message: "Usage: /prompts view <title>" };
|
|
30806
31436
|
const matches = await store.find(restJoined);
|
|
30807
31437
|
if (matches.length === 0) return { message: `No prompt matching "${restJoined}".` };
|
|
30808
|
-
const entry = matches.find((m) => m.title.toLowerCase() === restJoined.toLowerCase()) ??
|
|
31438
|
+
const entry = matches.find((m) => m.title.toLowerCase() === restJoined.toLowerCase()) ?? expectDefined(matches[0]);
|
|
30809
31439
|
const tags = entry.tags.length > 0 ? ` [${entry.tags.join(", ")}]` : "";
|
|
30810
31440
|
return {
|
|
30811
31441
|
message: `# ${entry.title}${tags}
|
|
@@ -30828,7 +31458,7 @@ ${dim2(`id: ${entry.id} | created: ${entry.createdAt}`)}`
|
|
|
30828
31458
|
if (!restJoined) return { message: "Usage: /prompts delete <title>" };
|
|
30829
31459
|
const matches = await store.find(restJoined);
|
|
30830
31460
|
if (matches.length === 0) return { message: `No prompt matching "${restJoined}".` };
|
|
30831
|
-
const exact = matches.find((m) => m.title.toLowerCase() === restJoined.toLowerCase()) ??
|
|
31461
|
+
const exact = matches.find((m) => m.title.toLowerCase() === restJoined.toLowerCase()) ?? expectDefined(matches[0]);
|
|
30832
31462
|
const deleted = await store.delete(exact.id);
|
|
30833
31463
|
return { message: deleted ? `Deleted "${exact.title}".` : "Delete failed." };
|
|
30834
31464
|
}
|
|
@@ -30838,7 +31468,7 @@ ${dim2(`id: ${entry.id} | created: ${entry.createdAt}`)}`
|
|
|
30838
31468
|
if (!parsed.title) return { message: 'Usage: /prompts edit "title" "new content"' };
|
|
30839
31469
|
const matches = await store.find(parsed.title);
|
|
30840
31470
|
if (matches.length === 0) return { message: `No prompt matching "${parsed.title}".` };
|
|
30841
|
-
const exact = matches.find((m) => m.title.toLowerCase() === parsed.title?.toLowerCase()) ??
|
|
31471
|
+
const exact = matches.find((m) => m.title.toLowerCase() === parsed.title?.toLowerCase()) ?? expectDefined(matches[0]);
|
|
30842
31472
|
exact.content = parsed.content;
|
|
30843
31473
|
exact.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
30844
31474
|
await store.save(exact);
|
|
@@ -30850,7 +31480,7 @@ ${dim2(`id: ${entry.id} | created: ${entry.createdAt}`)}`
|
|
|
30850
31480
|
if (!parsed.title) return { message: 'Usage: /prompts extend "title" <instructions>' };
|
|
30851
31481
|
const matches = await store.find(parsed.title);
|
|
30852
31482
|
if (matches.length === 0) return { message: `No prompt matching "${parsed.title}".` };
|
|
30853
|
-
const exact = matches.find((m) => m.title.toLowerCase() === parsed.title?.toLowerCase()) ??
|
|
31483
|
+
const exact = matches.find((m) => m.title.toLowerCase() === parsed.title?.toLowerCase()) ?? expectDefined(matches[0]);
|
|
30854
31484
|
const prov = ctx.provider;
|
|
30855
31485
|
if (!prov?.complete) return { message: "LLM not available. Configure a provider first." };
|
|
30856
31486
|
const enhanced = await prov.complete(ctx.model, [
|
|
@@ -30885,9 +31515,9 @@ function parseTitleContent(args) {
|
|
|
30885
31515
|
const trimmed = args.trim();
|
|
30886
31516
|
if (!trimmed) return { title: "", content: "" };
|
|
30887
31517
|
const doubleMatch = /^"([^"]+)"\s+"([^"]+)"$/.exec(trimmed) || /^'([^']+)'\s+'([^']+)'$/.exec(trimmed);
|
|
30888
|
-
if (doubleMatch) return { title:
|
|
31518
|
+
if (doubleMatch) return { title: expectDefined(doubleMatch[1]), content: expectDefined(doubleMatch[2]) };
|
|
30889
31519
|
const singleMatch = /^'([^']+)'\s+(.+)$/.exec(trimmed);
|
|
30890
|
-
if (singleMatch) return { title:
|
|
31520
|
+
if (singleMatch) return { title: expectDefined(singleMatch[1]), content: expectDefined(singleMatch[2]) };
|
|
30891
31521
|
const firstSpace = trimmed.indexOf(" ");
|
|
30892
31522
|
if (firstSpace === -1) return { title: trimmed, content: "" };
|
|
30893
31523
|
return { title: trimmed.slice(0, firstSpace), content: trimmed.slice(firstSpace + 1) };
|
|
@@ -30898,12 +31528,6 @@ function dim2(s) {
|
|
|
30898
31528
|
|
|
30899
31529
|
// src/plugins/sync-plugin.ts
|
|
30900
31530
|
init_atomic_write();
|
|
30901
|
-
function expectDefined27(value) {
|
|
30902
|
-
if (value === null || value === void 0) {
|
|
30903
|
-
throw new Error("Expected value to be defined");
|
|
30904
|
-
}
|
|
30905
|
-
return value;
|
|
30906
|
-
}
|
|
30907
31531
|
function createSyncPlugin(opts) {
|
|
30908
31532
|
let cloud = null;
|
|
30909
31533
|
let configStore;
|
|
@@ -30977,7 +31601,7 @@ function buildSyncCommand(cloud, configStore, vault, syncConfigPath) {
|
|
|
30977
31601
|
if (!repo || !repo.includes("/")) {
|
|
30978
31602
|
return { message: 'Invalid repo format. Expected "owner/repo".' };
|
|
30979
31603
|
}
|
|
30980
|
-
const storedToken = vault ? vault.encrypt(
|
|
31604
|
+
const storedToken = vault ? vault.encrypt(expectDefined(token)) : expectDefined(token);
|
|
30981
31605
|
const syncConfig = {
|
|
30982
31606
|
enabled: true,
|
|
30983
31607
|
repo,
|
|
@@ -31118,7 +31742,7 @@ function createGitPlugin() {
|
|
|
31118
31742
|
async function runGit(args, cwd) {
|
|
31119
31743
|
try {
|
|
31120
31744
|
return await new Promise((resolve13, reject) => {
|
|
31121
|
-
const child = spawn("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
31745
|
+
const child = spawn("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"], signal: AbortSignal.timeout(3e4) });
|
|
31122
31746
|
let stdout = "";
|
|
31123
31747
|
let stderr = "";
|
|
31124
31748
|
child.stdout?.on("data", (d) => {
|
|
@@ -31843,6 +32467,6 @@ ${formatPlan(updated)}`
|
|
|
31843
32467
|
};
|
|
31844
32468
|
}
|
|
31845
32469
|
|
|
31846
|
-
export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, Agent, AgentError, AnnotationsStore, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BrainDecisionQueue, BudgetExceededError, CONTEXT_WINDOW_MODES, CORE_RECONSTRUCT_EVENTS, CheckpointManager, CloudSync, CollaborationBus, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SESSION_PRUNE_DAYS, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultBrainArbiter, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ENHANCER_SYSTEM_PROMPT, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HookRegistry, HookRunner, HumanEscalatingBrainArbiter, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MATRIX_PHASE_KEYS, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, ObservableBrainArbiter, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReplayLogStore, ReplayProviderRunner, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, STANDARD_AUDIT_EVENTS, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SessionRecovery, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolAuditLog, ToolError, ToolExecutor, ToolRegistry, WorktreeManager, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, assertSafePath, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, bootConfig, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, collabInjectMiddleware, collabPauseMiddleware, color, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createGitPlugin, createMcpControlTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSessionEventBridge, createSkillsPlugin, createSyncPlugin, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, enhanceUserPrompt, ensureDir, estimateRequestTokens, estimateRequestTokensCalibrated, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, expandGlob,
|
|
32470
|
+
export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, Agent, AgentError, AnnotationsStore, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BrainDecisionQueue, BudgetExceededError, CONTEXT_WINDOW_MODES, CORE_RECONSTRUCT_EVENTS, CheckpointManager, CloudSync, CollaborationBus, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SESSION_PRUNE_DAYS, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultBrainArbiter, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ENHANCER_SYSTEM_PROMPT, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FileMemoryBackend, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, GraphMemoryBackend, HookRegistry, HookRunner, HumanEscalatingBrainArbiter, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MATRIX_PHASE_KEYS, MAX_JOURNAL_ENTRIES, MEMORY_TYPE_LABELS, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, ObservableBrainArbiter, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReplayLogStore, ReplayProviderRunner, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, STANDARD_AUDIT_EVENTS, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SessionMemoryConsolidator, SessionRecovery, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolAuditLog, ToolError, ToolExecutor, ToolRegistry, WorktreeManager, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, assertSafePath, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, bootConfig, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, collabInjectMiddleware, collabPauseMiddleware, color, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createGitPlugin, createMcpControlTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSessionEventBridge, createSkillsPlugin, createSyncPlugin, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, enhanceUserPrompt, ensureDir, estimateRequestTokens, estimateRequestTokensCalibrated, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, expandGlob, expectDefined, extractRunEnv, filesystemServer, findCriticalPath, flagsToConfigPatch, formatContextWindowModeList, formatGoal, formatHumanPrompt, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getCalibrationState, getContextWindowMode, getPlanTemplate, getTemplate, getTermSize, githubServer, goalFilePath, googleMapsServer, hashRequest, hookMatcherMatches, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isInteractive, isPluginError, isSessionError, isStdinTTY, isStdoutTTY, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isValidMatrixKey, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeRollUpTool, makeSpawnTool, makeTerminateTool, matchAny, matchGlob, matrixKeyKind, mergeCustomModelDefs, mergeModelsPayload, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, normalizedEqual, onResize, parseContinueDirective, parseEntries, parseSkillRef, pendingBtwCount, phaseForRole, projectHash, projectSlug, recentTextTurns, recordActualUsage, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resetCalibration, resolveAuditLevel, resolveContextWindowPolicy, resolveModelMatrix, resolveSessionLoggingConfig, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, runProviderWithRetry, runShellHook, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setOutputLineGuard, setPlanItemStatus, setRawMode, shouldEnhance, slackServer, sleep, stableStringify, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, withFileLock, wrapAsState, writeErr, writeOut, zaiVisionServer };
|
|
31847
32471
|
//# sourceMappingURL=index.js.map
|
|
31848
32472
|
//# sourceMappingURL=index.js.map
|