@inerrata-corporation/errata 2.0.17-dev.3416 → 2.0.17-dev.3426
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/consolidate-worker.mjs +19 -1
- package/errata.mjs +1132 -424
- package/package.json +1 -1
- package/pass-worker.mjs +11 -3
package/errata.mjs
CHANGED
|
@@ -960,7 +960,7 @@ function lemma(token) {
|
|
|
960
960
|
}
|
|
961
961
|
return token;
|
|
962
962
|
}
|
|
963
|
-
function tokenize(text,
|
|
963
|
+
function tokenize(text, resolve9) {
|
|
964
964
|
const matches = text.normalize("NFC").toLowerCase().match(TOKEN_RE) ?? [];
|
|
965
965
|
const out2 = /* @__PURE__ */ new Set();
|
|
966
966
|
for (const raw2 of matches) {
|
|
@@ -970,7 +970,7 @@ function tokenize(text, resolve8) {
|
|
|
970
970
|
out2.add(token);
|
|
971
971
|
continue;
|
|
972
972
|
}
|
|
973
|
-
const canonical =
|
|
973
|
+
const canonical = resolve9(token);
|
|
974
974
|
out2.add(canonical ?? lemma(token));
|
|
975
975
|
}
|
|
976
976
|
return [...out2].sort();
|
|
@@ -21903,6 +21903,24 @@ function parseIntentFences(text) {
|
|
|
21903
21903
|
}
|
|
21904
21904
|
return out2;
|
|
21905
21905
|
}
|
|
21906
|
+
function parseShareFence(text) {
|
|
21907
|
+
const m = /```errata-share[^\n]*\n([\s\S]*?)```/.exec(text);
|
|
21908
|
+
if (!m) return null;
|
|
21909
|
+
const parts2 = [];
|
|
21910
|
+
for (const line of m[1].split(/\r?\n/)) {
|
|
21911
|
+
const kv = /^\s*priors\s*:\s*(.*?)\s*$/i.exec(line);
|
|
21912
|
+
if (kv) parts2.push(kv[1]);
|
|
21913
|
+
else if (parts2.length > 0 && line.trim()) parts2.push(line.trim());
|
|
21914
|
+
}
|
|
21915
|
+
const value = parts2.join(" ").trim();
|
|
21916
|
+
if (/^all$/i.test(value)) return { all: true };
|
|
21917
|
+
const priors = [
|
|
21918
|
+
...new Set(
|
|
21919
|
+
value.split(/[\s,]+/).map((t) => t.replace(/^[`([]+|[`)\]]+$/g, "")).filter((t) => /^[\w.:-]+$/.test(t))
|
|
21920
|
+
)
|
|
21921
|
+
];
|
|
21922
|
+
return priors.length > 0 ? { all: false, priors } : null;
|
|
21923
|
+
}
|
|
21906
21924
|
function searchByIntent(store, intent, opts) {
|
|
21907
21925
|
const limit = opts?.limit ?? 5;
|
|
21908
21926
|
const minCoverage = opts?.minCoverage ?? DEFAULT_MIN_COVERAGE;
|
|
@@ -25010,6 +25028,7 @@ __export(src_exports2, {
|
|
|
25010
25028
|
parseAbstractionFences: () => parseAbstractionFences,
|
|
25011
25029
|
parseIntentFences: () => parseIntentFences,
|
|
25012
25030
|
parseSemver: () => parseSemver,
|
|
25031
|
+
parseShareFence: () => parseShareFence,
|
|
25013
25032
|
parseTriageFences: () => parseTriageFences,
|
|
25014
25033
|
pendingAbstractions: () => pendingAbstractions,
|
|
25015
25034
|
pendingDiscriminators: () => pendingDiscriminators,
|
|
@@ -25100,11 +25119,13 @@ function buildSnapshot(opts) {
|
|
|
25100
25119
|
const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
|
|
25101
25120
|
const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
|
|
25102
25121
|
allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
|
|
25103
|
-
const
|
|
25122
|
+
const openPool = allProblems.slice(0, RECENT_OPEN * SCOPE_POOL_FACTOR).map((p) => ({
|
|
25104
25123
|
node: p,
|
|
25105
25124
|
anchors: opts.store.outEdges(p.id, ["MANIFESTED_IN", "EVIDENCED_BY"])
|
|
25106
25125
|
}));
|
|
25107
|
-
const
|
|
25126
|
+
const recent3 = openPool.slice(0, RECENT_OPEN);
|
|
25127
|
+
const constraintPool = stillOpen.filter((p) => isConstraintProblem(p)).sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR);
|
|
25128
|
+
const recentConstraints = constraintPool.slice(0, RECENT_CONSTRAINTS);
|
|
25108
25129
|
const regressions = problems.filter((p) => p.attrs["resolvedAt"] == null && p.attrs["mergedInto"] === void 0).flatMap(
|
|
25109
25130
|
(open2) => opts.store.outEdges(open2.id, ["REGRESSION_OF"]).flatMap((e) => {
|
|
25110
25131
|
const closed = opts.store.getNode(e.to);
|
|
@@ -25117,11 +25138,12 @@ function buildSnapshot(opts) {
|
|
|
25117
25138
|
})
|
|
25118
25139
|
).sort((a, b) => Number(b.closed.attrs["recurredAt"] ?? 0) - Number(a.closed.attrs["recurredAt"] ?? 0)).slice(0, 2);
|
|
25119
25140
|
const regressionClosedIds = new Set(regressions.map((r) => r.closed.id));
|
|
25120
|
-
const
|
|
25141
|
+
const resolvedPool = problems.filter((p) => p.attrs["resolvedAt"] != null && p.attrs["resolvedAs"] == null).filter((p) => !regressionClosedIds.has(p.id)).sort((a, b) => Number(b.attrs["resolvedAt"] ?? 0) - Number(a.attrs["resolvedAt"] ?? 0)).slice(0, RECENT_RESOLVED * SCOPE_POOL_FACTOR).map((p) => {
|
|
25121
25142
|
const solEdge = opts.store.outEdges(p.id, ["SOLVED_BY"])[0];
|
|
25122
25143
|
const solution = solEdge ? opts.store.getNode(solEdge.to) ?? void 0 : void 0;
|
|
25123
25144
|
return { node: p, ...solution ? { solution } : {} };
|
|
25124
25145
|
});
|
|
25146
|
+
const recentResolved = resolvedPool.slice(0, RECENT_RESOLVED);
|
|
25125
25147
|
const motifs = [
|
|
25126
25148
|
...opts.store.findNodesByLabel("Pattern"),
|
|
25127
25149
|
...opts.store.findNodesByLabel("Technique"),
|
|
@@ -25199,9 +25221,23 @@ function buildSnapshot(opts) {
|
|
|
25199
25221
|
pendingEnrichment,
|
|
25200
25222
|
skills: opts.skills ?? [],
|
|
25201
25223
|
needsRevisit,
|
|
25224
|
+
scopePool: { open: openPool, resolved: resolvedPool, constraints: constraintPool },
|
|
25202
25225
|
generatedAt: (opts.now ?? /* @__PURE__ */ new Date()).toISOString()
|
|
25203
25226
|
};
|
|
25204
25227
|
}
|
|
25228
|
+
function scopeSnapshot(s, keep) {
|
|
25229
|
+
const pool = s.scopePool;
|
|
25230
|
+
if (!pool) return s;
|
|
25231
|
+
const open2 = pool.open.filter((r) => keep(r.node));
|
|
25232
|
+
return {
|
|
25233
|
+
...s,
|
|
25234
|
+
recentProblems: open2.slice(0, RECENT_OPEN),
|
|
25235
|
+
recentResolved: pool.resolved.filter((r) => keep(r.node)).slice(0, RECENT_RESOLVED),
|
|
25236
|
+
recentConstraints: pool.constraints.filter(keep).slice(0, RECENT_CONSTRAINTS),
|
|
25237
|
+
regressions: s.regressions.filter((r) => keep(r.open)),
|
|
25238
|
+
scopePool: { ...pool, open: open2 }
|
|
25239
|
+
};
|
|
25240
|
+
}
|
|
25205
25241
|
function sliceForFile(store, relPath, atCommit) {
|
|
25206
25242
|
const candidates = store.findNodesByLabel("File");
|
|
25207
25243
|
const file2 = candidates.find((n) => n.description === relPath);
|
|
@@ -25292,6 +25328,8 @@ function renderSnapshot(s) {
|
|
|
25292
25328
|
lines.push(SEARCH_IMPERATIVE_HEADER);
|
|
25293
25329
|
lines.push(SEARCH_IMPERATIVE_BODY);
|
|
25294
25330
|
lines.push("");
|
|
25331
|
+
lines.push(s.isolated ? SUBAGENT_OWN_BLOCK_NOTE : SPAWN_SHARE_HINT);
|
|
25332
|
+
lines.push("");
|
|
25295
25333
|
lines.push(`### Active workspace profile`);
|
|
25296
25334
|
lines.push(`- **Name:** ${s.profile.name}`);
|
|
25297
25335
|
const ctxName = (name2) => name2.startsWith("@") ? `\`${name2}\`` : name2;
|
|
@@ -25469,6 +25507,12 @@ function renderSnapshot(s) {
|
|
|
25469
25507
|
}
|
|
25470
25508
|
lines.push("");
|
|
25471
25509
|
}
|
|
25510
|
+
if (s.sharedPriors?.length) {
|
|
25511
|
+
lines.push(`### \u{1F91D} Handed to you by the agent that spawned you`);
|
|
25512
|
+
lines.push("_It chose these for your task \u2014 cite one with its `[handle]` if you lean on it:_");
|
|
25513
|
+
for (const n of s.sharedPriors) lines.push(`- **${n.label}:** ${n.description}${tagOf(n)}`);
|
|
25514
|
+
lines.push("");
|
|
25515
|
+
}
|
|
25472
25516
|
if (s.statedIntent) {
|
|
25473
25517
|
const si = s.statedIntent;
|
|
25474
25518
|
lines.push(`### \u{1F3AF} You said you're working on this`);
|
|
@@ -25650,6 +25694,35 @@ function budgetSnapshot(s, maxChars) {
|
|
|
25650
25694
|
while (renderSnapshot(s).length > maxChars && dropLowestUnit(s)) dropped++;
|
|
25651
25695
|
return dropped;
|
|
25652
25696
|
}
|
|
25697
|
+
function isolateSnapshot(s) {
|
|
25698
|
+
const {
|
|
25699
|
+
workingFile: _workingFile,
|
|
25700
|
+
statedIntent: _statedIntent,
|
|
25701
|
+
selfCiteSkips: _selfCiteSkips,
|
|
25702
|
+
pendingUpdate: _pendingUpdate,
|
|
25703
|
+
daemonDistress: _daemonDistress,
|
|
25704
|
+
reviewItems: _reviewItems,
|
|
25705
|
+
causalNudge: _causalNudge,
|
|
25706
|
+
domainNudge: _domainNudge,
|
|
25707
|
+
sharedPriors: _sharedPriors,
|
|
25708
|
+
scopePool: _scopePool,
|
|
25709
|
+
...graphWide
|
|
25710
|
+
} = s;
|
|
25711
|
+
return {
|
|
25712
|
+
...graphWide,
|
|
25713
|
+
isolated: true,
|
|
25714
|
+
recentProblems: [],
|
|
25715
|
+
recentResolved: [],
|
|
25716
|
+
regressions: [],
|
|
25717
|
+
recentConstraints: [],
|
|
25718
|
+
pendingEnrichment: [],
|
|
25719
|
+
needsRevisit: [],
|
|
25720
|
+
reviewCount: 0,
|
|
25721
|
+
motifs: [...s.motifs],
|
|
25722
|
+
skills: [...s.skills],
|
|
25723
|
+
...s.remote ? { remote: [...s.remote] } : {}
|
|
25724
|
+
};
|
|
25725
|
+
}
|
|
25653
25726
|
function assembleAgentContext(opts) {
|
|
25654
25727
|
const snapshot = opts.snapshot ?? buildSnapshot({
|
|
25655
25728
|
store: opts.store,
|
|
@@ -25666,6 +25739,7 @@ function assembleAgentContext(opts) {
|
|
|
25666
25739
|
if (opts.daemonDistress) snapshot.daemonDistress = opts.daemonDistress;
|
|
25667
25740
|
if (opts.reviewItems?.length) snapshot.reviewItems = [...opts.reviewItems];
|
|
25668
25741
|
if (opts.statedIntent) snapshot.statedIntent = opts.statedIntent;
|
|
25742
|
+
if (opts.sharedPriors?.length) snapshot.sharedPriors = [...opts.sharedPriors];
|
|
25669
25743
|
if (opts.remote && opts.remote.length > 0) {
|
|
25670
25744
|
const seen = /* @__PURE__ */ new Set();
|
|
25671
25745
|
const remote = opts.remote.filter((n) => {
|
|
@@ -25717,13 +25791,17 @@ function diffRenderLedger(before, after) {
|
|
|
25717
25791
|
for (const i2 of before) (survived.has(key(i2)) ? shown : evicted).push(i2);
|
|
25718
25792
|
return { shown, evicted };
|
|
25719
25793
|
}
|
|
25720
|
-
var RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, EVICTION_ORDER, MOTIF_FLOOR, REMOTE_FLOOR, PROBLEM_FLOOR, REVIEW_ITEM_FLOOR, DEFAULT_AGENT_CONTEXT_BUDGET;
|
|
25794
|
+
var RECENT_OPEN, RECENT_RESOLVED, RECENT_CONSTRAINTS, SCOPE_POOL_FACTOR, RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, SPAWN_SHARE_HINT, SUBAGENT_OWN_BLOCK_NOTE, EVICTION_ORDER, MOTIF_FLOOR, REMOTE_FLOOR, PROBLEM_FLOOR, REVIEW_ITEM_FLOOR, DEFAULT_AGENT_CONTEXT_BUDGET;
|
|
25721
25795
|
var init_render = __esm({
|
|
25722
25796
|
"../../packages/context-writer/src/render.ts"() {
|
|
25723
25797
|
"use strict";
|
|
25724
25798
|
init_src5();
|
|
25725
25799
|
init_src2();
|
|
25726
25800
|
init_src();
|
|
25801
|
+
RECENT_OPEN = 8;
|
|
25802
|
+
RECENT_RESOLVED = 4;
|
|
25803
|
+
RECENT_CONSTRAINTS = 3;
|
|
25804
|
+
SCOPE_POOL_FACTOR = 3;
|
|
25727
25805
|
RECALL_FIRST_HEADER = "## errata \u2014 recall before you work";
|
|
25728
25806
|
RECALL_FIRST_BODY = "Before investigating any bug or error, your FIRST tool call must be `mcp__errata__errata_search` with a few words describing the problem. This machine's knowledge graph records previously solved problems \u2014 the answer may already be recorded. Read what it returns before touching any files.";
|
|
25729
25807
|
RECALL_FIRST_BLOCK = `${RECALL_FIRST_HEADER}
|
|
@@ -25731,6 +25809,8 @@ var init_render = __esm({
|
|
|
25731
25809
|
${RECALL_FIRST_BODY}`;
|
|
25732
25810
|
SEARCH_IMPERATIVE_HEADER = "### \u{1F50E} PRIORS ARE SEEDS \u2014 a sample, not the whole graph";
|
|
25733
25811
|
SEARCH_IMPERATIVE_BODY = "Everything below is a budgeted slice of a much larger graph, not all errata knows. Starting a piece of work? Say what it is \u2014 we search on it between your tool calls and put what we find here:\n```errata-intent\nintent: <the work in hand, in your words>\n```\nNarration, not a detour: no tool call, no plan change. It is the one signal we cannot derive from your edits \u2014 everything else here is guessed from the files you touched.";
|
|
25812
|
+
SPAWN_SHARE_HINT = "_Spawning a subagent? It gets its own errata block, seeded from its task \u2014 none of the priors here. To hand it some, put this in its prompt (or `priors: all` for this whole block):_\n```errata-share\npriors: [handle], [handle]\n```";
|
|
25813
|
+
SUBAGENT_OWN_BLOCK_NOTE = "_This block is yours: seeded from the task you were given, then from what you state and touch. The agent that spawned you sees a different one._";
|
|
25734
25814
|
EVICTION_ORDER = [
|
|
25735
25815
|
"skills",
|
|
25736
25816
|
// Review items beyond the floor drop immediately after skills — one naming
|
|
@@ -32004,6 +32084,9 @@ function errorCardHeadline(items) {
|
|
|
32004
32084
|
const fixes = items.filter((it) => it.label === "Solution").length;
|
|
32005
32085
|
return fixes > 0 ? `${plural(fixes, "known fix", "known fixes")} for this error` : `${plural(items.length, "prior")} for this error`;
|
|
32006
32086
|
}
|
|
32087
|
+
function forSubagent(card, agentType) {
|
|
32088
|
+
return { ...card, headline: `\u21B3 ${agentType || "subagent"} \xB7 ${card.headline}` };
|
|
32089
|
+
}
|
|
32007
32090
|
function leadItem(card) {
|
|
32008
32091
|
return card.chain?.fix ?? card.items.find((it) => it.label === "Solution") ?? card.single ?? card.items[0];
|
|
32009
32092
|
}
|
|
@@ -32083,6 +32166,29 @@ function rememberCard(sessionId, card, now = Date.now(), since = now) {
|
|
|
32083
32166
|
if (current && current.at > since) return;
|
|
32084
32167
|
remember(latestBySession, sessionId, { card, at: now });
|
|
32085
32168
|
}
|
|
32169
|
+
function rememberAgentCard(sessionId, agentId, card, now = Date.now()) {
|
|
32170
|
+
if (!sessionId || !agentId) return;
|
|
32171
|
+
remember(latestByAgent, agentKey(sessionId, agentId), { card, at: now });
|
|
32172
|
+
}
|
|
32173
|
+
function subagentRows(body2, now = Date.now()) {
|
|
32174
|
+
const sessionId = typeof body2["session_id"] === "string" ? body2["session_id"] : "";
|
|
32175
|
+
const tasks = Array.isArray(body2["tasks"]) ? body2["tasks"] : [];
|
|
32176
|
+
const columns = typeof body2["columns"] === "number" && body2["columns"] > 20 ? body2["columns"] : 100;
|
|
32177
|
+
const lines = [];
|
|
32178
|
+
for (const task of tasks) {
|
|
32179
|
+
const id = typeof task["id"] === "string" ? task["id"] : "";
|
|
32180
|
+
const hit = id ? latestByAgent.get(agentKey(sessionId, id)) : void 0;
|
|
32181
|
+
if (!hit || now - hit.at > SUBAGENT_ROW_TTL_MS) continue;
|
|
32182
|
+
const lead2 = leadItem(hit.card);
|
|
32183
|
+
const title = String(task["description"] ?? task["label"] ?? "").trim();
|
|
32184
|
+
const plain = clip(
|
|
32185
|
+
`${title ? `${title} \xB7 ` : ""}\u26A1 errata \xB7 ${hit.card.headline}${lead2 ? ` \u2014 ${labelName(lead2.label)}: ${lead2.text}` : ""}`,
|
|
32186
|
+
columns - 2
|
|
32187
|
+
);
|
|
32188
|
+
lines.push(JSON.stringify({ id, content: plain.replace("\u26A1", `${AMBER}\u26A1${RESET}`) }));
|
|
32189
|
+
}
|
|
32190
|
+
return lines.join("\n");
|
|
32191
|
+
}
|
|
32086
32192
|
function rememberOpenCount(sessionId, open2) {
|
|
32087
32193
|
if (sessionId) remember(openBySession, sessionId, open2);
|
|
32088
32194
|
}
|
|
@@ -32105,7 +32211,7 @@ function recallCardEnabled(env2 = process.env) {
|
|
|
32105
32211
|
const v = (env2["ERRATA_RECALL_CARD"] ?? "").trim().toLowerCase();
|
|
32106
32212
|
return !(v === "0" || v === "off" || v === "false" || v === "no");
|
|
32107
32213
|
}
|
|
32108
|
-
var LABEL_NAMES, INLINE_TEXT_WIDTH, ESC, RESET, DIM, BOLD, AMBER, MADDER, GREEN, INK, STATUS_ROWS, STATUS_TEXT_WIDTH, LABEL_WIDTH, STATUS_CARD_TTL_MS, IDLE_STATUS, latestBySession, MAX_SESSIONS, openBySession;
|
|
32214
|
+
var LABEL_NAMES, INLINE_TEXT_WIDTH, ESC, RESET, DIM, BOLD, AMBER, MADDER, GREEN, INK, STATUS_ROWS, STATUS_TEXT_WIDTH, LABEL_WIDTH, STATUS_CARD_TTL_MS, IDLE_STATUS, latestBySession, MAX_SESSIONS, latestByAgent, agentKey, SUBAGENT_ROW_TTL_MS, openBySession;
|
|
32109
32215
|
var init_recall_card = __esm({
|
|
32110
32216
|
"src/recall-card.ts"() {
|
|
32111
32217
|
"use strict";
|
|
@@ -32129,6 +32235,9 @@ var init_recall_card = __esm({
|
|
|
32129
32235
|
IDLE_STATUS = `${AMBER}\u26A1${RESET} ${DIM}errata \xB7 watching${RESET}`;
|
|
32130
32236
|
latestBySession = /* @__PURE__ */ new Map();
|
|
32131
32237
|
MAX_SESSIONS = 256;
|
|
32238
|
+
latestByAgent = /* @__PURE__ */ new Map();
|
|
32239
|
+
agentKey = (sessionId, agentId) => `${sessionId}#${agentId}`;
|
|
32240
|
+
SUBAGENT_ROW_TTL_MS = 30 * 6e4;
|
|
32132
32241
|
openBySession = /* @__PURE__ */ new Map();
|
|
32133
32242
|
}
|
|
32134
32243
|
});
|
|
@@ -32243,18 +32352,141 @@ var init_recall_signal = __esm({
|
|
|
32243
32352
|
}
|
|
32244
32353
|
});
|
|
32245
32354
|
|
|
32355
|
+
// src/session-registry.ts
|
|
32356
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6, realpathSync, writeFileSync as writeFileSync7 } from "node:fs";
|
|
32357
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
32358
|
+
import { resolve } from "node:path";
|
|
32359
|
+
function shipsFromWorkspace(root, env2 = process.env) {
|
|
32360
|
+
return Boolean(env2["VITEST"]) || !isScratchWorkspace(root);
|
|
32361
|
+
}
|
|
32362
|
+
function isScratchWorkspace(root, tmp = tmpdir2()) {
|
|
32363
|
+
const norm = (p) => {
|
|
32364
|
+
let real = p;
|
|
32365
|
+
try {
|
|
32366
|
+
real = realpathSync.native(p);
|
|
32367
|
+
} catch {
|
|
32368
|
+
}
|
|
32369
|
+
return resolve(real).replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
32370
|
+
};
|
|
32371
|
+
const r = norm(root);
|
|
32372
|
+
const t = norm(tmp);
|
|
32373
|
+
return r === t || r.startsWith(`${t}/`);
|
|
32374
|
+
}
|
|
32375
|
+
function parseOrigin(raw2) {
|
|
32376
|
+
if (typeof raw2 !== "string") return void 0;
|
|
32377
|
+
const v = raw2.trim();
|
|
32378
|
+
if (!v || v.includes("%")) return void 0;
|
|
32379
|
+
return /^[\w.:-]{1,64}$/.test(v) ? v : void 0;
|
|
32380
|
+
}
|
|
32381
|
+
function createSessionRegistry(opts = {}) {
|
|
32382
|
+
const idleMs = opts.idleMs ?? SESSION_IDLE_MS;
|
|
32383
|
+
const lastSeen = /* @__PURE__ */ new Map();
|
|
32384
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
32385
|
+
const ended = /* @__PURE__ */ new Set();
|
|
32386
|
+
const origins = new Map(loadOrigins(opts.originsPath));
|
|
32387
|
+
let ver = 0;
|
|
32388
|
+
let lastLiveCount = -1;
|
|
32389
|
+
const persist = () => {
|
|
32390
|
+
if (!opts.originsPath) return;
|
|
32391
|
+
try {
|
|
32392
|
+
while (origins.size > MAX_ORIGINS) origins.delete(origins.keys().next().value);
|
|
32393
|
+
writeFileSync7(opts.originsPath, JSON.stringify(Object.fromEntries(origins)));
|
|
32394
|
+
} catch {
|
|
32395
|
+
}
|
|
32396
|
+
};
|
|
32397
|
+
const ownLive = (id, nowMs) => {
|
|
32398
|
+
const seen = lastSeen.get(id);
|
|
32399
|
+
return seen !== void 0 && !ended.has(id) && nowMs - seen < idleMs;
|
|
32400
|
+
};
|
|
32401
|
+
const registry2 = {
|
|
32402
|
+
touch(sessionId, nowMs, o = {}) {
|
|
32403
|
+
if (!sessionId) return;
|
|
32404
|
+
const wasLive = ownLive(sessionId, nowMs);
|
|
32405
|
+
lastSeen.set(sessionId, nowMs);
|
|
32406
|
+
ended.delete(sessionId);
|
|
32407
|
+
if (o.parent) parentOf.set(sessionId, o.parent);
|
|
32408
|
+
const origin = o.origin ?? (o.parent ? origins.get(o.parent) : void 0);
|
|
32409
|
+
if (origin && origins.get(sessionId) !== origin) {
|
|
32410
|
+
origins.set(sessionId, origin);
|
|
32411
|
+
persist();
|
|
32412
|
+
ver++;
|
|
32413
|
+
}
|
|
32414
|
+
if (!wasLive) ver++;
|
|
32415
|
+
},
|
|
32416
|
+
end(sessionId) {
|
|
32417
|
+
if (!sessionId || ended.has(sessionId)) return;
|
|
32418
|
+
ended.add(sessionId);
|
|
32419
|
+
ver++;
|
|
32420
|
+
},
|
|
32421
|
+
isLive(sessionId, nowMs) {
|
|
32422
|
+
if (ownLive(sessionId, nowMs)) return true;
|
|
32423
|
+
const parent = parentOf.get(sessionId);
|
|
32424
|
+
return parent !== void 0 && ownLive(parent, nowMs);
|
|
32425
|
+
},
|
|
32426
|
+
originOf: (sessionId) => origins.get(sessionId) ?? origins.get(parentOf.get(sessionId) ?? ""),
|
|
32427
|
+
originSessions: () => [...origins.keys()],
|
|
32428
|
+
isOwn: (sessionId, viewer) => sessionId === viewer || parentOf.get(sessionId) === viewer,
|
|
32429
|
+
version(nowMs) {
|
|
32430
|
+
let live3 = 0;
|
|
32431
|
+
for (const id of lastSeen.keys()) if (ownLive(id, nowMs)) live3++;
|
|
32432
|
+
if (live3 !== lastLiveCount) {
|
|
32433
|
+
lastLiveCount = live3;
|
|
32434
|
+
ver++;
|
|
32435
|
+
}
|
|
32436
|
+
return ver;
|
|
32437
|
+
}
|
|
32438
|
+
};
|
|
32439
|
+
return registry2;
|
|
32440
|
+
}
|
|
32441
|
+
function loadOrigins(path2) {
|
|
32442
|
+
if (!path2 || !existsSync8(path2)) return [];
|
|
32443
|
+
try {
|
|
32444
|
+
const raw2 = JSON.parse(readFileSync6(path2, "utf8"));
|
|
32445
|
+
return Object.entries(raw2).flatMap(([k, v]) => typeof v === "string" ? [[k, v]] : []);
|
|
32446
|
+
} catch {
|
|
32447
|
+
return [];
|
|
32448
|
+
}
|
|
32449
|
+
}
|
|
32450
|
+
function sessionsOf(node2) {
|
|
32451
|
+
const s = node2.attrs["sources"];
|
|
32452
|
+
return Array.isArray(s) ? s.filter((x) => typeof x === "string" && x.length > 0) : [];
|
|
32453
|
+
}
|
|
32454
|
+
function capturedOnlyBy(node2, sessions) {
|
|
32455
|
+
const recorded = sessionsOf(node2);
|
|
32456
|
+
return recorded.length > 0 && recorded.every((s) => sessions.has(s));
|
|
32457
|
+
}
|
|
32458
|
+
function isQuarantined(node2, reg) {
|
|
32459
|
+
const sessions = sessionsOf(node2);
|
|
32460
|
+
return sessions.length > 0 && sessions.every((s) => reg.originOf(s) !== void 0);
|
|
32461
|
+
}
|
|
32462
|
+
function hiddenFrom(node2, viewer, reg, nowMs) {
|
|
32463
|
+
const sessions = sessionsOf(node2);
|
|
32464
|
+
if (sessions.length === 0 || sessions.some((s) => reg.isOwn(s, viewer))) return false;
|
|
32465
|
+
if (isQuarantined(node2, reg)) return true;
|
|
32466
|
+
return sessions.every((s) => reg.isLive(s, nowMs));
|
|
32467
|
+
}
|
|
32468
|
+
var ORIGIN_HEADER, SESSION_IDLE_MS, MAX_ORIGINS;
|
|
32469
|
+
var init_session_registry = __esm({
|
|
32470
|
+
"src/session-registry.ts"() {
|
|
32471
|
+
"use strict";
|
|
32472
|
+
ORIGIN_HEADER = "x-errata-origin";
|
|
32473
|
+
SESSION_IDLE_MS = 20 * 6e4;
|
|
32474
|
+
MAX_ORIGINS = 5e4;
|
|
32475
|
+
}
|
|
32476
|
+
});
|
|
32477
|
+
|
|
32246
32478
|
// src/review.ts
|
|
32247
|
-
import { existsSync as
|
|
32479
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync8 } from "node:fs";
|
|
32248
32480
|
function loadReviewQueue(paths) {
|
|
32249
|
-
if (!
|
|
32481
|
+
if (!existsSync9(paths.reviewQueue)) return [];
|
|
32250
32482
|
try {
|
|
32251
|
-
return JSON.parse(
|
|
32483
|
+
return JSON.parse(readFileSync7(paths.reviewQueue, "utf8"));
|
|
32252
32484
|
} catch {
|
|
32253
32485
|
return [];
|
|
32254
32486
|
}
|
|
32255
32487
|
}
|
|
32256
32488
|
function saveReviewQueue(paths, queue) {
|
|
32257
|
-
|
|
32489
|
+
writeFileSync8(paths.reviewQueue, JSON.stringify(queue, null, 2), "utf8");
|
|
32258
32490
|
}
|
|
32259
32491
|
function addProposal(paths, store, node2, reason, surprise) {
|
|
32260
32492
|
const queue = loadReviewQueue(paths);
|
|
@@ -32324,26 +32556,26 @@ var init_consent = __esm({
|
|
|
32324
32556
|
});
|
|
32325
32557
|
|
|
32326
32558
|
// src/git-remote.ts
|
|
32327
|
-
import { existsSync as
|
|
32328
|
-
import { isAbsolute as isAbsolute2, join as join8, resolve } from "node:path";
|
|
32559
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8, statSync } from "node:fs";
|
|
32560
|
+
import { isAbsolute as isAbsolute2, join as join8, resolve as resolve2 } from "node:path";
|
|
32329
32561
|
function resolveGitDir(root) {
|
|
32330
32562
|
const dotGit = join8(root, ".git");
|
|
32331
32563
|
try {
|
|
32332
32564
|
const st = statSync(dotGit);
|
|
32333
32565
|
if (st.isDirectory()) return dotGit;
|
|
32334
|
-
const m = /^gitdir:\s*(.+?)\s*$/m.exec(
|
|
32566
|
+
const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync8(dotGit, "utf8"));
|
|
32335
32567
|
if (!m) return null;
|
|
32336
32568
|
const dir = m[1];
|
|
32337
|
-
return isAbsolute2(dir) ? dir :
|
|
32569
|
+
return isAbsolute2(dir) ? dir : resolve2(root, dir);
|
|
32338
32570
|
} catch {
|
|
32339
32571
|
return null;
|
|
32340
32572
|
}
|
|
32341
32573
|
}
|
|
32342
32574
|
function gitConfigPath(gitDir) {
|
|
32343
32575
|
const commondirFile = join8(gitDir, "commondir");
|
|
32344
|
-
if (
|
|
32345
|
-
const common =
|
|
32346
|
-
const commonDir = isAbsolute2(common) ? common :
|
|
32576
|
+
if (existsSync10(commondirFile)) {
|
|
32577
|
+
const common = readFileSync8(commondirFile, "utf8").trim();
|
|
32578
|
+
const commonDir = isAbsolute2(common) ? common : resolve2(gitDir, common);
|
|
32347
32579
|
return join8(commonDir, "config");
|
|
32348
32580
|
}
|
|
32349
32581
|
return join8(gitDir, "config");
|
|
@@ -32352,10 +32584,10 @@ function readRemotes(root) {
|
|
|
32352
32584
|
const gitDir = resolveGitDir(root);
|
|
32353
32585
|
if (!gitDir) return [];
|
|
32354
32586
|
const cfgPath = gitConfigPath(gitDir);
|
|
32355
|
-
if (!
|
|
32587
|
+
if (!existsSync10(cfgPath)) return [];
|
|
32356
32588
|
let txt;
|
|
32357
32589
|
try {
|
|
32358
|
-
txt =
|
|
32590
|
+
txt = readFileSync8(cfgPath, "utf8");
|
|
32359
32591
|
} catch {
|
|
32360
32592
|
return [];
|
|
32361
32593
|
}
|
|
@@ -32381,7 +32613,7 @@ var init_git_remote = __esm({
|
|
|
32381
32613
|
});
|
|
32382
32614
|
|
|
32383
32615
|
// src/profile.ts
|
|
32384
|
-
import { existsSync as
|
|
32616
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "node:fs";
|
|
32385
32617
|
import { createHash as createHash5 } from "node:crypto";
|
|
32386
32618
|
import { join as join9 } from "node:path";
|
|
32387
32619
|
function workspaceId(root) {
|
|
@@ -32406,13 +32638,13 @@ function refreshRepoLocator(root, profile) {
|
|
|
32406
32638
|
}
|
|
32407
32639
|
function loadProfile(root) {
|
|
32408
32640
|
const p = workspacePaths(root);
|
|
32409
|
-
if (!
|
|
32410
|
-
return JSON.parse(
|
|
32641
|
+
if (!existsSync11(p.workspaceJson)) return null;
|
|
32642
|
+
return JSON.parse(readFileSync9(p.workspaceJson, "utf8"));
|
|
32411
32643
|
}
|
|
32412
32644
|
function saveProfile(root, profile) {
|
|
32413
32645
|
const p = workspacePaths(root);
|
|
32414
32646
|
ensureDir(p.configDir);
|
|
32415
|
-
|
|
32647
|
+
writeFileSync9(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
|
|
32416
32648
|
}
|
|
32417
32649
|
function autodetectProfile(root) {
|
|
32418
32650
|
const id = workspaceId(root);
|
|
@@ -32421,12 +32653,12 @@ function autodetectProfile(root) {
|
|
|
32421
32653
|
const locator = detectRepoLocator(root);
|
|
32422
32654
|
if (locator) p.repoLocator = locator;
|
|
32423
32655
|
const pkgPath = join9(root, "package.json");
|
|
32424
|
-
if (
|
|
32656
|
+
if (existsSync11(pkgPath)) {
|
|
32425
32657
|
try {
|
|
32426
|
-
const pkg = JSON.parse(
|
|
32658
|
+
const pkg = JSON.parse(readFileSync9(pkgPath, "utf8"));
|
|
32427
32659
|
const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
32428
32660
|
p.languages.push("javascript");
|
|
32429
|
-
if (
|
|
32661
|
+
if (existsSync11(join9(root, "tsconfig.json")) || deps["typescript"]) {
|
|
32430
32662
|
p.languages.push("typescript");
|
|
32431
32663
|
}
|
|
32432
32664
|
const nodeVer = pkg.engines?.node?.trim();
|
|
@@ -32448,9 +32680,9 @@ function autodetectProfile(root) {
|
|
|
32448
32680
|
}
|
|
32449
32681
|
}
|
|
32450
32682
|
const pyproject = join9(root, "pyproject.toml");
|
|
32451
|
-
if (
|
|
32683
|
+
if (existsSync11(pyproject)) {
|
|
32452
32684
|
try {
|
|
32453
|
-
const txt =
|
|
32685
|
+
const txt = readFileSync9(pyproject, "utf8");
|
|
32454
32686
|
const py = /python\s*=\s*"([^"]+)"/.exec(txt)?.[1];
|
|
32455
32687
|
p.languages.push("python");
|
|
32456
32688
|
p.stack.push(`python@${py ?? "3"}`);
|
|
@@ -32462,15 +32694,15 @@ function autodetectProfile(root) {
|
|
|
32462
32694
|
}
|
|
32463
32695
|
}
|
|
32464
32696
|
const reqs = join9(root, "requirements.txt");
|
|
32465
|
-
if (
|
|
32697
|
+
if (existsSync11(reqs)) {
|
|
32466
32698
|
if (!p.languages.includes("python")) p.languages.push("python");
|
|
32467
32699
|
if (!p.stack.includes("python@3")) p.stack.push("python@3");
|
|
32468
32700
|
}
|
|
32469
|
-
if (
|
|
32701
|
+
if (existsSync11(join9(root, "go.mod"))) {
|
|
32470
32702
|
p.languages.push("go");
|
|
32471
32703
|
p.stack.push("go");
|
|
32472
32704
|
}
|
|
32473
|
-
if (
|
|
32705
|
+
if (existsSync11(join9(root, "Cargo.toml"))) {
|
|
32474
32706
|
p.languages.push("rust");
|
|
32475
32707
|
p.stack.push("rust");
|
|
32476
32708
|
}
|
|
@@ -32575,12 +32807,12 @@ var init_identity2 = __esm({
|
|
|
32575
32807
|
});
|
|
32576
32808
|
|
|
32577
32809
|
// src/checkout-root.ts
|
|
32578
|
-
import { existsSync as
|
|
32579
|
-
import { basename as basename2, dirname as dirname6, isAbsolute as isAbsolute3, join as join10, resolve as
|
|
32810
|
+
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
|
|
32811
|
+
import { basename as basename2, dirname as dirname6, isAbsolute as isAbsolute3, join as join10, resolve as resolve3 } from "node:path";
|
|
32580
32812
|
function nearestGitRoot(dir) {
|
|
32581
|
-
let cur =
|
|
32813
|
+
let cur = resolve3(dir);
|
|
32582
32814
|
for (; ; ) {
|
|
32583
|
-
if (
|
|
32815
|
+
if (existsSync12(join10(cur, ".git"))) return cur;
|
|
32584
32816
|
const parent = dirname6(cur);
|
|
32585
32817
|
if (parent === cur) return null;
|
|
32586
32818
|
cur = parent;
|
|
@@ -32590,22 +32822,22 @@ function mainCheckoutOfWorktree(root) {
|
|
|
32590
32822
|
const gitDir = resolveGitDir(root);
|
|
32591
32823
|
if (!gitDir || gitDir === join10(root, ".git")) return null;
|
|
32592
32824
|
const commondirFile = join10(gitDir, "commondir");
|
|
32593
|
-
if (!
|
|
32825
|
+
if (!existsSync12(commondirFile)) return null;
|
|
32594
32826
|
let common;
|
|
32595
32827
|
try {
|
|
32596
|
-
common =
|
|
32828
|
+
common = readFileSync10(commondirFile, "utf8").trim();
|
|
32597
32829
|
} catch {
|
|
32598
32830
|
return null;
|
|
32599
32831
|
}
|
|
32600
|
-
const commonDir =
|
|
32832
|
+
const commonDir = resolve3(isAbsolute3(common) ? common : resolve3(gitDir, common));
|
|
32601
32833
|
if (basename2(commonDir) !== ".git") return null;
|
|
32602
32834
|
const main2 = dirname6(commonDir);
|
|
32603
|
-
return
|
|
32835
|
+
return existsSync12(join10(main2, ".git")) ? main2 : null;
|
|
32604
32836
|
}
|
|
32605
32837
|
function checkoutRootOf(cwd) {
|
|
32606
32838
|
const root = nearestGitRoot(cwd);
|
|
32607
32839
|
const main2 = root ? mainCheckoutOfWorktree(root) : null;
|
|
32608
|
-
return main2 ??
|
|
32840
|
+
return main2 ?? resolve3(cwd);
|
|
32609
32841
|
}
|
|
32610
32842
|
function isLinkedWorktree(root) {
|
|
32611
32843
|
return mainCheckoutOfWorktree(root) !== null;
|
|
@@ -32619,7 +32851,7 @@ var init_checkout_root = __esm({
|
|
|
32619
32851
|
|
|
32620
32852
|
// src/process-identity.ts
|
|
32621
32853
|
import { execFileSync } from "node:child_process";
|
|
32622
|
-
import { readFileSync as
|
|
32854
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
32623
32855
|
function readProcessIdentity(pid, fresh = false) {
|
|
32624
32856
|
if (!Number.isSafeInteger(pid) || pid <= 0) return null;
|
|
32625
32857
|
if (pid === process.pid && self) return self;
|
|
@@ -32644,10 +32876,10 @@ function readProcessIdentity(pid, fresh = false) {
|
|
|
32644
32876
|
if (!/^\d+$/.test(ticks)) return null;
|
|
32645
32877
|
value = { key: `win32:${ticks}`, bornAt: Number((BigInt(ticks) - 621355968000000000n) / 10000n) };
|
|
32646
32878
|
} else if (process.platform === "linux") {
|
|
32647
|
-
const stat4 =
|
|
32879
|
+
const stat4 = readFileSync11(`/proc/${pid}/stat`, "utf8");
|
|
32648
32880
|
const ticks = stat4.slice(stat4.lastIndexOf(")") + 2).split(" ")[19];
|
|
32649
|
-
const bootId =
|
|
32650
|
-
const boot = /^btime (\d+)$/m.exec(
|
|
32881
|
+
const bootId = readFileSync11("/proc/sys/kernel/random/boot_id", "utf8").trim();
|
|
32882
|
+
const boot = /^btime (\d+)$/m.exec(readFileSync11("/proc/stat", "utf8"))?.[1];
|
|
32651
32883
|
const hz = Number(run3("getconf", ["CLK_TCK"]));
|
|
32652
32884
|
if (!boot || !/^\d+$/.test(ticks) || !Number.isFinite(hz) || hz <= 0) return null;
|
|
32653
32885
|
value = { key: `linux:${bootId}:${ticks}`, bornAt: Number(boot) * 1e3 + Number(ticks) * 1e3 / hz };
|
|
@@ -32673,7 +32905,7 @@ var init_process_identity = __esm({
|
|
|
32673
32905
|
});
|
|
32674
32906
|
|
|
32675
32907
|
// src/lock.ts
|
|
32676
|
-
import { existsSync as
|
|
32908
|
+
import { existsSync as existsSync13, readFileSync as readFileSync12, unlinkSync as unlinkSync2 } from "node:fs";
|
|
32677
32909
|
function daemonLockPayload(lock) {
|
|
32678
32910
|
return JSON.stringify({
|
|
32679
32911
|
pid: lock.pid,
|
|
@@ -32708,9 +32940,9 @@ function isProcessAlive(pid) {
|
|
|
32708
32940
|
}
|
|
32709
32941
|
}
|
|
32710
32942
|
function readDaemonLock(lockPath) {
|
|
32711
|
-
if (!
|
|
32943
|
+
if (!existsSync13(lockPath)) return null;
|
|
32712
32944
|
try {
|
|
32713
|
-
return parseDaemonLock(
|
|
32945
|
+
return parseDaemonLock(readFileSync12(lockPath, "utf8"));
|
|
32714
32946
|
} catch {
|
|
32715
32947
|
return null;
|
|
32716
32948
|
}
|
|
@@ -32740,7 +32972,7 @@ function daemonLockBlocksStartup(lockPath) {
|
|
|
32740
32972
|
function stopLockedDaemon(lockPath) {
|
|
32741
32973
|
let original;
|
|
32742
32974
|
try {
|
|
32743
|
-
original =
|
|
32975
|
+
original = readFileSync12(lockPath, "utf8");
|
|
32744
32976
|
} catch {
|
|
32745
32977
|
return "missing";
|
|
32746
32978
|
}
|
|
@@ -32748,7 +32980,7 @@ function stopLockedDaemon(lockPath) {
|
|
|
32748
32980
|
if (!lock) return "unknown";
|
|
32749
32981
|
const state = daemonLockState(lock, true);
|
|
32750
32982
|
try {
|
|
32751
|
-
if (
|
|
32983
|
+
if (readFileSync12(lockPath, "utf8") !== original) return "changed";
|
|
32752
32984
|
} catch {
|
|
32753
32985
|
return "changed";
|
|
32754
32986
|
}
|
|
@@ -32773,16 +33005,16 @@ var init_lock = __esm({
|
|
|
32773
33005
|
});
|
|
32774
33006
|
|
|
32775
33007
|
// src/registry.ts
|
|
32776
|
-
import { existsSync as
|
|
33008
|
+
import { existsSync as existsSync14, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "node:fs";
|
|
32777
33009
|
import { join as join11 } from "node:path";
|
|
32778
33010
|
function registryPath() {
|
|
32779
33011
|
return process.env["ERRATA_REGISTRY_PATH"] ?? join11(globalDir(), "workspaces.json");
|
|
32780
33012
|
}
|
|
32781
33013
|
function read() {
|
|
32782
33014
|
const p = registryPath();
|
|
32783
|
-
if (!
|
|
33015
|
+
if (!existsSync14(p)) return { version: 1, workspaces: {} };
|
|
32784
33016
|
try {
|
|
32785
|
-
const parsed = JSON.parse(
|
|
33017
|
+
const parsed = JSON.parse(readFileSync13(p, "utf8"));
|
|
32786
33018
|
return { version: 1, workspaces: parsed.workspaces ?? {} };
|
|
32787
33019
|
} catch {
|
|
32788
33020
|
return { version: 1, workspaces: {} };
|
|
@@ -32790,9 +33022,9 @@ function read() {
|
|
|
32790
33022
|
}
|
|
32791
33023
|
function registryCorrupt() {
|
|
32792
33024
|
const p = registryPath();
|
|
32793
|
-
if (!
|
|
33025
|
+
if (!existsSync14(p)) return false;
|
|
32794
33026
|
try {
|
|
32795
|
-
JSON.parse(
|
|
33027
|
+
JSON.parse(readFileSync13(p, "utf8"));
|
|
32796
33028
|
return false;
|
|
32797
33029
|
} catch {
|
|
32798
33030
|
return true;
|
|
@@ -32800,7 +33032,7 @@ function registryCorrupt() {
|
|
|
32800
33032
|
}
|
|
32801
33033
|
function write(reg) {
|
|
32802
33034
|
ensureDir(globalDir());
|
|
32803
|
-
|
|
33035
|
+
writeFileSync10(registryPath(), JSON.stringify(reg, null, 2), "utf8");
|
|
32804
33036
|
}
|
|
32805
33037
|
function registerWorkspace(profile, root, now = Date.now()) {
|
|
32806
33038
|
if (isLinkedWorktree(root)) return;
|
|
@@ -32845,7 +33077,7 @@ function pruneMissingWorkspaces() {
|
|
|
32845
33077
|
const reg = read();
|
|
32846
33078
|
const removed = [];
|
|
32847
33079
|
for (const [id, entry] of Object.entries(reg.workspaces)) {
|
|
32848
|
-
if (!
|
|
33080
|
+
if (!existsSync14(entry.path)) {
|
|
32849
33081
|
removed.push(entry);
|
|
32850
33082
|
delete reg.workspaces[id];
|
|
32851
33083
|
}
|
|
@@ -32854,7 +33086,7 @@ function pruneMissingWorkspaces() {
|
|
|
32854
33086
|
return removed;
|
|
32855
33087
|
}
|
|
32856
33088
|
function workspaceStatus(entry) {
|
|
32857
|
-
const missing = !
|
|
33089
|
+
const missing = !existsSync14(entry.path);
|
|
32858
33090
|
const lockPath = workspacePaths(entry.path).daemonLock;
|
|
32859
33091
|
let running = false;
|
|
32860
33092
|
let webUiUrl = null;
|
|
@@ -34173,7 +34405,7 @@ var init_dual_augment = __esm({
|
|
|
34173
34405
|
|
|
34174
34406
|
// ../../packages/indexer/src/parse-cache.ts
|
|
34175
34407
|
import { createHash as createHash6 } from "node:crypto";
|
|
34176
|
-
import { existsSync as
|
|
34408
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync6, readFileSync as readFileSync14, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync11 } from "node:fs";
|
|
34177
34409
|
import { homedir as homedir3 } from "node:os";
|
|
34178
34410
|
import { join as join12 } from "node:path";
|
|
34179
34411
|
function parseCacheDir() {
|
|
@@ -34188,7 +34420,7 @@ function entryPath(dir, key) {
|
|
|
34188
34420
|
function readParseCache(dir, key) {
|
|
34189
34421
|
const file2 = entryPath(dir, key);
|
|
34190
34422
|
try {
|
|
34191
|
-
const raw2 =
|
|
34423
|
+
const raw2 = readFileSync14(file2, "utf8");
|
|
34192
34424
|
const parsed = JSON.parse(raw2);
|
|
34193
34425
|
if (parsed.v !== PARSE_CACHE_VERSION || !Array.isArray(parsed.symbols)) return null;
|
|
34194
34426
|
return { symbols: parsed.symbols, reExports: parsed.reExports ?? [] };
|
|
@@ -34208,7 +34440,7 @@ function writeParseCache(dir, key, providerId, value) {
|
|
|
34208
34440
|
if (body2.length > MAX_ENTRY_BYTES) return;
|
|
34209
34441
|
const file2 = entryPath(dir, key);
|
|
34210
34442
|
mkdirSync6(join12(dir, key.slice(0, 2)), { recursive: true });
|
|
34211
|
-
|
|
34443
|
+
writeFileSync11(file2, body2);
|
|
34212
34444
|
} catch {
|
|
34213
34445
|
}
|
|
34214
34446
|
}
|
|
@@ -34217,7 +34449,7 @@ function sweepParseCacheOnce(dir, now = Date.now()) {
|
|
|
34217
34449
|
sweptThisProcess = true;
|
|
34218
34450
|
let removed = 0;
|
|
34219
34451
|
try {
|
|
34220
|
-
if (!
|
|
34452
|
+
if (!existsSync15(dir)) return 0;
|
|
34221
34453
|
for (const bucket of readdirSync2(dir)) {
|
|
34222
34454
|
const bucketDir = join12(dir, bucket);
|
|
34223
34455
|
let names;
|
|
@@ -34475,7 +34707,7 @@ var init_identity3 = __esm({
|
|
|
34475
34707
|
});
|
|
34476
34708
|
|
|
34477
34709
|
// ../../packages/indexer/src/pipeline.ts
|
|
34478
|
-
import { appendFileSync, readFileSync as
|
|
34710
|
+
import { appendFileSync, readFileSync as readFileSync15, statSync as statSync3 } from "node:fs";
|
|
34479
34711
|
import { readdir } from "node:fs/promises";
|
|
34480
34712
|
import { extname, join as join13, relative as relative2, sep } from "node:path";
|
|
34481
34713
|
import { createHash as createHash7 } from "node:crypto";
|
|
@@ -34615,7 +34847,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
|
|
|
34615
34847
|
for (const rel of [...changedRelPaths]) {
|
|
34616
34848
|
let h;
|
|
34617
34849
|
try {
|
|
34618
|
-
h = createHash7("sha256").update(
|
|
34850
|
+
h = createHash7("sha256").update(readFileSync15(join13(rootPath, rel))).digest("hex");
|
|
34619
34851
|
} catch {
|
|
34620
34852
|
continue;
|
|
34621
34853
|
}
|
|
@@ -34670,7 +34902,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
|
|
|
34670
34902
|
if (!provider) continue;
|
|
34671
34903
|
let symbols;
|
|
34672
34904
|
try {
|
|
34673
|
-
symbols = provider.extractSymbols(
|
|
34905
|
+
symbols = provider.extractSymbols(readFileSync15(abs, "utf8"), abs);
|
|
34674
34906
|
} catch {
|
|
34675
34907
|
continue;
|
|
34676
34908
|
}
|
|
@@ -34990,7 +35222,7 @@ async function runIndexer(store, opts) {
|
|
|
34990
35222
|
report.filesSkipped++;
|
|
34991
35223
|
continue;
|
|
34992
35224
|
}
|
|
34993
|
-
source =
|
|
35225
|
+
source = readFileSync15(f.absPath, "utf8");
|
|
34994
35226
|
} catch {
|
|
34995
35227
|
report.filesSkipped++;
|
|
34996
35228
|
continue;
|
|
@@ -35062,7 +35294,7 @@ async function runIndexer(store, opts) {
|
|
|
35062
35294
|
const depth = fileNode.relPath.split("/").length;
|
|
35063
35295
|
if (depth !== 3) continue;
|
|
35064
35296
|
try {
|
|
35065
|
-
const pkg = JSON.parse(
|
|
35297
|
+
const pkg = JSON.parse(readFileSync15(fileNode.absPath, "utf8"));
|
|
35066
35298
|
if (!pkg.name) continue;
|
|
35067
35299
|
const pkgDir = fileNode.relPath.replace(/\/package\.json$/, "");
|
|
35068
35300
|
const candidates = [
|
|
@@ -35538,7 +35770,7 @@ function upsertFile(store, id, f, workspaceId2, skip) {
|
|
|
35538
35770
|
if (existing && fileUnchanged(existing.attrs, f, skip)) return;
|
|
35539
35771
|
let contentHash;
|
|
35540
35772
|
try {
|
|
35541
|
-
contentHash = createHash7("sha256").update(
|
|
35773
|
+
contentHash = createHash7("sha256").update(readFileSync15(f.absPath)).digest("hex");
|
|
35542
35774
|
} catch {
|
|
35543
35775
|
}
|
|
35544
35776
|
const carried = { ...existing?.attrs ?? {} };
|
|
@@ -36155,13 +36387,13 @@ async function Module2(moduleArg = {}) {
|
|
|
36155
36387
|
}
|
|
36156
36388
|
readAsync = /* @__PURE__ */ __name(async (url2) => {
|
|
36157
36389
|
if (isFileURI(url2)) {
|
|
36158
|
-
return new Promise((
|
|
36390
|
+
return new Promise((resolve9, reject) => {
|
|
36159
36391
|
var xhr = new XMLHttpRequest();
|
|
36160
36392
|
xhr.open("GET", url2, true);
|
|
36161
36393
|
xhr.responseType = "arraybuffer";
|
|
36162
36394
|
xhr.onload = () => {
|
|
36163
36395
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
36164
|
-
|
|
36396
|
+
resolve9(xhr.response);
|
|
36165
36397
|
return;
|
|
36166
36398
|
}
|
|
36167
36399
|
reject(xhr.status);
|
|
@@ -36357,9 +36589,9 @@ async function Module2(moduleArg = {}) {
|
|
|
36357
36589
|
__name(receiveInstantiationResult, "receiveInstantiationResult");
|
|
36358
36590
|
var info2 = getWasmImports();
|
|
36359
36591
|
if (Module["instantiateWasm"]) {
|
|
36360
|
-
return new Promise((
|
|
36592
|
+
return new Promise((resolve9, reject) => {
|
|
36361
36593
|
Module["instantiateWasm"](info2, (mod, inst) => {
|
|
36362
|
-
|
|
36594
|
+
resolve9(receiveInstance(mod, inst));
|
|
36363
36595
|
});
|
|
36364
36596
|
});
|
|
36365
36597
|
}
|
|
@@ -37690,8 +37922,8 @@ async function Module2(moduleArg = {}) {
|
|
|
37690
37922
|
if (runtimeInitialized) {
|
|
37691
37923
|
moduleRtn = Module;
|
|
37692
37924
|
} else {
|
|
37693
|
-
moduleRtn = new Promise((
|
|
37694
|
-
readyPromiseResolve =
|
|
37925
|
+
moduleRtn = new Promise((resolve9, reject) => {
|
|
37926
|
+
readyPromiseResolve = resolve9;
|
|
37695
37927
|
readyPromiseReject = reject;
|
|
37696
37928
|
});
|
|
37697
37929
|
}
|
|
@@ -39922,7 +40154,7 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
39922
40154
|
// ../../packages/indexer/src/languages/tree-sitter-loader.ts
|
|
39923
40155
|
import { fileURLToPath } from "node:url";
|
|
39924
40156
|
import { dirname as dirname7, join as join14 } from "node:path";
|
|
39925
|
-
import { existsSync as
|
|
40157
|
+
import { existsSync as existsSync16, readdirSync as readdirSync3 } from "node:fs";
|
|
39926
40158
|
import { createRequire as createRequire2 } from "node:module";
|
|
39927
40159
|
function entryDir() {
|
|
39928
40160
|
try {
|
|
@@ -39937,7 +40169,7 @@ function entryDir() {
|
|
|
39937
40169
|
function findWasmDir() {
|
|
39938
40170
|
const here = entryDir();
|
|
39939
40171
|
const seaWasm = join14(here, "resources", "wasm");
|
|
39940
|
-
if (
|
|
40172
|
+
if (existsSync16(join14(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
|
|
39941
40173
|
let dir = here;
|
|
39942
40174
|
for (let i2 = 0; i2 < 6; i2++) {
|
|
39943
40175
|
const flat = join14(
|
|
@@ -39947,13 +40179,13 @@ function findWasmDir() {
|
|
|
39947
40179
|
"tree-sitter-wasm",
|
|
39948
40180
|
"wasm"
|
|
39949
40181
|
);
|
|
39950
|
-
if (
|
|
40182
|
+
if (existsSync16(join14(flat, "tree-sitter-typescript.wasm"))) return flat;
|
|
39951
40183
|
dir = dirname7(dir);
|
|
39952
40184
|
}
|
|
39953
40185
|
let root = here;
|
|
39954
40186
|
for (let i2 = 0; i2 < 6; i2++) {
|
|
39955
40187
|
const pnpmDir = join14(root, "node_modules", ".pnpm");
|
|
39956
|
-
if (
|
|
40188
|
+
if (existsSync16(pnpmDir)) {
|
|
39957
40189
|
for (const entry of readdirSync3(pnpmDir)) {
|
|
39958
40190
|
if (entry.startsWith("@vscode+tree-sitter-wasm@")) {
|
|
39959
40191
|
const candidate = join14(
|
|
@@ -39964,7 +40196,7 @@ function findWasmDir() {
|
|
|
39964
40196
|
"tree-sitter-wasm",
|
|
39965
40197
|
"wasm"
|
|
39966
40198
|
);
|
|
39967
|
-
if (
|
|
40199
|
+
if (existsSync16(join14(candidate, "tree-sitter-typescript.wasm"))) {
|
|
39968
40200
|
return candidate;
|
|
39969
40201
|
}
|
|
39970
40202
|
}
|
|
@@ -39979,17 +40211,17 @@ function findWasmDir() {
|
|
|
39979
40211
|
function findRuntimeDir() {
|
|
39980
40212
|
const here = entryDir();
|
|
39981
40213
|
const seaRuntime = join14(here, "resources", "wasm");
|
|
39982
|
-
if (
|
|
40214
|
+
if (existsSync16(join14(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
|
|
39983
40215
|
let dir = here;
|
|
39984
40216
|
for (let i2 = 0; i2 < 6; i2++) {
|
|
39985
40217
|
const flat = join14(dir, "node_modules", "web-tree-sitter");
|
|
39986
|
-
if (
|
|
40218
|
+
if (existsSync16(join14(flat, "web-tree-sitter.wasm"))) return flat;
|
|
39987
40219
|
dir = dirname7(dir);
|
|
39988
40220
|
}
|
|
39989
40221
|
let root = here;
|
|
39990
40222
|
for (let i2 = 0; i2 < 6; i2++) {
|
|
39991
40223
|
const pnpmDir = join14(root, "node_modules", ".pnpm");
|
|
39992
|
-
if (
|
|
40224
|
+
if (existsSync16(pnpmDir)) {
|
|
39993
40225
|
for (const entry of readdirSync3(pnpmDir)) {
|
|
39994
40226
|
if (entry.startsWith("web-tree-sitter@")) {
|
|
39995
40227
|
const candidate = join14(
|
|
@@ -39998,7 +40230,7 @@ function findRuntimeDir() {
|
|
|
39998
40230
|
"node_modules",
|
|
39999
40231
|
"web-tree-sitter"
|
|
40000
40232
|
);
|
|
40001
|
-
if (
|
|
40233
|
+
if (existsSync16(join14(candidate, "web-tree-sitter.wasm"))) {
|
|
40002
40234
|
return candidate;
|
|
40003
40235
|
}
|
|
40004
40236
|
}
|
|
@@ -43137,8 +43369,8 @@ __export(mcp_exports, {
|
|
|
43137
43369
|
runTool: () => runTool,
|
|
43138
43370
|
searchGraph: () => searchGraph
|
|
43139
43371
|
});
|
|
43140
|
-
import { existsSync as
|
|
43141
|
-
import { resolve as
|
|
43372
|
+
import { existsSync as existsSync17, readFileSync as readFileSync16 } from "node:fs";
|
|
43373
|
+
import { resolve as resolve4 } from "node:path";
|
|
43142
43374
|
function collectEnrichmentPulls(store, opts = {}) {
|
|
43143
43375
|
const pending = store.findNodesByLabel("Solution").filter((s) => s.attrs["enrichmentPending"] === true).filter((s) => !opts.onlyUnsurfaced || s.attrs["enrichmentSurfaced"] !== true);
|
|
43144
43376
|
const byEpisode = /* @__PURE__ */ new Map();
|
|
@@ -43174,7 +43406,7 @@ function takeEnrichmentNudge(store) {
|
|
|
43174
43406
|
` + items;
|
|
43175
43407
|
}
|
|
43176
43408
|
function takeDiscriminatorNudge(path2) {
|
|
43177
|
-
if (!path2 || !
|
|
43409
|
+
if (!path2 || !existsSync17(path2)) return null;
|
|
43178
43410
|
let shared;
|
|
43179
43411
|
try {
|
|
43180
43412
|
shared = openGraphStore({ path: path2 });
|
|
@@ -43304,11 +43536,11 @@ function showNode(store, node2, maxLines) {
|
|
|
43304
43536
|
const relPath = ownerFilePath(store, node2);
|
|
43305
43537
|
if (!relPath) return { found: false, reason: "no file owner for node" };
|
|
43306
43538
|
const workspaceRoot = process.cwd();
|
|
43307
|
-
const absPath =
|
|
43308
|
-
if (!
|
|
43539
|
+
const absPath = resolve4(workspaceRoot, relPath);
|
|
43540
|
+
if (!existsSync17(absPath)) {
|
|
43309
43541
|
return { found: false, reason: `file not found on disk: ${absPath}` };
|
|
43310
43542
|
}
|
|
43311
|
-
const source =
|
|
43543
|
+
const source = readFileSync16(absPath, "utf8");
|
|
43312
43544
|
const attrs = node2.attrs;
|
|
43313
43545
|
let startByte = attrs["bodyStartByte"] ?? attrs["startByte"];
|
|
43314
43546
|
let endByte = attrs["bodyEndByte"] ?? attrs["endByte"];
|
|
@@ -43534,7 +43766,7 @@ function buildToolContext(workspaceRoot) {
|
|
|
43534
43766
|
const base = { switchInstallationProfile: useInstallationProfile };
|
|
43535
43767
|
try {
|
|
43536
43768
|
const cfg = loadConfig();
|
|
43537
|
-
const entry = workspaceRoot ? workspaceEntryForPath(
|
|
43769
|
+
const entry = workspaceRoot ? workspaceEntryForPath(resolve4(workspaceRoot)) : null;
|
|
43538
43770
|
const syncOk = effectiveConsent(cfg, entry ? loadProfile(entry.path) : null).sync;
|
|
43539
43771
|
const identity = resolveWorkspaceIdentity(cfg, entry);
|
|
43540
43772
|
if (identity.invalid) {
|
|
@@ -44027,7 +44259,7 @@ var init_mcp = __esm({
|
|
|
44027
44259
|
const local = causalChain(store, { seedId: id, direction: "both", maxHops, limit });
|
|
44028
44260
|
try {
|
|
44029
44261
|
const path2 = sharedStorePath();
|
|
44030
|
-
if (!
|
|
44262
|
+
if (!existsSync17(path2)) return { found: true, ...local };
|
|
44031
44263
|
const shared = openGraphStore({ path: path2 });
|
|
44032
44264
|
try {
|
|
44033
44265
|
if (!shared.getNode(id)) return { found: true, ...local };
|
|
@@ -44630,7 +44862,7 @@ var init_mcp = __esm({
|
|
|
44630
44862
|
inputSchema: { type: "object", properties: {} },
|
|
44631
44863
|
handler: () => {
|
|
44632
44864
|
const path2 = sharedStorePath();
|
|
44633
|
-
if (!
|
|
44865
|
+
if (!existsSync17(path2)) return { count: 0, pending: [] };
|
|
44634
44866
|
const shared = openGraphStore({ path: path2 });
|
|
44635
44867
|
try {
|
|
44636
44868
|
const pending = pendingAbstractions(shared);
|
|
@@ -44658,7 +44890,7 @@ var init_mcp = __esm({
|
|
|
44658
44890
|
},
|
|
44659
44891
|
handler: (args2) => {
|
|
44660
44892
|
const path2 = sharedStorePath();
|
|
44661
|
-
if (!
|
|
44893
|
+
if (!existsSync17(path2)) return { count: 0, pending: [] };
|
|
44662
44894
|
const shared = openGraphStore({ path: path2 });
|
|
44663
44895
|
try {
|
|
44664
44896
|
const pending = pendingDiscriminators(shared, {
|
|
@@ -44702,7 +44934,7 @@ var init_mcp = __esm({
|
|
|
44702
44934
|
},
|
|
44703
44935
|
handler: (args2) => {
|
|
44704
44936
|
const path2 = sharedStorePath();
|
|
44705
|
-
if (!
|
|
44937
|
+
if (!existsSync17(path2)) return { count: 0, routes: [] };
|
|
44706
44938
|
const shared = openGraphStore({ path: path2 });
|
|
44707
44939
|
try {
|
|
44708
44940
|
const result = triageOf(shared, {
|
|
@@ -45087,8 +45319,8 @@ __export(vfile_exports, {
|
|
|
45087
45319
|
resolvePath: () => resolvePath,
|
|
45088
45320
|
segmentsOf: () => segmentsOf
|
|
45089
45321
|
});
|
|
45090
|
-
import { writeFileSync as
|
|
45091
|
-
import { join as join16, resolve as
|
|
45322
|
+
import { writeFileSync as writeFileSync12 } from "node:fs";
|
|
45323
|
+
import { join as join16, resolve as resolve5, sep as sep3 } from "node:path";
|
|
45092
45324
|
function segmentsOf(rawPath) {
|
|
45093
45325
|
let p = rawPath.replace(/\\/g, "/");
|
|
45094
45326
|
p = p.replace(/^.*\.errata\/g\//, "").replace(/^\/?g\//, "").replace(/^\/+/, "");
|
|
@@ -45163,13 +45395,13 @@ async function renderVFile(rawPath, store, ctx = {}) {
|
|
|
45163
45395
|
async function materializeVFile(rawPath, workspaceRoot, store, ctx = {}) {
|
|
45164
45396
|
const segs = segmentsOf(rawPath);
|
|
45165
45397
|
const gRoot = join16(workspaceRoot, ".errata", "g");
|
|
45166
|
-
const abs =
|
|
45398
|
+
const abs = resolve5(gRoot, ...segs.length ? segs : ["index"]);
|
|
45167
45399
|
if (abs !== gRoot && !abs.startsWith(gRoot + sep3)) {
|
|
45168
45400
|
throw new Error(`refusing to materialize outside .errata/g: ${rawPath}`);
|
|
45169
45401
|
}
|
|
45170
45402
|
const text = await renderVFile(rawPath, store, ctx);
|
|
45171
45403
|
ensureParent(abs);
|
|
45172
|
-
|
|
45404
|
+
writeFileSync12(abs, text, "utf8");
|
|
45173
45405
|
return abs;
|
|
45174
45406
|
}
|
|
45175
45407
|
async function materializeOverview(workspaceRoot, store, ctx = {}) {
|
|
@@ -52589,12 +52821,12 @@ var init_tool_index = __esm({
|
|
|
52589
52821
|
|
|
52590
52822
|
// src/outbox.ts
|
|
52591
52823
|
import {
|
|
52592
|
-
existsSync as
|
|
52824
|
+
existsSync as existsSync18,
|
|
52593
52825
|
readdirSync as readdirSync5,
|
|
52594
|
-
readFileSync as
|
|
52826
|
+
readFileSync as readFileSync17,
|
|
52595
52827
|
renameSync as renameSync2,
|
|
52596
52828
|
unlinkSync as unlinkSync3,
|
|
52597
|
-
writeFileSync as
|
|
52829
|
+
writeFileSync as writeFileSync13
|
|
52598
52830
|
} from "node:fs";
|
|
52599
52831
|
import { join as join17 } from "node:path";
|
|
52600
52832
|
import { createHash as createHash15 } from "node:crypto";
|
|
@@ -52602,12 +52834,12 @@ function enqueueOutbox(paths, payload) {
|
|
|
52602
52834
|
ensureDir(paths.outbox);
|
|
52603
52835
|
const id = createHash15("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
|
|
52604
52836
|
const file2 = join17(paths.outbox, `${Date.now()}-${id}.json`);
|
|
52605
|
-
|
|
52837
|
+
writeFileSync13(file2, JSON.stringify(payload, null, 2), "utf8");
|
|
52606
52838
|
return file2;
|
|
52607
52839
|
}
|
|
52608
52840
|
async function flushOutbox(paths, client, store) {
|
|
52609
52841
|
ensureDir(paths.outbox);
|
|
52610
|
-
const entries =
|
|
52842
|
+
const entries = existsSync18(paths.outbox) ? readdirSync5(paths.outbox) : [];
|
|
52611
52843
|
let uploaded = 0;
|
|
52612
52844
|
let failed = 0;
|
|
52613
52845
|
const quarantine = (abs, reason) => {
|
|
@@ -52621,7 +52853,7 @@ async function flushOutbox(paths, client, store) {
|
|
|
52621
52853
|
const abs = join17(paths.outbox, f);
|
|
52622
52854
|
let payload;
|
|
52623
52855
|
try {
|
|
52624
|
-
payload = JSON.parse(
|
|
52856
|
+
payload = JSON.parse(readFileSync17(abs, "utf8"));
|
|
52625
52857
|
} catch {
|
|
52626
52858
|
failed++;
|
|
52627
52859
|
quarantine(abs, "unparseable JSON");
|
|
@@ -52666,7 +52898,7 @@ async function flushOutbox(paths, client, store) {
|
|
|
52666
52898
|
}
|
|
52667
52899
|
}
|
|
52668
52900
|
}
|
|
52669
|
-
const remainingFiles =
|
|
52901
|
+
const remainingFiles = existsSync18(paths.outbox) ? readdirSync5(paths.outbox).filter((e) => e.endsWith(".json")) : [];
|
|
52670
52902
|
return { uploaded, failed, remaining: remainingFiles.length };
|
|
52671
52903
|
}
|
|
52672
52904
|
var init_outbox = __esm({
|
|
@@ -52721,6 +52953,7 @@ var init_message_accumulator = __esm({
|
|
|
52721
52953
|
// src/webui.ts
|
|
52722
52954
|
var webui_exports = {};
|
|
52723
52955
|
__export(webui_exports, {
|
|
52956
|
+
SUBAGENT_REFRESH_MIN_MS: () => SUBAGENT_REFRESH_MIN_MS,
|
|
52724
52957
|
asFailedPostToolUse: () => asFailedPostToolUse,
|
|
52725
52958
|
buildWebUi: () => buildWebUi,
|
|
52726
52959
|
decideContextInject: () => decideContextInject,
|
|
@@ -52728,6 +52961,7 @@ __export(webui_exports, {
|
|
|
52728
52961
|
fileRecall: () => fileRecall,
|
|
52729
52962
|
fileUriToFsPath: () => fileUriToFsPath,
|
|
52730
52963
|
findFileByPath: () => findFileByPath,
|
|
52964
|
+
hookAudience: () => hookAudience,
|
|
52731
52965
|
recallForFile: () => recallForFile,
|
|
52732
52966
|
recallForTool: () => recallForTool
|
|
52733
52967
|
});
|
|
@@ -52874,10 +53108,21 @@ ${lines.join("\n")}`,
|
|
|
52874
53108
|
card: { headline: `${plural(items.length, "prior")} before this command runs`, items }
|
|
52875
53109
|
};
|
|
52876
53110
|
}
|
|
53111
|
+
function hookAudience(body2) {
|
|
53112
|
+
const sessionId = String(body2["session_id"] ?? "");
|
|
53113
|
+
const agentId = typeof body2["agent_id"] === "string" ? body2["agent_id"] : "";
|
|
53114
|
+
if (!agentId) return { sessionId, contextKey: sessionId, subagent: null, agentId: "" };
|
|
53115
|
+
return {
|
|
53116
|
+
sessionId,
|
|
53117
|
+
contextKey: sessionId ? `${sessionId}#${agentId}` : "",
|
|
53118
|
+
subagent: typeof body2["agent_type"] === "string" ? body2["agent_type"] : "",
|
|
53119
|
+
agentId
|
|
53120
|
+
};
|
|
53121
|
+
}
|
|
52877
53122
|
function decideContextInject(args2) {
|
|
52878
53123
|
const { event, sessionId, block, lastInjectedHash } = args2;
|
|
52879
53124
|
if (!block) return null;
|
|
52880
|
-
if (event === "SessionStart") {
|
|
53125
|
+
if (event === "SessionStart" || event === "SubagentStart") {
|
|
52881
53126
|
if (sessionId) lastInjectedHash.set(sessionId, block.hash);
|
|
52882
53127
|
} else if (sessionId && lastInjectedHash.get(sessionId) === block.hash) {
|
|
52883
53128
|
return null;
|
|
@@ -52892,6 +53137,21 @@ function buildWebUi(deps) {
|
|
|
52892
53137
|
const B = deps.basePath ?? "";
|
|
52893
53138
|
const lastInjectedHash = /* @__PURE__ */ new Map();
|
|
52894
53139
|
const fileRecallSeen = /* @__PURE__ */ new Map();
|
|
53140
|
+
const lastSubagentInjectAt = /* @__PURE__ */ new Map();
|
|
53141
|
+
const noteSessionFrom = (headerOrigin, body2, ended = false) => {
|
|
53142
|
+
const { sessionId, agentId } = hookAudience(body2);
|
|
53143
|
+
if (!sessionId || !deps.noteSession) return;
|
|
53144
|
+
const origin = parseOrigin(headerOrigin) ?? parseOrigin(body2["errata_origin"]);
|
|
53145
|
+
try {
|
|
53146
|
+
deps.noteSession({
|
|
53147
|
+
sessionId,
|
|
53148
|
+
...agentId ? { agentId } : {},
|
|
53149
|
+
...origin ? { origin } : {},
|
|
53150
|
+
...ended ? { ended } : {}
|
|
53151
|
+
});
|
|
53152
|
+
} catch {
|
|
53153
|
+
}
|
|
53154
|
+
};
|
|
52895
53155
|
app.get(
|
|
52896
53156
|
"/",
|
|
52897
53157
|
(c) => c.json({
|
|
@@ -53034,6 +53294,15 @@ function buildWebUi(deps) {
|
|
|
53034
53294
|
if (hookEvent === "PostToolUseFailure") body2 = asFailedPostToolUse(body2);
|
|
53035
53295
|
const event = hookEvent === "PostToolUseFailure" ? "PostToolUse" : hookEvent;
|
|
53036
53296
|
let recall = null;
|
|
53297
|
+
const audience = hookAudience(body2);
|
|
53298
|
+
noteSessionFrom(c.req.header(ORIGIN_HEADER), body2);
|
|
53299
|
+
if (event === "PreToolUse" && (tool === "Agent" || tool === "Task") && audience.subagent === null) {
|
|
53300
|
+
try {
|
|
53301
|
+
deps.onSubagentSpawn?.(audience.sessionId, input);
|
|
53302
|
+
} catch {
|
|
53303
|
+
}
|
|
53304
|
+
return c.json({ ok: true, event, tool, spawn: true });
|
|
53305
|
+
}
|
|
53037
53306
|
if (event === "PreToolUse") {
|
|
53038
53307
|
const virtual = extractVirtualReads(input);
|
|
53039
53308
|
if (virtual.length > 0) {
|
|
@@ -53062,7 +53331,10 @@ function buildWebUi(deps) {
|
|
|
53062
53331
|
const workspaceRoot = (deps.paths.root ?? "").replace(/\\/g, "/");
|
|
53063
53332
|
const fp = filePath.replace(/\\/g, "/");
|
|
53064
53333
|
rel = fp.startsWith(workspaceRoot + "/") ? fp.slice(workspaceRoot.length + 1) : fp;
|
|
53065
|
-
if (deps.onWorkingFileChanged)
|
|
53334
|
+
if (deps.onWorkingFileChanged) {
|
|
53335
|
+
const agentId = typeof body2["agent_id"] === "string" && body2["agent_id"] ? body2["agent_id"] : void 0;
|
|
53336
|
+
deps.onWorkingFileChanged(rel, audience.sessionId, agentId);
|
|
53337
|
+
}
|
|
53066
53338
|
}
|
|
53067
53339
|
if (rel && event === "PostToolUse" && deps.onHookEvent) {
|
|
53068
53340
|
deps.onHookEvent({
|
|
@@ -53130,7 +53402,7 @@ function buildWebUi(deps) {
|
|
|
53130
53402
|
}
|
|
53131
53403
|
}
|
|
53132
53404
|
if (event === "PostToolUse" && !recall && rel && (tool === "Read" || tool === "Edit" || tool === "Write" || tool === "NotebookEdit")) {
|
|
53133
|
-
const sid =
|
|
53405
|
+
const sid = hookAudience(body2).contextKey;
|
|
53134
53406
|
let seen = fileRecallSeen.get(sid);
|
|
53135
53407
|
if (!seen) {
|
|
53136
53408
|
seen = /* @__PURE__ */ new Set();
|
|
@@ -53144,13 +53416,46 @@ function buildWebUi(deps) {
|
|
|
53144
53416
|
}
|
|
53145
53417
|
}
|
|
53146
53418
|
}
|
|
53147
|
-
|
|
53419
|
+
let refreshed = null;
|
|
53420
|
+
if (event === "PostToolUse" && audience.subagent !== null && audience.contextKey && deps.subagentContext) {
|
|
53421
|
+
const last = lastSubagentInjectAt.get(audience.contextKey) ?? 0;
|
|
53422
|
+
if (Date.now() - last >= SUBAGENT_REFRESH_MIN_MS) {
|
|
53423
|
+
try {
|
|
53424
|
+
const own = deps.subagentContext({
|
|
53425
|
+
sessionId: audience.sessionId,
|
|
53426
|
+
agentId: audience.agentId,
|
|
53427
|
+
agentType: audience.subagent,
|
|
53428
|
+
start: false
|
|
53429
|
+
});
|
|
53430
|
+
const decision = decideContextInject({
|
|
53431
|
+
event,
|
|
53432
|
+
source: "",
|
|
53433
|
+
sessionId: audience.contextKey,
|
|
53434
|
+
block: own,
|
|
53435
|
+
lastInjectedHash
|
|
53436
|
+
});
|
|
53437
|
+
if (decision) {
|
|
53438
|
+
lastSubagentInjectAt.set(audience.contextKey, Date.now());
|
|
53439
|
+
refreshed = { additionalContext: decision.additionalContext, card: own?.card ?? null };
|
|
53440
|
+
}
|
|
53441
|
+
} catch {
|
|
53442
|
+
}
|
|
53443
|
+
}
|
|
53444
|
+
}
|
|
53445
|
+
if ((event === "PostToolUse" || event === "PreToolUse") && (recall || refreshed)) {
|
|
53148
53446
|
const showCard = recallCardEnabled();
|
|
53149
|
-
|
|
53150
|
-
const
|
|
53447
|
+
const { sessionId, subagent } = audience;
|
|
53448
|
+
const raw2 = recall?.card ?? refreshed?.card ?? null;
|
|
53449
|
+
const card = raw2 && subagent !== null ? forSubagent(raw2, subagent) : raw2;
|
|
53450
|
+
if (showCard && raw2 && card) {
|
|
53451
|
+
if (subagent !== null) rememberAgentCard(sessionId, audience.agentId, raw2);
|
|
53452
|
+
else rememberCard(sessionId, card);
|
|
53453
|
+
}
|
|
53454
|
+
const line = showCard && recall && card ? renderRecallLine(card) : null;
|
|
53455
|
+
const additionalContext = [recall?.context, refreshed?.additionalContext].filter(Boolean).join("\n\n");
|
|
53151
53456
|
return c.json({
|
|
53152
53457
|
...line ? { systemMessage: line } : {},
|
|
53153
|
-
hookSpecificOutput: { hookEventName: hookEvent, additionalContext
|
|
53458
|
+
hookSpecificOutput: { hookEventName: hookEvent, additionalContext }
|
|
53154
53459
|
});
|
|
53155
53460
|
}
|
|
53156
53461
|
if (event === "PostToolUse") return c.body(null, 204);
|
|
@@ -53160,6 +53465,10 @@ function buildWebUi(deps) {
|
|
|
53160
53465
|
const body2 = await c.req.json().catch(() => ({}));
|
|
53161
53466
|
return c.text(statuslineText(String(body2["session_id"] ?? "")));
|
|
53162
53467
|
});
|
|
53468
|
+
app.post("/api/statusline/subagents", async (c) => {
|
|
53469
|
+
const body2 = await c.req.json().catch(() => ({}));
|
|
53470
|
+
return c.text(subagentRows(body2));
|
|
53471
|
+
});
|
|
53163
53472
|
app.post("/api/turn", async (c) => {
|
|
53164
53473
|
let body2;
|
|
53165
53474
|
try {
|
|
@@ -53172,6 +53481,12 @@ function buildWebUi(deps) {
|
|
|
53172
53481
|
if (transcriptPath && deps.onTurn) {
|
|
53173
53482
|
deps.onTurn({ sessionId, transcriptPath });
|
|
53174
53483
|
}
|
|
53484
|
+
if (body2["hook_event_name"] === "SubagentStop" && typeof body2["agent_id"] === "string" && body2["agent_id"]) {
|
|
53485
|
+
deps.onSubagentStop?.(body2["agent_id"]);
|
|
53486
|
+
noteSessionFrom(c.req.header(ORIGIN_HEADER), body2, true);
|
|
53487
|
+
} else {
|
|
53488
|
+
noteSessionFrom(c.req.header(ORIGIN_HEADER), body2);
|
|
53489
|
+
}
|
|
53175
53490
|
return c.json({ ok: true });
|
|
53176
53491
|
});
|
|
53177
53492
|
app.post("/api/message", async (c) => {
|
|
@@ -53183,12 +53498,19 @@ function buildWebUi(deps) {
|
|
|
53183
53498
|
}
|
|
53184
53499
|
const delta = String(body2["delta"] ?? "");
|
|
53185
53500
|
const sessionId = String(body2["session_id"] ?? "");
|
|
53501
|
+
noteSessionFrom(c.req.header(ORIGIN_HEADER), body2);
|
|
53186
53502
|
const messageId = typeof body2["message_id"] === "string" ? body2["message_id"] : void 0;
|
|
53187
53503
|
const index = typeof body2["index"] === "number" ? body2["index"] : 0;
|
|
53188
53504
|
const isFinal = body2["final"] !== false;
|
|
53189
53505
|
const whole = accumulateMessageDelta(messageId, index, delta, isFinal, Date.now());
|
|
53190
53506
|
if (whole !== null && whole.text && sessionId && deps.onMessage) {
|
|
53191
|
-
|
|
53507
|
+
const agentId = typeof body2["agent_id"] === "string" && body2["agent_id"] ? body2["agent_id"] : void 0;
|
|
53508
|
+
deps.onMessage({
|
|
53509
|
+
sessionId,
|
|
53510
|
+
text: whole.text,
|
|
53511
|
+
...messageId ? { messageId } : {},
|
|
53512
|
+
...agentId ? { agentId } : {}
|
|
53513
|
+
});
|
|
53192
53514
|
}
|
|
53193
53515
|
return c.json({ ok: true, ...whole === null ? { buffered: true } : {} });
|
|
53194
53516
|
});
|
|
@@ -53204,6 +53526,7 @@ function buildWebUi(deps) {
|
|
|
53204
53526
|
if (transcriptPath && deps.onSessionEnd) {
|
|
53205
53527
|
deps.onSessionEnd({ sessionId, transcriptPath });
|
|
53206
53528
|
}
|
|
53529
|
+
noteSessionFrom(c.req.header(ORIGIN_HEADER), body2, true);
|
|
53207
53530
|
return c.json({ ok: true });
|
|
53208
53531
|
});
|
|
53209
53532
|
app.post("/api/context-inject", async (c) => {
|
|
@@ -53213,9 +53536,10 @@ function buildWebUi(deps) {
|
|
|
53213
53536
|
} catch {
|
|
53214
53537
|
return c.json({});
|
|
53215
53538
|
}
|
|
53216
|
-
const sid =
|
|
53539
|
+
const { sessionId: sid, contextKey: contextKey2, subagent, agentId } = hookAudience(body2);
|
|
53540
|
+
noteSessionFrom(c.req.header(ORIGIN_HEADER), body2);
|
|
53217
53541
|
const hookEvent = String(body2["hook_event_name"] ?? "UserPromptSubmit");
|
|
53218
|
-
const atPrompt = hookEvent === "UserPromptSubmit" || hookEvent === "SessionStart";
|
|
53542
|
+
const atPrompt = hookEvent === "UserPromptSubmit" || hookEvent === "SessionStart" || hookEvent === "SubagentStart";
|
|
53219
53543
|
if (sid && recallCardEnabled() && atPrompt) {
|
|
53220
53544
|
setImmediate(() => {
|
|
53221
53545
|
try {
|
|
@@ -53224,20 +53548,39 @@ function buildWebUi(deps) {
|
|
|
53224
53548
|
}
|
|
53225
53549
|
});
|
|
53226
53550
|
}
|
|
53227
|
-
|
|
53551
|
+
let block;
|
|
53552
|
+
let storedCard = null;
|
|
53553
|
+
if (subagent !== null) {
|
|
53554
|
+
const own = deps.subagentContext?.({
|
|
53555
|
+
sessionId: sid,
|
|
53556
|
+
agentId,
|
|
53557
|
+
agentType: subagent,
|
|
53558
|
+
...typeof body2["task_description"] === "string" ? { taskDescription: body2["task_description"] } : {},
|
|
53559
|
+
start: hookEvent === "SubagentStart"
|
|
53560
|
+
}) ?? null;
|
|
53561
|
+
block = own;
|
|
53562
|
+
storedCard = own?.card ?? null;
|
|
53563
|
+
} else {
|
|
53564
|
+
const own = sid ? deps.sessionContext?.(sid) ?? null : null;
|
|
53565
|
+
block = own ?? readContextFileWithHash(deps.paths.root);
|
|
53566
|
+
storedCard = own ? own.card : block ? readContextCard(deps.paths.root, block.hash) : null;
|
|
53567
|
+
}
|
|
53228
53568
|
const decision = decideContextInject({
|
|
53229
53569
|
event: hookEvent,
|
|
53230
53570
|
source: String(body2["source"] ?? ""),
|
|
53231
|
-
sessionId:
|
|
53571
|
+
sessionId: contextKey2,
|
|
53232
53572
|
block,
|
|
53233
53573
|
lastInjectedHash
|
|
53234
53574
|
});
|
|
53575
|
+
if (decision && subagent !== null) lastSubagentInjectAt.set(contextKey2, Date.now());
|
|
53235
53576
|
let systemMessage = null;
|
|
53236
53577
|
if (sid && block && recallCardEnabled() && (decision || atPrompt)) {
|
|
53237
|
-
const card =
|
|
53578
|
+
const card = storedCard && subagent !== null ? forSubagent(storedCard, subagent) : storedCard;
|
|
53238
53579
|
if (card) {
|
|
53239
|
-
|
|
53240
|
-
|
|
53580
|
+
if (subagent !== null && storedCard) rememberAgentCard(sid, agentId, storedCard);
|
|
53581
|
+
else rememberCard(sid, card);
|
|
53582
|
+
if (decision && hookEvent === "SubagentStart") systemMessage = renderRecallLine(card);
|
|
53583
|
+
else if (decision && sid.startsWith("codex:")) systemMessage = renderRecallLine(card);
|
|
53241
53584
|
}
|
|
53242
53585
|
}
|
|
53243
53586
|
if (!decision) return c.json({});
|
|
@@ -53423,7 +53766,7 @@ function proposalToIngest(p, profile, daemonVersion) {
|
|
|
53423
53766
|
payloadDigest: p.id
|
|
53424
53767
|
};
|
|
53425
53768
|
}
|
|
53426
|
-
var messageAccumulator, GENERIC_ERROR_WORDS, wsPackagesCache, WS_PACKAGES_TTL_MS, loggedToolSessions, META_LABELS;
|
|
53769
|
+
var messageAccumulator, GENERIC_ERROR_WORDS, wsPackagesCache, WS_PACKAGES_TTL_MS, loggedToolSessions, SUBAGENT_REFRESH_MIN_MS, META_LABELS;
|
|
53427
53770
|
var init_webui = __esm({
|
|
53428
53771
|
"src/webui.ts"() {
|
|
53429
53772
|
"use strict";
|
|
@@ -53434,6 +53777,7 @@ var init_webui = __esm({
|
|
|
53434
53777
|
init_agent_signals();
|
|
53435
53778
|
init_recall_signal();
|
|
53436
53779
|
init_recall_card();
|
|
53780
|
+
init_session_registry();
|
|
53437
53781
|
init_review2();
|
|
53438
53782
|
init_vfile();
|
|
53439
53783
|
init_tool_index();
|
|
@@ -53484,6 +53828,7 @@ var init_webui = __esm({
|
|
|
53484
53828
|
wsPackagesCache = /* @__PURE__ */ new WeakMap();
|
|
53485
53829
|
WS_PACKAGES_TTL_MS = 6e4;
|
|
53486
53830
|
loggedToolSessions = /* @__PURE__ */ new Set();
|
|
53831
|
+
SUBAGENT_REFRESH_MIN_MS = 6e4;
|
|
53487
53832
|
META_LABELS = /* @__PURE__ */ new Set([
|
|
53488
53833
|
"Pattern",
|
|
53489
53834
|
"Technique",
|
|
@@ -54767,7 +55112,7 @@ var require_util = __commonJS({
|
|
|
54767
55112
|
}
|
|
54768
55113
|
return url2;
|
|
54769
55114
|
}
|
|
54770
|
-
function
|
|
55115
|
+
function parseOrigin2(url2) {
|
|
54771
55116
|
url2 = parseURL(url2);
|
|
54772
55117
|
if (url2.pathname !== "/" || url2.search || url2.hash) {
|
|
54773
55118
|
throw new InvalidArgumentError("invalid url");
|
|
@@ -55102,7 +55447,7 @@ var require_util = __commonJS({
|
|
|
55102
55447
|
toUSVString,
|
|
55103
55448
|
isUSVString,
|
|
55104
55449
|
isBlobLike,
|
|
55105
|
-
parseOrigin,
|
|
55450
|
+
parseOrigin: parseOrigin2,
|
|
55106
55451
|
parseURL,
|
|
55107
55452
|
getServerName,
|
|
55108
55453
|
isStream,
|
|
@@ -55760,9 +56105,9 @@ var require_dispatcher_base = __commonJS({
|
|
|
55760
56105
|
}
|
|
55761
56106
|
close(callback) {
|
|
55762
56107
|
if (callback === void 0) {
|
|
55763
|
-
return new Promise((
|
|
56108
|
+
return new Promise((resolve9, reject) => {
|
|
55764
56109
|
this.close((err2, data) => {
|
|
55765
|
-
return err2 ? reject(err2) :
|
|
56110
|
+
return err2 ? reject(err2) : resolve9(data);
|
|
55766
56111
|
});
|
|
55767
56112
|
});
|
|
55768
56113
|
}
|
|
@@ -55800,12 +56145,12 @@ var require_dispatcher_base = __commonJS({
|
|
|
55800
56145
|
err2 = null;
|
|
55801
56146
|
}
|
|
55802
56147
|
if (callback === void 0) {
|
|
55803
|
-
return new Promise((
|
|
56148
|
+
return new Promise((resolve9, reject) => {
|
|
55804
56149
|
this.destroy(err2, (err3, data) => {
|
|
55805
56150
|
return err3 ? (
|
|
55806
56151
|
/* istanbul ignore next: should never error */
|
|
55807
56152
|
reject(err3)
|
|
55808
|
-
) :
|
|
56153
|
+
) : resolve9(data);
|
|
55809
56154
|
});
|
|
55810
56155
|
});
|
|
55811
56156
|
}
|
|
@@ -58072,8 +58417,8 @@ var require_util2 = __commonJS({
|
|
|
58072
58417
|
function createDeferredPromise() {
|
|
58073
58418
|
let res;
|
|
58074
58419
|
let rej;
|
|
58075
|
-
const promise2 = new Promise((
|
|
58076
|
-
res =
|
|
58420
|
+
const promise2 = new Promise((resolve9, reject) => {
|
|
58421
|
+
res = resolve9;
|
|
58077
58422
|
rej = reject;
|
|
58078
58423
|
});
|
|
58079
58424
|
return { promise: promise2, resolve: res, reject: rej };
|
|
@@ -60214,12 +60559,12 @@ upgrade: ${upgrade}\r
|
|
|
60214
60559
|
cb();
|
|
60215
60560
|
}
|
|
60216
60561
|
}
|
|
60217
|
-
const waitForDrain = () => new Promise((
|
|
60562
|
+
const waitForDrain = () => new Promise((resolve9, reject) => {
|
|
60218
60563
|
assert2(callback === null);
|
|
60219
60564
|
if (socket[kError]) {
|
|
60220
60565
|
reject(socket[kError]);
|
|
60221
60566
|
} else {
|
|
60222
|
-
callback =
|
|
60567
|
+
callback = resolve9;
|
|
60223
60568
|
}
|
|
60224
60569
|
});
|
|
60225
60570
|
socket.on("close", onDrain).on("drain", onDrain);
|
|
@@ -60856,12 +61201,12 @@ var require_client_h2 = __commonJS({
|
|
|
60856
61201
|
cb();
|
|
60857
61202
|
}
|
|
60858
61203
|
}
|
|
60859
|
-
const waitForDrain = () => new Promise((
|
|
61204
|
+
const waitForDrain = () => new Promise((resolve9, reject) => {
|
|
60860
61205
|
assert2(callback === null);
|
|
60861
61206
|
if (socket[kError]) {
|
|
60862
61207
|
reject(socket[kError]);
|
|
60863
61208
|
} else {
|
|
60864
|
-
callback =
|
|
61209
|
+
callback = resolve9;
|
|
60865
61210
|
}
|
|
60866
61211
|
});
|
|
60867
61212
|
h2stream.on("close", onDrain).on("drain", onDrain);
|
|
@@ -61338,16 +61683,16 @@ var require_client = __commonJS({
|
|
|
61338
61683
|
return this[kNeedDrain] < 2;
|
|
61339
61684
|
}
|
|
61340
61685
|
async [kClose]() {
|
|
61341
|
-
return new Promise((
|
|
61686
|
+
return new Promise((resolve9) => {
|
|
61342
61687
|
if (this[kSize]) {
|
|
61343
|
-
this[kClosedResolve] =
|
|
61688
|
+
this[kClosedResolve] = resolve9;
|
|
61344
61689
|
} else {
|
|
61345
|
-
|
|
61690
|
+
resolve9(null);
|
|
61346
61691
|
}
|
|
61347
61692
|
});
|
|
61348
61693
|
}
|
|
61349
61694
|
async [kDestroy](err2) {
|
|
61350
|
-
return new Promise((
|
|
61695
|
+
return new Promise((resolve9) => {
|
|
61351
61696
|
const requests = this[kQueue].splice(this[kPendingIdx]);
|
|
61352
61697
|
for (let i2 = 0; i2 < requests.length; i2++) {
|
|
61353
61698
|
const request = requests[i2];
|
|
@@ -61358,7 +61703,7 @@ var require_client = __commonJS({
|
|
|
61358
61703
|
this[kClosedResolve]();
|
|
61359
61704
|
this[kClosedResolve] = null;
|
|
61360
61705
|
}
|
|
61361
|
-
|
|
61706
|
+
resolve9(null);
|
|
61362
61707
|
};
|
|
61363
61708
|
if (this[kHTTPContext]) {
|
|
61364
61709
|
this[kHTTPContext].destroy(err2, callback);
|
|
@@ -61409,7 +61754,7 @@ var require_client = __commonJS({
|
|
|
61409
61754
|
});
|
|
61410
61755
|
}
|
|
61411
61756
|
try {
|
|
61412
|
-
const socket = await new Promise((
|
|
61757
|
+
const socket = await new Promise((resolve9, reject) => {
|
|
61413
61758
|
client[kConnector]({
|
|
61414
61759
|
host,
|
|
61415
61760
|
hostname: hostname3,
|
|
@@ -61421,7 +61766,7 @@ var require_client = __commonJS({
|
|
|
61421
61766
|
if (err2) {
|
|
61422
61767
|
reject(err2);
|
|
61423
61768
|
} else {
|
|
61424
|
-
|
|
61769
|
+
resolve9(socket2);
|
|
61425
61770
|
}
|
|
61426
61771
|
});
|
|
61427
61772
|
});
|
|
@@ -61757,8 +62102,8 @@ var require_pool_base = __commonJS({
|
|
|
61757
62102
|
if (this[kQueue].isEmpty()) {
|
|
61758
62103
|
await Promise.all(this[kClients].map((c) => c.close()));
|
|
61759
62104
|
} else {
|
|
61760
|
-
await new Promise((
|
|
61761
|
-
this[kClosedResolve] =
|
|
62105
|
+
await new Promise((resolve9) => {
|
|
62106
|
+
this[kClosedResolve] = resolve9;
|
|
61762
62107
|
});
|
|
61763
62108
|
}
|
|
61764
62109
|
}
|
|
@@ -61926,7 +62271,7 @@ var require_balanced_pool = __commonJS({
|
|
|
61926
62271
|
} = require_pool_base();
|
|
61927
62272
|
var Pool = require_pool();
|
|
61928
62273
|
var { kUrl, kInterceptors } = require_symbols();
|
|
61929
|
-
var { parseOrigin } = require_util();
|
|
62274
|
+
var { parseOrigin: parseOrigin2 } = require_util();
|
|
61930
62275
|
var kFactory = Symbol("factory");
|
|
61931
62276
|
var kOptions = Symbol("options");
|
|
61932
62277
|
var kGreatestCommonDivisor = Symbol("kGreatestCommonDivisor");
|
|
@@ -61969,7 +62314,7 @@ var require_balanced_pool = __commonJS({
|
|
|
61969
62314
|
this._updateBalancedPoolStats();
|
|
61970
62315
|
}
|
|
61971
62316
|
addUpstream(upstream) {
|
|
61972
|
-
const upstreamOrigin =
|
|
62317
|
+
const upstreamOrigin = parseOrigin2(upstream).origin;
|
|
61973
62318
|
if (this[kClients].find((pool2) => pool2[kUrl].origin === upstreamOrigin && pool2.closed !== true && pool2.destroyed !== true)) {
|
|
61974
62319
|
return this;
|
|
61975
62320
|
}
|
|
@@ -62003,7 +62348,7 @@ var require_balanced_pool = __commonJS({
|
|
|
62003
62348
|
this[kGreatestCommonDivisor] = result;
|
|
62004
62349
|
}
|
|
62005
62350
|
removeUpstream(upstream) {
|
|
62006
|
-
const upstreamOrigin =
|
|
62351
|
+
const upstreamOrigin = parseOrigin2(upstream).origin;
|
|
62007
62352
|
const pool = this[kClients].find((pool2) => pool2[kUrl].origin === upstreamOrigin && pool2.closed !== true && pool2.destroyed !== true);
|
|
62008
62353
|
if (pool) {
|
|
62009
62354
|
this[kRemoveClient](pool);
|
|
@@ -62973,7 +63318,7 @@ var require_readable = __commonJS({
|
|
|
62973
63318
|
if (this._readableState.closeEmitted) {
|
|
62974
63319
|
return null;
|
|
62975
63320
|
}
|
|
62976
|
-
return await new Promise((
|
|
63321
|
+
return await new Promise((resolve9, reject) => {
|
|
62977
63322
|
if (this[kContentLength] > limit) {
|
|
62978
63323
|
this.destroy(new AbortError());
|
|
62979
63324
|
}
|
|
@@ -62986,7 +63331,7 @@ var require_readable = __commonJS({
|
|
|
62986
63331
|
if (signal?.aborted) {
|
|
62987
63332
|
reject(signal.reason ?? new AbortError());
|
|
62988
63333
|
} else {
|
|
62989
|
-
|
|
63334
|
+
resolve9(null);
|
|
62990
63335
|
}
|
|
62991
63336
|
}).on("error", noop).on("data", function(chunk) {
|
|
62992
63337
|
limit -= chunk.length;
|
|
@@ -63005,7 +63350,7 @@ var require_readable = __commonJS({
|
|
|
63005
63350
|
}
|
|
63006
63351
|
async function consume(stream, type) {
|
|
63007
63352
|
assert2(!stream[kConsume]);
|
|
63008
|
-
return new Promise((
|
|
63353
|
+
return new Promise((resolve9, reject) => {
|
|
63009
63354
|
if (isUnusable(stream)) {
|
|
63010
63355
|
const rState = stream._readableState;
|
|
63011
63356
|
if (rState.destroyed && rState.closeEmitted === false) {
|
|
@@ -63022,7 +63367,7 @@ var require_readable = __commonJS({
|
|
|
63022
63367
|
stream[kConsume] = {
|
|
63023
63368
|
type,
|
|
63024
63369
|
stream,
|
|
63025
|
-
resolve:
|
|
63370
|
+
resolve: resolve9,
|
|
63026
63371
|
reject,
|
|
63027
63372
|
length: 0,
|
|
63028
63373
|
body: []
|
|
@@ -63092,18 +63437,18 @@ var require_readable = __commonJS({
|
|
|
63092
63437
|
return buffer;
|
|
63093
63438
|
}
|
|
63094
63439
|
function consumeEnd(consume2) {
|
|
63095
|
-
const { type, body: body2, resolve:
|
|
63440
|
+
const { type, body: body2, resolve: resolve9, stream, length } = consume2;
|
|
63096
63441
|
try {
|
|
63097
63442
|
if (type === "text") {
|
|
63098
|
-
|
|
63443
|
+
resolve9(chunksDecode(body2, length));
|
|
63099
63444
|
} else if (type === "json") {
|
|
63100
|
-
|
|
63445
|
+
resolve9(JSON.parse(chunksDecode(body2, length)));
|
|
63101
63446
|
} else if (type === "arrayBuffer") {
|
|
63102
|
-
|
|
63447
|
+
resolve9(chunksConcat(body2, length).buffer);
|
|
63103
63448
|
} else if (type === "blob") {
|
|
63104
|
-
|
|
63449
|
+
resolve9(new Blob(body2, { type: stream[kContentType] }));
|
|
63105
63450
|
} else if (type === "bytes") {
|
|
63106
|
-
|
|
63451
|
+
resolve9(chunksConcat(body2, length));
|
|
63107
63452
|
}
|
|
63108
63453
|
consumeFinish(consume2);
|
|
63109
63454
|
} catch (err2) {
|
|
@@ -63360,9 +63705,9 @@ var require_api_request = __commonJS({
|
|
|
63360
63705
|
};
|
|
63361
63706
|
function request(opts, callback) {
|
|
63362
63707
|
if (callback === void 0) {
|
|
63363
|
-
return new Promise((
|
|
63708
|
+
return new Promise((resolve9, reject) => {
|
|
63364
63709
|
request.call(this, opts, (err2, data) => {
|
|
63365
|
-
return err2 ? reject(err2) :
|
|
63710
|
+
return err2 ? reject(err2) : resolve9(data);
|
|
63366
63711
|
});
|
|
63367
63712
|
});
|
|
63368
63713
|
}
|
|
@@ -63585,9 +63930,9 @@ var require_api_stream = __commonJS({
|
|
|
63585
63930
|
};
|
|
63586
63931
|
function stream(opts, factory, callback) {
|
|
63587
63932
|
if (callback === void 0) {
|
|
63588
|
-
return new Promise((
|
|
63933
|
+
return new Promise((resolve9, reject) => {
|
|
63589
63934
|
stream.call(this, opts, factory, (err2, data) => {
|
|
63590
|
-
return err2 ? reject(err2) :
|
|
63935
|
+
return err2 ? reject(err2) : resolve9(data);
|
|
63591
63936
|
});
|
|
63592
63937
|
});
|
|
63593
63938
|
}
|
|
@@ -63872,9 +64217,9 @@ var require_api_upgrade = __commonJS({
|
|
|
63872
64217
|
};
|
|
63873
64218
|
function upgrade(opts, callback) {
|
|
63874
64219
|
if (callback === void 0) {
|
|
63875
|
-
return new Promise((
|
|
64220
|
+
return new Promise((resolve9, reject) => {
|
|
63876
64221
|
upgrade.call(this, opts, (err2, data) => {
|
|
63877
|
-
return err2 ? reject(err2) :
|
|
64222
|
+
return err2 ? reject(err2) : resolve9(data);
|
|
63878
64223
|
});
|
|
63879
64224
|
});
|
|
63880
64225
|
}
|
|
@@ -63966,9 +64311,9 @@ var require_api_connect = __commonJS({
|
|
|
63966
64311
|
};
|
|
63967
64312
|
function connect(opts, callback) {
|
|
63968
64313
|
if (callback === void 0) {
|
|
63969
|
-
return new Promise((
|
|
64314
|
+
return new Promise((resolve9, reject) => {
|
|
63970
64315
|
connect.call(this, opts, (err2, data) => {
|
|
63971
|
-
return err2 ? reject(err2) :
|
|
64316
|
+
return err2 ? reject(err2) : resolve9(data);
|
|
63972
64317
|
});
|
|
63973
64318
|
});
|
|
63974
64319
|
}
|
|
@@ -67830,7 +68175,7 @@ var require_fetch = __commonJS({
|
|
|
67830
68175
|
function dispatch({ body: body2 }) {
|
|
67831
68176
|
const url2 = requestCurrentURL(request);
|
|
67832
68177
|
const agent = fetchParams.controller.dispatcher;
|
|
67833
|
-
return new Promise((
|
|
68178
|
+
return new Promise((resolve9, reject) => agent.dispatch(
|
|
67834
68179
|
{
|
|
67835
68180
|
path: url2.pathname + url2.search,
|
|
67836
68181
|
origin: url2.origin,
|
|
@@ -67906,7 +68251,7 @@ var require_fetch = __commonJS({
|
|
|
67906
68251
|
}
|
|
67907
68252
|
}
|
|
67908
68253
|
const onError = this.onError.bind(this);
|
|
67909
|
-
|
|
68254
|
+
resolve9({
|
|
67910
68255
|
status,
|
|
67911
68256
|
statusText,
|
|
67912
68257
|
headersList,
|
|
@@ -67952,7 +68297,7 @@ var require_fetch = __commonJS({
|
|
|
67952
68297
|
for (let i2 = 0; i2 < rawHeaders.length; i2 += 2) {
|
|
67953
68298
|
headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i2]), rawHeaders[i2 + 1].toString("latin1"), true);
|
|
67954
68299
|
}
|
|
67955
|
-
|
|
68300
|
+
resolve9({
|
|
67956
68301
|
status,
|
|
67957
68302
|
statusText: STATUS_CODES[status],
|
|
67958
68303
|
headersList,
|
|
@@ -71591,8 +71936,8 @@ var require_util8 = __commonJS({
|
|
|
71591
71936
|
return true;
|
|
71592
71937
|
}
|
|
71593
71938
|
function delay(ms) {
|
|
71594
|
-
return new Promise((
|
|
71595
|
-
setTimeout(
|
|
71939
|
+
return new Promise((resolve9) => {
|
|
71940
|
+
setTimeout(resolve9, ms).unref();
|
|
71596
71941
|
});
|
|
71597
71942
|
}
|
|
71598
71943
|
module2.exports = {
|
|
@@ -72280,7 +72625,7 @@ __export(witness_ledger_exports, {
|
|
|
72280
72625
|
summarizeWitnessLedger: () => summarizeWitnessLedger,
|
|
72281
72626
|
witnessLedgerPath: () => witnessLedgerPath
|
|
72282
72627
|
});
|
|
72283
|
-
import { appendFileSync as appendFileSync3, existsSync as
|
|
72628
|
+
import { appendFileSync as appendFileSync3, existsSync as existsSync27, readFileSync as readFileSync30, writeFileSync as writeFileSync21 } from "node:fs";
|
|
72284
72629
|
import { join as join33 } from "node:path";
|
|
72285
72630
|
function witnessLedgerPath(configDir) {
|
|
72286
72631
|
return join33(configDir, "witness-ledger.jsonl");
|
|
@@ -72289,18 +72634,18 @@ function appendWitnessLedger(configDir, entry) {
|
|
|
72289
72634
|
const path2 = witnessLedgerPath(configDir);
|
|
72290
72635
|
try {
|
|
72291
72636
|
appendFileSync3(path2, JSON.stringify(entry) + "\n");
|
|
72292
|
-
const lines =
|
|
72637
|
+
const lines = readFileSync30(path2, "utf8").split("\n").filter(Boolean);
|
|
72293
72638
|
if (lines.length > LEDGER_MAX_LINES) {
|
|
72294
|
-
|
|
72639
|
+
writeFileSync21(path2, lines.slice(-Math.floor(LEDGER_MAX_LINES / 2)).join("\n") + "\n");
|
|
72295
72640
|
}
|
|
72296
72641
|
} catch {
|
|
72297
72642
|
}
|
|
72298
72643
|
}
|
|
72299
72644
|
function readWitnessLedger(configDir) {
|
|
72300
72645
|
const path2 = witnessLedgerPath(configDir);
|
|
72301
|
-
if (!
|
|
72646
|
+
if (!existsSync27(path2)) return [];
|
|
72302
72647
|
try {
|
|
72303
|
-
return
|
|
72648
|
+
return readFileSync30(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter((e) => typeof e.ts === "number" && typeof e.channel === "string");
|
|
72304
72649
|
} catch {
|
|
72305
72650
|
return [];
|
|
72306
72651
|
}
|
|
@@ -72739,12 +73084,12 @@ var init_report_render = __esm({
|
|
|
72739
73084
|
|
|
72740
73085
|
// src/cli.ts
|
|
72741
73086
|
init_src6();
|
|
72742
|
-
import { closeSync as closeSync2, existsSync as
|
|
73087
|
+
import { closeSync as closeSync2, existsSync as existsSync38, openSync as openSync2, readFileSync as readFileSync41, renameSync as renameSync6, statSync as statSync11 } from "node:fs";
|
|
72743
73088
|
import { join as join47, resolve as pathResolve2 } from "node:path";
|
|
72744
73089
|
import { spawn as spawn5 } from "node:child_process";
|
|
72745
73090
|
|
|
72746
73091
|
// src/daemon.ts
|
|
72747
|
-
import { existsSync as
|
|
73092
|
+
import { existsSync as existsSync29, writeFileSync as writeFileSync24 } from "node:fs";
|
|
72748
73093
|
|
|
72749
73094
|
// ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.8/node_modules/@hono/node-server/dist/index.mjs
|
|
72750
73095
|
import { createServer as createServerHTTP } from "http";
|
|
@@ -73174,7 +73519,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
|
|
|
73174
73519
|
});
|
|
73175
73520
|
if (!chunk) {
|
|
73176
73521
|
if (i2 === 1) {
|
|
73177
|
-
await new Promise((
|
|
73522
|
+
await new Promise((resolve9) => setTimeout(resolve9));
|
|
73178
73523
|
maxReadCount = 3;
|
|
73179
73524
|
continue;
|
|
73180
73525
|
}
|
|
@@ -73325,7 +73670,7 @@ init_lock();
|
|
|
73325
73670
|
|
|
73326
73671
|
// src/engine.ts
|
|
73327
73672
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
73328
|
-
import { existsSync as
|
|
73673
|
+
import { existsSync as existsSync28, statSync as statSync8, appendFileSync as appendFileSync4, readdirSync as readdirSync10, renameSync as renameSync4, readFileSync as readFileSync32, writeFileSync as writeFileSync23 } from "node:fs";
|
|
73329
73674
|
import { basename as basename7, join as join35, relative as relative6, sep as sep4 } from "node:path";
|
|
73330
73675
|
|
|
73331
73676
|
// src/source-watcher.ts
|
|
@@ -74187,7 +74532,7 @@ var NodeFsHandler = class {
|
|
|
74187
74532
|
this._addToNodeFs(path2, initialAdd, wh, depth + 1);
|
|
74188
74533
|
}
|
|
74189
74534
|
}).on(EV.ERROR, this._boundHandleError);
|
|
74190
|
-
return new Promise((
|
|
74535
|
+
return new Promise((resolve9, reject) => {
|
|
74191
74536
|
if (!stream)
|
|
74192
74537
|
return reject();
|
|
74193
74538
|
stream.once(STR_END, () => {
|
|
@@ -74196,7 +74541,7 @@ var NodeFsHandler = class {
|
|
|
74196
74541
|
return;
|
|
74197
74542
|
}
|
|
74198
74543
|
const wasThrottled = throttler ? throttler.clear() : false;
|
|
74199
|
-
|
|
74544
|
+
resolve9(void 0);
|
|
74200
74545
|
previous.getChildren().filter((item2) => {
|
|
74201
74546
|
return item2 !== directory && !current.has(item2);
|
|
74202
74547
|
}).forEach((item2) => {
|
|
@@ -75364,13 +75709,162 @@ async function chat(req) {
|
|
|
75364
75709
|
// src/engine.ts
|
|
75365
75710
|
init_src11();
|
|
75366
75711
|
init_src6();
|
|
75712
|
+
init_session_registry();
|
|
75367
75713
|
init_recall_signal();
|
|
75714
|
+
|
|
75715
|
+
// src/subagent-state.ts
|
|
75716
|
+
init_src5();
|
|
75717
|
+
var SPAWN_CLAIM_TTL_MS = 2 * 6e4;
|
|
75718
|
+
var SUBAGENT_IDLE_TTL_MS = 60 * 6e4;
|
|
75719
|
+
var MAX_AGENTS = 200;
|
|
75720
|
+
var SEED_INTENT_MAX_CHARS = 400;
|
|
75721
|
+
function seedIntentOf(toolInput) {
|
|
75722
|
+
const prompt = typeof toolInput["prompt"] === "string" ? toolInput["prompt"] : "";
|
|
75723
|
+
const stated = parseIntentFences(prompt)[0]?.intent;
|
|
75724
|
+
if (stated) return stated;
|
|
75725
|
+
const description = typeof toolInput["description"] === "string" ? toolInput["description"].trim() : "";
|
|
75726
|
+
const body2 = prompt.replace(/```errata-[\s\S]*?```/g, " ").replace(/\s+/g, " ").trim();
|
|
75727
|
+
const seed = [description, body2].filter(Boolean).join(" \u2014 ");
|
|
75728
|
+
return seed.length > SEED_INTENT_MAX_CHARS ? `${seed.slice(0, SEED_INTENT_MAX_CHARS - 1)}\u2026` : seed;
|
|
75729
|
+
}
|
|
75730
|
+
function createSubagentState() {
|
|
75731
|
+
const pending = /* @__PURE__ */ new Map();
|
|
75732
|
+
const agents = /* @__PURE__ */ new Map();
|
|
75733
|
+
const sweep = (nowMs) => {
|
|
75734
|
+
for (const [id, a] of agents) if (nowMs - a.lastSeenMs > SUBAGENT_IDLE_TTL_MS) agents.delete(id);
|
|
75735
|
+
while (agents.size > MAX_AGENTS) agents.delete(agents.keys().next().value);
|
|
75736
|
+
for (const [sid, list] of pending) {
|
|
75737
|
+
const live3 = list.filter((s) => nowMs - s.atMs <= SPAWN_CLAIM_TTL_MS);
|
|
75738
|
+
if (live3.length) pending.set(sid, live3);
|
|
75739
|
+
else pending.delete(sid);
|
|
75740
|
+
}
|
|
75741
|
+
};
|
|
75742
|
+
const touch = (agentId, nowMs) => {
|
|
75743
|
+
const a = agents.get(agentId);
|
|
75744
|
+
if (!a) return void 0;
|
|
75745
|
+
if (nowMs - a.lastSeenMs > SUBAGENT_IDLE_TTL_MS) {
|
|
75746
|
+
agents.delete(agentId);
|
|
75747
|
+
return void 0;
|
|
75748
|
+
}
|
|
75749
|
+
a.lastSeenMs = nowMs;
|
|
75750
|
+
return a;
|
|
75751
|
+
};
|
|
75752
|
+
return {
|
|
75753
|
+
noteSpawn(sessionId, toolInput, nowMs) {
|
|
75754
|
+
sweep(nowMs);
|
|
75755
|
+
const prompt = typeof toolInput["prompt"] === "string" ? toolInput["prompt"] : "";
|
|
75756
|
+
const agentType = typeof toolInput["subagent_type"] === "string" ? toolInput["subagent_type"] : "";
|
|
75757
|
+
const list = pending.get(sessionId) ?? [];
|
|
75758
|
+
list.push({ agentType, seedIntent: seedIntentOf(toolInput), share: parseShareFence(prompt), atMs: nowMs });
|
|
75759
|
+
pending.set(sessionId, list);
|
|
75760
|
+
},
|
|
75761
|
+
start({ sessionId, agentId, agentType, taskDescription }, nowMs) {
|
|
75762
|
+
const existing = touch(agentId, nowMs);
|
|
75763
|
+
if (existing) return existing;
|
|
75764
|
+
sweep(nowMs);
|
|
75765
|
+
const list = pending.get(sessionId) ?? [];
|
|
75766
|
+
const i2 = list.findIndex((s) => s.agentType === agentType || s.agentType === "");
|
|
75767
|
+
const spawn6 = i2 >= 0 ? list.splice(i2, 1)[0] : void 0;
|
|
75768
|
+
const seed = spawn6?.seedIntent || (taskDescription ?? "").trim();
|
|
75769
|
+
const entry = {
|
|
75770
|
+
sessionId,
|
|
75771
|
+
agentType,
|
|
75772
|
+
...seed ? { intent: seed } : {},
|
|
75773
|
+
ownIntent: false,
|
|
75774
|
+
share: spawn6?.share ?? null,
|
|
75775
|
+
lastSeenMs: nowMs
|
|
75776
|
+
};
|
|
75777
|
+
agents.set(agentId, entry);
|
|
75778
|
+
return entry;
|
|
75779
|
+
},
|
|
75780
|
+
get: (agentId, nowMs) => touch(agentId, nowMs),
|
|
75781
|
+
setIntent(agentId, text, nowMs) {
|
|
75782
|
+
const a = touch(agentId, nowMs);
|
|
75783
|
+
const trimmed = text.trim();
|
|
75784
|
+
if (!a || !trimmed) return false;
|
|
75785
|
+
const changed = a.intent !== trimmed;
|
|
75786
|
+
a.intent = trimmed;
|
|
75787
|
+
a.ownIntent = true;
|
|
75788
|
+
return changed;
|
|
75789
|
+
},
|
|
75790
|
+
setWorkingFile(agentId, rel, nowMs) {
|
|
75791
|
+
const a = touch(agentId, nowMs);
|
|
75792
|
+
if (!a || a.workingFile === rel) return false;
|
|
75793
|
+
a.workingFile = rel;
|
|
75794
|
+
return true;
|
|
75795
|
+
},
|
|
75796
|
+
stop(agentId) {
|
|
75797
|
+
agents.delete(agentId);
|
|
75798
|
+
}
|
|
75799
|
+
};
|
|
75800
|
+
}
|
|
75801
|
+
|
|
75802
|
+
// src/subagent-context.ts
|
|
75803
|
+
init_src6();
|
|
75804
|
+
init_src5();
|
|
75805
|
+
init_src2();
|
|
75806
|
+
init_recall_signal();
|
|
75807
|
+
var MAX_SHARED_PRIORS = 8;
|
|
75808
|
+
var INTENT_HITS = 4;
|
|
75809
|
+
function resolveSharedPriors(store, wanted, handleMap, remote) {
|
|
75810
|
+
const out2 = [];
|
|
75811
|
+
const seen = /* @__PURE__ */ new Set();
|
|
75812
|
+
for (const ref of wanted) {
|
|
75813
|
+
const id = handleMap[ref]?.id ?? ref;
|
|
75814
|
+
const node2 = store.getNode(id) ?? remote.find((n) => n.id === id || priorHandle(n) === ref) ?? void 0;
|
|
75815
|
+
if (!node2 || seen.has(node2.id)) continue;
|
|
75816
|
+
seen.add(node2.id);
|
|
75817
|
+
out2.push(node2);
|
|
75818
|
+
if (out2.length >= MAX_SHARED_PRIORS) break;
|
|
75819
|
+
}
|
|
75820
|
+
return out2;
|
|
75821
|
+
}
|
|
75822
|
+
function renderSubagentBlock(args2) {
|
|
75823
|
+
const { store, entry } = args2;
|
|
75824
|
+
const snapshot = isolateSnapshot(structuredClone(args2.base));
|
|
75825
|
+
if (entry.workingFile) {
|
|
75826
|
+
const slice = sliceForFile(store, entry.workingFile, args2.atCommit);
|
|
75827
|
+
if (slice) snapshot.workingFile = slice;
|
|
75828
|
+
}
|
|
75829
|
+
const hits = entry.intent ? searchByIntent(store, entry.intent, { limit: INTENT_HITS }).map((h) => ({
|
|
75830
|
+
id: h.node.id,
|
|
75831
|
+
label: h.node.label,
|
|
75832
|
+
description: h.node.description,
|
|
75833
|
+
coverage: h.coverage
|
|
75834
|
+
})) : [];
|
|
75835
|
+
const shared = entry.share && !entry.share.all ? resolveSharedPriors(store, entry.share.priors, args2.handleMap, args2.remote) : [];
|
|
75836
|
+
const { body: body2, snapshot: shown } = assembleAgentContext({
|
|
75837
|
+
store,
|
|
75838
|
+
profile: args2.profile,
|
|
75839
|
+
...args2.atCommit ? { atCommit: args2.atCommit } : {},
|
|
75840
|
+
reviewCount: 0,
|
|
75841
|
+
reviewUiUrl: args2.reviewUiUrl,
|
|
75842
|
+
remote: args2.remote,
|
|
75843
|
+
snapshot,
|
|
75844
|
+
...args2.edgeElicitation ? { edgeElicitation: args2.edgeElicitation } : {},
|
|
75845
|
+
...entry.intent ? { statedIntent: { text: entry.intent, hits } } : {},
|
|
75846
|
+
...shared.length ? { sharedPriors: shared } : {}
|
|
75847
|
+
});
|
|
75848
|
+
const profileNodes = [
|
|
75849
|
+
...shown.profileContext.languages,
|
|
75850
|
+
...shown.profileContext.packages,
|
|
75851
|
+
...shown.profileContext.tools
|
|
75852
|
+
].flatMap((e) => e.node ? [e.node] : []);
|
|
75853
|
+
return {
|
|
75854
|
+
body: body2,
|
|
75855
|
+
hash: contextHash(body2),
|
|
75856
|
+
card: contextCard(store, shown),
|
|
75857
|
+
handleNodes: [...shown.sharedPriors ?? [], ...shown.motifs, ...shown.remote ?? [], ...profileNodes]
|
|
75858
|
+
};
|
|
75859
|
+
}
|
|
75860
|
+
|
|
75861
|
+
// src/engine.ts
|
|
75368
75862
|
init_src8();
|
|
75369
75863
|
init_review2();
|
|
75370
75864
|
|
|
75371
75865
|
// src/turn.ts
|
|
75372
75866
|
init_checkout_root();
|
|
75373
|
-
import { closeSync, existsSync as
|
|
75867
|
+
import { closeSync, existsSync as existsSync19, fstatSync, openSync, readdirSync as readdirSync6, readSync, realpathSync as realpathSync2, statSync as statSync6 } from "node:fs";
|
|
75374
75868
|
import { basename as basename5, delimiter, dirname as dirname10, join as join21, normalize as normalize3 } from "node:path";
|
|
75375
75869
|
import { homedir as homedir4 } from "node:os";
|
|
75376
75870
|
import { createHash as createHash16 } from "node:crypto";
|
|
@@ -75763,7 +76257,7 @@ function claudeProjectDir(cwd, home = homedir4()) {
|
|
|
75763
76257
|
}
|
|
75764
76258
|
function recentTranscripts(cwd, opts = {}) {
|
|
75765
76259
|
const dir = claudeProjectDir(cwd, opts.home ?? homedir4());
|
|
75766
|
-
if (!
|
|
76260
|
+
if (!existsSync19(dir)) return [];
|
|
75767
76261
|
let names;
|
|
75768
76262
|
try {
|
|
75769
76263
|
names = readdirSync6(dir);
|
|
@@ -75790,7 +76284,7 @@ function recentTranscripts(cwd, opts = {}) {
|
|
|
75790
76284
|
function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
75791
76285
|
if (!mainTranscriptPath || !sessionId) return [];
|
|
75792
76286
|
const dir = join21(dirname10(mainTranscriptPath), sessionId, "subagents");
|
|
75793
|
-
if (!
|
|
76287
|
+
if (!existsSync19(dir)) return [];
|
|
75794
76288
|
let names;
|
|
75795
76289
|
try {
|
|
75796
76290
|
names = readdirSync6(dir);
|
|
@@ -75874,7 +76368,7 @@ function codexRolloutsForCwd(cwd, opts = {}) {
|
|
|
75874
76368
|
const owner = checkoutRootOf(cwd);
|
|
75875
76369
|
const owners = /* @__PURE__ */ new Map();
|
|
75876
76370
|
for (const root of codexSessionRoots(opts.env, opts.home)) {
|
|
75877
|
-
if (!
|
|
76371
|
+
if (!existsSync19(root)) {
|
|
75878
76372
|
codexRolloutActivity.delete(root);
|
|
75879
76373
|
continue;
|
|
75880
76374
|
}
|
|
@@ -75944,7 +76438,7 @@ function geminiProjectHash(cwd) {
|
|
|
75944
76438
|
function geminiHashesFor(cwd) {
|
|
75945
76439
|
const variants = /* @__PURE__ */ new Set([cwd, cwd.replace(/\/+$/, "")]);
|
|
75946
76440
|
try {
|
|
75947
|
-
variants.add(
|
|
76441
|
+
variants.add(realpathSync2(cwd));
|
|
75948
76442
|
} catch {
|
|
75949
76443
|
}
|
|
75950
76444
|
return new Set([...variants].map(geminiProjectHash));
|
|
@@ -75975,7 +76469,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
|
|
|
75975
76469
|
const hashes = geminiHashesFor(cwd);
|
|
75976
76470
|
const out2 = [];
|
|
75977
76471
|
for (const root of geminiSessionRoots(opts.env, opts.home)) {
|
|
75978
|
-
if (!
|
|
76472
|
+
if (!existsSync19(root)) continue;
|
|
75979
76473
|
let slugs;
|
|
75980
76474
|
try {
|
|
75981
76475
|
slugs = readdirSync6(root);
|
|
@@ -76041,12 +76535,12 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
|
|
|
76041
76535
|
const limit = opts.limit ?? 25;
|
|
76042
76536
|
const want = /* @__PURE__ */ new Set([cwd, cwd.replace(/\/+$/, "")]);
|
|
76043
76537
|
try {
|
|
76044
|
-
want.add(
|
|
76538
|
+
want.add(realpathSync2(cwd));
|
|
76045
76539
|
} catch {
|
|
76046
76540
|
}
|
|
76047
76541
|
const out2 = [];
|
|
76048
76542
|
for (const root of opencodeSessionRoots(opts.env, opts.home)) {
|
|
76049
|
-
if (!
|
|
76543
|
+
if (!existsSync19(root)) continue;
|
|
76050
76544
|
let names;
|
|
76051
76545
|
try {
|
|
76052
76546
|
names = readdirSync6(root);
|
|
@@ -76078,7 +76572,7 @@ init_src2();
|
|
|
76078
76572
|
init_agent_signals();
|
|
76079
76573
|
init_tool_index();
|
|
76080
76574
|
init_src5();
|
|
76081
|
-
import { readFileSync as
|
|
76575
|
+
import { readFileSync as readFileSync18, writeFileSync as writeFileSync14 } from "node:fs";
|
|
76082
76576
|
var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
|
|
76083
76577
|
var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
|
|
76084
76578
|
var HANDLE_RE = /\[([a-z0-9][\w-]{0,80})\]|((?:pat|sol|drc|dcause|dfix|dprob|dvuln|prob|claim|err)_[0-9a-f]{6,})/gi;
|
|
@@ -76811,13 +77305,13 @@ function writePrimingHandles(path2, nodes, now = Date.now()) {
|
|
|
76811
77305
|
entries.sort((a, b) => (b[1].seenAt ?? 0) - (a[1].seenAt ?? 0));
|
|
76812
77306
|
entries.length = HANDLE_MAP_MAX;
|
|
76813
77307
|
}
|
|
76814
|
-
|
|
77308
|
+
writeFileSync14(path2, JSON.stringify(Object.fromEntries(entries)));
|
|
76815
77309
|
} catch {
|
|
76816
77310
|
}
|
|
76817
77311
|
}
|
|
76818
77312
|
function readPrimingHandles(path2) {
|
|
76819
77313
|
try {
|
|
76820
|
-
return JSON.parse(
|
|
77314
|
+
return JSON.parse(readFileSync18(path2, "utf8"));
|
|
76821
77315
|
} catch {
|
|
76822
77316
|
return {};
|
|
76823
77317
|
}
|
|
@@ -77297,7 +77791,7 @@ ${conversation}` }]
|
|
|
77297
77791
|
// src/constraint-backfill.ts
|
|
77298
77792
|
init_src5();
|
|
77299
77793
|
init_src2();
|
|
77300
|
-
import { existsSync as
|
|
77794
|
+
import { existsSync as existsSync20, readFileSync as readFileSync19, readdirSync as readdirSync7, writeFileSync as writeFileSync15 } from "node:fs";
|
|
77301
77795
|
import { join as join22 } from "node:path";
|
|
77302
77796
|
import { homedir as homedir5 } from "node:os";
|
|
77303
77797
|
var BACKFILL_VERSION = 1;
|
|
@@ -77316,9 +77810,9 @@ function markerPath(configDir) {
|
|
|
77316
77810
|
}
|
|
77317
77811
|
function alreadyDone(configDir) {
|
|
77318
77812
|
const p = markerPath(configDir);
|
|
77319
|
-
if (!
|
|
77813
|
+
if (!existsSync20(p)) return false;
|
|
77320
77814
|
try {
|
|
77321
|
-
const raw2 = JSON.parse(
|
|
77815
|
+
const raw2 = JSON.parse(readFileSync19(p, "utf8"));
|
|
77322
77816
|
return raw2?.version === BACKFILL_VERSION;
|
|
77323
77817
|
} catch {
|
|
77324
77818
|
return false;
|
|
@@ -77328,7 +77822,7 @@ function replay(root) {
|
|
|
77328
77822
|
const statements = /* @__PURE__ */ new Set();
|
|
77329
77823
|
const citedByFix = /* @__PURE__ */ new Set();
|
|
77330
77824
|
const dir = claudeProjectDir(root, homedir5());
|
|
77331
|
-
if (!
|
|
77825
|
+
if (!existsSync20(dir)) return { statements, citedByFix };
|
|
77332
77826
|
let names;
|
|
77333
77827
|
try {
|
|
77334
77828
|
names = readdirSync7(dir).filter((n) => n.endsWith(".jsonl"));
|
|
@@ -77338,7 +77832,7 @@ function replay(root) {
|
|
|
77338
77832
|
for (const f of names) {
|
|
77339
77833
|
let lines;
|
|
77340
77834
|
try {
|
|
77341
|
-
lines =
|
|
77835
|
+
lines = readFileSync19(join22(dir, f), "utf8").split("\n");
|
|
77342
77836
|
} catch {
|
|
77343
77837
|
continue;
|
|
77344
77838
|
}
|
|
@@ -77452,7 +77946,7 @@ function backfillConstraintKind(store, opts) {
|
|
|
77452
77946
|
}
|
|
77453
77947
|
});
|
|
77454
77948
|
try {
|
|
77455
|
-
|
|
77949
|
+
writeFileSync15(
|
|
77456
77950
|
markerPath(opts.configDir),
|
|
77457
77951
|
JSON.stringify({ version: BACKFILL_VERSION, at: opts.now, ...report, cloudTwins: report.cloudTwins.length }, null, 2),
|
|
77458
77952
|
"utf8"
|
|
@@ -77465,7 +77959,7 @@ function backfillConstraintKind(store, opts) {
|
|
|
77465
77959
|
// src/edge-repair.ts
|
|
77466
77960
|
init_src();
|
|
77467
77961
|
init_src5();
|
|
77468
|
-
import { existsSync as
|
|
77962
|
+
import { existsSync as existsSync21, readFileSync as readFileSync20, writeFileSync as writeFileSync16 } from "node:fs";
|
|
77469
77963
|
import { join as join23 } from "node:path";
|
|
77470
77964
|
function citeEdgeId(from, type, to) {
|
|
77471
77965
|
return `edge_${digest({ from, type, to })}`.slice(0, 24);
|
|
@@ -77485,9 +77979,9 @@ function markerPath2(configDir) {
|
|
|
77485
77979
|
}
|
|
77486
77980
|
function alreadyDone2(configDir) {
|
|
77487
77981
|
const p = markerPath2(configDir);
|
|
77488
|
-
if (!
|
|
77982
|
+
if (!existsSync21(p)) return false;
|
|
77489
77983
|
try {
|
|
77490
|
-
return JSON.parse(
|
|
77984
|
+
return JSON.parse(readFileSync20(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
|
|
77491
77985
|
} catch {
|
|
77492
77986
|
return false;
|
|
77493
77987
|
}
|
|
@@ -77536,7 +78030,7 @@ function repairInvalidEdges(store, opts) {
|
|
|
77536
78030
|
});
|
|
77537
78031
|
store.pruneEdgeRejections(opts.now - REJECTION_RETENTION_MS);
|
|
77538
78032
|
try {
|
|
77539
|
-
|
|
78033
|
+
writeFileSync16(
|
|
77540
78034
|
markerPath2(opts.configDir),
|
|
77541
78035
|
JSON.stringify({ version: EDGE_REPAIR_VERSION, at: opts.now, ...report }, null, 2),
|
|
77542
78036
|
"utf8"
|
|
@@ -77550,7 +78044,7 @@ function repairInvalidEdges(store, opts) {
|
|
|
77550
78044
|
init_reconcile();
|
|
77551
78045
|
|
|
77552
78046
|
// src/pass-ledger.ts
|
|
77553
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
78047
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync22, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "node:fs";
|
|
77554
78048
|
import { join as join24 } from "node:path";
|
|
77555
78049
|
|
|
77556
78050
|
// src/isolate-census.ts
|
|
@@ -77603,7 +78097,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
|
77603
78097
|
return;
|
|
77604
78098
|
}
|
|
77605
78099
|
appendsSinceTrim.set(path2, 0);
|
|
77606
|
-
const lines =
|
|
78100
|
+
const lines = readFileSync21(path2, "utf8").split("\n").filter(Boolean);
|
|
77607
78101
|
const keptByKind = /* @__PURE__ */ new Map();
|
|
77608
78102
|
const kept = [];
|
|
77609
78103
|
for (let i2 = lines.length - 1; i2 >= 0; i2--) {
|
|
@@ -77619,16 +78113,16 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
|
77619
78113
|
kept.push(lines[i2]);
|
|
77620
78114
|
}
|
|
77621
78115
|
if (kept.length < lines.length) {
|
|
77622
|
-
|
|
78116
|
+
writeFileSync17(path2, kept.reverse().join("\n") + "\n");
|
|
77623
78117
|
}
|
|
77624
78118
|
} catch {
|
|
77625
78119
|
}
|
|
77626
78120
|
}
|
|
77627
78121
|
function readPassLedger(configDir) {
|
|
77628
78122
|
const path2 = passLedgerPath(configDir);
|
|
77629
|
-
if (!
|
|
78123
|
+
if (!existsSync22(path2)) return [];
|
|
77630
78124
|
try {
|
|
77631
|
-
return
|
|
78125
|
+
return readFileSync21(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
|
|
77632
78126
|
(e) => typeof e?.ts === "number" && typeof e?.kind === "string" && typeof e?.durationMs === "number"
|
|
77633
78127
|
).map((e) => ({ ...e, counts: e.counts ?? {} }));
|
|
77634
78128
|
} catch {
|
|
@@ -77924,8 +78418,8 @@ var PassWorker = class {
|
|
|
77924
78418
|
const id = this.nextId++;
|
|
77925
78419
|
try {
|
|
77926
78420
|
await this.ready;
|
|
77927
|
-
return await new Promise((
|
|
77928
|
-
this.pending.set(id, { resolve:
|
|
78421
|
+
return await new Promise((resolve9, reject) => {
|
|
78422
|
+
this.pending.set(id, { resolve: resolve9, reject });
|
|
77929
78423
|
this.worker.postMessage({ id, kind, ...payload !== void 0 ? { payload } : {} });
|
|
77930
78424
|
});
|
|
77931
78425
|
} finally {
|
|
@@ -77959,12 +78453,12 @@ var PassWorker = class {
|
|
|
77959
78453
|
});
|
|
77960
78454
|
noteIsolateSpawned();
|
|
77961
78455
|
this.worker = worker;
|
|
77962
|
-
this.ready = new Promise((
|
|
78456
|
+
this.ready = new Promise((resolve9, reject) => {
|
|
77963
78457
|
const onReady = (m) => {
|
|
77964
78458
|
if (m?.ready) {
|
|
77965
78459
|
worker.off("message", onReady);
|
|
77966
78460
|
worker.off("error", onErr);
|
|
77967
|
-
|
|
78461
|
+
resolve9();
|
|
77968
78462
|
}
|
|
77969
78463
|
};
|
|
77970
78464
|
const onErr = (err2) => reject(err2);
|
|
@@ -78009,11 +78503,11 @@ init_outbox();
|
|
|
78009
78503
|
init_src10();
|
|
78010
78504
|
init_src();
|
|
78011
78505
|
init_src2();
|
|
78012
|
-
import { readFileSync as
|
|
78506
|
+
import { readFileSync as readFileSync22 } from "node:fs";
|
|
78013
78507
|
import { join as join25 } from "node:path";
|
|
78014
78508
|
function loadClaimIgnorePatterns(workspaceRoot) {
|
|
78015
78509
|
try {
|
|
78016
|
-
return
|
|
78510
|
+
return readFileSync22(join25(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
|
|
78017
78511
|
} catch {
|
|
78018
78512
|
return [];
|
|
78019
78513
|
}
|
|
@@ -78391,7 +78885,7 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
|
|
|
78391
78885
|
// src/retrieval-stack.ts
|
|
78392
78886
|
init_src();
|
|
78393
78887
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
78394
|
-
import { existsSync as
|
|
78888
|
+
import { existsSync as existsSync23, readFileSync as readFileSync23, statSync as statSync7 } from "node:fs";
|
|
78395
78889
|
import { homedir as homedir6 } from "node:os";
|
|
78396
78890
|
import { join as join26 } from "node:path";
|
|
78397
78891
|
var RETRIEVAL_STACK_CAP = 24;
|
|
@@ -78683,7 +79177,7 @@ function mavenGroupIsSelfDisclosing(name2, selfTokens) {
|
|
|
78683
79177
|
function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
|
|
78684
79178
|
const read2 = (p) => {
|
|
78685
79179
|
try {
|
|
78686
|
-
return
|
|
79180
|
+
return readFileSync23(p, "utf8");
|
|
78687
79181
|
} catch {
|
|
78688
79182
|
return null;
|
|
78689
79183
|
}
|
|
@@ -78909,7 +79403,7 @@ function readDirectDependencies(root) {
|
|
|
78909
79403
|
for (const c of LOCKFILES) {
|
|
78910
79404
|
if (familiesSeen.has(c.family)) continue;
|
|
78911
79405
|
const p = join26(root, c.file);
|
|
78912
|
-
if (!
|
|
79406
|
+
if (!existsSync23(p)) continue;
|
|
78913
79407
|
try {
|
|
78914
79408
|
const s = statSync7(p);
|
|
78915
79409
|
stamps.push(`${c.file}:${s.mtimeMs}:${s.size}`);
|
|
@@ -78929,7 +79423,7 @@ function readDirectDependencies(root) {
|
|
|
78929
79423
|
const direct = [];
|
|
78930
79424
|
for (const { c, path: path2 } of found) {
|
|
78931
79425
|
try {
|
|
78932
|
-
direct.push(...c.parse(
|
|
79426
|
+
direct.push(...c.parse(readFileSync23(path2, "utf8")).direct ?? []);
|
|
78933
79427
|
} catch {
|
|
78934
79428
|
}
|
|
78935
79429
|
}
|
|
@@ -78972,14 +79466,14 @@ function manifestPaths(root) {
|
|
|
78972
79466
|
"project.godot"
|
|
78973
79467
|
];
|
|
78974
79468
|
return {
|
|
78975
|
-
paths: ROOT_MANIFESTS.filter((f) =>
|
|
79469
|
+
paths: ROOT_MANIFESTS.filter((f) => existsSync23(join26(root, f))),
|
|
78976
79470
|
tracked: false,
|
|
78977
79471
|
truncated: false
|
|
78978
79472
|
};
|
|
78979
79473
|
}
|
|
78980
79474
|
var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
|
|
78981
79475
|
function rootDeclaresWorkspace(root, texts) {
|
|
78982
|
-
if (WORKSPACE_MARKERS.some((f) =>
|
|
79476
|
+
if (WORKSPACE_MARKERS.some((f) => existsSync23(join26(root, f)))) return true;
|
|
78983
79477
|
return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
|
|
78984
79478
|
}
|
|
78985
79479
|
var EMPTY_SCAN = { deps: [], self: [], complete: true };
|
|
@@ -78997,7 +79491,7 @@ function scanManifests(root) {
|
|
|
78997
79491
|
try {
|
|
78998
79492
|
const s = statSync7(abs);
|
|
78999
79493
|
stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
|
|
79000
|
-
texts.set(rel,
|
|
79494
|
+
texts.set(rel, readFileSync23(abs, "utf8"));
|
|
79001
79495
|
} catch {
|
|
79002
79496
|
}
|
|
79003
79497
|
}
|
|
@@ -79033,11 +79527,11 @@ function readRetrievalInputs(root, repoLocator) {
|
|
|
79033
79527
|
}
|
|
79034
79528
|
|
|
79035
79529
|
// src/git-sensor.ts
|
|
79036
|
-
import { existsSync as
|
|
79530
|
+
import { existsSync as existsSync24, readFileSync as readFileSync24, watch as fsWatch } from "node:fs";
|
|
79037
79531
|
import { join as join27 } from "node:path";
|
|
79038
79532
|
function readFirstLine(path2) {
|
|
79039
79533
|
try {
|
|
79040
|
-
return
|
|
79534
|
+
return readFileSync24(path2, "utf8").split(/\r?\n/, 1)[0].trim();
|
|
79041
79535
|
} catch {
|
|
79042
79536
|
return null;
|
|
79043
79537
|
}
|
|
@@ -79056,13 +79550,13 @@ function readGitRefState(gitDir) {
|
|
|
79056
79550
|
return {
|
|
79057
79551
|
branch,
|
|
79058
79552
|
sha: sha2,
|
|
79059
|
-
mergeHeadExists:
|
|
79060
|
-
origHeadExists:
|
|
79553
|
+
mergeHeadExists: existsSync24(join27(gitDir, "MERGE_HEAD")),
|
|
79554
|
+
origHeadExists: existsSync24(join27(gitDir, "ORIG_HEAD"))
|
|
79061
79555
|
};
|
|
79062
79556
|
}
|
|
79063
79557
|
function shaFromPackedRefs(gitDir, ref) {
|
|
79064
79558
|
try {
|
|
79065
|
-
for (const line of
|
|
79559
|
+
for (const line of readFileSync24(join27(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
|
|
79066
79560
|
const [sha2, name2] = line.split(/\s+/);
|
|
79067
79561
|
if (name2 === ref && sha2) return sha2;
|
|
79068
79562
|
}
|
|
@@ -79096,7 +79590,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
79096
79590
|
const settle = () => {
|
|
79097
79591
|
if (timer) clearTimeout(timer);
|
|
79098
79592
|
timer = setTimeout(() => {
|
|
79099
|
-
if (
|
|
79593
|
+
if (existsSync24(join27(gitDir, "index.lock"))) {
|
|
79100
79594
|
settle();
|
|
79101
79595
|
return;
|
|
79102
79596
|
}
|
|
@@ -79127,7 +79621,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
79127
79621
|
// src/git-delta.ts
|
|
79128
79622
|
import { execFile } from "node:child_process";
|
|
79129
79623
|
function git(repoDir, args2) {
|
|
79130
|
-
return new Promise((
|
|
79624
|
+
return new Promise((resolve9, reject) => {
|
|
79131
79625
|
execFile(
|
|
79132
79626
|
"git",
|
|
79133
79627
|
["-C", repoDir, ...args2],
|
|
@@ -79138,7 +79632,7 @@ function git(repoDir, args2) {
|
|
|
79138
79632
|
// git-sensor runs on every commit/checkout.
|
|
79139
79633
|
windowsHide: true
|
|
79140
79634
|
},
|
|
79141
|
-
(err2, stdout) => err2 ? reject(err2) :
|
|
79635
|
+
(err2, stdout) => err2 ? reject(err2) : resolve9(stdout)
|
|
79142
79636
|
);
|
|
79143
79637
|
});
|
|
79144
79638
|
}
|
|
@@ -79331,7 +79825,7 @@ var TelemetryRecorder = class {
|
|
|
79331
79825
|
};
|
|
79332
79826
|
|
|
79333
79827
|
// src/file-activity.ts
|
|
79334
|
-
import { readFileSync as
|
|
79828
|
+
import { readFileSync as readFileSync26 } from "node:fs";
|
|
79335
79829
|
import { join as join29 } from "node:path";
|
|
79336
79830
|
import { createHash as createHash17 } from "node:crypto";
|
|
79337
79831
|
|
|
@@ -80084,7 +80578,7 @@ init_git_remote();
|
|
|
80084
80578
|
// src/history-bundle.ts
|
|
80085
80579
|
init_src();
|
|
80086
80580
|
import { execFile as execFile2 } from "node:child_process";
|
|
80087
|
-
import { readFileSync as
|
|
80581
|
+
import { readFileSync as readFileSync25 } from "node:fs";
|
|
80088
80582
|
import { join as join28 } from "node:path";
|
|
80089
80583
|
var DEFAULT_MAX_TOKENS = 6e3;
|
|
80090
80584
|
var FILE_LIST_CAP = 60;
|
|
@@ -80120,7 +80614,7 @@ function pathAllowedByFloor(path2) {
|
|
|
80120
80614
|
function loadRepoIgnore(root, extraPatterns = []) {
|
|
80121
80615
|
let source = "";
|
|
80122
80616
|
try {
|
|
80123
|
-
source =
|
|
80617
|
+
source = readFileSync25(join28(root, ".errataignore"), "utf8");
|
|
80124
80618
|
} catch {
|
|
80125
80619
|
source = "";
|
|
80126
80620
|
}
|
|
@@ -80296,12 +80790,12 @@ function headerPaths(diff) {
|
|
|
80296
80790
|
return out2.filter((p) => p !== "/dev/null");
|
|
80297
80791
|
}
|
|
80298
80792
|
function git2(repoDir, args2) {
|
|
80299
|
-
return new Promise((
|
|
80793
|
+
return new Promise((resolve9, reject) => {
|
|
80300
80794
|
execFile2(
|
|
80301
80795
|
"git",
|
|
80302
80796
|
["-C", repoDir, ...args2],
|
|
80303
80797
|
{ encoding: "utf8", maxBuffer: 64 * 1024 * 1024, windowsHide: true },
|
|
80304
|
-
(err2, stdout) => err2 ? reject(err2) :
|
|
80798
|
+
(err2, stdout) => err2 ? reject(err2) : resolve9(stdout)
|
|
80305
80799
|
);
|
|
80306
80800
|
});
|
|
80307
80801
|
}
|
|
@@ -80413,7 +80907,7 @@ function readActivityBranch(root) {
|
|
|
80413
80907
|
try {
|
|
80414
80908
|
const gitDir = resolveGitDir(root);
|
|
80415
80909
|
if (!gitDir) return null;
|
|
80416
|
-
const head2 =
|
|
80910
|
+
const head2 = readFileSync26(join29(gitDir, "HEAD"), "utf8").trim();
|
|
80417
80911
|
const branch = head2.startsWith("ref: refs/heads/") ? head2.slice(16) : /^[a-f0-9]{40,64}$/i.test(head2) ? "HEAD" : null;
|
|
80418
80912
|
return branch && branch.length <= 256 && !/[\x00-\x1f\x7f]/.test(branch) ? branch : null;
|
|
80419
80913
|
} catch {
|
|
@@ -80570,21 +81064,21 @@ var FileActivityReporter = class {
|
|
|
80570
81064
|
|
|
80571
81065
|
// src/skills.ts
|
|
80572
81066
|
import {
|
|
80573
|
-
existsSync as
|
|
81067
|
+
existsSync as existsSync25,
|
|
80574
81068
|
mkdirSync as mkdirSync7,
|
|
80575
|
-
readFileSync as
|
|
81069
|
+
readFileSync as readFileSync27,
|
|
80576
81070
|
readdirSync as readdirSync8,
|
|
80577
81071
|
unlinkSync as unlinkSync4,
|
|
80578
|
-
writeFileSync as
|
|
81072
|
+
writeFileSync as writeFileSync18
|
|
80579
81073
|
} from "node:fs";
|
|
80580
81074
|
import { basename as basename6, join as join30 } from "node:path";
|
|
80581
81075
|
function skillFileName(id) {
|
|
80582
81076
|
return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
|
|
80583
81077
|
}
|
|
80584
81078
|
function readSkillManifest(manifestPath) {
|
|
80585
|
-
if (!
|
|
81079
|
+
if (!existsSync25(manifestPath)) return [];
|
|
80586
81080
|
try {
|
|
80587
|
-
const parsed = JSON.parse(
|
|
81081
|
+
const parsed = JSON.parse(readFileSync27(manifestPath, "utf8"));
|
|
80588
81082
|
return (parsed.skills ?? []).map((s) => ({
|
|
80589
81083
|
title: s.title ?? "",
|
|
80590
81084
|
layer: s.layer ?? "technique",
|
|
@@ -80608,7 +81102,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
80608
81102
|
for (const s of res.skills) {
|
|
80609
81103
|
const fileName = skillFileName(s.id);
|
|
80610
81104
|
keep.add(fileName);
|
|
80611
|
-
|
|
81105
|
+
writeFileSync18(join30(paths.skillsDir, fileName), s.markdown, "utf8");
|
|
80612
81106
|
rows.push({
|
|
80613
81107
|
id: s.id,
|
|
80614
81108
|
title: s.title,
|
|
@@ -80621,7 +81115,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
80621
81115
|
const fileName = skillFileName(p.id);
|
|
80622
81116
|
if (keep.has(fileName)) continue;
|
|
80623
81117
|
keep.add(fileName);
|
|
80624
|
-
|
|
81118
|
+
writeFileSync18(join30(paths.skillsDir, fileName), p.markdown, "utf8");
|
|
80625
81119
|
rows.push({
|
|
80626
81120
|
id: p.id,
|
|
80627
81121
|
title: p.title,
|
|
@@ -80641,7 +81135,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
80641
81135
|
}
|
|
80642
81136
|
}
|
|
80643
81137
|
rows.sort((a, b) => a.id.localeCompare(b.id));
|
|
80644
|
-
|
|
81138
|
+
writeFileSync18(
|
|
80645
81139
|
paths.skillsManifest,
|
|
80646
81140
|
JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
|
|
80647
81141
|
"utf8"
|
|
@@ -80653,14 +81147,14 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
80653
81147
|
init_src2();
|
|
80654
81148
|
import {
|
|
80655
81149
|
cpSync,
|
|
80656
|
-
existsSync as
|
|
81150
|
+
existsSync as existsSync26,
|
|
80657
81151
|
lstatSync,
|
|
80658
81152
|
mkdirSync as mkdirSync8,
|
|
80659
|
-
readFileSync as
|
|
81153
|
+
readFileSync as readFileSync28,
|
|
80660
81154
|
readdirSync as readdirSync9,
|
|
80661
81155
|
rmSync as rmSync3,
|
|
80662
81156
|
symlinkSync,
|
|
80663
|
-
writeFileSync as
|
|
81157
|
+
writeFileSync as writeFileSync19
|
|
80664
81158
|
} from "node:fs";
|
|
80665
81159
|
import { join as join31 } from "node:path";
|
|
80666
81160
|
var SKILL_NS = "errata-";
|
|
@@ -80713,7 +81207,7 @@ function skillCiteHandle(s) {
|
|
|
80713
81207
|
return priorHandle({ id: s.id, description: s.title });
|
|
80714
81208
|
}
|
|
80715
81209
|
function reconcileNamespaced(dir, keep) {
|
|
80716
|
-
if (!
|
|
81210
|
+
if (!existsSync26(dir)) return 0;
|
|
80717
81211
|
let pruned = 0;
|
|
80718
81212
|
for (const name2 of readdirSync9(dir)) {
|
|
80719
81213
|
if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
|
|
@@ -80727,7 +81221,7 @@ function reconcileNamespaced(dir, keep) {
|
|
|
80727
81221
|
}
|
|
80728
81222
|
function linkOrCopy(linkPath, target) {
|
|
80729
81223
|
try {
|
|
80730
|
-
if (
|
|
81224
|
+
if (existsSync26(linkPath) || safeLstat(linkPath)) rmSync3(linkPath, { recursive: true, force: true });
|
|
80731
81225
|
} catch {
|
|
80732
81226
|
}
|
|
80733
81227
|
try {
|
|
@@ -80756,7 +81250,7 @@ function emitAndProjectSkills(root, skills) {
|
|
|
80756
81250
|
for (const s of skills) {
|
|
80757
81251
|
let body2;
|
|
80758
81252
|
try {
|
|
80759
|
-
body2 =
|
|
81253
|
+
body2 = readFileSync28(s.bodyPath, "utf8");
|
|
80760
81254
|
} catch {
|
|
80761
81255
|
continue;
|
|
80762
81256
|
}
|
|
@@ -80766,7 +81260,7 @@ function emitAndProjectSkills(root, skills) {
|
|
|
80766
81260
|
slugs.push(slug2);
|
|
80767
81261
|
const description = deriveDescription(s.title, s.layer, body2);
|
|
80768
81262
|
mkdirSync8(join31(agentsSkillsDir, slug2), { recursive: true });
|
|
80769
|
-
|
|
81263
|
+
writeFileSync19(
|
|
80770
81264
|
join31(agentsSkillsDir, slug2, "SKILL.md"),
|
|
80771
81265
|
renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
|
|
80772
81266
|
"utf8"
|
|
@@ -80776,7 +81270,7 @@ function emitAndProjectSkills(root, skills) {
|
|
|
80776
81270
|
reconcileNamespaced(agentsSkillsDir, keep);
|
|
80777
81271
|
let projected = 0;
|
|
80778
81272
|
for (const h of HARNESS_SKILL_DIRS) {
|
|
80779
|
-
if (!
|
|
81273
|
+
if (!existsSync26(join31(root, h.configDir))) continue;
|
|
80780
81274
|
const dir = join31(root, h.skillsDir);
|
|
80781
81275
|
mkdirSync8(dir, { recursive: true });
|
|
80782
81276
|
for (const slug2 of slugs) {
|
|
@@ -80789,9 +81283,9 @@ function emitAndProjectSkills(root, skills) {
|
|
|
80789
81283
|
return { slugs, emitted, projected };
|
|
80790
81284
|
}
|
|
80791
81285
|
function emitInputsFromManifest(erretaDir, manifestPath) {
|
|
80792
|
-
if (!
|
|
81286
|
+
if (!existsSync26(manifestPath)) return [];
|
|
80793
81287
|
try {
|
|
80794
|
-
const parsed = JSON.parse(
|
|
81288
|
+
const parsed = JSON.parse(readFileSync28(manifestPath, "utf8"));
|
|
80795
81289
|
return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
|
|
80796
81290
|
id: s.id,
|
|
80797
81291
|
title: s.title ?? s.id,
|
|
@@ -80814,14 +81308,14 @@ function ensureSkillGitignore(root) {
|
|
|
80814
81308
|
const path2 = join31(root, ".gitignore");
|
|
80815
81309
|
let current = "";
|
|
80816
81310
|
try {
|
|
80817
|
-
current =
|
|
81311
|
+
current = existsSync26(path2) ? readFileSync28(path2, "utf8") : "";
|
|
80818
81312
|
} catch {
|
|
80819
81313
|
return;
|
|
80820
81314
|
}
|
|
80821
81315
|
if (current.includes(GITIGNORE_MARK)) return;
|
|
80822
81316
|
const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
|
|
80823
81317
|
try {
|
|
80824
|
-
|
|
81318
|
+
writeFileSync19(path2, `${current}${prefix}
|
|
80825
81319
|
${GITIGNORE_LINES.join("\n")}
|
|
80826
81320
|
`, "utf8");
|
|
80827
81321
|
} catch {
|
|
@@ -80917,7 +81411,7 @@ init_paths();
|
|
|
80917
81411
|
init_profile2();
|
|
80918
81412
|
|
|
80919
81413
|
// src/witness-queue.ts
|
|
80920
|
-
import { readFileSync as
|
|
81414
|
+
import { readFileSync as readFileSync29, renameSync as renameSync3, writeFileSync as writeFileSync20 } from "node:fs";
|
|
80921
81415
|
import { dirname as dirname11, join as join32 } from "node:path";
|
|
80922
81416
|
var WITNESS_QUEUE_CAP = 500;
|
|
80923
81417
|
var WITNESS_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
@@ -80928,7 +81422,7 @@ function witnessQueuePath(workspaceConfigDir) {
|
|
|
80928
81422
|
function loadWitnessQueueWithLosses(path2) {
|
|
80929
81423
|
let raw2;
|
|
80930
81424
|
try {
|
|
80931
|
-
raw2 = JSON.parse(
|
|
81425
|
+
raw2 = JSON.parse(readFileSync29(path2, "utf8"));
|
|
80932
81426
|
} catch (err2) {
|
|
80933
81427
|
const absent = err2?.code === "ENOENT";
|
|
80934
81428
|
return { queue: [], fileUnreadable: !absent, malformedEntries: 0 };
|
|
@@ -80942,7 +81436,7 @@ function loadWitnessQueueWithLosses(path2) {
|
|
|
80942
81436
|
function saveWitnessQueue(path2, queue) {
|
|
80943
81437
|
try {
|
|
80944
81438
|
const tmp = join32(dirname11(path2), `.${Date.now()}.witness-queue.tmp`);
|
|
80945
|
-
|
|
81439
|
+
writeFileSync20(tmp, JSON.stringify(queue), "utf8");
|
|
80946
81440
|
renameSync3(tmp, path2);
|
|
80947
81441
|
} catch {
|
|
80948
81442
|
}
|
|
@@ -81249,7 +81743,7 @@ function maybeFlushDigests() {
|
|
|
81249
81743
|
|
|
81250
81744
|
// src/liveness-watch.ts
|
|
81251
81745
|
init_src5();
|
|
81252
|
-
import { readFileSync as
|
|
81746
|
+
import { readFileSync as readFileSync31, writeFileSync as writeFileSync22 } from "node:fs";
|
|
81253
81747
|
import { join as join34 } from "node:path";
|
|
81254
81748
|
|
|
81255
81749
|
// src/loop-lag.ts
|
|
@@ -81385,7 +81879,7 @@ function alarmStatePath(configDir) {
|
|
|
81385
81879
|
}
|
|
81386
81880
|
function loadAlarmState(configDir) {
|
|
81387
81881
|
try {
|
|
81388
|
-
const raw2 = JSON.parse(
|
|
81882
|
+
const raw2 = JSON.parse(readFileSync31(alarmStatePath(configDir), "utf8"));
|
|
81389
81883
|
return new Map(Object.entries(raw2).filter((e) => typeof e[1] === "number"));
|
|
81390
81884
|
} catch {
|
|
81391
81885
|
return /* @__PURE__ */ new Map();
|
|
@@ -81393,7 +81887,7 @@ function loadAlarmState(configDir) {
|
|
|
81393
81887
|
}
|
|
81394
81888
|
function saveAlarmState(configDir, state) {
|
|
81395
81889
|
try {
|
|
81396
|
-
|
|
81890
|
+
writeFileSync22(alarmStatePath(configDir), JSON.stringify(Object.fromEntries(state)));
|
|
81397
81891
|
} catch {
|
|
81398
81892
|
}
|
|
81399
81893
|
}
|
|
@@ -81593,7 +82087,7 @@ function createWatchBreaker(deps) {
|
|
|
81593
82087
|
}
|
|
81594
82088
|
|
|
81595
82089
|
// src/engine.ts
|
|
81596
|
-
var DAEMON_VERSION = true ? "2.0.17-dev.
|
|
82090
|
+
var DAEMON_VERSION = true ? "2.0.17-dev.3426" : "2.0.0-alpha.0";
|
|
81597
82091
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
81598
82092
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
81599
82093
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -81605,7 +82099,7 @@ var CODEX_SWEEP_LOOKBACK_MS = 10 * 6e4;
|
|
|
81605
82099
|
function appendIdentityAudit(path2, record2, line) {
|
|
81606
82100
|
if (!record2.accepted && record2.score <= 0) return;
|
|
81607
82101
|
try {
|
|
81608
|
-
if (
|
|
82102
|
+
if (existsSync28(path2) && statSync8(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
|
|
81609
82103
|
renameSync4(path2, `${path2}.1`);
|
|
81610
82104
|
}
|
|
81611
82105
|
appendFileSync4(path2, line);
|
|
@@ -81615,7 +82109,7 @@ function appendIdentityAudit(path2, record2, line) {
|
|
|
81615
82109
|
var yieldToLoop = () => new Promise((r) => setImmediate(r));
|
|
81616
82110
|
function loadTurnCursors(path2) {
|
|
81617
82111
|
try {
|
|
81618
|
-
const raw2 = JSON.parse(
|
|
82112
|
+
const raw2 = JSON.parse(readFileSync32(path2, "utf8"));
|
|
81619
82113
|
return new Map(
|
|
81620
82114
|
Object.entries(raw2).map(([k, v]) => [k, typeof v === "string" ? v : String(v?.uuid ?? "")])
|
|
81621
82115
|
);
|
|
@@ -81625,7 +82119,7 @@ function loadTurnCursors(path2) {
|
|
|
81625
82119
|
}
|
|
81626
82120
|
function loadTurnOffsets(path2) {
|
|
81627
82121
|
try {
|
|
81628
|
-
const raw2 = JSON.parse(
|
|
82122
|
+
const raw2 = JSON.parse(readFileSync32(path2, "utf8"));
|
|
81629
82123
|
const out2 = /* @__PURE__ */ new Map();
|
|
81630
82124
|
for (const [k, v] of Object.entries(raw2)) {
|
|
81631
82125
|
const off = typeof v === "object" && v !== null ? v.offset : void 0;
|
|
@@ -81641,7 +82135,7 @@ function saveTurnCursors(path2, cursors, offsets) {
|
|
|
81641
82135
|
const merged = {};
|
|
81642
82136
|
for (const [k, uuid3] of cursors) merged[k] = { uuid: uuid3, offset: offsets.get(k) ?? 0 };
|
|
81643
82137
|
for (const [k, offset] of offsets) if (!merged[k]) merged[k] = { uuid: "", offset };
|
|
81644
|
-
|
|
82138
|
+
writeFileSync23(path2, JSON.stringify(merged), "utf8");
|
|
81645
82139
|
} catch {
|
|
81646
82140
|
}
|
|
81647
82141
|
}
|
|
@@ -81930,7 +82424,7 @@ function createWorkspaceEngine(opts) {
|
|
|
81930
82424
|
);
|
|
81931
82425
|
};
|
|
81932
82426
|
const gitDir = join35(opts.workspaceRoot, ".git");
|
|
81933
|
-
if (
|
|
82427
|
+
if (existsSync28(gitDir)) {
|
|
81934
82428
|
stopGit = startGitSensor(gitDir, (ev) => {
|
|
81935
82429
|
void handleGitEvent(ev).catch((err2) => {
|
|
81936
82430
|
console.warn("[errata] git event handler failed:", err2);
|
|
@@ -81991,6 +82485,13 @@ function createWorkspaceEngine(opts) {
|
|
|
81991
82485
|
witnessParked: () => witnessQueue.length
|
|
81992
82486
|
});
|
|
81993
82487
|
const intents = createIntentState();
|
|
82488
|
+
const subagents = createSubagentState();
|
|
82489
|
+
let subagentBase = null;
|
|
82490
|
+
let subagentBaseVersion = 0;
|
|
82491
|
+
const subagentRenders = /* @__PURE__ */ new Map();
|
|
82492
|
+
const sessions = createSessionRegistry({ originsPath: join35(paths.configDir, "session-origins.json") });
|
|
82493
|
+
const sessionRenders = /* @__PURE__ */ new Map();
|
|
82494
|
+
const selfCiteSkipsBySession = /* @__PURE__ */ new Map();
|
|
81994
82495
|
const toolRuns = createToolRunState();
|
|
81995
82496
|
let ctxRefreshTimer = null;
|
|
81996
82497
|
let contextDirty = false;
|
|
@@ -82046,6 +82547,22 @@ function createWorkspaceEngine(opts) {
|
|
|
82046
82547
|
return [];
|
|
82047
82548
|
}
|
|
82048
82549
|
};
|
|
82550
|
+
const statedIntentFor = (intent) => {
|
|
82551
|
+
const collective = intentRemote?.forIntent === intent ? intentRemote : null;
|
|
82552
|
+
return {
|
|
82553
|
+
text: intent,
|
|
82554
|
+
hits: searchByIntent(store, intent, { limit: 4 }).map((h) => ({
|
|
82555
|
+
id: h.node.id,
|
|
82556
|
+
label: h.node.label,
|
|
82557
|
+
description: h.node.description,
|
|
82558
|
+
coverage: h.coverage
|
|
82559
|
+
})),
|
|
82560
|
+
...collective && collective.hits.length > 0 ? {
|
|
82561
|
+
remoteHits: collective.hits.slice(0, 4).map((n) => ({ id: n.id, label: n.label, description: n.description }))
|
|
82562
|
+
} : {},
|
|
82563
|
+
...collective?.voidSignal ? { knownGap: collective.voidSignal } : {}
|
|
82564
|
+
};
|
|
82565
|
+
};
|
|
82049
82566
|
const refreshContextOnce = async () => {
|
|
82050
82567
|
const elicit = isEdgeElicitationEnabled();
|
|
82051
82568
|
const snapOpts = {
|
|
@@ -82069,41 +82586,26 @@ function createWorkspaceEngine(opts) {
|
|
|
82069
82586
|
return;
|
|
82070
82587
|
}
|
|
82071
82588
|
const doneRender = markPass(`${prebuilt ? "context-render" : "context-render-inline"}:${profile.name}`);
|
|
82589
|
+
const base = prebuilt ?? buildSnapshot({ store, ...snapOpts });
|
|
82590
|
+
subagentBase = structuredClone(base);
|
|
82591
|
+
subagentBaseVersion++;
|
|
82592
|
+
const sharedSnapshot = scopeSnapshot(base, (n) => !isQuarantined(n, sessions));
|
|
82072
82593
|
const pendingUpdate = opts.pendingUpdate?.() ?? null;
|
|
82073
82594
|
const daemonDistress = opts.daemonDistress?.() ?? null;
|
|
82074
82595
|
const reviewItems = pickReviewItems();
|
|
82075
82596
|
const liveIntent = intents.mostRecent(Date.now());
|
|
82076
82597
|
maybeRefreshIntentPriors(liveIntent ?? null);
|
|
82077
|
-
const
|
|
82078
|
-
id: h.node.id,
|
|
82079
|
-
label: h.node.label,
|
|
82080
|
-
description: h.node.description,
|
|
82081
|
-
coverage: h.coverage
|
|
82082
|
-
})) : [];
|
|
82083
|
-
const intentCollective = liveIntent && intentRemote?.forIntent === liveIntent ? intentRemote : null;
|
|
82598
|
+
const statedIntent = liveIntent ? statedIntentFor(liveIntent) : null;
|
|
82084
82599
|
const { body: body2, snapshot, ledger } = assembleAgentContext({
|
|
82085
82600
|
store,
|
|
82086
82601
|
...snapOpts,
|
|
82087
82602
|
remote: remotePriors,
|
|
82088
82603
|
...elicit ? { edgeElicitation: { instruction: PRIOR_TAG_INSTRUCTION } } : {},
|
|
82089
|
-
|
|
82604
|
+
snapshot: sharedSnapshot,
|
|
82090
82605
|
...pendingUpdate ? { pendingUpdate } : {},
|
|
82091
82606
|
...daemonDistress ? { daemonDistress } : {},
|
|
82092
82607
|
...reviewItems.length ? { reviewItems } : {},
|
|
82093
|
-
...
|
|
82094
|
-
statedIntent: {
|
|
82095
|
-
text: liveIntent,
|
|
82096
|
-
hits: intentHits,
|
|
82097
|
-
...intentCollective && intentCollective.hits.length > 0 ? {
|
|
82098
|
-
remoteHits: intentCollective.hits.slice(0, 4).map((n) => ({
|
|
82099
|
-
id: n.id,
|
|
82100
|
-
label: n.label,
|
|
82101
|
-
description: n.description
|
|
82102
|
-
}))
|
|
82103
|
-
} : {},
|
|
82104
|
-
...intentCollective?.voidSignal ? { knownGap: intentCollective.voidSignal } : {}
|
|
82105
|
-
}
|
|
82106
|
-
} : {}
|
|
82608
|
+
...statedIntent ? { statedIntent } : {}
|
|
82107
82609
|
});
|
|
82108
82610
|
doneRender();
|
|
82109
82611
|
try {
|
|
@@ -82408,7 +82910,11 @@ function createWorkspaceEngine(opts) {
|
|
|
82408
82910
|
}
|
|
82409
82911
|
return { report, localSkills: 0 };
|
|
82410
82912
|
};
|
|
82411
|
-
const onWorkingFileChanged = (rel, sessionId) => {
|
|
82913
|
+
const onWorkingFileChanged = (rel, sessionId, agentId) => {
|
|
82914
|
+
if (agentId) {
|
|
82915
|
+
subagents.setWorkingFile(agentId, rel, Date.now());
|
|
82916
|
+
return;
|
|
82917
|
+
}
|
|
82412
82918
|
if (!workingFiles.set(sessionId, rel)) return;
|
|
82413
82919
|
contextDirty = true;
|
|
82414
82920
|
if (ctxRefreshTimer) clearTimeout(ctxRefreshTimer);
|
|
@@ -82419,6 +82925,125 @@ function createWorkspaceEngine(opts) {
|
|
|
82419
82925
|
}
|
|
82420
82926
|
}, 500);
|
|
82421
82927
|
};
|
|
82928
|
+
const onSubagentSpawn = (sessionId, toolInput) => {
|
|
82929
|
+
subagents.noteSpawn(sessionId, toolInput, Date.now());
|
|
82930
|
+
};
|
|
82931
|
+
const subagentContext = (a) => {
|
|
82932
|
+
const now = Date.now();
|
|
82933
|
+
const entry = a.start ? subagents.start(a, now) : subagents.get(a.agentId, now);
|
|
82934
|
+
if (!entry) return null;
|
|
82935
|
+
if (entry.share?.all) {
|
|
82936
|
+
const file2 = readContextFileWithHash(opts.workspaceRoot);
|
|
82937
|
+
return file2 ? { body: file2.body, hash: file2.hash, card: readContextCard(opts.workspaceRoot, file2.hash), handleNodes: [] } : null;
|
|
82938
|
+
}
|
|
82939
|
+
if (!subagentBase) {
|
|
82940
|
+
contextDirty = true;
|
|
82941
|
+
return null;
|
|
82942
|
+
}
|
|
82943
|
+
const key = JSON.stringify([subagentBaseVersion, lastRemoteAt, entry.intent, entry.workingFile, entry.share]);
|
|
82944
|
+
const cached2 = subagentRenders.get(a.agentId);
|
|
82945
|
+
if (cached2?.key === key) return cached2.block;
|
|
82946
|
+
const elicit = isEdgeElicitationEnabled();
|
|
82947
|
+
const handlesPath = join35(paths.configDir, "priming-handles.json");
|
|
82948
|
+
const atCommit = readGitRefState(join35(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
82949
|
+
const block = renderSubagentBlock({
|
|
82950
|
+
store,
|
|
82951
|
+
entry,
|
|
82952
|
+
base: subagentBase,
|
|
82953
|
+
profile,
|
|
82954
|
+
...atCommit ? { atCommit } : {},
|
|
82955
|
+
reviewUiUrl: opts.reviewUrl(),
|
|
82956
|
+
remote: remotePriors,
|
|
82957
|
+
handleMap: readPrimingHandles(handlesPath),
|
|
82958
|
+
...elicit ? { edgeElicitation: { instruction: PRIOR_TAG_INSTRUCTION } } : {}
|
|
82959
|
+
});
|
|
82960
|
+
if (elicit && block.handleNodes.length) writePrimingHandles(handlesPath, block.handleNodes);
|
|
82961
|
+
subagentRenders.delete(a.agentId);
|
|
82962
|
+
subagentRenders.set(a.agentId, { key, block });
|
|
82963
|
+
if (subagentRenders.size > 200) subagentRenders.delete(subagentRenders.keys().next().value);
|
|
82964
|
+
return block;
|
|
82965
|
+
};
|
|
82966
|
+
const onSubagentStop = (agentId) => {
|
|
82967
|
+
subagents.stop(agentId);
|
|
82968
|
+
subagentRenders.delete(agentId);
|
|
82969
|
+
};
|
|
82970
|
+
const noteSession = (e) => {
|
|
82971
|
+
const now = Date.now();
|
|
82972
|
+
if (!e.sessionId) return;
|
|
82973
|
+
const origin = e.origin ? { origin: e.origin } : {};
|
|
82974
|
+
if (e.agentId) {
|
|
82975
|
+
const sub = `agent-${e.agentId}`;
|
|
82976
|
+
if (e.ended) sessions.end(sub);
|
|
82977
|
+
else sessions.touch(sub, now, { parent: e.sessionId, ...origin });
|
|
82978
|
+
sessions.touch(e.sessionId, now, origin);
|
|
82979
|
+
return;
|
|
82980
|
+
}
|
|
82981
|
+
if (e.ended) sessions.end(e.sessionId);
|
|
82982
|
+
else sessions.touch(e.sessionId, now, origin);
|
|
82983
|
+
};
|
|
82984
|
+
const sessionContext = (sessionId) => {
|
|
82985
|
+
if (!sessionId || !subagentBase) return null;
|
|
82986
|
+
const now = Date.now();
|
|
82987
|
+
const intent = intents.get(sessionId, now);
|
|
82988
|
+
const workingFile = workingFiles.get(sessionId);
|
|
82989
|
+
const skips = selfCiteSkipsBySession.get(sessionId) ?? 0;
|
|
82990
|
+
const key = JSON.stringify([
|
|
82991
|
+
subagentBaseVersion,
|
|
82992
|
+
lastRemoteAt,
|
|
82993
|
+
sessions.version(now),
|
|
82994
|
+
intent,
|
|
82995
|
+
workingFile,
|
|
82996
|
+
intentRemote?.forIntent === intent ? intentRemote?.hits.length : -1,
|
|
82997
|
+
skips
|
|
82998
|
+
]);
|
|
82999
|
+
const cached2 = sessionRenders.get(sessionId);
|
|
83000
|
+
if (cached2?.key === key) return cached2.block;
|
|
83001
|
+
const elicit = isEdgeElicitationEnabled();
|
|
83002
|
+
const atCommit = readGitRefState(join35(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
83003
|
+
const scoped = scopeSnapshot(structuredClone(subagentBase), (n) => !hiddenFrom(n, sessionId, sessions, now));
|
|
83004
|
+
delete scoped.workingFile;
|
|
83005
|
+
if (workingFile) {
|
|
83006
|
+
const slice = sliceForFile(store, workingFile, atCommit);
|
|
83007
|
+
if (slice) scoped.workingFile = slice;
|
|
83008
|
+
}
|
|
83009
|
+
delete scoped.selfCiteSkips;
|
|
83010
|
+
if (skips > 0) scoped.selfCiteSkips = skips;
|
|
83011
|
+
const pendingUpdate = opts.pendingUpdate?.() ?? null;
|
|
83012
|
+
const daemonDistress = opts.daemonDistress?.() ?? null;
|
|
83013
|
+
const reviewItems = pickReviewItems();
|
|
83014
|
+
const { body: body2, snapshot } = assembleAgentContext({
|
|
83015
|
+
store,
|
|
83016
|
+
profile,
|
|
83017
|
+
...atCommit ? { atCommit } : {},
|
|
83018
|
+
reviewCount: pendingCount(paths),
|
|
83019
|
+
reviewUiUrl: opts.reviewUrl(),
|
|
83020
|
+
remote: remotePriors,
|
|
83021
|
+
snapshot: scoped,
|
|
83022
|
+
...elicit ? { edgeElicitation: { instruction: PRIOR_TAG_INSTRUCTION } } : {},
|
|
83023
|
+
...pendingUpdate ? { pendingUpdate } : {},
|
|
83024
|
+
...daemonDistress ? { daemonDistress } : {},
|
|
83025
|
+
...reviewItems.length ? { reviewItems } : {},
|
|
83026
|
+
...intent ? { statedIntent: statedIntentFor(intent) } : {}
|
|
83027
|
+
});
|
|
83028
|
+
const block = {
|
|
83029
|
+
body: body2,
|
|
83030
|
+
hash: contextHash(body2),
|
|
83031
|
+
card: contextCard(store, snapshot),
|
|
83032
|
+
handleNodes: [
|
|
83033
|
+
...snapshot.recentProblems.map((r) => r.node),
|
|
83034
|
+
...snapshot.recentResolved.flatMap((r) => r.solution ? [r.node, r.solution] : [r.node]),
|
|
83035
|
+
...snapshot.motifs,
|
|
83036
|
+
...snapshot.remote ?? []
|
|
83037
|
+
]
|
|
83038
|
+
};
|
|
83039
|
+
if (elicit && block.handleNodes.length) {
|
|
83040
|
+
writePrimingHandles(join35(paths.configDir, "priming-handles.json"), block.handleNodes);
|
|
83041
|
+
}
|
|
83042
|
+
sessionRenders.delete(sessionId);
|
|
83043
|
+
sessionRenders.set(sessionId, { key, block });
|
|
83044
|
+
if (sessionRenders.size > 200) sessionRenders.delete(sessionRenders.keys().next().value);
|
|
83045
|
+
return block;
|
|
83046
|
+
};
|
|
82422
83047
|
const onHookEvent = (e) => {
|
|
82423
83048
|
const intentHints = deriveIntentHints(e.tool, e.oldString, e.newString);
|
|
82424
83049
|
const operation = /(?:edit|write|patch)/i.test(e.tool) ? "write" : /read/i.test(e.tool) ? "read" : null;
|
|
@@ -82668,8 +83293,10 @@ function createWorkspaceEngine(opts) {
|
|
|
82668
83293
|
}
|
|
82669
83294
|
const touched = new Set(toolRuns.get(sessionId));
|
|
82670
83295
|
if (touchedFileId) touched.add(touchedFileId);
|
|
83296
|
+
const fenceAgent = turn.agentId ?? (sessionId.startsWith("agent-") ? sessionId.slice(6) : void 0);
|
|
82671
83297
|
for (const fence of parseIntentFences(turn.text)) {
|
|
82672
|
-
if (
|
|
83298
|
+
if (fenceAgent) subagents.setIntent(fenceAgent, fence.intent, t);
|
|
83299
|
+
else if (intents.set(sessionId, fence.intent, t)) refreshContextNow();
|
|
82673
83300
|
}
|
|
82674
83301
|
const plan = harvestInlineTags(store, turn.text, {
|
|
82675
83302
|
sourceId: sessionLastProblem.get(sessionId),
|
|
@@ -82736,7 +83363,7 @@ function createWorkspaceEngine(opts) {
|
|
|
82736
83363
|
let anchorReadFailed = false;
|
|
82737
83364
|
if (p.location) {
|
|
82738
83365
|
try {
|
|
82739
|
-
fileText =
|
|
83366
|
+
fileText = readFileSync32(join35(opts.workspaceRoot, p.location.path), "utf8");
|
|
82740
83367
|
} catch {
|
|
82741
83368
|
anchorReadFailed = true;
|
|
82742
83369
|
}
|
|
@@ -82896,7 +83523,7 @@ function createWorkspaceEngine(opts) {
|
|
|
82896
83523
|
const headSha = readGitRefState(join35(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
82897
83524
|
enclosing = {
|
|
82898
83525
|
line: p.location.line,
|
|
82899
|
-
fileText:
|
|
83526
|
+
fileText: readFileSync32(join35(opts.workspaceRoot, anchorPath), "utf8"),
|
|
82900
83527
|
...headSha ? { headSha } : {}
|
|
82901
83528
|
};
|
|
82902
83529
|
} catch {
|
|
@@ -83157,6 +83784,12 @@ function createWorkspaceEngine(opts) {
|
|
|
83157
83784
|
}
|
|
83158
83785
|
const citingSession = sessionOriginKey(sessionId);
|
|
83159
83786
|
const mintedHere = (nodeId) => store.getNode(nodeId)?.attrs["sources"]?.[0] === sessionId;
|
|
83787
|
+
const synthetic = sessions.originOf(sessionId) !== void 0;
|
|
83788
|
+
if (synthetic && plan.corroborations.length + plan.refutes.length > 0) {
|
|
83789
|
+
console.log(
|
|
83790
|
+
`[errata] witnesses: ${plan.corroborations.length + plan.refutes.length} withheld (session ${sessionId.slice(0, 8)} is ${sessions.originOf(sessionId)})`
|
|
83791
|
+
);
|
|
83792
|
+
}
|
|
83160
83793
|
const sendWitnesses = async (channel, fresh, send) => {
|
|
83161
83794
|
const isShipped = (nodeId) => {
|
|
83162
83795
|
const n = store.getNode(nodeId);
|
|
@@ -83281,7 +83914,7 @@ function createWorkspaceEngine(opts) {
|
|
|
83281
83914
|
if (typeof cloud.reportContradictions === "function") {
|
|
83282
83915
|
await sendWitnesses(
|
|
83283
83916
|
"contradict",
|
|
83284
|
-
wireWitnessItems(plan.refutes),
|
|
83917
|
+
synthetic ? [] : wireWitnessItems(plan.refutes),
|
|
83285
83918
|
(items2, session) => cloud.reportContradictions({
|
|
83286
83919
|
daemonVersion: DAEMON_VERSION,
|
|
83287
83920
|
projectId: profile.id,
|
|
@@ -83291,12 +83924,13 @@ function createWorkspaceEngine(opts) {
|
|
|
83291
83924
|
);
|
|
83292
83925
|
}
|
|
83293
83926
|
if (typeof cloud.reportCorroborations === "function") {
|
|
83294
|
-
const emit = plan.corroborations.filter((c) => !mintedHere(c.nodeId));
|
|
83927
|
+
const emit = synthetic ? [] : plan.corroborations.filter((c) => !mintedHere(c.nodeId));
|
|
83295
83928
|
const skipped = plan.corroborations.length - emit.length;
|
|
83296
83929
|
if (skipped > 0) {
|
|
83297
83930
|
console.log(`[errata] corroborate: ${skipped} skipped (this session authored the node)`);
|
|
83298
83931
|
appendWitnessLedger(paths.configDir, { ts: Date.now(), channel: "corroborate", clientSelfSkipped: skipped });
|
|
83299
83932
|
lastSelfCiteSkips = skipped;
|
|
83933
|
+
selfCiteSkipsBySession.set(sessionId, skipped);
|
|
83300
83934
|
refreshContextNow();
|
|
83301
83935
|
}
|
|
83302
83936
|
await sendWitnesses(
|
|
@@ -83478,7 +84112,7 @@ function createWorkspaceEngine(opts) {
|
|
|
83478
84112
|
}
|
|
83479
84113
|
turns = next.turns;
|
|
83480
84114
|
nextOffset = next.nextOffset;
|
|
83481
|
-
await new Promise((
|
|
84115
|
+
await new Promise((resolve9) => setImmediate(resolve9));
|
|
83482
84116
|
}
|
|
83483
84117
|
};
|
|
83484
84118
|
const seenMessageIds = /* @__PURE__ */ new Set();
|
|
@@ -83493,7 +84127,7 @@ function createWorkspaceEngine(opts) {
|
|
|
83493
84127
|
}
|
|
83494
84128
|
}
|
|
83495
84129
|
}
|
|
83496
|
-
setImmediate(() => void harvestTexts(e.sessionId, [{ text: e.text }]));
|
|
84130
|
+
setImmediate(() => void harvestTexts(e.sessionId, [{ text: e.text, ...e.agentId ? { agentId: e.agentId } : {} }]));
|
|
83497
84131
|
};
|
|
83498
84132
|
const harvestInFlight = /* @__PURE__ */ new Map();
|
|
83499
84133
|
const repairedSessions = /* @__PURE__ */ new Set();
|
|
@@ -83732,6 +84366,11 @@ B: ${b}`,
|
|
|
83732
84366
|
telemetry,
|
|
83733
84367
|
webHooks: {
|
|
83734
84368
|
onWorkingFileChanged,
|
|
84369
|
+
onSubagentSpawn,
|
|
84370
|
+
subagentContext,
|
|
84371
|
+
onSubagentStop,
|
|
84372
|
+
noteSession,
|
|
84373
|
+
sessionContext,
|
|
83735
84374
|
onHook: () => telemetry.count("hooks_fired"),
|
|
83736
84375
|
onToolsObserved: (sessionId, toolNodeIds) => toolRuns.record(sessionId, toolNodeIds),
|
|
83737
84376
|
onHookEvent,
|
|
@@ -83749,6 +84388,7 @@ B: ${b}`,
|
|
|
83749
84388
|
lastActivityAt() {
|
|
83750
84389
|
return lastActivityTs;
|
|
83751
84390
|
},
|
|
84391
|
+
quarantinedSessions: () => sessions.originSessions(),
|
|
83752
84392
|
markContextDirty() {
|
|
83753
84393
|
contextDirty = true;
|
|
83754
84394
|
refreshContextNow();
|
|
@@ -84013,15 +84653,19 @@ B: ${b}`,
|
|
|
84013
84653
|
console.log(
|
|
84014
84654
|
"[errata] sync skipped \u2014 cloud sync consent is off (enable with `errata consent sync on`)"
|
|
84015
84655
|
);
|
|
84016
|
-
const pending =
|
|
84656
|
+
const pending = existsSync28(paths.outbox) ? readdirSync10(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
|
|
84017
84657
|
return { uploaded: 0, failed: 0, remaining: pending };
|
|
84018
84658
|
}
|
|
84659
|
+
if (!shipsFromWorkspace(opts.workspaceRoot)) {
|
|
84660
|
+
console.log("[errata] sync skipped \u2014 scratch workspace (under the OS temp dir); its captures stay local");
|
|
84661
|
+
return { uploaded: 0, failed: 0, remaining: 0 };
|
|
84662
|
+
}
|
|
84019
84663
|
const onDisk = loadProfile(opts.workspaceRoot);
|
|
84020
84664
|
if (!onDisk?.projectId && onDisk?.projectLinkHold) {
|
|
84021
84665
|
console.log(
|
|
84022
84666
|
"[errata] sync held \u2014 this repo is already on errata in another workspace; run `errata link` to join it or create your own project"
|
|
84023
84667
|
);
|
|
84024
|
-
const pending =
|
|
84668
|
+
const pending = existsSync28(paths.outbox) ? readdirSync10(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
|
|
84025
84669
|
return { uploaded: 0, failed: 0, remaining: pending };
|
|
84026
84670
|
}
|
|
84027
84671
|
try {
|
|
@@ -84115,7 +84759,7 @@ async function startDaemon(opts) {
|
|
|
84115
84759
|
reviewUrl: () => webUiUrl + "/review"
|
|
84116
84760
|
});
|
|
84117
84761
|
const writeLockFile = (url2) => {
|
|
84118
|
-
|
|
84762
|
+
writeFileSync24(
|
|
84119
84763
|
engine.paths.daemonLock,
|
|
84120
84764
|
daemonLockPayload({ pid: process.pid, webUiUrl: url2, processStartedAt, version: DAEMON_VERSION }),
|
|
84121
84765
|
"utf8"
|
|
@@ -84129,6 +84773,11 @@ async function startDaemon(opts) {
|
|
|
84129
84773
|
profile: engine.profile,
|
|
84130
84774
|
daemonVersion: DAEMON_VERSION,
|
|
84131
84775
|
onWorkingFileChanged: engine.webHooks.onWorkingFileChanged,
|
|
84776
|
+
onSubagentSpawn: engine.webHooks.onSubagentSpawn,
|
|
84777
|
+
subagentContext: engine.webHooks.subagentContext,
|
|
84778
|
+
onSubagentStop: engine.webHooks.onSubagentStop,
|
|
84779
|
+
noteSession: engine.webHooks.noteSession,
|
|
84780
|
+
sessionContext: engine.webHooks.sessionContext,
|
|
84132
84781
|
onHook: engine.webHooks.onHook,
|
|
84133
84782
|
onHookEvent: engine.webHooks.onHookEvent,
|
|
84134
84783
|
onShellEvent: engine.webHooks.onShellEvent,
|
|
@@ -84158,7 +84807,7 @@ async function startDaemon(opts) {
|
|
|
84158
84807
|
);
|
|
84159
84808
|
await engine.stop();
|
|
84160
84809
|
try {
|
|
84161
|
-
if (
|
|
84810
|
+
if (existsSync29(engine.paths.daemonLock)) {
|
|
84162
84811
|
}
|
|
84163
84812
|
} catch {
|
|
84164
84813
|
}
|
|
@@ -84166,9 +84815,9 @@ async function startDaemon(opts) {
|
|
|
84166
84815
|
};
|
|
84167
84816
|
}
|
|
84168
84817
|
async function listenServer(fetchFn, port) {
|
|
84169
|
-
return new Promise((
|
|
84818
|
+
return new Promise((resolve9) => {
|
|
84170
84819
|
const server = serve({ fetch: fetchFn, hostname: "127.0.0.1", port }, (info2) => {
|
|
84171
|
-
|
|
84820
|
+
resolve9({ server, port: info2.port });
|
|
84172
84821
|
});
|
|
84173
84822
|
});
|
|
84174
84823
|
}
|
|
@@ -84359,7 +85008,7 @@ function instanceReceiptSequence(n) {
|
|
|
84359
85008
|
// src/multi.ts
|
|
84360
85009
|
init_dist();
|
|
84361
85010
|
init_src5();
|
|
84362
|
-
import { existsSync as
|
|
85011
|
+
import { existsSync as existsSync34, readFileSync as readFileSync36, unlinkSync as unlinkSync5, writeFileSync as writeFileSync26 } from "node:fs";
|
|
84363
85012
|
import { resolve as pathResolve } from "node:path";
|
|
84364
85013
|
|
|
84365
85014
|
// src/principle-sync.ts
|
|
@@ -84388,7 +85037,7 @@ init_reconcile();
|
|
|
84388
85037
|
|
|
84389
85038
|
// src/lockfile-auto.ts
|
|
84390
85039
|
init_src();
|
|
84391
|
-
import { existsSync as
|
|
85040
|
+
import { existsSync as existsSync30, readFileSync as readFileSync33 } from "node:fs";
|
|
84392
85041
|
import { join as join36 } from "node:path";
|
|
84393
85042
|
|
|
84394
85043
|
// src/package-index.ts
|
|
@@ -84539,10 +85188,10 @@ function runLockfilePass(opts) {
|
|
|
84539
85188
|
];
|
|
84540
85189
|
for (const c of candidates) {
|
|
84541
85190
|
const p = join36(opts.root, c.file);
|
|
84542
|
-
if (!
|
|
85191
|
+
if (!existsSync30(p)) continue;
|
|
84543
85192
|
let sbom;
|
|
84544
85193
|
try {
|
|
84545
|
-
sbom = c.parse(
|
|
85194
|
+
sbom = c.parse(readFileSync33(p, "utf8"));
|
|
84546
85195
|
} catch {
|
|
84547
85196
|
continue;
|
|
84548
85197
|
}
|
|
@@ -84600,9 +85249,10 @@ function noveltyAgainst(node2, neighbors, opts = {}) {
|
|
|
84600
85249
|
|
|
84601
85250
|
// src/instance-ingest.ts
|
|
84602
85251
|
init_profile2();
|
|
85252
|
+
init_session_registry();
|
|
84603
85253
|
|
|
84604
85254
|
// src/public-symbols.ts
|
|
84605
|
-
import { readFileSync as
|
|
85255
|
+
import { readFileSync as readFileSync34, readdirSync as readdirSync11, existsSync as existsSync31 } from "node:fs";
|
|
84606
85256
|
import { join as join37 } from "node:path";
|
|
84607
85257
|
var HEAD_BYTES = 8 * 1024;
|
|
84608
85258
|
var INDEX_TTL_MS = 10 * 60 * 1e3;
|
|
@@ -84637,9 +85287,9 @@ function internalPackageNames(workspaceRoot) {
|
|
|
84637
85287
|
const names = /* @__PURE__ */ new Set();
|
|
84638
85288
|
const tryRead = (dir) => {
|
|
84639
85289
|
const pj = join37(dir, "package.json");
|
|
84640
|
-
if (!
|
|
85290
|
+
if (!existsSync31(pj)) return;
|
|
84641
85291
|
try {
|
|
84642
|
-
const name2 = JSON.parse(
|
|
85292
|
+
const name2 = JSON.parse(readFileSync34(pj, "utf8")).name;
|
|
84643
85293
|
if (typeof name2 === "string" && name2.length > 0) names.add(name2);
|
|
84644
85294
|
} catch {
|
|
84645
85295
|
}
|
|
@@ -84647,7 +85297,7 @@ function internalPackageNames(workspaceRoot) {
|
|
|
84647
85297
|
tryRead(workspaceRoot);
|
|
84648
85298
|
for (const group of ["packages", "apps"]) {
|
|
84649
85299
|
const groupDir = join37(workspaceRoot, group);
|
|
84650
|
-
if (!
|
|
85300
|
+
if (!existsSync31(groupDir)) continue;
|
|
84651
85301
|
try {
|
|
84652
85302
|
for (const entry of readdirSync11(groupDir)) tryRead(join37(groupDir, entry));
|
|
84653
85303
|
} catch {
|
|
@@ -84668,7 +85318,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
|
|
|
84668
85318
|
}
|
|
84669
85319
|
const readHead = deps.readHead ?? ((absPath) => {
|
|
84670
85320
|
try {
|
|
84671
|
-
return
|
|
85321
|
+
return readFileSync34(absPath, "utf8").slice(0, HEAD_BYTES);
|
|
84672
85322
|
} catch {
|
|
84673
85323
|
return "";
|
|
84674
85324
|
}
|
|
@@ -84825,6 +85475,7 @@ function shareableContext(n, wireId) {
|
|
|
84825
85475
|
function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [], opts = {}) {
|
|
84826
85476
|
const level = opts.level ?? 1;
|
|
84827
85477
|
const noveltyOpts = opts.dedupCosine != null ? { dedupCosine: opts.dedupCosine } : {};
|
|
85478
|
+
const quarantine = opts.quarantinedSessions?.length ? new Set(opts.quarantinedSessions) : null;
|
|
84828
85479
|
const ignored = (text) => ignorePatterns.length > 0 && ignorePatterns.some((p) => text.toLowerCase().includes(p));
|
|
84829
85480
|
const originSessionOf = (n) => {
|
|
84830
85481
|
const key = sessionOriginKey(n.attrs["sources"]?.[0]);
|
|
@@ -84893,6 +85544,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
84893
85544
|
candidates: 0,
|
|
84894
85545
|
shipped: 0,
|
|
84895
85546
|
cloudSourced: 0,
|
|
85547
|
+
quarantined: 0,
|
|
84896
85548
|
falsePositive: 0,
|
|
84897
85549
|
ignored: 0,
|
|
84898
85550
|
watermarked: 0,
|
|
@@ -84943,6 +85595,10 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
84943
85595
|
composition.cloudSourced++;
|
|
84944
85596
|
continue;
|
|
84945
85597
|
}
|
|
85598
|
+
if (quarantine && capturedOnlyBy(n, quarantine)) {
|
|
85599
|
+
composition.quarantined++;
|
|
85600
|
+
continue;
|
|
85601
|
+
}
|
|
84946
85602
|
if (n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) {
|
|
84947
85603
|
composition.falsePositive++;
|
|
84948
85604
|
continue;
|
|
@@ -85350,7 +86006,8 @@ function buildDrainInstances(store, sharedStore, input) {
|
|
|
85350
86006
|
},
|
|
85351
86007
|
...lexicon ? { lexicon } : {},
|
|
85352
86008
|
...fileLexicon ? { fileLexicon } : {},
|
|
85353
|
-
...input.project ? { project: input.project } : {}
|
|
86009
|
+
...input.project ? { project: input.project } : {},
|
|
86010
|
+
...input.quarantinedSessions?.length ? { quarantinedSessions: input.quarantinedSessions } : {}
|
|
85354
86011
|
});
|
|
85355
86012
|
return {
|
|
85356
86013
|
batch,
|
|
@@ -85362,6 +86019,7 @@ function buildDrainInstances(store, sharedStore, input) {
|
|
|
85362
86019
|
// src/multi.ts
|
|
85363
86020
|
init_webui();
|
|
85364
86021
|
init_recall_card();
|
|
86022
|
+
init_session_registry();
|
|
85365
86023
|
|
|
85366
86024
|
// src/consolidate-worker-client.ts
|
|
85367
86025
|
import { Worker as Worker2 } from "node:worker_threads";
|
|
@@ -85381,8 +86039,8 @@ var ConsolidateWorker = class {
|
|
|
85381
86039
|
const id = this.nextId++;
|
|
85382
86040
|
try {
|
|
85383
86041
|
await this.ready;
|
|
85384
|
-
return await new Promise((
|
|
85385
|
-
this.pending.set(id, { resolve:
|
|
86042
|
+
return await new Promise((resolve9, reject) => {
|
|
86043
|
+
this.pending.set(id, { resolve: resolve9, reject });
|
|
85386
86044
|
this.worker.postMessage({ ...req, id });
|
|
85387
86045
|
});
|
|
85388
86046
|
} finally {
|
|
@@ -85411,12 +86069,12 @@ var ConsolidateWorker = class {
|
|
|
85411
86069
|
});
|
|
85412
86070
|
noteIsolateSpawned();
|
|
85413
86071
|
this.worker = worker;
|
|
85414
|
-
this.ready = new Promise((
|
|
86072
|
+
this.ready = new Promise((resolve9, reject) => {
|
|
85415
86073
|
const onReady = (m) => {
|
|
85416
86074
|
if (m?.ready) {
|
|
85417
86075
|
worker.off("message", onReady);
|
|
85418
86076
|
worker.off("error", onErr);
|
|
85419
|
-
|
|
86077
|
+
resolve9();
|
|
85420
86078
|
}
|
|
85421
86079
|
};
|
|
85422
86080
|
const onErr = (err2) => {
|
|
@@ -85621,17 +86279,17 @@ function startUpdatePoller(opts) {
|
|
|
85621
86279
|
};
|
|
85622
86280
|
}
|
|
85623
86281
|
function runNpmInstall(channel) {
|
|
85624
|
-
return new Promise((
|
|
86282
|
+
return new Promise((resolve9) => {
|
|
85625
86283
|
const child = spawn2("npm", ["install", "-g", `${PACKAGE_NAME}@${channel}`], {
|
|
85626
86284
|
stdio: "inherit",
|
|
85627
86285
|
shell: true
|
|
85628
86286
|
});
|
|
85629
|
-
child.on("close", (code) =>
|
|
85630
|
-
child.on("error", () =>
|
|
86287
|
+
child.on("close", (code) => resolve9(code ?? 1));
|
|
86288
|
+
child.on("error", () => resolve9(1));
|
|
85631
86289
|
});
|
|
85632
86290
|
}
|
|
85633
86291
|
async function runInstalledHookRefresh() {
|
|
85634
|
-
const root = await new Promise((
|
|
86292
|
+
const root = await new Promise((resolve9) => {
|
|
85635
86293
|
const child = spawn2("npm", ["root", "-g"], {
|
|
85636
86294
|
shell: true,
|
|
85637
86295
|
windowsHide: true,
|
|
@@ -85643,18 +86301,18 @@ async function runInstalledHookRefresh() {
|
|
|
85643
86301
|
output += chunk;
|
|
85644
86302
|
if (output.length > 32768) child.kill();
|
|
85645
86303
|
});
|
|
85646
|
-
child.on("error", () =>
|
|
85647
|
-
child.on("close", (code) =>
|
|
86304
|
+
child.on("error", () => resolve9(""));
|
|
86305
|
+
child.on("close", (code) => resolve9(code === 0 ? output.trim() : ""));
|
|
85648
86306
|
});
|
|
85649
86307
|
if (!isAbsolute5(root)) return 1;
|
|
85650
|
-
return new Promise((
|
|
86308
|
+
return new Promise((resolve9) => {
|
|
85651
86309
|
const child = spawn2(process.execPath, [join38(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
|
|
85652
86310
|
windowsHide: true,
|
|
85653
86311
|
stdio: "inherit",
|
|
85654
86312
|
timeout: 3e4
|
|
85655
86313
|
});
|
|
85656
|
-
child.on("error", () =>
|
|
85657
|
-
child.on("close", (code) =>
|
|
86314
|
+
child.on("error", () => resolve9(1));
|
|
86315
|
+
child.on("close", (code) => resolve9(code ?? 1));
|
|
85658
86316
|
});
|
|
85659
86317
|
}
|
|
85660
86318
|
|
|
@@ -85669,7 +86327,7 @@ function liveCloudClient(src) {
|
|
|
85669
86327
|
let current = null;
|
|
85670
86328
|
let currentKey = "";
|
|
85671
86329
|
let checkedAt = -Infinity;
|
|
85672
|
-
const
|
|
86330
|
+
const resolve9 = () => {
|
|
85673
86331
|
const t = now();
|
|
85674
86332
|
if (current && t - checkedAt < recheckMs) return current;
|
|
85675
86333
|
checkedAt = t;
|
|
@@ -85689,7 +86347,7 @@ function liveCloudClient(src) {
|
|
|
85689
86347
|
};
|
|
85690
86348
|
return new Proxy({}, {
|
|
85691
86349
|
get(_target, prop) {
|
|
85692
|
-
const client =
|
|
86350
|
+
const client = resolve9();
|
|
85693
86351
|
const value = Reflect.get(client, prop, client);
|
|
85694
86352
|
return typeof value === "function" ? value.bind(client) : value;
|
|
85695
86353
|
}
|
|
@@ -86127,7 +86785,7 @@ async function syncHistoryRevision(opts) {
|
|
|
86127
86785
|
changed += result.changed;
|
|
86128
86786
|
remaining = result.remaining;
|
|
86129
86787
|
if (!remaining || Date.now() - started2 >= (opts.budgetMs ?? 45e3)) break;
|
|
86130
|
-
await new Promise((
|
|
86788
|
+
await new Promise((resolve9) => setImmediate(resolve9));
|
|
86131
86789
|
}
|
|
86132
86790
|
return { changed, remaining };
|
|
86133
86791
|
})();
|
|
@@ -86230,7 +86888,7 @@ async function syncHistoryRevisionPage(opts) {
|
|
|
86230
86888
|
init_src7();
|
|
86231
86889
|
init_src();
|
|
86232
86890
|
import { execFile as execFile5 } from "node:child_process";
|
|
86233
|
-
import { readFileSync as
|
|
86891
|
+
import { readFileSync as readFileSync35 } from "node:fs";
|
|
86234
86892
|
import { join as join39 } from "node:path";
|
|
86235
86893
|
import { promisify as promisify3 } from "node:util";
|
|
86236
86894
|
|
|
@@ -86631,8 +87289,8 @@ var GitBlobReader = class {
|
|
|
86631
87289
|
if (this.failed) return Promise.reject(this.failed);
|
|
86632
87290
|
if (/[\r\n]/.test(spec)) return Promise.resolve(null);
|
|
86633
87291
|
const proc = this.start();
|
|
86634
|
-
return new Promise((
|
|
86635
|
-
this.queue.push({ resolve:
|
|
87292
|
+
return new Promise((resolve9, reject) => {
|
|
87293
|
+
this.queue.push({ resolve: resolve9, reject });
|
|
86636
87294
|
proc.stdin.write(`${spec}
|
|
86637
87295
|
`);
|
|
86638
87296
|
});
|
|
@@ -86646,14 +87304,14 @@ var GitBlobReader = class {
|
|
|
86646
87304
|
const proc = this.proc;
|
|
86647
87305
|
this.proc = null;
|
|
86648
87306
|
if (!proc || proc.exitCode !== null) return Promise.resolve();
|
|
86649
|
-
return new Promise((
|
|
87307
|
+
return new Promise((resolve9) => {
|
|
86650
87308
|
const timer = setTimeout(() => {
|
|
86651
87309
|
proc.kill();
|
|
86652
|
-
|
|
87310
|
+
resolve9();
|
|
86653
87311
|
}, timeoutMs);
|
|
86654
87312
|
proc.once("exit", () => {
|
|
86655
87313
|
clearTimeout(timer);
|
|
86656
|
-
|
|
87314
|
+
resolve9();
|
|
86657
87315
|
});
|
|
86658
87316
|
proc.stdin.end();
|
|
86659
87317
|
});
|
|
@@ -86778,7 +87436,7 @@ async function defaultGit(root, args2) {
|
|
|
86778
87436
|
function readIgnoreLines(root, profile) {
|
|
86779
87437
|
let lines = [];
|
|
86780
87438
|
try {
|
|
86781
|
-
lines =
|
|
87439
|
+
lines = readFileSync35(join39(root, ".errataignore"), "utf8").split("\n");
|
|
86782
87440
|
} catch {
|
|
86783
87441
|
}
|
|
86784
87442
|
return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
@@ -87243,7 +87901,7 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
|
|
|
87243
87901
|
init_cloud_auth();
|
|
87244
87902
|
import { createHash as createHash19 } from "node:crypto";
|
|
87245
87903
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
87246
|
-
import { existsSync as
|
|
87904
|
+
import { existsSync as existsSync32, writeFileSync as writeFileSync25 } from "node:fs";
|
|
87247
87905
|
import { join as join40 } from "node:path";
|
|
87248
87906
|
|
|
87249
87907
|
// src/device-poll.ts
|
|
@@ -87333,7 +87991,7 @@ async function loginOAuthDevice(opts) {
|
|
|
87333
87991
|
let deviceSession = null;
|
|
87334
87992
|
let approvedInstallation = null;
|
|
87335
87993
|
while (Date.now() < deadline) {
|
|
87336
|
-
await (opts.sleep ?? ((ms) => new Promise((
|
|
87994
|
+
await (opts.sleep ?? ((ms) => new Promise((resolve9) => setTimeout(resolve9, ms))))(waitMs);
|
|
87337
87995
|
waitMs = intervalMs;
|
|
87338
87996
|
const poll = await fetchDevicePoll(fetchFn, device.token, {
|
|
87339
87997
|
method: "POST",
|
|
@@ -87458,7 +88116,7 @@ async function loginOAuthLoopback(opts) {
|
|
|
87458
88116
|
const state = randomState();
|
|
87459
88117
|
const scope = opts.scope ?? DEFAULT_OAUTH_SCOPE;
|
|
87460
88118
|
const { code, redirectUri, clientId } = await new Promise(
|
|
87461
|
-
(
|
|
88119
|
+
(resolve9, reject) => {
|
|
87462
88120
|
const server = createServer((req, res) => {
|
|
87463
88121
|
const u = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
87464
88122
|
if (u.pathname !== "/callback") {
|
|
@@ -87481,7 +88139,7 @@ async function loginOAuthLoopback(opts) {
|
|
|
87481
88139
|
res.writeHead(200, { "content-type": "text/html" });
|
|
87482
88140
|
res.end("<html><body>inErrata: you're logged in. You can close this tab.</body></html>");
|
|
87483
88141
|
server.close();
|
|
87484
|
-
|
|
88142
|
+
resolve9({ code: code2, redirectUri: `http://127.0.0.1:${port}/callback`, clientId: activeClientId });
|
|
87485
88143
|
});
|
|
87486
88144
|
let activeClientId = oauthClientId();
|
|
87487
88145
|
server.on("error", reject);
|
|
@@ -87580,7 +88238,7 @@ async function linkThroughConsole(opts) {
|
|
|
87580
88238
|
const deadline = Date.now() + Math.min(code.expires_in * 1e3, opts.timeoutMs ?? Number.POSITIVE_INFINITY);
|
|
87581
88239
|
let intervalMs = Math.max(2, code.interval ?? 5) * 1e3;
|
|
87582
88240
|
let waitMs = intervalMs;
|
|
87583
|
-
const sleep = opts.sleep ?? ((ms) => new Promise((
|
|
88241
|
+
const sleep = opts.sleep ?? ((ms) => new Promise((resolve9) => setTimeout(resolve9, ms)));
|
|
87584
88242
|
while (Date.now() < deadline) {
|
|
87585
88243
|
await sleep(waitMs);
|
|
87586
88244
|
waitMs = intervalMs;
|
|
@@ -87703,8 +88361,8 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
|
|
|
87703
88361
|
let wroteIgnore = false;
|
|
87704
88362
|
if (decision.writeIgnoreStarter !== false) {
|
|
87705
88363
|
const target = join40(root, ".errataignore");
|
|
87706
|
-
if (!
|
|
87707
|
-
|
|
88364
|
+
if (!existsSync32(target)) {
|
|
88365
|
+
writeFileSync25(target, IGNORE_STARTER, "utf8");
|
|
87708
88366
|
wroteIgnore = true;
|
|
87709
88367
|
}
|
|
87710
88368
|
}
|
|
@@ -87717,12 +88375,12 @@ init_registry();
|
|
|
87717
88375
|
|
|
87718
88376
|
// src/adopt.ts
|
|
87719
88377
|
init_git_remote();
|
|
87720
|
-
import { existsSync as
|
|
88378
|
+
import { existsSync as existsSync33 } from "node:fs";
|
|
87721
88379
|
import { dirname as dirname12, join as join41 } from "node:path";
|
|
87722
88380
|
function findGitRoot(absPath) {
|
|
87723
88381
|
let dir = absPath;
|
|
87724
88382
|
for (let depth = 0; depth < 64; depth++) {
|
|
87725
|
-
if (
|
|
88383
|
+
if (existsSync33(join41(dir, ".git"))) return dir;
|
|
87726
88384
|
const parent = dirname12(dir);
|
|
87727
88385
|
if (parent === dir) return null;
|
|
87728
88386
|
dir = parent;
|
|
@@ -88348,6 +89006,13 @@ async function startMultiDaemon(opts = {}) {
|
|
|
88348
89006
|
daemonVersion: DAEMON_VERSION,
|
|
88349
89007
|
basePath: `/ws/${id}`,
|
|
88350
89008
|
onWorkingFileChanged: engine.webHooks.onWorkingFileChanged,
|
|
89009
|
+
// CAP-subagent-prime: each Task-tool subagent's own block.
|
|
89010
|
+
onSubagentSpawn: engine.webHooks.onSubagentSpawn,
|
|
89011
|
+
subagentContext: engine.webHooks.subagentContext,
|
|
89012
|
+
onSubagentStop: engine.webHooks.onSubagentStop,
|
|
89013
|
+
// CAP-session-scope: per-session blocks + harness/fixture quarantine.
|
|
89014
|
+
noteSession: engine.webHooks.noteSession,
|
|
89015
|
+
sessionContext: engine.webHooks.sessionContext,
|
|
88351
89016
|
onHook: engine.webHooks.onHook,
|
|
88352
89017
|
onHookEvent: engine.webHooks.onHookEvent,
|
|
88353
89018
|
onShellEvent: engine.webHooks.onShellEvent,
|
|
@@ -88415,7 +89080,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
88415
89080
|
records.push(rec);
|
|
88416
89081
|
void ambientLinkAll();
|
|
88417
89082
|
try {
|
|
88418
|
-
|
|
89083
|
+
writeFileSync26(
|
|
88419
89084
|
rec.engine.paths.daemonLock,
|
|
88420
89085
|
daemonLockPayload({
|
|
88421
89086
|
pid: process.pid,
|
|
@@ -88622,7 +89287,12 @@ async function startMultiDaemon(opts = {}) {
|
|
|
88622
89287
|
return await owner.webApp.fetch(
|
|
88623
89288
|
new Request(`http://local${sub}`, {
|
|
88624
89289
|
method: "POST",
|
|
88625
|
-
|
|
89290
|
+
// The origin header (harness/fixture quarantine, session-registry.ts)
|
|
89291
|
+
// is the one caller header the sub-app needs; nothing else crosses.
|
|
89292
|
+
headers: {
|
|
89293
|
+
"content-type": "application/json",
|
|
89294
|
+
...c.req.header(ORIGIN_HEADER) ? { [ORIGIN_HEADER]: c.req.header(ORIGIN_HEADER) } : {}
|
|
89295
|
+
},
|
|
88626
89296
|
body: raw2
|
|
88627
89297
|
})
|
|
88628
89298
|
);
|
|
@@ -88664,6 +89334,19 @@ async function startMultiDaemon(opts = {}) {
|
|
|
88664
89334
|
}
|
|
88665
89335
|
return c.text(statuslineText(String(body2["session_id"] ?? "")));
|
|
88666
89336
|
});
|
|
89337
|
+
app.post("/api/statusline/subagents", async (c) => {
|
|
89338
|
+
const body2 = await c.req.json().catch(() => ({}));
|
|
89339
|
+
const dir = statuslineDir(body2);
|
|
89340
|
+
if (dir !== null) {
|
|
89341
|
+
const d = normPath(dir);
|
|
89342
|
+
const known = listWorkspaceEntries().some((e) => {
|
|
89343
|
+
const root = normPath(e.path);
|
|
89344
|
+
return d === root || d.startsWith(`${root}/`);
|
|
89345
|
+
});
|
|
89346
|
+
if (!known) return c.text("");
|
|
89347
|
+
}
|
|
89348
|
+
return c.text(subagentRows(body2));
|
|
89349
|
+
});
|
|
88667
89350
|
for (const r of records) {
|
|
88668
89351
|
mountedIds.add(r.id);
|
|
88669
89352
|
app.route(`/ws/${r.id}`, r.webApp);
|
|
@@ -88701,7 +89384,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
88701
89384
|
lastActiveAt = Math.max(lastActiveAt, rec.engine.lastActivityAt());
|
|
88702
89385
|
} catch {
|
|
88703
89386
|
}
|
|
88704
|
-
const reason = retireDecision({ exists:
|
|
89387
|
+
const reason = retireDecision({ exists: existsSync34(rec.root), lastActiveAt, now });
|
|
88705
89388
|
if (reason) void retireWorkspace(rec, reason);
|
|
88706
89389
|
}
|
|
88707
89390
|
};
|
|
@@ -88772,7 +89455,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
88772
89455
|
baseUrl = `http://127.0.0.1:${port}`;
|
|
88773
89456
|
try {
|
|
88774
89457
|
ensureDir(globalDir());
|
|
88775
|
-
|
|
89458
|
+
writeFileSync26(
|
|
88776
89459
|
lockPath,
|
|
88777
89460
|
daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
|
|
88778
89461
|
"utf8"
|
|
@@ -88781,7 +89464,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
88781
89464
|
}
|
|
88782
89465
|
for (const r of records) {
|
|
88783
89466
|
try {
|
|
88784
|
-
|
|
89467
|
+
writeFileSync26(
|
|
88785
89468
|
r.engine.paths.daemonLock,
|
|
88786
89469
|
daemonLockPayload({
|
|
88787
89470
|
pid: process.pid,
|
|
@@ -89015,7 +89698,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
89015
89698
|
const packageAutoAll = async () => {
|
|
89016
89699
|
const out2 = /* @__PURE__ */ new Map();
|
|
89017
89700
|
for (const r of records) {
|
|
89018
|
-
await new Promise((
|
|
89701
|
+
await new Promise((resolve9) => setImmediate(resolve9));
|
|
89019
89702
|
const done = markPass(`package-index:${r.entry.name}`);
|
|
89020
89703
|
try {
|
|
89021
89704
|
out2.set(
|
|
@@ -89324,7 +90007,9 @@ async function startMultiDaemon(opts = {}) {
|
|
|
89324
90007
|
done();
|
|
89325
90008
|
}
|
|
89326
90009
|
};
|
|
89327
|
-
const buildInstanceBatch = async (r,
|
|
90010
|
+
const buildInstanceBatch = async (r, laneInput) => {
|
|
90011
|
+
const quarantinedSessions = r.engine.quarantinedSessions();
|
|
90012
|
+
const input = quarantinedSessions.length ? { ...laneInput, quarantinedSessions } : laneInput;
|
|
89328
90013
|
const w = workerFor(r);
|
|
89329
90014
|
if (w) {
|
|
89330
90015
|
try {
|
|
@@ -89359,6 +90044,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
89359
90044
|
for (const r of records) {
|
|
89360
90045
|
const recordConsent = effectiveConsent(cfg2, r.engine.profile);
|
|
89361
90046
|
if (!recordConsent.sync) continue;
|
|
90047
|
+
if (!shipsFromWorkspace(r.root)) continue;
|
|
89362
90048
|
const recordIdentity = identityFor(liveWorkspaceEntry(r.entry));
|
|
89363
90049
|
if (recordIdentity.invalid) {
|
|
89364
90050
|
noteIdentityBlock(r.id, r.entry.name, recordIdentity);
|
|
@@ -89753,7 +90439,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
89753
90439
|
clearInterval(anchorPull);
|
|
89754
90440
|
clearTimeout(codexWakeBoot);
|
|
89755
90441
|
try {
|
|
89756
|
-
const cur =
|
|
90442
|
+
const cur = readFileSync36(lockPath, "utf8");
|
|
89757
90443
|
if (JSON.parse(cur).pid === process.pid) unlinkSync5(lockPath);
|
|
89758
90444
|
} catch {
|
|
89759
90445
|
}
|
|
@@ -90314,23 +91000,25 @@ async function diagnoseInstallation(cfg, dependencies) {
|
|
|
90314
91000
|
|
|
90315
91001
|
// src/codex-doctor.ts
|
|
90316
91002
|
import { spawn as spawn4 } from "node:child_process";
|
|
90317
|
-
import { readFileSync as
|
|
91003
|
+
import { readFileSync as readFileSync38, statSync as statSync10 } from "node:fs";
|
|
90318
91004
|
import { join as join44 } from "node:path";
|
|
90319
91005
|
import { createInterface } from "node:readline";
|
|
90320
91006
|
|
|
90321
91007
|
// src/codex-hooks.ts
|
|
90322
|
-
import { existsSync as
|
|
91008
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync37, renameSync as renameSync5, unlinkSync as unlinkSync6, writeFileSync as writeFileSync27 } from "node:fs";
|
|
90323
91009
|
import { homedir as homedir7 } from "node:os";
|
|
90324
91010
|
import { join as join43 } from "node:path";
|
|
90325
91011
|
|
|
90326
91012
|
// src/hook-commands.ts
|
|
90327
91013
|
function hookCurlCommand(port, path2 = "/api/hook") {
|
|
90328
91014
|
const url2 = `http://127.0.0.1:${port}${path2}`;
|
|
90329
|
-
return process.platform === "win32" ? `cmd //c "curl -s --connect-timeout 1 --max-time 3 -X POST
|
|
91015
|
+
return process.platform === "win32" ? `cmd //c "curl -s --connect-timeout 1 --max-time 3 -X POST ${HEADERS_WIN} --data-binary @- ${url2} >NUL 2>NUL || exit /b 0"` : `curl -s --connect-timeout 1 --max-time 3 -X POST -H 'Content-Type: application/json' ${ORIGIN_HEADER_POSIX} --data-binary @- ${url2} >/dev/null 2>&1 || true`;
|
|
90330
91016
|
}
|
|
91017
|
+
var HEADERS_WIN = `-H Content-Type:application/json -H x-errata-origin:%ERRATA_ORIGIN%`;
|
|
91018
|
+
var ORIGIN_HEADER_POSIX = `-H "x-errata-origin: \${ERRATA_ORIGIN:-}"`;
|
|
90331
91019
|
function hookRelayCommand(port, path2) {
|
|
90332
91020
|
const url2 = `http://127.0.0.1:${port}${path2}`;
|
|
90333
|
-
return process.platform === "win32" ? `cmd //c "curl -s --connect-timeout 1 --max-time 2 -X POST
|
|
91021
|
+
return process.platform === "win32" ? `cmd //c "curl -s --connect-timeout 1 --max-time 2 -X POST ${HEADERS_WIN} --data-binary @- ${url2} 2>NUL || echo {}"` : `curl -s --connect-timeout 1 --max-time 2 -X POST -H 'Content-Type: application/json' ${ORIGIN_HEADER_POSIX} --data-binary @- ${url2} 2>/dev/null || echo '{}'`;
|
|
90334
91022
|
}
|
|
90335
91023
|
var CODEX_HOOKS_BEGIN = `# >>> errata hooks (errata-managed)`;
|
|
90336
91024
|
var CODEX_HOOKS_END = `# <<< errata hooks`;
|
|
@@ -90467,23 +91155,23 @@ function buildCodexRelaySource(workspaceRoot) {
|
|
|
90467
91155
|
init_checkout_root();
|
|
90468
91156
|
var CODEX_HOOK_REVIEW_HELP = "Codex desktop: Settings > Hooks, select this project, expand each event and Trust the Errata hook. CLI users can use /hooks.";
|
|
90469
91157
|
function writeRelay(file2, source) {
|
|
90470
|
-
if (
|
|
91158
|
+
if (existsSync35(file2) && readFileSync37(file2, "utf8") === source) return;
|
|
90471
91159
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
90472
91160
|
try {
|
|
90473
|
-
|
|
91161
|
+
writeFileSync27(temp, source, { encoding: "utf8", mode: 384 });
|
|
90474
91162
|
renameSync5(temp, file2);
|
|
90475
91163
|
} finally {
|
|
90476
|
-
if (
|
|
91164
|
+
if (existsSync35(temp)) unlinkSync6(temp);
|
|
90477
91165
|
}
|
|
90478
91166
|
}
|
|
90479
91167
|
function refreshCodexRelay(root) {
|
|
90480
91168
|
const config2 = join43(root, ".codex", "config.toml");
|
|
90481
|
-
if (!
|
|
90482
|
-
const existing =
|
|
91169
|
+
if (!existsSync35(config2)) return "absent";
|
|
91170
|
+
const existing = readFileSync37(config2, "utf8");
|
|
90483
91171
|
if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
|
|
90484
91172
|
replaceCodexHooks(existing, "");
|
|
90485
91173
|
const relay = join43(root, ".codex", "hooks", "errata-relay.mjs");
|
|
90486
|
-
const prior =
|
|
91174
|
+
const prior = existsSync35(relay) ? readFileSync37(relay, "utf8") : "";
|
|
90487
91175
|
if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
|
|
90488
91176
|
throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
|
|
90489
91177
|
}
|
|
@@ -90494,7 +91182,7 @@ function refreshCodexRelay(root) {
|
|
|
90494
91182
|
return "updated";
|
|
90495
91183
|
}
|
|
90496
91184
|
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join43(homedir7(), ".codex")) {
|
|
90497
|
-
return
|
|
91185
|
+
return existsSync35(join43(root, ".codex")) || existsSync35(codexHome);
|
|
90498
91186
|
}
|
|
90499
91187
|
function replaceCodexHooks(existing, block) {
|
|
90500
91188
|
const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
|
|
@@ -90514,10 +91202,10 @@ function writeCodexHooks(root, port, nodePath = process.execPath) {
|
|
|
90514
91202
|
const file2 = join43(dir, "config.toml");
|
|
90515
91203
|
const relay = join43(dir, "hooks", "errata-relay.mjs");
|
|
90516
91204
|
const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
|
|
90517
|
-
const final = replaceCodexHooks(
|
|
91205
|
+
const final = replaceCodexHooks(existsSync35(file2) ? readFileSync37(file2, "utf8") : "", block);
|
|
90518
91206
|
mkdirSync9(join43(dir, "hooks"), { recursive: true });
|
|
90519
91207
|
writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
|
|
90520
|
-
if (!
|
|
91208
|
+
if (!existsSync35(file2) || readFileSync37(file2, "utf8") !== final) writeFileSync27(file2, final, "utf8");
|
|
90521
91209
|
return file2;
|
|
90522
91210
|
}
|
|
90523
91211
|
|
|
@@ -90526,7 +91214,7 @@ init_checkout_root();
|
|
|
90526
91214
|
function inspectCodexRelay(cwd) {
|
|
90527
91215
|
const root = nearestGitRoot(cwd) ?? cwd;
|
|
90528
91216
|
try {
|
|
90529
|
-
const source =
|
|
91217
|
+
const source = readFileSync38(join44(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
|
|
90530
91218
|
if (source === buildCodexRelaySource(checkoutRootOf(root))) {
|
|
90531
91219
|
return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
|
|
90532
91220
|
}
|
|
@@ -90538,7 +91226,7 @@ function inspectCodexContext(cwd) {
|
|
|
90538
91226
|
const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
|
|
90539
91227
|
try {
|
|
90540
91228
|
const file2 = join44(root, ".errata", "context.md");
|
|
90541
|
-
if (statSync10(file2).size <= 128 * 1024 &&
|
|
91229
|
+
if (statSync10(file2).size <= 128 * 1024 && readFileSync38(file2, "utf8").trim()) {
|
|
90542
91230
|
return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
|
|
90543
91231
|
}
|
|
90544
91232
|
} catch {
|
|
@@ -90546,7 +91234,7 @@ function inspectCodexContext(cwd) {
|
|
|
90546
91234
|
return { id: "codex_context", status: "fail", detail: "No usable saved workspace context; run errata start here and check the daemon log if context.md remains unavailable" };
|
|
90547
91235
|
}
|
|
90548
91236
|
function readCodexHookState(cwd, options = {}) {
|
|
90549
|
-
return new Promise((
|
|
91237
|
+
return new Promise((resolve9, reject) => {
|
|
90550
91238
|
const child = spawn4(options.bin ?? resolveCodexExecutable(), options.args ?? ["app-server", "--stdio"], {
|
|
90551
91239
|
cwd,
|
|
90552
91240
|
windowsHide: true,
|
|
@@ -90567,7 +91255,7 @@ function readCodexHookState(cwd, options = {}) {
|
|
|
90567
91255
|
child.once("close", () => {
|
|
90568
91256
|
clearTimeout(reap);
|
|
90569
91257
|
if (error48) reject(error48);
|
|
90570
|
-
else
|
|
91258
|
+
else resolve9({ ...hooks, features });
|
|
90571
91259
|
});
|
|
90572
91260
|
child.kill();
|
|
90573
91261
|
};
|
|
@@ -90714,16 +91402,16 @@ function consolidationGapMs(lastPassMs, policy) {
|
|
|
90714
91402
|
|
|
90715
91403
|
// src/codex-hook-refresh.ts
|
|
90716
91404
|
init_checkout_root();
|
|
90717
|
-
import { existsSync as
|
|
90718
|
-
import { dirname as dirname13, join as join45, resolve as
|
|
91405
|
+
import { existsSync as existsSync36, readdirSync as readdirSync13, readFileSync as readFileSync39 } from "node:fs";
|
|
91406
|
+
import { dirname as dirname13, join as join45, resolve as resolve8 } from "node:path";
|
|
90719
91407
|
init_registry();
|
|
90720
91408
|
function codexHookRoots(roots) {
|
|
90721
|
-
const found = new Set(roots.map((root) =>
|
|
91409
|
+
const found = new Set(roots.map((root) => resolve8(root)));
|
|
90722
91410
|
for (const root of [...found]) {
|
|
90723
91411
|
const main2 = mainCheckoutOfWorktree(root) ?? root;
|
|
90724
91412
|
found.add(main2);
|
|
90725
91413
|
const dir = join45(main2, ".git", "worktrees");
|
|
90726
|
-
if (!
|
|
91414
|
+
if (!existsSync36(dir)) continue;
|
|
90727
91415
|
let names;
|
|
90728
91416
|
try {
|
|
90729
91417
|
names = readdirSync13(dir);
|
|
@@ -90732,7 +91420,7 @@ function codexHookRoots(roots) {
|
|
|
90732
91420
|
}
|
|
90733
91421
|
for (const name2 of names) {
|
|
90734
91422
|
try {
|
|
90735
|
-
const checkout = dirname13(
|
|
91423
|
+
const checkout = dirname13(readFileSync39(join45(dir, name2, "gitdir"), "utf8").trim());
|
|
90736
91424
|
if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
|
|
90737
91425
|
} catch {
|
|
90738
91426
|
}
|
|
@@ -90754,7 +91442,7 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
|
|
|
90754
91442
|
}
|
|
90755
91443
|
|
|
90756
91444
|
// src/claude-statusline.ts
|
|
90757
|
-
import { existsSync as
|
|
91445
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync10, readFileSync as readFileSync40, writeFileSync as writeFileSync28 } from "node:fs";
|
|
90758
91446
|
import { homedir as homedir8 } from "node:os";
|
|
90759
91447
|
import { dirname as dirname14, join as join46 } from "node:path";
|
|
90760
91448
|
var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
|
|
@@ -90762,8 +91450,9 @@ import { readFileSync } from 'node:fs';
|
|
|
90762
91450
|
|
|
90763
91451
|
try {
|
|
90764
91452
|
const port = Number(process.argv[2]);
|
|
91453
|
+
const route = process.argv[3] === 'subagents' ? '/api/statusline/subagents' : '/api/statusline';
|
|
90765
91454
|
if (Number.isInteger(port) && port > 0 && port < 65536) {
|
|
90766
|
-
const response = await fetch('http://127.0.0.1:' + port +
|
|
91455
|
+
const response = await fetch('http://127.0.0.1:' + port + route, {
|
|
90767
91456
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
90768
91457
|
body: readFileSync(0, 'utf8') || '{}', signal: AbortSignal.timeout(800),
|
|
90769
91458
|
});
|
|
@@ -90773,20 +91462,30 @@ try {
|
|
|
90773
91462
|
`;
|
|
90774
91463
|
var STATUSLINE_RELAY_FILE = "errata-statusline.mjs";
|
|
90775
91464
|
function buildStatusLine(port, nodePath, relayPath) {
|
|
91465
|
+
return { type: "command", command: relayCommand(port, nodePath, relayPath), padding: 0 };
|
|
91466
|
+
}
|
|
91467
|
+
function buildSubagentStatusLine(port, nodePath, relayPath) {
|
|
91468
|
+
return { type: "command", command: `${relayCommand(port, nodePath, relayPath)} subagents` };
|
|
91469
|
+
}
|
|
91470
|
+
function relayCommand(port, nodePath, relayPath) {
|
|
90776
91471
|
if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error("Invalid status line port");
|
|
90777
91472
|
const q = (p) => {
|
|
90778
91473
|
if (/["$`\r\n]/.test(p)) throw new Error("Unsupported character in status line path");
|
|
90779
91474
|
return `"${p.replace(/\\/g, "/")}"`;
|
|
90780
91475
|
};
|
|
90781
|
-
return
|
|
91476
|
+
return `${q(nodePath)} ${q(relayPath)} ${port}`;
|
|
90782
91477
|
}
|
|
90783
91478
|
function isErrataStatusLine(value) {
|
|
90784
91479
|
return !!value && typeof value === "object" && typeof value["command"] === "string" && value["command"].includes(STATUSLINE_RELAY_FILE);
|
|
90785
91480
|
}
|
|
90786
91481
|
function removeProjectStatusLine(settings) {
|
|
90787
|
-
|
|
90788
|
-
|
|
90789
|
-
|
|
91482
|
+
let removed = false;
|
|
91483
|
+
for (const key of ["statusLine", "subagentStatusLine"]) {
|
|
91484
|
+
if (!isErrataStatusLine(settings[key])) continue;
|
|
91485
|
+
delete settings[key];
|
|
91486
|
+
removed = true;
|
|
91487
|
+
}
|
|
91488
|
+
return removed;
|
|
90790
91489
|
}
|
|
90791
91490
|
function userClaudeSettingsPath() {
|
|
90792
91491
|
const base = process.env["CLAUDE_CONFIG_DIR"] ?? join46(homedir8(), ".claude");
|
|
@@ -90798,26 +91497,34 @@ function ensureUserStatusLine(opts) {
|
|
|
90798
91497
|
if (off === "0" || off === "off" || off === "false" || off === "no") return "disabled";
|
|
90799
91498
|
const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
|
|
90800
91499
|
let settings = {};
|
|
90801
|
-
if (
|
|
91500
|
+
if (existsSync37(settingsPath)) {
|
|
90802
91501
|
try {
|
|
90803
|
-
const parsed = JSON.parse(
|
|
91502
|
+
const parsed = JSON.parse(readFileSync40(settingsPath, "utf8"));
|
|
90804
91503
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
|
|
90805
91504
|
settings = parsed;
|
|
90806
91505
|
} catch {
|
|
90807
91506
|
return "unreadable";
|
|
90808
91507
|
}
|
|
90809
91508
|
}
|
|
90810
|
-
|
|
91509
|
+
const ownMain = settings["statusLine"] !== void 0 && !isErrataStatusLine(settings["statusLine"]);
|
|
91510
|
+
const ownRows = settings["subagentStatusLine"] !== void 0 && !isErrataStatusLine(settings["subagentStatusLine"]);
|
|
91511
|
+
if (ownMain && ownRows) return "kept-own";
|
|
90811
91512
|
const relay = join46(opts.relayDir, STATUSLINE_RELAY_FILE);
|
|
90812
91513
|
mkdirSync10(opts.relayDir, { recursive: true });
|
|
90813
|
-
if (!
|
|
90814
|
-
|
|
91514
|
+
if (!existsSync37(relay) || readFileSync40(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
|
|
91515
|
+
writeFileSync28(relay, STATUSLINE_RELAY_SOURCE, "utf8");
|
|
91516
|
+
}
|
|
91517
|
+
const nodePath = opts.nodePath ?? process.execPath;
|
|
91518
|
+
const next = {
|
|
91519
|
+
...ownMain ? {} : { statusLine: buildStatusLine(opts.port, nodePath, relay) },
|
|
91520
|
+
...ownRows ? {} : { subagentStatusLine: buildSubagentStatusLine(opts.port, nodePath, relay) }
|
|
91521
|
+
};
|
|
91522
|
+
if (Object.entries(next).every(([k, v]) => JSON.stringify(settings[k]) === JSON.stringify(v))) {
|
|
91523
|
+
return ownMain ? "kept-own" : "unchanged";
|
|
90815
91524
|
}
|
|
90816
|
-
|
|
90817
|
-
if (JSON.stringify(settings["statusLine"]) === JSON.stringify(next)) return "unchanged";
|
|
90818
|
-
settings["statusLine"] = next;
|
|
91525
|
+
Object.assign(settings, next);
|
|
90819
91526
|
mkdirSync10(dirname14(settingsPath), { recursive: true });
|
|
90820
|
-
|
|
91527
|
+
writeFileSync28(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
90821
91528
|
return "installed";
|
|
90822
91529
|
}
|
|
90823
91530
|
function describeStatusLineOutcome(outcome) {
|
|
@@ -91240,14 +91947,14 @@ async function cmdInit() {
|
|
|
91240
91947
|
if (!skipHooks) {
|
|
91241
91948
|
console.log("");
|
|
91242
91949
|
console.log("installing harness hooks...");
|
|
91243
|
-
const { existsSync:
|
|
91950
|
+
const { existsSync: existsSync39 } = await import("node:fs");
|
|
91244
91951
|
const { join: join48 } = await import("node:path");
|
|
91245
91952
|
try {
|
|
91246
91953
|
await installClaudeHooks(port);
|
|
91247
91954
|
} catch (err2) {
|
|
91248
91955
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
91249
91956
|
}
|
|
91250
|
-
if (
|
|
91957
|
+
if (existsSync39(join48(ROOT, ".cursor"))) {
|
|
91251
91958
|
try {
|
|
91252
91959
|
await installCursorMcpConfig();
|
|
91253
91960
|
} catch (err2) {
|
|
@@ -91441,9 +92148,9 @@ async function cmdStatus() {
|
|
|
91441
92148
|
console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
|
|
91442
92149
|
console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
|
|
91443
92150
|
}
|
|
91444
|
-
console.log(` graph db: ${
|
|
91445
|
-
console.log(` event log: ${
|
|
91446
|
-
if (
|
|
92151
|
+
console.log(` graph db: ${existsSync38(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
|
|
92152
|
+
console.log(` event log: ${existsSync38(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
|
|
92153
|
+
if (existsSync38(paths.castalia)) {
|
|
91447
92154
|
try {
|
|
91448
92155
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
|
|
91449
92156
|
const store = openGraphStore2({ path: paths.castalia });
|
|
@@ -92414,11 +93121,11 @@ async function cmdInstallationProfile(args2) {
|
|
|
92414
93121
|
}
|
|
92415
93122
|
async function cmdReview() {
|
|
92416
93123
|
const paths = workspacePaths(ROOT);
|
|
92417
|
-
if (!
|
|
93124
|
+
if (!existsSync38(paths.reviewQueue)) {
|
|
92418
93125
|
console.log("(review queue empty)");
|
|
92419
93126
|
return;
|
|
92420
93127
|
}
|
|
92421
|
-
const queue = JSON.parse(
|
|
93128
|
+
const queue = JSON.parse(readFileSync41(paths.reviewQueue, "utf8"));
|
|
92422
93129
|
if (queue.length === 0) {
|
|
92423
93130
|
console.log("(review queue empty)");
|
|
92424
93131
|
return;
|
|
@@ -93089,7 +93796,7 @@ async function gatherRepo(store, ws) {
|
|
|
93089
93796
|
};
|
|
93090
93797
|
}
|
|
93091
93798
|
async function gatherReportData(generatedAt) {
|
|
93092
|
-
const { existsSync:
|
|
93799
|
+
const { existsSync: existsSync39 } = await import("node:fs");
|
|
93093
93800
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
|
|
93094
93801
|
const cfg = loadConfig();
|
|
93095
93802
|
const outbound = cfg.consent.sync ? "auto" : "off";
|
|
@@ -93097,7 +93804,7 @@ async function gatherReportData(generatedAt) {
|
|
|
93097
93804
|
for (const ws of listWorkspaces()) {
|
|
93098
93805
|
if (ws.missing) continue;
|
|
93099
93806
|
const dbPath = workspacePaths(ws.path).castalia;
|
|
93100
|
-
if (!
|
|
93807
|
+
if (!existsSync39(dbPath)) continue;
|
|
93101
93808
|
let store = null;
|
|
93102
93809
|
try {
|
|
93103
93810
|
store = openGraphStore2({ path: dbPath });
|
|
@@ -93128,7 +93835,7 @@ async function gatherReportData(generatedAt) {
|
|
|
93128
93835
|
};
|
|
93129
93836
|
}
|
|
93130
93837
|
async function cmdReport(args2) {
|
|
93131
|
-
const { mkdirSync: mkdirSync11, writeFileSync:
|
|
93838
|
+
const { mkdirSync: mkdirSync11, writeFileSync: writeFileSync29 } = await import("node:fs");
|
|
93132
93839
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
93133
93840
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
93134
93841
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -93141,7 +93848,7 @@ async function cmdReport(args2) {
|
|
|
93141
93848
|
const outDir = workspacePaths(ROOT).configDir;
|
|
93142
93849
|
mkdirSync11(outDir, { recursive: true });
|
|
93143
93850
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
93144
|
-
for (const f of files)
|
|
93851
|
+
for (const f of files) writeFileSync29(join47(outDir, f.name), f.html, "utf8");
|
|
93145
93852
|
const indexPath = join47(outDir, "report.html");
|
|
93146
93853
|
console.log(`report \u2192 ${indexPath}`);
|
|
93147
93854
|
console.log(
|
|
@@ -93255,24 +93962,24 @@ async function cmdInstallHooks(args2) {
|
|
|
93255
93962
|
}
|
|
93256
93963
|
}
|
|
93257
93964
|
async function installOpencodePlugin(port) {
|
|
93258
|
-
const { mkdirSync: mkdirSync11, existsSync:
|
|
93965
|
+
const { mkdirSync: mkdirSync11, existsSync: existsSync39, readFileSync: readFileSync42, writeFileSync: writeFileSync29 } = await import("node:fs");
|
|
93259
93966
|
const { join: join48 } = await import("node:path");
|
|
93260
93967
|
const dir = join48(ROOT, ".opencode", "plugin");
|
|
93261
|
-
if (!
|
|
93968
|
+
if (!existsSync39(dir)) mkdirSync11(dir, { recursive: true });
|
|
93262
93969
|
const file2 = join48(dir, "inerrata.js");
|
|
93263
|
-
if (
|
|
93264
|
-
const head2 =
|
|
93970
|
+
if (existsSync39(file2)) {
|
|
93971
|
+
const head2 = readFileSync42(file2, "utf8").split("\n")[0] ?? "";
|
|
93265
93972
|
if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
|
|
93266
93973
|
console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
|
|
93267
93974
|
process.exit(2);
|
|
93268
93975
|
}
|
|
93269
93976
|
}
|
|
93270
|
-
|
|
93977
|
+
writeFileSync29(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
|
|
93271
93978
|
const cfgFile = join48(ROOT, "opencode.json");
|
|
93272
93979
|
let cfg = { $schema: "https://opencode.ai/config.json" };
|
|
93273
|
-
if (
|
|
93980
|
+
if (existsSync39(cfgFile)) {
|
|
93274
93981
|
try {
|
|
93275
|
-
cfg = JSON.parse(
|
|
93982
|
+
cfg = JSON.parse(readFileSync42(cfgFile, "utf8"));
|
|
93276
93983
|
} catch {
|
|
93277
93984
|
console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
|
|
93278
93985
|
process.exit(2);
|
|
@@ -93283,7 +93990,7 @@ async function installOpencodePlugin(port) {
|
|
|
93283
93990
|
if (!hadErrata) {
|
|
93284
93991
|
const inv = errataMcpInvocation();
|
|
93285
93992
|
cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
|
|
93286
|
-
|
|
93993
|
+
writeFileSync29(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
93287
93994
|
}
|
|
93288
93995
|
console.log(`installed OpenCode plugin \u2192 ${file2}`);
|
|
93289
93996
|
if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
|
|
@@ -93310,15 +94017,15 @@ function ensureStatusLine(port) {
|
|
|
93310
94017
|
}
|
|
93311
94018
|
}
|
|
93312
94019
|
async function installClaudeHooks(port) {
|
|
93313
|
-
const { mkdirSync: mkdirSync11, existsSync:
|
|
94020
|
+
const { mkdirSync: mkdirSync11, existsSync: existsSync39, readFileSync: readFileSync42, writeFileSync: writeFileSync29 } = await import("node:fs");
|
|
93314
94021
|
const { join: join48 } = await import("node:path");
|
|
93315
94022
|
const dir = join48(ROOT, ".claude");
|
|
93316
|
-
if (!
|
|
94023
|
+
if (!existsSync39(dir)) mkdirSync11(dir, { recursive: true });
|
|
93317
94024
|
const file2 = join48(dir, "settings.json");
|
|
93318
94025
|
let settings = {};
|
|
93319
|
-
if (
|
|
94026
|
+
if (existsSync39(file2)) {
|
|
93320
94027
|
try {
|
|
93321
|
-
settings = JSON.parse(
|
|
94028
|
+
settings = JSON.parse(readFileSync42(file2, "utf8"));
|
|
93322
94029
|
} catch {
|
|
93323
94030
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
93324
94031
|
process.exit(2);
|
|
@@ -93326,6 +94033,7 @@ async function installClaudeHooks(port) {
|
|
|
93326
94033
|
}
|
|
93327
94034
|
const matcher = "Read|Edit|Write|Grep|Glob|NotebookEdit|Bash";
|
|
93328
94035
|
const postMatcher = `${matcher}|ToolSearch|mcp__errata__.*`;
|
|
94036
|
+
const preMatcher = `${matcher}|Agent|Task`;
|
|
93329
94037
|
const preCmd = `${hookRelayCommand(port, "/api/hook")} ${ERRATA_TAG}`;
|
|
93330
94038
|
const postCmd = `${hookRelayCommand(port, "/api/hook")} ${ERRATA_TAG}`;
|
|
93331
94039
|
settings.hooks ??= {};
|
|
@@ -93335,7 +94043,7 @@ async function installClaudeHooks(port) {
|
|
|
93335
94043
|
}
|
|
93336
94044
|
};
|
|
93337
94045
|
for (const [event, command, eventMatcher] of [
|
|
93338
|
-
["PreToolUse", preCmd,
|
|
94046
|
+
["PreToolUse", preCmd, preMatcher],
|
|
93339
94047
|
["PostToolUse", postCmd, postMatcher],
|
|
93340
94048
|
["PostToolUseFailure", postCmd, postMatcher]
|
|
93341
94049
|
]) {
|
|
@@ -93360,13 +94068,13 @@ async function installClaudeHooks(port) {
|
|
|
93360
94068
|
dropErrata(endList);
|
|
93361
94069
|
endList.push({ hooks: [{ type: "command", command: endCmd }] });
|
|
93362
94070
|
const injectCmd = `${hookRelayCommand(port, "/api/context-inject")} ${ERRATA_TAG}`;
|
|
93363
|
-
for (const event of ["SessionStart", "UserPromptSubmit"]) {
|
|
94071
|
+
for (const event of ["SessionStart", "UserPromptSubmit", "SubagentStart"]) {
|
|
93364
94072
|
const list = settings.hooks[event] ??= [];
|
|
93365
94073
|
dropErrata(list);
|
|
93366
94074
|
list.push({ hooks: [{ type: "command", command: injectCmd }] });
|
|
93367
94075
|
}
|
|
93368
94076
|
removeProjectStatusLine(settings);
|
|
93369
|
-
|
|
94077
|
+
writeFileSync29(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
93370
94078
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
93371
94079
|
console.log(` ${ensureStatusLine(port)}`);
|
|
93372
94080
|
await installClaudeMcpConfig();
|
|
@@ -93382,15 +94090,15 @@ async function installClaudeHooks(port) {
|
|
|
93382
94090
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
93383
94091
|
}
|
|
93384
94092
|
async function installClaudeMcpConfig() {
|
|
93385
|
-
const { mkdirSync: mkdirSync11, existsSync:
|
|
94093
|
+
const { mkdirSync: mkdirSync11, existsSync: existsSync39, readFileSync: readFileSync42, writeFileSync: writeFileSync29 } = await import("node:fs");
|
|
93386
94094
|
const { join: join48, dirname: dirname15 } = await import("node:path");
|
|
93387
94095
|
const file2 = join48(ROOT, ".mcp.json");
|
|
93388
94096
|
const dir = dirname15(file2);
|
|
93389
|
-
if (!
|
|
94097
|
+
if (!existsSync39(dir)) mkdirSync11(dir, { recursive: true });
|
|
93390
94098
|
let cfg = {};
|
|
93391
|
-
if (
|
|
94099
|
+
if (existsSync39(file2)) {
|
|
93392
94100
|
try {
|
|
93393
|
-
cfg = JSON.parse(
|
|
94101
|
+
cfg = JSON.parse(readFileSync42(file2, "utf8"));
|
|
93394
94102
|
} catch {
|
|
93395
94103
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
93396
94104
|
process.exit(2);
|
|
@@ -93398,21 +94106,21 @@ async function installClaudeMcpConfig() {
|
|
|
93398
94106
|
}
|
|
93399
94107
|
cfg.mcpServers ??= {};
|
|
93400
94108
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
93401
|
-
|
|
94109
|
+
writeFileSync29(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
93402
94110
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
93403
94111
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
93404
94112
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
93405
94113
|
}
|
|
93406
94114
|
async function installCursorMcpConfig() {
|
|
93407
|
-
const { mkdirSync: mkdirSync11, existsSync:
|
|
94115
|
+
const { mkdirSync: mkdirSync11, existsSync: existsSync39, readFileSync: readFileSync42, writeFileSync: writeFileSync29 } = await import("node:fs");
|
|
93408
94116
|
const { join: join48 } = await import("node:path");
|
|
93409
94117
|
const dir = join48(ROOT, ".cursor");
|
|
93410
|
-
if (!
|
|
94118
|
+
if (!existsSync39(dir)) mkdirSync11(dir, { recursive: true });
|
|
93411
94119
|
const file2 = join48(dir, "mcp.json");
|
|
93412
94120
|
let cfg = {};
|
|
93413
|
-
if (
|
|
94121
|
+
if (existsSync39(file2)) {
|
|
93414
94122
|
try {
|
|
93415
|
-
cfg = JSON.parse(
|
|
94123
|
+
cfg = JSON.parse(readFileSync42(file2, "utf8"));
|
|
93416
94124
|
} catch {
|
|
93417
94125
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
93418
94126
|
process.exit(2);
|
|
@@ -93420,7 +94128,7 @@ async function installCursorMcpConfig() {
|
|
|
93420
94128
|
}
|
|
93421
94129
|
cfg.mcpServers ??= {};
|
|
93422
94130
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
93423
|
-
|
|
94131
|
+
writeFileSync29(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
93424
94132
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
93425
94133
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
93426
94134
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -93773,7 +94481,7 @@ async function cmdDash(args2) {
|
|
|
93773
94481
|
const hotspotScanMark = /* @__PURE__ */ new Map();
|
|
93774
94482
|
const HOTSPOT_FANIN = 20;
|
|
93775
94483
|
const runNightlyPass = async (dueIds) => {
|
|
93776
|
-
const yieldToLoop2 = () => new Promise((
|
|
94484
|
+
const yieldToLoop2 = () => new Promise((resolve9) => setImmediate(resolve9));
|
|
93777
94485
|
const fullReclusterPass = nightlyCount++ % FULL_RECLUSTER_EVERY === 0;
|
|
93778
94486
|
const m = dueIds ? await handle2.nightlyFor(dueIds) : await handle2.nightlyAll();
|
|
93779
94487
|
let skillsLearned = 0;
|