@inerrata-corporation/errata 2.0.23-dev.4901 → 2.0.23-dev.5015
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.5015" : "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;
|
|
@@ -95898,6 +96164,11 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
95898
96164
|
return { profile, processed, state: profile.historyStage?.state ?? "done" };
|
|
95899
96165
|
}
|
|
95900
96166
|
|
|
96167
|
+
// src/history-flag.ts
|
|
96168
|
+
function historyIngestEnabled() {
|
|
96169
|
+
return process.env.ERRATA_HISTORY === "1";
|
|
96170
|
+
}
|
|
96171
|
+
|
|
95901
96172
|
// src/history-stage.ts
|
|
95902
96173
|
function historyConsents(profile) {
|
|
95903
96174
|
const c = profile.linkConsents;
|
|
@@ -95961,9 +96232,6 @@ function applyStopRequest(profile, now = () => /* @__PURE__ */ new Date()) {
|
|
|
95961
96232
|
}
|
|
95962
96233
|
};
|
|
95963
96234
|
}
|
|
95964
|
-
function historyIngestEnabled() {
|
|
95965
|
-
return process.env.ERRATA_HISTORY === "1";
|
|
95966
|
-
}
|
|
95967
96235
|
async function startHistoryStage(root, input, client, walk11 = {}) {
|
|
95968
96236
|
let profile = input;
|
|
95969
96237
|
if (!profile.projectId) return { started: false, reason: "no-project", profile };
|
|
@@ -95987,8 +96255,8 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
|
|
|
95987
96255
|
init_cloud_auth();
|
|
95988
96256
|
import { createHash as createHash20 } from "node:crypto";
|
|
95989
96257
|
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
95990
|
-
import { existsSync as existsSync34, writeFileSync as
|
|
95991
|
-
import { join as
|
|
96258
|
+
import { existsSync as existsSync34, writeFileSync as writeFileSync29 } from "node:fs";
|
|
96259
|
+
import { join as join48 } from "node:path";
|
|
95992
96260
|
|
|
95993
96261
|
// src/device-poll.ts
|
|
95994
96262
|
var THROTTLED_POLL_MIN_WAIT_MS = 11e3;
|
|
@@ -96447,9 +96715,9 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
|
|
|
96447
96715
|
delete nextProfile.projectLinkHold;
|
|
96448
96716
|
let wroteIgnore = false;
|
|
96449
96717
|
if (decision.writeIgnoreStarter !== false) {
|
|
96450
|
-
const target =
|
|
96718
|
+
const target = join48(root, ".errataignore");
|
|
96451
96719
|
if (!existsSync34(target)) {
|
|
96452
|
-
|
|
96720
|
+
writeFileSync29(target, IGNORE_STARTER, "utf8");
|
|
96453
96721
|
wroteIgnore = true;
|
|
96454
96722
|
}
|
|
96455
96723
|
}
|
|
@@ -96463,12 +96731,12 @@ init_registry();
|
|
|
96463
96731
|
// src/adopt.ts
|
|
96464
96732
|
init_git_remote();
|
|
96465
96733
|
import { existsSync as existsSync35 } from "node:fs";
|
|
96466
|
-
import { dirname as
|
|
96734
|
+
import { dirname as dirname19, join as join49 } from "node:path";
|
|
96467
96735
|
function findGitRoot(absPath) {
|
|
96468
96736
|
let dir = absPath;
|
|
96469
96737
|
for (let depth = 0; depth < 64; depth++) {
|
|
96470
|
-
if (existsSync35(
|
|
96471
|
-
const parent =
|
|
96738
|
+
if (existsSync35(join49(dir, ".git"))) return dir;
|
|
96739
|
+
const parent = dirname19(dir);
|
|
96472
96740
|
if (parent === dir) return null;
|
|
96473
96741
|
dir = parent;
|
|
96474
96742
|
}
|
|
@@ -97110,7 +97378,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97110
97378
|
};
|
|
97111
97379
|
const sharedDbPath = sharedStorePath();
|
|
97112
97380
|
ensureParent(sharedDbPath);
|
|
97113
|
-
if (sharedDbPath !== ":memory:") excludeFromIndexing(
|
|
97381
|
+
if (sharedDbPath !== ":memory:") excludeFromIndexing(dirname20(sharedDbPath));
|
|
97114
97382
|
await prepareStore(sharedDbPath, process.cwd(), "shared");
|
|
97115
97383
|
const sharedStore = openGraphStore({ path: sharedDbPath });
|
|
97116
97384
|
const bundledRun = import.meta.url.endsWith(".mjs");
|
|
@@ -97254,7 +97522,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97254
97522
|
held.push(...quarantined);
|
|
97255
97523
|
let ignoreFile = "";
|
|
97256
97524
|
try {
|
|
97257
|
-
ignoreFile =
|
|
97525
|
+
ignoreFile = readFileSync43(join50(r.root, ".errataignore"), "utf8");
|
|
97258
97526
|
} catch {
|
|
97259
97527
|
}
|
|
97260
97528
|
const retryInputs = JSON.stringify([
|
|
@@ -97322,7 +97590,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97322
97590
|
const id = entry.id;
|
|
97323
97591
|
const castaliaPath = workspacePaths(entry.path).castalia;
|
|
97324
97592
|
ensureParent(castaliaPath);
|
|
97325
|
-
excludeFromIndexing(
|
|
97593
|
+
excludeFromIndexing(dirname20(castaliaPath));
|
|
97326
97594
|
await prepareStore(castaliaPath, entry.path, id);
|
|
97327
97595
|
if (stopping) throw new Error("daemon stopping");
|
|
97328
97596
|
const wsIdentity = identityFor(entry);
|
|
@@ -97459,7 +97727,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97459
97727
|
records.push(rec);
|
|
97460
97728
|
void ambientLinkAll();
|
|
97461
97729
|
try {
|
|
97462
|
-
|
|
97730
|
+
writeFileSync30(
|
|
97463
97731
|
rec.engine.paths.daemonLock,
|
|
97464
97732
|
daemonLockPayload({
|
|
97465
97733
|
pid: process.pid,
|
|
@@ -97835,10 +98103,10 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97835
98103
|
};
|
|
97836
98104
|
const MISFILED_SWEEP_DELAY_MS = 2 * 6e4;
|
|
97837
98105
|
const sweepMisfiled = async (rec) => {
|
|
97838
|
-
const checkedPath =
|
|
98106
|
+
const checkedPath = join50(workspacePaths(rec.root).configDir, "rehome-checked.json");
|
|
97839
98107
|
let checked;
|
|
97840
98108
|
try {
|
|
97841
|
-
checked = new Set(JSON.parse(
|
|
98109
|
+
checked = new Set(JSON.parse(readFileSync43(checkedPath, "utf8")));
|
|
97842
98110
|
} catch {
|
|
97843
98111
|
checked = /* @__PURE__ */ new Set();
|
|
97844
98112
|
}
|
|
@@ -97854,7 +98122,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97854
98122
|
if (to) await rehomeMisfiled(sid, rec, to, "its captures were raised in its files");
|
|
97855
98123
|
await new Promise((r) => setImmediate(r));
|
|
97856
98124
|
}
|
|
97857
|
-
if (changed)
|
|
98125
|
+
if (changed) writeFileSync30(checkedPath, JSON.stringify([...checked]), "utf8");
|
|
97858
98126
|
};
|
|
97859
98127
|
afterAttach = (rec) => {
|
|
97860
98128
|
const t = setTimeout(() => {
|
|
@@ -98030,7 +98298,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
98030
98298
|
baseUrl = `http://127.0.0.1:${port}`;
|
|
98031
98299
|
try {
|
|
98032
98300
|
ensureDir(globalDir());
|
|
98033
|
-
|
|
98301
|
+
writeFileSync30(
|
|
98034
98302
|
lockPath,
|
|
98035
98303
|
daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
|
|
98036
98304
|
"utf8"
|
|
@@ -98039,7 +98307,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
98039
98307
|
}
|
|
98040
98308
|
for (const r of records) {
|
|
98041
98309
|
try {
|
|
98042
|
-
|
|
98310
|
+
writeFileSync30(
|
|
98043
98311
|
r.engine.paths.daemonLock,
|
|
98044
98312
|
daemonLockPayload({
|
|
98045
98313
|
pid: process.pid,
|
|
@@ -99586,7 +99854,7 @@ import { spawnSync as spawnSync2 } from "node:child_process";
|
|
|
99586
99854
|
|
|
99587
99855
|
// src/codex-runtime.ts
|
|
99588
99856
|
import { readdirSync as readdirSync13, statSync as statSync13 } from "node:fs";
|
|
99589
|
-
import { join as
|
|
99857
|
+
import { join as join51 } from "node:path";
|
|
99590
99858
|
function resolveCodexExecutable(options = {}) {
|
|
99591
99859
|
const platform = options.platform ?? process.platform;
|
|
99592
99860
|
const env2 = options.env ?? process.env;
|
|
@@ -99601,13 +99869,13 @@ function resolveCodexExecutable(options = {}) {
|
|
|
99601
99869
|
};
|
|
99602
99870
|
for (const dir of (env2["PATH"] ?? env2["Path"] ?? "").split(";")) {
|
|
99603
99871
|
if (!dir.trim()) continue;
|
|
99604
|
-
const path3 =
|
|
99872
|
+
const path3 = join51(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
|
|
99605
99873
|
if (fileTime(path3) !== null) return path3;
|
|
99606
99874
|
}
|
|
99607
99875
|
if (!env2["LOCALAPPDATA"]) return "codex";
|
|
99608
|
-
const root =
|
|
99876
|
+
const root = join51(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
|
|
99609
99877
|
try {
|
|
99610
|
-
const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
99878
|
+
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
99879
|
return candidates[0]?.path ?? "codex";
|
|
99612
99880
|
} catch {
|
|
99613
99881
|
return "codex";
|
|
@@ -99746,14 +100014,14 @@ async function diagnoseInstallation(cfg, dependencies) {
|
|
|
99746
100014
|
}
|
|
99747
100015
|
|
|
99748
100016
|
// src/credential-scan.ts
|
|
99749
|
-
import { readFileSync as
|
|
100017
|
+
import { readFileSync as readFileSync45, statSync as statSync14 } from "node:fs";
|
|
99750
100018
|
import { homedir as homedir8 } from "node:os";
|
|
99751
|
-
import { join as
|
|
100019
|
+
import { join as join53 } from "node:path";
|
|
99752
100020
|
|
|
99753
100021
|
// src/claude-statusline.ts
|
|
99754
|
-
import { existsSync as existsSync37, mkdirSync as mkdirSync9, readFileSync as
|
|
100022
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync9, readFileSync as readFileSync44, writeFileSync as writeFileSync31 } from "node:fs";
|
|
99755
100023
|
import { homedir as homedir7 } from "node:os";
|
|
99756
|
-
import { dirname as
|
|
100024
|
+
import { dirname as dirname21, join as join52 } from "node:path";
|
|
99757
100025
|
var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
|
|
99758
100026
|
import { readFileSync } from 'node:fs';
|
|
99759
100027
|
|
|
@@ -99801,8 +100069,8 @@ function isSameInstall(value, relay) {
|
|
|
99801
100069
|
return command.includes(relay.replace(/\\/g, "/").toLowerCase());
|
|
99802
100070
|
}
|
|
99803
100071
|
function userClaudeSettingsPath() {
|
|
99804
|
-
const base = process.env["CLAUDE_CONFIG_DIR"] ??
|
|
99805
|
-
return
|
|
100072
|
+
const base = process.env["CLAUDE_CONFIG_DIR"] ?? join52(homedir7(), ".claude");
|
|
100073
|
+
return join52(base, "settings.json");
|
|
99806
100074
|
}
|
|
99807
100075
|
function ensureUserStatusLine(opts) {
|
|
99808
100076
|
const env2 = opts.env ?? process.env;
|
|
@@ -99812,21 +100080,21 @@ function ensureUserStatusLine(opts) {
|
|
|
99812
100080
|
let settings = {};
|
|
99813
100081
|
if (existsSync37(settingsPath)) {
|
|
99814
100082
|
try {
|
|
99815
|
-
const parsed = JSON.parse(
|
|
100083
|
+
const parsed = JSON.parse(readFileSync44(settingsPath, "utf8"));
|
|
99816
100084
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
|
|
99817
100085
|
settings = parsed;
|
|
99818
100086
|
} catch {
|
|
99819
100087
|
return "unreadable";
|
|
99820
100088
|
}
|
|
99821
100089
|
}
|
|
99822
|
-
const relay =
|
|
100090
|
+
const relay = join52(opts.relayDir, STATUSLINE_RELAY_FILE);
|
|
99823
100091
|
const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
|
|
99824
100092
|
const ownMain = keep(settings["statusLine"]);
|
|
99825
100093
|
const ownRows = keep(settings["subagentStatusLine"]);
|
|
99826
100094
|
if (ownMain && ownRows) return "kept-own";
|
|
99827
100095
|
mkdirSync9(opts.relayDir, { recursive: true });
|
|
99828
|
-
if (!existsSync37(relay) ||
|
|
99829
|
-
|
|
100096
|
+
if (!existsSync37(relay) || readFileSync44(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
|
|
100097
|
+
writeFileSync31(relay, STATUSLINE_RELAY_SOURCE, "utf8");
|
|
99830
100098
|
}
|
|
99831
100099
|
const nodePath = opts.nodePath ?? process.execPath;
|
|
99832
100100
|
const next = {
|
|
@@ -99837,8 +100105,8 @@ function ensureUserStatusLine(opts) {
|
|
|
99837
100105
|
return ownMain ? "kept-own" : "unchanged";
|
|
99838
100106
|
}
|
|
99839
100107
|
Object.assign(settings, next);
|
|
99840
|
-
mkdirSync9(
|
|
99841
|
-
|
|
100108
|
+
mkdirSync9(dirname21(settingsPath), { recursive: true });
|
|
100109
|
+
writeFileSync31(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
99842
100110
|
return "installed";
|
|
99843
100111
|
}
|
|
99844
100112
|
function describeStatusLineOutcome(outcome) {
|
|
@@ -99879,36 +100147,36 @@ function findCredentialLines(text) {
|
|
|
99879
100147
|
function harnessConfigPaths(root) {
|
|
99880
100148
|
const env2 = process.env;
|
|
99881
100149
|
const home = homedir8();
|
|
99882
|
-
const codexHome = env2["CODEX_HOME"] ||
|
|
99883
|
-
const geminiHome =
|
|
100150
|
+
const codexHome = env2["CODEX_HOME"] || join53(home, ".codex");
|
|
100151
|
+
const geminiHome = join53(env2["GEMINI_CLI_HOME"] ?? home, ".gemini");
|
|
99884
100152
|
return [
|
|
99885
100153
|
// Claude Code: user settings, `claude mcp add` (local/user scope), project.
|
|
99886
100154
|
userClaudeSettingsPath(),
|
|
99887
|
-
|
|
99888
|
-
|
|
99889
|
-
|
|
99890
|
-
|
|
100155
|
+
join53(env2["CLAUDE_CONFIG_DIR"] ?? home, ".claude.json"),
|
|
100156
|
+
join53(root, ".claude", "settings.json"),
|
|
100157
|
+
join53(root, ".claude", "settings.local.json"),
|
|
100158
|
+
join53(root, ".mcp.json"),
|
|
99891
100159
|
// Codex
|
|
99892
|
-
|
|
99893
|
-
|
|
100160
|
+
join53(codexHome, "config.toml"),
|
|
100161
|
+
join53(root, ".codex", "config.toml"),
|
|
99894
100162
|
// Gemini CLI
|
|
99895
|
-
|
|
99896
|
-
|
|
100163
|
+
join53(geminiHome, "settings.json"),
|
|
100164
|
+
join53(root, ".gemini", "settings.json"),
|
|
99897
100165
|
// Cursor
|
|
99898
|
-
|
|
99899
|
-
|
|
100166
|
+
join53(home, ".cursor", "mcp.json"),
|
|
100167
|
+
join53(root, ".cursor", "mcp.json"),
|
|
99900
100168
|
// VS Code (user profile mcp.json + workspace)
|
|
99901
|
-
|
|
99902
|
-
|
|
100169
|
+
join53(vscodeUserDir(home, env2), "mcp.json"),
|
|
100170
|
+
join53(root, ".vscode", "mcp.json"),
|
|
99903
100171
|
// OpenCode (XDG on every platform; the daemon's installer writes the project one)
|
|
99904
|
-
|
|
99905
|
-
|
|
100172
|
+
join53(env2["XDG_CONFIG_HOME"] ?? join53(home, ".config"), "opencode", "opencode.json"),
|
|
100173
|
+
join53(root, "opencode.json")
|
|
99906
100174
|
];
|
|
99907
100175
|
}
|
|
99908
100176
|
function vscodeUserDir(home, env2) {
|
|
99909
|
-
if (process.platform === "win32") return
|
|
99910
|
-
if (process.platform === "darwin") return
|
|
99911
|
-
return
|
|
100177
|
+
if (process.platform === "win32") return join53(env2["APPDATA"] ?? join53(home, "AppData", "Roaming"), "Code", "User");
|
|
100178
|
+
if (process.platform === "darwin") return join53(home, "Library", "Application Support", "Code", "User");
|
|
100179
|
+
return join53(env2["XDG_CONFIG_HOME"] ?? join53(home, ".config"), "Code", "User");
|
|
99912
100180
|
}
|
|
99913
100181
|
function scanHarnessConfigs(paths, read2 = readBounded) {
|
|
99914
100182
|
const findings = [];
|
|
@@ -99925,7 +100193,7 @@ function readBounded(path3) {
|
|
|
99925
100193
|
try {
|
|
99926
100194
|
const stat4 = statSync14(path3);
|
|
99927
100195
|
if (!stat4.isFile() || stat4.size > MAX_SCAN_BYTES) return null;
|
|
99928
|
-
return
|
|
100196
|
+
return readFileSync45(path3, "utf8");
|
|
99929
100197
|
} catch {
|
|
99930
100198
|
return null;
|
|
99931
100199
|
}
|
|
@@ -99950,14 +100218,14 @@ function credentialHygieneCheck(scan2) {
|
|
|
99950
100218
|
|
|
99951
100219
|
// src/codex-doctor.ts
|
|
99952
100220
|
import { spawn as spawn4 } from "node:child_process";
|
|
99953
|
-
import { readFileSync as
|
|
99954
|
-
import { join as
|
|
100221
|
+
import { readFileSync as readFileSync47, statSync as statSync15 } from "node:fs";
|
|
100222
|
+
import { join as join55 } from "node:path";
|
|
99955
100223
|
import { createInterface } from "node:readline";
|
|
99956
100224
|
|
|
99957
100225
|
// src/codex-hooks.ts
|
|
99958
|
-
import { existsSync as existsSync38, mkdirSync as mkdirSync10, readFileSync as
|
|
100226
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync10, readFileSync as readFileSync46, renameSync as renameSync9, unlinkSync as unlinkSync5, writeFileSync as writeFileSync32 } from "node:fs";
|
|
99959
100227
|
import { homedir as homedir9 } from "node:os";
|
|
99960
|
-
import { join as
|
|
100228
|
+
import { join as join54 } from "node:path";
|
|
99961
100229
|
|
|
99962
100230
|
// src/hook-commands.ts
|
|
99963
100231
|
function hookCurlCommand(port, path3 = "/api/hook") {
|
|
@@ -100213,34 +100481,34 @@ function buildCodexRelaySource(workspaceRoot) {
|
|
|
100213
100481
|
init_checkout_root();
|
|
100214
100482
|
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
100483
|
function writeRelay(file2, source) {
|
|
100216
|
-
if (existsSync38(file2) &&
|
|
100484
|
+
if (existsSync38(file2) && readFileSync46(file2, "utf8") === source) return;
|
|
100217
100485
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
100218
100486
|
try {
|
|
100219
|
-
|
|
100220
|
-
|
|
100487
|
+
writeFileSync32(temp, source, { encoding: "utf8", mode: 384 });
|
|
100488
|
+
renameSync9(temp, file2);
|
|
100221
100489
|
} finally {
|
|
100222
100490
|
if (existsSync38(temp)) unlinkSync5(temp);
|
|
100223
100491
|
}
|
|
100224
100492
|
}
|
|
100225
100493
|
function refreshCodexRelay(root) {
|
|
100226
|
-
const config2 =
|
|
100494
|
+
const config2 = join54(root, ".codex", "config.toml");
|
|
100227
100495
|
if (!existsSync38(config2)) return "absent";
|
|
100228
|
-
const existing =
|
|
100496
|
+
const existing = readFileSync46(config2, "utf8");
|
|
100229
100497
|
if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
|
|
100230
100498
|
replaceCodexHooks(existing, "");
|
|
100231
|
-
const relay =
|
|
100232
|
-
const prior = existsSync38(relay) ?
|
|
100499
|
+
const relay = join54(root, ".codex", "hooks", "errata-relay.mjs");
|
|
100500
|
+
const prior = existsSync38(relay) ? readFileSync46(relay, "utf8") : "";
|
|
100233
100501
|
if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
|
|
100234
100502
|
throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
|
|
100235
100503
|
}
|
|
100236
100504
|
const source = buildCodexRelaySource(checkoutRootOf(root));
|
|
100237
100505
|
if (prior === source) return "current";
|
|
100238
|
-
mkdirSync10(
|
|
100506
|
+
mkdirSync10(join54(root, ".codex", "hooks"), { recursive: true });
|
|
100239
100507
|
writeRelay(relay, source);
|
|
100240
100508
|
return "updated";
|
|
100241
100509
|
}
|
|
100242
|
-
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] ||
|
|
100243
|
-
return existsSync38(
|
|
100510
|
+
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join54(homedir9(), ".codex")) {
|
|
100511
|
+
return existsSync38(join54(root, ".codex")) || existsSync38(codexHome);
|
|
100244
100512
|
}
|
|
100245
100513
|
function replaceCodexHooks(existing, block) {
|
|
100246
100514
|
const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
|
|
@@ -100256,14 +100524,14 @@ function replaceCodexHooks(existing, block) {
|
|
|
100256
100524
|
return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
|
|
100257
100525
|
}
|
|
100258
100526
|
function writeCodexHooks(root, port, nodePath = process.execPath) {
|
|
100259
|
-
const dir =
|
|
100260
|
-
const file2 =
|
|
100261
|
-
const relay =
|
|
100527
|
+
const dir = join54(root, ".codex");
|
|
100528
|
+
const file2 = join54(dir, "config.toml");
|
|
100529
|
+
const relay = join54(dir, "hooks", "errata-relay.mjs");
|
|
100262
100530
|
const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
|
|
100263
|
-
const final = replaceCodexHooks(existsSync38(file2) ?
|
|
100264
|
-
mkdirSync10(
|
|
100531
|
+
const final = replaceCodexHooks(existsSync38(file2) ? readFileSync46(file2, "utf8") : "", block);
|
|
100532
|
+
mkdirSync10(join54(dir, "hooks"), { recursive: true });
|
|
100265
100533
|
writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
|
|
100266
|
-
if (!existsSync38(file2) ||
|
|
100534
|
+
if (!existsSync38(file2) || readFileSync46(file2, "utf8") !== final) writeFileSync32(file2, final, "utf8");
|
|
100267
100535
|
return file2;
|
|
100268
100536
|
}
|
|
100269
100537
|
|
|
@@ -100272,7 +100540,7 @@ init_checkout_root();
|
|
|
100272
100540
|
function inspectCodexRelay(cwd) {
|
|
100273
100541
|
const root = nearestGitRoot(cwd) ?? cwd;
|
|
100274
100542
|
try {
|
|
100275
|
-
const source =
|
|
100543
|
+
const source = readFileSync47(join55(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
|
|
100276
100544
|
if (source === buildCodexRelaySource(checkoutRootOf(root))) {
|
|
100277
100545
|
return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
|
|
100278
100546
|
}
|
|
@@ -100283,8 +100551,8 @@ function inspectCodexRelay(cwd) {
|
|
|
100283
100551
|
function inspectCodexContext(cwd) {
|
|
100284
100552
|
const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
|
|
100285
100553
|
try {
|
|
100286
|
-
const file2 =
|
|
100287
|
-
if (statSync15(file2).size <= 128 * 1024 &&
|
|
100554
|
+
const file2 = join55(root, ".errata", "context.md");
|
|
100555
|
+
if (statSync15(file2).size <= 128 * 1024 && readFileSync47(file2, "utf8").trim()) {
|
|
100288
100556
|
return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
|
|
100289
100557
|
}
|
|
100290
100558
|
} catch {
|
|
@@ -100423,9 +100691,9 @@ function effectiveMomentumThreshold(policy, liveNodes) {
|
|
|
100423
100691
|
return Math.max(policy.momentumThreshold, Math.ceil(liveNodes * policy.momentumRatio));
|
|
100424
100692
|
}
|
|
100425
100693
|
function nextMomentumThreshold(args2) {
|
|
100426
|
-
const { current, consumed, landmarkFlips, floor, cap } = args2;
|
|
100694
|
+
const { current, consumed, landmarkFlips, floor, cap: cap2 } = args2;
|
|
100427
100695
|
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(
|
|
100696
|
+
return Math.max(floor, Math.min(cap2, next));
|
|
100429
100697
|
}
|
|
100430
100698
|
var DEFAULT_CONSOLIDATION_POLICY = {
|
|
100431
100699
|
baseFloorMs: 6e4,
|
|
@@ -100462,9 +100730,9 @@ function consolidationGapMs(lastPassMs, policy) {
|
|
|
100462
100730
|
|
|
100463
100731
|
// src/codex-context-plugin.ts
|
|
100464
100732
|
import { createHash as createHash21 } from "node:crypto";
|
|
100465
|
-
import { cpSync as cpSync2, existsSync as existsSync39, mkdirSync as mkdirSync11, readFileSync as
|
|
100733
|
+
import { cpSync as cpSync2, existsSync as existsSync39, mkdirSync as mkdirSync11, readFileSync as readFileSync48, renameSync as renameSync10, writeFileSync as writeFileSync33 } from "node:fs";
|
|
100466
100734
|
import { homedir as homedir10 } from "node:os";
|
|
100467
|
-
import { join as
|
|
100735
|
+
import { join as join56 } from "node:path";
|
|
100468
100736
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
100469
100737
|
|
|
100470
100738
|
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
|
|
@@ -101162,23 +101430,23 @@ var NAME = "errata-context";
|
|
|
101162
101430
|
var PREFIX2 = `./.errata/plugins/${NAME}/`;
|
|
101163
101431
|
var object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
101164
101432
|
function readText(file2) {
|
|
101165
|
-
return existsSync39(file2) ?
|
|
101433
|
+
return existsSync39(file2) ? readFileSync48(file2, "utf8") : "";
|
|
101166
101434
|
}
|
|
101167
101435
|
function writeChanged(file2, content) {
|
|
101168
101436
|
if (readText(file2) === content) return;
|
|
101169
101437
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
101170
|
-
|
|
101171
|
-
|
|
101438
|
+
writeFileSync33(temp, content, "utf8");
|
|
101439
|
+
renameSync10(temp, file2);
|
|
101172
101440
|
}
|
|
101173
101441
|
function bundledContextPlugin() {
|
|
101174
101442
|
const packaged = fileURLToPath4(new URL("./resources/context-plugin/", import.meta.url));
|
|
101175
|
-
if (existsSync39(
|
|
101443
|
+
if (existsSync39(join56(packaged, ".codex-plugin/plugin.json"))) return packaged;
|
|
101176
101444
|
return fileURLToPath4(new URL("../dist/resources/context-plugin/", import.meta.url));
|
|
101177
101445
|
}
|
|
101178
101446
|
function refreshCodexContextPlugin(root) {
|
|
101179
|
-
const file2 =
|
|
101447
|
+
const file2 = join56(root, ".agents", "plugins", "marketplace.json");
|
|
101180
101448
|
if (!existsSync39(file2)) return false;
|
|
101181
|
-
const marketplace = JSON.parse(
|
|
101449
|
+
const marketplace = JSON.parse(readFileSync48(file2, "utf8"));
|
|
101182
101450
|
const entries = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
|
|
101183
101451
|
const entry = entries.map(object2).find((value) => value.name === NAME && String(object2(value.source).path).startsWith(PREFIX2));
|
|
101184
101452
|
if (!entry) return false;
|
|
@@ -101189,24 +101457,24 @@ function refreshCodexContextPlugin(root) {
|
|
|
101189
101457
|
function installCodexContextPlugin(root, options = {}) {
|
|
101190
101458
|
const bundle = options.bundle ?? bundledContextPlugin();
|
|
101191
101459
|
const manifest = JSON.parse(
|
|
101192
|
-
|
|
101460
|
+
readFileSync48(join56(bundle, ".codex-plugin/plugin.json"), "utf8")
|
|
101193
101461
|
);
|
|
101194
101462
|
if (manifest.name !== NAME || typeof manifest.version !== "string" || !/^[\w.-]+$/.test(manifest.version)) {
|
|
101195
101463
|
throw new Error("Invalid bundled Errata Context manifest.");
|
|
101196
101464
|
}
|
|
101197
|
-
const checksums =
|
|
101465
|
+
const checksums = readFileSync48(join56(bundle, "SHA256SUMS"), "utf8");
|
|
101198
101466
|
for (const line of checksums.trim().split("\n")) {
|
|
101199
101467
|
const match2 = /^([a-f0-9]{64}) ([\w./-]+)$/.exec(line);
|
|
101200
101468
|
if (!match2 || match2[2].startsWith("/") || match2[2].split("/").includes("..")) {
|
|
101201
101469
|
throw new Error("Invalid bundled Errata Context checksum manifest.");
|
|
101202
101470
|
}
|
|
101203
|
-
const actual = createHash21("sha256").update(
|
|
101471
|
+
const actual = createHash21("sha256").update(readFileSync48(join56(bundle, match2[2]))).digest("hex");
|
|
101204
101472
|
if (actual !== match2[1])
|
|
101205
101473
|
throw new Error(`Bundled Errata Context checksum mismatch: ${match2[2]}`);
|
|
101206
101474
|
}
|
|
101207
101475
|
const release = `${manifest.version}-${createHash21("sha256").update(checksums).digest("hex").slice(0, 12)}`;
|
|
101208
|
-
const plugin =
|
|
101209
|
-
const marketplaceFile =
|
|
101476
|
+
const plugin = join56(root, ".errata", "plugins", NAME, release);
|
|
101477
|
+
const marketplaceFile = join56(root, ".agents", "plugins", "marketplace.json");
|
|
101210
101478
|
const priorMarketplace = readText(marketplaceFile);
|
|
101211
101479
|
const marketplace = priorMarketplace ? JSON.parse(priorMarketplace) : {
|
|
101212
101480
|
name: "errata-local",
|
|
@@ -101227,12 +101495,12 @@ function installCodexContextPlugin(root, options = {}) {
|
|
|
101227
101495
|
);
|
|
101228
101496
|
}
|
|
101229
101497
|
const key = `${NAME}@${marketplace.name}`;
|
|
101230
|
-
const configFile =
|
|
101498
|
+
const configFile = join56(root, ".codex", "config.toml");
|
|
101231
101499
|
const config2 = readText(configFile);
|
|
101232
101500
|
const parsed = parse4(config2);
|
|
101233
101501
|
const plugins = object2(parsed.plugins);
|
|
101234
|
-
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ??
|
|
101235
|
-
const globalPlugins = object2(parse4(readText(
|
|
101502
|
+
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join56(homedir10(), ".codex");
|
|
101503
|
+
const globalPlugins = object2(parse4(readText(join56(codexHome, "config.toml"))).plugins);
|
|
101236
101504
|
const disabledGlobally = Object.entries(globalPlugins).some(
|
|
101237
101505
|
([name2, value]) => (name2 === NAME || name2.startsWith(`${NAME}@`)) && object2(value).enabled === false
|
|
101238
101506
|
);
|
|
@@ -101256,13 +101524,13 @@ enabled = ${enabled}
|
|
|
101256
101524
|
mkdirSync11(plugin, { recursive: true });
|
|
101257
101525
|
cpSync2(bundle, plugin, { recursive: true });
|
|
101258
101526
|
writeChanged(
|
|
101259
|
-
|
|
101527
|
+
join56(plugin, ".mcp.json"),
|
|
101260
101528
|
JSON.stringify(
|
|
101261
101529
|
{
|
|
101262
101530
|
mcpServers: {
|
|
101263
101531
|
errata_context: {
|
|
101264
101532
|
command: options.nodePath ?? process.execPath,
|
|
101265
|
-
args: [
|
|
101533
|
+
args: [join56(plugin, "dist", "mcp-server.mjs")],
|
|
101266
101534
|
env: { ERRATA_WORKSPACE: root, ERRATA_CONTEXT_VERSION: manifest.version }
|
|
101267
101535
|
}
|
|
101268
101536
|
}
|
|
@@ -101271,8 +101539,8 @@ enabled = ${enabled}
|
|
|
101271
101539
|
2
|
|
101272
101540
|
) + "\n"
|
|
101273
101541
|
);
|
|
101274
|
-
mkdirSync11(
|
|
101275
|
-
mkdirSync11(
|
|
101542
|
+
mkdirSync11(join56(root, ".agents", "plugins"), { recursive: true });
|
|
101543
|
+
mkdirSync11(join56(root, ".codex"), { recursive: true });
|
|
101276
101544
|
writeChanged(marketplaceFile, JSON.stringify(marketplace, null, 2) + "\n");
|
|
101277
101545
|
writeChanged(configFile, nextConfig);
|
|
101278
101546
|
return { plugin, enabled, marketplace: marketplaceFile };
|
|
@@ -101280,15 +101548,15 @@ enabled = ${enabled}
|
|
|
101280
101548
|
|
|
101281
101549
|
// src/codex-hook-refresh.ts
|
|
101282
101550
|
init_checkout_root();
|
|
101283
|
-
import { existsSync as existsSync40, readdirSync as readdirSync14, readFileSync as
|
|
101284
|
-
import { dirname as
|
|
101551
|
+
import { existsSync as existsSync40, readdirSync as readdirSync14, readFileSync as readFileSync49 } from "node:fs";
|
|
101552
|
+
import { dirname as dirname22, join as join57, resolve as resolve9 } from "node:path";
|
|
101285
101553
|
init_registry();
|
|
101286
101554
|
function codexHookRoots(roots) {
|
|
101287
101555
|
const found = new Set(roots.map((root) => resolve9(root)));
|
|
101288
101556
|
for (const root of [...found]) {
|
|
101289
101557
|
const main2 = mainCheckoutOfWorktree(root) ?? root;
|
|
101290
101558
|
found.add(main2);
|
|
101291
|
-
const dir =
|
|
101559
|
+
const dir = join57(main2, ".git", "worktrees");
|
|
101292
101560
|
if (!existsSync40(dir)) continue;
|
|
101293
101561
|
let names;
|
|
101294
101562
|
try {
|
|
@@ -101298,7 +101566,7 @@ function codexHookRoots(roots) {
|
|
|
101298
101566
|
}
|
|
101299
101567
|
for (const name2 of names) {
|
|
101300
101568
|
try {
|
|
101301
|
-
const checkout =
|
|
101569
|
+
const checkout = dirname22(readFileSync49(join57(dir, name2, "gitdir"), "utf8").trim());
|
|
101302
101570
|
if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
|
|
101303
101571
|
} catch {
|
|
101304
101572
|
}
|
|
@@ -101321,8 +101589,8 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
|
|
|
101321
101589
|
|
|
101322
101590
|
// src/claude-mods.ts
|
|
101323
101591
|
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
|
|
101592
|
+
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";
|
|
101593
|
+
import { delimiter as delimiter2, dirname as dirname23, join as join58, relative as relative7, resolve as resolve10, sep as sep6 } from "node:path";
|
|
101326
101594
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
101327
101595
|
var CLAUDE_PLUGIN_DIRS_ENV = "CLAUDE_CODE_PLUGIN_DIRS";
|
|
101328
101596
|
var HASH_FILE = ".errata-mod-hash";
|
|
@@ -101337,7 +101605,7 @@ function isEngineOwned(relPath) {
|
|
|
101337
101605
|
function listFiles(root, dir = root) {
|
|
101338
101606
|
const out2 = [];
|
|
101339
101607
|
for (const name2 of readdirSync15(dir)) {
|
|
101340
|
-
const abs =
|
|
101608
|
+
const abs = join58(dir, name2);
|
|
101341
101609
|
if (isEngineOwned(relative7(root, abs))) continue;
|
|
101342
101610
|
if (statSync16(abs).isDirectory()) out2.push(...listFiles(root, abs));
|
|
101343
101611
|
else out2.push(abs);
|
|
@@ -101349,14 +101617,14 @@ function modHash(dir) {
|
|
|
101349
101617
|
for (const abs of listFiles(dir).sort()) {
|
|
101350
101618
|
h.update(relative7(dir, abs).split(sep6).join("/"));
|
|
101351
101619
|
h.update("\0");
|
|
101352
|
-
h.update(
|
|
101620
|
+
h.update(readFileSync50(abs));
|
|
101353
101621
|
h.update("\0");
|
|
101354
101622
|
}
|
|
101355
101623
|
return h.digest("hex");
|
|
101356
101624
|
}
|
|
101357
101625
|
function bundledMods(bundleDir) {
|
|
101358
101626
|
if (!existsSync41(bundleDir)) return [];
|
|
101359
|
-
return readdirSync15(bundleDir).filter((name2) => existsSync41(
|
|
101627
|
+
return readdirSync15(bundleDir).filter((name2) => existsSync41(join58(bundleDir, name2, ".claude-plugin", "plugin.json")));
|
|
101360
101628
|
}
|
|
101361
101629
|
function sameDir(a, b) {
|
|
101362
101630
|
const norm = (p) => resolve10(p).replace(/[\\/]+$/, "").toLowerCase();
|
|
@@ -101373,7 +101641,7 @@ function off(env2) {
|
|
|
101373
101641
|
function readSettings(path3) {
|
|
101374
101642
|
if (!existsSync41(path3)) return {};
|
|
101375
101643
|
try {
|
|
101376
|
-
const parsed = JSON.parse(
|
|
101644
|
+
const parsed = JSON.parse(readFileSync50(path3, "utf8"));
|
|
101377
101645
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
101378
101646
|
return parsed;
|
|
101379
101647
|
} catch {
|
|
@@ -101397,13 +101665,13 @@ function currentDirs(settings) {
|
|
|
101397
101665
|
return raw2.split(delimiter2).map((s) => s.trim()).filter(Boolean);
|
|
101398
101666
|
}
|
|
101399
101667
|
function writeSettings(path3, settings) {
|
|
101400
|
-
mkdirSync12(
|
|
101401
|
-
|
|
101668
|
+
mkdirSync12(dirname23(path3), { recursive: true });
|
|
101669
|
+
writeFileSync34(path3, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
101402
101670
|
}
|
|
101403
101671
|
function ensureClaudeMods(opts) {
|
|
101404
101672
|
const env2 = opts.env ?? process.env;
|
|
101405
101673
|
const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
|
|
101406
|
-
const modsRoot =
|
|
101674
|
+
const modsRoot = join58(opts.installRoot, "claude-mods");
|
|
101407
101675
|
if (off(env2)) {
|
|
101408
101676
|
const settings2 = readSettings(settingsPath);
|
|
101409
101677
|
if (!settings2) return { kind: "unreadable" };
|
|
@@ -101420,14 +101688,14 @@ function ensureClaudeMods(opts) {
|
|
|
101420
101688
|
let changed = false;
|
|
101421
101689
|
const installed = [];
|
|
101422
101690
|
for (const name2 of names) {
|
|
101423
|
-
const src =
|
|
101424
|
-
const dest =
|
|
101691
|
+
const src = join58(bundleDir, name2);
|
|
101692
|
+
const dest = join58(modsRoot, name2);
|
|
101425
101693
|
const hash2 = modHash(src);
|
|
101426
|
-
const hashFile =
|
|
101427
|
-
if (!existsSync41(hashFile) ||
|
|
101694
|
+
const hashFile = join58(dest, HASH_FILE);
|
|
101695
|
+
if (!existsSync41(hashFile) || readFileSync50(hashFile, "utf8") !== hash2) {
|
|
101428
101696
|
rmSync4(dest, { recursive: true, force: true });
|
|
101429
101697
|
cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative7(src, p)) });
|
|
101430
|
-
|
|
101698
|
+
writeFileSync34(hashFile, hash2, "utf8");
|
|
101431
101699
|
changed = true;
|
|
101432
101700
|
}
|
|
101433
101701
|
installed.push(dest);
|
|
@@ -101858,9 +102126,9 @@ function resolveHookPort(explicit) {
|
|
|
101858
102126
|
}
|
|
101859
102127
|
}
|
|
101860
102128
|
}
|
|
101861
|
-
const settingsPath =
|
|
102129
|
+
const settingsPath = join59(ROOT, ".claude", "settings.json");
|
|
101862
102130
|
try {
|
|
101863
|
-
if (existsSync42(settingsPath)) return installedHookPort(
|
|
102131
|
+
if (existsSync42(settingsPath)) return installedHookPort(readFileSync51(settingsPath, "utf8")) ?? 7891;
|
|
101864
102132
|
} catch {
|
|
101865
102133
|
}
|
|
101866
102134
|
return 7891;
|
|
@@ -101886,13 +102154,13 @@ async function cmdInit() {
|
|
|
101886
102154
|
console.log("");
|
|
101887
102155
|
console.log("installing harness hooks...");
|
|
101888
102156
|
const { existsSync: existsSync43 } = await import("node:fs");
|
|
101889
|
-
const { join:
|
|
102157
|
+
const { join: join60 } = await import("node:path");
|
|
101890
102158
|
try {
|
|
101891
102159
|
await installClaudeHooks(port);
|
|
101892
102160
|
} catch (err2) {
|
|
101893
102161
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
101894
102162
|
}
|
|
101895
|
-
if (existsSync43(
|
|
102163
|
+
if (existsSync43(join60(ROOT, ".cursor"))) {
|
|
101896
102164
|
try {
|
|
101897
102165
|
await installCursorMcpConfig();
|
|
101898
102166
|
} catch (err2) {
|
|
@@ -103118,7 +103386,7 @@ async function cmdReview() {
|
|
|
103118
103386
|
console.log("(review queue empty)");
|
|
103119
103387
|
return;
|
|
103120
103388
|
}
|
|
103121
|
-
const queue = JSON.parse(
|
|
103389
|
+
const queue = JSON.parse(readFileSync51(paths.reviewQueue, "utf8"));
|
|
103122
103390
|
if (queue.length === 0) {
|
|
103123
103391
|
console.log("(review queue empty)");
|
|
103124
103392
|
return;
|
|
@@ -103857,7 +104125,7 @@ async function gatherReportData(generatedAt) {
|
|
|
103857
104125
|
};
|
|
103858
104126
|
}
|
|
103859
104127
|
async function cmdReport(args2) {
|
|
103860
|
-
const { mkdirSync: mkdirSync13, writeFileSync:
|
|
104128
|
+
const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
103861
104129
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
103862
104130
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
103863
104131
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -103870,8 +104138,8 @@ async function cmdReport(args2) {
|
|
|
103870
104138
|
const outDir = workspacePaths(ROOT).configDir;
|
|
103871
104139
|
mkdirSync13(outDir, { recursive: true });
|
|
103872
104140
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
103873
|
-
for (const f of files)
|
|
103874
|
-
const indexPath =
|
|
104141
|
+
for (const f of files) writeFileSync36(join59(outDir, f.name), f.html, "utf8");
|
|
104142
|
+
const indexPath = join59(outDir, "report.html");
|
|
103875
104143
|
console.log(`report \u2192 ${indexPath}`);
|
|
103876
104144
|
console.log(
|
|
103877
104145
|
` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
|
|
@@ -103927,7 +104195,7 @@ function spawnDaemonDetached(options = {}) {
|
|
|
103927
104195
|
try {
|
|
103928
104196
|
const logPath = daemonLogPath();
|
|
103929
104197
|
try {
|
|
103930
|
-
if (statSync17(logPath).size > 5 * 1024 * 1024)
|
|
104198
|
+
if (statSync17(logPath).size > 5 * 1024 * 1024) renameSync11(logPath, `${logPath}.1`);
|
|
103931
104199
|
} catch {
|
|
103932
104200
|
}
|
|
103933
104201
|
out2 = openSync3(logPath, "a");
|
|
@@ -104000,24 +104268,24 @@ async function cmdInstallHooks(args2) {
|
|
|
104000
104268
|
}
|
|
104001
104269
|
}
|
|
104002
104270
|
async function installOpencodePlugin(port) {
|
|
104003
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync:
|
|
104004
|
-
const { join:
|
|
104005
|
-
const dir =
|
|
104271
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync: readFileSync52, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
104272
|
+
const { join: join60 } = await import("node:path");
|
|
104273
|
+
const dir = join60(ROOT, ".opencode", "plugin");
|
|
104006
104274
|
if (!existsSync43(dir)) mkdirSync13(dir, { recursive: true });
|
|
104007
|
-
const file2 =
|
|
104275
|
+
const file2 = join60(dir, "inerrata.js");
|
|
104008
104276
|
if (existsSync43(file2)) {
|
|
104009
|
-
const head2 =
|
|
104277
|
+
const head2 = readFileSync52(file2, "utf8").split("\n")[0] ?? "";
|
|
104010
104278
|
if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
|
|
104011
104279
|
console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
|
|
104012
104280
|
process.exit(2);
|
|
104013
104281
|
}
|
|
104014
104282
|
}
|
|
104015
|
-
|
|
104016
|
-
const cfgFile =
|
|
104283
|
+
writeFileSync36(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
|
|
104284
|
+
const cfgFile = join60(ROOT, "opencode.json");
|
|
104017
104285
|
let cfg = { $schema: "https://opencode.ai/config.json" };
|
|
104018
104286
|
if (existsSync43(cfgFile)) {
|
|
104019
104287
|
try {
|
|
104020
|
-
cfg = JSON.parse(
|
|
104288
|
+
cfg = JSON.parse(readFileSync52(cfgFile, "utf8"));
|
|
104021
104289
|
} catch {
|
|
104022
104290
|
console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
|
|
104023
104291
|
process.exit(2);
|
|
@@ -104028,7 +104296,7 @@ async function installOpencodePlugin(port) {
|
|
|
104028
104296
|
if (!hadErrata) {
|
|
104029
104297
|
const inv = errataMcpInvocation();
|
|
104030
104298
|
cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
|
|
104031
|
-
|
|
104299
|
+
writeFileSync36(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
104032
104300
|
}
|
|
104033
104301
|
console.log(`installed OpenCode plugin \u2192 ${file2}`);
|
|
104034
104302
|
if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
|
|
@@ -104062,15 +104330,15 @@ function installClaudeMods() {
|
|
|
104062
104330
|
}
|
|
104063
104331
|
}
|
|
104064
104332
|
async function installClaudeHooks(port) {
|
|
104065
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync:
|
|
104066
|
-
const { join:
|
|
104067
|
-
const dir =
|
|
104333
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync: readFileSync52, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
104334
|
+
const { join: join60 } = await import("node:path");
|
|
104335
|
+
const dir = join60(ROOT, ".claude");
|
|
104068
104336
|
if (!existsSync43(dir)) mkdirSync13(dir, { recursive: true });
|
|
104069
|
-
const file2 =
|
|
104337
|
+
const file2 = join60(dir, "settings.json");
|
|
104070
104338
|
let settings = {};
|
|
104071
104339
|
if (existsSync43(file2)) {
|
|
104072
104340
|
try {
|
|
104073
|
-
settings = JSON.parse(
|
|
104341
|
+
settings = JSON.parse(readFileSync52(file2, "utf8"));
|
|
104074
104342
|
} catch {
|
|
104075
104343
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
104076
104344
|
process.exit(2);
|
|
@@ -104078,12 +104346,12 @@ async function installClaudeHooks(port) {
|
|
|
104078
104346
|
}
|
|
104079
104347
|
applyClaudeErrataHooks(settings, port);
|
|
104080
104348
|
removeProjectStatusLine(settings);
|
|
104081
|
-
|
|
104349
|
+
writeFileSync36(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
104082
104350
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
104083
104351
|
console.log(` ${ensureStatusLine(port)}`);
|
|
104084
104352
|
console.log(` ${installClaudeMods().line}`);
|
|
104085
104353
|
await installClaudeMcpConfig();
|
|
104086
|
-
const claudeMd =
|
|
104354
|
+
const claudeMd = join60(ROOT, "CLAUDE.md");
|
|
104087
104355
|
const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
|
|
104088
104356
|
if (recall.kind === "collision") {
|
|
104089
104357
|
console.warn(
|
|
@@ -104095,15 +104363,15 @@ async function installClaudeHooks(port) {
|
|
|
104095
104363
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
104096
104364
|
}
|
|
104097
104365
|
async function installClaudeMcpConfig() {
|
|
104098
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync:
|
|
104099
|
-
const { join:
|
|
104100
|
-
const file2 =
|
|
104101
|
-
const dir =
|
|
104366
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync: readFileSync52, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
104367
|
+
const { join: join60, dirname: dirname24 } = await import("node:path");
|
|
104368
|
+
const file2 = join60(ROOT, ".mcp.json");
|
|
104369
|
+
const dir = dirname24(file2);
|
|
104102
104370
|
if (!existsSync43(dir)) mkdirSync13(dir, { recursive: true });
|
|
104103
104371
|
let cfg = {};
|
|
104104
104372
|
if (existsSync43(file2)) {
|
|
104105
104373
|
try {
|
|
104106
|
-
cfg = JSON.parse(
|
|
104374
|
+
cfg = JSON.parse(readFileSync52(file2, "utf8"));
|
|
104107
104375
|
} catch {
|
|
104108
104376
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
104109
104377
|
process.exit(2);
|
|
@@ -104111,21 +104379,21 @@ async function installClaudeMcpConfig() {
|
|
|
104111
104379
|
}
|
|
104112
104380
|
cfg.mcpServers ??= {};
|
|
104113
104381
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
104114
|
-
|
|
104382
|
+
writeFileSync36(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
104115
104383
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
104116
104384
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
104117
104385
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
104118
104386
|
}
|
|
104119
104387
|
async function installCursorMcpConfig() {
|
|
104120
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync:
|
|
104121
|
-
const { join:
|
|
104122
|
-
const dir =
|
|
104388
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync: readFileSync52, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
104389
|
+
const { join: join60 } = await import("node:path");
|
|
104390
|
+
const dir = join60(ROOT, ".cursor");
|
|
104123
104391
|
if (!existsSync43(dir)) mkdirSync13(dir, { recursive: true });
|
|
104124
|
-
const file2 =
|
|
104392
|
+
const file2 = join60(dir, "mcp.json");
|
|
104125
104393
|
let cfg = {};
|
|
104126
104394
|
if (existsSync43(file2)) {
|
|
104127
104395
|
try {
|
|
104128
|
-
cfg = JSON.parse(
|
|
104396
|
+
cfg = JSON.parse(readFileSync52(file2, "utf8"));
|
|
104129
104397
|
} catch {
|
|
104130
104398
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
104131
104399
|
process.exit(2);
|
|
@@ -104133,7 +104401,7 @@ async function installCursorMcpConfig() {
|
|
|
104133
104401
|
}
|
|
104134
104402
|
cfg.mcpServers ??= {};
|
|
104135
104403
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
104136
|
-
|
|
104404
|
+
writeFileSync36(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
104137
104405
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
104138
104406
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
104139
104407
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -104144,7 +104412,7 @@ async function installCodexHooks(port) {
|
|
|
104144
104412
|
const gitRoot = nearestGitRoot(process.cwd());
|
|
104145
104413
|
const hookRoot = gitRoot && mainCheckoutOfWorktree(gitRoot) ? gitRoot : ROOT;
|
|
104146
104414
|
const file2 = writeCodexHooks(hookRoot, port);
|
|
104147
|
-
const instructions = writeManagedBlock(
|
|
104415
|
+
const instructions = writeManagedBlock(join59(hookRoot, "AGENTS.md"), {
|
|
104148
104416
|
body: AGENTS_POINTER_BODY,
|
|
104149
104417
|
stable: true
|
|
104150
104418
|
});
|
|
@@ -104192,12 +104460,12 @@ function refreshExistingClaudeHooks() {
|
|
|
104192
104460
|
let ok = true;
|
|
104193
104461
|
const roots = [...listWorkspaceEntries().map((entry) => entry.path), process.cwd()];
|
|
104194
104462
|
for (const root of codexHookRoots(roots)) {
|
|
104195
|
-
const file2 =
|
|
104463
|
+
const file2 = join59(root, ".claude", "settings.json");
|
|
104196
104464
|
try {
|
|
104197
104465
|
if (!existsSync42(file2) || isReplayCheckout(root)) continue;
|
|
104198
|
-
const next = refreshClaudeHookSettings(
|
|
104466
|
+
const next = refreshClaudeHookSettings(readFileSync51(file2, "utf8"));
|
|
104199
104467
|
if (next === null) continue;
|
|
104200
|
-
|
|
104468
|
+
writeFileSync35(file2, next, "utf8");
|
|
104201
104469
|
console.log(`updated existing Claude Code hooks \u2192 ${file2}`);
|
|
104202
104470
|
} catch (error48) {
|
|
104203
104471
|
ok = false;
|
|
@@ -104609,9 +104877,9 @@ async function cmdDash(args2) {
|
|
|
104609
104877
|
await yieldToLoop2();
|
|
104610
104878
|
try {
|
|
104611
104879
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
|
|
104612
|
-
atCommit: readGitRefState(
|
|
104880
|
+
atCommit: readGitRefState(join59(r.root, ".git")).sha ?? void 0
|
|
104613
104881
|
});
|
|
104614
|
-
const res = bleedRules(
|
|
104882
|
+
const res = bleedRules(join59(r.root, ".claude", "rules"), items);
|
|
104615
104883
|
if (res.written || res.pruned) {
|
|
104616
104884
|
console.log(
|
|
104617
104885
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|