@inerrata-corporation/errata 2.0.22-dev.4180 → 2.0.22-dev.4277
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 +42 -9
- package/errata.mjs +644 -198
- package/generalize-worker.mjs +13 -7
- package/package.json +1 -1
- package/pass-worker.mjs +57 -10
- package/resources/context-plugin/.codex-plugin/plugin.json +1 -1
- package/resources/context-plugin/SHA256SUMS +1 -1
package/errata.mjs
CHANGED
|
@@ -19108,17 +19108,23 @@ function installTextIndex(db) {
|
|
|
19108
19108
|
db.transaction(() => {
|
|
19109
19109
|
db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS nodes_text
|
|
19110
19110
|
USING fts5(description, content='nodes', content_rowid='rowid', tokenize='trigram')`);
|
|
19111
|
+
db.exec(`DROP TRIGGER IF EXISTS nodes_text_update_out; DROP TRIGGER IF EXISTS nodes_text_update_in;
|
|
19112
|
+
DROP TRIGGER IF EXISTS nodes_text_update`);
|
|
19111
19113
|
db.exec(`CREATE TRIGGER IF NOT EXISTS nodes_text_insert AFTER INSERT ON nodes WHEN NEW.valid_to IS NULL
|
|
19112
19114
|
BEGIN INSERT INTO nodes_text(rowid, description) VALUES (NEW.rowid, NEW.description); END;`);
|
|
19113
|
-
db.exec(`CREATE TRIGGER
|
|
19114
|
-
WHEN OLD.valid_to IS
|
|
19115
|
-
BEGIN
|
|
19116
|
-
|
|
19117
|
-
|
|
19118
|
-
|
|
19115
|
+
db.exec(`CREATE TRIGGER nodes_text_update AFTER UPDATE OF description, valid_to ON nodes
|
|
19116
|
+
WHEN OLD.description IS NOT NEW.description OR OLD.valid_to IS NOT NEW.valid_to
|
|
19117
|
+
BEGIN
|
|
19118
|
+
INSERT INTO nodes_text(nodes_text, rowid, description)
|
|
19119
|
+
SELECT 'delete', OLD.rowid, OLD.description WHERE OLD.valid_to IS NULL;
|
|
19120
|
+
INSERT INTO nodes_text(rowid, description)
|
|
19121
|
+
SELECT NEW.rowid, NEW.description WHERE NEW.valid_to IS NULL;
|
|
19122
|
+
END;`);
|
|
19119
19123
|
db.exec(`CREATE TRIGGER IF NOT EXISTS nodes_text_delete AFTER DELETE ON nodes WHEN OLD.valid_to IS NULL
|
|
19120
19124
|
BEGIN INSERT INTO nodes_text(nodes_text, rowid, description) VALUES ('delete', OLD.rowid, OLD.description); END;`);
|
|
19125
|
+
db.exec(`INSERT INTO nodes_text(nodes_text) VALUES ('delete-all')`);
|
|
19121
19126
|
db.exec(`INSERT INTO nodes_text(rowid, description) SELECT rowid, description FROM nodes WHERE valid_to IS NULL`);
|
|
19127
|
+
db.prepare("INSERT OR REPLACE INTO store_meta(key,value) VALUES (?,?)").run("text-index-trigram-1", "installed");
|
|
19122
19128
|
db.prepare("INSERT INTO store_meta(key,value) VALUES (?,?)").run(TEXT_INDEX_KEY, "installed");
|
|
19123
19129
|
});
|
|
19124
19130
|
}
|
|
@@ -19129,7 +19135,7 @@ var TEXT_INDEX_KEY, TEXT_INDEX_MIN_TERM;
|
|
|
19129
19135
|
var init_text_index = __esm({
|
|
19130
19136
|
"../../packages/local-graph/src/text-index.ts"() {
|
|
19131
19137
|
"use strict";
|
|
19132
|
-
TEXT_INDEX_KEY = "text-index-trigram-
|
|
19138
|
+
TEXT_INDEX_KEY = "text-index-trigram-2";
|
|
19133
19139
|
TEXT_INDEX_MIN_TERM = 3;
|
|
19134
19140
|
}
|
|
19135
19141
|
});
|
|
@@ -26226,6 +26232,20 @@ function clearCandidate(store, node2, ts, rejectTargetId) {
|
|
|
26226
26232
|
}
|
|
26227
26233
|
store.updateNode(node2.id, { attrs, lastUpdatedAt: ts });
|
|
26228
26234
|
}
|
|
26235
|
+
function markStanding(store, node2, mark, reason, ts) {
|
|
26236
|
+
const stamped = {
|
|
26237
|
+
...mark,
|
|
26238
|
+
examinedAtSeq: store.currentIngestSeq(),
|
|
26239
|
+
examinations: (mark.examinations ?? 0) + 1,
|
|
26240
|
+
standingReason: reason
|
|
26241
|
+
};
|
|
26242
|
+
store.updateNode(node2.id, { attrs: { ...node2.attrs, foldCandidate: stamped }, lastUpdatedAt: ts });
|
|
26243
|
+
}
|
|
26244
|
+
function foldCandidateEligible(mark, currentSeq, judgeConfigured) {
|
|
26245
|
+
if (mark.examinedAtSeq === void 0) return true;
|
|
26246
|
+
if (mark.standingReason === "no-judge" && judgeConfigured) return true;
|
|
26247
|
+
return currentSeq - mark.examinedAtSeq >= FOLD_REEXAMINE_SEQ;
|
|
26248
|
+
}
|
|
26229
26249
|
async function resolveFoldCandidates(store, opts) {
|
|
26230
26250
|
const report = {
|
|
26231
26251
|
examined: 0,
|
|
@@ -26235,10 +26255,17 @@ async function resolveFoldCandidates(store, opts) {
|
|
|
26235
26255
|
rejected: 0,
|
|
26236
26256
|
standing: 0,
|
|
26237
26257
|
judgeErrors: 0,
|
|
26238
|
-
retargeted: 0
|
|
26258
|
+
retargeted: 0,
|
|
26259
|
+
pending: 0,
|
|
26260
|
+
neverExamined: 0,
|
|
26261
|
+
firstExamined: 0,
|
|
26262
|
+
waiting: 0,
|
|
26263
|
+
judgeBudgetDeferred: 0
|
|
26239
26264
|
};
|
|
26240
|
-
const limit = opts.limit ??
|
|
26241
|
-
const
|
|
26265
|
+
const limit = opts.limit ?? FOLD_EXAMINE_LIMIT;
|
|
26266
|
+
const judgeBudget = opts.judgeBudget ?? FOLD_JUDGE_BUDGET;
|
|
26267
|
+
const currentSeq = store.currentIngestSeq();
|
|
26268
|
+
const pool = store.selectNodes({
|
|
26242
26269
|
labels: ["Problem"],
|
|
26243
26270
|
attrs: ["foldCandidate"],
|
|
26244
26271
|
where: [
|
|
@@ -26246,16 +26273,35 @@ async function resolveFoldCandidates(store, opts) {
|
|
|
26246
26273
|
{ attr: "mergedInto", absent: true },
|
|
26247
26274
|
{ attr: "foldCandidate", present: true }
|
|
26248
26275
|
]
|
|
26249
|
-
})
|
|
26250
|
-
|
|
26251
|
-
|
|
26252
|
-
|
|
26276
|
+
});
|
|
26277
|
+
const markOf = (n) => n.attrs["foldCandidate"];
|
|
26278
|
+
report.pending = pool.length;
|
|
26279
|
+
let neverExamined = pool.filter((n) => markOf(n).examinedAtSeq === void 0).length;
|
|
26280
|
+
const eligible = pool.filter((n) => foldCandidateEligible(markOf(n), currentSeq, !!opts.judge));
|
|
26281
|
+
report.waiting = pool.length - eligible.length;
|
|
26282
|
+
const marked = eligible.sort((a, b) => {
|
|
26283
|
+
const ma = markOf(a);
|
|
26284
|
+
const mb = markOf(b);
|
|
26285
|
+
const ea = ma.examinedAtSeq ?? -1;
|
|
26286
|
+
const eb = mb.examinedAtSeq ?? -1;
|
|
26287
|
+
if (ea !== eb) return ea - eb;
|
|
26288
|
+
return (ma.ts ?? 0) - (mb.ts ?? 0);
|
|
26253
26289
|
}).slice(0, limit);
|
|
26290
|
+
let judgeCalls = 0;
|
|
26291
|
+
const unseenMark = (n) => {
|
|
26292
|
+
const m = n.attrs["foldCandidate"];
|
|
26293
|
+
return m !== void 0 && m.examinedAtSeq === void 0;
|
|
26294
|
+
};
|
|
26254
26295
|
for (const node2 of marked) {
|
|
26255
26296
|
const fresh = store.getNode(node2.id);
|
|
26256
26297
|
if (!openProblem(fresh)) continue;
|
|
26257
|
-
report.examined++;
|
|
26258
26298
|
const mark = fresh.attrs["foldCandidate"];
|
|
26299
|
+
const firstLook = mark.examinedAtSeq === void 0;
|
|
26300
|
+
report.examined++;
|
|
26301
|
+
if (firstLook) {
|
|
26302
|
+
report.firstExamined++;
|
|
26303
|
+
neverExamined--;
|
|
26304
|
+
}
|
|
26259
26305
|
let target = followMerges(store, mark.targetId);
|
|
26260
26306
|
if (target && target.id !== mark.targetId) report.retargeted++;
|
|
26261
26307
|
if (!openProblem(target)) {
|
|
@@ -26273,6 +26319,7 @@ async function resolveFoldCandidates(store, opts) {
|
|
|
26273
26319
|
cos = cosine(fresh.embedding, target.embedding);
|
|
26274
26320
|
}
|
|
26275
26321
|
if (cos !== null && cos >= FOLD_EMBED_AUTO_COSINE) {
|
|
26322
|
+
if (unseenMark(target)) neverExamined--;
|
|
26276
26323
|
foldPair(store, fresh, target, opts.ts);
|
|
26277
26324
|
report.folded++;
|
|
26278
26325
|
report.foldedEmbedding++;
|
|
@@ -26284,9 +26331,20 @@ async function resolveFoldCandidates(store, opts) {
|
|
|
26284
26331
|
continue;
|
|
26285
26332
|
}
|
|
26286
26333
|
if (!opts.judge) {
|
|
26334
|
+
markStanding(store, fresh, mark, "no-judge", opts.ts);
|
|
26287
26335
|
report.standing++;
|
|
26288
26336
|
continue;
|
|
26289
26337
|
}
|
|
26338
|
+
if (judgeCalls >= judgeBudget) {
|
|
26339
|
+
report.examined--;
|
|
26340
|
+
if (firstLook) {
|
|
26341
|
+
report.firstExamined--;
|
|
26342
|
+
neverExamined++;
|
|
26343
|
+
}
|
|
26344
|
+
report.judgeBudgetDeferred++;
|
|
26345
|
+
continue;
|
|
26346
|
+
}
|
|
26347
|
+
judgeCalls++;
|
|
26290
26348
|
let verdict = null;
|
|
26291
26349
|
try {
|
|
26292
26350
|
verdict = await opts.judge(fresh.description, target.description);
|
|
@@ -26294,6 +26352,7 @@ async function resolveFoldCandidates(store, opts) {
|
|
|
26294
26352
|
verdict = null;
|
|
26295
26353
|
}
|
|
26296
26354
|
if (verdict === "same") {
|
|
26355
|
+
if (unseenMark(target)) neverExamined--;
|
|
26297
26356
|
foldPair(store, fresh, target, opts.ts);
|
|
26298
26357
|
report.folded++;
|
|
26299
26358
|
report.foldedJudge++;
|
|
@@ -26301,10 +26360,12 @@ async function resolveFoldCandidates(store, opts) {
|
|
|
26301
26360
|
clearCandidate(store, fresh, opts.ts, target.id);
|
|
26302
26361
|
report.rejected++;
|
|
26303
26362
|
} else {
|
|
26363
|
+
markStanding(store, fresh, mark, "judge-error", opts.ts);
|
|
26304
26364
|
report.judgeErrors++;
|
|
26305
26365
|
report.standing++;
|
|
26306
26366
|
}
|
|
26307
26367
|
}
|
|
26368
|
+
report.neverExamined = neverExamined;
|
|
26308
26369
|
return report;
|
|
26309
26370
|
}
|
|
26310
26371
|
function foldPair(store, a, b, ts) {
|
|
@@ -26319,7 +26380,7 @@ function foldPair(store, a, b, ts) {
|
|
|
26319
26380
|
if (!freshSurvivor || !freshDup) return;
|
|
26320
26381
|
foldDuplicateProblem(store, freshDup, freshSurvivor, ts);
|
|
26321
26382
|
}
|
|
26322
|
-
var FOLD_SCOUT_AUTO_COSINE, FOLD_SCOUT_MIN_COSINE, FOLD_SCOUT_MIN_JACCARD, FOLD_EMBED_AUTO_COSINE, FOLD_JUDGE_MIN_COSINE, FOLD_REJECTED_CAP, WORKSPACE_SCAN_CAP, openProblem;
|
|
26383
|
+
var FOLD_SCOUT_AUTO_COSINE, FOLD_SCOUT_MIN_COSINE, FOLD_SCOUT_MIN_JACCARD, FOLD_EMBED_AUTO_COSINE, FOLD_JUDGE_MIN_COSINE, FOLD_REJECTED_CAP, FOLD_REEXAMINE_SEQ, FOLD_EXAMINE_LIMIT, FOLD_JUDGE_BUDGET, WORKSPACE_SCAN_CAP, openProblem;
|
|
26323
26384
|
var init_fold_candidates = __esm({
|
|
26324
26385
|
"../../packages/local-graph/src/fold-candidates.ts"() {
|
|
26325
26386
|
"use strict";
|
|
@@ -26332,6 +26393,9 @@ var init_fold_candidates = __esm({
|
|
|
26332
26393
|
FOLD_EMBED_AUTO_COSINE = 0.88;
|
|
26333
26394
|
FOLD_JUDGE_MIN_COSINE = 0.5;
|
|
26334
26395
|
FOLD_REJECTED_CAP = 8;
|
|
26396
|
+
FOLD_REEXAMINE_SEQ = 100;
|
|
26397
|
+
FOLD_EXAMINE_LIMIT = 32;
|
|
26398
|
+
FOLD_JUDGE_BUDGET = 8;
|
|
26335
26399
|
WORKSPACE_SCAN_CAP = 400;
|
|
26336
26400
|
openProblem = (n) => !!n && n.label === "Problem" && n.attrs["resolvedAt"] == null && n.attrs["mergedInto"] === void 0;
|
|
26337
26401
|
}
|
|
@@ -26790,6 +26854,28 @@ var init_mechanism_liveness = __esm({
|
|
|
26790
26854
|
// climbs while `accepted` stays flat is the shape of a silently-closed door.
|
|
26791
26855
|
backlogCounter: "candidates"
|
|
26792
26856
|
},
|
|
26857
|
+
{
|
|
26858
|
+
id: "edge-park-replay",
|
|
26859
|
+
what: "parks causal/anchor edges the door refused as unresolvable, replays them when due, drops them with a disposition",
|
|
26860
|
+
pass: "ship",
|
|
26861
|
+
// FED = a source whose whole binding-edge family LANDED: the digest is
|
|
26862
|
+
// stamped only when every edge in it came back created/reinforced, so it is
|
|
26863
|
+
// the store-side proof that edges (not just nodes) cross. Live dev
|
|
26864
|
+
// 2026-10-12 sat with the same 241 refusals re-sent every drain and this
|
|
26865
|
+
// stamp frozen — nodes crossed, their causal wiring did not.
|
|
26866
|
+
fed: {
|
|
26867
|
+
labels: ["Problem", "RootCause"],
|
|
26868
|
+
attr: "semanticEdgesContributedDigest",
|
|
26869
|
+
minFraction: 0.01
|
|
26870
|
+
},
|
|
26871
|
+
// A parked edge that later LANDED — the replay doing its job.
|
|
26872
|
+
effectCounter: "edgesReplayLanded",
|
|
26873
|
+
// Outstanding parked edges (a level). Flat-and-nonzero while replays keep
|
|
26874
|
+
// re-parking is an endpoint that never resolves; it drains to tombstones
|
|
26875
|
+
// (`edgesDroppedExhausted`) instead of being resent forever.
|
|
26876
|
+
backlogCounter: "edgeParkSize",
|
|
26877
|
+
note: "edge-park.ts; quiet (no-effect) is healthy when nothing is refused \u2014 read edgesParked/edgesDropped* on the ship row"
|
|
26878
|
+
},
|
|
26793
26879
|
{
|
|
26794
26880
|
id: "orphan-reap",
|
|
26795
26881
|
what: "closes File nodes whose path the indexer no longer covers",
|
|
@@ -26844,12 +26930,31 @@ var init_mechanism_liveness = __esm({
|
|
|
26844
26930
|
// the bar is "the field is written at all", the revisit-sweep precedent.
|
|
26845
26931
|
fed: { labels: ["Problem"], attr: "foldCandidate", minFraction: 0 },
|
|
26846
26932
|
effectCounter: "folded",
|
|
26847
|
-
//
|
|
26848
|
-
//
|
|
26849
|
-
|
|
26933
|
+
// The open-nomination POOL is the backlog. It used to be `standing`, which
|
|
26934
|
+
// only counts what the pass examined — capped at the per-run limit — so it
|
|
26935
|
+
// read a flat 8 for weeks while 824 nominations sat open (2026-10-12): the
|
|
26936
|
+
// gauge could not see past the slice it was meant to be measuring.
|
|
26937
|
+
backlogCounter: "pending",
|
|
26850
26938
|
configCounter: "judgeConfigured",
|
|
26851
26939
|
note: "the ambiguous band needs the opt-in judge: set ERRATA_FOLD_JUDGE=1 + a configured chat provider (azure env), or leave it off and the nominations stand"
|
|
26852
26940
|
},
|
|
26941
|
+
{
|
|
26942
|
+
id: "fold-candidate-coverage",
|
|
26943
|
+
what: "rotates the fold-judge pass through every open nomination (never-examined first, standing ones re-examined on new evidence)",
|
|
26944
|
+
// Judge-INDEPENDENT on purpose — no configCounter. The embedding-certain
|
|
26945
|
+
// bands fold/reject with no judge at all, and the defect this watches is
|
|
26946
|
+
// the pass re-reading the same oldest 8 forever (101 runs, 8 distinct
|
|
26947
|
+
// nodes, 816 of 824 nominations never looked at). That starves those
|
|
26948
|
+
// bands on a judge-less daemon exactly as much as on a judged one, so an
|
|
26949
|
+
// opt-in being off must not excuse it.
|
|
26950
|
+
pass: "fold-judge",
|
|
26951
|
+
fed: { labels: ["Problem"], attr: "foldCandidate", minFraction: 0 },
|
|
26952
|
+
effectCounter: "firstExamined",
|
|
26953
|
+
// A LEVEL: open nominations never examined. Flat-and-positive with no
|
|
26954
|
+
// first examinations across the stall window = the rotation is stuck.
|
|
26955
|
+
backlogCounter: "neverExamined",
|
|
26956
|
+
note: "neverExamined must drain while the pass runs; flat means the selection is re-reading the same slice"
|
|
26957
|
+
},
|
|
26853
26958
|
{
|
|
26854
26959
|
id: "cite-anchor-accrual",
|
|
26855
26960
|
what: "accrues cite-context anchor evidence on anchorless cited priors; two distinct sessions promote a cite-confirmed ANCHORED_AT",
|
|
@@ -27029,7 +27134,10 @@ __export(src_exports2, {
|
|
|
27029
27134
|
FINGERPRINT_INDEXED_LABELS: () => FINGERPRINT_INDEXED_LABELS,
|
|
27030
27135
|
FIX_CANDIDATE_ASK_LIMIT: () => FIX_CANDIDATE_ASK_LIMIT,
|
|
27031
27136
|
FOLD_EMBED_AUTO_COSINE: () => FOLD_EMBED_AUTO_COSINE,
|
|
27137
|
+
FOLD_EXAMINE_LIMIT: () => FOLD_EXAMINE_LIMIT,
|
|
27138
|
+
FOLD_JUDGE_BUDGET: () => FOLD_JUDGE_BUDGET,
|
|
27032
27139
|
FOLD_JUDGE_MIN_COSINE: () => FOLD_JUDGE_MIN_COSINE,
|
|
27140
|
+
FOLD_REEXAMINE_SEQ: () => FOLD_REEXAMINE_SEQ,
|
|
27033
27141
|
FOLD_REJECTED_CAP: () => FOLD_REJECTED_CAP,
|
|
27034
27142
|
FOLD_SCOUT_AUTO_COSINE: () => FOLD_SCOUT_AUTO_COSINE,
|
|
27035
27143
|
FOLD_SCOUT_MIN_COSINE: () => FOLD_SCOUT_MIN_COSINE,
|
|
@@ -27106,6 +27214,7 @@ __export(src_exports2, {
|
|
|
27106
27214
|
findReusableSolution: () => findReusableSolution,
|
|
27107
27215
|
findWorkspaceFoldCandidate: () => findWorkspaceFoldCandidate,
|
|
27108
27216
|
flattenCloudCounts: () => flattenCloudCounts,
|
|
27217
|
+
foldCandidateEligible: () => foldCandidateEligible,
|
|
27109
27218
|
foldDuplicateProblem: () => foldDuplicateProblem,
|
|
27110
27219
|
foldSameAnchorProblem: () => foldSameAnchorProblem,
|
|
27111
27220
|
formatMechanismStatus: () => formatMechanismStatus,
|
|
@@ -28663,7 +28772,7 @@ function parseRestErrorEnvelope(text) {
|
|
|
28663
28772
|
return null;
|
|
28664
28773
|
}
|
|
28665
28774
|
}
|
|
28666
|
-
var asWireCount, INGEST_NODE_CHUNK, INGEST_EDGE_CHUNK, E6B_PUBLIC_CONTEXT_SENTINEL, gzipAsync, CloudClient, CloudError;
|
|
28775
|
+
var asWireCount, INGEST_NODE_CHUNK, INGEST_EDGE_CHUNK, ENDPOINT_NOT_LANDED_PREFIX, E6B_PUBLIC_CONTEXT_SENTINEL, gzipAsync, CloudClient, CloudError;
|
|
28667
28776
|
var init_client = __esm({
|
|
28668
28777
|
"../../packages/cloud-client/src/client.ts"() {
|
|
28669
28778
|
"use strict";
|
|
@@ -28672,6 +28781,7 @@ var init_client = __esm({
|
|
|
28672
28781
|
asWireCount = (n) => typeof n === "number" && Number.isFinite(n) && n >= 0 ? Math.floor(n) : null;
|
|
28673
28782
|
INGEST_NODE_CHUNK = 8;
|
|
28674
28783
|
INGEST_EDGE_CHUNK = 32;
|
|
28784
|
+
ENDPOINT_NOT_LANDED_PREFIX = "endpoint did not land this drain";
|
|
28675
28785
|
E6B_PUBLIC_CONTEXT_SENTINEL = "00000000-0000-4e6b-8000-000000000e6b";
|
|
28676
28786
|
gzipAsync = promisify(gzip);
|
|
28677
28787
|
CloudClient = class {
|
|
@@ -28874,7 +28984,7 @@ var init_client = __esm({
|
|
|
28874
28984
|
pendingEdges = pendingEdges.filter((e) => !shipped.has(e));
|
|
28875
28985
|
return { nodes, edges };
|
|
28876
28986
|
});
|
|
28877
|
-
|
|
28987
|
+
let totalChunks = single ? 1 : nodePlan.length + Math.ceil(pendingEdges.length / INGEST_EDGE_CHUNK);
|
|
28878
28988
|
let chunkIndex = 0;
|
|
28879
28989
|
const blocked = [];
|
|
28880
28990
|
const emit = async (nodeIds, result) => {
|
|
@@ -28901,9 +29011,18 @@ var init_client = __esm({
|
|
|
28901
29011
|
}
|
|
28902
29012
|
const merged = { runId, nodes: [], edges: [] };
|
|
28903
29013
|
const echoedCloudId = /* @__PURE__ */ new Map();
|
|
29014
|
+
const notLanded = /* @__PURE__ */ new Map();
|
|
28904
29015
|
for (const { nodes: nodeChunk, edges: inChunk } of nodePlan) {
|
|
28905
29016
|
const r = await this.ingestWithSplit(batch, nodeChunk, inChunk, blocked);
|
|
29017
|
+
const refusedHere = new Set(blocked);
|
|
28906
29018
|
await emit(nodeChunk.map((n) => n.id), r);
|
|
29019
|
+
const verdict = new Map(r.nodes.map((rn) => [rn.canonicalId, rn]));
|
|
29020
|
+
for (const n of nodeChunk) {
|
|
29021
|
+
const rn = verdict.get(n.id);
|
|
29022
|
+
if (refusedHere.has(n.id)) notLanded.set(n.id, "refused by an intermediary");
|
|
29023
|
+
else if (!rn) notLanded.set(n.id, "no verdict from the door");
|
|
29024
|
+
else if (rn.decision === "rejected") notLanded.set(n.id, rn.reason ?? "rejected");
|
|
29025
|
+
}
|
|
28907
29026
|
merged.nodes.push(...r.nodes);
|
|
28908
29027
|
merged.edges.push(...r.edges);
|
|
28909
29028
|
for (const rn of r.nodes) {
|
|
@@ -28915,6 +29034,19 @@ var init_client = __esm({
|
|
|
28915
29034
|
merged.patternReconciliation = { ...merged.patternReconciliation, ...r.patternReconciliation };
|
|
28916
29035
|
}
|
|
28917
29036
|
}
|
|
29037
|
+
pendingEdges = pendingEdges.filter((e) => {
|
|
29038
|
+
const missing = notLanded.has(e.from) && !echoedCloudId.has(e.from) ? e.from : notLanded.has(e.to) && !echoedCloudId.has(e.to) ? e.to : null;
|
|
29039
|
+
if (missing === null) return true;
|
|
29040
|
+
merged.edges.push({
|
|
29041
|
+
from: e.from,
|
|
29042
|
+
to: e.to,
|
|
29043
|
+
type: e.type,
|
|
29044
|
+
decision: "rejected",
|
|
29045
|
+
reason: `${ENDPOINT_NOT_LANDED_PREFIX} '${missing}' \u2014 ${notLanded.get(missing)}`
|
|
29046
|
+
});
|
|
29047
|
+
return false;
|
|
29048
|
+
});
|
|
29049
|
+
totalChunks = nodePlan.length + Math.ceil(pendingEdges.length / INGEST_EDGE_CHUNK);
|
|
28918
29050
|
for (const edgeChunk of chunkArray(pendingEdges, INGEST_EDGE_CHUNK)) {
|
|
28919
29051
|
const projected = edgeChunk.map((e) => ({
|
|
28920
29052
|
...e,
|
|
@@ -37332,6 +37464,7 @@ function isQuotaError(err2) {
|
|
|
37332
37464
|
async function dualAugment(opts) {
|
|
37333
37465
|
const { store, cloud, localHits, seedNode, queryText, limit, generalizeSoft } = opts;
|
|
37334
37466
|
const cloudHits = [];
|
|
37467
|
+
let completeResponse = true;
|
|
37335
37468
|
let seedUsageCount;
|
|
37336
37469
|
let seedProvenance = "local";
|
|
37337
37470
|
const calls = [];
|
|
@@ -37358,6 +37491,7 @@ async function dualAugment(opts) {
|
|
|
37358
37491
|
if (cloudSeeds.length > 0 || softQ) {
|
|
37359
37492
|
calls.push(
|
|
37360
37493
|
cloud.search({ stack: [], domains: [], kinds: [], seed: cloudSeeds, ...softQ ? { q: softQ } : {}, limit, community: true, via: true }).then((res) => {
|
|
37494
|
+
if (res.seeds?.some((seed) => seed.status === "error")) completeResponse = false;
|
|
37361
37495
|
cloudHits.push(...searchResultToCloudHits(res));
|
|
37362
37496
|
})
|
|
37363
37497
|
);
|
|
@@ -37379,18 +37513,29 @@ async function dualAugment(opts) {
|
|
|
37379
37513
|
}
|
|
37380
37514
|
if (cloudHits.length === 0) return { status: "empty" };
|
|
37381
37515
|
const deduped = dedupCloudHits(cloudHits);
|
|
37516
|
+
const merged = mergeDualBurst(localHits, deduped, {
|
|
37517
|
+
// A hit's `via` parent is resolved too, so an edge from a folded twin
|
|
37518
|
+
// can be re-pointed at the entity it folded into.
|
|
37519
|
+
twins: storeTwinIndex(store, deduped.flatMap((c) => {
|
|
37520
|
+
const parent = c.via?.parentId;
|
|
37521
|
+
return parent ? [c.id, parent] : [c.id];
|
|
37522
|
+
})),
|
|
37523
|
+
...seedNode ? { seedId: seedNode.id } : {},
|
|
37524
|
+
...opts.fuse ? { fuse: opts.fuse } : {}
|
|
37525
|
+
});
|
|
37526
|
+
if (completeResponse) {
|
|
37527
|
+
const candidates = new Set(deduped.filter((hit) => !isCodeLabel(hit.label)).map((hit) => hit.id));
|
|
37528
|
+
const localIds = /* @__PURE__ */ new Set([...localHits.map((hit) => hit.id), ...seedNode ? [seedNode.id] : []]);
|
|
37529
|
+
const emitted = [];
|
|
37530
|
+
for (const node2 of merged.nodes) {
|
|
37531
|
+
const ids = [...node2.provenance === "collective" ? [node2.id] : [], ...node2.twins ?? []];
|
|
37532
|
+
for (const id of ids) if (candidates.has(id) && !localIds.has(id)) emitted.push(id);
|
|
37533
|
+
}
|
|
37534
|
+
rememberCollectiveIds(cloud, emitted);
|
|
37535
|
+
}
|
|
37382
37536
|
return {
|
|
37383
37537
|
status: "merged",
|
|
37384
|
-
merged
|
|
37385
|
-
// A hit's `via` parent is resolved too, so an edge from a folded twin
|
|
37386
|
-
// can be re-pointed at the entity it folded into.
|
|
37387
|
-
twins: storeTwinIndex(store, deduped.flatMap((c) => {
|
|
37388
|
-
const parent = c.via?.parentId;
|
|
37389
|
-
return parent ? [c.id, parent] : [c.id];
|
|
37390
|
-
})),
|
|
37391
|
-
...seedNode ? { seedId: seedNode.id } : {},
|
|
37392
|
-
...opts.fuse ? { fuse: opts.fuse } : {}
|
|
37393
|
-
}),
|
|
37538
|
+
merged,
|
|
37394
37539
|
seedProvenance,
|
|
37395
37540
|
seedUsageCount
|
|
37396
37541
|
};
|
|
@@ -37408,6 +37553,38 @@ function federationHint(status) {
|
|
|
37408
37553
|
function hasCloudNodeShape(id) {
|
|
37409
37554
|
return CANONICAL_KNOWLEDGE_ID.test(id) || UUID_ID.test(id) || id.startsWith("pkg:");
|
|
37410
37555
|
}
|
|
37556
|
+
function safeCollectiveId(id) {
|
|
37557
|
+
if (typeof id !== "string") return false;
|
|
37558
|
+
const separator = id.indexOf("_");
|
|
37559
|
+
return id.length > 0 && id.trim() === id && !/[\u0000-\u001f\u007f,]/.test(id) && !(separator > 0 && isCodeLabel(id.slice(0, separator)));
|
|
37560
|
+
}
|
|
37561
|
+
function rememberCollectiveIds(cloud, ids) {
|
|
37562
|
+
const now = Date.now();
|
|
37563
|
+
let remembered = returnedCollectiveIds.get(cloud);
|
|
37564
|
+
if (!remembered) {
|
|
37565
|
+
remembered = /* @__PURE__ */ new Map();
|
|
37566
|
+
returnedCollectiveIds.set(cloud, remembered);
|
|
37567
|
+
}
|
|
37568
|
+
for (const [id, expiresAt] of remembered) if (expiresAt <= now) remembered.delete(id);
|
|
37569
|
+
for (const id of ids) {
|
|
37570
|
+
if (!safeCollectiveId(id) || id.length > 160) continue;
|
|
37571
|
+
remembered.delete(id);
|
|
37572
|
+
remembered.set(id, now + COLLECTIVE_ID_TTL_MS);
|
|
37573
|
+
if (remembered.size > COLLECTIVE_ID_LIMIT) remembered.delete(remembered.keys().next().value);
|
|
37574
|
+
}
|
|
37575
|
+
}
|
|
37576
|
+
function canFollowCollectiveId(cloud, id) {
|
|
37577
|
+
if (!safeCollectiveId(id)) return false;
|
|
37578
|
+
if (hasCloudNodeShape(id)) return true;
|
|
37579
|
+
const remembered = returnedCollectiveIds.get(cloud);
|
|
37580
|
+
const expiresAt = remembered?.get(id);
|
|
37581
|
+
if (expiresAt === void 0) return false;
|
|
37582
|
+
if (expiresAt <= Date.now()) {
|
|
37583
|
+
remembered.delete(id);
|
|
37584
|
+
return false;
|
|
37585
|
+
}
|
|
37586
|
+
return true;
|
|
37587
|
+
}
|
|
37411
37588
|
function attrsCommunity(attrs) {
|
|
37412
37589
|
const id = attrs?.["community"];
|
|
37413
37590
|
if (typeof id !== "number") return void 0;
|
|
@@ -37447,7 +37624,7 @@ async function collectiveDrilldown(cloud, seedId, limit, opts = {}) {
|
|
|
37447
37624
|
if (resolution === "unresolved") return { status: "no-twin" };
|
|
37448
37625
|
if (resolution === "error") return { status: "seed-error" };
|
|
37449
37626
|
if (res.nodes.length === 0 && resolution !== "resolved") return { status: "no-twin" };
|
|
37450
|
-
|
|
37627
|
+
const resolved = {
|
|
37451
37628
|
status: "resolved",
|
|
37452
37629
|
neighborhood: {
|
|
37453
37630
|
seed: seedId,
|
|
@@ -37474,6 +37651,10 @@ async function collectiveDrilldown(cloud, seedId, limit, opts = {}) {
|
|
|
37474
37651
|
...seedEntry?.bridges ? { bridges: seedEntry.bridges } : {}
|
|
37475
37652
|
}
|
|
37476
37653
|
};
|
|
37654
|
+
if (!res.seeds?.some((seed) => seed.status === "error")) {
|
|
37655
|
+
rememberCollectiveIds(cloud, resolved.neighborhood.nodes.filter((node2) => node2.id !== seedId && !isCodeLabel(node2.label)).map((node2) => node2.id));
|
|
37656
|
+
}
|
|
37657
|
+
return resolved;
|
|
37477
37658
|
}
|
|
37478
37659
|
async function collectiveNodeDetail(cloud, id) {
|
|
37479
37660
|
const read2 = async (nodeId) => {
|
|
@@ -37550,7 +37731,7 @@ function formatDualNodes(merged) {
|
|
|
37550
37731
|
...n.uploaded ? { uploaded: true } : {}
|
|
37551
37732
|
}));
|
|
37552
37733
|
}
|
|
37553
|
-
var BRIDGE_LABELS, CANONICAL_KNOWLEDGE_ID, UUID_ID;
|
|
37734
|
+
var BRIDGE_LABELS, CANONICAL_KNOWLEDGE_ID, UUID_ID, COLLECTIVE_ID_LIMIT, COLLECTIVE_ID_TTL_MS, returnedCollectiveIds;
|
|
37554
37735
|
var init_dual_augment = __esm({
|
|
37555
37736
|
"src/dual-augment.ts"() {
|
|
37556
37737
|
"use strict";
|
|
@@ -37561,6 +37742,9 @@ var init_dual_augment = __esm({
|
|
|
37561
37742
|
BRIDGE_LABELS = new Set(SEMANTIC_NODE_LABELS);
|
|
37562
37743
|
CANONICAL_KNOWLEDGE_ID = /^[a-z][a-z0-9]*_[0-9a-f]{8,}$/;
|
|
37563
37744
|
UUID_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
37745
|
+
COLLECTIVE_ID_LIMIT = 512;
|
|
37746
|
+
COLLECTIVE_ID_TTL_MS = 15 * 6e4;
|
|
37747
|
+
returnedCollectiveIds = /* @__PURE__ */ new WeakMap();
|
|
37564
37748
|
}
|
|
37565
37749
|
});
|
|
37566
37750
|
|
|
@@ -46957,7 +47141,7 @@ function cosine3(a, b) {
|
|
|
46957
47141
|
}
|
|
46958
47142
|
async function collectiveSeedFallback(args2, ctx, defaultLimit, opts = {}) {
|
|
46959
47143
|
const seedId = typeof args2["nodeId"] === "string" ? args2["nodeId"] : null;
|
|
46960
|
-
if (!seedId || !ctx.cloud || !
|
|
47144
|
+
if (!seedId || !ctx.cloud || !canFollowCollectiveId(ctx.cloud, seedId)) return null;
|
|
46961
47145
|
const limit = Math.max(1, Math.min(100, Number(args2["limit"] ?? defaultLimit)));
|
|
46962
47146
|
const scope = args2["scope"];
|
|
46963
47147
|
return collectiveDrilldown(ctx.cloud, seedId, limit, {
|
|
@@ -48051,7 +48235,7 @@ var init_mcp = __esm({
|
|
|
48051
48235
|
const id = resolveSymbol2(store, args2);
|
|
48052
48236
|
if (!id) {
|
|
48053
48237
|
const seedId = typeof args2["nodeId"] === "string" ? args2["nodeId"] : null;
|
|
48054
|
-
if (!seedId || !ctx.cloud || !
|
|
48238
|
+
if (!seedId || !ctx.cloud || !canFollowCollectiveId(ctx.cloud, seedId)) return unresolved(args2);
|
|
48055
48239
|
const shown = await collectiveNodeDetail(ctx.cloud, seedId);
|
|
48056
48240
|
if (shown.status !== "found") return collectiveSeedMiss(args2, shown);
|
|
48057
48241
|
return {
|
|
@@ -76634,8 +76818,8 @@ var init_report_render = __esm({
|
|
|
76634
76818
|
|
|
76635
76819
|
// src/cli.ts
|
|
76636
76820
|
init_src6();
|
|
76637
|
-
import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as
|
|
76638
|
-
import { join as
|
|
76821
|
+
import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as readFileSync44, renameSync as renameSync9, statSync as statSync13 } from "node:fs";
|
|
76822
|
+
import { join as join51, resolve as pathResolve2 } from "node:path";
|
|
76639
76823
|
import { spawn as spawn5 } from "node:child_process";
|
|
76640
76824
|
|
|
76641
76825
|
// src/daemon.ts
|
|
@@ -78100,9 +78284,9 @@ var NodeFsHandler = class {
|
|
|
78100
78284
|
if (this.fsw.closed) {
|
|
78101
78285
|
return;
|
|
78102
78286
|
}
|
|
78103
|
-
const
|
|
78287
|
+
const dirname19 = sysPath.dirname(file2);
|
|
78104
78288
|
const basename10 = sysPath.basename(file2);
|
|
78105
|
-
const parent = this.fsw._getWatchedDir(
|
|
78289
|
+
const parent = this.fsw._getWatchedDir(dirname19);
|
|
78106
78290
|
let prevStats = stats;
|
|
78107
78291
|
if (parent.has(basename10))
|
|
78108
78292
|
return;
|
|
@@ -78129,7 +78313,7 @@ var NodeFsHandler = class {
|
|
|
78129
78313
|
prevStats = newStats2;
|
|
78130
78314
|
}
|
|
78131
78315
|
} catch (error48) {
|
|
78132
|
-
this.fsw._remove(
|
|
78316
|
+
this.fsw._remove(dirname19, basename10);
|
|
78133
78317
|
}
|
|
78134
78318
|
} else if (parent.has(basename10)) {
|
|
78135
78319
|
const at = newStats.atimeMs;
|
|
@@ -86043,7 +86227,7 @@ function createWatchBreaker(deps) {
|
|
|
86043
86227
|
}
|
|
86044
86228
|
|
|
86045
86229
|
// src/engine.ts
|
|
86046
|
-
var DAEMON_VERSION = true ? "2.0.22-dev.
|
|
86230
|
+
var DAEMON_VERSION = true ? "2.0.22-dev.4277" : "2.0.0-alpha.0";
|
|
86047
86231
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
86048
86232
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
86049
86233
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -88564,7 +88748,12 @@ B: ${b}`,
|
|
|
88564
88748
|
standing: fj.standing,
|
|
88565
88749
|
judgeErrors: fj.judgeErrors,
|
|
88566
88750
|
retargeted: fj.retargeted,
|
|
88567
|
-
judgeConfigured: foldJudge ? 1 : 0
|
|
88751
|
+
judgeConfigured: foldJudge ? 1 : 0,
|
|
88752
|
+
pending: fj.pending,
|
|
88753
|
+
neverExamined: fj.neverExamined,
|
|
88754
|
+
firstExamined: fj.firstExamined,
|
|
88755
|
+
waiting: fj.waiting,
|
|
88756
|
+
judgeBudgetDeferred: fj.judgeBudgetDeferred
|
|
88568
88757
|
});
|
|
88569
88758
|
if (fj.folded > 0) {
|
|
88570
88759
|
console.log(`[errata] fold-judge: folded ${fj.folded} paraphrase pair(s) (${fj.foldedEmbedding} by embedding, ${fj.foldedJudge} by judge), ${fj.standing} standing`);
|
|
@@ -89028,6 +89217,212 @@ async function linkRegisteredWorkspaces(cfg, loggedInProfile = cfg.activeInstall
|
|
|
89028
89217
|
}
|
|
89029
89218
|
}
|
|
89030
89219
|
|
|
89220
|
+
// src/edge-park.ts
|
|
89221
|
+
import { readFileSync as readFileSync33, renameSync as renameSync5, writeFileSync as writeFileSync25 } from "node:fs";
|
|
89222
|
+
import { dirname as dirname13, join as join36 } from "node:path";
|
|
89223
|
+
var EDGE_PARK_CAP = 2e3;
|
|
89224
|
+
var EDGE_PARK_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
89225
|
+
var EDGE_PARK_MAX_ATTEMPTS = 6;
|
|
89226
|
+
var EDGE_RETRY_BASE_MS = 30 * 60 * 1e3;
|
|
89227
|
+
var EDGE_RETRY_MAX_MS = 12 * 60 * 60 * 1e3;
|
|
89228
|
+
var EDGE_TOMBSTONE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
89229
|
+
var EDGE_EXHAUSTED_TOMBSTONE_TTL_MS = 3 * 24 * 60 * 60 * 1e3;
|
|
89230
|
+
function tombstoneTtl(e) {
|
|
89231
|
+
return e.dropReason === "refused" ? EDGE_TOMBSTONE_TTL_MS : EDGE_EXHAUSTED_TOMBSTONE_TTL_MS;
|
|
89232
|
+
}
|
|
89233
|
+
function wireEdgeKey(from, type, to) {
|
|
89234
|
+
return JSON.stringify([from, type, to]);
|
|
89235
|
+
}
|
|
89236
|
+
function edgeParkPath(workspaceConfigDir, destinationKey) {
|
|
89237
|
+
return join36(workspaceConfigDir, `edge-park.${destinationKey.slice(0, 16)}.json`);
|
|
89238
|
+
}
|
|
89239
|
+
function loadEdgePark(path3) {
|
|
89240
|
+
let raw2;
|
|
89241
|
+
try {
|
|
89242
|
+
raw2 = JSON.parse(readFileSync33(path3, "utf8"));
|
|
89243
|
+
} catch {
|
|
89244
|
+
return [];
|
|
89245
|
+
}
|
|
89246
|
+
if (!Array.isArray(raw2)) return [];
|
|
89247
|
+
return raw2.filter(
|
|
89248
|
+
(e) => !!e && typeof e === "object" && typeof e.key === "string" && typeof e.from === "string" && typeof e.to === "string" && typeof e.type === "string" && (e.state === "parked" || e.state === "dropped")
|
|
89249
|
+
);
|
|
89250
|
+
}
|
|
89251
|
+
function saveEdgePark(path3, queue) {
|
|
89252
|
+
try {
|
|
89253
|
+
const tmp = join36(dirname13(path3), `.${Date.now()}.edge-park.tmp`);
|
|
89254
|
+
writeFileSync25(tmp, JSON.stringify(queue), "utf8");
|
|
89255
|
+
renameSync5(tmp, path3);
|
|
89256
|
+
} catch {
|
|
89257
|
+
}
|
|
89258
|
+
}
|
|
89259
|
+
function edgeHolds(queue, now) {
|
|
89260
|
+
const holds = {};
|
|
89261
|
+
for (const e of queue) {
|
|
89262
|
+
if (e.state === "dropped") {
|
|
89263
|
+
if (now - (e.droppedAt ?? e.ts) < tombstoneTtl(e)) holds[e.key] = "dropped";
|
|
89264
|
+
} else if (e.dueAt > now) {
|
|
89265
|
+
holds[e.key] = "held";
|
|
89266
|
+
}
|
|
89267
|
+
}
|
|
89268
|
+
return holds;
|
|
89269
|
+
}
|
|
89270
|
+
function classifyEdgeVerdict(decision, reason) {
|
|
89271
|
+
if (decision === "created" || decision === "reinforced") return "landed";
|
|
89272
|
+
const why = reason ?? "";
|
|
89273
|
+
if (/^unresolved endpoint\b/.test(why) || /^endpoint did not land this drain\b/.test(why) || /\bretry\b/i.test(why)) {
|
|
89274
|
+
return "park";
|
|
89275
|
+
}
|
|
89276
|
+
return "drop";
|
|
89277
|
+
}
|
|
89278
|
+
function matchEdgeVerdicts(sent, received, echo) {
|
|
89279
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
89280
|
+
for (const r of received) {
|
|
89281
|
+
const k = wireEdgeKey(r.from, r.type, r.to);
|
|
89282
|
+
if (!byKey.has(k) || r.decision === "rejected") byKey.set(k, { decision: r.decision, reason: r.reason });
|
|
89283
|
+
}
|
|
89284
|
+
const out2 = /* @__PURE__ */ new Map();
|
|
89285
|
+
for (const e of sent) {
|
|
89286
|
+
const v = byKey.get(wireEdgeKey(echo.get(e.from) ?? e.from, e.type, echo.get(e.to) ?? e.to)) ?? byKey.get(wireEdgeKey(e.from, e.type, e.to));
|
|
89287
|
+
if (v) out2.set(e.id, v);
|
|
89288
|
+
}
|
|
89289
|
+
return out2;
|
|
89290
|
+
}
|
|
89291
|
+
function zeroEdgeSettleCounts(queue) {
|
|
89292
|
+
const parked = queue.filter((e) => e.state === "parked").length;
|
|
89293
|
+
return {
|
|
89294
|
+
edgesSent: 0,
|
|
89295
|
+
edgesLanded: 0,
|
|
89296
|
+
edgesReplayLanded: 0,
|
|
89297
|
+
edgesReplayed: 0,
|
|
89298
|
+
edgesParked: 0,
|
|
89299
|
+
edgesReparked: 0,
|
|
89300
|
+
edgesDroppedRefused: 0,
|
|
89301
|
+
edgesDroppedExhausted: 0,
|
|
89302
|
+
edgesDroppedExpired: 0,
|
|
89303
|
+
edgesDroppedCapped: 0,
|
|
89304
|
+
edgesNoVerdict: 0,
|
|
89305
|
+
edgeParkSize: parked,
|
|
89306
|
+
edgeTombstones: queue.length - parked
|
|
89307
|
+
};
|
|
89308
|
+
}
|
|
89309
|
+
function backoff(attempts) {
|
|
89310
|
+
return Math.min(EDGE_RETRY_MAX_MS, EDGE_RETRY_BASE_MS * 2 ** Math.max(0, attempts - 1));
|
|
89311
|
+
}
|
|
89312
|
+
function settleEdgeOutcomes(queue, sent, verdicts, now) {
|
|
89313
|
+
const counts = {
|
|
89314
|
+
edgesSent: sent.length,
|
|
89315
|
+
edgesLanded: 0,
|
|
89316
|
+
edgesReplayLanded: 0,
|
|
89317
|
+
edgesReplayed: 0,
|
|
89318
|
+
edgesParked: 0,
|
|
89319
|
+
edgesReparked: 0,
|
|
89320
|
+
edgesDroppedRefused: 0,
|
|
89321
|
+
edgesDroppedExhausted: 0,
|
|
89322
|
+
edgesDroppedExpired: 0,
|
|
89323
|
+
edgesDroppedCapped: 0,
|
|
89324
|
+
edgesNoVerdict: 0,
|
|
89325
|
+
edgeParkSize: 0,
|
|
89326
|
+
edgeTombstones: 0
|
|
89327
|
+
};
|
|
89328
|
+
const byKey = new Map(queue.map((e) => [e.key, { ...e }]));
|
|
89329
|
+
const seen = /* @__PURE__ */ new Set();
|
|
89330
|
+
for (const e of sent) {
|
|
89331
|
+
const key = e.id;
|
|
89332
|
+
if (seen.has(key)) continue;
|
|
89333
|
+
seen.add(key);
|
|
89334
|
+
const prior = byKey.get(key);
|
|
89335
|
+
if (prior?.state === "parked") counts.edgesReplayed++;
|
|
89336
|
+
const v = verdicts.get(key);
|
|
89337
|
+
if (!v) {
|
|
89338
|
+
counts.edgesNoVerdict++;
|
|
89339
|
+
continue;
|
|
89340
|
+
}
|
|
89341
|
+
const disposition = classifyEdgeVerdict(v.decision, v.reason);
|
|
89342
|
+
if (disposition === "landed") {
|
|
89343
|
+
counts.edgesLanded++;
|
|
89344
|
+
if (prior) {
|
|
89345
|
+
byKey.delete(key);
|
|
89346
|
+
if (prior.state === "parked") counts.edgesReplayLanded++;
|
|
89347
|
+
}
|
|
89348
|
+
continue;
|
|
89349
|
+
}
|
|
89350
|
+
const reason = v.reason ?? "rejected";
|
|
89351
|
+
if (prior?.state === "dropped") continue;
|
|
89352
|
+
if (disposition === "drop") {
|
|
89353
|
+
byKey.set(key, {
|
|
89354
|
+
key,
|
|
89355
|
+
from: e.from,
|
|
89356
|
+
type: e.type,
|
|
89357
|
+
to: e.to,
|
|
89358
|
+
ts: prior?.ts ?? now,
|
|
89359
|
+
attempts: (prior?.attempts ?? 0) + 1,
|
|
89360
|
+
lastReason: reason,
|
|
89361
|
+
dueAt: now,
|
|
89362
|
+
state: "dropped",
|
|
89363
|
+
dropReason: "refused",
|
|
89364
|
+
droppedAt: now
|
|
89365
|
+
});
|
|
89366
|
+
counts.edgesDroppedRefused++;
|
|
89367
|
+
continue;
|
|
89368
|
+
}
|
|
89369
|
+
const attempts = (prior?.state === "parked" ? prior.attempts : 0) + 1;
|
|
89370
|
+
const ts = prior?.state === "parked" ? prior.ts : now;
|
|
89371
|
+
if (attempts >= EDGE_PARK_MAX_ATTEMPTS || now - ts >= EDGE_PARK_TTL_MS) {
|
|
89372
|
+
const why = attempts >= EDGE_PARK_MAX_ATTEMPTS ? "exhausted" : "expired";
|
|
89373
|
+
byKey.set(key, {
|
|
89374
|
+
key,
|
|
89375
|
+
from: e.from,
|
|
89376
|
+
type: e.type,
|
|
89377
|
+
to: e.to,
|
|
89378
|
+
ts,
|
|
89379
|
+
attempts,
|
|
89380
|
+
lastReason: reason,
|
|
89381
|
+
dueAt: now,
|
|
89382
|
+
state: "dropped",
|
|
89383
|
+
dropReason: why,
|
|
89384
|
+
droppedAt: now
|
|
89385
|
+
});
|
|
89386
|
+
if (why === "exhausted") counts.edgesDroppedExhausted++;
|
|
89387
|
+
else counts.edgesDroppedExpired++;
|
|
89388
|
+
continue;
|
|
89389
|
+
}
|
|
89390
|
+
byKey.set(key, {
|
|
89391
|
+
key,
|
|
89392
|
+
from: e.from,
|
|
89393
|
+
type: e.type,
|
|
89394
|
+
to: e.to,
|
|
89395
|
+
ts,
|
|
89396
|
+
attempts,
|
|
89397
|
+
lastReason: reason,
|
|
89398
|
+
dueAt: now + backoff(attempts),
|
|
89399
|
+
state: "parked"
|
|
89400
|
+
});
|
|
89401
|
+
if (prior?.state === "parked") counts.edgesReparked++;
|
|
89402
|
+
else counts.edgesParked++;
|
|
89403
|
+
}
|
|
89404
|
+
const live3 = [];
|
|
89405
|
+
for (const e of byKey.values()) {
|
|
89406
|
+
if (e.state === "parked" && now - e.ts >= EDGE_PARK_TTL_MS) {
|
|
89407
|
+
counts.edgesDroppedExpired++;
|
|
89408
|
+
continue;
|
|
89409
|
+
}
|
|
89410
|
+
if (e.state === "dropped" && now - (e.droppedAt ?? e.ts) >= tombstoneTtl(e)) continue;
|
|
89411
|
+
live3.push(e);
|
|
89412
|
+
}
|
|
89413
|
+
let next = live3;
|
|
89414
|
+
if (next.length > EDGE_PARK_CAP) {
|
|
89415
|
+
const over = next.length - EDGE_PARK_CAP;
|
|
89416
|
+
const order = [...next].sort((a, b) => (a.state === b.state ? 0 : a.state === "dropped" ? -1 : 1) || a.ts - b.ts);
|
|
89417
|
+
const evict = new Set(order.slice(0, over).map((e) => e.key));
|
|
89418
|
+
counts.edgesDroppedCapped = order.slice(0, over).filter((e) => e.state === "parked").length;
|
|
89419
|
+
next = next.filter((e) => !evict.has(e.key));
|
|
89420
|
+
}
|
|
89421
|
+
counts.edgeParkSize = next.filter((e) => e.state === "parked").length;
|
|
89422
|
+
counts.edgeTombstones = next.length - counts.edgeParkSize;
|
|
89423
|
+
return { queue: next, counts };
|
|
89424
|
+
}
|
|
89425
|
+
|
|
89031
89426
|
// src/instance-receipts.ts
|
|
89032
89427
|
import { createHash as createHash18 } from "node:crypto";
|
|
89033
89428
|
var INSTANCE_SEMANTIC_EDGE_TYPES = ["CAUSED_BY", "SOLVED_BY"];
|
|
@@ -89169,7 +89564,7 @@ function invalidateInstanceReceipt(current, destination, failedId, mirrorLegacy)
|
|
|
89169
89564
|
// src/multi.ts
|
|
89170
89565
|
init_dist();
|
|
89171
89566
|
init_src5();
|
|
89172
|
-
import { existsSync as existsSync34, writeFileSync as
|
|
89567
|
+
import { existsSync as existsSync34, writeFileSync as writeFileSync28 } from "node:fs";
|
|
89173
89568
|
import { resolve as pathResolve } from "node:path";
|
|
89174
89569
|
|
|
89175
89570
|
// src/principle-sync.ts
|
|
@@ -89198,8 +89593,8 @@ init_reconcile();
|
|
|
89198
89593
|
|
|
89199
89594
|
// src/lockfile-auto.ts
|
|
89200
89595
|
init_src();
|
|
89201
|
-
import { existsSync as existsSync30, readFileSync as
|
|
89202
|
-
import { join as
|
|
89596
|
+
import { existsSync as existsSync30, readFileSync as readFileSync34 } from "node:fs";
|
|
89597
|
+
import { join as join37 } from "node:path";
|
|
89203
89598
|
|
|
89204
89599
|
// src/package-index.ts
|
|
89205
89600
|
init_src();
|
|
@@ -89351,11 +89746,11 @@ function runLockfilePass(opts) {
|
|
|
89351
89746
|
{ file: "package-lock.json", parse: parsePackageLockJson }
|
|
89352
89747
|
];
|
|
89353
89748
|
for (const c of candidates) {
|
|
89354
|
-
const p =
|
|
89749
|
+
const p = join37(opts.root, c.file);
|
|
89355
89750
|
if (!existsSync30(p)) continue;
|
|
89356
89751
|
let sbom;
|
|
89357
89752
|
try {
|
|
89358
|
-
sbom = c.parse(
|
|
89753
|
+
sbom = c.parse(readFileSync34(p, "utf8"));
|
|
89359
89754
|
} catch {
|
|
89360
89755
|
continue;
|
|
89361
89756
|
}
|
|
@@ -89416,8 +89811,8 @@ init_profile2();
|
|
|
89416
89811
|
init_session_registry();
|
|
89417
89812
|
|
|
89418
89813
|
// src/public-symbols.ts
|
|
89419
|
-
import { readFileSync as
|
|
89420
|
-
import { join as
|
|
89814
|
+
import { readFileSync as readFileSync35, readdirSync as readdirSync12, existsSync as existsSync31 } from "node:fs";
|
|
89815
|
+
import { join as join38 } from "node:path";
|
|
89421
89816
|
var HEAD_BYTES = 8 * 1024;
|
|
89422
89817
|
var INDEX_TTL_MS = 10 * 60 * 1e3;
|
|
89423
89818
|
var MIN_SYMBOL_LEN = 4;
|
|
@@ -89450,20 +89845,20 @@ function bindingNames(clause) {
|
|
|
89450
89845
|
function internalPackageNames(workspaceRoot) {
|
|
89451
89846
|
const names = /* @__PURE__ */ new Set();
|
|
89452
89847
|
const tryRead = (dir) => {
|
|
89453
|
-
const pj =
|
|
89848
|
+
const pj = join38(dir, "package.json");
|
|
89454
89849
|
if (!existsSync31(pj)) return;
|
|
89455
89850
|
try {
|
|
89456
|
-
const name2 = JSON.parse(
|
|
89851
|
+
const name2 = JSON.parse(readFileSync35(pj, "utf8")).name;
|
|
89457
89852
|
if (typeof name2 === "string" && name2.length > 0) names.add(name2);
|
|
89458
89853
|
} catch {
|
|
89459
89854
|
}
|
|
89460
89855
|
};
|
|
89461
89856
|
tryRead(workspaceRoot);
|
|
89462
89857
|
for (const group of ["packages", "apps"]) {
|
|
89463
|
-
const groupDir =
|
|
89858
|
+
const groupDir = join38(workspaceRoot, group);
|
|
89464
89859
|
if (!existsSync31(groupDir)) continue;
|
|
89465
89860
|
try {
|
|
89466
|
-
for (const entry of readdirSync12(groupDir)) tryRead(
|
|
89861
|
+
for (const entry of readdirSync12(groupDir)) tryRead(join38(groupDir, entry));
|
|
89467
89862
|
} catch {
|
|
89468
89863
|
}
|
|
89469
89864
|
}
|
|
@@ -89482,7 +89877,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
|
|
|
89482
89877
|
}
|
|
89483
89878
|
const readHead = deps.readHead ?? ((absPath) => {
|
|
89484
89879
|
try {
|
|
89485
|
-
return
|
|
89880
|
+
return readFileSync35(absPath, "utf8").slice(0, HEAD_BYTES);
|
|
89486
89881
|
} catch {
|
|
89487
89882
|
return "";
|
|
89488
89883
|
}
|
|
@@ -89502,7 +89897,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
|
|
|
89502
89897
|
}
|
|
89503
89898
|
const symbols = /* @__PURE__ */ new Set();
|
|
89504
89899
|
for (const rel of files) {
|
|
89505
|
-
const head2 = readHead(
|
|
89900
|
+
const head2 = readHead(join38(workspaceRoot, rel));
|
|
89506
89901
|
if (!head2) continue;
|
|
89507
89902
|
for (const re of [NAMED_IMPORT_RE, REQUIRE_RE]) {
|
|
89508
89903
|
re.lastIndex = 0;
|
|
@@ -89727,7 +90122,9 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
89727
90122
|
sidecarNoSummary: 0,
|
|
89728
90123
|
fileRefsSubstituted: 0,
|
|
89729
90124
|
fileRefLexiconMisses: 0,
|
|
89730
|
-
collapsedEdges: 0
|
|
90125
|
+
collapsedEdges: 0,
|
|
90126
|
+
edgesHeldParked: 0,
|
|
90127
|
+
edgesHeldDropped: 0
|
|
89731
90128
|
};
|
|
89732
90129
|
const sharedCauses = /* @__PURE__ */ new Map();
|
|
89733
90130
|
const causalQueue = store.findNodeFieldsByLabel("Problem", ["source", "resolvedAs"]).filter((r) => r.attrs["source"] !== "cloud" && r.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE).map((r) => r.id).filter((id) => ignorePatterns.length === 0 || !ignored(store.getNode(id)?.description ?? ""));
|
|
@@ -90038,6 +90435,30 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
90038
90435
|
if (count > 0) symbolSummaries = sidecar;
|
|
90039
90436
|
}
|
|
90040
90437
|
edges.push(...anchorEdges);
|
|
90438
|
+
if (opts.edgeHolds && Object.keys(opts.edgeHolds).length > 0) {
|
|
90439
|
+
const holds = opts.edgeHolds;
|
|
90440
|
+
const shipsHere = (wireId) => (endpointSources[wireId] ?? [wireId]).some((localId) => shippedById.has(localId));
|
|
90441
|
+
const kept = [];
|
|
90442
|
+
for (const e of edges) {
|
|
90443
|
+
const hold = holds[e.id];
|
|
90444
|
+
if (!hold || hold === "held" && (shipsHere(e.from) || shipsHere(e.to))) {
|
|
90445
|
+
kept.push(e);
|
|
90446
|
+
continue;
|
|
90447
|
+
}
|
|
90448
|
+
if (hold === "held") {
|
|
90449
|
+
composition.edgesHeldParked++;
|
|
90450
|
+
for (const localId of endpointSources[e.from] ?? [e.from]) {
|
|
90451
|
+
delete anchorDigests[localId];
|
|
90452
|
+
delete semanticEdgeDigests[localId];
|
|
90453
|
+
delete projectAnchorDigests[localId];
|
|
90454
|
+
}
|
|
90455
|
+
} else {
|
|
90456
|
+
composition.edgesHeldDropped++;
|
|
90457
|
+
}
|
|
90458
|
+
}
|
|
90459
|
+
edges.length = 0;
|
|
90460
|
+
edges.push(...kept);
|
|
90461
|
+
}
|
|
90041
90462
|
const bindingEndpoints = /* @__PURE__ */ new Set();
|
|
90042
90463
|
for (const e of edges) {
|
|
90043
90464
|
if (e.type === "CAUSED_BY" || e.type === "SOLVED_BY") {
|
|
@@ -90203,7 +90624,8 @@ function buildDrainInstances(store, sharedStore, input) {
|
|
|
90203
90624
|
...lexicon ? { lexicon } : {},
|
|
90204
90625
|
...fileLexicon ? { fileLexicon } : {},
|
|
90205
90626
|
...input.project ? { project: input.project } : {},
|
|
90206
|
-
...input.quarantinedSessions?.length ? { quarantinedSessions: input.quarantinedSessions } : {}
|
|
90627
|
+
...input.quarantinedSessions?.length ? { quarantinedSessions: input.quarantinedSessions } : {},
|
|
90628
|
+
...input.edgeHolds ? { edgeHolds: input.edgeHolds } : {}
|
|
90207
90629
|
});
|
|
90208
90630
|
return {
|
|
90209
90631
|
batch,
|
|
@@ -90460,7 +90882,7 @@ init_config();
|
|
|
90460
90882
|
|
|
90461
90883
|
// src/update.ts
|
|
90462
90884
|
import { spawn as spawn2 } from "node:child_process";
|
|
90463
|
-
import { isAbsolute as isAbsolute6, join as
|
|
90885
|
+
import { isAbsolute as isAbsolute6, join as join39 } from "node:path";
|
|
90464
90886
|
var PACKAGE_NAME = "@inerrata-corporation/errata";
|
|
90465
90887
|
function parse3(v) {
|
|
90466
90888
|
const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z][0-9A-Za-z.-]*))?/.exec(v.trim());
|
|
@@ -90607,7 +91029,7 @@ async function runInstalledHookRefresh() {
|
|
|
90607
91029
|
});
|
|
90608
91030
|
if (!isAbsolute6(root)) return 1;
|
|
90609
91031
|
return new Promise((resolve10) => {
|
|
90610
|
-
const child = spawn2(process.execPath, [
|
|
91032
|
+
const child = spawn2(process.execPath, [join39(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
|
|
90611
91033
|
windowsHide: true,
|
|
90612
91034
|
stdio: "inherit",
|
|
90613
91035
|
timeout: 3e4
|
|
@@ -90753,12 +91175,12 @@ function landCloudEdge(store, e, from, to) {
|
|
|
90753
91175
|
}
|
|
90754
91176
|
|
|
90755
91177
|
// src/causal-edge-queue.ts
|
|
90756
|
-
import { readFileSync as
|
|
90757
|
-
import { dirname as
|
|
91178
|
+
import { readFileSync as readFileSync36, renameSync as renameSync6, writeFileSync as writeFileSync26 } from "node:fs";
|
|
91179
|
+
import { dirname as dirname14, join as join40 } from "node:path";
|
|
90758
91180
|
var CAUSAL_EDGE_QUEUE_CAP = 5e3;
|
|
90759
91181
|
var CAUSAL_EDGE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
90760
91182
|
function causalEdgeQueuePath(workspaceConfigDir) {
|
|
90761
|
-
return
|
|
91183
|
+
return join40(workspaceConfigDir, "causal-edge-queue.json");
|
|
90762
91184
|
}
|
|
90763
91185
|
function parkedEdgeKey(e) {
|
|
90764
91186
|
return `${e.from}|${e.type}|${e.to}`;
|
|
@@ -90766,7 +91188,7 @@ function parkedEdgeKey(e) {
|
|
|
90766
91188
|
function loadCausalEdgeQueue(path3) {
|
|
90767
91189
|
let raw2;
|
|
90768
91190
|
try {
|
|
90769
|
-
raw2 = JSON.parse(
|
|
91191
|
+
raw2 = JSON.parse(readFileSync36(path3, "utf8"));
|
|
90770
91192
|
} catch {
|
|
90771
91193
|
return [];
|
|
90772
91194
|
}
|
|
@@ -90777,9 +91199,9 @@ function loadCausalEdgeQueue(path3) {
|
|
|
90777
91199
|
}
|
|
90778
91200
|
function saveCausalEdgeQueue(path3, queue) {
|
|
90779
91201
|
try {
|
|
90780
|
-
const tmp =
|
|
90781
|
-
|
|
90782
|
-
|
|
91202
|
+
const tmp = join40(dirname14(path3), `.${Date.now()}.causal-edge-queue.tmp`);
|
|
91203
|
+
writeFileSync26(tmp, JSON.stringify(queue), "utf8");
|
|
91204
|
+
renameSync6(tmp, path3);
|
|
90783
91205
|
} catch {
|
|
90784
91206
|
}
|
|
90785
91207
|
}
|
|
@@ -91450,8 +91872,8 @@ async function syncHistoryRevisionPage(opts) {
|
|
|
91450
91872
|
init_src7();
|
|
91451
91873
|
init_src();
|
|
91452
91874
|
import { execFile as execFile6 } from "node:child_process";
|
|
91453
|
-
import { readFileSync as
|
|
91454
|
-
import { join as
|
|
91875
|
+
import { readFileSync as readFileSync37 } from "node:fs";
|
|
91876
|
+
import { join as join41 } from "node:path";
|
|
91455
91877
|
import { promisify as promisify5 } from "node:util";
|
|
91456
91878
|
|
|
91457
91879
|
// src/history-walk.ts
|
|
@@ -92003,7 +92425,7 @@ async function defaultGit(root, args2) {
|
|
|
92003
92425
|
function readIgnoreLines(root, profile) {
|
|
92004
92426
|
let lines = [];
|
|
92005
92427
|
try {
|
|
92006
|
-
lines =
|
|
92428
|
+
lines = readFileSync37(join41(root, ".errataignore"), "utf8").split("\n");
|
|
92007
92429
|
} catch {
|
|
92008
92430
|
}
|
|
92009
92431
|
return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
@@ -92579,8 +93001,8 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
|
|
|
92579
93001
|
init_cloud_auth();
|
|
92580
93002
|
import { createHash as createHash19 } from "node:crypto";
|
|
92581
93003
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
92582
|
-
import { existsSync as existsSync32, writeFileSync as
|
|
92583
|
-
import { join as
|
|
93004
|
+
import { existsSync as existsSync32, writeFileSync as writeFileSync27 } from "node:fs";
|
|
93005
|
+
import { join as join42 } from "node:path";
|
|
92584
93006
|
|
|
92585
93007
|
// src/device-poll.ts
|
|
92586
93008
|
var THROTTLED_POLL_MIN_WAIT_MS = 11e3;
|
|
@@ -93039,9 +93461,9 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
|
|
|
93039
93461
|
delete nextProfile.projectLinkHold;
|
|
93040
93462
|
let wroteIgnore = false;
|
|
93041
93463
|
if (decision.writeIgnoreStarter !== false) {
|
|
93042
|
-
const target =
|
|
93464
|
+
const target = join42(root, ".errataignore");
|
|
93043
93465
|
if (!existsSync32(target)) {
|
|
93044
|
-
|
|
93466
|
+
writeFileSync27(target, IGNORE_STARTER, "utf8");
|
|
93045
93467
|
wroteIgnore = true;
|
|
93046
93468
|
}
|
|
93047
93469
|
}
|
|
@@ -93055,12 +93477,12 @@ init_registry();
|
|
|
93055
93477
|
// src/adopt.ts
|
|
93056
93478
|
init_git_remote();
|
|
93057
93479
|
import { existsSync as existsSync33 } from "node:fs";
|
|
93058
|
-
import { dirname as
|
|
93480
|
+
import { dirname as dirname15, join as join43 } from "node:path";
|
|
93059
93481
|
function findGitRoot(absPath) {
|
|
93060
93482
|
let dir = absPath;
|
|
93061
93483
|
for (let depth = 0; depth < 64; depth++) {
|
|
93062
|
-
if (existsSync33(
|
|
93063
|
-
const parent =
|
|
93484
|
+
if (existsSync33(join43(dir, ".git"))) return dir;
|
|
93485
|
+
const parent = dirname15(dir);
|
|
93064
93486
|
if (parent === dir) return null;
|
|
93065
93487
|
dir = parent;
|
|
93066
93488
|
}
|
|
@@ -93777,7 +94199,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
93777
94199
|
records.push(rec);
|
|
93778
94200
|
void ambientLinkAll();
|
|
93779
94201
|
try {
|
|
93780
|
-
|
|
94202
|
+
writeFileSync28(
|
|
93781
94203
|
rec.engine.paths.daemonLock,
|
|
93782
94204
|
daemonLockPayload({
|
|
93783
94205
|
pid: process.pid,
|
|
@@ -94156,7 +94578,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94156
94578
|
baseUrl = `http://127.0.0.1:${port}`;
|
|
94157
94579
|
try {
|
|
94158
94580
|
ensureDir(globalDir());
|
|
94159
|
-
|
|
94581
|
+
writeFileSync28(
|
|
94160
94582
|
lockPath,
|
|
94161
94583
|
daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
|
|
94162
94584
|
"utf8"
|
|
@@ -94165,7 +94587,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94165
94587
|
}
|
|
94166
94588
|
for (const r of records) {
|
|
94167
94589
|
try {
|
|
94168
|
-
|
|
94590
|
+
writeFileSync28(
|
|
94169
94591
|
r.engine.paths.daemonLock,
|
|
94170
94592
|
daemonLockPayload({
|
|
94171
94593
|
pid: process.pid,
|
|
@@ -94866,7 +95288,10 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94866
95288
|
projectId: project?.projectId,
|
|
94867
95289
|
writeTarget: project ? null : receiptContext.context.default_write_target
|
|
94868
95290
|
});
|
|
95291
|
+
const parkPath = edgeParkPath(r.engine.paths.configDir, destinationKey);
|
|
95292
|
+
const parkQueue = loadEdgePark(parkPath);
|
|
94869
95293
|
const built = await buildInstanceBatch(r, {
|
|
95294
|
+
edgeHolds: edgeHolds(parkQueue, Date.now()),
|
|
94870
95295
|
destinationKey,
|
|
94871
95296
|
profile: r.engine.profile,
|
|
94872
95297
|
daemonVersion: DAEMON_VERSION,
|
|
@@ -94892,7 +95317,8 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94892
95317
|
// straddle rows where the counter is merely absent.
|
|
94893
95318
|
blockedRepeat: 0,
|
|
94894
95319
|
rejectedRepeat: 0,
|
|
94895
|
-
edgesRejected: 0
|
|
95320
|
+
edgesRejected: 0,
|
|
95321
|
+
...zeroEdgeSettleCounts(parkQueue)
|
|
94896
95322
|
});
|
|
94897
95323
|
}
|
|
94898
95324
|
if (instances) {
|
|
@@ -94957,14 +95383,26 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94957
95383
|
if (typeof cloudId === "string" && cloudId) cloudIds.set(localId, cloudId);
|
|
94958
95384
|
}
|
|
94959
95385
|
const edgeReceipts = instanceEdgeReceipts(instances.edges, res.result.edges, cloudIds);
|
|
95386
|
+
const echo = /* @__PURE__ */ new Map();
|
|
95387
|
+
for (const node2 of res.result.nodes) {
|
|
95388
|
+
if (node2.nodeId && node2.decision !== "rejected") echo.set(node2.canonicalId, node2.nodeId);
|
|
95389
|
+
}
|
|
95390
|
+
const settled = settleEdgeOutcomes(
|
|
95391
|
+
parkQueue,
|
|
95392
|
+
instances.edges,
|
|
95393
|
+
matchEdgeVerdicts(instances.edges, res.result.edges, echo),
|
|
95394
|
+
Date.now()
|
|
95395
|
+
);
|
|
95396
|
+
saveEdgePark(parkPath, settled.queue);
|
|
95397
|
+
const edgeCounts = settled.counts;
|
|
94960
95398
|
if (rejectedEdges.length > 0) {
|
|
94961
95399
|
const byReason = /* @__PURE__ */ new Map();
|
|
94962
95400
|
for (const re of rejectedEdges) {
|
|
94963
|
-
const why = `${re.type}: ${re.reason ?? "no reason given"}`;
|
|
95401
|
+
const why = `${re.type}: ${(re.reason ?? "no reason given").replace(/'[^']*'/g, "'\u2026'")}`;
|
|
94964
95402
|
byReason.set(why, (byReason.get(why) ?? 0) + 1);
|
|
94965
95403
|
}
|
|
94966
95404
|
console.warn(
|
|
94967
|
-
`[sync\u2192cloud] [${projectName}] instances: ${rejectedEdges.length} edge(s) REJECTED by the door: ` + [...byReason.entries()].map(([why, n]) => `${n}\xD7 ${why}`).join(" | ")
|
|
95405
|
+
`[sync\u2192cloud] [${projectName}] instances: ${rejectedEdges.length} edge(s) REJECTED by the door (parked ${edgeCounts.edgesParked}, re-parked ${edgeCounts.edgesReparked}, dropped ${edgeCounts.edgesDroppedRefused + edgeCounts.edgesDroppedExhausted + edgeCounts.edgesDroppedExpired}; park now ${edgeCounts.edgeParkSize}): ` + [...byReason.entries()].map(([why, n]) => `${n}\xD7 ${why}`).join(" | ")
|
|
94968
95406
|
);
|
|
94969
95407
|
}
|
|
94970
95408
|
if (rejected.size > 0) {
|
|
@@ -95041,7 +95479,13 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95041
95479
|
});
|
|
95042
95480
|
});
|
|
95043
95481
|
let invalidatedReceipts = 0;
|
|
95482
|
+
const affirmedThisDrain = new Set(echo.values());
|
|
95483
|
+
let invalidationSkipped = 0;
|
|
95044
95484
|
for (const failedId of invalidInstanceEndpointIds(res.result.edges)) {
|
|
95485
|
+
if (affirmedThisDrain.has(failedId)) {
|
|
95486
|
+
invalidationSkipped++;
|
|
95487
|
+
continue;
|
|
95488
|
+
}
|
|
95045
95489
|
const localIds = new Set(instances.endpointSources[failedId] ?? []);
|
|
95046
95490
|
for (const [wireId, cloudId] of cloudIds) if (cloudId === failedId) {
|
|
95047
95491
|
for (const id of instances.endpointSources[wireId] ?? [instances.contextNodeSources[wireId] ?? wireId]) localIds.add(id);
|
|
@@ -95068,7 +95512,9 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95068
95512
|
// failing every pass. Same total, different bug.
|
|
95069
95513
|
blockedRepeat,
|
|
95070
95514
|
rejectedRepeat,
|
|
95071
|
-
edgesRejected: rejectedEdges.length
|
|
95515
|
+
edgesRejected: rejectedEdges.length,
|
|
95516
|
+
invalidationSkipped,
|
|
95517
|
+
...edgeCounts
|
|
95072
95518
|
});
|
|
95073
95519
|
return res.accepted;
|
|
95074
95520
|
});
|
|
@@ -95660,7 +96106,7 @@ import { spawnSync as spawnSync2 } from "node:child_process";
|
|
|
95660
96106
|
|
|
95661
96107
|
// src/codex-runtime.ts
|
|
95662
96108
|
import { readdirSync as readdirSync13, statSync as statSync10 } from "node:fs";
|
|
95663
|
-
import { join as
|
|
96109
|
+
import { join as join44 } from "node:path";
|
|
95664
96110
|
function resolveCodexExecutable(options = {}) {
|
|
95665
96111
|
const platform = options.platform ?? process.platform;
|
|
95666
96112
|
const env2 = options.env ?? process.env;
|
|
@@ -95675,13 +96121,13 @@ function resolveCodexExecutable(options = {}) {
|
|
|
95675
96121
|
};
|
|
95676
96122
|
for (const dir of (env2["PATH"] ?? env2["Path"] ?? "").split(";")) {
|
|
95677
96123
|
if (!dir.trim()) continue;
|
|
95678
|
-
const path3 =
|
|
96124
|
+
const path3 = join44(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
|
|
95679
96125
|
if (fileTime(path3) !== null) return path3;
|
|
95680
96126
|
}
|
|
95681
96127
|
if (!env2["LOCALAPPDATA"]) return "codex";
|
|
95682
|
-
const root =
|
|
96128
|
+
const root = join44(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
|
|
95683
96129
|
try {
|
|
95684
|
-
const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
96130
|
+
const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join44(root, entry.name, "codex.exe")).map((path3) => ({ path: path3, mtime: fileTime(path3) })).filter((candidate) => candidate.mtime !== null).sort((a, b) => b.mtime - a.mtime || a.path.localeCompare(b.path));
|
|
95685
96131
|
return candidates[0]?.path ?? "codex";
|
|
95686
96132
|
} catch {
|
|
95687
96133
|
return "codex";
|
|
@@ -95820,14 +96266,14 @@ async function diagnoseInstallation(cfg, dependencies) {
|
|
|
95820
96266
|
|
|
95821
96267
|
// src/codex-doctor.ts
|
|
95822
96268
|
import { spawn as spawn4 } from "node:child_process";
|
|
95823
|
-
import { readFileSync as
|
|
95824
|
-
import { join as
|
|
96269
|
+
import { readFileSync as readFileSync39, statSync as statSync11 } from "node:fs";
|
|
96270
|
+
import { join as join46 } from "node:path";
|
|
95825
96271
|
import { createInterface } from "node:readline";
|
|
95826
96272
|
|
|
95827
96273
|
// src/codex-hooks.ts
|
|
95828
|
-
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as
|
|
96274
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync38, renameSync as renameSync7, unlinkSync as unlinkSync5, writeFileSync as writeFileSync29 } from "node:fs";
|
|
95829
96275
|
import { homedir as homedir7 } from "node:os";
|
|
95830
|
-
import { join as
|
|
96276
|
+
import { join as join45 } from "node:path";
|
|
95831
96277
|
|
|
95832
96278
|
// src/hook-commands.ts
|
|
95833
96279
|
function hookCurlCommand(port, path3 = "/api/hook") {
|
|
@@ -96031,34 +96477,34 @@ function buildCodexRelaySource(workspaceRoot) {
|
|
|
96031
96477
|
init_checkout_root();
|
|
96032
96478
|
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.";
|
|
96033
96479
|
function writeRelay(file2, source) {
|
|
96034
|
-
if (existsSync35(file2) &&
|
|
96480
|
+
if (existsSync35(file2) && readFileSync38(file2, "utf8") === source) return;
|
|
96035
96481
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
96036
96482
|
try {
|
|
96037
|
-
|
|
96038
|
-
|
|
96483
|
+
writeFileSync29(temp, source, { encoding: "utf8", mode: 384 });
|
|
96484
|
+
renameSync7(temp, file2);
|
|
96039
96485
|
} finally {
|
|
96040
96486
|
if (existsSync35(temp)) unlinkSync5(temp);
|
|
96041
96487
|
}
|
|
96042
96488
|
}
|
|
96043
96489
|
function refreshCodexRelay(root) {
|
|
96044
|
-
const config2 =
|
|
96490
|
+
const config2 = join45(root, ".codex", "config.toml");
|
|
96045
96491
|
if (!existsSync35(config2)) return "absent";
|
|
96046
|
-
const existing =
|
|
96492
|
+
const existing = readFileSync38(config2, "utf8");
|
|
96047
96493
|
if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
|
|
96048
96494
|
replaceCodexHooks(existing, "");
|
|
96049
|
-
const relay =
|
|
96050
|
-
const prior = existsSync35(relay) ?
|
|
96495
|
+
const relay = join45(root, ".codex", "hooks", "errata-relay.mjs");
|
|
96496
|
+
const prior = existsSync35(relay) ? readFileSync38(relay, "utf8") : "";
|
|
96051
96497
|
if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
|
|
96052
96498
|
throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
|
|
96053
96499
|
}
|
|
96054
96500
|
const source = buildCodexRelaySource(checkoutRootOf(root));
|
|
96055
96501
|
if (prior === source) return "current";
|
|
96056
|
-
mkdirSync9(
|
|
96502
|
+
mkdirSync9(join45(root, ".codex", "hooks"), { recursive: true });
|
|
96057
96503
|
writeRelay(relay, source);
|
|
96058
96504
|
return "updated";
|
|
96059
96505
|
}
|
|
96060
|
-
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] ||
|
|
96061
|
-
return existsSync35(
|
|
96506
|
+
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join45(homedir7(), ".codex")) {
|
|
96507
|
+
return existsSync35(join45(root, ".codex")) || existsSync35(codexHome);
|
|
96062
96508
|
}
|
|
96063
96509
|
function replaceCodexHooks(existing, block) {
|
|
96064
96510
|
const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
|
|
@@ -96074,14 +96520,14 @@ function replaceCodexHooks(existing, block) {
|
|
|
96074
96520
|
return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
|
|
96075
96521
|
}
|
|
96076
96522
|
function writeCodexHooks(root, port, nodePath = process.execPath) {
|
|
96077
|
-
const dir =
|
|
96078
|
-
const file2 =
|
|
96079
|
-
const relay =
|
|
96523
|
+
const dir = join45(root, ".codex");
|
|
96524
|
+
const file2 = join45(dir, "config.toml");
|
|
96525
|
+
const relay = join45(dir, "hooks", "errata-relay.mjs");
|
|
96080
96526
|
const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
|
|
96081
|
-
const final = replaceCodexHooks(existsSync35(file2) ?
|
|
96082
|
-
mkdirSync9(
|
|
96527
|
+
const final = replaceCodexHooks(existsSync35(file2) ? readFileSync38(file2, "utf8") : "", block);
|
|
96528
|
+
mkdirSync9(join45(dir, "hooks"), { recursive: true });
|
|
96083
96529
|
writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
|
|
96084
|
-
if (!existsSync35(file2) ||
|
|
96530
|
+
if (!existsSync35(file2) || readFileSync38(file2, "utf8") !== final) writeFileSync29(file2, final, "utf8");
|
|
96085
96531
|
return file2;
|
|
96086
96532
|
}
|
|
96087
96533
|
|
|
@@ -96090,7 +96536,7 @@ init_checkout_root();
|
|
|
96090
96536
|
function inspectCodexRelay(cwd) {
|
|
96091
96537
|
const root = nearestGitRoot(cwd) ?? cwd;
|
|
96092
96538
|
try {
|
|
96093
|
-
const source =
|
|
96539
|
+
const source = readFileSync39(join46(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
|
|
96094
96540
|
if (source === buildCodexRelaySource(checkoutRootOf(root))) {
|
|
96095
96541
|
return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
|
|
96096
96542
|
}
|
|
@@ -96101,8 +96547,8 @@ function inspectCodexRelay(cwd) {
|
|
|
96101
96547
|
function inspectCodexContext(cwd) {
|
|
96102
96548
|
const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
|
|
96103
96549
|
try {
|
|
96104
|
-
const file2 =
|
|
96105
|
-
if (statSync11(file2).size <= 128 * 1024 &&
|
|
96550
|
+
const file2 = join46(root, ".errata", "context.md");
|
|
96551
|
+
if (statSync11(file2).size <= 128 * 1024 && readFileSync39(file2, "utf8").trim()) {
|
|
96106
96552
|
return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
|
|
96107
96553
|
}
|
|
96108
96554
|
} catch {
|
|
@@ -96280,9 +96726,9 @@ function consolidationGapMs(lastPassMs, policy) {
|
|
|
96280
96726
|
|
|
96281
96727
|
// src/codex-context-plugin.ts
|
|
96282
96728
|
import { createHash as createHash20 } from "node:crypto";
|
|
96283
|
-
import { cpSync as cpSync2, existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as
|
|
96729
|
+
import { cpSync as cpSync2, existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync40, renameSync as renameSync8, writeFileSync as writeFileSync30 } from "node:fs";
|
|
96284
96730
|
import { homedir as homedir8 } from "node:os";
|
|
96285
|
-
import { join as
|
|
96731
|
+
import { join as join47 } from "node:path";
|
|
96286
96732
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
96287
96733
|
|
|
96288
96734
|
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
|
|
@@ -96980,23 +97426,23 @@ var NAME = "errata-context";
|
|
|
96980
97426
|
var PREFIX2 = `./.errata/plugins/${NAME}/`;
|
|
96981
97427
|
var object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
96982
97428
|
function readText(file2) {
|
|
96983
|
-
return existsSync36(file2) ?
|
|
97429
|
+
return existsSync36(file2) ? readFileSync40(file2, "utf8") : "";
|
|
96984
97430
|
}
|
|
96985
97431
|
function writeChanged(file2, content) {
|
|
96986
97432
|
if (readText(file2) === content) return;
|
|
96987
97433
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
96988
|
-
|
|
96989
|
-
|
|
97434
|
+
writeFileSync30(temp, content, "utf8");
|
|
97435
|
+
renameSync8(temp, file2);
|
|
96990
97436
|
}
|
|
96991
97437
|
function bundledContextPlugin() {
|
|
96992
97438
|
const packaged = fileURLToPath2(new URL("./resources/context-plugin/", import.meta.url));
|
|
96993
|
-
if (existsSync36(
|
|
97439
|
+
if (existsSync36(join47(packaged, ".codex-plugin/plugin.json"))) return packaged;
|
|
96994
97440
|
return fileURLToPath2(new URL("../dist/resources/context-plugin/", import.meta.url));
|
|
96995
97441
|
}
|
|
96996
97442
|
function refreshCodexContextPlugin(root) {
|
|
96997
|
-
const file2 =
|
|
97443
|
+
const file2 = join47(root, ".agents", "plugins", "marketplace.json");
|
|
96998
97444
|
if (!existsSync36(file2)) return false;
|
|
96999
|
-
const marketplace = JSON.parse(
|
|
97445
|
+
const marketplace = JSON.parse(readFileSync40(file2, "utf8"));
|
|
97000
97446
|
const entries = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
|
|
97001
97447
|
const entry = entries.map(object2).find((value) => value.name === NAME && String(object2(value.source).path).startsWith(PREFIX2));
|
|
97002
97448
|
if (!entry) return false;
|
|
@@ -97007,24 +97453,24 @@ function refreshCodexContextPlugin(root) {
|
|
|
97007
97453
|
function installCodexContextPlugin(root, options = {}) {
|
|
97008
97454
|
const bundle = options.bundle ?? bundledContextPlugin();
|
|
97009
97455
|
const manifest = JSON.parse(
|
|
97010
|
-
|
|
97456
|
+
readFileSync40(join47(bundle, ".codex-plugin/plugin.json"), "utf8")
|
|
97011
97457
|
);
|
|
97012
97458
|
if (manifest.name !== NAME || typeof manifest.version !== "string" || !/^[\w.-]+$/.test(manifest.version)) {
|
|
97013
97459
|
throw new Error("Invalid bundled Errata Context manifest.");
|
|
97014
97460
|
}
|
|
97015
|
-
const checksums =
|
|
97461
|
+
const checksums = readFileSync40(join47(bundle, "SHA256SUMS"), "utf8");
|
|
97016
97462
|
for (const line of checksums.trim().split("\n")) {
|
|
97017
97463
|
const match2 = /^([a-f0-9]{64}) ([\w./-]+)$/.exec(line);
|
|
97018
97464
|
if (!match2 || match2[2].startsWith("/") || match2[2].split("/").includes("..")) {
|
|
97019
97465
|
throw new Error("Invalid bundled Errata Context checksum manifest.");
|
|
97020
97466
|
}
|
|
97021
|
-
const actual = createHash20("sha256").update(
|
|
97467
|
+
const actual = createHash20("sha256").update(readFileSync40(join47(bundle, match2[2]))).digest("hex");
|
|
97022
97468
|
if (actual !== match2[1])
|
|
97023
97469
|
throw new Error(`Bundled Errata Context checksum mismatch: ${match2[2]}`);
|
|
97024
97470
|
}
|
|
97025
97471
|
const release = `${manifest.version}-${createHash20("sha256").update(checksums).digest("hex").slice(0, 12)}`;
|
|
97026
|
-
const plugin =
|
|
97027
|
-
const marketplaceFile =
|
|
97472
|
+
const plugin = join47(root, ".errata", "plugins", NAME, release);
|
|
97473
|
+
const marketplaceFile = join47(root, ".agents", "plugins", "marketplace.json");
|
|
97028
97474
|
const priorMarketplace = readText(marketplaceFile);
|
|
97029
97475
|
const marketplace = priorMarketplace ? JSON.parse(priorMarketplace) : {
|
|
97030
97476
|
name: "errata-local",
|
|
@@ -97045,12 +97491,12 @@ function installCodexContextPlugin(root, options = {}) {
|
|
|
97045
97491
|
);
|
|
97046
97492
|
}
|
|
97047
97493
|
const key = `${NAME}@${marketplace.name}`;
|
|
97048
|
-
const configFile =
|
|
97494
|
+
const configFile = join47(root, ".codex", "config.toml");
|
|
97049
97495
|
const config2 = readText(configFile);
|
|
97050
97496
|
const parsed = parse4(config2);
|
|
97051
97497
|
const plugins = object2(parsed.plugins);
|
|
97052
|
-
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ??
|
|
97053
|
-
const globalPlugins = object2(parse4(readText(
|
|
97498
|
+
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join47(homedir8(), ".codex");
|
|
97499
|
+
const globalPlugins = object2(parse4(readText(join47(codexHome, "config.toml"))).plugins);
|
|
97054
97500
|
const disabledGlobally = Object.entries(globalPlugins).some(
|
|
97055
97501
|
([name2, value]) => (name2 === NAME || name2.startsWith(`${NAME}@`)) && object2(value).enabled === false
|
|
97056
97502
|
);
|
|
@@ -97074,13 +97520,13 @@ enabled = ${enabled}
|
|
|
97074
97520
|
mkdirSync10(plugin, { recursive: true });
|
|
97075
97521
|
cpSync2(bundle, plugin, { recursive: true });
|
|
97076
97522
|
writeChanged(
|
|
97077
|
-
|
|
97523
|
+
join47(plugin, ".mcp.json"),
|
|
97078
97524
|
JSON.stringify(
|
|
97079
97525
|
{
|
|
97080
97526
|
mcpServers: {
|
|
97081
97527
|
errata_context: {
|
|
97082
97528
|
command: options.nodePath ?? process.execPath,
|
|
97083
|
-
args: [
|
|
97529
|
+
args: [join47(plugin, "dist", "mcp-server.mjs")],
|
|
97084
97530
|
env: { ERRATA_WORKSPACE: root, ERRATA_CONTEXT_VERSION: manifest.version }
|
|
97085
97531
|
}
|
|
97086
97532
|
}
|
|
@@ -97089,8 +97535,8 @@ enabled = ${enabled}
|
|
|
97089
97535
|
2
|
|
97090
97536
|
) + "\n"
|
|
97091
97537
|
);
|
|
97092
|
-
mkdirSync10(
|
|
97093
|
-
mkdirSync10(
|
|
97538
|
+
mkdirSync10(join47(root, ".agents", "plugins"), { recursive: true });
|
|
97539
|
+
mkdirSync10(join47(root, ".codex"), { recursive: true });
|
|
97094
97540
|
writeChanged(marketplaceFile, JSON.stringify(marketplace, null, 2) + "\n");
|
|
97095
97541
|
writeChanged(configFile, nextConfig);
|
|
97096
97542
|
return { plugin, enabled, marketplace: marketplaceFile };
|
|
@@ -97098,15 +97544,15 @@ enabled = ${enabled}
|
|
|
97098
97544
|
|
|
97099
97545
|
// src/codex-hook-refresh.ts
|
|
97100
97546
|
init_checkout_root();
|
|
97101
|
-
import { existsSync as existsSync37, readdirSync as readdirSync14, readFileSync as
|
|
97102
|
-
import { dirname as
|
|
97547
|
+
import { existsSync as existsSync37, readdirSync as readdirSync14, readFileSync as readFileSync41 } from "node:fs";
|
|
97548
|
+
import { dirname as dirname16, join as join48, resolve as resolve8 } from "node:path";
|
|
97103
97549
|
init_registry();
|
|
97104
97550
|
function codexHookRoots(roots) {
|
|
97105
97551
|
const found = new Set(roots.map((root) => resolve8(root)));
|
|
97106
97552
|
for (const root of [...found]) {
|
|
97107
97553
|
const main2 = mainCheckoutOfWorktree(root) ?? root;
|
|
97108
97554
|
found.add(main2);
|
|
97109
|
-
const dir =
|
|
97555
|
+
const dir = join48(main2, ".git", "worktrees");
|
|
97110
97556
|
if (!existsSync37(dir)) continue;
|
|
97111
97557
|
let names;
|
|
97112
97558
|
try {
|
|
@@ -97116,7 +97562,7 @@ function codexHookRoots(roots) {
|
|
|
97116
97562
|
}
|
|
97117
97563
|
for (const name2 of names) {
|
|
97118
97564
|
try {
|
|
97119
|
-
const checkout =
|
|
97565
|
+
const checkout = dirname16(readFileSync41(join48(dir, name2, "gitdir"), "utf8").trim());
|
|
97120
97566
|
if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
|
|
97121
97567
|
} catch {
|
|
97122
97568
|
}
|
|
@@ -97138,9 +97584,9 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
|
|
|
97138
97584
|
}
|
|
97139
97585
|
|
|
97140
97586
|
// src/claude-statusline.ts
|
|
97141
|
-
import { existsSync as existsSync38, mkdirSync as mkdirSync11, readFileSync as
|
|
97587
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync11, readFileSync as readFileSync42, writeFileSync as writeFileSync31 } from "node:fs";
|
|
97142
97588
|
import { homedir as homedir9 } from "node:os";
|
|
97143
|
-
import { dirname as
|
|
97589
|
+
import { dirname as dirname17, join as join49 } from "node:path";
|
|
97144
97590
|
var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
|
|
97145
97591
|
import { readFileSync } from 'node:fs';
|
|
97146
97592
|
|
|
@@ -97188,8 +97634,8 @@ function isSameInstall(value, relay) {
|
|
|
97188
97634
|
return command.includes(relay.replace(/\\/g, "/").toLowerCase());
|
|
97189
97635
|
}
|
|
97190
97636
|
function userClaudeSettingsPath() {
|
|
97191
|
-
const base = process.env["CLAUDE_CONFIG_DIR"] ??
|
|
97192
|
-
return
|
|
97637
|
+
const base = process.env["CLAUDE_CONFIG_DIR"] ?? join49(homedir9(), ".claude");
|
|
97638
|
+
return join49(base, "settings.json");
|
|
97193
97639
|
}
|
|
97194
97640
|
function ensureUserStatusLine(opts) {
|
|
97195
97641
|
const env2 = opts.env ?? process.env;
|
|
@@ -97199,21 +97645,21 @@ function ensureUserStatusLine(opts) {
|
|
|
97199
97645
|
let settings = {};
|
|
97200
97646
|
if (existsSync38(settingsPath)) {
|
|
97201
97647
|
try {
|
|
97202
|
-
const parsed = JSON.parse(
|
|
97648
|
+
const parsed = JSON.parse(readFileSync42(settingsPath, "utf8"));
|
|
97203
97649
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
|
|
97204
97650
|
settings = parsed;
|
|
97205
97651
|
} catch {
|
|
97206
97652
|
return "unreadable";
|
|
97207
97653
|
}
|
|
97208
97654
|
}
|
|
97209
|
-
const relay =
|
|
97655
|
+
const relay = join49(opts.relayDir, STATUSLINE_RELAY_FILE);
|
|
97210
97656
|
const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
|
|
97211
97657
|
const ownMain = keep(settings["statusLine"]);
|
|
97212
97658
|
const ownRows = keep(settings["subagentStatusLine"]);
|
|
97213
97659
|
if (ownMain && ownRows) return "kept-own";
|
|
97214
97660
|
mkdirSync11(opts.relayDir, { recursive: true });
|
|
97215
|
-
if (!existsSync38(relay) ||
|
|
97216
|
-
|
|
97661
|
+
if (!existsSync38(relay) || readFileSync42(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
|
|
97662
|
+
writeFileSync31(relay, STATUSLINE_RELAY_SOURCE, "utf8");
|
|
97217
97663
|
}
|
|
97218
97664
|
const nodePath = opts.nodePath ?? process.execPath;
|
|
97219
97665
|
const next = {
|
|
@@ -97224,8 +97670,8 @@ function ensureUserStatusLine(opts) {
|
|
|
97224
97670
|
return ownMain ? "kept-own" : "unchanged";
|
|
97225
97671
|
}
|
|
97226
97672
|
Object.assign(settings, next);
|
|
97227
|
-
mkdirSync11(
|
|
97228
|
-
|
|
97673
|
+
mkdirSync11(dirname17(settingsPath), { recursive: true });
|
|
97674
|
+
writeFileSync31(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
97229
97675
|
return "installed";
|
|
97230
97676
|
}
|
|
97231
97677
|
function describeStatusLineOutcome(outcome) {
|
|
@@ -97245,8 +97691,8 @@ function describeStatusLineOutcome(outcome) {
|
|
|
97245
97691
|
|
|
97246
97692
|
// src/claude-mods.ts
|
|
97247
97693
|
import { createHash as createHash21 } from "node:crypto";
|
|
97248
|
-
import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as
|
|
97249
|
-
import { delimiter as delimiter2, dirname as
|
|
97694
|
+
import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync43, readdirSync as readdirSync15, rmSync as rmSync4, statSync as statSync12, writeFileSync as writeFileSync32 } from "node:fs";
|
|
97695
|
+
import { delimiter as delimiter2, dirname as dirname18, join as join50, relative as relative8, resolve as resolve9, sep as sep5 } from "node:path";
|
|
97250
97696
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
97251
97697
|
var CLAUDE_PLUGIN_DIRS_ENV = "CLAUDE_CODE_PLUGIN_DIRS";
|
|
97252
97698
|
var HASH_FILE = ".errata-mod-hash";
|
|
@@ -97261,7 +97707,7 @@ function isEngineOwned(relPath) {
|
|
|
97261
97707
|
function listFiles(root, dir = root) {
|
|
97262
97708
|
const out2 = [];
|
|
97263
97709
|
for (const name2 of readdirSync15(dir)) {
|
|
97264
|
-
const abs =
|
|
97710
|
+
const abs = join50(dir, name2);
|
|
97265
97711
|
if (isEngineOwned(relative8(root, abs))) continue;
|
|
97266
97712
|
if (statSync12(abs).isDirectory()) out2.push(...listFiles(root, abs));
|
|
97267
97713
|
else out2.push(abs);
|
|
@@ -97273,14 +97719,14 @@ function modHash(dir) {
|
|
|
97273
97719
|
for (const abs of listFiles(dir).sort()) {
|
|
97274
97720
|
h.update(relative8(dir, abs).split(sep5).join("/"));
|
|
97275
97721
|
h.update("\0");
|
|
97276
|
-
h.update(
|
|
97722
|
+
h.update(readFileSync43(abs));
|
|
97277
97723
|
h.update("\0");
|
|
97278
97724
|
}
|
|
97279
97725
|
return h.digest("hex");
|
|
97280
97726
|
}
|
|
97281
97727
|
function bundledMods(bundleDir) {
|
|
97282
97728
|
if (!existsSync39(bundleDir)) return [];
|
|
97283
|
-
return readdirSync15(bundleDir).filter((name2) => existsSync39(
|
|
97729
|
+
return readdirSync15(bundleDir).filter((name2) => existsSync39(join50(bundleDir, name2, ".claude-plugin", "plugin.json")));
|
|
97284
97730
|
}
|
|
97285
97731
|
function sameDir(a, b) {
|
|
97286
97732
|
const norm = (p) => resolve9(p).replace(/[\\/]+$/, "").toLowerCase();
|
|
@@ -97297,7 +97743,7 @@ function off(env2) {
|
|
|
97297
97743
|
function readSettings(path3) {
|
|
97298
97744
|
if (!existsSync39(path3)) return {};
|
|
97299
97745
|
try {
|
|
97300
|
-
const parsed = JSON.parse(
|
|
97746
|
+
const parsed = JSON.parse(readFileSync43(path3, "utf8"));
|
|
97301
97747
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
97302
97748
|
return parsed;
|
|
97303
97749
|
} catch {
|
|
@@ -97321,13 +97767,13 @@ function currentDirs(settings) {
|
|
|
97321
97767
|
return raw2.split(delimiter2).map((s) => s.trim()).filter(Boolean);
|
|
97322
97768
|
}
|
|
97323
97769
|
function writeSettings(path3, settings) {
|
|
97324
|
-
mkdirSync12(
|
|
97325
|
-
|
|
97770
|
+
mkdirSync12(dirname18(path3), { recursive: true });
|
|
97771
|
+
writeFileSync32(path3, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
97326
97772
|
}
|
|
97327
97773
|
function ensureClaudeMods(opts) {
|
|
97328
97774
|
const env2 = opts.env ?? process.env;
|
|
97329
97775
|
const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
|
|
97330
|
-
const modsRoot =
|
|
97776
|
+
const modsRoot = join50(opts.installRoot, "claude-mods");
|
|
97331
97777
|
if (off(env2)) {
|
|
97332
97778
|
const settings2 = readSettings(settingsPath);
|
|
97333
97779
|
if (!settings2) return { kind: "unreadable" };
|
|
@@ -97344,14 +97790,14 @@ function ensureClaudeMods(opts) {
|
|
|
97344
97790
|
let changed = false;
|
|
97345
97791
|
const installed = [];
|
|
97346
97792
|
for (const name2 of names) {
|
|
97347
|
-
const src =
|
|
97348
|
-
const dest =
|
|
97793
|
+
const src = join50(bundleDir, name2);
|
|
97794
|
+
const dest = join50(modsRoot, name2);
|
|
97349
97795
|
const hash2 = modHash(src);
|
|
97350
|
-
const hashFile =
|
|
97351
|
-
if (!existsSync39(hashFile) ||
|
|
97796
|
+
const hashFile = join50(dest, HASH_FILE);
|
|
97797
|
+
if (!existsSync39(hashFile) || readFileSync43(hashFile, "utf8") !== hash2) {
|
|
97352
97798
|
rmSync4(dest, { recursive: true, force: true });
|
|
97353
97799
|
cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative8(src, p)) });
|
|
97354
|
-
|
|
97800
|
+
writeFileSync32(hashFile, hash2, "utf8");
|
|
97355
97801
|
changed = true;
|
|
97356
97802
|
}
|
|
97357
97803
|
installed.push(dest);
|
|
@@ -97772,9 +98218,9 @@ function resolveHookPort(explicit) {
|
|
|
97772
98218
|
}
|
|
97773
98219
|
}
|
|
97774
98220
|
}
|
|
97775
|
-
const settingsPath =
|
|
98221
|
+
const settingsPath = join51(ROOT, ".claude", "settings.json");
|
|
97776
98222
|
try {
|
|
97777
|
-
if (existsSync40(settingsPath)) return installedHookPort(
|
|
98223
|
+
if (existsSync40(settingsPath)) return installedHookPort(readFileSync44(settingsPath, "utf8")) ?? 7891;
|
|
97778
98224
|
} catch {
|
|
97779
98225
|
}
|
|
97780
98226
|
return 7891;
|
|
@@ -97800,13 +98246,13 @@ async function cmdInit() {
|
|
|
97800
98246
|
console.log("");
|
|
97801
98247
|
console.log("installing harness hooks...");
|
|
97802
98248
|
const { existsSync: existsSync41 } = await import("node:fs");
|
|
97803
|
-
const { join:
|
|
98249
|
+
const { join: join52 } = await import("node:path");
|
|
97804
98250
|
try {
|
|
97805
98251
|
await installClaudeHooks(port);
|
|
97806
98252
|
} catch (err2) {
|
|
97807
98253
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
97808
98254
|
}
|
|
97809
|
-
if (existsSync41(
|
|
98255
|
+
if (existsSync41(join52(ROOT, ".cursor"))) {
|
|
97810
98256
|
try {
|
|
97811
98257
|
await installCursorMcpConfig();
|
|
97812
98258
|
} catch (err2) {
|
|
@@ -99028,7 +99474,7 @@ async function cmdReview() {
|
|
|
99028
99474
|
console.log("(review queue empty)");
|
|
99029
99475
|
return;
|
|
99030
99476
|
}
|
|
99031
|
-
const queue = JSON.parse(
|
|
99477
|
+
const queue = JSON.parse(readFileSync44(paths.reviewQueue, "utf8"));
|
|
99032
99478
|
if (queue.length === 0) {
|
|
99033
99479
|
console.log("(review queue empty)");
|
|
99034
99480
|
return;
|
|
@@ -99767,7 +100213,7 @@ async function gatherReportData(generatedAt) {
|
|
|
99767
100213
|
};
|
|
99768
100214
|
}
|
|
99769
100215
|
async function cmdReport(args2) {
|
|
99770
|
-
const { mkdirSync: mkdirSync13, writeFileSync:
|
|
100216
|
+
const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync33 } = await import("node:fs");
|
|
99771
100217
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
99772
100218
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
99773
100219
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -99780,8 +100226,8 @@ async function cmdReport(args2) {
|
|
|
99780
100226
|
const outDir = workspacePaths(ROOT).configDir;
|
|
99781
100227
|
mkdirSync13(outDir, { recursive: true });
|
|
99782
100228
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
99783
|
-
for (const f of files)
|
|
99784
|
-
const indexPath =
|
|
100229
|
+
for (const f of files) writeFileSync33(join51(outDir, f.name), f.html, "utf8");
|
|
100230
|
+
const indexPath = join51(outDir, "report.html");
|
|
99785
100231
|
console.log(`report \u2192 ${indexPath}`);
|
|
99786
100232
|
console.log(
|
|
99787
100233
|
` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
|
|
@@ -99837,7 +100283,7 @@ function spawnDaemonDetached(options = {}) {
|
|
|
99837
100283
|
try {
|
|
99838
100284
|
const logPath = daemonLogPath();
|
|
99839
100285
|
try {
|
|
99840
|
-
if (statSync13(logPath).size > 5 * 1024 * 1024)
|
|
100286
|
+
if (statSync13(logPath).size > 5 * 1024 * 1024) renameSync9(logPath, `${logPath}.1`);
|
|
99841
100287
|
} catch {
|
|
99842
100288
|
}
|
|
99843
100289
|
out2 = openSync3(logPath, "a");
|
|
@@ -99906,24 +100352,24 @@ async function cmdInstallHooks(args2) {
|
|
|
99906
100352
|
}
|
|
99907
100353
|
}
|
|
99908
100354
|
async function installOpencodePlugin(port) {
|
|
99909
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
99910
|
-
const { join:
|
|
99911
|
-
const dir =
|
|
100355
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync45, writeFileSync: writeFileSync33 } = await import("node:fs");
|
|
100356
|
+
const { join: join52 } = await import("node:path");
|
|
100357
|
+
const dir = join52(ROOT, ".opencode", "plugin");
|
|
99912
100358
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
99913
|
-
const file2 =
|
|
100359
|
+
const file2 = join52(dir, "inerrata.js");
|
|
99914
100360
|
if (existsSync41(file2)) {
|
|
99915
|
-
const head2 =
|
|
100361
|
+
const head2 = readFileSync45(file2, "utf8").split("\n")[0] ?? "";
|
|
99916
100362
|
if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
|
|
99917
100363
|
console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
|
|
99918
100364
|
process.exit(2);
|
|
99919
100365
|
}
|
|
99920
100366
|
}
|
|
99921
|
-
|
|
99922
|
-
const cfgFile =
|
|
100367
|
+
writeFileSync33(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
|
|
100368
|
+
const cfgFile = join52(ROOT, "opencode.json");
|
|
99923
100369
|
let cfg = { $schema: "https://opencode.ai/config.json" };
|
|
99924
100370
|
if (existsSync41(cfgFile)) {
|
|
99925
100371
|
try {
|
|
99926
|
-
cfg = JSON.parse(
|
|
100372
|
+
cfg = JSON.parse(readFileSync45(cfgFile, "utf8"));
|
|
99927
100373
|
} catch {
|
|
99928
100374
|
console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
|
|
99929
100375
|
process.exit(2);
|
|
@@ -99934,7 +100380,7 @@ async function installOpencodePlugin(port) {
|
|
|
99934
100380
|
if (!hadErrata) {
|
|
99935
100381
|
const inv = errataMcpInvocation();
|
|
99936
100382
|
cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
|
|
99937
|
-
|
|
100383
|
+
writeFileSync33(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
99938
100384
|
}
|
|
99939
100385
|
console.log(`installed OpenCode plugin \u2192 ${file2}`);
|
|
99940
100386
|
if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
|
|
@@ -99969,15 +100415,15 @@ function installClaudeMods() {
|
|
|
99969
100415
|
}
|
|
99970
100416
|
}
|
|
99971
100417
|
async function installClaudeHooks(port) {
|
|
99972
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
99973
|
-
const { join:
|
|
99974
|
-
const dir =
|
|
100418
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync45, writeFileSync: writeFileSync33 } = await import("node:fs");
|
|
100419
|
+
const { join: join52 } = await import("node:path");
|
|
100420
|
+
const dir = join52(ROOT, ".claude");
|
|
99975
100421
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
99976
|
-
const file2 =
|
|
100422
|
+
const file2 = join52(dir, "settings.json");
|
|
99977
100423
|
let settings = {};
|
|
99978
100424
|
if (existsSync41(file2)) {
|
|
99979
100425
|
try {
|
|
99980
|
-
settings = JSON.parse(
|
|
100426
|
+
settings = JSON.parse(readFileSync45(file2, "utf8"));
|
|
99981
100427
|
} catch {
|
|
99982
100428
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
99983
100429
|
process.exit(2);
|
|
@@ -100026,12 +100472,12 @@ async function installClaudeHooks(port) {
|
|
|
100026
100472
|
list.push({ hooks: [{ type: "command", command: injectCmd }] });
|
|
100027
100473
|
}
|
|
100028
100474
|
removeProjectStatusLine(settings);
|
|
100029
|
-
|
|
100475
|
+
writeFileSync33(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
100030
100476
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
100031
100477
|
console.log(` ${ensureStatusLine(port)}`);
|
|
100032
100478
|
console.log(` ${installClaudeMods().line}`);
|
|
100033
100479
|
await installClaudeMcpConfig();
|
|
100034
|
-
const claudeMd =
|
|
100480
|
+
const claudeMd = join52(ROOT, "CLAUDE.md");
|
|
100035
100481
|
const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
|
|
100036
100482
|
if (recall.kind === "collision") {
|
|
100037
100483
|
console.warn(
|
|
@@ -100043,15 +100489,15 @@ async function installClaudeHooks(port) {
|
|
|
100043
100489
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
100044
100490
|
}
|
|
100045
100491
|
async function installClaudeMcpConfig() {
|
|
100046
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100047
|
-
const { join:
|
|
100048
|
-
const file2 =
|
|
100049
|
-
const dir =
|
|
100492
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync45, writeFileSync: writeFileSync33 } = await import("node:fs");
|
|
100493
|
+
const { join: join52, dirname: dirname19 } = await import("node:path");
|
|
100494
|
+
const file2 = join52(ROOT, ".mcp.json");
|
|
100495
|
+
const dir = dirname19(file2);
|
|
100050
100496
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100051
100497
|
let cfg = {};
|
|
100052
100498
|
if (existsSync41(file2)) {
|
|
100053
100499
|
try {
|
|
100054
|
-
cfg = JSON.parse(
|
|
100500
|
+
cfg = JSON.parse(readFileSync45(file2, "utf8"));
|
|
100055
100501
|
} catch {
|
|
100056
100502
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
100057
100503
|
process.exit(2);
|
|
@@ -100059,21 +100505,21 @@ async function installClaudeMcpConfig() {
|
|
|
100059
100505
|
}
|
|
100060
100506
|
cfg.mcpServers ??= {};
|
|
100061
100507
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
100062
|
-
|
|
100508
|
+
writeFileSync33(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
100063
100509
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
100064
100510
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
100065
100511
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
100066
100512
|
}
|
|
100067
100513
|
async function installCursorMcpConfig() {
|
|
100068
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100069
|
-
const { join:
|
|
100070
|
-
const dir =
|
|
100514
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync45, writeFileSync: writeFileSync33 } = await import("node:fs");
|
|
100515
|
+
const { join: join52 } = await import("node:path");
|
|
100516
|
+
const dir = join52(ROOT, ".cursor");
|
|
100071
100517
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100072
|
-
const file2 =
|
|
100518
|
+
const file2 = join52(dir, "mcp.json");
|
|
100073
100519
|
let cfg = {};
|
|
100074
100520
|
if (existsSync41(file2)) {
|
|
100075
100521
|
try {
|
|
100076
|
-
cfg = JSON.parse(
|
|
100522
|
+
cfg = JSON.parse(readFileSync45(file2, "utf8"));
|
|
100077
100523
|
} catch {
|
|
100078
100524
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
100079
100525
|
process.exit(2);
|
|
@@ -100081,7 +100527,7 @@ async function installCursorMcpConfig() {
|
|
|
100081
100527
|
}
|
|
100082
100528
|
cfg.mcpServers ??= {};
|
|
100083
100529
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
100084
|
-
|
|
100530
|
+
writeFileSync33(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
100085
100531
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
100086
100532
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
100087
100533
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -100092,7 +100538,7 @@ async function installCodexHooks(port) {
|
|
|
100092
100538
|
const gitRoot = nearestGitRoot(process.cwd());
|
|
100093
100539
|
const hookRoot = gitRoot && mainCheckoutOfWorktree(gitRoot) ? gitRoot : ROOT;
|
|
100094
100540
|
const file2 = writeCodexHooks(hookRoot, port);
|
|
100095
|
-
const instructions = writeManagedBlock(
|
|
100541
|
+
const instructions = writeManagedBlock(join51(hookRoot, "AGENTS.md"), {
|
|
100096
100542
|
body: AGENTS_POINTER_BODY,
|
|
100097
100543
|
stable: true
|
|
100098
100544
|
});
|
|
@@ -100538,9 +100984,9 @@ async function cmdDash(args2) {
|
|
|
100538
100984
|
await yieldToLoop2();
|
|
100539
100985
|
try {
|
|
100540
100986
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
|
|
100541
|
-
atCommit: readGitRefState(
|
|
100987
|
+
atCommit: readGitRefState(join51(r.root, ".git")).sha ?? void 0
|
|
100542
100988
|
});
|
|
100543
|
-
const res = bleedRules(
|
|
100989
|
+
const res = bleedRules(join51(r.root, ".claude", "rules"), items);
|
|
100544
100990
|
if (res.written || res.pruned) {
|
|
100545
100991
|
console.log(
|
|
100546
100992
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|