@inerrata-corporation/errata 2.0.23-dev.4901 → 2.0.23-dev.4938
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/errata.mjs
CHANGED
|
@@ -25093,8 +25093,8 @@ function anchorNodeToDiff(store, nodeId, expectLabel, changedPaths, workspaceId2
|
|
|
25093
25093
|
const n0 = store.getNode(nodeId);
|
|
25094
25094
|
if (!n0 || n0.label !== expectLabel) return 0;
|
|
25095
25095
|
const code = changedPaths.filter((f) => isAnchorableCodePath(f));
|
|
25096
|
-
const
|
|
25097
|
-
if (code.length === 0 || code.length >
|
|
25096
|
+
const cap2 = opts.maxFiles ?? MAX_ANCHOR_FILES;
|
|
25097
|
+
if (code.length === 0 || code.length > cap2) return 0;
|
|
25098
25098
|
const already = new Set(store.outEdges(nodeId, ["ANCHORED_AT"]).map((e) => e.to));
|
|
25099
25099
|
let n = 0;
|
|
25100
25100
|
for (const path3 of code) {
|
|
@@ -27937,6 +27937,24 @@ var init_mechanism_liveness = __esm({
|
|
|
27937
27937
|
effectCounter: "structureLinksMinted",
|
|
27938
27938
|
note: "the answer is the agent's; nothing is inferred"
|
|
27939
27939
|
},
|
|
27940
|
+
{
|
|
27941
|
+
id: "held-ask",
|
|
27942
|
+
what: "asks a session whether a prior it leaned on held; the agent's confirm/refute answers it",
|
|
27943
|
+
pass: "capture",
|
|
27944
|
+
// Opened only by a lean-on cite of a prior the session did not mint —
|
|
27945
|
+
// written-at-all bar. The answers feed confirmedAt/refutedAt locally and
|
|
27946
|
+
// the cloud's corroborate/contradict channels (§5.4 α/β) — the contrastive
|
|
27947
|
+
// verdicts the FEP core needs (docs/reference/plans/fep-core.md §5.7).
|
|
27948
|
+
fed: {
|
|
27949
|
+
labels: ["Problem", "Solution", "RootCause", "Pattern"],
|
|
27950
|
+
attr: "heldAskedAt",
|
|
27951
|
+
minFraction: 0
|
|
27952
|
+
},
|
|
27953
|
+
// Counts only answers to questions a render actually SHOWED — a verdict the
|
|
27954
|
+
// agent would have given unasked does not prove the ask did anything.
|
|
27955
|
+
effectCounter: "heldAnswered",
|
|
27956
|
+
note: "asked, never inferred; the lean is provisional while asked and replaced by the answer; Network-only priors are asked by id"
|
|
27957
|
+
},
|
|
27940
27958
|
{
|
|
27941
27959
|
id: "regression-recognize",
|
|
27942
27960
|
what: "marks a resolved problem as resolutionSuspect when it recurs at the door",
|
|
@@ -28931,6 +28949,18 @@ function renderSnapshot(s) {
|
|
|
28931
28949
|
}
|
|
28932
28950
|
lines.push("");
|
|
28933
28951
|
}
|
|
28952
|
+
if (s.heldAsks?.length) {
|
|
28953
|
+
lines.push("### \u{1F9EA} Did it hold?");
|
|
28954
|
+
lines.push(
|
|
28955
|
+
"_You leaned on these priors this session. Once you know whether each one held up in your work, say so \u2014 a prior nobody judges ranks the same whether it worked or not:_"
|
|
28956
|
+
);
|
|
28957
|
+
for (const p of s.heldAsks) {
|
|
28958
|
+
const what = p.description ? `**${p.description}** \u2014 \`${p.id}\`` : `\`${p.id}\``;
|
|
28959
|
+
lines.push(`- ${what}${p.lifecycle ? ` _(${p.lifecycle})_` : ""}`);
|
|
28960
|
+
lines.push(` - it held \u2192 ${TAG_VERDICT_TOKENS.confirm(p.id)} \xB7 it didn't \u2192 ${TAG_VERDICT_TOKENS.refute(p.id)}`);
|
|
28961
|
+
}
|
|
28962
|
+
lines.push("");
|
|
28963
|
+
}
|
|
28934
28964
|
lines.push("### Recently observed problems in this workspace");
|
|
28935
28965
|
if (s.recentProblems.length === 0 && s.recentResolved.length === 0 && s.recentConstraints.length === 0 && s.regressions.length === 0) {
|
|
28936
28966
|
lines.push("- _none yet \u2014 errata is still building its model_");
|
|
@@ -29234,6 +29264,7 @@ function isolateSnapshot(s) {
|
|
|
29234
29264
|
statedIntent: _statedIntent,
|
|
29235
29265
|
selfCiteSkips: _selfCiteSkips,
|
|
29236
29266
|
supersessionAsks: _supersessionAsks,
|
|
29267
|
+
heldAsks: _heldAsks,
|
|
29237
29268
|
pendingUpdate: _pendingUpdate,
|
|
29238
29269
|
daemonDistress: _daemonDistress,
|
|
29239
29270
|
reviewItems: _reviewItems,
|
|
@@ -35417,13 +35448,13 @@ function runGraphRescore(store, opts = {}) {
|
|
|
35417
35448
|
function tryIncrementalRescore(store, lastRescoreAt, started2) {
|
|
35418
35449
|
const allowedTypes = new Set(pagerankEdgeTypes());
|
|
35419
35450
|
const liveN = store.nodeCount();
|
|
35420
|
-
const
|
|
35451
|
+
const cap2 = Math.max(1e3, Math.floor(liveN * INCREMENTAL_REGION_MAX_FRACTION));
|
|
35421
35452
|
const region = new Set(store.dirtyNodeIdsSince(lastRescoreAt));
|
|
35422
35453
|
for (const e of store.edgeEndpointsTouchedSince(lastRescoreAt)) {
|
|
35423
35454
|
region.add(e.from);
|
|
35424
35455
|
region.add(e.to);
|
|
35425
35456
|
}
|
|
35426
|
-
if (region.size >
|
|
35457
|
+
if (region.size > cap2) return null;
|
|
35427
35458
|
let frontier = [...region];
|
|
35428
35459
|
for (let hop = 0; hop < INCREMENTAL_HOPS && frontier.length > 0; hop++) {
|
|
35429
35460
|
const next = [];
|
|
@@ -35434,7 +35465,7 @@ function tryIncrementalRescore(store, lastRescoreAt, started2) {
|
|
|
35434
35465
|
next.push(e.to);
|
|
35435
35466
|
}
|
|
35436
35467
|
}
|
|
35437
|
-
if (region.size >
|
|
35468
|
+
if (region.size > cap2) return null;
|
|
35438
35469
|
frontier = next;
|
|
35439
35470
|
}
|
|
35440
35471
|
const rank0 = store.ranksForMany([...region]);
|
|
@@ -35471,7 +35502,7 @@ function tryIncrementalRescore(store, lastRescoreAt, started2) {
|
|
|
35471
35502
|
}
|
|
35472
35503
|
const boundaryEdges = store.inEdgesForMany(regionIds).filter((e) => allowedTypes.has(e.type) && !inRegion.has(e.from) && (EDGE_WEIGHT[e.type] ?? 1) > 0);
|
|
35473
35504
|
const boundarySources = [...new Set(boundaryEdges.map((e) => e.from))];
|
|
35474
|
-
if (boundarySources.length >
|
|
35505
|
+
if (boundarySources.length > cap2) return null;
|
|
35475
35506
|
const boundaryRanks = store.ranksForMany(boundarySources);
|
|
35476
35507
|
const boundaryOutSum = /* @__PURE__ */ new Map();
|
|
35477
35508
|
for (const e of store.outEdgesForMany(boundarySources)) {
|
|
@@ -38656,14 +38687,14 @@ var init_generalize_graph = __esm({
|
|
|
38656
38687
|
});
|
|
38657
38688
|
|
|
38658
38689
|
// src/dual-burst.ts
|
|
38659
|
-
function collectiveScore(hit,
|
|
38660
|
-
if (hit.cloudScore != null) return
|
|
38690
|
+
function collectiveScore(hit, cap2) {
|
|
38691
|
+
if (hit.cloudScore != null) return cap2 * Math.max(0, Math.min(1, hit.cloudScore));
|
|
38661
38692
|
const u = hit.usageCount ?? 0;
|
|
38662
|
-
return Math.min(
|
|
38693
|
+
return Math.min(cap2, Math.log10(u + 1) / 3);
|
|
38663
38694
|
}
|
|
38664
38695
|
function mergeDualBurst(local, cloud, opts = {}) {
|
|
38665
38696
|
const boost = opts.corroborationBoost ?? 0.15;
|
|
38666
|
-
const
|
|
38697
|
+
const cap2 = opts.collectiveScoreCap ?? 0.5;
|
|
38667
38698
|
const twins = opts.twins;
|
|
38668
38699
|
const cloudIdsOf = (id) => twins?.cloudIdsOf(id) ?? [];
|
|
38669
38700
|
const seedSet = /* @__PURE__ */ new Set();
|
|
@@ -38734,7 +38765,7 @@ function mergeDualBurst(local, cloud, opts = {}) {
|
|
|
38734
38765
|
id: mine.id,
|
|
38735
38766
|
label: mine.label,
|
|
38736
38767
|
name: mine.description,
|
|
38737
|
-
score: collectiveScore(c,
|
|
38768
|
+
score: collectiveScore(c, cap2),
|
|
38738
38769
|
hops: 1,
|
|
38739
38770
|
provenance: "local"
|
|
38740
38771
|
};
|
|
@@ -38751,7 +38782,7 @@ function mergeDualBurst(local, cloud, opts = {}) {
|
|
|
38751
38782
|
id: c.id,
|
|
38752
38783
|
label: c.label,
|
|
38753
38784
|
name: c.description,
|
|
38754
|
-
score: collectiveScore(c,
|
|
38785
|
+
score: collectiveScore(c, cap2),
|
|
38755
38786
|
hops: 1,
|
|
38756
38787
|
// adapters surface 1-hop neighbors of the seed
|
|
38757
38788
|
provenance: "collective",
|
|
@@ -78358,18 +78389,18 @@ __export(witness_ledger_exports, {
|
|
|
78358
78389
|
summarizeWitnessLedger: () => summarizeWitnessLedger,
|
|
78359
78390
|
witnessLedgerPath: () => witnessLedgerPath
|
|
78360
78391
|
});
|
|
78361
|
-
import { appendFileSync as appendFileSync3, existsSync as existsSync29, readFileSync as
|
|
78362
|
-
import { join as
|
|
78392
|
+
import { appendFileSync as appendFileSync3, existsSync as existsSync29, readFileSync as readFileSync34, writeFileSync as writeFileSync23 } from "node:fs";
|
|
78393
|
+
import { join as join38 } from "node:path";
|
|
78363
78394
|
function witnessLedgerPath(configDir) {
|
|
78364
|
-
return
|
|
78395
|
+
return join38(configDir, "witness-ledger.jsonl");
|
|
78365
78396
|
}
|
|
78366
78397
|
function appendWitnessLedger(configDir, entry) {
|
|
78367
78398
|
const path3 = witnessLedgerPath(configDir);
|
|
78368
78399
|
try {
|
|
78369
78400
|
appendFileSync3(path3, JSON.stringify(entry) + "\n");
|
|
78370
|
-
const lines =
|
|
78401
|
+
const lines = readFileSync34(path3, "utf8").split("\n").filter(Boolean);
|
|
78371
78402
|
if (lines.length > LEDGER_MAX_LINES) {
|
|
78372
|
-
|
|
78403
|
+
writeFileSync23(path3, lines.slice(-Math.floor(LEDGER_MAX_LINES / 2)).join("\n") + "\n");
|
|
78373
78404
|
}
|
|
78374
78405
|
} catch {
|
|
78375
78406
|
}
|
|
@@ -78378,7 +78409,7 @@ function readWitnessLedger(configDir) {
|
|
|
78378
78409
|
const path3 = witnessLedgerPath(configDir);
|
|
78379
78410
|
if (!existsSync29(path3)) return [];
|
|
78380
78411
|
try {
|
|
78381
|
-
return
|
|
78412
|
+
return readFileSync34(path3, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter((e) => typeof e.ts === "number" && typeof e.channel === "string");
|
|
78382
78413
|
} catch {
|
|
78383
78414
|
return [];
|
|
78384
78415
|
}
|
|
@@ -78817,12 +78848,12 @@ var init_report_render = __esm({
|
|
|
78817
78848
|
|
|
78818
78849
|
// src/cli.ts
|
|
78819
78850
|
init_src6();
|
|
78820
|
-
import { closeSync as closeSync3, existsSync as existsSync42, openSync as openSync3, readFileSync as
|
|
78821
|
-
import { join as
|
|
78851
|
+
import { closeSync as closeSync3, existsSync as existsSync42, openSync as openSync3, readFileSync as readFileSync51, renameSync as renameSync11, statSync as statSync17, writeFileSync as writeFileSync35 } from "node:fs";
|
|
78852
|
+
import { join as join59, resolve as pathResolve2 } from "node:path";
|
|
78822
78853
|
import { spawn as spawn5 } from "node:child_process";
|
|
78823
78854
|
|
|
78824
78855
|
// src/daemon.ts
|
|
78825
|
-
import { existsSync as existsSync31, writeFileSync as
|
|
78856
|
+
import { existsSync as existsSync31, writeFileSync as writeFileSync26 } from "node:fs";
|
|
78826
78857
|
|
|
78827
78858
|
// ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.34/node_modules/@hono/node-server/dist/index.mjs
|
|
78828
78859
|
import { createServer as createServerHTTP } from "http";
|
|
@@ -79532,8 +79563,8 @@ function knowledgeTag(label, attrs) {
|
|
|
79532
79563
|
|
|
79533
79564
|
// src/engine.ts
|
|
79534
79565
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
79535
|
-
import { existsSync as existsSync30, statSync as statSync12, appendFileSync as appendFileSync4, readdirSync as readdirSync11, renameSync as
|
|
79536
|
-
import { basename as basename8, join as
|
|
79566
|
+
import { existsSync as existsSync30, statSync as statSync12, appendFileSync as appendFileSync4, readdirSync as readdirSync11, renameSync as renameSync6, readFileSync as readFileSync36, writeFileSync as writeFileSync25 } from "node:fs";
|
|
79567
|
+
import { basename as basename8, join as join40, relative as relative6, sep as sep5 } from "node:path";
|
|
79537
79568
|
|
|
79538
79569
|
// src/coalesced-file-pass.ts
|
|
79539
79570
|
function createCoalescedFilePass(delayMs, run3, onError) {
|
|
@@ -80309,9 +80340,9 @@ var NodeFsHandler = class {
|
|
|
80309
80340
|
if (this.fsw.closed) {
|
|
80310
80341
|
return;
|
|
80311
80342
|
}
|
|
80312
|
-
const
|
|
80343
|
+
const dirname24 = sysPath.dirname(file2);
|
|
80313
80344
|
const basename11 = sysPath.basename(file2);
|
|
80314
|
-
const parent = this.fsw._getWatchedDir(
|
|
80345
|
+
const parent = this.fsw._getWatchedDir(dirname24);
|
|
80315
80346
|
let prevStats = stats;
|
|
80316
80347
|
if (parent.has(basename11))
|
|
80317
80348
|
return;
|
|
@@ -80338,7 +80369,7 @@ var NodeFsHandler = class {
|
|
|
80338
80369
|
prevStats = newStats2;
|
|
80339
80370
|
}
|
|
80340
80371
|
} catch (error48) {
|
|
80341
|
-
this.fsw._remove(
|
|
80372
|
+
this.fsw._remove(dirname24, basename11);
|
|
80342
80373
|
}
|
|
80343
80374
|
} else if (parent.has(basename11)) {
|
|
80344
80375
|
const at = newStats.atimeMs;
|
|
@@ -81951,9 +81982,9 @@ function readFrom(path3, fromByte, maxBytes) {
|
|
|
81951
81982
|
const start2 = fromByte > 0 && fromByte <= size ? fromByte : 0;
|
|
81952
81983
|
const remaining = size - start2;
|
|
81953
81984
|
if (remaining <= 0) return { text: "", nextOffset: size, more: false, ioFailed: false };
|
|
81954
|
-
let
|
|
81985
|
+
let cap2 = maxBytes && maxBytes > 0 ? maxBytes : remaining;
|
|
81955
81986
|
for (; ; ) {
|
|
81956
|
-
const len = Math.min(
|
|
81987
|
+
const len = Math.min(cap2, remaining);
|
|
81957
81988
|
const buf = Buffer.allocUnsafe(len);
|
|
81958
81989
|
const read2 = readSync2(fd, buf, 0, len, start2);
|
|
81959
81990
|
if (len >= remaining || read2 < len) {
|
|
@@ -81969,7 +82000,7 @@ function readFrom(path3, fromByte, maxBytes) {
|
|
|
81969
82000
|
ioFailed: false
|
|
81970
82001
|
};
|
|
81971
82002
|
}
|
|
81972
|
-
|
|
82003
|
+
cap2 *= 2;
|
|
81973
82004
|
}
|
|
81974
82005
|
} catch {
|
|
81975
82006
|
return { text: "", nextOffset: fromByte, more: false, ioFailed: true };
|
|
@@ -83646,7 +83677,7 @@ function harvestInlineTags(store, text, opts) {
|
|
|
83646
83677
|
plan.fixes.push({ problemId, ...tag.fixRationale ? { fixNote: tag.fixRationale } : {} });
|
|
83647
83678
|
const witnessKey = `corrob:${problemId}:${digest({ h: tag.handle })}`.slice(0, 72);
|
|
83648
83679
|
if (!plan.corroborations.some((c) => c.witnessKey === witnessKey)) {
|
|
83649
|
-
plan.corroborations.push({ nodeId: problemId, witnessKey });
|
|
83680
|
+
plan.corroborations.push({ nodeId: problemId, witnessKey, via: "fix" });
|
|
83650
83681
|
}
|
|
83651
83682
|
} else plan.unresolvedFixes.push({ handle: tag.handle, ...tag.fixRationale ? { fixNote: tag.fixRationale } : {} });
|
|
83652
83683
|
} else if (tag.fixRationale) {
|
|
@@ -83807,7 +83838,7 @@ function harvestInlineTags(store, text, opts) {
|
|
|
83807
83838
|
if (!plan.corroborations.some((c) => c.witnessKey === witnessKey)) {
|
|
83808
83839
|
const exposure = typeof store.currentIngestSeq === "function" ? priorExposure(store, targetId, { seq: store.currentIngestSeq(), ts: opts.ts }) : "unshown";
|
|
83809
83840
|
countExposure(plan, exposure);
|
|
83810
|
-
plan.corroborations.push({ nodeId: targetId, witnessKey, exposure });
|
|
83841
|
+
plan.corroborations.push({ nodeId: targetId, witnessKey, exposure, via: "confirm" });
|
|
83811
83842
|
}
|
|
83812
83843
|
} else {
|
|
83813
83844
|
const witnessKey = `refute:${targetId}:${digest({ s: tag.statement ?? "" })}`.slice(0, 72);
|
|
@@ -83826,7 +83857,7 @@ function harvestInlineTags(store, text, opts) {
|
|
|
83826
83857
|
if (!plan.corroborations.some((c) => c.witnessKey === witnessKey)) {
|
|
83827
83858
|
const exposure = typeof store.currentIngestSeq === "function" ? priorExposure(store, targetId, { seq: store.currentIngestSeq(), ts: opts.ts }) : "unshown";
|
|
83828
83859
|
countExposure(plan, exposure);
|
|
83829
|
-
plan.corroborations.push({ nodeId: targetId, witnessKey, exposure });
|
|
83860
|
+
plan.corroborations.push({ nodeId: targetId, witnessKey, exposure, via: "lean" });
|
|
83830
83861
|
}
|
|
83831
83862
|
}
|
|
83832
83863
|
if (mintPriors && source && target) {
|
|
@@ -83982,6 +84013,154 @@ var SupersessionAsks = class {
|
|
|
83982
84013
|
}
|
|
83983
84014
|
};
|
|
83984
84015
|
|
|
84016
|
+
// src/held-asks.ts
|
|
84017
|
+
import { readFileSync as readFileSync22, renameSync as renameSync4, writeFileSync as writeFileSync16 } from "node:fs";
|
|
84018
|
+
import { dirname as dirname15, join as join26 } from "node:path";
|
|
84019
|
+
var HELD_ASK_TTL_MS = 2 * 60 * 6e4;
|
|
84020
|
+
var HELD_ASK_END_GRACE_MS = 2 * 6e4;
|
|
84021
|
+
var HELD_ASKS_SHOWN = 3;
|
|
84022
|
+
var REMEMBERED_PER_SESSION = 200;
|
|
84023
|
+
var SESSION_IDLE_MS2 = 24 * 60 * 6e4;
|
|
84024
|
+
var cap = (xs) => xs.slice(-REMEMBERED_PER_SESSION);
|
|
84025
|
+
var HeldAsks = class {
|
|
84026
|
+
sessions = /* @__PURE__ */ new Map();
|
|
84027
|
+
constructor(snapshot) {
|
|
84028
|
+
const isWitness = (w) => typeof w?.nodeId === "string" && typeof w?.witnessKey === "string";
|
|
84029
|
+
for (const s of snapshot?.sessions ?? []) {
|
|
84030
|
+
if (typeof s?.id !== "string" || !Array.isArray(s.asks)) continue;
|
|
84031
|
+
this.sessions.set(s.id, {
|
|
84032
|
+
asks: s.asks.filter((a) => typeof a?.priorId === "string" && isWitness(a.witness)),
|
|
84033
|
+
judged: Array.isArray(s.judged) ? s.judged.filter((j) => typeof j === "string") : [],
|
|
84034
|
+
released: Array.isArray(s.released) ? s.released.filter(isWitness) : [],
|
|
84035
|
+
touchedAt: Number(s.touchedAt) || 0,
|
|
84036
|
+
...typeof s.endedAt === "number" ? { endedAt: s.endedAt } : {}
|
|
84037
|
+
});
|
|
84038
|
+
}
|
|
84039
|
+
}
|
|
84040
|
+
/**
|
|
84041
|
+
* One harvest's leans and verdicts for a session — see the module doc for the
|
|
84042
|
+
* rules. `canOpen` is whether this turn can be asked (a live main session's own
|
|
84043
|
+
* turn); when it can't, leans still settle against what the session holds but
|
|
84044
|
+
* open nothing, and a lean on a prior it holds nothing for passes through.
|
|
84045
|
+
*/
|
|
84046
|
+
record(sessionId, harvest, now = Date.now()) {
|
|
84047
|
+
const out2 = {
|
|
84048
|
+
withheld: /* @__PURE__ */ new Set(),
|
|
84049
|
+
opened: [],
|
|
84050
|
+
answered: [],
|
|
84051
|
+
answeredShown: [],
|
|
84052
|
+
release: [],
|
|
84053
|
+
changed: false
|
|
84054
|
+
};
|
|
84055
|
+
if (!sessionId) return out2;
|
|
84056
|
+
const existing = this.sessions.get(sessionId);
|
|
84057
|
+
if (!existing && harvest.leaned.length === 0) return out2;
|
|
84058
|
+
const state = existing ?? { asks: [], judged: [], released: [], touchedAt: now };
|
|
84059
|
+
state.touchedAt = now;
|
|
84060
|
+
if (harvest.canOpen) delete state.endedAt;
|
|
84061
|
+
out2.changed = true;
|
|
84062
|
+
const said = new Set(state.judged);
|
|
84063
|
+
for (const v of harvest.verdicts) {
|
|
84064
|
+
const open2 = state.asks.find((a) => a.priorId === v.priorId);
|
|
84065
|
+
if (open2) {
|
|
84066
|
+
state.asks = state.asks.filter((a) => a !== open2);
|
|
84067
|
+
if (v.kind === "link") {
|
|
84068
|
+
out2.release.push({ sessionId, witness: open2.witness });
|
|
84069
|
+
state.released = cap([...state.released, open2.witness]);
|
|
84070
|
+
} else {
|
|
84071
|
+
out2.answered.push(v.priorId);
|
|
84072
|
+
if (open2.shownAt != null && open2.shownAt < now) out2.answeredShown.push(v.priorId);
|
|
84073
|
+
}
|
|
84074
|
+
} else if ((v.kind === "confirm" || v.kind === "fix") && v.witnessKey && state.released.some((w) => w.nodeId === v.priorId)) {
|
|
84075
|
+
out2.withheld.add(v.witnessKey);
|
|
84076
|
+
}
|
|
84077
|
+
if (v.kind !== "link") said.add(v.priorId);
|
|
84078
|
+
}
|
|
84079
|
+
state.judged = cap([...said]);
|
|
84080
|
+
for (const w of harvest.leaned) {
|
|
84081
|
+
const open2 = state.asks.find((a) => a.priorId === w.nodeId);
|
|
84082
|
+
if (open2 || said.has(w.nodeId) || state.released.some((r) => r.nodeId === w.nodeId)) {
|
|
84083
|
+
out2.withheld.add(w.witnessKey);
|
|
84084
|
+
if (open2) open2.leanedAt = Math.max(open2.leanedAt, now);
|
|
84085
|
+
continue;
|
|
84086
|
+
}
|
|
84087
|
+
if (!harvest.canOpen || harvest.verdicts.some((v) => v.priorId === w.nodeId && v.kind === "link")) {
|
|
84088
|
+
state.released = cap([...state.released, w]);
|
|
84089
|
+
continue;
|
|
84090
|
+
}
|
|
84091
|
+
out2.withheld.add(w.witnessKey);
|
|
84092
|
+
state.asks.push({ priorId: w.nodeId, leanedAt: now, witness: w });
|
|
84093
|
+
out2.opened.push(w.nodeId);
|
|
84094
|
+
}
|
|
84095
|
+
this.sessions.set(sessionId, state);
|
|
84096
|
+
return out2;
|
|
84097
|
+
}
|
|
84098
|
+
/** Open questions, newest first (the caller drops dead priors, then shows the first few). */
|
|
84099
|
+
forSession(sessionId, now = Date.now()) {
|
|
84100
|
+
const state = this.sessions.get(sessionId);
|
|
84101
|
+
if (!state || state.endedAt != null) return [];
|
|
84102
|
+
return state.asks.filter((a) => now - a.leanedAt < HELD_ASK_TTL_MS).sort((a, b) => b.leanedAt - a.leanedAt);
|
|
84103
|
+
}
|
|
84104
|
+
/** A render showed these questions. */
|
|
84105
|
+
markShown(sessionId, priorIds, now = Date.now()) {
|
|
84106
|
+
for (const a of this.sessions.get(sessionId)?.asks ?? []) if (priorIds.includes(a.priorId)) a.shownAt ??= now;
|
|
84107
|
+
}
|
|
84108
|
+
/** The prior is gone (invalidated): drop the question and its witness — there is nothing to corroborate. */
|
|
84109
|
+
discard(sessionId, priorId) {
|
|
84110
|
+
const state = this.sessions.get(sessionId);
|
|
84111
|
+
if (state) state.asks = state.asks.filter((a) => a.priorId !== priorId);
|
|
84112
|
+
}
|
|
84113
|
+
/** The session ended: its questions are released after a short grace (see {@link HELD_ASK_END_GRACE_MS}). */
|
|
84114
|
+
endSession(sessionId, now = Date.now()) {
|
|
84115
|
+
const state = this.sessions.get(sessionId);
|
|
84116
|
+
if (!state || state.endedAt != null) return false;
|
|
84117
|
+
state.endedAt = now;
|
|
84118
|
+
return true;
|
|
84119
|
+
}
|
|
84120
|
+
/** Questions past their TTL, or of sessions ended past the grace, across sessions: their leans are released. */
|
|
84121
|
+
expire(now = Date.now()) {
|
|
84122
|
+
const released = [];
|
|
84123
|
+
for (const [sessionId, state] of this.sessions) {
|
|
84124
|
+
const ended = state.endedAt != null && now - state.endedAt >= HELD_ASK_END_GRACE_MS;
|
|
84125
|
+
const keep = [];
|
|
84126
|
+
for (const a of state.asks) {
|
|
84127
|
+
if (ended || now - a.leanedAt >= HELD_ASK_TTL_MS) {
|
|
84128
|
+
released.push({ sessionId, witness: a.witness });
|
|
84129
|
+
state.released = cap([...state.released, a.witness]);
|
|
84130
|
+
} else keep.push(a);
|
|
84131
|
+
}
|
|
84132
|
+
state.asks = keep;
|
|
84133
|
+
if (keep.length === 0 && now - state.touchedAt > SESSION_IDLE_MS2) this.sessions.delete(sessionId);
|
|
84134
|
+
}
|
|
84135
|
+
return released;
|
|
84136
|
+
}
|
|
84137
|
+
/** A cache-key fingerprint of what this session's block could show. */
|
|
84138
|
+
version(sessionId, now = Date.now()) {
|
|
84139
|
+
return this.forSession(sessionId, now).map((a) => a.priorId).join(",");
|
|
84140
|
+
}
|
|
84141
|
+
snapshot() {
|
|
84142
|
+
return { sessions: [...this.sessions].map(([id, s]) => ({ id, ...s })) };
|
|
84143
|
+
}
|
|
84144
|
+
};
|
|
84145
|
+
function heldAsksPath(workspaceConfigDir) {
|
|
84146
|
+
return join26(workspaceConfigDir, "held-asks.json");
|
|
84147
|
+
}
|
|
84148
|
+
function loadHeldAsks(path3) {
|
|
84149
|
+
try {
|
|
84150
|
+
return new HeldAsks(JSON.parse(readFileSync22(path3, "utf8")));
|
|
84151
|
+
} catch {
|
|
84152
|
+
return new HeldAsks();
|
|
84153
|
+
}
|
|
84154
|
+
}
|
|
84155
|
+
function saveHeldAsks(path3, asks) {
|
|
84156
|
+
try {
|
|
84157
|
+
const tmp = join26(dirname15(path3), `.${Date.now()}.held-asks.tmp`);
|
|
84158
|
+
writeFileSync16(tmp, JSON.stringify(asks.snapshot()), "utf8");
|
|
84159
|
+
renameSync4(tmp, path3);
|
|
84160
|
+
} catch {
|
|
84161
|
+
}
|
|
84162
|
+
}
|
|
84163
|
+
|
|
83985
84164
|
// src/rollup.ts
|
|
83986
84165
|
function readConversation(transcriptPath, includeThinking = true, maxChars = 6e4) {
|
|
83987
84166
|
const raw2 = readTail(transcriptPath, 4e6);
|
|
@@ -84070,8 +84249,8 @@ ${conversation}` }]
|
|
|
84070
84249
|
// src/constraint-backfill.ts
|
|
84071
84250
|
init_src5();
|
|
84072
84251
|
init_src2();
|
|
84073
|
-
import { existsSync as existsSync22, readFileSync as
|
|
84074
|
-
import { join as
|
|
84252
|
+
import { existsSync as existsSync22, readFileSync as readFileSync23, readdirSync as readdirSync8, writeFileSync as writeFileSync17 } from "node:fs";
|
|
84253
|
+
import { join as join27 } from "node:path";
|
|
84075
84254
|
import { homedir as homedir5 } from "node:os";
|
|
84076
84255
|
var BACKFILL_VERSION = 1;
|
|
84077
84256
|
var EMPTY = {
|
|
@@ -84085,13 +84264,13 @@ var EMPTY = {
|
|
|
84085
84264
|
recoverable: 0
|
|
84086
84265
|
};
|
|
84087
84266
|
function markerPath(configDir) {
|
|
84088
|
-
return
|
|
84267
|
+
return join27(configDir, "constraint-backfill.json");
|
|
84089
84268
|
}
|
|
84090
84269
|
function alreadyDone(configDir) {
|
|
84091
84270
|
const p = markerPath(configDir);
|
|
84092
84271
|
if (!existsSync22(p)) return false;
|
|
84093
84272
|
try {
|
|
84094
|
-
const raw2 = JSON.parse(
|
|
84273
|
+
const raw2 = JSON.parse(readFileSync23(p, "utf8"));
|
|
84095
84274
|
return raw2?.version === BACKFILL_VERSION;
|
|
84096
84275
|
} catch {
|
|
84097
84276
|
return false;
|
|
@@ -84111,7 +84290,7 @@ function replay(root) {
|
|
|
84111
84290
|
for (const f of names) {
|
|
84112
84291
|
let lines;
|
|
84113
84292
|
try {
|
|
84114
|
-
lines =
|
|
84293
|
+
lines = readFileSync23(join27(dir, f), "utf8").split("\n");
|
|
84115
84294
|
} catch {
|
|
84116
84295
|
continue;
|
|
84117
84296
|
}
|
|
@@ -84225,7 +84404,7 @@ function backfillConstraintKind(store, opts) {
|
|
|
84225
84404
|
}
|
|
84226
84405
|
});
|
|
84227
84406
|
try {
|
|
84228
|
-
|
|
84407
|
+
writeFileSync17(
|
|
84229
84408
|
markerPath(opts.configDir),
|
|
84230
84409
|
JSON.stringify({ version: BACKFILL_VERSION, at: opts.now, ...report, cloudTwins: report.cloudTwins.length }, null, 2),
|
|
84231
84410
|
"utf8"
|
|
@@ -84238,8 +84417,8 @@ function backfillConstraintKind(store, opts) {
|
|
|
84238
84417
|
// src/edge-repair.ts
|
|
84239
84418
|
init_src();
|
|
84240
84419
|
init_src5();
|
|
84241
|
-
import { existsSync as existsSync23, readFileSync as
|
|
84242
|
-
import { join as
|
|
84420
|
+
import { existsSync as existsSync23, readFileSync as readFileSync24, writeFileSync as writeFileSync18 } from "node:fs";
|
|
84421
|
+
import { join as join28 } from "node:path";
|
|
84243
84422
|
function citeEdgeId(from, type, to) {
|
|
84244
84423
|
return `edge_${digest({ from, type, to })}`.slice(0, 24);
|
|
84245
84424
|
}
|
|
@@ -84254,13 +84433,13 @@ var EMPTY2 = {
|
|
|
84254
84433
|
byType: {}
|
|
84255
84434
|
};
|
|
84256
84435
|
function markerPath2(configDir) {
|
|
84257
|
-
return
|
|
84436
|
+
return join28(configDir, "edge-repair.json");
|
|
84258
84437
|
}
|
|
84259
84438
|
function alreadyDone2(configDir) {
|
|
84260
84439
|
const p = markerPath2(configDir);
|
|
84261
84440
|
if (!existsSync23(p)) return false;
|
|
84262
84441
|
try {
|
|
84263
|
-
return JSON.parse(
|
|
84442
|
+
return JSON.parse(readFileSync24(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
|
|
84264
84443
|
} catch {
|
|
84265
84444
|
return false;
|
|
84266
84445
|
}
|
|
@@ -84309,7 +84488,7 @@ function repairInvalidEdges(store, opts) {
|
|
|
84309
84488
|
});
|
|
84310
84489
|
store.pruneEdgeRejections(opts.now - REJECTION_RETENTION_MS);
|
|
84311
84490
|
try {
|
|
84312
|
-
|
|
84491
|
+
writeFileSync18(
|
|
84313
84492
|
markerPath2(opts.configDir),
|
|
84314
84493
|
JSON.stringify({ version: EDGE_REPAIR_VERSION, at: opts.now, ...report }, null, 2),
|
|
84315
84494
|
"utf8"
|
|
@@ -84323,8 +84502,8 @@ function repairInvalidEdges(store, opts) {
|
|
|
84323
84502
|
init_reconcile();
|
|
84324
84503
|
|
|
84325
84504
|
// src/pass-ledger.ts
|
|
84326
|
-
import { appendFileSync as appendFileSync2, existsSync as existsSync24, readFileSync as
|
|
84327
|
-
import { join as
|
|
84505
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync24, readFileSync as readFileSync25, writeFileSync as writeFileSync19 } from "node:fs";
|
|
84506
|
+
import { join as join29 } from "node:path";
|
|
84328
84507
|
|
|
84329
84508
|
// src/isolate-census.ts
|
|
84330
84509
|
var live3 = 0;
|
|
@@ -84355,7 +84534,7 @@ var HOUR_MS = 36e5;
|
|
|
84355
84534
|
var TRIM_EVERY = 50;
|
|
84356
84535
|
var appendsSinceTrim = /* @__PURE__ */ new Map();
|
|
84357
84536
|
function passLedgerPath(configDir) {
|
|
84358
|
-
return
|
|
84537
|
+
return join29(configDir, "pass-ledger.jsonl");
|
|
84359
84538
|
}
|
|
84360
84539
|
function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
84361
84540
|
const path3 = passLedgerPath(configDir);
|
|
@@ -84387,7 +84566,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
|
84387
84566
|
return;
|
|
84388
84567
|
}
|
|
84389
84568
|
appendsSinceTrim.set(path3, 0);
|
|
84390
|
-
const lines =
|
|
84569
|
+
const lines = readFileSync25(path3, "utf8").split("\n").filter(Boolean);
|
|
84391
84570
|
const keptByKind = /* @__PURE__ */ new Map();
|
|
84392
84571
|
const tailHours = /* @__PURE__ */ new Map();
|
|
84393
84572
|
const tailFloor = Date.now() - LEVEL_TAIL_DAYS * 24 * HOUR_MS;
|
|
@@ -84415,7 +84594,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
|
84415
84594
|
kept.push(lines[i2]);
|
|
84416
84595
|
}
|
|
84417
84596
|
if (kept.length < lines.length) {
|
|
84418
|
-
|
|
84597
|
+
writeFileSync19(path3, kept.reverse().join("\n") + "\n");
|
|
84419
84598
|
}
|
|
84420
84599
|
} catch {
|
|
84421
84600
|
}
|
|
@@ -84424,7 +84603,7 @@ function readPassLedger(configDir) {
|
|
|
84424
84603
|
const path3 = passLedgerPath(configDir);
|
|
84425
84604
|
if (!existsSync24(path3)) return [];
|
|
84426
84605
|
try {
|
|
84427
|
-
return
|
|
84606
|
+
return readFileSync25(path3, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
|
|
84428
84607
|
(e) => typeof e?.ts === "number" && typeof e?.kind === "string" && typeof e?.durationMs === "number"
|
|
84429
84608
|
).map((e) => ({ ...e, counts: e.counts ?? {} }));
|
|
84430
84609
|
} catch {
|
|
@@ -84867,11 +85046,11 @@ init_outbox();
|
|
|
84867
85046
|
init_src10();
|
|
84868
85047
|
init_src();
|
|
84869
85048
|
init_src2();
|
|
84870
|
-
import { readFileSync as
|
|
84871
|
-
import { join as
|
|
85049
|
+
import { readFileSync as readFileSync26 } from "node:fs";
|
|
85050
|
+
import { join as join30 } from "node:path";
|
|
84872
85051
|
function loadClaimIgnorePatterns(workspaceRoot) {
|
|
84873
85052
|
try {
|
|
84874
|
-
return
|
|
85053
|
+
return readFileSync26(join30(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
|
|
84875
85054
|
} catch {
|
|
84876
85055
|
return [];
|
|
84877
85056
|
}
|
|
@@ -85254,9 +85433,9 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
|
|
|
85254
85433
|
// src/retrieval-stack.ts
|
|
85255
85434
|
init_src();
|
|
85256
85435
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
85257
|
-
import { existsSync as existsSync25, readFileSync as
|
|
85436
|
+
import { existsSync as existsSync25, readFileSync as readFileSync27, statSync as statSync11 } from "node:fs";
|
|
85258
85437
|
import { homedir as homedir6 } from "node:os";
|
|
85259
|
-
import { join as
|
|
85438
|
+
import { join as join31 } from "node:path";
|
|
85260
85439
|
var RETRIEVAL_STACK_CAP = 24;
|
|
85261
85440
|
var MANIFEST_SCAN_CAP = 400;
|
|
85262
85441
|
var RUNTIME_TOKENS = /* @__PURE__ */ new Set([
|
|
@@ -85546,51 +85725,51 @@ function mavenGroupIsSelfDisclosing(name2, selfTokens) {
|
|
|
85546
85725
|
function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
|
|
85547
85726
|
const read2 = (p) => {
|
|
85548
85727
|
try {
|
|
85549
|
-
return
|
|
85728
|
+
return readFileSync27(p, "utf8");
|
|
85550
85729
|
} catch {
|
|
85551
85730
|
return null;
|
|
85552
85731
|
}
|
|
85553
85732
|
};
|
|
85554
85733
|
const texts = (...paths) => paths.map(read2).filter((t) => t !== null);
|
|
85555
85734
|
const home = homedir6();
|
|
85556
|
-
const npm = parseNpmrcPolicy(texts(
|
|
85735
|
+
const npm = parseNpmrcPolicy(texts(join31(root, ".npmrc"), join31(home, ".npmrc")));
|
|
85557
85736
|
const blocked = /* @__PURE__ */ new Set();
|
|
85558
85737
|
if (!npm.defaultPublic) blocked.add("npm");
|
|
85559
85738
|
if (pypiIndexIsPrivate(
|
|
85560
85739
|
texts(
|
|
85561
|
-
|
|
85562
|
-
|
|
85563
|
-
|
|
85564
|
-
|
|
85565
|
-
|
|
85566
|
-
|
|
85567
|
-
|
|
85740
|
+
join31(root, "pip.conf"),
|
|
85741
|
+
join31(root, "pip.ini"),
|
|
85742
|
+
join31(root, "pyproject.toml"),
|
|
85743
|
+
join31(root, "requirements.txt"),
|
|
85744
|
+
join31(home, ".pip", "pip.conf"),
|
|
85745
|
+
join31(home, ".config", "pip", "pip.conf"),
|
|
85746
|
+
join31(env2["APPDATA"] ?? home, "pip", "pip.ini")
|
|
85568
85747
|
)
|
|
85569
85748
|
)) {
|
|
85570
85749
|
blocked.add("pypi");
|
|
85571
85750
|
}
|
|
85572
85751
|
if (cargoRegistryIsPrivate(
|
|
85573
85752
|
texts(
|
|
85574
|
-
|
|
85575
|
-
|
|
85576
|
-
|
|
85577
|
-
|
|
85753
|
+
join31(root, ".cargo", "config.toml"),
|
|
85754
|
+
join31(root, ".cargo", "config"),
|
|
85755
|
+
join31(home, ".cargo", "config.toml"),
|
|
85756
|
+
join31(home, ".cargo", "config")
|
|
85578
85757
|
)
|
|
85579
85758
|
)) {
|
|
85580
85759
|
blocked.add("cargo");
|
|
85581
85760
|
}
|
|
85582
85761
|
if (nugetSourcesArePrivate(
|
|
85583
85762
|
texts(
|
|
85584
|
-
|
|
85585
|
-
|
|
85586
|
-
|
|
85587
|
-
|
|
85588
|
-
|
|
85763
|
+
join31(root, "NuGet.config"),
|
|
85764
|
+
join31(root, "nuget.config"),
|
|
85765
|
+
join31(root, "NuGet.Config"),
|
|
85766
|
+
join31(env2["APPDATA"] ?? home, "NuGet", "NuGet.Config"),
|
|
85767
|
+
join31(home, ".nuget", "NuGet", "NuGet.Config")
|
|
85589
85768
|
)
|
|
85590
85769
|
)) {
|
|
85591
85770
|
blocked.add("nuget");
|
|
85592
85771
|
}
|
|
85593
|
-
const goEnvFile = env2["GOENV"] ??
|
|
85772
|
+
const goEnvFile = env2["GOENV"] ?? join31(env2["APPDATA"] ?? join31(home, ".config"), "go", "env");
|
|
85594
85773
|
const goEnvText = read2(goEnvFile) ?? "";
|
|
85595
85774
|
const fromFile = ["GOPRIVATE", "GONOSUMDB", "GONOSUMCHECK"].map(
|
|
85596
85775
|
(k) => new RegExp(`^${k}=(.*)$`, "m").exec(goEnvText)?.[1]
|
|
@@ -85601,10 +85780,10 @@ function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
|
|
|
85601
85780
|
env2["GONOSUMCHECK"],
|
|
85602
85781
|
...fromFile
|
|
85603
85782
|
]);
|
|
85604
|
-
const gemfiles = texts(
|
|
85783
|
+
const gemfiles = texts(join31(root, "Gemfile"));
|
|
85605
85784
|
if (gemSourceIsPrivate(gemfiles)) blocked.add("gem");
|
|
85606
85785
|
if (mavenReposArePrivate(
|
|
85607
|
-
texts(
|
|
85786
|
+
texts(join31(root, "pom.xml"), join31(home, ".m2", "settings.xml"))
|
|
85608
85787
|
)) {
|
|
85609
85788
|
blocked.add("maven");
|
|
85610
85789
|
}
|
|
@@ -85676,7 +85855,7 @@ function isLocalSpec(version3) {
|
|
|
85676
85855
|
return v.startsWith("workspace:") || v.startsWith("link:") || v.startsWith("file:") || v.startsWith("portal:") || v.startsWith("path:") || v.startsWith("git:") || v.startsWith("git+") || v.includes("://") || VCS_HOST_SHORTHAND.test(v) || SCP_STYLE_REMOTE.test(v) || BARE_REPO_SHORTHAND.test(v);
|
|
85677
85856
|
}
|
|
85678
85857
|
function retrievalStackTokens(input) {
|
|
85679
|
-
const
|
|
85858
|
+
const cap2 = input.cap ?? RETRIEVAL_STACK_CAP;
|
|
85680
85859
|
const registry2 = input.registry ?? PUBLIC_REGISTRY_POLICY;
|
|
85681
85860
|
const ignore2 = input.ignorePatterns ?? [];
|
|
85682
85861
|
const ignored = (token) => ignore2.length > 0 && ignore2.some((p) => token.includes(p));
|
|
@@ -85734,10 +85913,10 @@ function retrievalStackTokens(input) {
|
|
|
85734
85913
|
}
|
|
85735
85914
|
const queues = [...byEcosystem.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([ecosystem, cs]) => ({ ecosystem, items: rankCandidates(cs) }));
|
|
85736
85915
|
const usedEcosystems = /* @__PURE__ */ new Set();
|
|
85737
|
-
for (let round2 = 0; tokens.length <
|
|
85916
|
+
for (let round2 = 0; tokens.length < cap2; round2++) {
|
|
85738
85917
|
let emittedThisRound = false;
|
|
85739
85918
|
for (const q of queues) {
|
|
85740
|
-
if (tokens.length >=
|
|
85919
|
+
if (tokens.length >= cap2) break;
|
|
85741
85920
|
const c = q.items[round2];
|
|
85742
85921
|
if (!c) continue;
|
|
85743
85922
|
emittedThisRound = true;
|
|
@@ -85750,14 +85929,14 @@ function retrievalStackTokens(input) {
|
|
|
85750
85929
|
}
|
|
85751
85930
|
if (packagesAllowed) {
|
|
85752
85931
|
for (const t of normStackTokens(input.profileStack)) {
|
|
85753
|
-
if (tokens.length >=
|
|
85932
|
+
if (tokens.length >= cap2) break;
|
|
85754
85933
|
if (isRuntimeToken(t)) continue;
|
|
85755
85934
|
if (!isPublicDep({ ecosystem: "npm", name: t }, registry2)) continue;
|
|
85756
85935
|
push(t);
|
|
85757
85936
|
}
|
|
85758
85937
|
}
|
|
85759
85938
|
const source = fromLockfile > 0 && fromManifest > 0 ? "both" : fromLockfile > 0 ? "lockfile" : fromManifest > 0 ? "manifest" : "profile";
|
|
85760
|
-
return { tokens: tokens.slice(0,
|
|
85939
|
+
return { tokens: tokens.slice(0, cap2), source, ecosystems: [...usedEcosystems].sort() };
|
|
85761
85940
|
}
|
|
85762
85941
|
var LOCKFILES = [
|
|
85763
85942
|
{ file: "pnpm-lock.yaml", family: "npm", parse: parsePnpmLock },
|
|
@@ -85771,7 +85950,7 @@ function readDirectDependencies(root) {
|
|
|
85771
85950
|
const familiesSeen = /* @__PURE__ */ new Set();
|
|
85772
85951
|
for (const c of LOCKFILES) {
|
|
85773
85952
|
if (familiesSeen.has(c.family)) continue;
|
|
85774
|
-
const p =
|
|
85953
|
+
const p = join31(root, c.file);
|
|
85775
85954
|
if (!existsSync25(p)) continue;
|
|
85776
85955
|
try {
|
|
85777
85956
|
const s = statSync11(p);
|
|
@@ -85792,7 +85971,7 @@ function readDirectDependencies(root) {
|
|
|
85792
85971
|
const direct = [];
|
|
85793
85972
|
for (const { c, path: path3 } of found) {
|
|
85794
85973
|
try {
|
|
85795
|
-
direct.push(...c.parse(
|
|
85974
|
+
direct.push(...c.parse(readFileSync27(path3, "utf8")).direct ?? []);
|
|
85796
85975
|
} catch {
|
|
85797
85976
|
}
|
|
85798
85977
|
}
|
|
@@ -85835,14 +86014,14 @@ function manifestPaths(root) {
|
|
|
85835
86014
|
"project.godot"
|
|
85836
86015
|
];
|
|
85837
86016
|
return {
|
|
85838
|
-
paths: ROOT_MANIFESTS.filter((f) => existsSync25(
|
|
86017
|
+
paths: ROOT_MANIFESTS.filter((f) => existsSync25(join31(root, f))),
|
|
85839
86018
|
tracked: false,
|
|
85840
86019
|
truncated: false
|
|
85841
86020
|
};
|
|
85842
86021
|
}
|
|
85843
86022
|
var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
|
|
85844
86023
|
function rootDeclaresWorkspace(root, texts) {
|
|
85845
|
-
if (WORKSPACE_MARKERS.some((f) => existsSync25(
|
|
86024
|
+
if (WORKSPACE_MARKERS.some((f) => existsSync25(join31(root, f)))) return true;
|
|
85846
86025
|
return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
|
|
85847
86026
|
}
|
|
85848
86027
|
var EMPTY_SCAN = { deps: [], self: [], complete: true };
|
|
@@ -85856,11 +86035,11 @@ function scanManifests(root) {
|
|
|
85856
86035
|
const texts = /* @__PURE__ */ new Map();
|
|
85857
86036
|
const stamps = [];
|
|
85858
86037
|
for (const rel of paths) {
|
|
85859
|
-
const abs =
|
|
86038
|
+
const abs = join31(root, rel);
|
|
85860
86039
|
try {
|
|
85861
86040
|
const s = statSync11(abs);
|
|
85862
86041
|
stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
|
|
85863
|
-
texts.set(rel,
|
|
86042
|
+
texts.set(rel, readFileSync27(abs, "utf8"));
|
|
85864
86043
|
} catch {
|
|
85865
86044
|
}
|
|
85866
86045
|
}
|
|
@@ -85896,22 +86075,22 @@ function readRetrievalInputs(root, repoLocator) {
|
|
|
85896
86075
|
}
|
|
85897
86076
|
|
|
85898
86077
|
// src/git-sensor.ts
|
|
85899
|
-
import { existsSync as existsSync26, readFileSync as
|
|
85900
|
-
import { join as
|
|
86078
|
+
import { existsSync as existsSync26, readFileSync as readFileSync28, watch as fsWatch } from "node:fs";
|
|
86079
|
+
import { join as join32 } from "node:path";
|
|
85901
86080
|
function readFirstLine(path3) {
|
|
85902
86081
|
try {
|
|
85903
|
-
return
|
|
86082
|
+
return readFileSync28(path3, "utf8").split(/\r?\n/, 1)[0].trim();
|
|
85904
86083
|
} catch {
|
|
85905
86084
|
return null;
|
|
85906
86085
|
}
|
|
85907
86086
|
}
|
|
85908
86087
|
function readGitRefState(gitDir) {
|
|
85909
|
-
const head2 = readFirstLine(
|
|
86088
|
+
const head2 = readFirstLine(join32(gitDir, "HEAD"));
|
|
85910
86089
|
const m = head2 ? /^ref:\s*refs\/heads\/(.+)$/.exec(head2) : null;
|
|
85911
86090
|
const branch = m ? m[1] : null;
|
|
85912
86091
|
let sha2 = null;
|
|
85913
86092
|
if (branch) {
|
|
85914
|
-
sha2 = readFirstLine(
|
|
86093
|
+
sha2 = readFirstLine(join32(gitDir, "refs", "heads", branch));
|
|
85915
86094
|
if (!sha2) sha2 = shaFromPackedRefs(gitDir, `refs/heads/${branch}`);
|
|
85916
86095
|
} else if (head2 && /^[0-9a-f]{7,40}$/i.test(head2)) {
|
|
85917
86096
|
sha2 = head2;
|
|
@@ -85919,13 +86098,13 @@ function readGitRefState(gitDir) {
|
|
|
85919
86098
|
return {
|
|
85920
86099
|
branch,
|
|
85921
86100
|
sha: sha2,
|
|
85922
|
-
mergeHeadExists: existsSync26(
|
|
85923
|
-
origHeadExists: existsSync26(
|
|
86101
|
+
mergeHeadExists: existsSync26(join32(gitDir, "MERGE_HEAD")),
|
|
86102
|
+
origHeadExists: existsSync26(join32(gitDir, "ORIG_HEAD"))
|
|
85924
86103
|
};
|
|
85925
86104
|
}
|
|
85926
86105
|
function shaFromPackedRefs(gitDir, ref) {
|
|
85927
86106
|
try {
|
|
85928
|
-
for (const line of
|
|
86107
|
+
for (const line of readFileSync28(join32(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
|
|
85929
86108
|
const [sha2, name2] = line.split(/\s+/);
|
|
85930
86109
|
if (name2 === ref && sha2) return sha2;
|
|
85931
86110
|
}
|
|
@@ -85959,7 +86138,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
85959
86138
|
const settle = () => {
|
|
85960
86139
|
if (timer) clearTimeout(timer);
|
|
85961
86140
|
timer = setTimeout(() => {
|
|
85962
|
-
if (existsSync26(
|
|
86141
|
+
if (existsSync26(join32(gitDir, "index.lock"))) {
|
|
85963
86142
|
settle();
|
|
85964
86143
|
return;
|
|
85965
86144
|
}
|
|
@@ -85970,7 +86149,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
85970
86149
|
}, debounceMs);
|
|
85971
86150
|
};
|
|
85972
86151
|
for (const sub of ["HEAD", "logs/HEAD", "MERGE_HEAD", "ORIG_HEAD"]) {
|
|
85973
|
-
const p =
|
|
86152
|
+
const p = join32(gitDir, sub);
|
|
85974
86153
|
try {
|
|
85975
86154
|
watchers.push(fsWatch(p, settle));
|
|
85976
86155
|
} catch {
|
|
@@ -86200,8 +86379,8 @@ var TelemetryRecorder = class {
|
|
|
86200
86379
|
};
|
|
86201
86380
|
|
|
86202
86381
|
// src/file-activity.ts
|
|
86203
|
-
import { readFileSync as
|
|
86204
|
-
import { join as
|
|
86382
|
+
import { readFileSync as readFileSync30 } from "node:fs";
|
|
86383
|
+
import { join as join34 } from "node:path";
|
|
86205
86384
|
import { createHash as createHash17 } from "node:crypto";
|
|
86206
86385
|
|
|
86207
86386
|
// ../../packages/privacy/src/patterns/credentials.ts
|
|
@@ -86953,8 +87132,8 @@ init_git_remote();
|
|
|
86953
87132
|
// src/history-bundle.ts
|
|
86954
87133
|
init_src();
|
|
86955
87134
|
import { execFile as execFile3 } from "node:child_process";
|
|
86956
|
-
import { readFileSync as
|
|
86957
|
-
import { join as
|
|
87135
|
+
import { readFileSync as readFileSync29 } from "node:fs";
|
|
87136
|
+
import { join as join33 } from "node:path";
|
|
86958
87137
|
var DEFAULT_MAX_TOKENS = 6e3;
|
|
86959
87138
|
var FILE_LIST_CAP = 60;
|
|
86960
87139
|
var DIFF_FILE_CAP = 40;
|
|
@@ -86993,7 +87172,7 @@ function pathAllowedByFloor(path3) {
|
|
|
86993
87172
|
function loadRepoIgnore(root, extraPatterns = []) {
|
|
86994
87173
|
let source = "";
|
|
86995
87174
|
try {
|
|
86996
|
-
source =
|
|
87175
|
+
source = readFileSync29(join33(root, ".errataignore"), "utf8");
|
|
86997
87176
|
} catch {
|
|
86998
87177
|
source = "";
|
|
86999
87178
|
}
|
|
@@ -87298,7 +87477,7 @@ function readActivityBranch(root) {
|
|
|
87298
87477
|
try {
|
|
87299
87478
|
const gitDir = resolveGitDir(root);
|
|
87300
87479
|
if (!gitDir) return null;
|
|
87301
|
-
const head2 =
|
|
87480
|
+
const head2 = readFileSync30(join34(gitDir, "HEAD"), "utf8").trim();
|
|
87302
87481
|
const branch = head2.startsWith("ref: refs/heads/") ? head2.slice(16) : /^[a-f0-9]{40,64}$/i.test(head2) ? "HEAD" : null;
|
|
87303
87482
|
return branch && branch.length <= 256 && !/[\x00-\x1f\x7f]/.test(branch) ? branch : null;
|
|
87304
87483
|
} catch {
|
|
@@ -87457,19 +87636,19 @@ var FileActivityReporter = class {
|
|
|
87457
87636
|
import {
|
|
87458
87637
|
existsSync as existsSync27,
|
|
87459
87638
|
mkdirSync as mkdirSync7,
|
|
87460
|
-
readFileSync as
|
|
87639
|
+
readFileSync as readFileSync31,
|
|
87461
87640
|
readdirSync as readdirSync9,
|
|
87462
87641
|
unlinkSync as unlinkSync4,
|
|
87463
|
-
writeFileSync as
|
|
87642
|
+
writeFileSync as writeFileSync20
|
|
87464
87643
|
} from "node:fs";
|
|
87465
|
-
import { basename as basename7, join as
|
|
87644
|
+
import { basename as basename7, join as join35 } from "node:path";
|
|
87466
87645
|
function skillFileName(id) {
|
|
87467
87646
|
return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
|
|
87468
87647
|
}
|
|
87469
87648
|
function readSkillManifest(manifestPath) {
|
|
87470
87649
|
if (!existsSync27(manifestPath)) return [];
|
|
87471
87650
|
try {
|
|
87472
|
-
const parsed = JSON.parse(
|
|
87651
|
+
const parsed = JSON.parse(readFileSync31(manifestPath, "utf8"));
|
|
87473
87652
|
return (parsed.skills ?? []).map((s) => ({
|
|
87474
87653
|
title: s.title ?? "",
|
|
87475
87654
|
layer: s.layer ?? "technique",
|
|
@@ -87493,7 +87672,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
87493
87672
|
for (const s of res.skills) {
|
|
87494
87673
|
const fileName = skillFileName(s.id);
|
|
87495
87674
|
keep.add(fileName);
|
|
87496
|
-
|
|
87675
|
+
writeFileSync20(join35(paths.skillsDir, fileName), s.markdown, "utf8");
|
|
87497
87676
|
rows.push({
|
|
87498
87677
|
id: s.id,
|
|
87499
87678
|
title: s.title,
|
|
@@ -87506,7 +87685,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
87506
87685
|
const fileName = skillFileName(p.id);
|
|
87507
87686
|
if (keep.has(fileName)) continue;
|
|
87508
87687
|
keep.add(fileName);
|
|
87509
|
-
|
|
87688
|
+
writeFileSync20(join35(paths.skillsDir, fileName), p.markdown, "utf8");
|
|
87510
87689
|
rows.push({
|
|
87511
87690
|
id: p.id,
|
|
87512
87691
|
title: p.title,
|
|
@@ -87520,13 +87699,13 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
87520
87699
|
if (!f.endsWith(".md")) continue;
|
|
87521
87700
|
if (keep.has(basename7(f))) continue;
|
|
87522
87701
|
try {
|
|
87523
|
-
unlinkSync4(
|
|
87702
|
+
unlinkSync4(join35(paths.skillsDir, f));
|
|
87524
87703
|
pruned++;
|
|
87525
87704
|
} catch {
|
|
87526
87705
|
}
|
|
87527
87706
|
}
|
|
87528
87707
|
rows.sort((a, b) => a.id.localeCompare(b.id));
|
|
87529
|
-
|
|
87708
|
+
writeFileSync20(
|
|
87530
87709
|
paths.skillsManifest,
|
|
87531
87710
|
JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
|
|
87532
87711
|
"utf8"
|
|
@@ -87541,19 +87720,19 @@ import {
|
|
|
87541
87720
|
existsSync as existsSync28,
|
|
87542
87721
|
lstatSync,
|
|
87543
87722
|
mkdirSync as mkdirSync8,
|
|
87544
|
-
readFileSync as
|
|
87723
|
+
readFileSync as readFileSync32,
|
|
87545
87724
|
readdirSync as readdirSync10,
|
|
87546
87725
|
rmSync as rmSync3,
|
|
87547
87726
|
symlinkSync,
|
|
87548
|
-
writeFileSync as
|
|
87727
|
+
writeFileSync as writeFileSync21
|
|
87549
87728
|
} from "node:fs";
|
|
87550
|
-
import { join as
|
|
87729
|
+
import { join as join36 } from "node:path";
|
|
87551
87730
|
var SKILL_NS = "errata-";
|
|
87552
87731
|
var HARNESS_SKILL_DIRS = [
|
|
87553
|
-
{ configDir: ".claude", skillsDir:
|
|
87732
|
+
{ configDir: ".claude", skillsDir: join36(".claude", "skills") },
|
|
87554
87733
|
// Cursor adopted the standard; its exact project dir is still moving — kept
|
|
87555
87734
|
// best-effort and gated on `.cursor/` presence so we never create it blind.
|
|
87556
|
-
{ configDir: ".cursor", skillsDir:
|
|
87735
|
+
{ configDir: ".cursor", skillsDir: join36(".cursor", "skills") }
|
|
87557
87736
|
];
|
|
87558
87737
|
function skillSlug(title, id) {
|
|
87559
87738
|
const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
|
|
@@ -87603,7 +87782,7 @@ function reconcileNamespaced(dir, keep) {
|
|
|
87603
87782
|
for (const name2 of readdirSync10(dir)) {
|
|
87604
87783
|
if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
|
|
87605
87784
|
try {
|
|
87606
|
-
rmSync3(
|
|
87785
|
+
rmSync3(join36(dir, name2), { recursive: true, force: true });
|
|
87607
87786
|
pruned++;
|
|
87608
87787
|
} catch {
|
|
87609
87788
|
}
|
|
@@ -87633,7 +87812,7 @@ function safeLstat(p) {
|
|
|
87633
87812
|
}
|
|
87634
87813
|
}
|
|
87635
87814
|
function emitAndProjectSkills(root, skills) {
|
|
87636
|
-
const agentsSkillsDir =
|
|
87815
|
+
const agentsSkillsDir = join36(root, ".agents", "skills");
|
|
87637
87816
|
mkdirSync8(agentsSkillsDir, { recursive: true });
|
|
87638
87817
|
const slugs = [];
|
|
87639
87818
|
const keep = /* @__PURE__ */ new Set();
|
|
@@ -87641,7 +87820,7 @@ function emitAndProjectSkills(root, skills) {
|
|
|
87641
87820
|
for (const s of skills) {
|
|
87642
87821
|
let body2;
|
|
87643
87822
|
try {
|
|
87644
|
-
body2 =
|
|
87823
|
+
body2 = readFileSync32(s.bodyPath, "utf8");
|
|
87645
87824
|
} catch {
|
|
87646
87825
|
continue;
|
|
87647
87826
|
}
|
|
@@ -87650,9 +87829,9 @@ function emitAndProjectSkills(root, skills) {
|
|
|
87650
87829
|
keep.add(slug2);
|
|
87651
87830
|
slugs.push(slug2);
|
|
87652
87831
|
const description = deriveDescription(s.title, s.layer, body2);
|
|
87653
|
-
mkdirSync8(
|
|
87654
|
-
|
|
87655
|
-
|
|
87832
|
+
mkdirSync8(join36(agentsSkillsDir, slug2), { recursive: true });
|
|
87833
|
+
writeFileSync21(
|
|
87834
|
+
join36(agentsSkillsDir, slug2, "SKILL.md"),
|
|
87656
87835
|
renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
|
|
87657
87836
|
"utf8"
|
|
87658
87837
|
);
|
|
@@ -87661,11 +87840,11 @@ function emitAndProjectSkills(root, skills) {
|
|
|
87661
87840
|
reconcileNamespaced(agentsSkillsDir, keep);
|
|
87662
87841
|
let projected = 0;
|
|
87663
87842
|
for (const h of HARNESS_SKILL_DIRS) {
|
|
87664
|
-
if (!existsSync28(
|
|
87665
|
-
const dir =
|
|
87843
|
+
if (!existsSync28(join36(root, h.configDir))) continue;
|
|
87844
|
+
const dir = join36(root, h.skillsDir);
|
|
87666
87845
|
mkdirSync8(dir, { recursive: true });
|
|
87667
87846
|
for (const slug2 of slugs) {
|
|
87668
|
-
linkOrCopy(
|
|
87847
|
+
linkOrCopy(join36(dir, slug2), join36(agentsSkillsDir, slug2));
|
|
87669
87848
|
projected++;
|
|
87670
87849
|
}
|
|
87671
87850
|
reconcileNamespaced(dir, keep);
|
|
@@ -87676,13 +87855,13 @@ function emitAndProjectSkills(root, skills) {
|
|
|
87676
87855
|
function emitInputsFromManifest(erretaDir, manifestPath) {
|
|
87677
87856
|
if (!existsSync28(manifestPath)) return [];
|
|
87678
87857
|
try {
|
|
87679
|
-
const parsed = JSON.parse(
|
|
87858
|
+
const parsed = JSON.parse(readFileSync32(manifestPath, "utf8"));
|
|
87680
87859
|
return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
|
|
87681
87860
|
id: s.id,
|
|
87682
87861
|
title: s.title ?? s.id,
|
|
87683
87862
|
layer: s.layer ?? "technique",
|
|
87684
87863
|
confidence: s.confidence ?? 0,
|
|
87685
|
-
bodyPath:
|
|
87864
|
+
bodyPath: join36(erretaDir, s.file)
|
|
87686
87865
|
}));
|
|
87687
87866
|
} catch {
|
|
87688
87867
|
return [];
|
|
@@ -87696,17 +87875,17 @@ var GITIGNORE_LINES = [
|
|
|
87696
87875
|
".cursor/skills/errata-*/"
|
|
87697
87876
|
];
|
|
87698
87877
|
function ensureSkillGitignore(root) {
|
|
87699
|
-
const path3 =
|
|
87878
|
+
const path3 = join36(root, ".gitignore");
|
|
87700
87879
|
let current = "";
|
|
87701
87880
|
try {
|
|
87702
|
-
current = existsSync28(path3) ?
|
|
87881
|
+
current = existsSync28(path3) ? readFileSync32(path3, "utf8") : "";
|
|
87703
87882
|
} catch {
|
|
87704
87883
|
return;
|
|
87705
87884
|
}
|
|
87706
87885
|
if (current.includes(GITIGNORE_MARK)) return;
|
|
87707
87886
|
const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
|
|
87708
87887
|
try {
|
|
87709
|
-
|
|
87888
|
+
writeFileSync21(path3, `${current}${prefix}
|
|
87710
87889
|
${GITIGNORE_LINES.join("\n")}
|
|
87711
87890
|
`, "utf8");
|
|
87712
87891
|
} catch {
|
|
@@ -87896,18 +88075,18 @@ init_paths();
|
|
|
87896
88075
|
init_profile2();
|
|
87897
88076
|
|
|
87898
88077
|
// src/witness-queue.ts
|
|
87899
|
-
import { readFileSync as
|
|
87900
|
-
import { dirname as
|
|
88078
|
+
import { readFileSync as readFileSync33, renameSync as renameSync5, writeFileSync as writeFileSync22 } from "node:fs";
|
|
88079
|
+
import { dirname as dirname16, join as join37 } from "node:path";
|
|
87901
88080
|
var WITNESS_QUEUE_CAP = 500;
|
|
87902
88081
|
var WITNESS_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
87903
88082
|
var WITNESS_MAX_ATTEMPTS = 5;
|
|
87904
88083
|
function witnessQueuePath(workspaceConfigDir) {
|
|
87905
|
-
return
|
|
88084
|
+
return join37(workspaceConfigDir, "witness-queue.json");
|
|
87906
88085
|
}
|
|
87907
88086
|
function loadWitnessQueueWithLosses(path3) {
|
|
87908
88087
|
let raw2;
|
|
87909
88088
|
try {
|
|
87910
|
-
raw2 = JSON.parse(
|
|
88089
|
+
raw2 = JSON.parse(readFileSync33(path3, "utf8"));
|
|
87911
88090
|
} catch (err2) {
|
|
87912
88091
|
const absent = err2?.code === "ENOENT";
|
|
87913
88092
|
return { queue: [], fileUnreadable: !absent, malformedEntries: 0 };
|
|
@@ -87920,9 +88099,9 @@ function loadWitnessQueueWithLosses(path3) {
|
|
|
87920
88099
|
}
|
|
87921
88100
|
function saveWitnessQueue(path3, queue) {
|
|
87922
88101
|
try {
|
|
87923
|
-
const tmp =
|
|
87924
|
-
|
|
87925
|
-
|
|
88102
|
+
const tmp = join37(dirname16(path3), `.${Date.now()}.witness-queue.tmp`);
|
|
88103
|
+
writeFileSync22(tmp, JSON.stringify(queue), "utf8");
|
|
88104
|
+
renameSync5(tmp, path3);
|
|
87926
88105
|
} catch {
|
|
87927
88106
|
}
|
|
87928
88107
|
}
|
|
@@ -87940,6 +88119,9 @@ function pruneWitnessQueueWithDispositions(queue, now) {
|
|
|
87940
88119
|
}
|
|
87941
88120
|
return { queue: live4, dropped };
|
|
87942
88121
|
}
|
|
88122
|
+
function enqueueWitnesses(queue, fresh, now) {
|
|
88123
|
+
return enqueueWitnessesWithDispositions(queue, fresh, now).queue;
|
|
88124
|
+
}
|
|
87943
88125
|
function enqueueWitnessesWithDispositions(queue, fresh, now) {
|
|
87944
88126
|
const byKey = new Map(queue.map((w) => [`${w.channel}:${w.witnessKey}`, w]));
|
|
87945
88127
|
for (const f of fresh) {
|
|
@@ -88230,8 +88412,8 @@ function maybeFlushDigests() {
|
|
|
88230
88412
|
|
|
88231
88413
|
// src/liveness-watch.ts
|
|
88232
88414
|
init_src5();
|
|
88233
|
-
import { readFileSync as
|
|
88234
|
-
import { join as
|
|
88415
|
+
import { readFileSync as readFileSync35, writeFileSync as writeFileSync24 } from "node:fs";
|
|
88416
|
+
import { join as join39 } from "node:path";
|
|
88235
88417
|
|
|
88236
88418
|
// src/loop-lag.ts
|
|
88237
88419
|
var HEARTBEAT_MS = 500;
|
|
@@ -88363,11 +88545,11 @@ function watchCensusLine(c = watchCensus(), now = Date.now()) {
|
|
|
88363
88545
|
var LIVENESS_WATCH_INTERVAL_MS = 60 * 60 * 1e3;
|
|
88364
88546
|
var ALARM_RENOTIFY_MS = 24 * 60 * 60 * 1e3;
|
|
88365
88547
|
function alarmStatePath(configDir) {
|
|
88366
|
-
return
|
|
88548
|
+
return join39(configDir, "liveness-alarms.json");
|
|
88367
88549
|
}
|
|
88368
88550
|
function loadAlarmState(path3) {
|
|
88369
88551
|
try {
|
|
88370
|
-
const raw2 = JSON.parse(
|
|
88552
|
+
const raw2 = JSON.parse(readFileSync35(path3, "utf8"));
|
|
88371
88553
|
return new Map(Object.entries(raw2).filter((e) => typeof e[1] === "number"));
|
|
88372
88554
|
} catch {
|
|
88373
88555
|
return /* @__PURE__ */ new Map();
|
|
@@ -88375,7 +88557,7 @@ function loadAlarmState(path3) {
|
|
|
88375
88557
|
}
|
|
88376
88558
|
function saveAlarmState(path3, state) {
|
|
88377
88559
|
try {
|
|
88378
|
-
|
|
88560
|
+
writeFileSync24(path3, JSON.stringify(Object.fromEntries(state)));
|
|
88379
88561
|
} catch {
|
|
88380
88562
|
}
|
|
88381
88563
|
}
|
|
@@ -88631,7 +88813,7 @@ function createWatchBreaker(deps) {
|
|
|
88631
88813
|
}
|
|
88632
88814
|
|
|
88633
88815
|
// src/engine.ts
|
|
88634
|
-
var DAEMON_VERSION = true ? "2.0.23-dev.
|
|
88816
|
+
var DAEMON_VERSION = true ? "2.0.23-dev.4938" : "2.0.0-alpha.0";
|
|
88635
88817
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
88636
88818
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
88637
88819
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -88644,7 +88826,7 @@ function appendIdentityAudit(path3, record2, line) {
|
|
|
88644
88826
|
if (!record2.accepted && record2.score <= 0) return;
|
|
88645
88827
|
try {
|
|
88646
88828
|
if (existsSync30(path3) && statSync12(path3).size >= IDENTITY_AUDIT_MAX_BYTES) {
|
|
88647
|
-
|
|
88829
|
+
renameSync6(path3, `${path3}.1`);
|
|
88648
88830
|
}
|
|
88649
88831
|
appendFileSync4(path3, line);
|
|
88650
88832
|
} catch {
|
|
@@ -88653,7 +88835,7 @@ function appendIdentityAudit(path3, record2, line) {
|
|
|
88653
88835
|
var yieldToLoop = () => new Promise((r) => setImmediate(r));
|
|
88654
88836
|
function loadTurnCursors(path3) {
|
|
88655
88837
|
try {
|
|
88656
|
-
const raw2 = JSON.parse(
|
|
88838
|
+
const raw2 = JSON.parse(readFileSync36(path3, "utf8"));
|
|
88657
88839
|
return new Map(
|
|
88658
88840
|
Object.entries(raw2).map(([k, v]) => [k, typeof v === "string" ? v : String(v?.uuid ?? "")])
|
|
88659
88841
|
);
|
|
@@ -88663,7 +88845,7 @@ function loadTurnCursors(path3) {
|
|
|
88663
88845
|
}
|
|
88664
88846
|
function loadTurnOffsets(path3) {
|
|
88665
88847
|
try {
|
|
88666
|
-
const raw2 = JSON.parse(
|
|
88848
|
+
const raw2 = JSON.parse(readFileSync36(path3, "utf8"));
|
|
88667
88849
|
const out2 = /* @__PURE__ */ new Map();
|
|
88668
88850
|
for (const [k, v] of Object.entries(raw2)) {
|
|
88669
88851
|
const off2 = typeof v === "object" && v !== null ? v.offset : void 0;
|
|
@@ -88676,7 +88858,7 @@ function loadTurnOffsets(path3) {
|
|
|
88676
88858
|
}
|
|
88677
88859
|
function loadTurnMoves(path3) {
|
|
88678
88860
|
try {
|
|
88679
|
-
const raw2 = JSON.parse(
|
|
88861
|
+
const raw2 = JSON.parse(readFileSync36(path3, "utf8"));
|
|
88680
88862
|
const out2 = /* @__PURE__ */ new Map();
|
|
88681
88863
|
for (const [k, v] of Object.entries(raw2)) {
|
|
88682
88864
|
const to = typeof v === "object" && v !== null ? v.movedTo : void 0;
|
|
@@ -88693,11 +88875,11 @@ function saveTurnCursors(path3, cursors, offsets, moves = /* @__PURE__ */ new Ma
|
|
|
88693
88875
|
for (const [k, uuid3] of cursors) merged[k] = { uuid: uuid3, offset: offsets.get(k) ?? 0 };
|
|
88694
88876
|
for (const [k, offset] of offsets) if (!merged[k]) merged[k] = { uuid: "", offset };
|
|
88695
88877
|
for (const [k, movedTo] of moves) merged[k] = { ...merged[k] ?? { uuid: "", offset: 0 }, movedTo };
|
|
88696
|
-
|
|
88878
|
+
writeFileSync25(path3, JSON.stringify(merged), "utf8");
|
|
88697
88879
|
} catch {
|
|
88698
88880
|
}
|
|
88699
88881
|
}
|
|
88700
|
-
var turnCursorFile = (configDir) =>
|
|
88882
|
+
var turnCursorFile = (configDir) => join40(configDir, "turn-cursors.json");
|
|
88701
88883
|
function turnCursorOnDisk(configDir, sessionId) {
|
|
88702
88884
|
const path3 = turnCursorFile(configDir);
|
|
88703
88885
|
const offset = loadTurnOffsets(path3).get(sessionId);
|
|
@@ -88729,7 +88911,7 @@ function gitSourceWatchTargets(root) {
|
|
|
88729
88911
|
["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
|
|
88730
88912
|
{ encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
|
|
88731
88913
|
);
|
|
88732
|
-
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(
|
|
88914
|
+
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join40(root, d) + sep5));
|
|
88733
88915
|
} catch {
|
|
88734
88916
|
}
|
|
88735
88917
|
const hasIgnoredChild = (dir) => ignoredDirs.some((ig) => ig.startsWith(dir + "/"));
|
|
@@ -88741,19 +88923,19 @@ function gitSourceWatchTargets(root) {
|
|
|
88741
88923
|
if (!f.startsWith(prefix)) continue;
|
|
88742
88924
|
const rest2 = f.slice(prefix.length);
|
|
88743
88925
|
if (rest2.includes("/")) children.add(dir === "" ? rest2.slice(0, rest2.indexOf("/")) : dir + "/" + rest2.slice(0, rest2.indexOf("/")));
|
|
88744
|
-
else targets.add(
|
|
88926
|
+
else targets.add(join40(root, f));
|
|
88745
88927
|
}
|
|
88746
88928
|
for (const c of children) {
|
|
88747
|
-
if (IGNORED_PATH.test(
|
|
88929
|
+
if (IGNORED_PATH.test(join40(root, c) + sep5)) continue;
|
|
88748
88930
|
if (hasIgnoredChild(c)) addUnder(c);
|
|
88749
|
-
else targets.add(
|
|
88931
|
+
else targets.add(join40(root, c));
|
|
88750
88932
|
}
|
|
88751
88933
|
};
|
|
88752
88934
|
addUnder("");
|
|
88753
88935
|
if (targets.size > 0) return [...targets];
|
|
88754
88936
|
} catch {
|
|
88755
88937
|
}
|
|
88756
|
-
return readdirSync11(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(
|
|
88938
|
+
return readdirSync11(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join40(root, String(e.name)) + sep5)).map((e) => join40(root, String(e.name)));
|
|
88757
88939
|
}
|
|
88758
88940
|
function createWorkspaceEngine(opts) {
|
|
88759
88941
|
const paths = workspacePaths(opts.workspaceRoot);
|
|
@@ -88955,7 +89137,7 @@ function createWorkspaceEngine(opts) {
|
|
|
88955
89137
|
const srcPaths = diff.changedPaths.filter((p) => /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p));
|
|
88956
89138
|
let episodeId2;
|
|
88957
89139
|
if (srcPaths.length > 0) {
|
|
88958
|
-
const abs = srcPaths.map((p) =>
|
|
89140
|
+
const abs = srcPaths.map((p) => join40(opts.workspaceRoot, p));
|
|
88959
89141
|
try {
|
|
88960
89142
|
const r = await runReindexPass(
|
|
88961
89143
|
`git-reindex:${profile.name} (${abs.length} files)`,
|
|
@@ -88991,7 +89173,7 @@ function createWorkspaceEngine(opts) {
|
|
|
88991
89173
|
`[errata] git: ${ev.kind} ${ev.newSha.slice(0, 7)} by ${meta3.authorName} \u2014 ${diff.changedPaths.length} file(s), ${diff.renames.length} rename(s)`
|
|
88992
89174
|
);
|
|
88993
89175
|
};
|
|
88994
|
-
const gitDir =
|
|
89176
|
+
const gitDir = join40(opts.workspaceRoot, ".git");
|
|
88995
89177
|
if (existsSync30(gitDir)) {
|
|
88996
89178
|
stopGit = startGitSensor(gitDir, (ev) => {
|
|
88997
89179
|
void handleGitEvent(ev).catch((err2) => {
|
|
@@ -89053,7 +89235,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89053
89235
|
},
|
|
89054
89236
|
onAlarms: (alarms) => {
|
|
89055
89237
|
toastLivenessAlarms(
|
|
89056
|
-
sharedAlarmToastGate(
|
|
89238
|
+
sharedAlarmToastGate(join40(globalDir(), "liveness-toasts.json")),
|
|
89057
89239
|
{ root: opts.workspaceRoot, name: profile.name },
|
|
89058
89240
|
alarms,
|
|
89059
89241
|
(body2, key) => notifyEvent("mechanism-stalled", body2, { key }),
|
|
@@ -89080,10 +89262,27 @@ function createWorkspaceEngine(opts) {
|
|
|
89080
89262
|
let subagentBase = null;
|
|
89081
89263
|
let subagentBaseVersion = 0;
|
|
89082
89264
|
const subagentRenders = /* @__PURE__ */ new Map();
|
|
89083
|
-
const sessions = createSessionRegistry({ originsPath:
|
|
89265
|
+
const sessions = createSessionRegistry({ originsPath: join40(paths.configDir, "session-origins.json") });
|
|
89084
89266
|
const sessionRenders = /* @__PURE__ */ new Map();
|
|
89085
89267
|
const selfCiteSkipsBySession = /* @__PURE__ */ new Map();
|
|
89086
89268
|
const supersessionAsks = new SupersessionAsks();
|
|
89269
|
+
const heldAsks = loadHeldAsks(heldAsksPath(paths.configDir));
|
|
89270
|
+
const releaseHeld = (all, t) => {
|
|
89271
|
+
const released = all.filter((r) => store.getNode(r.witness.nodeId)?.validTo == null);
|
|
89272
|
+
if (all.length > 0 && released.length === 0) saveHeldAsks(heldAsksPath(paths.configDir), heldAsks);
|
|
89273
|
+
if (released.length === 0) return { stamped: 0, fixHeld: 0 };
|
|
89274
|
+
const { stamped } = applyLocalConfirmations(store, released.map((r) => r.witness), t);
|
|
89275
|
+
let fixHeld = 0;
|
|
89276
|
+
for (const r of released) if (store.getNode(r.witness.nodeId)?.label === "Solution") fixHeld += confirmFixHeld(store, r.witness.nodeId, t);
|
|
89277
|
+
witnessQueue = enqueueWitnesses(
|
|
89278
|
+
witnessQueue,
|
|
89279
|
+
released.map((r) => ({ channel: "corroborate", ...r.witness, sessionKey: sessionOriginKey(r.sessionId), counted: false })),
|
|
89280
|
+
Date.now()
|
|
89281
|
+
);
|
|
89282
|
+
saveWitnessQueue(witnessQueuePath(paths.configDir), witnessQueue);
|
|
89283
|
+
saveHeldAsks(heldAsksPath(paths.configDir), heldAsks);
|
|
89284
|
+
return { stamped, fixHeld };
|
|
89285
|
+
};
|
|
89087
89286
|
const toolRuns = createToolRunState();
|
|
89088
89287
|
let ctxRefreshTimer = null;
|
|
89089
89288
|
let contextDirty = false;
|
|
@@ -89163,6 +89362,23 @@ function createWorkspaceEngine(opts) {
|
|
|
89163
89362
|
const priors = a.priorIds.map((id) => store.getNode(id)).filter((n) => n !== null && n.validTo == null).map((n) => ({ id: n.id, description: n.description, ...lifecycleField(n) }));
|
|
89164
89363
|
return fix && priors.length > 0 ? [{ fix: { id: fix.id, description: fix.description }, priors }] : [];
|
|
89165
89364
|
});
|
|
89365
|
+
const heldAsksFor = (sessionId) => {
|
|
89366
|
+
const shown = [];
|
|
89367
|
+
let discarded = false;
|
|
89368
|
+
for (const a of heldAsks.forSession(sessionId)) {
|
|
89369
|
+
if (shown.length >= HELD_ASKS_SHOWN) break;
|
|
89370
|
+
const n = store.getNode(a.priorId);
|
|
89371
|
+
if (n && n.validTo != null) {
|
|
89372
|
+
heldAsks.discard(sessionId, a.priorId);
|
|
89373
|
+
discarded = true;
|
|
89374
|
+
continue;
|
|
89375
|
+
}
|
|
89376
|
+
shown.push(n ? { id: n.id, description: n.description, ...lifecycleField(n) } : { id: a.priorId });
|
|
89377
|
+
}
|
|
89378
|
+
heldAsks.markShown(sessionId, shown.map((s) => s.id));
|
|
89379
|
+
if (discarded) saveHeldAsks(heldAsksPath(paths.configDir), heldAsks);
|
|
89380
|
+
return shown;
|
|
89381
|
+
};
|
|
89166
89382
|
const statedIntentFor = (intent) => {
|
|
89167
89383
|
const collective = intentRemote?.forIntent === intent ? intentRemote : null;
|
|
89168
89384
|
return {
|
|
@@ -89185,7 +89401,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89185
89401
|
const elicit = isEdgeElicitationEnabled();
|
|
89186
89402
|
const snapOpts = {
|
|
89187
89403
|
profile,
|
|
89188
|
-
atCommit: readGitRefState(
|
|
89404
|
+
atCommit: readGitRefState(join40(opts.workspaceRoot, ".git")).sha ?? void 0,
|
|
89189
89405
|
reviewCount: pendingCount(paths),
|
|
89190
89406
|
reviewUiUrl: opts.reviewUrl(),
|
|
89191
89407
|
workingFile: workingFiles.mostRecent() ?? void 0,
|
|
@@ -89225,7 +89441,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89225
89441
|
);
|
|
89226
89442
|
return null;
|
|
89227
89443
|
}) : null;
|
|
89228
|
-
if (snapOpts.atCommit !== (readGitRefState(
|
|
89444
|
+
if (snapOpts.atCommit !== (readGitRefState(join40(opts.workspaceRoot, ".git")).sha ?? void 0)) {
|
|
89229
89445
|
contextDirty = true;
|
|
89230
89446
|
return;
|
|
89231
89447
|
}
|
|
@@ -89271,10 +89487,10 @@ function createWorkspaceEngine(opts) {
|
|
|
89271
89487
|
} catch (err2) {
|
|
89272
89488
|
console.warn("[errata] context card failed:", err2.message?.slice(0, 120));
|
|
89273
89489
|
}
|
|
89274
|
-
const target =
|
|
89490
|
+
const target = join40(opts.workspaceRoot, "AGENTS.md");
|
|
89275
89491
|
writeManagedBlock(target, { body: AGENTS_POINTER_BODY, stable: true, force: true });
|
|
89276
89492
|
if (elicit) {
|
|
89277
|
-
writePrimingHandles(
|
|
89493
|
+
writePrimingHandles(join40(paths.configDir, "priming-handles.json"), [
|
|
89278
89494
|
...snapshot.recentProblems.map((r) => r.node),
|
|
89279
89495
|
// Resolved-band handles: the ✓ problem AND its Solution are citable
|
|
89280
89496
|
// (a fix tag on an already-resolved problem no-ops idempotently; the
|
|
@@ -89582,8 +89798,8 @@ function createWorkspaceEngine(opts) {
|
|
|
89582
89798
|
const cached2 = subagentRenders.get(a.agentId);
|
|
89583
89799
|
if (cached2?.key === key) return cached2.block;
|
|
89584
89800
|
const elicit = isEdgeElicitationEnabled();
|
|
89585
|
-
const handlesPath =
|
|
89586
|
-
const atCommit = readGitRefState(
|
|
89801
|
+
const handlesPath = join40(paths.configDir, "priming-handles.json");
|
|
89802
|
+
const atCommit = readGitRefState(join40(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
89587
89803
|
const block = renderSubagentBlock({
|
|
89588
89804
|
store,
|
|
89589
89805
|
entry,
|
|
@@ -89616,8 +89832,10 @@ function createWorkspaceEngine(opts) {
|
|
|
89616
89832
|
sessions.touch(e.sessionId, now, origin);
|
|
89617
89833
|
return;
|
|
89618
89834
|
}
|
|
89619
|
-
if (e.ended)
|
|
89620
|
-
|
|
89835
|
+
if (e.ended) {
|
|
89836
|
+
sessions.end(e.sessionId);
|
|
89837
|
+
if (heldAsks.endSession(e.sessionId, now)) saveHeldAsks(heldAsksPath(paths.configDir), heldAsks);
|
|
89838
|
+
} else sessions.touch(e.sessionId, now, origin);
|
|
89621
89839
|
};
|
|
89622
89840
|
const sessionContext = (sessionId) => {
|
|
89623
89841
|
if (!sessionId || !subagentBase) return null;
|
|
@@ -89627,6 +89845,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89627
89845
|
const skips = selfCiteSkipsBySession.get(sessionId) ?? 0;
|
|
89628
89846
|
const key = JSON.stringify([
|
|
89629
89847
|
supersessionAsks.version(sessionId),
|
|
89848
|
+
heldAsks.version(sessionId),
|
|
89630
89849
|
subagentBaseVersion,
|
|
89631
89850
|
lastRemoteAt,
|
|
89632
89851
|
sessions.version(now),
|
|
@@ -89638,7 +89857,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89638
89857
|
const cached2 = sessionRenders.get(sessionId);
|
|
89639
89858
|
if (cached2?.key === key) return cached2.block;
|
|
89640
89859
|
const elicit = isEdgeElicitationEnabled();
|
|
89641
|
-
const atCommit = readGitRefState(
|
|
89860
|
+
const atCommit = readGitRefState(join40(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
89642
89861
|
const scoped = scopeSnapshot(structuredClone(subagentBase), (n) => !hiddenFrom(n, sessionId, sessions, now));
|
|
89643
89862
|
delete scoped.workingFile;
|
|
89644
89863
|
if (workingFile) {
|
|
@@ -89650,6 +89869,9 @@ function createWorkspaceEngine(opts) {
|
|
|
89650
89869
|
delete scoped.supersessionAsks;
|
|
89651
89870
|
const asks = supersessionAsksFor(sessionId);
|
|
89652
89871
|
if (asks.length > 0) scoped.supersessionAsks = asks;
|
|
89872
|
+
delete scoped.heldAsks;
|
|
89873
|
+
const held = heldAsksFor(sessionId);
|
|
89874
|
+
if (held.length > 0) scoped.heldAsks = held;
|
|
89653
89875
|
if (taskPriorsOn) {
|
|
89654
89876
|
scoped.recentProblems = [];
|
|
89655
89877
|
scoped.recentResolved = [];
|
|
@@ -89690,7 +89912,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89690
89912
|
]
|
|
89691
89913
|
};
|
|
89692
89914
|
if (elicit && block.handleNodes.length) {
|
|
89693
|
-
writePrimingHandles(
|
|
89915
|
+
writePrimingHandles(join40(paths.configDir, "priming-handles.json"), block.handleNodes);
|
|
89694
89916
|
}
|
|
89695
89917
|
sessionRenders.delete(sessionId);
|
|
89696
89918
|
sessionRenders.set(sessionId, { key, block });
|
|
@@ -89798,6 +90020,8 @@ function createWorkspaceEngine(opts) {
|
|
|
89798
90020
|
let confirmsStamped = 0;
|
|
89799
90021
|
let supersessionAsked = 0;
|
|
89800
90022
|
let structureLinksMinted = 0;
|
|
90023
|
+
let heldAsked = 0;
|
|
90024
|
+
let heldAnswered = 0;
|
|
89801
90025
|
let recurrencesMarked = 0;
|
|
89802
90026
|
let reopenedFromRegression = 0;
|
|
89803
90027
|
let fixHeldConfirmed = 0;
|
|
@@ -89824,7 +90048,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89824
90048
|
let processedTurns = 0;
|
|
89825
90049
|
const seqAtStart = store.currentIngestSeq();
|
|
89826
90050
|
const elicit = isEdgeElicitationEnabled();
|
|
89827
|
-
const handleMap = elicit ? readPrimingHandles(
|
|
90051
|
+
const handleMap = elicit ? readPrimingHandles(join40(paths.configDir, "priming-handles.json")) : {};
|
|
89828
90052
|
const wsRoot = (opts.workspaceRoot ?? "").replace(/\\/g, "/");
|
|
89829
90053
|
const toRel = (abs) => {
|
|
89830
90054
|
const p = abs.replace(/\\/g, "/");
|
|
@@ -89988,6 +90212,45 @@ function createWorkspaceEngine(opts) {
|
|
|
89988
90212
|
corroboratedEdges += plan.corroboratedEdges;
|
|
89989
90213
|
citeAnchorsAccrued += plan.citeAnchorsAccrued;
|
|
89990
90214
|
citeAnchorsPromoted += plan.citeAnchorsPromoted;
|
|
90215
|
+
{
|
|
90216
|
+
const expired = releaseHeld(heldAsks.expire(t), t);
|
|
90217
|
+
confirmsStamped += expired.stamped;
|
|
90218
|
+
fixHeldConfirmed += expired.fixHeld;
|
|
90219
|
+
}
|
|
90220
|
+
let withheldLeanIds = [];
|
|
90221
|
+
if (sessions.originOf(sessionId) === void 0) {
|
|
90222
|
+
const subagentTurn = turn.agentId != null || sessionId.startsWith("agent-");
|
|
90223
|
+
const canOpen = !subagentTurn && sessions.isLive(sessionId, t);
|
|
90224
|
+
const mintedBySession = (nodeId) => store.getNode(nodeId)?.attrs["sources"]?.[0] === sessionId;
|
|
90225
|
+
const held = heldAsks.record(
|
|
90226
|
+
sessionId,
|
|
90227
|
+
{
|
|
90228
|
+
canOpen,
|
|
90229
|
+
leaned: plan.corroborations.filter((c) => c.via === "lean" && !mintedBySession(c.nodeId)).map(({ nodeId, witnessKey }) => ({ nodeId, witnessKey })),
|
|
90230
|
+
// A subagent's verdict is its own, not an answer to the parent's question.
|
|
90231
|
+
verdicts: subagentTurn ? [] : [
|
|
90232
|
+
...plan.corroborations.filter((c) => c.via === "confirm" || c.via === "fix").map((c) => ({ priorId: c.nodeId, kind: c.via, witnessKey: c.witnessKey })),
|
|
90233
|
+
...plan.refutes.map((r) => ({ priorId: r.nodeId, kind: "refute" })),
|
|
90234
|
+
...plan.solutionLinks.flatMap((sl) => sl.targetIds.map((id) => ({ priorId: id, kind: "link" })))
|
|
90235
|
+
]
|
|
90236
|
+
},
|
|
90237
|
+
t
|
|
90238
|
+
);
|
|
90239
|
+
if (held.withheld.size > 0) {
|
|
90240
|
+
withheldLeanIds = plan.corroborations.filter((c) => c.via === "lean" && held.withheld.has(c.witnessKey)).map((c) => c.nodeId);
|
|
90241
|
+
plan.corroborations = plan.corroborations.filter((c) => !held.withheld.has(c.witnessKey));
|
|
90242
|
+
}
|
|
90243
|
+
const linked2 = releaseHeld(held.release, t);
|
|
90244
|
+
confirmsStamped += linked2.stamped;
|
|
90245
|
+
fixHeldConfirmed += linked2.fixHeld;
|
|
90246
|
+
heldAnswered += held.answeredShown.length;
|
|
90247
|
+
for (const id of held.opened) {
|
|
90248
|
+
const n = store.getNode(id);
|
|
90249
|
+
if (n) store.updateNode(id, { attrs: { ...n.attrs, heldAskedAt: t }, lastUpdatedAt: t });
|
|
90250
|
+
heldAsked++;
|
|
90251
|
+
}
|
|
90252
|
+
if (held.changed) saveHeldAsks(heldAsksPath(paths.configDir), heldAsks);
|
|
90253
|
+
}
|
|
89991
90254
|
const refuteResult = applyLocalRefutations(store, plan.refutes, t);
|
|
89992
90255
|
refutesStamped += refuteResult.stamped;
|
|
89993
90256
|
if (sessions.originOf(sessionId) === void 0) {
|
|
@@ -90047,7 +90310,7 @@ function createWorkspaceEngine(opts) {
|
|
|
90047
90310
|
let anchorReadFailed = false;
|
|
90048
90311
|
if (p.location) {
|
|
90049
90312
|
try {
|
|
90050
|
-
fileText =
|
|
90313
|
+
fileText = readFileSync36(join40(opts.workspaceRoot, p.location.path), "utf8");
|
|
90051
90314
|
} catch {
|
|
90052
90315
|
anchorReadFailed = true;
|
|
90053
90316
|
}
|
|
@@ -90210,10 +90473,10 @@ function createWorkspaceEngine(opts) {
|
|
|
90210
90473
|
let enclosing = {};
|
|
90211
90474
|
if (p.location?.line !== void 0) {
|
|
90212
90475
|
try {
|
|
90213
|
-
const headSha = readGitRefState(
|
|
90476
|
+
const headSha = readGitRefState(join40(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
90214
90477
|
enclosing = {
|
|
90215
90478
|
line: p.location.line,
|
|
90216
|
-
fileText:
|
|
90479
|
+
fileText: readFileSync36(join40(opts.workspaceRoot, anchorPath), "utf8"),
|
|
90217
90480
|
...headSha ? { headSha } : {}
|
|
90218
90481
|
};
|
|
90219
90482
|
} catch {
|
|
@@ -90502,6 +90765,7 @@ function createWorkspaceEngine(opts) {
|
|
|
90502
90765
|
/* @__PURE__ */ new Set([
|
|
90503
90766
|
...plan.solutionLinks.flatMap((sl) => sl.targetIds),
|
|
90504
90767
|
...plan.corroborations.map((c) => c.nodeId),
|
|
90768
|
+
...withheldLeanIds,
|
|
90505
90769
|
...plan.refutes.map((r) => r.nodeId)
|
|
90506
90770
|
])
|
|
90507
90771
|
);
|
|
@@ -90715,6 +90979,8 @@ function createWorkspaceEngine(opts) {
|
|
|
90715
90979
|
confirmsStamped,
|
|
90716
90980
|
supersessionAsked,
|
|
90717
90981
|
structureLinksMinted,
|
|
90982
|
+
heldAsked,
|
|
90983
|
+
heldAnswered,
|
|
90718
90984
|
// RG-recognize tier A: resolved problems the door saw recur this pass.
|
|
90719
90985
|
recurrencesMarked,
|
|
90720
90986
|
// RG-reopen: closes flipped open on the two-touch evidence bar.
|
|
@@ -91088,7 +91354,7 @@ B: ${b}`,
|
|
|
91088
91354
|
try {
|
|
91089
91355
|
const inputs = emitInputsFromManifest(paths.configDir, paths.skillsManifest);
|
|
91090
91356
|
emitAndProjectSkills(opts.workspaceRoot, inputs);
|
|
91091
|
-
writePrimingHandles(
|
|
91357
|
+
writePrimingHandles(join40(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
|
|
91092
91358
|
} catch (err2) {
|
|
91093
91359
|
console.warn("[skills] agent-skills projection failed (non-fatal):", err2 instanceof Error ? err2.message : err2);
|
|
91094
91360
|
}
|
|
@@ -91599,7 +91865,7 @@ async function startDaemon(opts) {
|
|
|
91599
91865
|
reviewUrl: () => webUiUrl + "/review"
|
|
91600
91866
|
});
|
|
91601
91867
|
const writeLockFile = (url2) => {
|
|
91602
|
-
|
|
91868
|
+
writeFileSync26(
|
|
91603
91869
|
engine.paths.daemonLock,
|
|
91604
91870
|
daemonLockPayload({ pid: process.pid, webUiUrl: url2, processStartedAt, version: DAEMON_VERSION }),
|
|
91605
91871
|
"utf8"
|
|
@@ -91852,8 +92118,8 @@ async function linkRegisteredWorkspaces(cfg, loggedInProfile = cfg.activeInstall
|
|
|
91852
92118
|
}
|
|
91853
92119
|
|
|
91854
92120
|
// src/edge-park.ts
|
|
91855
|
-
import { readFileSync as
|
|
91856
|
-
import { dirname as
|
|
92121
|
+
import { readFileSync as readFileSync37, renameSync as renameSync7, writeFileSync as writeFileSync27 } from "node:fs";
|
|
92122
|
+
import { dirname as dirname17, join as join41 } from "node:path";
|
|
91857
92123
|
var EDGE_PARK_CAP = 2e3;
|
|
91858
92124
|
var EDGE_PARK_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
91859
92125
|
var EDGE_PARK_MAX_ATTEMPTS = 6;
|
|
@@ -91868,12 +92134,12 @@ function wireEdgeKey(from, type, to) {
|
|
|
91868
92134
|
return JSON.stringify([from, type, to]);
|
|
91869
92135
|
}
|
|
91870
92136
|
function edgeParkPath(workspaceConfigDir, destinationKey) {
|
|
91871
|
-
return
|
|
92137
|
+
return join41(workspaceConfigDir, `edge-park.${destinationKey.slice(0, 16)}.json`);
|
|
91872
92138
|
}
|
|
91873
92139
|
function loadEdgePark(path3) {
|
|
91874
92140
|
let raw2;
|
|
91875
92141
|
try {
|
|
91876
|
-
raw2 = JSON.parse(
|
|
92142
|
+
raw2 = JSON.parse(readFileSync37(path3, "utf8"));
|
|
91877
92143
|
} catch {
|
|
91878
92144
|
return [];
|
|
91879
92145
|
}
|
|
@@ -91884,9 +92150,9 @@ function loadEdgePark(path3) {
|
|
|
91884
92150
|
}
|
|
91885
92151
|
function saveEdgePark(path3, queue) {
|
|
91886
92152
|
try {
|
|
91887
|
-
const tmp =
|
|
91888
|
-
|
|
91889
|
-
|
|
92153
|
+
const tmp = join41(dirname17(path3), `.${Date.now()}.edge-park.tmp`);
|
|
92154
|
+
writeFileSync27(tmp, JSON.stringify(queue), "utf8");
|
|
92155
|
+
renameSync7(tmp, path3);
|
|
91890
92156
|
} catch {
|
|
91891
92157
|
}
|
|
91892
92158
|
}
|
|
@@ -92207,8 +92473,8 @@ function invalidateInstanceReceipt(current, destination, failedId, mirrorLegacy)
|
|
|
92207
92473
|
// src/multi.ts
|
|
92208
92474
|
init_dist();
|
|
92209
92475
|
init_src5();
|
|
92210
|
-
import { existsSync as existsSync36, readFileSync as
|
|
92211
|
-
import { basename as basename10, dirname as
|
|
92476
|
+
import { existsSync as existsSync36, readFileSync as readFileSync43, writeFileSync as writeFileSync30 } from "node:fs";
|
|
92477
|
+
import { basename as basename10, dirname as dirname20, join as join50, resolve as pathResolve } from "node:path";
|
|
92212
92478
|
|
|
92213
92479
|
// src/principle-sync.ts
|
|
92214
92480
|
init_src5();
|
|
@@ -92236,8 +92502,8 @@ init_reconcile();
|
|
|
92236
92502
|
|
|
92237
92503
|
// src/lockfile-auto.ts
|
|
92238
92504
|
init_src();
|
|
92239
|
-
import { existsSync as existsSync32, readFileSync as
|
|
92240
|
-
import { join as
|
|
92505
|
+
import { existsSync as existsSync32, readFileSync as readFileSync38 } from "node:fs";
|
|
92506
|
+
import { join as join42 } from "node:path";
|
|
92241
92507
|
|
|
92242
92508
|
// src/package-index.ts
|
|
92243
92509
|
init_src();
|
|
@@ -92410,11 +92676,11 @@ function runLockfilePass(opts) {
|
|
|
92410
92676
|
{ file: "package-lock.json", parse: parsePackageLockJson }
|
|
92411
92677
|
];
|
|
92412
92678
|
for (const c of candidates) {
|
|
92413
|
-
const p =
|
|
92679
|
+
const p = join42(opts.root, c.file);
|
|
92414
92680
|
if (!existsSync32(p)) continue;
|
|
92415
92681
|
let sbom;
|
|
92416
92682
|
try {
|
|
92417
|
-
sbom = c.parse(
|
|
92683
|
+
sbom = c.parse(readFileSync38(p, "utf8"));
|
|
92418
92684
|
} catch {
|
|
92419
92685
|
continue;
|
|
92420
92686
|
}
|
|
@@ -92477,8 +92743,8 @@ init_profile2();
|
|
|
92477
92743
|
init_session_registry();
|
|
92478
92744
|
|
|
92479
92745
|
// src/public-symbols.ts
|
|
92480
|
-
import { readFileSync as
|
|
92481
|
-
import { join as
|
|
92746
|
+
import { readFileSync as readFileSync39, readdirSync as readdirSync12, existsSync as existsSync33 } from "node:fs";
|
|
92747
|
+
import { join as join43 } from "node:path";
|
|
92482
92748
|
var HEAD_BYTES = 8 * 1024;
|
|
92483
92749
|
var INDEX_TTL_MS = 10 * 60 * 1e3;
|
|
92484
92750
|
var MIN_SYMBOL_LEN = 4;
|
|
@@ -92511,20 +92777,20 @@ function bindingNames(clause) {
|
|
|
92511
92777
|
function internalPackageNames(workspaceRoot) {
|
|
92512
92778
|
const names = /* @__PURE__ */ new Set();
|
|
92513
92779
|
const tryRead = (dir) => {
|
|
92514
|
-
const pj =
|
|
92780
|
+
const pj = join43(dir, "package.json");
|
|
92515
92781
|
if (!existsSync33(pj)) return;
|
|
92516
92782
|
try {
|
|
92517
|
-
const name2 = JSON.parse(
|
|
92783
|
+
const name2 = JSON.parse(readFileSync39(pj, "utf8")).name;
|
|
92518
92784
|
if (typeof name2 === "string" && name2.length > 0) names.add(name2);
|
|
92519
92785
|
} catch {
|
|
92520
92786
|
}
|
|
92521
92787
|
};
|
|
92522
92788
|
tryRead(workspaceRoot);
|
|
92523
92789
|
for (const group of ["packages", "apps"]) {
|
|
92524
|
-
const groupDir =
|
|
92790
|
+
const groupDir = join43(workspaceRoot, group);
|
|
92525
92791
|
if (!existsSync33(groupDir)) continue;
|
|
92526
92792
|
try {
|
|
92527
|
-
for (const entry of readdirSync12(groupDir)) tryRead(
|
|
92793
|
+
for (const entry of readdirSync12(groupDir)) tryRead(join43(groupDir, entry));
|
|
92528
92794
|
} catch {
|
|
92529
92795
|
}
|
|
92530
92796
|
}
|
|
@@ -92543,7 +92809,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
|
|
|
92543
92809
|
}
|
|
92544
92810
|
const readHead = deps.readHead ?? ((absPath) => {
|
|
92545
92811
|
try {
|
|
92546
|
-
return
|
|
92812
|
+
return readFileSync39(absPath, "utf8").slice(0, HEAD_BYTES);
|
|
92547
92813
|
} catch {
|
|
92548
92814
|
return "";
|
|
92549
92815
|
}
|
|
@@ -92563,7 +92829,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
|
|
|
92563
92829
|
}
|
|
92564
92830
|
const symbols = /* @__PURE__ */ new Set();
|
|
92565
92831
|
for (const rel of files) {
|
|
92566
|
-
const head2 = readHead(
|
|
92832
|
+
const head2 = readHead(join43(workspaceRoot, rel));
|
|
92567
92833
|
if (!head2) continue;
|
|
92568
92834
|
for (const re of [NAMED_IMPORT_RE, REQUIRE_RE]) {
|
|
92569
92835
|
re.lastIndex = 0;
|
|
@@ -93594,7 +93860,7 @@ init_config();
|
|
|
93594
93860
|
|
|
93595
93861
|
// src/update.ts
|
|
93596
93862
|
import { spawn as spawn2 } from "node:child_process";
|
|
93597
|
-
import { isAbsolute as isAbsolute6, join as
|
|
93863
|
+
import { isAbsolute as isAbsolute6, join as join44 } from "node:path";
|
|
93598
93864
|
var PACKAGE_NAME = "@inerrata-corporation/errata";
|
|
93599
93865
|
function parse3(v) {
|
|
93600
93866
|
const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z][0-9A-Za-z.-]*))?/.exec(v.trim());
|
|
@@ -93743,7 +94009,7 @@ async function runInstalledHookRefresh() {
|
|
|
93743
94009
|
let worst = 0;
|
|
93744
94010
|
for (const harness of ["codex", "claude"]) {
|
|
93745
94011
|
const code = await new Promise((resolve11) => {
|
|
93746
|
-
const child = spawn2(process.execPath, [
|
|
94012
|
+
const child = spawn2(process.execPath, [join44(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", harness, "--refresh-existing"], {
|
|
93747
94013
|
windowsHide: true,
|
|
93748
94014
|
stdio: "inherit",
|
|
93749
94015
|
timeout: 3e4
|
|
@@ -93892,12 +94158,12 @@ function landCloudEdge(store, e, from, to) {
|
|
|
93892
94158
|
}
|
|
93893
94159
|
|
|
93894
94160
|
// src/causal-edge-queue.ts
|
|
93895
|
-
import { readFileSync as
|
|
93896
|
-
import { dirname as
|
|
94161
|
+
import { readFileSync as readFileSync40, renameSync as renameSync8, writeFileSync as writeFileSync28 } from "node:fs";
|
|
94162
|
+
import { dirname as dirname18, join as join45 } from "node:path";
|
|
93897
94163
|
var CAUSAL_EDGE_QUEUE_CAP = 5e3;
|
|
93898
94164
|
var CAUSAL_EDGE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
93899
94165
|
function causalEdgeQueuePath(workspaceConfigDir) {
|
|
93900
|
-
return
|
|
94166
|
+
return join45(workspaceConfigDir, "causal-edge-queue.json");
|
|
93901
94167
|
}
|
|
93902
94168
|
function parkedEdgeKey(e) {
|
|
93903
94169
|
return `${e.from}|${e.type}|${e.to}`;
|
|
@@ -93905,7 +94171,7 @@ function parkedEdgeKey(e) {
|
|
|
93905
94171
|
function loadCausalEdgeQueue(path3) {
|
|
93906
94172
|
let raw2;
|
|
93907
94173
|
try {
|
|
93908
|
-
raw2 = JSON.parse(
|
|
94174
|
+
raw2 = JSON.parse(readFileSync40(path3, "utf8"));
|
|
93909
94175
|
} catch {
|
|
93910
94176
|
return [];
|
|
93911
94177
|
}
|
|
@@ -93916,9 +94182,9 @@ function loadCausalEdgeQueue(path3) {
|
|
|
93916
94182
|
}
|
|
93917
94183
|
function saveCausalEdgeQueue(path3, queue) {
|
|
93918
94184
|
try {
|
|
93919
|
-
const tmp =
|
|
93920
|
-
|
|
93921
|
-
|
|
94185
|
+
const tmp = join45(dirname18(path3), `.${Date.now()}.causal-edge-queue.tmp`);
|
|
94186
|
+
writeFileSync28(tmp, JSON.stringify(queue), "utf8");
|
|
94187
|
+
renameSync8(tmp, path3);
|
|
93922
94188
|
} catch {
|
|
93923
94189
|
}
|
|
93924
94190
|
}
|
|
@@ -94348,9 +94614,9 @@ init_src11();
|
|
|
94348
94614
|
init_src();
|
|
94349
94615
|
import { execFile as execFile6 } from "node:child_process";
|
|
94350
94616
|
import { promisify as promisify4 } from "node:util";
|
|
94351
|
-
import { extname as extname3, join as
|
|
94617
|
+
import { extname as extname3, join as join46 } from "node:path";
|
|
94352
94618
|
import { createHash as createHash19 } from "node:crypto";
|
|
94353
|
-
import { readFileSync as
|
|
94619
|
+
import { readFileSync as readFileSync41 } from "node:fs";
|
|
94354
94620
|
|
|
94355
94621
|
// src/history-dependency-snapshot.ts
|
|
94356
94622
|
init_src();
|
|
@@ -94461,9 +94727,9 @@ var carryRefused = /* @__PURE__ */ new Set();
|
|
|
94461
94727
|
var carryFailures = /* @__PURE__ */ new Map();
|
|
94462
94728
|
var CARRY_ATTEMPTS = 3;
|
|
94463
94729
|
var Bounded = class extends Map {
|
|
94464
|
-
constructor(
|
|
94730
|
+
constructor(cap2) {
|
|
94465
94731
|
super();
|
|
94466
|
-
this.cap =
|
|
94732
|
+
this.cap = cap2;
|
|
94467
94733
|
}
|
|
94468
94734
|
set(key, value) {
|
|
94469
94735
|
if (!this.has(key) && this.size >= this.cap) this.delete(this.keys().next().value);
|
|
@@ -94473,7 +94739,7 @@ var Bounded = class extends Map {
|
|
|
94473
94739
|
var DEFAULT_GIT = {};
|
|
94474
94740
|
function readFileSafe(path3) {
|
|
94475
94741
|
try {
|
|
94476
|
-
return
|
|
94742
|
+
return readFileSync41(path3, "utf8");
|
|
94477
94743
|
} catch {
|
|
94478
94744
|
return "";
|
|
94479
94745
|
}
|
|
@@ -94527,7 +94793,7 @@ async function syncHistoryRevisionPage(opts, resolve11) {
|
|
|
94527
94793
|
const projectId = profile.projectId;
|
|
94528
94794
|
const git3 = opts.git ?? (async (args2) => (await exec2("git", ["-C", root, ...args2], { windowsHide: true, maxBuffer: 8 * 1024 * 1024 })).stdout);
|
|
94529
94795
|
const caches = cachesFor(opts.git ?? DEFAULT_GIT);
|
|
94530
|
-
const ignoreKey = createHash19("sha256").update(JSON.stringify(profile.ignoreExtra ?? [])).update(readFileSafe(
|
|
94796
|
+
const ignoreKey = createHash19("sha256").update(JSON.stringify(profile.ignoreExtra ?? [])).update(readFileSafe(join46(root, ".errataignore"))).digest("hex").slice(0, 16);
|
|
94531
94797
|
const atCommit = (await git3(["rev-parse", "--verify", "HEAD"])).trim();
|
|
94532
94798
|
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(atCommit)) throw new Error("history revision is not a full Git object id");
|
|
94533
94799
|
const oldCursor = profile.historyRevisionCursor;
|
|
@@ -94847,8 +95113,8 @@ ${await git3(["rev-list", "--parents", "-1", from])}`.split("\n").map((row) => r
|
|
|
94847
95113
|
init_src7();
|
|
94848
95114
|
init_src();
|
|
94849
95115
|
import { execFile as execFile7 } from "node:child_process";
|
|
94850
|
-
import { readFileSync as
|
|
94851
|
-
import { join as
|
|
95116
|
+
import { readFileSync as readFileSync42 } from "node:fs";
|
|
95117
|
+
import { join as join47 } from "node:path";
|
|
94852
95118
|
import { promisify as promisify5 } from "node:util";
|
|
94853
95119
|
|
|
94854
95120
|
// src/history-walk.ts
|
|
@@ -95407,7 +95673,7 @@ async function defaultGit(root, args2) {
|
|
|
95407
95673
|
function readIgnoreLines(root, profile) {
|
|
95408
95674
|
let lines = [];
|
|
95409
95675
|
try {
|
|
95410
|
-
lines =
|
|
95676
|
+
lines = readFileSync42(join47(root, ".errataignore"), "utf8").split("\n");
|
|
95411
95677
|
} catch {
|
|
95412
95678
|
}
|
|
95413
95679
|
return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
@@ -95588,7 +95854,7 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
95588
95854
|
const settle = (p) => p.then((res) => ({ res }), (err2) => ({ err: err2 }));
|
|
95589
95855
|
const prepared = /* @__PURE__ */ new Map();
|
|
95590
95856
|
const launched = /* @__PURE__ */ new Map();
|
|
95591
|
-
const
|
|
95857
|
+
const cap2 = opts.maxUnits;
|
|
95592
95858
|
const edgeParked = /* @__PURE__ */ new Set();
|
|
95593
95859
|
const parkedEarlier = new Set((profile.historyStage?.coverageGaps ?? []).filter((g) => g.reason === "edge-blocked" && !recoveryKeys.has(unitKey(g))).map(unitKey));
|
|
95594
95860
|
units.forEach((u, j) => {
|
|
@@ -95681,7 +95947,7 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
95681
95947
|
if (!doorOrders || lookahead === 0) return;
|
|
95682
95948
|
let ahead = 0;
|
|
95683
95949
|
for (let j = k + 1; j < units.length && ahead < lookahead; j++) {
|
|
95684
|
-
if (
|
|
95950
|
+
if (cap2 !== void 0 && processed + (j - k) >= cap2) break;
|
|
95685
95951
|
if (units[j].skip || edgeParked.has(j)) continue;
|
|
95686
95952
|
ahead += 1;
|
|
95687
95953
|
await launch(j);
|
|
@@ -95689,7 +95955,7 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
95689
95955
|
};
|
|
95690
95956
|
for (let k = 0; k < units.length; k++) {
|
|
95691
95957
|
const u = units[k];
|
|
95692
|
-
if (
|
|
95958
|
+
if (cap2 !== void 0 && processed >= cap2) break;
|
|
95693
95959
|
const label = `${u.sha.slice(0, 12)}${u.subIndex ? `/${u.subIndex}` : ""}`;
|
|
95694
95960
|
const recovering = recoveryKeys.has(unitKey(u));
|
|
95695
95961
|
const walkIncrement = recovering ? 0 : 1;
|
|
@@ -95987,8 +96253,8 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
|
|
|
95987
96253
|
init_cloud_auth();
|
|
95988
96254
|
import { createHash as createHash20 } from "node:crypto";
|
|
95989
96255
|
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
95990
|
-
import { existsSync as existsSync34, writeFileSync as
|
|
95991
|
-
import { join as
|
|
96256
|
+
import { existsSync as existsSync34, writeFileSync as writeFileSync29 } from "node:fs";
|
|
96257
|
+
import { join as join48 } from "node:path";
|
|
95992
96258
|
|
|
95993
96259
|
// src/device-poll.ts
|
|
95994
96260
|
var THROTTLED_POLL_MIN_WAIT_MS = 11e3;
|
|
@@ -96447,9 +96713,9 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
|
|
|
96447
96713
|
delete nextProfile.projectLinkHold;
|
|
96448
96714
|
let wroteIgnore = false;
|
|
96449
96715
|
if (decision.writeIgnoreStarter !== false) {
|
|
96450
|
-
const target =
|
|
96716
|
+
const target = join48(root, ".errataignore");
|
|
96451
96717
|
if (!existsSync34(target)) {
|
|
96452
|
-
|
|
96718
|
+
writeFileSync29(target, IGNORE_STARTER, "utf8");
|
|
96453
96719
|
wroteIgnore = true;
|
|
96454
96720
|
}
|
|
96455
96721
|
}
|
|
@@ -96463,12 +96729,12 @@ init_registry();
|
|
|
96463
96729
|
// src/adopt.ts
|
|
96464
96730
|
init_git_remote();
|
|
96465
96731
|
import { existsSync as existsSync35 } from "node:fs";
|
|
96466
|
-
import { dirname as
|
|
96732
|
+
import { dirname as dirname19, join as join49 } from "node:path";
|
|
96467
96733
|
function findGitRoot(absPath) {
|
|
96468
96734
|
let dir = absPath;
|
|
96469
96735
|
for (let depth = 0; depth < 64; depth++) {
|
|
96470
|
-
if (existsSync35(
|
|
96471
|
-
const parent =
|
|
96736
|
+
if (existsSync35(join49(dir, ".git"))) return dir;
|
|
96737
|
+
const parent = dirname19(dir);
|
|
96472
96738
|
if (parent === dir) return null;
|
|
96473
96739
|
dir = parent;
|
|
96474
96740
|
}
|
|
@@ -97110,7 +97376,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97110
97376
|
};
|
|
97111
97377
|
const sharedDbPath = sharedStorePath();
|
|
97112
97378
|
ensureParent(sharedDbPath);
|
|
97113
|
-
if (sharedDbPath !== ":memory:") excludeFromIndexing(
|
|
97379
|
+
if (sharedDbPath !== ":memory:") excludeFromIndexing(dirname20(sharedDbPath));
|
|
97114
97380
|
await prepareStore(sharedDbPath, process.cwd(), "shared");
|
|
97115
97381
|
const sharedStore = openGraphStore({ path: sharedDbPath });
|
|
97116
97382
|
const bundledRun = import.meta.url.endsWith(".mjs");
|
|
@@ -97254,7 +97520,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97254
97520
|
held.push(...quarantined);
|
|
97255
97521
|
let ignoreFile = "";
|
|
97256
97522
|
try {
|
|
97257
|
-
ignoreFile =
|
|
97523
|
+
ignoreFile = readFileSync43(join50(r.root, ".errataignore"), "utf8");
|
|
97258
97524
|
} catch {
|
|
97259
97525
|
}
|
|
97260
97526
|
const retryInputs = JSON.stringify([
|
|
@@ -97322,7 +97588,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97322
97588
|
const id = entry.id;
|
|
97323
97589
|
const castaliaPath = workspacePaths(entry.path).castalia;
|
|
97324
97590
|
ensureParent(castaliaPath);
|
|
97325
|
-
excludeFromIndexing(
|
|
97591
|
+
excludeFromIndexing(dirname20(castaliaPath));
|
|
97326
97592
|
await prepareStore(castaliaPath, entry.path, id);
|
|
97327
97593
|
if (stopping) throw new Error("daemon stopping");
|
|
97328
97594
|
const wsIdentity = identityFor(entry);
|
|
@@ -97459,7 +97725,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97459
97725
|
records.push(rec);
|
|
97460
97726
|
void ambientLinkAll();
|
|
97461
97727
|
try {
|
|
97462
|
-
|
|
97728
|
+
writeFileSync30(
|
|
97463
97729
|
rec.engine.paths.daemonLock,
|
|
97464
97730
|
daemonLockPayload({
|
|
97465
97731
|
pid: process.pid,
|
|
@@ -97835,10 +98101,10 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97835
98101
|
};
|
|
97836
98102
|
const MISFILED_SWEEP_DELAY_MS = 2 * 6e4;
|
|
97837
98103
|
const sweepMisfiled = async (rec) => {
|
|
97838
|
-
const checkedPath =
|
|
98104
|
+
const checkedPath = join50(workspacePaths(rec.root).configDir, "rehome-checked.json");
|
|
97839
98105
|
let checked;
|
|
97840
98106
|
try {
|
|
97841
|
-
checked = new Set(JSON.parse(
|
|
98107
|
+
checked = new Set(JSON.parse(readFileSync43(checkedPath, "utf8")));
|
|
97842
98108
|
} catch {
|
|
97843
98109
|
checked = /* @__PURE__ */ new Set();
|
|
97844
98110
|
}
|
|
@@ -97854,7 +98120,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97854
98120
|
if (to) await rehomeMisfiled(sid, rec, to, "its captures were raised in its files");
|
|
97855
98121
|
await new Promise((r) => setImmediate(r));
|
|
97856
98122
|
}
|
|
97857
|
-
if (changed)
|
|
98123
|
+
if (changed) writeFileSync30(checkedPath, JSON.stringify([...checked]), "utf8");
|
|
97858
98124
|
};
|
|
97859
98125
|
afterAttach = (rec) => {
|
|
97860
98126
|
const t = setTimeout(() => {
|
|
@@ -98030,7 +98296,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
98030
98296
|
baseUrl = `http://127.0.0.1:${port}`;
|
|
98031
98297
|
try {
|
|
98032
98298
|
ensureDir(globalDir());
|
|
98033
|
-
|
|
98299
|
+
writeFileSync30(
|
|
98034
98300
|
lockPath,
|
|
98035
98301
|
daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
|
|
98036
98302
|
"utf8"
|
|
@@ -98039,7 +98305,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
98039
98305
|
}
|
|
98040
98306
|
for (const r of records) {
|
|
98041
98307
|
try {
|
|
98042
|
-
|
|
98308
|
+
writeFileSync30(
|
|
98043
98309
|
r.engine.paths.daemonLock,
|
|
98044
98310
|
daemonLockPayload({
|
|
98045
98311
|
pid: process.pid,
|
|
@@ -99586,7 +99852,7 @@ import { spawnSync as spawnSync2 } from "node:child_process";
|
|
|
99586
99852
|
|
|
99587
99853
|
// src/codex-runtime.ts
|
|
99588
99854
|
import { readdirSync as readdirSync13, statSync as statSync13 } from "node:fs";
|
|
99589
|
-
import { join as
|
|
99855
|
+
import { join as join51 } from "node:path";
|
|
99590
99856
|
function resolveCodexExecutable(options = {}) {
|
|
99591
99857
|
const platform = options.platform ?? process.platform;
|
|
99592
99858
|
const env2 = options.env ?? process.env;
|
|
@@ -99601,13 +99867,13 @@ function resolveCodexExecutable(options = {}) {
|
|
|
99601
99867
|
};
|
|
99602
99868
|
for (const dir of (env2["PATH"] ?? env2["Path"] ?? "").split(";")) {
|
|
99603
99869
|
if (!dir.trim()) continue;
|
|
99604
|
-
const path3 =
|
|
99870
|
+
const path3 = join51(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
|
|
99605
99871
|
if (fileTime(path3) !== null) return path3;
|
|
99606
99872
|
}
|
|
99607
99873
|
if (!env2["LOCALAPPDATA"]) return "codex";
|
|
99608
|
-
const root =
|
|
99874
|
+
const root = join51(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
|
|
99609
99875
|
try {
|
|
99610
|
-
const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
99876
|
+
const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join51(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));
|
|
99611
99877
|
return candidates[0]?.path ?? "codex";
|
|
99612
99878
|
} catch {
|
|
99613
99879
|
return "codex";
|
|
@@ -99746,14 +100012,14 @@ async function diagnoseInstallation(cfg, dependencies) {
|
|
|
99746
100012
|
}
|
|
99747
100013
|
|
|
99748
100014
|
// src/credential-scan.ts
|
|
99749
|
-
import { readFileSync as
|
|
100015
|
+
import { readFileSync as readFileSync45, statSync as statSync14 } from "node:fs";
|
|
99750
100016
|
import { homedir as homedir8 } from "node:os";
|
|
99751
|
-
import { join as
|
|
100017
|
+
import { join as join53 } from "node:path";
|
|
99752
100018
|
|
|
99753
100019
|
// src/claude-statusline.ts
|
|
99754
|
-
import { existsSync as existsSync37, mkdirSync as mkdirSync9, readFileSync as
|
|
100020
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync9, readFileSync as readFileSync44, writeFileSync as writeFileSync31 } from "node:fs";
|
|
99755
100021
|
import { homedir as homedir7 } from "node:os";
|
|
99756
|
-
import { dirname as
|
|
100022
|
+
import { dirname as dirname21, join as join52 } from "node:path";
|
|
99757
100023
|
var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
|
|
99758
100024
|
import { readFileSync } from 'node:fs';
|
|
99759
100025
|
|
|
@@ -99801,8 +100067,8 @@ function isSameInstall(value, relay) {
|
|
|
99801
100067
|
return command.includes(relay.replace(/\\/g, "/").toLowerCase());
|
|
99802
100068
|
}
|
|
99803
100069
|
function userClaudeSettingsPath() {
|
|
99804
|
-
const base = process.env["CLAUDE_CONFIG_DIR"] ??
|
|
99805
|
-
return
|
|
100070
|
+
const base = process.env["CLAUDE_CONFIG_DIR"] ?? join52(homedir7(), ".claude");
|
|
100071
|
+
return join52(base, "settings.json");
|
|
99806
100072
|
}
|
|
99807
100073
|
function ensureUserStatusLine(opts) {
|
|
99808
100074
|
const env2 = opts.env ?? process.env;
|
|
@@ -99812,21 +100078,21 @@ function ensureUserStatusLine(opts) {
|
|
|
99812
100078
|
let settings = {};
|
|
99813
100079
|
if (existsSync37(settingsPath)) {
|
|
99814
100080
|
try {
|
|
99815
|
-
const parsed = JSON.parse(
|
|
100081
|
+
const parsed = JSON.parse(readFileSync44(settingsPath, "utf8"));
|
|
99816
100082
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
|
|
99817
100083
|
settings = parsed;
|
|
99818
100084
|
} catch {
|
|
99819
100085
|
return "unreadable";
|
|
99820
100086
|
}
|
|
99821
100087
|
}
|
|
99822
|
-
const relay =
|
|
100088
|
+
const relay = join52(opts.relayDir, STATUSLINE_RELAY_FILE);
|
|
99823
100089
|
const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
|
|
99824
100090
|
const ownMain = keep(settings["statusLine"]);
|
|
99825
100091
|
const ownRows = keep(settings["subagentStatusLine"]);
|
|
99826
100092
|
if (ownMain && ownRows) return "kept-own";
|
|
99827
100093
|
mkdirSync9(opts.relayDir, { recursive: true });
|
|
99828
|
-
if (!existsSync37(relay) ||
|
|
99829
|
-
|
|
100094
|
+
if (!existsSync37(relay) || readFileSync44(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
|
|
100095
|
+
writeFileSync31(relay, STATUSLINE_RELAY_SOURCE, "utf8");
|
|
99830
100096
|
}
|
|
99831
100097
|
const nodePath = opts.nodePath ?? process.execPath;
|
|
99832
100098
|
const next = {
|
|
@@ -99837,8 +100103,8 @@ function ensureUserStatusLine(opts) {
|
|
|
99837
100103
|
return ownMain ? "kept-own" : "unchanged";
|
|
99838
100104
|
}
|
|
99839
100105
|
Object.assign(settings, next);
|
|
99840
|
-
mkdirSync9(
|
|
99841
|
-
|
|
100106
|
+
mkdirSync9(dirname21(settingsPath), { recursive: true });
|
|
100107
|
+
writeFileSync31(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
99842
100108
|
return "installed";
|
|
99843
100109
|
}
|
|
99844
100110
|
function describeStatusLineOutcome(outcome) {
|
|
@@ -99879,36 +100145,36 @@ function findCredentialLines(text) {
|
|
|
99879
100145
|
function harnessConfigPaths(root) {
|
|
99880
100146
|
const env2 = process.env;
|
|
99881
100147
|
const home = homedir8();
|
|
99882
|
-
const codexHome = env2["CODEX_HOME"] ||
|
|
99883
|
-
const geminiHome =
|
|
100148
|
+
const codexHome = env2["CODEX_HOME"] || join53(home, ".codex");
|
|
100149
|
+
const geminiHome = join53(env2["GEMINI_CLI_HOME"] ?? home, ".gemini");
|
|
99884
100150
|
return [
|
|
99885
100151
|
// Claude Code: user settings, `claude mcp add` (local/user scope), project.
|
|
99886
100152
|
userClaudeSettingsPath(),
|
|
99887
|
-
|
|
99888
|
-
|
|
99889
|
-
|
|
99890
|
-
|
|
100153
|
+
join53(env2["CLAUDE_CONFIG_DIR"] ?? home, ".claude.json"),
|
|
100154
|
+
join53(root, ".claude", "settings.json"),
|
|
100155
|
+
join53(root, ".claude", "settings.local.json"),
|
|
100156
|
+
join53(root, ".mcp.json"),
|
|
99891
100157
|
// Codex
|
|
99892
|
-
|
|
99893
|
-
|
|
100158
|
+
join53(codexHome, "config.toml"),
|
|
100159
|
+
join53(root, ".codex", "config.toml"),
|
|
99894
100160
|
// Gemini CLI
|
|
99895
|
-
|
|
99896
|
-
|
|
100161
|
+
join53(geminiHome, "settings.json"),
|
|
100162
|
+
join53(root, ".gemini", "settings.json"),
|
|
99897
100163
|
// Cursor
|
|
99898
|
-
|
|
99899
|
-
|
|
100164
|
+
join53(home, ".cursor", "mcp.json"),
|
|
100165
|
+
join53(root, ".cursor", "mcp.json"),
|
|
99900
100166
|
// VS Code (user profile mcp.json + workspace)
|
|
99901
|
-
|
|
99902
|
-
|
|
100167
|
+
join53(vscodeUserDir(home, env2), "mcp.json"),
|
|
100168
|
+
join53(root, ".vscode", "mcp.json"),
|
|
99903
100169
|
// OpenCode (XDG on every platform; the daemon's installer writes the project one)
|
|
99904
|
-
|
|
99905
|
-
|
|
100170
|
+
join53(env2["XDG_CONFIG_HOME"] ?? join53(home, ".config"), "opencode", "opencode.json"),
|
|
100171
|
+
join53(root, "opencode.json")
|
|
99906
100172
|
];
|
|
99907
100173
|
}
|
|
99908
100174
|
function vscodeUserDir(home, env2) {
|
|
99909
|
-
if (process.platform === "win32") return
|
|
99910
|
-
if (process.platform === "darwin") return
|
|
99911
|
-
return
|
|
100175
|
+
if (process.platform === "win32") return join53(env2["APPDATA"] ?? join53(home, "AppData", "Roaming"), "Code", "User");
|
|
100176
|
+
if (process.platform === "darwin") return join53(home, "Library", "Application Support", "Code", "User");
|
|
100177
|
+
return join53(env2["XDG_CONFIG_HOME"] ?? join53(home, ".config"), "Code", "User");
|
|
99912
100178
|
}
|
|
99913
100179
|
function scanHarnessConfigs(paths, read2 = readBounded) {
|
|
99914
100180
|
const findings = [];
|
|
@@ -99925,7 +100191,7 @@ function readBounded(path3) {
|
|
|
99925
100191
|
try {
|
|
99926
100192
|
const stat4 = statSync14(path3);
|
|
99927
100193
|
if (!stat4.isFile() || stat4.size > MAX_SCAN_BYTES) return null;
|
|
99928
|
-
return
|
|
100194
|
+
return readFileSync45(path3, "utf8");
|
|
99929
100195
|
} catch {
|
|
99930
100196
|
return null;
|
|
99931
100197
|
}
|
|
@@ -99950,14 +100216,14 @@ function credentialHygieneCheck(scan2) {
|
|
|
99950
100216
|
|
|
99951
100217
|
// src/codex-doctor.ts
|
|
99952
100218
|
import { spawn as spawn4 } from "node:child_process";
|
|
99953
|
-
import { readFileSync as
|
|
99954
|
-
import { join as
|
|
100219
|
+
import { readFileSync as readFileSync47, statSync as statSync15 } from "node:fs";
|
|
100220
|
+
import { join as join55 } from "node:path";
|
|
99955
100221
|
import { createInterface } from "node:readline";
|
|
99956
100222
|
|
|
99957
100223
|
// src/codex-hooks.ts
|
|
99958
|
-
import { existsSync as existsSync38, mkdirSync as mkdirSync10, readFileSync as
|
|
100224
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync10, readFileSync as readFileSync46, renameSync as renameSync9, unlinkSync as unlinkSync5, writeFileSync as writeFileSync32 } from "node:fs";
|
|
99959
100225
|
import { homedir as homedir9 } from "node:os";
|
|
99960
|
-
import { join as
|
|
100226
|
+
import { join as join54 } from "node:path";
|
|
99961
100227
|
|
|
99962
100228
|
// src/hook-commands.ts
|
|
99963
100229
|
function hookCurlCommand(port, path3 = "/api/hook") {
|
|
@@ -100213,34 +100479,34 @@ function buildCodexRelaySource(workspaceRoot) {
|
|
|
100213
100479
|
init_checkout_root();
|
|
100214
100480
|
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.";
|
|
100215
100481
|
function writeRelay(file2, source) {
|
|
100216
|
-
if (existsSync38(file2) &&
|
|
100482
|
+
if (existsSync38(file2) && readFileSync46(file2, "utf8") === source) return;
|
|
100217
100483
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
100218
100484
|
try {
|
|
100219
|
-
|
|
100220
|
-
|
|
100485
|
+
writeFileSync32(temp, source, { encoding: "utf8", mode: 384 });
|
|
100486
|
+
renameSync9(temp, file2);
|
|
100221
100487
|
} finally {
|
|
100222
100488
|
if (existsSync38(temp)) unlinkSync5(temp);
|
|
100223
100489
|
}
|
|
100224
100490
|
}
|
|
100225
100491
|
function refreshCodexRelay(root) {
|
|
100226
|
-
const config2 =
|
|
100492
|
+
const config2 = join54(root, ".codex", "config.toml");
|
|
100227
100493
|
if (!existsSync38(config2)) return "absent";
|
|
100228
|
-
const existing =
|
|
100494
|
+
const existing = readFileSync46(config2, "utf8");
|
|
100229
100495
|
if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
|
|
100230
100496
|
replaceCodexHooks(existing, "");
|
|
100231
|
-
const relay =
|
|
100232
|
-
const prior = existsSync38(relay) ?
|
|
100497
|
+
const relay = join54(root, ".codex", "hooks", "errata-relay.mjs");
|
|
100498
|
+
const prior = existsSync38(relay) ? readFileSync46(relay, "utf8") : "";
|
|
100233
100499
|
if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
|
|
100234
100500
|
throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
|
|
100235
100501
|
}
|
|
100236
100502
|
const source = buildCodexRelaySource(checkoutRootOf(root));
|
|
100237
100503
|
if (prior === source) return "current";
|
|
100238
|
-
mkdirSync10(
|
|
100504
|
+
mkdirSync10(join54(root, ".codex", "hooks"), { recursive: true });
|
|
100239
100505
|
writeRelay(relay, source);
|
|
100240
100506
|
return "updated";
|
|
100241
100507
|
}
|
|
100242
|
-
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] ||
|
|
100243
|
-
return existsSync38(
|
|
100508
|
+
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join54(homedir9(), ".codex")) {
|
|
100509
|
+
return existsSync38(join54(root, ".codex")) || existsSync38(codexHome);
|
|
100244
100510
|
}
|
|
100245
100511
|
function replaceCodexHooks(existing, block) {
|
|
100246
100512
|
const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
|
|
@@ -100256,14 +100522,14 @@ function replaceCodexHooks(existing, block) {
|
|
|
100256
100522
|
return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
|
|
100257
100523
|
}
|
|
100258
100524
|
function writeCodexHooks(root, port, nodePath = process.execPath) {
|
|
100259
|
-
const dir =
|
|
100260
|
-
const file2 =
|
|
100261
|
-
const relay =
|
|
100525
|
+
const dir = join54(root, ".codex");
|
|
100526
|
+
const file2 = join54(dir, "config.toml");
|
|
100527
|
+
const relay = join54(dir, "hooks", "errata-relay.mjs");
|
|
100262
100528
|
const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
|
|
100263
|
-
const final = replaceCodexHooks(existsSync38(file2) ?
|
|
100264
|
-
mkdirSync10(
|
|
100529
|
+
const final = replaceCodexHooks(existsSync38(file2) ? readFileSync46(file2, "utf8") : "", block);
|
|
100530
|
+
mkdirSync10(join54(dir, "hooks"), { recursive: true });
|
|
100265
100531
|
writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
|
|
100266
|
-
if (!existsSync38(file2) ||
|
|
100532
|
+
if (!existsSync38(file2) || readFileSync46(file2, "utf8") !== final) writeFileSync32(file2, final, "utf8");
|
|
100267
100533
|
return file2;
|
|
100268
100534
|
}
|
|
100269
100535
|
|
|
@@ -100272,7 +100538,7 @@ init_checkout_root();
|
|
|
100272
100538
|
function inspectCodexRelay(cwd) {
|
|
100273
100539
|
const root = nearestGitRoot(cwd) ?? cwd;
|
|
100274
100540
|
try {
|
|
100275
|
-
const source =
|
|
100541
|
+
const source = readFileSync47(join55(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
|
|
100276
100542
|
if (source === buildCodexRelaySource(checkoutRootOf(root))) {
|
|
100277
100543
|
return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
|
|
100278
100544
|
}
|
|
@@ -100283,8 +100549,8 @@ function inspectCodexRelay(cwd) {
|
|
|
100283
100549
|
function inspectCodexContext(cwd) {
|
|
100284
100550
|
const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
|
|
100285
100551
|
try {
|
|
100286
|
-
const file2 =
|
|
100287
|
-
if (statSync15(file2).size <= 128 * 1024 &&
|
|
100552
|
+
const file2 = join55(root, ".errata", "context.md");
|
|
100553
|
+
if (statSync15(file2).size <= 128 * 1024 && readFileSync47(file2, "utf8").trim()) {
|
|
100288
100554
|
return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
|
|
100289
100555
|
}
|
|
100290
100556
|
} catch {
|
|
@@ -100423,9 +100689,9 @@ function effectiveMomentumThreshold(policy, liveNodes) {
|
|
|
100423
100689
|
return Math.max(policy.momentumThreshold, Math.ceil(liveNodes * policy.momentumRatio));
|
|
100424
100690
|
}
|
|
100425
100691
|
function nextMomentumThreshold(args2) {
|
|
100426
|
-
const { current, consumed, landmarkFlips, floor, cap } = args2;
|
|
100692
|
+
const { current, consumed, landmarkFlips, floor, cap: cap2 } = args2;
|
|
100427
100693
|
const next = landmarkFlips > 0 ? Math.min(current, Math.round(consumed / 2)) : Math.max(current, Math.round(consumed * 1.5));
|
|
100428
|
-
return Math.max(floor, Math.min(
|
|
100694
|
+
return Math.max(floor, Math.min(cap2, next));
|
|
100429
100695
|
}
|
|
100430
100696
|
var DEFAULT_CONSOLIDATION_POLICY = {
|
|
100431
100697
|
baseFloorMs: 6e4,
|
|
@@ -100462,9 +100728,9 @@ function consolidationGapMs(lastPassMs, policy) {
|
|
|
100462
100728
|
|
|
100463
100729
|
// src/codex-context-plugin.ts
|
|
100464
100730
|
import { createHash as createHash21 } from "node:crypto";
|
|
100465
|
-
import { cpSync as cpSync2, existsSync as existsSync39, mkdirSync as mkdirSync11, readFileSync as
|
|
100731
|
+
import { cpSync as cpSync2, existsSync as existsSync39, mkdirSync as mkdirSync11, readFileSync as readFileSync48, renameSync as renameSync10, writeFileSync as writeFileSync33 } from "node:fs";
|
|
100466
100732
|
import { homedir as homedir10 } from "node:os";
|
|
100467
|
-
import { join as
|
|
100733
|
+
import { join as join56 } from "node:path";
|
|
100468
100734
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
100469
100735
|
|
|
100470
100736
|
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
|
|
@@ -101162,23 +101428,23 @@ var NAME = "errata-context";
|
|
|
101162
101428
|
var PREFIX2 = `./.errata/plugins/${NAME}/`;
|
|
101163
101429
|
var object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
101164
101430
|
function readText(file2) {
|
|
101165
|
-
return existsSync39(file2) ?
|
|
101431
|
+
return existsSync39(file2) ? readFileSync48(file2, "utf8") : "";
|
|
101166
101432
|
}
|
|
101167
101433
|
function writeChanged(file2, content) {
|
|
101168
101434
|
if (readText(file2) === content) return;
|
|
101169
101435
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
101170
|
-
|
|
101171
|
-
|
|
101436
|
+
writeFileSync33(temp, content, "utf8");
|
|
101437
|
+
renameSync10(temp, file2);
|
|
101172
101438
|
}
|
|
101173
101439
|
function bundledContextPlugin() {
|
|
101174
101440
|
const packaged = fileURLToPath4(new URL("./resources/context-plugin/", import.meta.url));
|
|
101175
|
-
if (existsSync39(
|
|
101441
|
+
if (existsSync39(join56(packaged, ".codex-plugin/plugin.json"))) return packaged;
|
|
101176
101442
|
return fileURLToPath4(new URL("../dist/resources/context-plugin/", import.meta.url));
|
|
101177
101443
|
}
|
|
101178
101444
|
function refreshCodexContextPlugin(root) {
|
|
101179
|
-
const file2 =
|
|
101445
|
+
const file2 = join56(root, ".agents", "plugins", "marketplace.json");
|
|
101180
101446
|
if (!existsSync39(file2)) return false;
|
|
101181
|
-
const marketplace = JSON.parse(
|
|
101447
|
+
const marketplace = JSON.parse(readFileSync48(file2, "utf8"));
|
|
101182
101448
|
const entries = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
|
|
101183
101449
|
const entry = entries.map(object2).find((value) => value.name === NAME && String(object2(value.source).path).startsWith(PREFIX2));
|
|
101184
101450
|
if (!entry) return false;
|
|
@@ -101189,24 +101455,24 @@ function refreshCodexContextPlugin(root) {
|
|
|
101189
101455
|
function installCodexContextPlugin(root, options = {}) {
|
|
101190
101456
|
const bundle = options.bundle ?? bundledContextPlugin();
|
|
101191
101457
|
const manifest = JSON.parse(
|
|
101192
|
-
|
|
101458
|
+
readFileSync48(join56(bundle, ".codex-plugin/plugin.json"), "utf8")
|
|
101193
101459
|
);
|
|
101194
101460
|
if (manifest.name !== NAME || typeof manifest.version !== "string" || !/^[\w.-]+$/.test(manifest.version)) {
|
|
101195
101461
|
throw new Error("Invalid bundled Errata Context manifest.");
|
|
101196
101462
|
}
|
|
101197
|
-
const checksums =
|
|
101463
|
+
const checksums = readFileSync48(join56(bundle, "SHA256SUMS"), "utf8");
|
|
101198
101464
|
for (const line of checksums.trim().split("\n")) {
|
|
101199
101465
|
const match2 = /^([a-f0-9]{64}) ([\w./-]+)$/.exec(line);
|
|
101200
101466
|
if (!match2 || match2[2].startsWith("/") || match2[2].split("/").includes("..")) {
|
|
101201
101467
|
throw new Error("Invalid bundled Errata Context checksum manifest.");
|
|
101202
101468
|
}
|
|
101203
|
-
const actual = createHash21("sha256").update(
|
|
101469
|
+
const actual = createHash21("sha256").update(readFileSync48(join56(bundle, match2[2]))).digest("hex");
|
|
101204
101470
|
if (actual !== match2[1])
|
|
101205
101471
|
throw new Error(`Bundled Errata Context checksum mismatch: ${match2[2]}`);
|
|
101206
101472
|
}
|
|
101207
101473
|
const release = `${manifest.version}-${createHash21("sha256").update(checksums).digest("hex").slice(0, 12)}`;
|
|
101208
|
-
const plugin =
|
|
101209
|
-
const marketplaceFile =
|
|
101474
|
+
const plugin = join56(root, ".errata", "plugins", NAME, release);
|
|
101475
|
+
const marketplaceFile = join56(root, ".agents", "plugins", "marketplace.json");
|
|
101210
101476
|
const priorMarketplace = readText(marketplaceFile);
|
|
101211
101477
|
const marketplace = priorMarketplace ? JSON.parse(priorMarketplace) : {
|
|
101212
101478
|
name: "errata-local",
|
|
@@ -101227,12 +101493,12 @@ function installCodexContextPlugin(root, options = {}) {
|
|
|
101227
101493
|
);
|
|
101228
101494
|
}
|
|
101229
101495
|
const key = `${NAME}@${marketplace.name}`;
|
|
101230
|
-
const configFile =
|
|
101496
|
+
const configFile = join56(root, ".codex", "config.toml");
|
|
101231
101497
|
const config2 = readText(configFile);
|
|
101232
101498
|
const parsed = parse4(config2);
|
|
101233
101499
|
const plugins = object2(parsed.plugins);
|
|
101234
|
-
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ??
|
|
101235
|
-
const globalPlugins = object2(parse4(readText(
|
|
101500
|
+
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join56(homedir10(), ".codex");
|
|
101501
|
+
const globalPlugins = object2(parse4(readText(join56(codexHome, "config.toml"))).plugins);
|
|
101236
101502
|
const disabledGlobally = Object.entries(globalPlugins).some(
|
|
101237
101503
|
([name2, value]) => (name2 === NAME || name2.startsWith(`${NAME}@`)) && object2(value).enabled === false
|
|
101238
101504
|
);
|
|
@@ -101256,13 +101522,13 @@ enabled = ${enabled}
|
|
|
101256
101522
|
mkdirSync11(plugin, { recursive: true });
|
|
101257
101523
|
cpSync2(bundle, plugin, { recursive: true });
|
|
101258
101524
|
writeChanged(
|
|
101259
|
-
|
|
101525
|
+
join56(plugin, ".mcp.json"),
|
|
101260
101526
|
JSON.stringify(
|
|
101261
101527
|
{
|
|
101262
101528
|
mcpServers: {
|
|
101263
101529
|
errata_context: {
|
|
101264
101530
|
command: options.nodePath ?? process.execPath,
|
|
101265
|
-
args: [
|
|
101531
|
+
args: [join56(plugin, "dist", "mcp-server.mjs")],
|
|
101266
101532
|
env: { ERRATA_WORKSPACE: root, ERRATA_CONTEXT_VERSION: manifest.version }
|
|
101267
101533
|
}
|
|
101268
101534
|
}
|
|
@@ -101271,8 +101537,8 @@ enabled = ${enabled}
|
|
|
101271
101537
|
2
|
|
101272
101538
|
) + "\n"
|
|
101273
101539
|
);
|
|
101274
|
-
mkdirSync11(
|
|
101275
|
-
mkdirSync11(
|
|
101540
|
+
mkdirSync11(join56(root, ".agents", "plugins"), { recursive: true });
|
|
101541
|
+
mkdirSync11(join56(root, ".codex"), { recursive: true });
|
|
101276
101542
|
writeChanged(marketplaceFile, JSON.stringify(marketplace, null, 2) + "\n");
|
|
101277
101543
|
writeChanged(configFile, nextConfig);
|
|
101278
101544
|
return { plugin, enabled, marketplace: marketplaceFile };
|
|
@@ -101280,15 +101546,15 @@ enabled = ${enabled}
|
|
|
101280
101546
|
|
|
101281
101547
|
// src/codex-hook-refresh.ts
|
|
101282
101548
|
init_checkout_root();
|
|
101283
|
-
import { existsSync as existsSync40, readdirSync as readdirSync14, readFileSync as
|
|
101284
|
-
import { dirname as
|
|
101549
|
+
import { existsSync as existsSync40, readdirSync as readdirSync14, readFileSync as readFileSync49 } from "node:fs";
|
|
101550
|
+
import { dirname as dirname22, join as join57, resolve as resolve9 } from "node:path";
|
|
101285
101551
|
init_registry();
|
|
101286
101552
|
function codexHookRoots(roots) {
|
|
101287
101553
|
const found = new Set(roots.map((root) => resolve9(root)));
|
|
101288
101554
|
for (const root of [...found]) {
|
|
101289
101555
|
const main2 = mainCheckoutOfWorktree(root) ?? root;
|
|
101290
101556
|
found.add(main2);
|
|
101291
|
-
const dir =
|
|
101557
|
+
const dir = join57(main2, ".git", "worktrees");
|
|
101292
101558
|
if (!existsSync40(dir)) continue;
|
|
101293
101559
|
let names;
|
|
101294
101560
|
try {
|
|
@@ -101298,7 +101564,7 @@ function codexHookRoots(roots) {
|
|
|
101298
101564
|
}
|
|
101299
101565
|
for (const name2 of names) {
|
|
101300
101566
|
try {
|
|
101301
|
-
const checkout =
|
|
101567
|
+
const checkout = dirname22(readFileSync49(join57(dir, name2, "gitdir"), "utf8").trim());
|
|
101302
101568
|
if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
|
|
101303
101569
|
} catch {
|
|
101304
101570
|
}
|
|
@@ -101321,8 +101587,8 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
|
|
|
101321
101587
|
|
|
101322
101588
|
// src/claude-mods.ts
|
|
101323
101589
|
import { createHash as createHash22 } from "node:crypto";
|
|
101324
|
-
import { cpSync as cpSync3, existsSync as existsSync41, mkdirSync as mkdirSync12, readFileSync as
|
|
101325
|
-
import { delimiter as delimiter2, dirname as
|
|
101590
|
+
import { cpSync as cpSync3, existsSync as existsSync41, mkdirSync as mkdirSync12, readFileSync as readFileSync50, readdirSync as readdirSync15, rmSync as rmSync4, statSync as statSync16, writeFileSync as writeFileSync34 } from "node:fs";
|
|
101591
|
+
import { delimiter as delimiter2, dirname as dirname23, join as join58, relative as relative7, resolve as resolve10, sep as sep6 } from "node:path";
|
|
101326
101592
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
101327
101593
|
var CLAUDE_PLUGIN_DIRS_ENV = "CLAUDE_CODE_PLUGIN_DIRS";
|
|
101328
101594
|
var HASH_FILE = ".errata-mod-hash";
|
|
@@ -101337,7 +101603,7 @@ function isEngineOwned(relPath) {
|
|
|
101337
101603
|
function listFiles(root, dir = root) {
|
|
101338
101604
|
const out2 = [];
|
|
101339
101605
|
for (const name2 of readdirSync15(dir)) {
|
|
101340
|
-
const abs =
|
|
101606
|
+
const abs = join58(dir, name2);
|
|
101341
101607
|
if (isEngineOwned(relative7(root, abs))) continue;
|
|
101342
101608
|
if (statSync16(abs).isDirectory()) out2.push(...listFiles(root, abs));
|
|
101343
101609
|
else out2.push(abs);
|
|
@@ -101349,14 +101615,14 @@ function modHash(dir) {
|
|
|
101349
101615
|
for (const abs of listFiles(dir).sort()) {
|
|
101350
101616
|
h.update(relative7(dir, abs).split(sep6).join("/"));
|
|
101351
101617
|
h.update("\0");
|
|
101352
|
-
h.update(
|
|
101618
|
+
h.update(readFileSync50(abs));
|
|
101353
101619
|
h.update("\0");
|
|
101354
101620
|
}
|
|
101355
101621
|
return h.digest("hex");
|
|
101356
101622
|
}
|
|
101357
101623
|
function bundledMods(bundleDir) {
|
|
101358
101624
|
if (!existsSync41(bundleDir)) return [];
|
|
101359
|
-
return readdirSync15(bundleDir).filter((name2) => existsSync41(
|
|
101625
|
+
return readdirSync15(bundleDir).filter((name2) => existsSync41(join58(bundleDir, name2, ".claude-plugin", "plugin.json")));
|
|
101360
101626
|
}
|
|
101361
101627
|
function sameDir(a, b) {
|
|
101362
101628
|
const norm = (p) => resolve10(p).replace(/[\\/]+$/, "").toLowerCase();
|
|
@@ -101373,7 +101639,7 @@ function off(env2) {
|
|
|
101373
101639
|
function readSettings(path3) {
|
|
101374
101640
|
if (!existsSync41(path3)) return {};
|
|
101375
101641
|
try {
|
|
101376
|
-
const parsed = JSON.parse(
|
|
101642
|
+
const parsed = JSON.parse(readFileSync50(path3, "utf8"));
|
|
101377
101643
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
101378
101644
|
return parsed;
|
|
101379
101645
|
} catch {
|
|
@@ -101397,13 +101663,13 @@ function currentDirs(settings) {
|
|
|
101397
101663
|
return raw2.split(delimiter2).map((s) => s.trim()).filter(Boolean);
|
|
101398
101664
|
}
|
|
101399
101665
|
function writeSettings(path3, settings) {
|
|
101400
|
-
mkdirSync12(
|
|
101401
|
-
|
|
101666
|
+
mkdirSync12(dirname23(path3), { recursive: true });
|
|
101667
|
+
writeFileSync34(path3, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
101402
101668
|
}
|
|
101403
101669
|
function ensureClaudeMods(opts) {
|
|
101404
101670
|
const env2 = opts.env ?? process.env;
|
|
101405
101671
|
const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
|
|
101406
|
-
const modsRoot =
|
|
101672
|
+
const modsRoot = join58(opts.installRoot, "claude-mods");
|
|
101407
101673
|
if (off(env2)) {
|
|
101408
101674
|
const settings2 = readSettings(settingsPath);
|
|
101409
101675
|
if (!settings2) return { kind: "unreadable" };
|
|
@@ -101420,14 +101686,14 @@ function ensureClaudeMods(opts) {
|
|
|
101420
101686
|
let changed = false;
|
|
101421
101687
|
const installed = [];
|
|
101422
101688
|
for (const name2 of names) {
|
|
101423
|
-
const src =
|
|
101424
|
-
const dest =
|
|
101689
|
+
const src = join58(bundleDir, name2);
|
|
101690
|
+
const dest = join58(modsRoot, name2);
|
|
101425
101691
|
const hash2 = modHash(src);
|
|
101426
|
-
const hashFile =
|
|
101427
|
-
if (!existsSync41(hashFile) ||
|
|
101692
|
+
const hashFile = join58(dest, HASH_FILE);
|
|
101693
|
+
if (!existsSync41(hashFile) || readFileSync50(hashFile, "utf8") !== hash2) {
|
|
101428
101694
|
rmSync4(dest, { recursive: true, force: true });
|
|
101429
101695
|
cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative7(src, p)) });
|
|
101430
|
-
|
|
101696
|
+
writeFileSync34(hashFile, hash2, "utf8");
|
|
101431
101697
|
changed = true;
|
|
101432
101698
|
}
|
|
101433
101699
|
installed.push(dest);
|
|
@@ -101858,9 +102124,9 @@ function resolveHookPort(explicit) {
|
|
|
101858
102124
|
}
|
|
101859
102125
|
}
|
|
101860
102126
|
}
|
|
101861
|
-
const settingsPath =
|
|
102127
|
+
const settingsPath = join59(ROOT, ".claude", "settings.json");
|
|
101862
102128
|
try {
|
|
101863
|
-
if (existsSync42(settingsPath)) return installedHookPort(
|
|
102129
|
+
if (existsSync42(settingsPath)) return installedHookPort(readFileSync51(settingsPath, "utf8")) ?? 7891;
|
|
101864
102130
|
} catch {
|
|
101865
102131
|
}
|
|
101866
102132
|
return 7891;
|
|
@@ -101886,13 +102152,13 @@ async function cmdInit() {
|
|
|
101886
102152
|
console.log("");
|
|
101887
102153
|
console.log("installing harness hooks...");
|
|
101888
102154
|
const { existsSync: existsSync43 } = await import("node:fs");
|
|
101889
|
-
const { join:
|
|
102155
|
+
const { join: join60 } = await import("node:path");
|
|
101890
102156
|
try {
|
|
101891
102157
|
await installClaudeHooks(port);
|
|
101892
102158
|
} catch (err2) {
|
|
101893
102159
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
101894
102160
|
}
|
|
101895
|
-
if (existsSync43(
|
|
102161
|
+
if (existsSync43(join60(ROOT, ".cursor"))) {
|
|
101896
102162
|
try {
|
|
101897
102163
|
await installCursorMcpConfig();
|
|
101898
102164
|
} catch (err2) {
|
|
@@ -103118,7 +103384,7 @@ async function cmdReview() {
|
|
|
103118
103384
|
console.log("(review queue empty)");
|
|
103119
103385
|
return;
|
|
103120
103386
|
}
|
|
103121
|
-
const queue = JSON.parse(
|
|
103387
|
+
const queue = JSON.parse(readFileSync51(paths.reviewQueue, "utf8"));
|
|
103122
103388
|
if (queue.length === 0) {
|
|
103123
103389
|
console.log("(review queue empty)");
|
|
103124
103390
|
return;
|
|
@@ -103857,7 +104123,7 @@ async function gatherReportData(generatedAt) {
|
|
|
103857
104123
|
};
|
|
103858
104124
|
}
|
|
103859
104125
|
async function cmdReport(args2) {
|
|
103860
|
-
const { mkdirSync: mkdirSync13, writeFileSync:
|
|
104126
|
+
const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
103861
104127
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
103862
104128
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
103863
104129
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -103870,8 +104136,8 @@ async function cmdReport(args2) {
|
|
|
103870
104136
|
const outDir = workspacePaths(ROOT).configDir;
|
|
103871
104137
|
mkdirSync13(outDir, { recursive: true });
|
|
103872
104138
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
103873
|
-
for (const f of files)
|
|
103874
|
-
const indexPath =
|
|
104139
|
+
for (const f of files) writeFileSync36(join59(outDir, f.name), f.html, "utf8");
|
|
104140
|
+
const indexPath = join59(outDir, "report.html");
|
|
103875
104141
|
console.log(`report \u2192 ${indexPath}`);
|
|
103876
104142
|
console.log(
|
|
103877
104143
|
` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
|
|
@@ -103927,7 +104193,7 @@ function spawnDaemonDetached(options = {}) {
|
|
|
103927
104193
|
try {
|
|
103928
104194
|
const logPath = daemonLogPath();
|
|
103929
104195
|
try {
|
|
103930
|
-
if (statSync17(logPath).size > 5 * 1024 * 1024)
|
|
104196
|
+
if (statSync17(logPath).size > 5 * 1024 * 1024) renameSync11(logPath, `${logPath}.1`);
|
|
103931
104197
|
} catch {
|
|
103932
104198
|
}
|
|
103933
104199
|
out2 = openSync3(logPath, "a");
|
|
@@ -104000,24 +104266,24 @@ async function cmdInstallHooks(args2) {
|
|
|
104000
104266
|
}
|
|
104001
104267
|
}
|
|
104002
104268
|
async function installOpencodePlugin(port) {
|
|
104003
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync:
|
|
104004
|
-
const { join:
|
|
104005
|
-
const dir =
|
|
104269
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync: readFileSync52, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
104270
|
+
const { join: join60 } = await import("node:path");
|
|
104271
|
+
const dir = join60(ROOT, ".opencode", "plugin");
|
|
104006
104272
|
if (!existsSync43(dir)) mkdirSync13(dir, { recursive: true });
|
|
104007
|
-
const file2 =
|
|
104273
|
+
const file2 = join60(dir, "inerrata.js");
|
|
104008
104274
|
if (existsSync43(file2)) {
|
|
104009
|
-
const head2 =
|
|
104275
|
+
const head2 = readFileSync52(file2, "utf8").split("\n")[0] ?? "";
|
|
104010
104276
|
if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
|
|
104011
104277
|
console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
|
|
104012
104278
|
process.exit(2);
|
|
104013
104279
|
}
|
|
104014
104280
|
}
|
|
104015
|
-
|
|
104016
|
-
const cfgFile =
|
|
104281
|
+
writeFileSync36(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
|
|
104282
|
+
const cfgFile = join60(ROOT, "opencode.json");
|
|
104017
104283
|
let cfg = { $schema: "https://opencode.ai/config.json" };
|
|
104018
104284
|
if (existsSync43(cfgFile)) {
|
|
104019
104285
|
try {
|
|
104020
|
-
cfg = JSON.parse(
|
|
104286
|
+
cfg = JSON.parse(readFileSync52(cfgFile, "utf8"));
|
|
104021
104287
|
} catch {
|
|
104022
104288
|
console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
|
|
104023
104289
|
process.exit(2);
|
|
@@ -104028,7 +104294,7 @@ async function installOpencodePlugin(port) {
|
|
|
104028
104294
|
if (!hadErrata) {
|
|
104029
104295
|
const inv = errataMcpInvocation();
|
|
104030
104296
|
cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
|
|
104031
|
-
|
|
104297
|
+
writeFileSync36(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
104032
104298
|
}
|
|
104033
104299
|
console.log(`installed OpenCode plugin \u2192 ${file2}`);
|
|
104034
104300
|
if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
|
|
@@ -104062,15 +104328,15 @@ function installClaudeMods() {
|
|
|
104062
104328
|
}
|
|
104063
104329
|
}
|
|
104064
104330
|
async function installClaudeHooks(port) {
|
|
104065
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync:
|
|
104066
|
-
const { join:
|
|
104067
|
-
const dir =
|
|
104331
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync: readFileSync52, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
104332
|
+
const { join: join60 } = await import("node:path");
|
|
104333
|
+
const dir = join60(ROOT, ".claude");
|
|
104068
104334
|
if (!existsSync43(dir)) mkdirSync13(dir, { recursive: true });
|
|
104069
|
-
const file2 =
|
|
104335
|
+
const file2 = join60(dir, "settings.json");
|
|
104070
104336
|
let settings = {};
|
|
104071
104337
|
if (existsSync43(file2)) {
|
|
104072
104338
|
try {
|
|
104073
|
-
settings = JSON.parse(
|
|
104339
|
+
settings = JSON.parse(readFileSync52(file2, "utf8"));
|
|
104074
104340
|
} catch {
|
|
104075
104341
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
104076
104342
|
process.exit(2);
|
|
@@ -104078,12 +104344,12 @@ async function installClaudeHooks(port) {
|
|
|
104078
104344
|
}
|
|
104079
104345
|
applyClaudeErrataHooks(settings, port);
|
|
104080
104346
|
removeProjectStatusLine(settings);
|
|
104081
|
-
|
|
104347
|
+
writeFileSync36(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
104082
104348
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
104083
104349
|
console.log(` ${ensureStatusLine(port)}`);
|
|
104084
104350
|
console.log(` ${installClaudeMods().line}`);
|
|
104085
104351
|
await installClaudeMcpConfig();
|
|
104086
|
-
const claudeMd =
|
|
104352
|
+
const claudeMd = join60(ROOT, "CLAUDE.md");
|
|
104087
104353
|
const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
|
|
104088
104354
|
if (recall.kind === "collision") {
|
|
104089
104355
|
console.warn(
|
|
@@ -104095,15 +104361,15 @@ async function installClaudeHooks(port) {
|
|
|
104095
104361
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
104096
104362
|
}
|
|
104097
104363
|
async function installClaudeMcpConfig() {
|
|
104098
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync:
|
|
104099
|
-
const { join:
|
|
104100
|
-
const file2 =
|
|
104101
|
-
const dir =
|
|
104364
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync: readFileSync52, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
104365
|
+
const { join: join60, dirname: dirname24 } = await import("node:path");
|
|
104366
|
+
const file2 = join60(ROOT, ".mcp.json");
|
|
104367
|
+
const dir = dirname24(file2);
|
|
104102
104368
|
if (!existsSync43(dir)) mkdirSync13(dir, { recursive: true });
|
|
104103
104369
|
let cfg = {};
|
|
104104
104370
|
if (existsSync43(file2)) {
|
|
104105
104371
|
try {
|
|
104106
|
-
cfg = JSON.parse(
|
|
104372
|
+
cfg = JSON.parse(readFileSync52(file2, "utf8"));
|
|
104107
104373
|
} catch {
|
|
104108
104374
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
104109
104375
|
process.exit(2);
|
|
@@ -104111,21 +104377,21 @@ async function installClaudeMcpConfig() {
|
|
|
104111
104377
|
}
|
|
104112
104378
|
cfg.mcpServers ??= {};
|
|
104113
104379
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
104114
|
-
|
|
104380
|
+
writeFileSync36(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
104115
104381
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
104116
104382
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
104117
104383
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
104118
104384
|
}
|
|
104119
104385
|
async function installCursorMcpConfig() {
|
|
104120
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync:
|
|
104121
|
-
const { join:
|
|
104122
|
-
const dir =
|
|
104386
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync: readFileSync52, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
104387
|
+
const { join: join60 } = await import("node:path");
|
|
104388
|
+
const dir = join60(ROOT, ".cursor");
|
|
104123
104389
|
if (!existsSync43(dir)) mkdirSync13(dir, { recursive: true });
|
|
104124
|
-
const file2 =
|
|
104390
|
+
const file2 = join60(dir, "mcp.json");
|
|
104125
104391
|
let cfg = {};
|
|
104126
104392
|
if (existsSync43(file2)) {
|
|
104127
104393
|
try {
|
|
104128
|
-
cfg = JSON.parse(
|
|
104394
|
+
cfg = JSON.parse(readFileSync52(file2, "utf8"));
|
|
104129
104395
|
} catch {
|
|
104130
104396
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
104131
104397
|
process.exit(2);
|
|
@@ -104133,7 +104399,7 @@ async function installCursorMcpConfig() {
|
|
|
104133
104399
|
}
|
|
104134
104400
|
cfg.mcpServers ??= {};
|
|
104135
104401
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
104136
|
-
|
|
104402
|
+
writeFileSync36(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
104137
104403
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
104138
104404
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
104139
104405
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -104144,7 +104410,7 @@ async function installCodexHooks(port) {
|
|
|
104144
104410
|
const gitRoot = nearestGitRoot(process.cwd());
|
|
104145
104411
|
const hookRoot = gitRoot && mainCheckoutOfWorktree(gitRoot) ? gitRoot : ROOT;
|
|
104146
104412
|
const file2 = writeCodexHooks(hookRoot, port);
|
|
104147
|
-
const instructions = writeManagedBlock(
|
|
104413
|
+
const instructions = writeManagedBlock(join59(hookRoot, "AGENTS.md"), {
|
|
104148
104414
|
body: AGENTS_POINTER_BODY,
|
|
104149
104415
|
stable: true
|
|
104150
104416
|
});
|
|
@@ -104192,12 +104458,12 @@ function refreshExistingClaudeHooks() {
|
|
|
104192
104458
|
let ok = true;
|
|
104193
104459
|
const roots = [...listWorkspaceEntries().map((entry) => entry.path), process.cwd()];
|
|
104194
104460
|
for (const root of codexHookRoots(roots)) {
|
|
104195
|
-
const file2 =
|
|
104461
|
+
const file2 = join59(root, ".claude", "settings.json");
|
|
104196
104462
|
try {
|
|
104197
104463
|
if (!existsSync42(file2) || isReplayCheckout(root)) continue;
|
|
104198
|
-
const next = refreshClaudeHookSettings(
|
|
104464
|
+
const next = refreshClaudeHookSettings(readFileSync51(file2, "utf8"));
|
|
104199
104465
|
if (next === null) continue;
|
|
104200
|
-
|
|
104466
|
+
writeFileSync35(file2, next, "utf8");
|
|
104201
104467
|
console.log(`updated existing Claude Code hooks \u2192 ${file2}`);
|
|
104202
104468
|
} catch (error48) {
|
|
104203
104469
|
ok = false;
|
|
@@ -104609,9 +104875,9 @@ async function cmdDash(args2) {
|
|
|
104609
104875
|
await yieldToLoop2();
|
|
104610
104876
|
try {
|
|
104611
104877
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
|
|
104612
|
-
atCommit: readGitRefState(
|
|
104878
|
+
atCommit: readGitRefState(join59(r.root, ".git")).sha ?? void 0
|
|
104613
104879
|
});
|
|
104614
|
-
const res = bleedRules(
|
|
104880
|
+
const res = bleedRules(join59(r.root, ".claude", "rules"), items);
|
|
104615
104881
|
if (res.written || res.pruned) {
|
|
104616
104882
|
console.log(
|
|
104617
104883
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|