@inerrata-corporation/errata 2.0.22-dev.4411 → 2.0.22-dev.4530
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/consolidate-worker.mjs +155 -4
- package/errata.mjs +1246 -574
- package/generalize-worker.mjs +149 -2
- package/package.json +1 -1
- package/pass-worker.mjs +176 -9
- package/resources/context-plugin/.codex-plugin/plugin.json +1 -1
- package/resources/context-plugin/SHA256SUMS +1 -1
package/errata.mjs
CHANGED
|
@@ -17425,6 +17425,12 @@ var init_history_temporal = __esm({
|
|
|
17425
17425
|
});
|
|
17426
17426
|
|
|
17427
17427
|
// ../../packages/shared/src/history-revision.ts
|
|
17428
|
+
function settledHistoryReceipt(evidence) {
|
|
17429
|
+
if (!evidence || typeof evidence !== "object") return false;
|
|
17430
|
+
const e = evidence;
|
|
17431
|
+
const review = e["review"];
|
|
17432
|
+
return e["build"] === HISTORY_RECONCILE_BUILD && e["reviewStatus"] !== "failed-provider" && review?.["status"] !== "failed-schema" && (e["reviewStatus"] !== "deferred-budget" || e["reviewPolicy"] === HISTORY_REVIEW_POLICY);
|
|
17433
|
+
}
|
|
17428
17434
|
function historyDag(records) {
|
|
17429
17435
|
const graph = new Map(records.map((r) => [r.commit, r.parents]));
|
|
17430
17436
|
if (graph.size !== records.length) throw new Error("duplicate Git commit in history proof");
|
|
@@ -17481,7 +17487,7 @@ function preservedHistoryOccurrence(o, observed, atCommit, ancestor) {
|
|
|
17481
17487
|
if (!anchors?.length || anchors.some((a) => a.side !== "after" || !a.bodyHash || !observed.symbols.some((s) => s.symbolId === a.symbolId && s.bodyHash === a.bodyHash))) return false;
|
|
17482
17488
|
return parsed.data.every((e) => anchors.some((a) => a.blockDigest === e.blockDigest && a.startByte <= e.startByte && a.endByte >= e.endByte));
|
|
17483
17489
|
}
|
|
17484
|
-
var Sha, HistoryRevisionRequestSchema;
|
|
17490
|
+
var Sha, HistoryRevisionRequestSchema, HistoryCarryRequestSchema, HISTORY_REVIEW_BUDGET, HISTORY_REVIEW_POLICY;
|
|
17485
17491
|
var init_history_revision = __esm({
|
|
17486
17492
|
"../../packages/shared/src/history-revision.ts"() {
|
|
17487
17493
|
"use strict";
|
|
@@ -17501,6 +17507,17 @@ var init_history_revision = __esm({
|
|
|
17501
17507
|
dependencyContext: HistoryDependencyContextSchema.optional()
|
|
17502
17508
|
})).max(50)
|
|
17503
17509
|
});
|
|
17510
|
+
HistoryCarryRequestSchema = external_exports.strictObject({
|
|
17511
|
+
fromCommit: Sha,
|
|
17512
|
+
atCommit: Sha,
|
|
17513
|
+
parents: external_exports.array(external_exports.strictObject({ commit: Sha, parents: external_exports.array(Sha).max(32) })).max(8192),
|
|
17514
|
+
/** Every symbol in a file the range changed, both sides; `null` = too many to name, treat all as changed. */
|
|
17515
|
+
changedSymbols: external_exports.array(external_exports.string().regex(/^sym_[a-f0-9]{8,64}$/)).max(5e3).nullable(),
|
|
17516
|
+
/** Manifests the range changed; `null` = a lockfile (or too many manifests) changed, treat all as changed. */
|
|
17517
|
+
changedManifests: external_exports.array(external_exports.string().regex(/^hmanifest_[a-f0-9]{32}$/)).max(512).nullable()
|
|
17518
|
+
});
|
|
17519
|
+
HISTORY_REVIEW_BUDGET = 48e3;
|
|
17520
|
+
HISTORY_REVIEW_POLICY = `reviewer-view-${HISTORY_REVIEW_BUDGET}`;
|
|
17504
17521
|
}
|
|
17505
17522
|
});
|
|
17506
17523
|
|
|
@@ -17608,10 +17625,13 @@ __export(src_exports, {
|
|
|
17608
17625
|
HISTORY_MAX_SPINE_DEPS: () => HISTORY_MAX_SPINE_DEPS,
|
|
17609
17626
|
HISTORY_MAX_TEXT_CHARS: () => HISTORY_MAX_TEXT_CHARS,
|
|
17610
17627
|
HISTORY_RECONCILE_BUILD: () => HISTORY_RECONCILE_BUILD,
|
|
17628
|
+
HISTORY_REVIEW_BUDGET: () => HISTORY_REVIEW_BUDGET,
|
|
17629
|
+
HISTORY_REVIEW_POLICY: () => HISTORY_REVIEW_POLICY,
|
|
17611
17630
|
HISTORY_SCRUBBER_VERSION: () => HISTORY_SCRUBBER_VERSION,
|
|
17612
17631
|
HistoryAnchorSourceSchema: () => HistoryAnchorSourceSchema,
|
|
17613
17632
|
HistoryCandidateBatchSchema: () => HistoryCandidateBatchSchema,
|
|
17614
17633
|
HistoryCandidateSchema: () => HistoryCandidateSchema,
|
|
17634
|
+
HistoryCarryRequestSchema: () => HistoryCarryRequestSchema,
|
|
17615
17635
|
HistoryDependencyContextSchema: () => HistoryDependencyContextSchema,
|
|
17616
17636
|
HistoryDependencySchema: () => HistoryDependencySchema,
|
|
17617
17637
|
HistoryEvidenceRefSchema: () => HistoryEvidenceRefSchema,
|
|
@@ -17750,6 +17770,7 @@ __export(src_exports, {
|
|
|
17750
17770
|
scrubHistoryText: () => scrubHistoryText,
|
|
17751
17771
|
scrubHistoryValue: () => scrubHistoryValue,
|
|
17752
17772
|
selectHistoryDependencies: () => selectHistoryDependencies,
|
|
17773
|
+
settledHistoryReceipt: () => settledHistoryReceipt,
|
|
17753
17774
|
sha256: () => sha256,
|
|
17754
17775
|
sha256Short: () => sha256Short,
|
|
17755
17776
|
sidecarDropBucket: () => sidecarDropBucket,
|
|
@@ -17826,8 +17847,8 @@ ${endMarker}
|
|
|
17826
17847
|
const startM = current.match(START_RE);
|
|
17827
17848
|
const endM = current.match(END_RE);
|
|
17828
17849
|
if (!startM || !endM || startM.index === void 0 || endM.index === void 0) {
|
|
17829
|
-
const
|
|
17830
|
-
writeFileSync(filePath, `${current}${
|
|
17850
|
+
const sep7 = current.endsWith("\n") ? "" : "\n";
|
|
17851
|
+
writeFileSync(filePath, `${current}${sep7}
|
|
17831
17852
|
${blockText}`, "utf8");
|
|
17832
17853
|
return { kind: "created", newHash };
|
|
17833
17854
|
}
|
|
@@ -19145,6 +19166,129 @@ var init_text_index = __esm({
|
|
|
19145
19166
|
}
|
|
19146
19167
|
});
|
|
19147
19168
|
|
|
19169
|
+
// ../../packages/local-graph/src/exposure-attrs.ts
|
|
19170
|
+
var EXPOSURE_ATTRS, EXPOSURE_SCOPE;
|
|
19171
|
+
var init_exposure_attrs = __esm({
|
|
19172
|
+
"../../packages/local-graph/src/exposure-attrs.ts"() {
|
|
19173
|
+
"use strict";
|
|
19174
|
+
EXPOSURE_ATTRS = [
|
|
19175
|
+
"shownCount",
|
|
19176
|
+
"evictedCount",
|
|
19177
|
+
"firstShownAt",
|
|
19178
|
+
"firstEvictedAt",
|
|
19179
|
+
"firstShownAtSeq",
|
|
19180
|
+
"lastShownAtSeq",
|
|
19181
|
+
"lastEvictedAtSeq",
|
|
19182
|
+
"shownSinceTouch",
|
|
19183
|
+
"shownSinceTouchAt",
|
|
19184
|
+
"exposureLog",
|
|
19185
|
+
"exposureLogStart",
|
|
19186
|
+
"exposureLogSince",
|
|
19187
|
+
"exposureFirst",
|
|
19188
|
+
"exposureTrimmed"
|
|
19189
|
+
];
|
|
19190
|
+
EXPOSURE_SCOPE = "exposure";
|
|
19191
|
+
}
|
|
19192
|
+
});
|
|
19193
|
+
|
|
19194
|
+
// ../../packages/local-graph/src/change-feed.ts
|
|
19195
|
+
function installChangeFeed(db) {
|
|
19196
|
+
if (changeFeedInstalled(db)) return;
|
|
19197
|
+
db.transaction(() => {
|
|
19198
|
+
db.exec("CREATE TABLE IF NOT EXISTS change_seq (scope TEXT PRIMARY KEY, seq INTEGER NOT NULL) WITHOUT ROWID");
|
|
19199
|
+
db.exec(`CREATE TABLE IF NOT EXISTS change_log (change_seq INTEGER PRIMARY KEY, kind TEXT NOT NULL, id TEXT NOT NULL,
|
|
19200
|
+
label TEXT, from_id TEXT, to_id TEXT)`);
|
|
19201
|
+
for (const name2 of ["nodes", "edges"].flatMap((t) => ["insert", "update", "delete"].map((op) => `change_feed_${t}_${op}`))) {
|
|
19202
|
+
db.exec(`DROP TRIGGER IF EXISTS ${name2}`);
|
|
19203
|
+
}
|
|
19204
|
+
const changed = (table) => columns(db, table).map((c) => `OLD."${c}" IS NOT NEW."${c}"`).join(" OR ");
|
|
19205
|
+
const strip3 = (row) => `json_remove(${row}.attrs_json, ${EXPOSURE_ATTRS.map((a) => `'$.${a}'`).join(", ")})`;
|
|
19206
|
+
const exposureOnly = `(${columns(db, "nodes").filter((c) => c !== "attrs_json").map((c) => `OLD."${c}" IS NEW."${c}"`).join(" AND ")}
|
|
19207
|
+
AND CASE WHEN json_valid(OLD.attrs_json) AND json_valid(NEW.attrs_json) THEN ${strip3("OLD")} IS ${strip3("NEW")} ELSE 0 END)`;
|
|
19208
|
+
const bump = (...scopes) => `INSERT INTO change_seq(scope, seq) VALUES ${scopes.map((s) => `(${s}, 1)`).join(", ")}
|
|
19209
|
+
ON CONFLICT(scope) DO UPDATE SET seq = seq + 1;`;
|
|
19210
|
+
const seq = `(SELECT seq FROM change_seq WHERE scope = '*')`;
|
|
19211
|
+
const logNode = (row) => `INSERT INTO change_log(change_seq, kind, id, label) VALUES (${seq}, 'node', ${row}.id, ${row}.label);`;
|
|
19212
|
+
const logEdge = (row) => `INSERT INTO change_log(change_seq, kind, id, label, from_id, to_id) VALUES (${seq}, 'edge', ${row}.id, ${row}.type, ${row}.from_id, ${row}.to_id);`;
|
|
19213
|
+
const node2 = (row) => `'node:' || ${row}.label`;
|
|
19214
|
+
const edge2 = (row) => `'edge:' || ${row}.type`;
|
|
19215
|
+
db.exec(`CREATE TRIGGER change_feed_nodes_insert AFTER INSERT ON nodes BEGIN ${bump(`'*'`, node2("NEW"))} ${logNode("NEW")} END;`);
|
|
19216
|
+
db.exec(`CREATE TRIGGER change_feed_nodes_update AFTER UPDATE ON nodes WHEN ${changed("nodes")} BEGIN
|
|
19217
|
+
${bump(`'*'`)}
|
|
19218
|
+
INSERT INTO change_seq(scope, seq) SELECT CASE WHEN ${exposureOnly} THEN '${EXPOSURE_SCOPE}' ELSE ${node2("NEW")} END, 1 WHERE 1
|
|
19219
|
+
ON CONFLICT(scope) DO UPDATE SET seq = seq + 1;
|
|
19220
|
+
INSERT INTO change_seq(scope, seq) SELECT ${node2("OLD")}, 1 WHERE OLD.label IS NOT NEW.label
|
|
19221
|
+
ON CONFLICT(scope) DO UPDATE SET seq = seq + 1;
|
|
19222
|
+
${logNode("NEW")}
|
|
19223
|
+
END;`);
|
|
19224
|
+
db.exec(`CREATE TRIGGER change_feed_nodes_delete AFTER DELETE ON nodes BEGIN ${bump(`'*'`, node2("OLD"))} ${logNode("OLD")} END;`);
|
|
19225
|
+
db.exec(`CREATE TRIGGER change_feed_edges_insert AFTER INSERT ON edges BEGIN ${bump(`'*'`, edge2("NEW"))} ${logEdge("NEW")} END;`);
|
|
19226
|
+
db.exec(`CREATE TRIGGER change_feed_edges_update AFTER UPDATE ON edges WHEN ${changed("edges")} BEGIN
|
|
19227
|
+
${bump(`'*'`, edge2("NEW"))}
|
|
19228
|
+
INSERT INTO change_seq(scope, seq) SELECT ${edge2("OLD")}, 1 WHERE OLD.type IS NOT NEW.type
|
|
19229
|
+
ON CONFLICT(scope) DO UPDATE SET seq = seq + 1;
|
|
19230
|
+
${logEdge("NEW")}
|
|
19231
|
+
END;`);
|
|
19232
|
+
db.exec(`CREATE TRIGGER change_feed_edges_delete AFTER DELETE ON edges BEGIN ${bump(`'*'`, edge2("OLD"))} ${logEdge("OLD")} END;`);
|
|
19233
|
+
db.prepare("INSERT OR REPLACE INTO store_meta(key, value) VALUES (?, ?)").run(PRUNED_TO_KEY, String(readChangeSeq(db)));
|
|
19234
|
+
db.prepare("INSERT OR REPLACE INTO store_meta(key, value) VALUES (?, ?)").run(CHANGE_FEED_KEY, columnSignature(db));
|
|
19235
|
+
});
|
|
19236
|
+
}
|
|
19237
|
+
function readChangeSeq(db, scopes = [ANY_CHANGE]) {
|
|
19238
|
+
if (!scopes.length) return 0;
|
|
19239
|
+
const row = db.prepare(`SELECT coalesce(sum(seq), 0) AS n FROM change_seq WHERE scope IN (${scopes.map(() => "?").join(",")})`).get(...scopes);
|
|
19240
|
+
return Number(row?.n ?? 0);
|
|
19241
|
+
}
|
|
19242
|
+
function changeLogCovers(db, sinceSeq) {
|
|
19243
|
+
const prunedTo = Number(db.prepare("SELECT value FROM store_meta WHERE key = ?").get(PRUNED_TO_KEY)?.["value"] ?? NaN);
|
|
19244
|
+
return Number.isFinite(prunedTo) && sinceSeq >= prunedTo;
|
|
19245
|
+
}
|
|
19246
|
+
function readLineageChangedFiles(db, sinceSeq) {
|
|
19247
|
+
if (!changeLogCovers(db, sinceSeq)) return null;
|
|
19248
|
+
const rows = db.prepare(LINEAGE_CHANGED_FILES_SQL).all({ s: sinceSeq });
|
|
19249
|
+
return rows.map((r) => r.id);
|
|
19250
|
+
}
|
|
19251
|
+
function pruneChangeLog(db) {
|
|
19252
|
+
const max = Number(db.prepare("SELECT coalesce(max(change_seq), 0) AS n FROM change_log").get()?.["n"] ?? 0);
|
|
19253
|
+
const cut = max - CHANGE_LOG_KEEP;
|
|
19254
|
+
if (cut <= 0) return 0;
|
|
19255
|
+
let removed = 0;
|
|
19256
|
+
db.transaction(() => {
|
|
19257
|
+
removed = Number(db.prepare("DELETE FROM change_log WHERE change_seq <= ?").run(cut).changes);
|
|
19258
|
+
const prev = Number(db.prepare("SELECT value FROM store_meta WHERE key = ?").get(PRUNED_TO_KEY)?.["value"] ?? 0);
|
|
19259
|
+
db.prepare("INSERT OR REPLACE INTO store_meta(key, value) VALUES (?, ?)").run(PRUNED_TO_KEY, String(Math.max(prev, cut)));
|
|
19260
|
+
});
|
|
19261
|
+
return removed;
|
|
19262
|
+
}
|
|
19263
|
+
function changeFeedInstalled(db) {
|
|
19264
|
+
return db.prepare("SELECT value FROM store_meta WHERE key = ?").get(CHANGE_FEED_KEY)?.["value"] === columnSignature(db);
|
|
19265
|
+
}
|
|
19266
|
+
function columns(db, table) {
|
|
19267
|
+
return db.prepare(`SELECT name FROM pragma_table_info('${table}') ORDER BY cid`).all().map((r) => r.name);
|
|
19268
|
+
}
|
|
19269
|
+
function columnSignature(db) {
|
|
19270
|
+
return `5|${columns(db, "nodes").join(",")}|${columns(db, "edges").join(",")}|${EXPOSURE_ATTRS.join(",")}`;
|
|
19271
|
+
}
|
|
19272
|
+
var CHANGE_FEED_KEY, ANY_CHANGE, nodeScope, edgeScope, CHANGE_LOG_KEEP, PRUNED_TO_KEY, LINEAGE_CHANGED_FILES_SQL;
|
|
19273
|
+
var init_change_feed = __esm({
|
|
19274
|
+
"../../packages/local-graph/src/change-feed.ts"() {
|
|
19275
|
+
"use strict";
|
|
19276
|
+
init_exposure_attrs();
|
|
19277
|
+
CHANGE_FEED_KEY = "change-feed";
|
|
19278
|
+
ANY_CHANGE = "*";
|
|
19279
|
+
nodeScope = (label) => `node:${label}`;
|
|
19280
|
+
edgeScope = (type) => `edge:${type}`;
|
|
19281
|
+
CHANGE_LOG_KEEP = 25e4;
|
|
19282
|
+
PRUNED_TO_KEY = "change-log-pruned-to";
|
|
19283
|
+
LINEAGE_CHANGED_FILES_SQL = `
|
|
19284
|
+
SELECT id FROM change_log WHERE change_seq > :s AND kind = 'node' AND label = 'File'
|
|
19285
|
+
UNION SELECT from_id FROM change_log WHERE change_seq > :s AND kind = 'edge' AND label IN ('DEFINES','CONTAINS')
|
|
19286
|
+
UNION SELECT e.from_id FROM (SELECT DISTINCT id FROM change_log WHERE change_seq > :s AND kind = 'node') c
|
|
19287
|
+
CROSS JOIN edges e ON e.to_id = c.id AND e.type IN ('DEFINES','CONTAINS')
|
|
19288
|
+
`;
|
|
19289
|
+
}
|
|
19290
|
+
});
|
|
19291
|
+
|
|
19148
19292
|
// ../../packages/local-graph/src/lineage-integrity.ts
|
|
19149
19293
|
function stmt(db, sql) {
|
|
19150
19294
|
let byDb = statements.get(db);
|
|
@@ -20399,6 +20543,7 @@ function graphStoreNeedsPreparation(path3) {
|
|
|
20399
20543
|
for (const match2 of (SCHEMA_SQL + TEMPORAL_INDEX_SQL).matchAll(/CREATE INDEX IF NOT EXISTS (\w+)/g)) {
|
|
20400
20544
|
if (!indexes.has(match2[1])) return true;
|
|
20401
20545
|
}
|
|
20546
|
+
if (!changeFeedInstalled(db)) return true;
|
|
20402
20547
|
return [SESSION_REPAIR_KEY, HISTORY_CACHE_FLOOR_KEY, EDIT_PLACEHOLDER_FLOOR_KEY, CLOUD_ATTR_COMPACTION_KEY, HISTORY_ATTR_SLIM_KEY, TEXT_INDEX_KEY, LINEAGE_INTEGRITY_KEY].some((key) => !db.prepare("SELECT value FROM store_meta WHERE key = ?").get(key));
|
|
20403
20548
|
} catch {
|
|
20404
20549
|
return true;
|
|
@@ -20478,6 +20623,7 @@ var init_store = __esm({
|
|
|
20478
20623
|
init_cloud_attr_compaction();
|
|
20479
20624
|
init_history_attr_slim();
|
|
20480
20625
|
init_text_index();
|
|
20626
|
+
init_change_feed();
|
|
20481
20627
|
init_lineage_integrity();
|
|
20482
20628
|
init_src3();
|
|
20483
20629
|
init_node_select();
|
|
@@ -20705,6 +20851,7 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
20705
20851
|
});
|
|
20706
20852
|
}
|
|
20707
20853
|
installLineageIntegrityRepair(this.db);
|
|
20854
|
+
installChangeFeed(this.db);
|
|
20708
20855
|
this.stmts = {
|
|
20709
20856
|
insertNode: this.db.prepare(`
|
|
20710
20857
|
INSERT INTO nodes (
|
|
@@ -21492,12 +21639,39 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
21492
21639
|
mutationCount() {
|
|
21493
21640
|
return this.mutations;
|
|
21494
21641
|
}
|
|
21642
|
+
changeStamp() {
|
|
21643
|
+
const { data_version } = this.db.pragma("data_version");
|
|
21644
|
+
const { n } = this.db.prepare("SELECT total_changes() AS n").get();
|
|
21645
|
+
return `${data_version}:${n}`;
|
|
21646
|
+
}
|
|
21647
|
+
changeSeq(scopes) {
|
|
21648
|
+
return readChangeSeq(this.db, scopes);
|
|
21649
|
+
}
|
|
21650
|
+
lineageChangedFiles(sinceSeq) {
|
|
21651
|
+
return readLineageChangedFiles(this.db, sinceSeq);
|
|
21652
|
+
}
|
|
21653
|
+
pruneChangeLog() {
|
|
21654
|
+
return pruneChangeLog(this.db);
|
|
21655
|
+
}
|
|
21656
|
+
fileRowStates(ids) {
|
|
21657
|
+
if (ids.length === 0) return [];
|
|
21658
|
+
if (ids.length > 500) throw new RangeError("fileRowStates accepts at most 500 ids per read");
|
|
21659
|
+
return this.db.prepare(`SELECT id, last_updated_at AS lastUpdatedAt, valid_to AS validTo FROM nodes WHERE id IN (${ids.map(() => "?").join(",")})`).all(...ids);
|
|
21660
|
+
}
|
|
21661
|
+
// Read and advanced in SQL, never from a per-connection copy: pass workers and
|
|
21662
|
+
// MCP processes open their own connections and advance the same row, so a
|
|
21663
|
+
// copy loaded at open went stale, and `copy + 1` wrote a duplicate or a
|
|
21664
|
+
// backwards seq from whichever connection had fallen behind.
|
|
21495
21665
|
currentIngestSeq() {
|
|
21666
|
+
const row = this.db.prepare("SELECT value FROM store_meta WHERE key = 'ingest_seq'").get();
|
|
21667
|
+
this.ingestSeq = row ? Number(row.value) : 0;
|
|
21496
21668
|
return this.ingestSeq;
|
|
21497
21669
|
}
|
|
21498
21670
|
nextIngestSeq() {
|
|
21499
|
-
this.
|
|
21500
|
-
|
|
21671
|
+
const row = this.db.prepare(
|
|
21672
|
+
"INSERT INTO store_meta (key, value) VALUES ('ingest_seq', '1') ON CONFLICT(key) DO UPDATE SET value = CAST(value AS INTEGER) + 1 RETURNING value"
|
|
21673
|
+
).get();
|
|
21674
|
+
this.ingestSeq = Number(row.value);
|
|
21501
21675
|
return this.ingestSeq;
|
|
21502
21676
|
}
|
|
21503
21677
|
edgeCount() {
|
|
@@ -27128,14 +27302,17 @@ var init_wm_calibration = __esm({
|
|
|
27128
27302
|
// ../../packages/local-graph/src/index.ts
|
|
27129
27303
|
var src_exports2 = {};
|
|
27130
27304
|
__export(src_exports2, {
|
|
27305
|
+
ANY_CHANGE: () => ANY_CHANGE,
|
|
27131
27306
|
AUTO_MINT_PREFIX: () => AUTO_MINT_PREFIX,
|
|
27132
27307
|
CAUSAL_FAMILY: () => CAUSAL_FAMILY,
|
|
27133
27308
|
CITABLE_PRIOR_LABELS: () => CITABLE_PRIOR_LABELS,
|
|
27134
27309
|
CODE_REACH_EDGES: () => CODE_REACH_EDGES,
|
|
27135
27310
|
CREDIT_FAMILY: () => CREDIT_FAMILY,
|
|
27136
27311
|
DEFAULT_MIN_COVERAGE: () => DEFAULT_MIN_COVERAGE,
|
|
27312
|
+
EXPOSURE_ATTRS: () => EXPOSURE_ATTRS,
|
|
27137
27313
|
EXPOSURE_LOG_KEYS: () => EXPOSURE_LOG_KEYS,
|
|
27138
27314
|
EXPOSURE_LOG_MAX: () => EXPOSURE_LOG_MAX,
|
|
27315
|
+
EXPOSURE_SCOPE: () => EXPOSURE_SCOPE,
|
|
27139
27316
|
FINGERPRINT_INDEXED_LABELS: () => FINGERPRINT_INDEXED_LABELS,
|
|
27140
27317
|
FIX_CANDIDATE_ASK_LIMIT: () => FIX_CANDIDATE_ASK_LIMIT,
|
|
27141
27318
|
FOLD_EMBED_AUTO_COSINE: () => FOLD_EMBED_AUTO_COSINE,
|
|
@@ -27208,6 +27385,7 @@ __export(src_exports2, {
|
|
|
27208
27385
|
designProblemId: () => designProblemId,
|
|
27209
27386
|
detectLocalCommunities: () => detectLocalCommunities,
|
|
27210
27387
|
edgeConductance: () => edgeConductance,
|
|
27388
|
+
edgeScope: () => edgeScope,
|
|
27211
27389
|
evaluateDependency: () => evaluateDependency,
|
|
27212
27390
|
evaluateFed: () => evaluateFed,
|
|
27213
27391
|
evaluateMechanisms: () => evaluateMechanisms,
|
|
@@ -27261,6 +27439,7 @@ __export(src_exports2, {
|
|
|
27261
27439
|
mintDomainNode: () => mintDomainNode,
|
|
27262
27440
|
mintPatternNode: () => mintPatternNode,
|
|
27263
27441
|
mintWorkspaceCausalFact: () => mintWorkspaceCausalFact,
|
|
27442
|
+
nodeScope: () => nodeScope,
|
|
27264
27443
|
openGraphStore: () => openGraphStore,
|
|
27265
27444
|
osNodeId: () => osNodeId,
|
|
27266
27445
|
parseAbstractionFences: () => parseAbstractionFences,
|
|
@@ -27321,6 +27500,8 @@ var init_src5 = __esm({
|
|
|
27321
27500
|
"use strict";
|
|
27322
27501
|
init_store();
|
|
27323
27502
|
init_types();
|
|
27503
|
+
init_change_feed();
|
|
27504
|
+
init_exposure_attrs();
|
|
27324
27505
|
init_traversal();
|
|
27325
27506
|
init_justification();
|
|
27326
27507
|
init_credit();
|
|
@@ -27374,12 +27555,12 @@ function buildSnapshot(opts) {
|
|
|
27374
27555
|
const problems = opts.store.selectNodes({ labels: ["Problem", "Vulnerability"], attrs: PROBLEM_BAND_ATTRS }).filter((p) => p.attrs["mergedInto"] === void 0 && passiveAllowed(p, opts.atCommit));
|
|
27375
27556
|
const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
|
|
27376
27557
|
const allProblems = rankRecentBand(stillOpen.filter((p) => !isConstraintProblem(p)));
|
|
27377
|
-
const openPool = allProblems.slice(0, RECENT_OPEN * SCOPE_POOL_FACTOR).map((p) => ({
|
|
27558
|
+
const openPool = allProblems.slice(0, Math.max(RECENT_OPEN * SCOPE_POOL_FACTOR, RECENT_WINDOW_BANDS * RECENT_OPEN)).map((p) => ({
|
|
27378
27559
|
node: hydrate(p.id),
|
|
27379
27560
|
anchors: opts.store.outEdges(p.id, ["MANIFESTED_IN", "EVIDENCED_BY"])
|
|
27380
27561
|
}));
|
|
27381
27562
|
const recent4 = openPool.slice(0, RECENT_OPEN);
|
|
27382
|
-
const constraintPool = rankRecentBand(stillOpen.filter((p) => isConstraintProblem(p)), { window: RECENT_WINDOW_BANDS * RECENT_CONSTRAINTS }).slice(0, RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR).map((p) => hydrate(p.id));
|
|
27563
|
+
const constraintPool = rankRecentBand(stillOpen.filter((p) => isConstraintProblem(p)), { window: RECENT_WINDOW_BANDS * RECENT_CONSTRAINTS }).slice(0, Math.max(RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR, RECENT_WINDOW_BANDS * RECENT_CONSTRAINTS)).map((p) => hydrate(p.id));
|
|
27383
27564
|
const recentConstraints = constraintPool.slice(0, RECENT_CONSTRAINTS);
|
|
27384
27565
|
const regressionSources = /* @__PURE__ */ new Set();
|
|
27385
27566
|
for (const target of opts.store.inDegreeByType(["REGRESSION_OF"]).keys()) {
|
|
@@ -27489,6 +27670,22 @@ function rankRecentBand(problems, { quota = RECENT_SHOW_QUOTA, window: window2 =
|
|
|
27489
27670
|
const head2 = byRecency.slice(0, window2);
|
|
27490
27671
|
return [...head2.filter((p) => !spent(p)), ...head2.filter(spent), ...byRecency.slice(window2)];
|
|
27491
27672
|
}
|
|
27673
|
+
function freshenRecentBands(s, read2) {
|
|
27674
|
+
const pool = s.scopePool;
|
|
27675
|
+
if (!pool) return s;
|
|
27676
|
+
const fresh = (n) => read2(n.id) ?? n;
|
|
27677
|
+
const openRows = pool.open.map((r) => ({ ...r, node: fresh(r.node) }));
|
|
27678
|
+
const openOrder = rankRecentBand(openRows.map((r) => r.node), { window: openRows.length });
|
|
27679
|
+
const byId = new Map(openRows.map((r) => [r.node.id, r]));
|
|
27680
|
+
const open2 = openOrder.map((n) => byId.get(n.id));
|
|
27681
|
+
const constraints = rankRecentBand(pool.constraints.map(fresh), { window: pool.constraints.length });
|
|
27682
|
+
return {
|
|
27683
|
+
...s,
|
|
27684
|
+
recentProblems: open2.slice(0, RECENT_OPEN),
|
|
27685
|
+
recentConstraints: constraints.slice(0, RECENT_CONSTRAINTS),
|
|
27686
|
+
scopePool: { ...pool, open: open2, constraints }
|
|
27687
|
+
};
|
|
27688
|
+
}
|
|
27492
27689
|
function scopeSnapshot(s, keep) {
|
|
27493
27690
|
const pool = s.scopePool;
|
|
27494
27691
|
if (!pool) return s;
|
|
@@ -29363,10 +29560,16 @@ var init_client = __esm({
|
|
|
29363
29560
|
async getProjectHistoryCorrections(projectId, since, limit = 200) {
|
|
29364
29561
|
return this.json("GET", `/v2/projects/${encodeURIComponent(projectId)}/anchors?correctionsOnly=1&correctionSince=${String(since)}&limit=${String(limit)}`);
|
|
29365
29562
|
}
|
|
29366
|
-
|
|
29367
|
-
|
|
29563
|
+
/** `pendingOnly`: just what a sweep at `atCommit` must post (no settled receipt) or land
|
|
29564
|
+
* (a verdict other than unknown). A cloud that predates the filter returns every occurrence. */
|
|
29565
|
+
async getHistoryOccurrences(projectId, atCommit, after, opts = {}) {
|
|
29566
|
+
const query = new URLSearchParams({ atCommit, limit: "50", ...after ? { after } : {}, ...opts.pendingOnly ? { pending: "1" } : {} });
|
|
29368
29567
|
return this.json("GET", `/v2/projects/${encodeURIComponent(projectId)}/history/occurrences?${query}`);
|
|
29369
29568
|
}
|
|
29569
|
+
/** Carry settled verdicts across a commit range; 404 from a cloud that predates the route. */
|
|
29570
|
+
async carryHistory(projectId, carry) {
|
|
29571
|
+
return this.json("POST", `/v2/projects/${encodeURIComponent(projectId)}/history/carry`, carry);
|
|
29572
|
+
}
|
|
29370
29573
|
async reconcileHistory(projectId, proof) {
|
|
29371
29574
|
return this.json("POST", `/v2/projects/${encodeURIComponent(projectId)}/history/reconcile`, proof);
|
|
29372
29575
|
}
|
|
@@ -29943,31 +30146,9 @@ var init_config = __esm({
|
|
|
29943
30146
|
});
|
|
29944
30147
|
|
|
29945
30148
|
// src/cloud-endpoint-policy.ts
|
|
29946
|
-
function warnDirectV1OverrideOnce() {
|
|
29947
|
-
if (warnedDirectV1Override) return;
|
|
29948
|
-
warnedDirectV1Override = true;
|
|
29949
|
-
console.error(
|
|
29950
|
-
[
|
|
29951
|
-
"",
|
|
29952
|
-
"!!! DIRECT V1 OVERRIDE ACTIVE !!!",
|
|
29953
|
-
`${DIRECT_V1_OVERRIDE_ENV} + ${DIRECT_V1_ACK_ENV} are set: this daemon is talking`,
|
|
29954
|
-
"straight to the legacy v1 data plane, BYPASSING the Console Gateway \u2014",
|
|
29955
|
-
"no metering, no signed context enforcement, no write-target binding.",
|
|
29956
|
-
"Staff testing only. This escape hatch is removed at v1 EOL.",
|
|
29957
|
-
""
|
|
29958
|
-
].join("\n")
|
|
29959
|
-
);
|
|
29960
|
-
}
|
|
29961
|
-
function isDirectV1OverrideRequested() {
|
|
29962
|
-
const raw2 = process.env[DIRECT_V1_OVERRIDE_ENV]?.trim().toLowerCase();
|
|
29963
|
-
return raw2 === "1" || raw2 === "true" || raw2 === "yes" || raw2 === "on";
|
|
29964
|
-
}
|
|
29965
30149
|
function normalizeCloudUrl(url2) {
|
|
29966
30150
|
return url2.replace(/\/+$/, "");
|
|
29967
30151
|
}
|
|
29968
|
-
function isDirectV1OverrideEnabled() {
|
|
29969
|
-
return isDirectV1OverrideRequested() && process.env[DIRECT_V1_ACK_ENV]?.trim() === DIRECT_V1_ACK_VALUE;
|
|
29970
|
-
}
|
|
29971
30152
|
function isLocalCloudUrl(url2) {
|
|
29972
30153
|
try {
|
|
29973
30154
|
const host = new URL(url2).hostname.toLowerCase();
|
|
@@ -29997,21 +30178,12 @@ function evaluateCloudEndpoint(url2, inspection) {
|
|
|
29997
30178
|
if (looksLikeGatewayCloudUrl(url2)) {
|
|
29998
30179
|
return { allowed: true, label: "gateway-configured" };
|
|
29999
30180
|
}
|
|
30000
|
-
if (isDirectV1OverrideEnabled()) {
|
|
30001
|
-
warnDirectV1OverrideOnce();
|
|
30002
|
-
return {
|
|
30003
|
-
allowed: true,
|
|
30004
|
-
label: "legacy-direct (override)",
|
|
30005
|
-
reason: `${DIRECT_V1_OVERRIDE_ENV} acknowledged via ${DIRECT_V1_ACK_ENV}`
|
|
30006
|
-
};
|
|
30007
|
-
}
|
|
30008
30181
|
const service = inspection?.service ? ` (${inspection.service})` : "";
|
|
30009
|
-
const unacked = isDirectV1OverrideRequested() ? ` ${DIRECT_V1_OVERRIDE_ENV} is set but unacknowledged \u2014 staff testing additionally requires ${DIRECT_V1_ACK_ENV}=${DIRECT_V1_ACK_VALUE}.` : "";
|
|
30010
30182
|
return {
|
|
30011
30183
|
allowed: false,
|
|
30012
30184
|
label: "legacy-direct blocked",
|
|
30013
30185
|
reason: `non-local cloud endpoint is not the Console Gateway${service}`,
|
|
30014
|
-
guidance:
|
|
30186
|
+
guidance: "Point ERRATA_CLOUD_URL at the Console Gateway."
|
|
30015
30187
|
};
|
|
30016
30188
|
}
|
|
30017
30189
|
function formatCloudEndpointBlock(url2, decision) {
|
|
@@ -30153,16 +30325,12 @@ async function fetchHealthJson(fetchFn, url2, timeoutMs) {
|
|
|
30153
30325
|
clearTimeout(tid);
|
|
30154
30326
|
}
|
|
30155
30327
|
}
|
|
30156
|
-
var
|
|
30328
|
+
var GATEWAY_SERVICE, PROBE_TIMEOUT_MS, CloudEndpointPolicyError, BLOCKED_RECHECK_MS;
|
|
30157
30329
|
var init_cloud_endpoint_policy = __esm({
|
|
30158
30330
|
"src/cloud-endpoint-policy.ts"() {
|
|
30159
30331
|
"use strict";
|
|
30160
|
-
DIRECT_V1_OVERRIDE_ENV = "ERRATA_ALLOW_DIRECT_V1_CLOUD";
|
|
30161
|
-
DIRECT_V1_ACK_ENV = "ERRATA_DIRECT_V1_ACK";
|
|
30162
|
-
DIRECT_V1_ACK_VALUE = "I_ACCEPT_UNMETERED_DIRECT_V1";
|
|
30163
30332
|
GATEWAY_SERVICE = "console-gateway";
|
|
30164
30333
|
PROBE_TIMEOUT_MS = 2e3;
|
|
30165
|
-
warnedDirectV1Override = false;
|
|
30166
30334
|
CloudEndpointPolicyError = class extends Error {
|
|
30167
30335
|
decision;
|
|
30168
30336
|
constructor(message2, decision) {
|
|
@@ -35193,7 +35361,7 @@ function rememberAgentCard(sessionId, agentId, card, now = Date.now()) {
|
|
|
35193
35361
|
function subagentRows(body2, now = Date.now()) {
|
|
35194
35362
|
const sessionId = typeof body2["session_id"] === "string" ? body2["session_id"] : "";
|
|
35195
35363
|
const tasks = Array.isArray(body2["tasks"]) ? body2["tasks"] : [];
|
|
35196
|
-
const
|
|
35364
|
+
const columns2 = typeof body2["columns"] === "number" && body2["columns"] > 20 ? body2["columns"] : 100;
|
|
35197
35365
|
const lines = [];
|
|
35198
35366
|
for (const task of tasks) {
|
|
35199
35367
|
const id = typeof task["id"] === "string" ? task["id"] : "";
|
|
@@ -35203,7 +35371,7 @@ function subagentRows(body2, now = Date.now()) {
|
|
|
35203
35371
|
const title = String(task["description"] ?? task["label"] ?? "").trim();
|
|
35204
35372
|
const plain = clip(
|
|
35205
35373
|
`${title ? `${title} \xB7 ` : ""}\u26A1 errata \xB7 ${hit.card.headline}${lead2 ? ` \u2014 ${labelName(lead2.label)}: ${lead2.text}` : ""}`,
|
|
35206
|
-
|
|
35374
|
+
columns2 - 2
|
|
35207
35375
|
);
|
|
35208
35376
|
lines.push(JSON.stringify({ id, content: plain.replace("\u26A1", `${AMBER}\u26A1${RESET}`) }));
|
|
35209
35377
|
}
|
|
@@ -38251,8 +38419,8 @@ import { execFileSync as execFileSync3 } from "node:child_process";
|
|
|
38251
38419
|
function nowTs() {
|
|
38252
38420
|
return indexNow ?? Date.now();
|
|
38253
38421
|
}
|
|
38254
|
-
function fingerprintOf(
|
|
38255
|
-
return `${
|
|
38422
|
+
function fingerprintOf(signature2, bodyHash) {
|
|
38423
|
+
return `${signature2 ?? ""}|${bodyHash ?? ""}`;
|
|
38256
38424
|
}
|
|
38257
38425
|
function sha(s) {
|
|
38258
38426
|
return createHash7("sha256").update(s).digest("hex").slice(0, 16);
|
|
@@ -46768,11 +46936,20 @@ function* walkSource(dir) {
|
|
|
46768
46936
|
function listSourceFiles(root) {
|
|
46769
46937
|
return gitSourceFiles(root) ?? walkSource(root);
|
|
46770
46938
|
}
|
|
46771
|
-
async function findStaleFiles(store, rootPath, workspaceId2) {
|
|
46939
|
+
async function findStaleFiles(store, rootPath, workspaceId2, lineageVerifiedAt) {
|
|
46772
46940
|
const stale = [];
|
|
46941
|
+
const changed = lineageVerifiedAt !== void 0 && store.fileRowStates ? store.lineageChangedFiles?.(lineageVerifiedAt) : null;
|
|
46942
|
+
const relineage = changed ? new Set(changed) : null;
|
|
46773
46943
|
let pending = [];
|
|
46774
46944
|
const check2 = () => {
|
|
46775
|
-
const
|
|
46945
|
+
const full = relineage ? pending.filter((f) => relineage.has(f.id)) : pending;
|
|
46946
|
+
const states = new Map(
|
|
46947
|
+
store.fileIndexStates(full.map((f) => f.id)).map((s) => [s.id, s])
|
|
46948
|
+
);
|
|
46949
|
+
if (relineage) {
|
|
46950
|
+
const rowOnly = pending.filter((f) => !relineage.has(f.id)).map((f) => f.id);
|
|
46951
|
+
for (const s of store.fileRowStates(rowOnly)) states.set(s.id, { ...s, complete: true });
|
|
46952
|
+
}
|
|
46776
46953
|
for (const f of pending) {
|
|
46777
46954
|
const state = states.get(f.id);
|
|
46778
46955
|
if (!state || state.validTo !== null || state.lastUpdatedAt < f.mtimeMs || !state.complete) stale.push(f.abs);
|
|
@@ -46797,6 +46974,19 @@ async function findStaleFiles(store, rootPath, workspaceId2) {
|
|
|
46797
46974
|
function findStrandedSymbols(store) {
|
|
46798
46975
|
return store.strandedSymbols();
|
|
46799
46976
|
}
|
|
46977
|
+
function standingStrandedCount(store) {
|
|
46978
|
+
try {
|
|
46979
|
+
const last = JSON.parse(store.getMeta?.(STRANDED_KEY) ?? "null");
|
|
46980
|
+
if (!last) return null;
|
|
46981
|
+
if ((store.changeSeq?.() ?? Infinity) - last.seq > STRANDED_WINDOW_MAX) return null;
|
|
46982
|
+
return store.lineageChangedFiles?.(last.seq)?.length === 0 ? last.count : null;
|
|
46983
|
+
} catch {
|
|
46984
|
+
return null;
|
|
46985
|
+
}
|
|
46986
|
+
}
|
|
46987
|
+
function recordStrandedCount(store, seq, count) {
|
|
46988
|
+
if (seq !== void 0) store.setMeta?.(STRANDED_KEY, JSON.stringify({ seq, count }));
|
|
46989
|
+
}
|
|
46800
46990
|
function reapOrphanedFiles(store, rootPath, workspaceId2, ignoreDirs = []) {
|
|
46801
46991
|
const ignores = /* @__PURE__ */ new Set([...DEFAULT_IGNORES, ...ignoreDirs]);
|
|
46802
46992
|
const listed = gitListRelPaths(rootPath, ignores);
|
|
@@ -46835,8 +47025,16 @@ function reapOrphanedFiles(store, rootPath, workspaceId2, ignoreDirs = []) {
|
|
|
46835
47025
|
return { reaped: orphans.length, symbolsClosed };
|
|
46836
47026
|
}
|
|
46837
47027
|
async function reconcileStaleFiles(store, rootPath, workspaceId2) {
|
|
46838
|
-
const
|
|
46839
|
-
|
|
47028
|
+
const startedAt = store.changeSeq?.();
|
|
47029
|
+
const verified = Number(store.getMeta?.(LINEAGE_VERIFIED_KEY) ?? NaN);
|
|
47030
|
+
const stale = await findStaleFiles(store, rootPath, workspaceId2, Number.isFinite(verified) ? verified : void 0);
|
|
47031
|
+
const verify = () => {
|
|
47032
|
+
if (startedAt !== void 0) store.setMeta?.(LINEAGE_VERIFIED_KEY, String(startedAt));
|
|
47033
|
+
};
|
|
47034
|
+
if (stale.length === 0) {
|
|
47035
|
+
verify();
|
|
47036
|
+
return 0;
|
|
47037
|
+
}
|
|
46840
47038
|
let total = 0;
|
|
46841
47039
|
let failedBatches = 0;
|
|
46842
47040
|
const BATCH = 20;
|
|
@@ -46854,10 +47052,12 @@ async function reconcileStaleFiles(store, rootPath, workspaceId2) {
|
|
|
46854
47052
|
}
|
|
46855
47053
|
if (failedBatches > 0) {
|
|
46856
47054
|
console.warn(`[errata] reconcile: ${failedBatches} batch(es) failed; ${total} file(s) reindexed`);
|
|
47055
|
+
} else {
|
|
47056
|
+
verify();
|
|
46857
47057
|
}
|
|
46858
47058
|
return total;
|
|
46859
47059
|
}
|
|
46860
|
-
var IGNORED, SOURCE_RE, SCAN_YIELD_EVERY, ORPHAN_REAP_MAX_FRACTION, ORPHAN_REAP_MIN_ALLOWANCE;
|
|
47060
|
+
var IGNORED, SOURCE_RE, SCAN_YIELD_EVERY, STRANDED_KEY, STRANDED_WINDOW_MAX, ORPHAN_REAP_MAX_FRACTION, ORPHAN_REAP_MIN_ALLOWANCE, LINEAGE_VERIFIED_KEY;
|
|
46861
47061
|
var init_reconcile = __esm({
|
|
46862
47062
|
"src/reconcile.ts"() {
|
|
46863
47063
|
"use strict";
|
|
@@ -46865,8 +47065,11 @@ var init_reconcile = __esm({
|
|
|
46865
47065
|
IGNORED = /[\\/](?:\.git|node_modules|\.errata|dist|__pycache__)(?:[\\/]|$)/;
|
|
46866
47066
|
SOURCE_RE = /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i;
|
|
46867
47067
|
SCAN_YIELD_EVERY = 100;
|
|
47068
|
+
STRANDED_KEY = "pass-inputs:stranded";
|
|
47069
|
+
STRANDED_WINDOW_MAX = 2e4;
|
|
46868
47070
|
ORPHAN_REAP_MAX_FRACTION = 0.25;
|
|
46869
47071
|
ORPHAN_REAP_MIN_ALLOWANCE = 50;
|
|
47072
|
+
LINEAGE_VERIFIED_KEY = "pass-inputs:reconcile-lineage";
|
|
46870
47073
|
}
|
|
46871
47074
|
});
|
|
46872
47075
|
|
|
@@ -76506,18 +76709,18 @@ __export(witness_ledger_exports, {
|
|
|
76506
76709
|
summarizeWitnessLedger: () => summarizeWitnessLedger,
|
|
76507
76710
|
witnessLedgerPath: () => witnessLedgerPath
|
|
76508
76711
|
});
|
|
76509
|
-
import { appendFileSync as appendFileSync3, existsSync as existsSync27, readFileSync as
|
|
76510
|
-
import { join as
|
|
76712
|
+
import { appendFileSync as appendFileSync3, existsSync as existsSync27, readFileSync as readFileSync31, writeFileSync as writeFileSync22 } from "node:fs";
|
|
76713
|
+
import { join as join35 } from "node:path";
|
|
76511
76714
|
function witnessLedgerPath(configDir) {
|
|
76512
|
-
return
|
|
76715
|
+
return join35(configDir, "witness-ledger.jsonl");
|
|
76513
76716
|
}
|
|
76514
76717
|
function appendWitnessLedger(configDir, entry) {
|
|
76515
76718
|
const path3 = witnessLedgerPath(configDir);
|
|
76516
76719
|
try {
|
|
76517
76720
|
appendFileSync3(path3, JSON.stringify(entry) + "\n");
|
|
76518
|
-
const lines =
|
|
76721
|
+
const lines = readFileSync31(path3, "utf8").split("\n").filter(Boolean);
|
|
76519
76722
|
if (lines.length > LEDGER_MAX_LINES) {
|
|
76520
|
-
|
|
76723
|
+
writeFileSync22(path3, lines.slice(-Math.floor(LEDGER_MAX_LINES / 2)).join("\n") + "\n");
|
|
76521
76724
|
}
|
|
76522
76725
|
} catch {
|
|
76523
76726
|
}
|
|
@@ -76526,7 +76729,7 @@ function readWitnessLedger(configDir) {
|
|
|
76526
76729
|
const path3 = witnessLedgerPath(configDir);
|
|
76527
76730
|
if (!existsSync27(path3)) return [];
|
|
76528
76731
|
try {
|
|
76529
|
-
return
|
|
76732
|
+
return readFileSync31(path3, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter((e) => typeof e.ts === "number" && typeof e.channel === "string");
|
|
76530
76733
|
} catch {
|
|
76531
76734
|
return [];
|
|
76532
76735
|
}
|
|
@@ -76965,12 +77168,12 @@ var init_report_render = __esm({
|
|
|
76965
77168
|
|
|
76966
77169
|
// src/cli.ts
|
|
76967
77170
|
init_src6();
|
|
76968
|
-
import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as
|
|
76969
|
-
import { join as
|
|
77171
|
+
import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as readFileSync48, renameSync as renameSync10, statSync as statSync16 } from "node:fs";
|
|
77172
|
+
import { join as join56, resolve as pathResolve2 } from "node:path";
|
|
76970
77173
|
import { spawn as spawn5 } from "node:child_process";
|
|
76971
77174
|
|
|
76972
77175
|
// src/daemon.ts
|
|
76973
|
-
import { existsSync as existsSync29, writeFileSync as
|
|
77176
|
+
import { existsSync as existsSync29, writeFileSync as writeFileSync25 } from "node:fs";
|
|
76974
77177
|
|
|
76975
77178
|
// ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.34/node_modules/@hono/node-server/dist/index.mjs
|
|
76976
77179
|
import { createServer as createServerHTTP } from "http";
|
|
@@ -77654,8 +77857,8 @@ function knowledgeTag(label, attrs) {
|
|
|
77654
77857
|
|
|
77655
77858
|
// src/engine.ts
|
|
77656
77859
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
77657
|
-
import { existsSync as existsSync28, statSync as
|
|
77658
|
-
import { basename as basename8, join as
|
|
77860
|
+
import { existsSync as existsSync28, statSync as statSync11, appendFileSync as appendFileSync4, readdirSync as readdirSync11, renameSync as renameSync5, readFileSync as readFileSync33, writeFileSync as writeFileSync24 } from "node:fs";
|
|
77861
|
+
import { basename as basename8, join as join37, relative as relative6, sep as sep5 } from "node:path";
|
|
77659
77862
|
|
|
77660
77863
|
// src/coalesced-file-pass.ts
|
|
77661
77864
|
function createCoalescedFilePass(delayMs, run3, onError) {
|
|
@@ -77700,7 +77903,7 @@ function createCoalescedFilePass(delayMs, run3, onError) {
|
|
|
77700
77903
|
// src/source-watcher.ts
|
|
77701
77904
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
77702
77905
|
import { readdirSync as readdirSync6, statSync as statSync7, watch as watch2 } from "node:fs";
|
|
77703
|
-
import {
|
|
77906
|
+
import { join as join21, sep as sep4 } from "node:path";
|
|
77704
77907
|
|
|
77705
77908
|
// ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
|
|
77706
77909
|
import { stat as statcb } from "fs";
|
|
@@ -78431,9 +78634,9 @@ var NodeFsHandler = class {
|
|
|
78431
78634
|
if (this.fsw.closed) {
|
|
78432
78635
|
return;
|
|
78433
78636
|
}
|
|
78434
|
-
const
|
|
78637
|
+
const dirname20 = sysPath.dirname(file2);
|
|
78435
78638
|
const basename10 = sysPath.basename(file2);
|
|
78436
|
-
const parent = this.fsw._getWatchedDir(
|
|
78639
|
+
const parent = this.fsw._getWatchedDir(dirname20);
|
|
78437
78640
|
let prevStats = stats;
|
|
78438
78641
|
if (parent.has(basename10))
|
|
78439
78642
|
return;
|
|
@@ -78460,7 +78663,7 @@ var NodeFsHandler = class {
|
|
|
78460
78663
|
prevStats = newStats2;
|
|
78461
78664
|
}
|
|
78462
78665
|
} catch (error48) {
|
|
78463
|
-
this.fsw._remove(
|
|
78666
|
+
this.fsw._remove(dirname20, basename10);
|
|
78464
78667
|
}
|
|
78465
78668
|
} else if (parent.has(basename10)) {
|
|
78466
78669
|
const at = newStats.atimeMs;
|
|
@@ -78709,11 +78912,11 @@ function createPattern(matcher) {
|
|
|
78709
78912
|
if (matcher.path === string4)
|
|
78710
78913
|
return true;
|
|
78711
78914
|
if (matcher.recursive) {
|
|
78712
|
-
const
|
|
78713
|
-
if (!
|
|
78915
|
+
const relative8 = sysPath2.relative(matcher.path, string4);
|
|
78916
|
+
if (!relative8) {
|
|
78714
78917
|
return false;
|
|
78715
78918
|
}
|
|
78716
|
-
return !
|
|
78919
|
+
return !relative8.startsWith("..") && !sysPath2.isAbsolute(relative8);
|
|
78717
78920
|
}
|
|
78718
78921
|
return false;
|
|
78719
78922
|
};
|
|
@@ -79422,7 +79625,9 @@ var NativeSourceWatcher = class extends EventEmitter2 {
|
|
|
79422
79625
|
handles = /* @__PURE__ */ new Map();
|
|
79423
79626
|
pending = /* @__PURE__ */ new Map();
|
|
79424
79627
|
rescans = /* @__PURE__ */ new Map();
|
|
79425
|
-
known
|
|
79628
|
+
/** Each known file's content signature (mtime and size). A raw event whose
|
|
79629
|
+
* file still has the same signature changed nothing in it. */
|
|
79630
|
+
known = /* @__PURE__ */ new Map();
|
|
79426
79631
|
closed = false;
|
|
79427
79632
|
add(target) {
|
|
79428
79633
|
if (this.closed || this.handles.has(target)) return;
|
|
@@ -79476,21 +79681,35 @@ var NativeSourceWatcher = class extends EventEmitter2 {
|
|
|
79476
79681
|
this.pending.set(path3, { timer, renamed: renamed || (prev?.renamed ?? false) });
|
|
79477
79682
|
}
|
|
79478
79683
|
seedKnown(target, isDir) {
|
|
79479
|
-
for (const path3 of this.filesUnder(target, isDir)) this.known.
|
|
79684
|
+
for (const [path3, sig] of this.filesUnder(target, isDir)) this.known.set(path3, sig);
|
|
79480
79685
|
}
|
|
79481
79686
|
filesUnder(target, isDir) {
|
|
79482
|
-
const files = /* @__PURE__ */ new
|
|
79687
|
+
const files = /* @__PURE__ */ new Map();
|
|
79688
|
+
const add = (path3) => {
|
|
79689
|
+
try {
|
|
79690
|
+
files.set(path3, signature(statSync7(path3)));
|
|
79691
|
+
} catch {
|
|
79692
|
+
}
|
|
79693
|
+
};
|
|
79483
79694
|
if (!isDir) {
|
|
79484
|
-
if (!this.ignored(target))
|
|
79695
|
+
if (!this.ignored(target)) add(target);
|
|
79485
79696
|
return files;
|
|
79486
79697
|
}
|
|
79487
|
-
|
|
79488
|
-
|
|
79489
|
-
|
|
79490
|
-
|
|
79491
|
-
|
|
79698
|
+
const dirs = [target];
|
|
79699
|
+
while (dirs.length > 0) {
|
|
79700
|
+
const dir = dirs.pop();
|
|
79701
|
+
let entries;
|
|
79702
|
+
try {
|
|
79703
|
+
entries = readdirSync6(dir, { withFileTypes: true });
|
|
79704
|
+
} catch {
|
|
79705
|
+
continue;
|
|
79706
|
+
}
|
|
79707
|
+
for (const entry of entries) {
|
|
79708
|
+
const path3 = join21(dir, entry.name);
|
|
79709
|
+
if (this.ignored(path3)) continue;
|
|
79710
|
+
if (entry.isDirectory()) dirs.push(path3);
|
|
79711
|
+
else if (entry.isFile()) add(path3);
|
|
79492
79712
|
}
|
|
79493
|
-
} catch {
|
|
79494
79713
|
}
|
|
79495
79714
|
return files;
|
|
79496
79715
|
}
|
|
@@ -79501,19 +79720,17 @@ var NativeSourceWatcher = class extends EventEmitter2 {
|
|
|
79501
79720
|
this.rescans.delete(target);
|
|
79502
79721
|
if (this.closed || !this.handles.has(target)) return;
|
|
79503
79722
|
const current = this.filesUnder(target, isDir);
|
|
79504
|
-
const
|
|
79505
|
-
|
|
79506
|
-
|
|
79507
|
-
};
|
|
79508
|
-
for (const path3 of [...this.known]) {
|
|
79723
|
+
const prefix = target.endsWith(sep4) ? target : target + sep4;
|
|
79724
|
+
const belongsToTarget = (path3) => path3 === target || path3.startsWith(prefix);
|
|
79725
|
+
for (const path3 of [...this.known.keys()]) {
|
|
79509
79726
|
if (belongsToTarget(path3) && !current.has(path3)) {
|
|
79510
79727
|
this.known.delete(path3);
|
|
79511
79728
|
this.emit("unlink", path3);
|
|
79512
79729
|
}
|
|
79513
79730
|
}
|
|
79514
|
-
for (const path3 of current) {
|
|
79731
|
+
for (const [path3, sig] of current) {
|
|
79515
79732
|
if (!this.known.has(path3)) {
|
|
79516
|
-
this.known.
|
|
79733
|
+
this.known.set(path3, sig);
|
|
79517
79734
|
this.emit("add", path3);
|
|
79518
79735
|
}
|
|
79519
79736
|
}
|
|
@@ -79523,21 +79740,27 @@ var NativeSourceWatcher = class extends EventEmitter2 {
|
|
|
79523
79740
|
classify(path3, renamed) {
|
|
79524
79741
|
if (this.closed) return;
|
|
79525
79742
|
let isFile;
|
|
79743
|
+
let sig;
|
|
79526
79744
|
try {
|
|
79527
79745
|
const s = statSync7(path3);
|
|
79528
79746
|
if (s.isDirectory()) return;
|
|
79529
79747
|
isFile = s.isFile();
|
|
79748
|
+
sig = signature(s);
|
|
79530
79749
|
} catch {
|
|
79531
79750
|
this.known.delete(path3);
|
|
79532
79751
|
this.emit("unlink", path3);
|
|
79533
79752
|
return;
|
|
79534
79753
|
}
|
|
79535
79754
|
if (!isFile) return;
|
|
79536
|
-
const
|
|
79537
|
-
|
|
79538
|
-
this.
|
|
79755
|
+
const prev = this.known.get(path3);
|
|
79756
|
+
if (prev === sig) return;
|
|
79757
|
+
this.known.set(path3, sig);
|
|
79758
|
+
this.emit(renamed && prev === void 0 ? "add" : "change", path3);
|
|
79539
79759
|
}
|
|
79540
79760
|
};
|
|
79761
|
+
function signature(s) {
|
|
79762
|
+
return `${Math.trunc(s.mtimeMs)}:${s.size}:${Math.trunc(s.ctimeMs)}`;
|
|
79763
|
+
}
|
|
79541
79764
|
|
|
79542
79765
|
// src/engine.ts
|
|
79543
79766
|
init_generalize_graph();
|
|
@@ -79791,6 +80014,47 @@ async function chat(req) {
|
|
|
79791
80014
|
init_src11();
|
|
79792
80015
|
init_src6();
|
|
79793
80016
|
init_session_registry();
|
|
80017
|
+
|
|
80018
|
+
// src/snapshot-reuse.ts
|
|
80019
|
+
import { readFileSync as readFileSync18, renameSync as renameSync3, statSync as statSync8, writeFileSync as writeFileSync14 } from "node:fs";
|
|
80020
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
80021
|
+
import { dirname as dirname11, join as join22 } from "node:path";
|
|
80022
|
+
function snapshotReusable(held, want) {
|
|
80023
|
+
return held !== null && held.key === want.key && held.atCommit === want.atCommit && held.workingFile === want.workingFile;
|
|
80024
|
+
}
|
|
80025
|
+
var codeIdentityMemo;
|
|
80026
|
+
function snapshotCodeIdentity(version3) {
|
|
80027
|
+
if (codeIdentityMemo === void 0) {
|
|
80028
|
+
let built = "unknown";
|
|
80029
|
+
try {
|
|
80030
|
+
built = String(statSync8(fileURLToPath2(import.meta.url)).mtimeMs);
|
|
80031
|
+
} catch {
|
|
80032
|
+
}
|
|
80033
|
+
codeIdentityMemo = `${version3}@${built}`;
|
|
80034
|
+
}
|
|
80035
|
+
return codeIdentityMemo;
|
|
80036
|
+
}
|
|
80037
|
+
function heldSnapshotPath(configDir) {
|
|
80038
|
+
return join22(configDir, "snapshot-held.json");
|
|
80039
|
+
}
|
|
80040
|
+
function loadHeldSnapshot(path3) {
|
|
80041
|
+
try {
|
|
80042
|
+
const held = JSON.parse(readFileSync18(path3, "utf8"));
|
|
80043
|
+
return typeof held?.key === "string" && typeof held.at === "number" ? held : null;
|
|
80044
|
+
} catch {
|
|
80045
|
+
return null;
|
|
80046
|
+
}
|
|
80047
|
+
}
|
|
80048
|
+
function saveHeldSnapshot(path3, held) {
|
|
80049
|
+
try {
|
|
80050
|
+
const tmp = join22(dirname11(path3), `.${process.pid}.snapshot-held.tmp`);
|
|
80051
|
+
writeFileSync14(tmp, JSON.stringify(held));
|
|
80052
|
+
renameSync3(tmp, path3);
|
|
80053
|
+
} catch {
|
|
80054
|
+
}
|
|
80055
|
+
}
|
|
80056
|
+
|
|
80057
|
+
// src/engine.ts
|
|
79794
80058
|
init_recall_signal();
|
|
79795
80059
|
|
|
79796
80060
|
// src/subagent-state.ts
|
|
@@ -79979,8 +80243,8 @@ init_review2();
|
|
|
79979
80243
|
|
|
79980
80244
|
// src/turn.ts
|
|
79981
80245
|
init_checkout_root();
|
|
79982
|
-
import { closeSync as closeSync2, existsSync as existsSync19, fstatSync, openSync as openSync2, readdirSync as readdirSync7, readSync as readSync2, realpathSync as realpathSync2, statSync as
|
|
79983
|
-
import { basename as basename6, delimiter, dirname as
|
|
80246
|
+
import { closeSync as closeSync2, existsSync as existsSync19, fstatSync, openSync as openSync2, readdirSync as readdirSync7, readSync as readSync2, realpathSync as realpathSync2, statSync as statSync9 } from "node:fs";
|
|
80247
|
+
import { basename as basename6, delimiter, dirname as dirname12, join as join23, normalize as normalize3 } from "node:path";
|
|
79984
80248
|
import { homedir as homedir4 } from "node:os";
|
|
79985
80249
|
import { createHash as createHash16 } from "node:crypto";
|
|
79986
80250
|
function completeJsonlPrefix(buf) {
|
|
@@ -80368,7 +80632,7 @@ function turnsSince(turns, mark) {
|
|
|
80368
80632
|
return at >= 0 ? turns.slice(at + 1) : turns;
|
|
80369
80633
|
}
|
|
80370
80634
|
function claudeProjectDir(cwd, home = homedir4()) {
|
|
80371
|
-
return
|
|
80635
|
+
return join23(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
|
|
80372
80636
|
}
|
|
80373
80637
|
function recentTranscripts(cwd, opts = {}) {
|
|
80374
80638
|
const dir = claudeProjectDir(cwd, opts.home ?? homedir4());
|
|
@@ -80383,10 +80647,10 @@ function recentTranscripts(cwd, opts = {}) {
|
|
|
80383
80647
|
const refs = [];
|
|
80384
80648
|
for (const name2 of names) {
|
|
80385
80649
|
if (!name2.endsWith(".jsonl")) continue;
|
|
80386
|
-
const path3 =
|
|
80650
|
+
const path3 = join23(dir, name2);
|
|
80387
80651
|
let mtimeMs;
|
|
80388
80652
|
try {
|
|
80389
|
-
mtimeMs =
|
|
80653
|
+
mtimeMs = statSync9(path3).mtimeMs;
|
|
80390
80654
|
} catch {
|
|
80391
80655
|
continue;
|
|
80392
80656
|
}
|
|
@@ -80398,7 +80662,7 @@ function recentTranscripts(cwd, opts = {}) {
|
|
|
80398
80662
|
}
|
|
80399
80663
|
function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
80400
80664
|
if (!mainTranscriptPath || !sessionId) return [];
|
|
80401
|
-
const dir =
|
|
80665
|
+
const dir = join23(dirname12(mainTranscriptPath), sessionId, "subagents");
|
|
80402
80666
|
if (!existsSync19(dir)) return [];
|
|
80403
80667
|
let names;
|
|
80404
80668
|
try {
|
|
@@ -80409,10 +80673,10 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
|
80409
80673
|
const refs = [];
|
|
80410
80674
|
for (const name2 of names) {
|
|
80411
80675
|
if (!name2.endsWith(".jsonl")) continue;
|
|
80412
|
-
const path3 =
|
|
80676
|
+
const path3 = join23(dir, name2);
|
|
80413
80677
|
let mtimeMs;
|
|
80414
80678
|
try {
|
|
80415
|
-
mtimeMs =
|
|
80679
|
+
mtimeMs = statSync9(path3).mtimeMs;
|
|
80416
80680
|
} catch {
|
|
80417
80681
|
continue;
|
|
80418
80682
|
}
|
|
@@ -80421,15 +80685,15 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
|
80421
80685
|
refs.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
80422
80686
|
return refs;
|
|
80423
80687
|
}
|
|
80424
|
-
function splitPathList(value,
|
|
80688
|
+
function splitPathList(value, sep7 = delimiter) {
|
|
80425
80689
|
if (!value) return [];
|
|
80426
|
-
return value.split(
|
|
80690
|
+
return value.split(sep7).map((d) => d.trim()).filter(Boolean).map((d) => normalize3(d));
|
|
80427
80691
|
}
|
|
80428
80692
|
function codexSessionRoots(env2 = process.env, home = homedir4()) {
|
|
80429
80693
|
const roots = /* @__PURE__ */ new Set();
|
|
80430
80694
|
for (const d of splitPathList(env2["ERRATA_CODEX_SESSIONS_DIRS"])) roots.add(d);
|
|
80431
|
-
if (env2["CODEX_HOME"]) roots.add(
|
|
80432
|
-
roots.add(
|
|
80695
|
+
if (env2["CODEX_HOME"]) roots.add(join23(env2["CODEX_HOME"], "sessions"));
|
|
80696
|
+
roots.add(join23(home, ".codex", "sessions"));
|
|
80433
80697
|
return [...roots];
|
|
80434
80698
|
}
|
|
80435
80699
|
function readCodexRolloutIdentity(path3) {
|
|
@@ -80501,10 +80765,10 @@ function codexRolloutsForCwd(cwd, opts = {}) {
|
|
|
80501
80765
|
continue;
|
|
80502
80766
|
}
|
|
80503
80767
|
for (const name2 of names) {
|
|
80504
|
-
const full =
|
|
80768
|
+
const full = join23(dir, name2);
|
|
80505
80769
|
let st;
|
|
80506
80770
|
try {
|
|
80507
|
-
st =
|
|
80771
|
+
st = statSync9(full);
|
|
80508
80772
|
} catch {
|
|
80509
80773
|
continue;
|
|
80510
80774
|
}
|
|
@@ -80543,8 +80807,8 @@ function codexRolloutsForCwd(cwd, opts = {}) {
|
|
|
80543
80807
|
function geminiSessionRoots(env2 = process.env, home = homedir4()) {
|
|
80544
80808
|
const roots = /* @__PURE__ */ new Set();
|
|
80545
80809
|
for (const d of splitPathList(env2["ERRATA_GEMINI_SESSIONS_DIRS"])) roots.add(d);
|
|
80546
|
-
if (env2["GEMINI_CLI_HOME"]) roots.add(
|
|
80547
|
-
roots.add(
|
|
80810
|
+
if (env2["GEMINI_CLI_HOME"]) roots.add(join23(env2["GEMINI_CLI_HOME"], ".gemini", "tmp"));
|
|
80811
|
+
roots.add(join23(home, ".gemini", "tmp"));
|
|
80548
80812
|
return [...roots];
|
|
80549
80813
|
}
|
|
80550
80814
|
function geminiProjectHash(cwd) {
|
|
@@ -80592,7 +80856,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
|
|
|
80592
80856
|
continue;
|
|
80593
80857
|
}
|
|
80594
80858
|
for (const slug2 of slugs) {
|
|
80595
|
-
const chats =
|
|
80859
|
+
const chats = join23(root, slug2, "chats");
|
|
80596
80860
|
let names;
|
|
80597
80861
|
try {
|
|
80598
80862
|
names = readdirSync7(chats);
|
|
@@ -80601,10 +80865,10 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
|
|
|
80601
80865
|
}
|
|
80602
80866
|
for (const name2 of names) {
|
|
80603
80867
|
if (!name2.startsWith("session-") || !name2.endsWith(".jsonl")) continue;
|
|
80604
|
-
const full =
|
|
80868
|
+
const full = join23(chats, name2);
|
|
80605
80869
|
let st;
|
|
80606
80870
|
try {
|
|
80607
|
-
st =
|
|
80871
|
+
st = statSync9(full);
|
|
80608
80872
|
} catch {
|
|
80609
80873
|
continue;
|
|
80610
80874
|
}
|
|
@@ -80621,8 +80885,8 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
|
|
|
80621
80885
|
function opencodeSessionRoots(env2 = process.env, home = homedir4()) {
|
|
80622
80886
|
const roots = /* @__PURE__ */ new Set();
|
|
80623
80887
|
for (const d of splitPathList(env2["ERRATA_OPENCODE_SESSIONS_DIRS"])) roots.add(d);
|
|
80624
|
-
if (env2["XDG_DATA_HOME"]) roots.add(
|
|
80625
|
-
roots.add(
|
|
80888
|
+
if (env2["XDG_DATA_HOME"]) roots.add(join23(env2["XDG_DATA_HOME"], "opencode", "errata"));
|
|
80889
|
+
roots.add(join23(home, ".local", "share", "opencode", "errata"));
|
|
80626
80890
|
return [...roots];
|
|
80627
80891
|
}
|
|
80628
80892
|
function readOpencodeTranscriptDirectory(path3) {
|
|
@@ -80664,10 +80928,10 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
|
|
|
80664
80928
|
}
|
|
80665
80929
|
for (const name2 of names) {
|
|
80666
80930
|
if (!name2.endsWith(".jsonl")) continue;
|
|
80667
|
-
const full =
|
|
80931
|
+
const full = join23(root, name2);
|
|
80668
80932
|
let st;
|
|
80669
80933
|
try {
|
|
80670
|
-
st =
|
|
80934
|
+
st = statSync9(full);
|
|
80671
80935
|
} catch {
|
|
80672
80936
|
continue;
|
|
80673
80937
|
}
|
|
@@ -80687,7 +80951,7 @@ init_src2();
|
|
|
80687
80951
|
init_agent_signals();
|
|
80688
80952
|
init_tool_index();
|
|
80689
80953
|
init_src5();
|
|
80690
|
-
import { readFileSync as
|
|
80954
|
+
import { readFileSync as readFileSync19, writeFileSync as writeFileSync15 } from "node:fs";
|
|
80691
80955
|
var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
|
|
80692
80956
|
var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
|
|
80693
80957
|
var HANDLE_RE2 = new RegExp(TAG_HANDLE_SOURCE, "gi");
|
|
@@ -81487,13 +81751,13 @@ function writePrimingHandles(path3, nodes, now = Date.now()) {
|
|
|
81487
81751
|
entries.sort((a, b) => (b[1].seenAt ?? 0) - (a[1].seenAt ?? 0));
|
|
81488
81752
|
entries.length = HANDLE_MAP_MAX;
|
|
81489
81753
|
}
|
|
81490
|
-
|
|
81754
|
+
writeFileSync15(path3, JSON.stringify(Object.fromEntries(entries)));
|
|
81491
81755
|
} catch {
|
|
81492
81756
|
}
|
|
81493
81757
|
}
|
|
81494
81758
|
function readPrimingHandles(path3) {
|
|
81495
81759
|
try {
|
|
81496
|
-
return JSON.parse(
|
|
81760
|
+
return JSON.parse(readFileSync19(path3, "utf8"));
|
|
81497
81761
|
} catch {
|
|
81498
81762
|
return {};
|
|
81499
81763
|
}
|
|
@@ -81982,8 +82246,8 @@ ${conversation}` }]
|
|
|
81982
82246
|
// src/constraint-backfill.ts
|
|
81983
82247
|
init_src5();
|
|
81984
82248
|
init_src2();
|
|
81985
|
-
import { existsSync as existsSync20, readFileSync as
|
|
81986
|
-
import { join as
|
|
82249
|
+
import { existsSync as existsSync20, readFileSync as readFileSync20, readdirSync as readdirSync8, writeFileSync as writeFileSync16 } from "node:fs";
|
|
82250
|
+
import { join as join24 } from "node:path";
|
|
81987
82251
|
import { homedir as homedir5 } from "node:os";
|
|
81988
82252
|
var BACKFILL_VERSION = 1;
|
|
81989
82253
|
var EMPTY = {
|
|
@@ -81997,13 +82261,13 @@ var EMPTY = {
|
|
|
81997
82261
|
recoverable: 0
|
|
81998
82262
|
};
|
|
81999
82263
|
function markerPath(configDir) {
|
|
82000
|
-
return
|
|
82264
|
+
return join24(configDir, "constraint-backfill.json");
|
|
82001
82265
|
}
|
|
82002
82266
|
function alreadyDone(configDir) {
|
|
82003
82267
|
const p = markerPath(configDir);
|
|
82004
82268
|
if (!existsSync20(p)) return false;
|
|
82005
82269
|
try {
|
|
82006
|
-
const raw2 = JSON.parse(
|
|
82270
|
+
const raw2 = JSON.parse(readFileSync20(p, "utf8"));
|
|
82007
82271
|
return raw2?.version === BACKFILL_VERSION;
|
|
82008
82272
|
} catch {
|
|
82009
82273
|
return false;
|
|
@@ -82023,7 +82287,7 @@ function replay(root) {
|
|
|
82023
82287
|
for (const f of names) {
|
|
82024
82288
|
let lines;
|
|
82025
82289
|
try {
|
|
82026
|
-
lines =
|
|
82290
|
+
lines = readFileSync20(join24(dir, f), "utf8").split("\n");
|
|
82027
82291
|
} catch {
|
|
82028
82292
|
continue;
|
|
82029
82293
|
}
|
|
@@ -82137,7 +82401,7 @@ function backfillConstraintKind(store, opts) {
|
|
|
82137
82401
|
}
|
|
82138
82402
|
});
|
|
82139
82403
|
try {
|
|
82140
|
-
|
|
82404
|
+
writeFileSync16(
|
|
82141
82405
|
markerPath(opts.configDir),
|
|
82142
82406
|
JSON.stringify({ version: BACKFILL_VERSION, at: opts.now, ...report, cloudTwins: report.cloudTwins.length }, null, 2),
|
|
82143
82407
|
"utf8"
|
|
@@ -82150,8 +82414,8 @@ function backfillConstraintKind(store, opts) {
|
|
|
82150
82414
|
// src/edge-repair.ts
|
|
82151
82415
|
init_src();
|
|
82152
82416
|
init_src5();
|
|
82153
|
-
import { existsSync as existsSync21, readFileSync as
|
|
82154
|
-
import { join as
|
|
82417
|
+
import { existsSync as existsSync21, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "node:fs";
|
|
82418
|
+
import { join as join25 } from "node:path";
|
|
82155
82419
|
function citeEdgeId(from, type, to) {
|
|
82156
82420
|
return `edge_${digest({ from, type, to })}`.slice(0, 24);
|
|
82157
82421
|
}
|
|
@@ -82166,13 +82430,13 @@ var EMPTY2 = {
|
|
|
82166
82430
|
byType: {}
|
|
82167
82431
|
};
|
|
82168
82432
|
function markerPath2(configDir) {
|
|
82169
|
-
return
|
|
82433
|
+
return join25(configDir, "edge-repair.json");
|
|
82170
82434
|
}
|
|
82171
82435
|
function alreadyDone2(configDir) {
|
|
82172
82436
|
const p = markerPath2(configDir);
|
|
82173
82437
|
if (!existsSync21(p)) return false;
|
|
82174
82438
|
try {
|
|
82175
|
-
return JSON.parse(
|
|
82439
|
+
return JSON.parse(readFileSync21(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
|
|
82176
82440
|
} catch {
|
|
82177
82441
|
return false;
|
|
82178
82442
|
}
|
|
@@ -82221,7 +82485,7 @@ function repairInvalidEdges(store, opts) {
|
|
|
82221
82485
|
});
|
|
82222
82486
|
store.pruneEdgeRejections(opts.now - REJECTION_RETENTION_MS);
|
|
82223
82487
|
try {
|
|
82224
|
-
|
|
82488
|
+
writeFileSync17(
|
|
82225
82489
|
markerPath2(opts.configDir),
|
|
82226
82490
|
JSON.stringify({ version: EDGE_REPAIR_VERSION, at: opts.now, ...report }, null, 2),
|
|
82227
82491
|
"utf8"
|
|
@@ -82235,8 +82499,8 @@ function repairInvalidEdges(store, opts) {
|
|
|
82235
82499
|
init_reconcile();
|
|
82236
82500
|
|
|
82237
82501
|
// src/pass-ledger.ts
|
|
82238
|
-
import { appendFileSync as appendFileSync2, existsSync as existsSync22, readFileSync as
|
|
82239
|
-
import { join as
|
|
82502
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync22, readFileSync as readFileSync22, writeFileSync as writeFileSync18 } from "node:fs";
|
|
82503
|
+
import { join as join26 } from "node:path";
|
|
82240
82504
|
|
|
82241
82505
|
// src/isolate-census.ts
|
|
82242
82506
|
var live2 = 0;
|
|
@@ -82254,6 +82518,11 @@ function isolateCensus() {
|
|
|
82254
82518
|
return { live: live2, spawnedTotal, peak };
|
|
82255
82519
|
}
|
|
82256
82520
|
|
|
82521
|
+
// src/io-reads.ts
|
|
82522
|
+
function ioReadOps() {
|
|
82523
|
+
return process.resourceUsage().fsRead;
|
|
82524
|
+
}
|
|
82525
|
+
|
|
82257
82526
|
// src/pass-ledger.ts
|
|
82258
82527
|
var PER_KIND_MAX = 100;
|
|
82259
82528
|
var LEVEL_TAIL_KINDS = /* @__PURE__ */ new Set(["wm-calibration"]);
|
|
@@ -82262,7 +82531,7 @@ var HOUR_MS = 36e5;
|
|
|
82262
82531
|
var TRIM_EVERY = 50;
|
|
82263
82532
|
var appendsSinceTrim = /* @__PURE__ */ new Map();
|
|
82264
82533
|
function passLedgerPath(configDir) {
|
|
82265
|
-
return
|
|
82534
|
+
return join26(configDir, "pass-ledger.jsonl");
|
|
82266
82535
|
}
|
|
82267
82536
|
function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
82268
82537
|
const path3 = passLedgerPath(configDir);
|
|
@@ -82281,7 +82550,10 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
|
82281
82550
|
arrayBuffersMB: Math.round(mem.arrayBuffers / 1048576),
|
|
82282
82551
|
isolatesLive: census2.live,
|
|
82283
82552
|
isolatesSpawned: census2.spawnedTotal,
|
|
82284
|
-
isolatesPeak: census2.peak
|
|
82553
|
+
isolatesPeak: census2.peak,
|
|
82554
|
+
// Cumulative process-wide file reads (io-reads.ts): the difference
|
|
82555
|
+
// between two rows is what ran between them.
|
|
82556
|
+
ioReadOps: ioReadOps()
|
|
82285
82557
|
}
|
|
82286
82558
|
};
|
|
82287
82559
|
appendFileSync2(path3, JSON.stringify(entry) + "\n");
|
|
@@ -82291,7 +82563,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
|
82291
82563
|
return;
|
|
82292
82564
|
}
|
|
82293
82565
|
appendsSinceTrim.set(path3, 0);
|
|
82294
|
-
const lines =
|
|
82566
|
+
const lines = readFileSync22(path3, "utf8").split("\n").filter(Boolean);
|
|
82295
82567
|
const keptByKind = /* @__PURE__ */ new Map();
|
|
82296
82568
|
const tailHours = /* @__PURE__ */ new Map();
|
|
82297
82569
|
const tailFloor = Date.now() - LEVEL_TAIL_DAYS * 24 * HOUR_MS;
|
|
@@ -82319,7 +82591,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
|
82319
82591
|
kept.push(lines[i2]);
|
|
82320
82592
|
}
|
|
82321
82593
|
if (kept.length < lines.length) {
|
|
82322
|
-
|
|
82594
|
+
writeFileSync18(path3, kept.reverse().join("\n") + "\n");
|
|
82323
82595
|
}
|
|
82324
82596
|
} catch {
|
|
82325
82597
|
}
|
|
@@ -82328,7 +82600,7 @@ function readPassLedger(configDir) {
|
|
|
82328
82600
|
const path3 = passLedgerPath(configDir);
|
|
82329
82601
|
if (!existsSync22(path3)) return [];
|
|
82330
82602
|
try {
|
|
82331
|
-
return
|
|
82603
|
+
return readFileSync22(path3, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
|
|
82332
82604
|
(e) => typeof e?.ts === "number" && typeof e?.kind === "string" && typeof e?.durationMs === "number"
|
|
82333
82605
|
).map((e) => ({ ...e, counts: e.counts ?? {} }));
|
|
82334
82606
|
} catch {
|
|
@@ -82575,6 +82847,7 @@ function withHeavyPassSlot(label, fn) {
|
|
|
82575
82847
|
const waited = Date.now() - queuedAt;
|
|
82576
82848
|
waiting.delete(id);
|
|
82577
82849
|
const startedAt = Date.now();
|
|
82850
|
+
const readsAtStart = ioReadOps();
|
|
82578
82851
|
active = { label, startedAt, waitedMs: waited };
|
|
82579
82852
|
if (waited > QUEUE_WARN_MS) {
|
|
82580
82853
|
console.warn(`[errata] heavy-pass slot: ${label} waited ${Math.round(waited / 1e3)}s`);
|
|
@@ -82586,7 +82859,7 @@ function withHeavyPassSlot(label, fn) {
|
|
|
82586
82859
|
failed = true;
|
|
82587
82860
|
throw err2;
|
|
82588
82861
|
} finally {
|
|
82589
|
-
recent2.push({ label, waitedMs: waited, durationMs: Date.now() - startedAt, failed });
|
|
82862
|
+
recent2.push({ label, waitedMs: waited, durationMs: Date.now() - startedAt, readOps: ioReadOps() - readsAtStart, failed });
|
|
82590
82863
|
if (recent2.length > 16) recent2.shift();
|
|
82591
82864
|
active = null;
|
|
82592
82865
|
}
|
|
@@ -82739,11 +83012,11 @@ init_outbox();
|
|
|
82739
83012
|
init_src10();
|
|
82740
83013
|
init_src();
|
|
82741
83014
|
init_src2();
|
|
82742
|
-
import { readFileSync as
|
|
82743
|
-
import { join as
|
|
83015
|
+
import { readFileSync as readFileSync23 } from "node:fs";
|
|
83016
|
+
import { join as join27 } from "node:path";
|
|
82744
83017
|
function loadClaimIgnorePatterns(workspaceRoot) {
|
|
82745
83018
|
try {
|
|
82746
|
-
return
|
|
83019
|
+
return readFileSync23(join27(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
|
|
82747
83020
|
} catch {
|
|
82748
83021
|
return [];
|
|
82749
83022
|
}
|
|
@@ -83126,9 +83399,9 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
|
|
|
83126
83399
|
// src/retrieval-stack.ts
|
|
83127
83400
|
init_src();
|
|
83128
83401
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
83129
|
-
import { existsSync as existsSync23, readFileSync as
|
|
83402
|
+
import { existsSync as existsSync23, readFileSync as readFileSync24, statSync as statSync10 } from "node:fs";
|
|
83130
83403
|
import { homedir as homedir6 } from "node:os";
|
|
83131
|
-
import { join as
|
|
83404
|
+
import { join as join28 } from "node:path";
|
|
83132
83405
|
var RETRIEVAL_STACK_CAP = 24;
|
|
83133
83406
|
var MANIFEST_SCAN_CAP = 400;
|
|
83134
83407
|
var RUNTIME_TOKENS = /* @__PURE__ */ new Set([
|
|
@@ -83418,51 +83691,51 @@ function mavenGroupIsSelfDisclosing(name2, selfTokens) {
|
|
|
83418
83691
|
function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
|
|
83419
83692
|
const read2 = (p) => {
|
|
83420
83693
|
try {
|
|
83421
|
-
return
|
|
83694
|
+
return readFileSync24(p, "utf8");
|
|
83422
83695
|
} catch {
|
|
83423
83696
|
return null;
|
|
83424
83697
|
}
|
|
83425
83698
|
};
|
|
83426
83699
|
const texts = (...paths) => paths.map(read2).filter((t) => t !== null);
|
|
83427
83700
|
const home = homedir6();
|
|
83428
|
-
const npm = parseNpmrcPolicy(texts(
|
|
83701
|
+
const npm = parseNpmrcPolicy(texts(join28(root, ".npmrc"), join28(home, ".npmrc")));
|
|
83429
83702
|
const blocked = /* @__PURE__ */ new Set();
|
|
83430
83703
|
if (!npm.defaultPublic) blocked.add("npm");
|
|
83431
83704
|
if (pypiIndexIsPrivate(
|
|
83432
83705
|
texts(
|
|
83433
|
-
|
|
83434
|
-
|
|
83435
|
-
|
|
83436
|
-
|
|
83437
|
-
|
|
83438
|
-
|
|
83439
|
-
|
|
83706
|
+
join28(root, "pip.conf"),
|
|
83707
|
+
join28(root, "pip.ini"),
|
|
83708
|
+
join28(root, "pyproject.toml"),
|
|
83709
|
+
join28(root, "requirements.txt"),
|
|
83710
|
+
join28(home, ".pip", "pip.conf"),
|
|
83711
|
+
join28(home, ".config", "pip", "pip.conf"),
|
|
83712
|
+
join28(env2["APPDATA"] ?? home, "pip", "pip.ini")
|
|
83440
83713
|
)
|
|
83441
83714
|
)) {
|
|
83442
83715
|
blocked.add("pypi");
|
|
83443
83716
|
}
|
|
83444
83717
|
if (cargoRegistryIsPrivate(
|
|
83445
83718
|
texts(
|
|
83446
|
-
|
|
83447
|
-
|
|
83448
|
-
|
|
83449
|
-
|
|
83719
|
+
join28(root, ".cargo", "config.toml"),
|
|
83720
|
+
join28(root, ".cargo", "config"),
|
|
83721
|
+
join28(home, ".cargo", "config.toml"),
|
|
83722
|
+
join28(home, ".cargo", "config")
|
|
83450
83723
|
)
|
|
83451
83724
|
)) {
|
|
83452
83725
|
blocked.add("cargo");
|
|
83453
83726
|
}
|
|
83454
83727
|
if (nugetSourcesArePrivate(
|
|
83455
83728
|
texts(
|
|
83456
|
-
|
|
83457
|
-
|
|
83458
|
-
|
|
83459
|
-
|
|
83460
|
-
|
|
83729
|
+
join28(root, "NuGet.config"),
|
|
83730
|
+
join28(root, "nuget.config"),
|
|
83731
|
+
join28(root, "NuGet.Config"),
|
|
83732
|
+
join28(env2["APPDATA"] ?? home, "NuGet", "NuGet.Config"),
|
|
83733
|
+
join28(home, ".nuget", "NuGet", "NuGet.Config")
|
|
83461
83734
|
)
|
|
83462
83735
|
)) {
|
|
83463
83736
|
blocked.add("nuget");
|
|
83464
83737
|
}
|
|
83465
|
-
const goEnvFile = env2["GOENV"] ??
|
|
83738
|
+
const goEnvFile = env2["GOENV"] ?? join28(env2["APPDATA"] ?? join28(home, ".config"), "go", "env");
|
|
83466
83739
|
const goEnvText = read2(goEnvFile) ?? "";
|
|
83467
83740
|
const fromFile = ["GOPRIVATE", "GONOSUMDB", "GONOSUMCHECK"].map(
|
|
83468
83741
|
(k) => new RegExp(`^${k}=(.*)$`, "m").exec(goEnvText)?.[1]
|
|
@@ -83473,10 +83746,10 @@ function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
|
|
|
83473
83746
|
env2["GONOSUMCHECK"],
|
|
83474
83747
|
...fromFile
|
|
83475
83748
|
]);
|
|
83476
|
-
const gemfiles = texts(
|
|
83749
|
+
const gemfiles = texts(join28(root, "Gemfile"));
|
|
83477
83750
|
if (gemSourceIsPrivate(gemfiles)) blocked.add("gem");
|
|
83478
83751
|
if (mavenReposArePrivate(
|
|
83479
|
-
texts(
|
|
83752
|
+
texts(join28(root, "pom.xml"), join28(home, ".m2", "settings.xml"))
|
|
83480
83753
|
)) {
|
|
83481
83754
|
blocked.add("maven");
|
|
83482
83755
|
}
|
|
@@ -83643,10 +83916,10 @@ function readDirectDependencies(root) {
|
|
|
83643
83916
|
const familiesSeen = /* @__PURE__ */ new Set();
|
|
83644
83917
|
for (const c of LOCKFILES) {
|
|
83645
83918
|
if (familiesSeen.has(c.family)) continue;
|
|
83646
|
-
const p =
|
|
83919
|
+
const p = join28(root, c.file);
|
|
83647
83920
|
if (!existsSync23(p)) continue;
|
|
83648
83921
|
try {
|
|
83649
|
-
const s =
|
|
83922
|
+
const s = statSync10(p);
|
|
83650
83923
|
stamps.push(`${c.file}:${s.mtimeMs}:${s.size}`);
|
|
83651
83924
|
} catch {
|
|
83652
83925
|
continue;
|
|
@@ -83664,7 +83937,7 @@ function readDirectDependencies(root) {
|
|
|
83664
83937
|
const direct = [];
|
|
83665
83938
|
for (const { c, path: path3 } of found) {
|
|
83666
83939
|
try {
|
|
83667
|
-
direct.push(...c.parse(
|
|
83940
|
+
direct.push(...c.parse(readFileSync24(path3, "utf8")).direct ?? []);
|
|
83668
83941
|
} catch {
|
|
83669
83942
|
}
|
|
83670
83943
|
}
|
|
@@ -83707,14 +83980,14 @@ function manifestPaths(root) {
|
|
|
83707
83980
|
"project.godot"
|
|
83708
83981
|
];
|
|
83709
83982
|
return {
|
|
83710
|
-
paths: ROOT_MANIFESTS.filter((f) => existsSync23(
|
|
83983
|
+
paths: ROOT_MANIFESTS.filter((f) => existsSync23(join28(root, f))),
|
|
83711
83984
|
tracked: false,
|
|
83712
83985
|
truncated: false
|
|
83713
83986
|
};
|
|
83714
83987
|
}
|
|
83715
83988
|
var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
|
|
83716
83989
|
function rootDeclaresWorkspace(root, texts) {
|
|
83717
|
-
if (WORKSPACE_MARKERS.some((f) => existsSync23(
|
|
83990
|
+
if (WORKSPACE_MARKERS.some((f) => existsSync23(join28(root, f)))) return true;
|
|
83718
83991
|
return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
|
|
83719
83992
|
}
|
|
83720
83993
|
var EMPTY_SCAN = { deps: [], self: [], complete: true };
|
|
@@ -83728,11 +84001,11 @@ function scanManifests(root) {
|
|
|
83728
84001
|
const texts = /* @__PURE__ */ new Map();
|
|
83729
84002
|
const stamps = [];
|
|
83730
84003
|
for (const rel of paths) {
|
|
83731
|
-
const abs =
|
|
84004
|
+
const abs = join28(root, rel);
|
|
83732
84005
|
try {
|
|
83733
|
-
const s =
|
|
84006
|
+
const s = statSync10(abs);
|
|
83734
84007
|
stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
|
|
83735
|
-
texts.set(rel,
|
|
84008
|
+
texts.set(rel, readFileSync24(abs, "utf8"));
|
|
83736
84009
|
} catch {
|
|
83737
84010
|
}
|
|
83738
84011
|
}
|
|
@@ -83768,22 +84041,22 @@ function readRetrievalInputs(root, repoLocator) {
|
|
|
83768
84041
|
}
|
|
83769
84042
|
|
|
83770
84043
|
// src/git-sensor.ts
|
|
83771
|
-
import { existsSync as existsSync24, readFileSync as
|
|
83772
|
-
import { join as
|
|
84044
|
+
import { existsSync as existsSync24, readFileSync as readFileSync25, watch as fsWatch } from "node:fs";
|
|
84045
|
+
import { join as join29 } from "node:path";
|
|
83773
84046
|
function readFirstLine(path3) {
|
|
83774
84047
|
try {
|
|
83775
|
-
return
|
|
84048
|
+
return readFileSync25(path3, "utf8").split(/\r?\n/, 1)[0].trim();
|
|
83776
84049
|
} catch {
|
|
83777
84050
|
return null;
|
|
83778
84051
|
}
|
|
83779
84052
|
}
|
|
83780
84053
|
function readGitRefState(gitDir) {
|
|
83781
|
-
const head2 = readFirstLine(
|
|
84054
|
+
const head2 = readFirstLine(join29(gitDir, "HEAD"));
|
|
83782
84055
|
const m = head2 ? /^ref:\s*refs\/heads\/(.+)$/.exec(head2) : null;
|
|
83783
84056
|
const branch = m ? m[1] : null;
|
|
83784
84057
|
let sha2 = null;
|
|
83785
84058
|
if (branch) {
|
|
83786
|
-
sha2 = readFirstLine(
|
|
84059
|
+
sha2 = readFirstLine(join29(gitDir, "refs", "heads", branch));
|
|
83787
84060
|
if (!sha2) sha2 = shaFromPackedRefs(gitDir, `refs/heads/${branch}`);
|
|
83788
84061
|
} else if (head2 && /^[0-9a-f]{7,40}$/i.test(head2)) {
|
|
83789
84062
|
sha2 = head2;
|
|
@@ -83791,13 +84064,13 @@ function readGitRefState(gitDir) {
|
|
|
83791
84064
|
return {
|
|
83792
84065
|
branch,
|
|
83793
84066
|
sha: sha2,
|
|
83794
|
-
mergeHeadExists: existsSync24(
|
|
83795
|
-
origHeadExists: existsSync24(
|
|
84067
|
+
mergeHeadExists: existsSync24(join29(gitDir, "MERGE_HEAD")),
|
|
84068
|
+
origHeadExists: existsSync24(join29(gitDir, "ORIG_HEAD"))
|
|
83796
84069
|
};
|
|
83797
84070
|
}
|
|
83798
84071
|
function shaFromPackedRefs(gitDir, ref) {
|
|
83799
84072
|
try {
|
|
83800
|
-
for (const line of
|
|
84073
|
+
for (const line of readFileSync25(join29(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
|
|
83801
84074
|
const [sha2, name2] = line.split(/\s+/);
|
|
83802
84075
|
if (name2 === ref && sha2) return sha2;
|
|
83803
84076
|
}
|
|
@@ -83831,7 +84104,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
83831
84104
|
const settle = () => {
|
|
83832
84105
|
if (timer) clearTimeout(timer);
|
|
83833
84106
|
timer = setTimeout(() => {
|
|
83834
|
-
if (existsSync24(
|
|
84107
|
+
if (existsSync24(join29(gitDir, "index.lock"))) {
|
|
83835
84108
|
settle();
|
|
83836
84109
|
return;
|
|
83837
84110
|
}
|
|
@@ -83842,7 +84115,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
83842
84115
|
}, debounceMs);
|
|
83843
84116
|
};
|
|
83844
84117
|
for (const sub of ["HEAD", "logs/HEAD", "MERGE_HEAD", "ORIG_HEAD"]) {
|
|
83845
|
-
const p =
|
|
84118
|
+
const p = join29(gitDir, sub);
|
|
83846
84119
|
try {
|
|
83847
84120
|
watchers.push(fsWatch(p, settle));
|
|
83848
84121
|
} catch {
|
|
@@ -84072,8 +84345,8 @@ var TelemetryRecorder = class {
|
|
|
84072
84345
|
};
|
|
84073
84346
|
|
|
84074
84347
|
// src/file-activity.ts
|
|
84075
|
-
import { readFileSync as
|
|
84076
|
-
import { join as
|
|
84348
|
+
import { readFileSync as readFileSync27 } from "node:fs";
|
|
84349
|
+
import { join as join31 } from "node:path";
|
|
84077
84350
|
import { createHash as createHash17 } from "node:crypto";
|
|
84078
84351
|
|
|
84079
84352
|
// ../../packages/privacy/src/patterns/credentials.ts
|
|
@@ -84825,8 +85098,8 @@ init_git_remote();
|
|
|
84825
85098
|
// src/history-bundle.ts
|
|
84826
85099
|
init_src();
|
|
84827
85100
|
import { execFile as execFile2 } from "node:child_process";
|
|
84828
|
-
import { readFileSync as
|
|
84829
|
-
import { join as
|
|
85101
|
+
import { readFileSync as readFileSync26 } from "node:fs";
|
|
85102
|
+
import { join as join30 } from "node:path";
|
|
84830
85103
|
var DEFAULT_MAX_TOKENS = 6e3;
|
|
84831
85104
|
var FILE_LIST_CAP = 60;
|
|
84832
85105
|
var DIFF_FILE_CAP = 40;
|
|
@@ -84865,7 +85138,7 @@ function pathAllowedByFloor(path3) {
|
|
|
84865
85138
|
function loadRepoIgnore(root, extraPatterns = []) {
|
|
84866
85139
|
let source = "";
|
|
84867
85140
|
try {
|
|
84868
|
-
source =
|
|
85141
|
+
source = readFileSync26(join30(root, ".errataignore"), "utf8");
|
|
84869
85142
|
} catch {
|
|
84870
85143
|
source = "";
|
|
84871
85144
|
}
|
|
@@ -85040,24 +85313,28 @@ function headerPaths(diff) {
|
|
|
85040
85313
|
}
|
|
85041
85314
|
return out2.filter((p) => p !== "/dev/null");
|
|
85042
85315
|
}
|
|
85043
|
-
|
|
85316
|
+
var GIT_MAX_BUFFER = 64 * 1024 * 1024;
|
|
85317
|
+
function git2(repoDir, args2, maxBuffer = GIT_MAX_BUFFER) {
|
|
85044
85318
|
return new Promise((resolve10, reject) => {
|
|
85045
85319
|
execFile2(
|
|
85046
85320
|
"git",
|
|
85047
85321
|
["-C", repoDir, ...args2],
|
|
85048
|
-
{ encoding: "utf8", maxBuffer
|
|
85322
|
+
{ encoding: "utf8", maxBuffer, windowsHide: true },
|
|
85049
85323
|
(err2, stdout) => err2 ? reject(err2) : resolve10(stdout)
|
|
85050
85324
|
);
|
|
85051
85325
|
});
|
|
85052
85326
|
}
|
|
85053
|
-
async function unitDiff(root, unit, paths) {
|
|
85327
|
+
async function unitDiff(root, unit, paths, maxChars = GIT_MAX_BUFFER) {
|
|
85054
85328
|
if (paths.length === 0) return "";
|
|
85055
85329
|
const common = ["--unified=3", "--no-color", "-M", "--no-ext-diff"];
|
|
85056
85330
|
const firstParent = unit.parents[0];
|
|
85057
|
-
|
|
85058
|
-
|
|
85331
|
+
const args2 = unit.isMerge && firstParent ? ["diff", ...common, firstParent, unit.sha, "--", ...paths] : ["show", "--format=", ...common, unit.sha, "--", ...paths];
|
|
85332
|
+
try {
|
|
85333
|
+
return await git2(root, args2, maxChars);
|
|
85334
|
+
} catch (err2) {
|
|
85335
|
+
if (err2.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER" && maxChars < GIT_MAX_BUFFER) return null;
|
|
85336
|
+
throw err2;
|
|
85059
85337
|
}
|
|
85060
|
-
return git2(root, ["show", "--format=", ...common, unit.sha, "--", ...paths]);
|
|
85061
85338
|
}
|
|
85062
85339
|
function fileRow(token, f) {
|
|
85063
85340
|
const tag = f.binary ? "bin" : `+${f.adds}/-${f.dels}`;
|
|
@@ -85094,7 +85371,9 @@ async function buildUnitBundle(root, unit, opts = {}) {
|
|
|
85094
85371
|
const sourceFiles = ordered.filter(isSourceFile);
|
|
85095
85372
|
const diffPaths = sourceFiles.slice(0, DIFF_FILE_CAP).map((f) => f.path);
|
|
85096
85373
|
if (sourceFiles.length > DIFF_FILE_CAP) truncated = true;
|
|
85097
|
-
const
|
|
85374
|
+
const cappedDiff = await unitDiff(root, unit, diffPaths, opts.maxRawDiffChars);
|
|
85375
|
+
if (cappedDiff === null) truncated = true;
|
|
85376
|
+
const rawDiff = cappedDiff ?? "";
|
|
85098
85377
|
for (const p of headerPaths(rawDiff)) tokens.token(p);
|
|
85099
85378
|
const narrativeRaw = opts.narrative ?? [unit.subject.trim(), stripTrailers(unit.body)].filter((s) => s.length > 0).join("\n\n");
|
|
85100
85379
|
const n = scrubHistoryText(tokens.apply(stripTrailers(narrativeRaw)));
|
|
@@ -85164,7 +85443,7 @@ function readActivityBranch(root) {
|
|
|
85164
85443
|
try {
|
|
85165
85444
|
const gitDir = resolveGitDir(root);
|
|
85166
85445
|
if (!gitDir) return null;
|
|
85167
|
-
const head2 =
|
|
85446
|
+
const head2 = readFileSync27(join31(gitDir, "HEAD"), "utf8").trim();
|
|
85168
85447
|
const branch = head2.startsWith("ref: refs/heads/") ? head2.slice(16) : /^[a-f0-9]{40,64}$/i.test(head2) ? "HEAD" : null;
|
|
85169
85448
|
return branch && branch.length <= 256 && !/[\x00-\x1f\x7f]/.test(branch) ? branch : null;
|
|
85170
85449
|
} catch {
|
|
@@ -85323,19 +85602,19 @@ var FileActivityReporter = class {
|
|
|
85323
85602
|
import {
|
|
85324
85603
|
existsSync as existsSync25,
|
|
85325
85604
|
mkdirSync as mkdirSync7,
|
|
85326
|
-
readFileSync as
|
|
85605
|
+
readFileSync as readFileSync28,
|
|
85327
85606
|
readdirSync as readdirSync9,
|
|
85328
85607
|
unlinkSync as unlinkSync4,
|
|
85329
|
-
writeFileSync as
|
|
85608
|
+
writeFileSync as writeFileSync19
|
|
85330
85609
|
} from "node:fs";
|
|
85331
|
-
import { basename as basename7, join as
|
|
85610
|
+
import { basename as basename7, join as join32 } from "node:path";
|
|
85332
85611
|
function skillFileName(id) {
|
|
85333
85612
|
return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
|
|
85334
85613
|
}
|
|
85335
85614
|
function readSkillManifest(manifestPath) {
|
|
85336
85615
|
if (!existsSync25(manifestPath)) return [];
|
|
85337
85616
|
try {
|
|
85338
|
-
const parsed = JSON.parse(
|
|
85617
|
+
const parsed = JSON.parse(readFileSync28(manifestPath, "utf8"));
|
|
85339
85618
|
return (parsed.skills ?? []).map((s) => ({
|
|
85340
85619
|
title: s.title ?? "",
|
|
85341
85620
|
layer: s.layer ?? "technique",
|
|
@@ -85359,7 +85638,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
85359
85638
|
for (const s of res.skills) {
|
|
85360
85639
|
const fileName = skillFileName(s.id);
|
|
85361
85640
|
keep.add(fileName);
|
|
85362
|
-
|
|
85641
|
+
writeFileSync19(join32(paths.skillsDir, fileName), s.markdown, "utf8");
|
|
85363
85642
|
rows.push({
|
|
85364
85643
|
id: s.id,
|
|
85365
85644
|
title: s.title,
|
|
@@ -85372,7 +85651,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
85372
85651
|
const fileName = skillFileName(p.id);
|
|
85373
85652
|
if (keep.has(fileName)) continue;
|
|
85374
85653
|
keep.add(fileName);
|
|
85375
|
-
|
|
85654
|
+
writeFileSync19(join32(paths.skillsDir, fileName), p.markdown, "utf8");
|
|
85376
85655
|
rows.push({
|
|
85377
85656
|
id: p.id,
|
|
85378
85657
|
title: p.title,
|
|
@@ -85386,13 +85665,13 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
85386
85665
|
if (!f.endsWith(".md")) continue;
|
|
85387
85666
|
if (keep.has(basename7(f))) continue;
|
|
85388
85667
|
try {
|
|
85389
|
-
unlinkSync4(
|
|
85668
|
+
unlinkSync4(join32(paths.skillsDir, f));
|
|
85390
85669
|
pruned++;
|
|
85391
85670
|
} catch {
|
|
85392
85671
|
}
|
|
85393
85672
|
}
|
|
85394
85673
|
rows.sort((a, b) => a.id.localeCompare(b.id));
|
|
85395
|
-
|
|
85674
|
+
writeFileSync19(
|
|
85396
85675
|
paths.skillsManifest,
|
|
85397
85676
|
JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
|
|
85398
85677
|
"utf8"
|
|
@@ -85407,19 +85686,19 @@ import {
|
|
|
85407
85686
|
existsSync as existsSync26,
|
|
85408
85687
|
lstatSync,
|
|
85409
85688
|
mkdirSync as mkdirSync8,
|
|
85410
|
-
readFileSync as
|
|
85689
|
+
readFileSync as readFileSync29,
|
|
85411
85690
|
readdirSync as readdirSync10,
|
|
85412
85691
|
rmSync as rmSync3,
|
|
85413
85692
|
symlinkSync,
|
|
85414
|
-
writeFileSync as
|
|
85693
|
+
writeFileSync as writeFileSync20
|
|
85415
85694
|
} from "node:fs";
|
|
85416
|
-
import { join as
|
|
85695
|
+
import { join as join33 } from "node:path";
|
|
85417
85696
|
var SKILL_NS = "errata-";
|
|
85418
85697
|
var HARNESS_SKILL_DIRS = [
|
|
85419
|
-
{ configDir: ".claude", skillsDir:
|
|
85698
|
+
{ configDir: ".claude", skillsDir: join33(".claude", "skills") },
|
|
85420
85699
|
// Cursor adopted the standard; its exact project dir is still moving — kept
|
|
85421
85700
|
// best-effort and gated on `.cursor/` presence so we never create it blind.
|
|
85422
|
-
{ configDir: ".cursor", skillsDir:
|
|
85701
|
+
{ configDir: ".cursor", skillsDir: join33(".cursor", "skills") }
|
|
85423
85702
|
];
|
|
85424
85703
|
function skillSlug(title, id) {
|
|
85425
85704
|
const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
|
|
@@ -85469,7 +85748,7 @@ function reconcileNamespaced(dir, keep) {
|
|
|
85469
85748
|
for (const name2 of readdirSync10(dir)) {
|
|
85470
85749
|
if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
|
|
85471
85750
|
try {
|
|
85472
|
-
rmSync3(
|
|
85751
|
+
rmSync3(join33(dir, name2), { recursive: true, force: true });
|
|
85473
85752
|
pruned++;
|
|
85474
85753
|
} catch {
|
|
85475
85754
|
}
|
|
@@ -85499,7 +85778,7 @@ function safeLstat(p) {
|
|
|
85499
85778
|
}
|
|
85500
85779
|
}
|
|
85501
85780
|
function emitAndProjectSkills(root, skills) {
|
|
85502
|
-
const agentsSkillsDir =
|
|
85781
|
+
const agentsSkillsDir = join33(root, ".agents", "skills");
|
|
85503
85782
|
mkdirSync8(agentsSkillsDir, { recursive: true });
|
|
85504
85783
|
const slugs = [];
|
|
85505
85784
|
const keep = /* @__PURE__ */ new Set();
|
|
@@ -85507,7 +85786,7 @@ function emitAndProjectSkills(root, skills) {
|
|
|
85507
85786
|
for (const s of skills) {
|
|
85508
85787
|
let body2;
|
|
85509
85788
|
try {
|
|
85510
|
-
body2 =
|
|
85789
|
+
body2 = readFileSync29(s.bodyPath, "utf8");
|
|
85511
85790
|
} catch {
|
|
85512
85791
|
continue;
|
|
85513
85792
|
}
|
|
@@ -85516,9 +85795,9 @@ function emitAndProjectSkills(root, skills) {
|
|
|
85516
85795
|
keep.add(slug2);
|
|
85517
85796
|
slugs.push(slug2);
|
|
85518
85797
|
const description = deriveDescription(s.title, s.layer, body2);
|
|
85519
|
-
mkdirSync8(
|
|
85520
|
-
|
|
85521
|
-
|
|
85798
|
+
mkdirSync8(join33(agentsSkillsDir, slug2), { recursive: true });
|
|
85799
|
+
writeFileSync20(
|
|
85800
|
+
join33(agentsSkillsDir, slug2, "SKILL.md"),
|
|
85522
85801
|
renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
|
|
85523
85802
|
"utf8"
|
|
85524
85803
|
);
|
|
@@ -85527,11 +85806,11 @@ function emitAndProjectSkills(root, skills) {
|
|
|
85527
85806
|
reconcileNamespaced(agentsSkillsDir, keep);
|
|
85528
85807
|
let projected = 0;
|
|
85529
85808
|
for (const h of HARNESS_SKILL_DIRS) {
|
|
85530
|
-
if (!existsSync26(
|
|
85531
|
-
const dir =
|
|
85809
|
+
if (!existsSync26(join33(root, h.configDir))) continue;
|
|
85810
|
+
const dir = join33(root, h.skillsDir);
|
|
85532
85811
|
mkdirSync8(dir, { recursive: true });
|
|
85533
85812
|
for (const slug2 of slugs) {
|
|
85534
|
-
linkOrCopy(
|
|
85813
|
+
linkOrCopy(join33(dir, slug2), join33(agentsSkillsDir, slug2));
|
|
85535
85814
|
projected++;
|
|
85536
85815
|
}
|
|
85537
85816
|
reconcileNamespaced(dir, keep);
|
|
@@ -85542,13 +85821,13 @@ function emitAndProjectSkills(root, skills) {
|
|
|
85542
85821
|
function emitInputsFromManifest(erretaDir, manifestPath) {
|
|
85543
85822
|
if (!existsSync26(manifestPath)) return [];
|
|
85544
85823
|
try {
|
|
85545
|
-
const parsed = JSON.parse(
|
|
85824
|
+
const parsed = JSON.parse(readFileSync29(manifestPath, "utf8"));
|
|
85546
85825
|
return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
|
|
85547
85826
|
id: s.id,
|
|
85548
85827
|
title: s.title ?? s.id,
|
|
85549
85828
|
layer: s.layer ?? "technique",
|
|
85550
85829
|
confidence: s.confidence ?? 0,
|
|
85551
|
-
bodyPath:
|
|
85830
|
+
bodyPath: join33(erretaDir, s.file)
|
|
85552
85831
|
}));
|
|
85553
85832
|
} catch {
|
|
85554
85833
|
return [];
|
|
@@ -85562,17 +85841,17 @@ var GITIGNORE_LINES = [
|
|
|
85562
85841
|
".cursor/skills/errata-*/"
|
|
85563
85842
|
];
|
|
85564
85843
|
function ensureSkillGitignore(root) {
|
|
85565
|
-
const path3 =
|
|
85844
|
+
const path3 = join33(root, ".gitignore");
|
|
85566
85845
|
let current = "";
|
|
85567
85846
|
try {
|
|
85568
|
-
current = existsSync26(path3) ?
|
|
85847
|
+
current = existsSync26(path3) ? readFileSync29(path3, "utf8") : "";
|
|
85569
85848
|
} catch {
|
|
85570
85849
|
return;
|
|
85571
85850
|
}
|
|
85572
85851
|
if (current.includes(GITIGNORE_MARK)) return;
|
|
85573
85852
|
const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
|
|
85574
85853
|
try {
|
|
85575
|
-
|
|
85854
|
+
writeFileSync20(path3, `${current}${prefix}
|
|
85576
85855
|
${GITIGNORE_LINES.join("\n")}
|
|
85577
85856
|
`, "utf8");
|
|
85578
85857
|
} catch {
|
|
@@ -85668,18 +85947,18 @@ init_paths();
|
|
|
85668
85947
|
init_profile2();
|
|
85669
85948
|
|
|
85670
85949
|
// src/witness-queue.ts
|
|
85671
|
-
import { readFileSync as
|
|
85672
|
-
import { dirname as
|
|
85950
|
+
import { readFileSync as readFileSync30, renameSync as renameSync4, writeFileSync as writeFileSync21 } from "node:fs";
|
|
85951
|
+
import { dirname as dirname13, join as join34 } from "node:path";
|
|
85673
85952
|
var WITNESS_QUEUE_CAP = 500;
|
|
85674
85953
|
var WITNESS_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
85675
85954
|
var WITNESS_MAX_ATTEMPTS = 5;
|
|
85676
85955
|
function witnessQueuePath(workspaceConfigDir) {
|
|
85677
|
-
return
|
|
85956
|
+
return join34(workspaceConfigDir, "witness-queue.json");
|
|
85678
85957
|
}
|
|
85679
85958
|
function loadWitnessQueueWithLosses(path3) {
|
|
85680
85959
|
let raw2;
|
|
85681
85960
|
try {
|
|
85682
|
-
raw2 = JSON.parse(
|
|
85961
|
+
raw2 = JSON.parse(readFileSync30(path3, "utf8"));
|
|
85683
85962
|
} catch (err2) {
|
|
85684
85963
|
const absent = err2?.code === "ENOENT";
|
|
85685
85964
|
return { queue: [], fileUnreadable: !absent, malformedEntries: 0 };
|
|
@@ -85692,9 +85971,9 @@ function loadWitnessQueueWithLosses(path3) {
|
|
|
85692
85971
|
}
|
|
85693
85972
|
function saveWitnessQueue(path3, queue) {
|
|
85694
85973
|
try {
|
|
85695
|
-
const tmp =
|
|
85696
|
-
|
|
85697
|
-
|
|
85974
|
+
const tmp = join34(dirname13(path3), `.${Date.now()}.witness-queue.tmp`);
|
|
85975
|
+
writeFileSync21(tmp, JSON.stringify(queue), "utf8");
|
|
85976
|
+
renameSync4(tmp, path3);
|
|
85698
85977
|
} catch {
|
|
85699
85978
|
}
|
|
85700
85979
|
}
|
|
@@ -86002,8 +86281,8 @@ function maybeFlushDigests() {
|
|
|
86002
86281
|
|
|
86003
86282
|
// src/liveness-watch.ts
|
|
86004
86283
|
init_src5();
|
|
86005
|
-
import { readFileSync as
|
|
86006
|
-
import { join as
|
|
86284
|
+
import { readFileSync as readFileSync32, writeFileSync as writeFileSync23 } from "node:fs";
|
|
86285
|
+
import { join as join36 } from "node:path";
|
|
86007
86286
|
|
|
86008
86287
|
// src/loop-lag.ts
|
|
86009
86288
|
var HEARTBEAT_MS = 500;
|
|
@@ -86015,13 +86294,14 @@ var recent3 = [];
|
|
|
86015
86294
|
function markPass(name2) {
|
|
86016
86295
|
const id = nextPassId++;
|
|
86017
86296
|
const startedAt = Date.now();
|
|
86297
|
+
const readsAtStart = ioReadOps();
|
|
86018
86298
|
active2.set(id, { name: name2, startedAt });
|
|
86019
86299
|
let ended = false;
|
|
86020
86300
|
return () => {
|
|
86021
86301
|
if (ended) return;
|
|
86022
86302
|
ended = true;
|
|
86023
86303
|
active2.delete(id);
|
|
86024
|
-
recent3.unshift({ name: name2, ms: Date.now() - startedAt, endedAt: Date.now() });
|
|
86304
|
+
recent3.unshift({ name: name2, ms: Date.now() - startedAt, endedAt: Date.now(), readOps: ioReadOps() - readsAtStart });
|
|
86025
86305
|
if (recent3.length > RECENT_PASS_LIMIT) recent3.pop();
|
|
86026
86306
|
};
|
|
86027
86307
|
}
|
|
@@ -86134,11 +86414,11 @@ function watchCensusLine(c = watchCensus(), now = Date.now()) {
|
|
|
86134
86414
|
var LIVENESS_WATCH_INTERVAL_MS = 60 * 60 * 1e3;
|
|
86135
86415
|
var ALARM_RENOTIFY_MS = 24 * 60 * 60 * 1e3;
|
|
86136
86416
|
function alarmStatePath(configDir) {
|
|
86137
|
-
return
|
|
86417
|
+
return join36(configDir, "liveness-alarms.json");
|
|
86138
86418
|
}
|
|
86139
86419
|
function loadAlarmState(path3) {
|
|
86140
86420
|
try {
|
|
86141
|
-
const raw2 = JSON.parse(
|
|
86421
|
+
const raw2 = JSON.parse(readFileSync32(path3, "utf8"));
|
|
86142
86422
|
return new Map(Object.entries(raw2).filter((e) => typeof e[1] === "number"));
|
|
86143
86423
|
} catch {
|
|
86144
86424
|
return /* @__PURE__ */ new Map();
|
|
@@ -86146,7 +86426,7 @@ function loadAlarmState(path3) {
|
|
|
86146
86426
|
}
|
|
86147
86427
|
function saveAlarmState(path3, state) {
|
|
86148
86428
|
try {
|
|
86149
|
-
|
|
86429
|
+
writeFileSync23(path3, JSON.stringify(Object.fromEntries(state)));
|
|
86150
86430
|
} catch {
|
|
86151
86431
|
}
|
|
86152
86432
|
}
|
|
@@ -86176,12 +86456,15 @@ function toastLivenessAlarms(gate, workspace, alarms, deliver, nowMs) {
|
|
|
86176
86456
|
return fresh;
|
|
86177
86457
|
}
|
|
86178
86458
|
function createLivenessWatch(deps) {
|
|
86179
|
-
let lastRunAt =
|
|
86459
|
+
let lastRunAt = null;
|
|
86180
86460
|
let running = false;
|
|
86181
86461
|
const lastAlarmedAt = loadAlarmState(alarmStatePath(deps.configDir));
|
|
86182
86462
|
return {
|
|
86183
86463
|
async maybeRun(nowMs = Date.now()) {
|
|
86184
|
-
if (running
|
|
86464
|
+
if (running) return null;
|
|
86465
|
+
lastRunAt ??= summarizePassLedger(deps.configDir).get("liveness-watch")?.lastTs ?? 0;
|
|
86466
|
+
if (lastRunAt > nowMs) lastRunAt = 0;
|
|
86467
|
+
if (nowMs - lastRunAt < LIVENESS_WATCH_INTERVAL_MS) return null;
|
|
86185
86468
|
lastRunAt = nowMs;
|
|
86186
86469
|
running = true;
|
|
86187
86470
|
try {
|
|
@@ -86273,6 +86556,25 @@ function runWorkspaceMaintenance(store, workspaceId2) {
|
|
|
86273
86556
|
};
|
|
86274
86557
|
}
|
|
86275
86558
|
|
|
86559
|
+
// src/pass-inputs.ts
|
|
86560
|
+
function passInputs(store, pass, scopes) {
|
|
86561
|
+
const key = `pass-inputs:${pass}`;
|
|
86562
|
+
const seq = store.changeSeq?.(scopes);
|
|
86563
|
+
let held = null;
|
|
86564
|
+
try {
|
|
86565
|
+
held = JSON.parse(store.getMeta?.(key) ?? "null");
|
|
86566
|
+
} catch {
|
|
86567
|
+
held = null;
|
|
86568
|
+
}
|
|
86569
|
+
return {
|
|
86570
|
+
unchanged: seq !== void 0 && held !== null && held.seq === seq,
|
|
86571
|
+
last: held?.result ?? null,
|
|
86572
|
+
complete(result) {
|
|
86573
|
+
if (seq !== void 0) store.setMeta?.(key, JSON.stringify({ seq, result }));
|
|
86574
|
+
}
|
|
86575
|
+
};
|
|
86576
|
+
}
|
|
86577
|
+
|
|
86276
86578
|
// src/watch-breaker.ts
|
|
86277
86579
|
function numEnv3(key, fallback) {
|
|
86278
86580
|
const n = Number(process.env[key]);
|
|
@@ -86374,7 +86676,7 @@ function createWatchBreaker(deps) {
|
|
|
86374
86676
|
}
|
|
86375
86677
|
|
|
86376
86678
|
// src/engine.ts
|
|
86377
|
-
var DAEMON_VERSION = true ? "2.0.22-dev.
|
|
86679
|
+
var DAEMON_VERSION = true ? "2.0.22-dev.4530" : "2.0.0-alpha.0";
|
|
86378
86680
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
86379
86681
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
86380
86682
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -86386,8 +86688,8 @@ var CODEX_SWEEP_LOOKBACK_MS = 10 * 6e4;
|
|
|
86386
86688
|
function appendIdentityAudit(path3, record2, line) {
|
|
86387
86689
|
if (!record2.accepted && record2.score <= 0) return;
|
|
86388
86690
|
try {
|
|
86389
|
-
if (existsSync28(path3) &&
|
|
86390
|
-
|
|
86691
|
+
if (existsSync28(path3) && statSync11(path3).size >= IDENTITY_AUDIT_MAX_BYTES) {
|
|
86692
|
+
renameSync5(path3, `${path3}.1`);
|
|
86391
86693
|
}
|
|
86392
86694
|
appendFileSync4(path3, line);
|
|
86393
86695
|
} catch {
|
|
@@ -86396,7 +86698,7 @@ function appendIdentityAudit(path3, record2, line) {
|
|
|
86396
86698
|
var yieldToLoop = () => new Promise((r) => setImmediate(r));
|
|
86397
86699
|
function loadTurnCursors(path3) {
|
|
86398
86700
|
try {
|
|
86399
|
-
const raw2 = JSON.parse(
|
|
86701
|
+
const raw2 = JSON.parse(readFileSync33(path3, "utf8"));
|
|
86400
86702
|
return new Map(
|
|
86401
86703
|
Object.entries(raw2).map(([k, v]) => [k, typeof v === "string" ? v : String(v?.uuid ?? "")])
|
|
86402
86704
|
);
|
|
@@ -86406,7 +86708,7 @@ function loadTurnCursors(path3) {
|
|
|
86406
86708
|
}
|
|
86407
86709
|
function loadTurnOffsets(path3) {
|
|
86408
86710
|
try {
|
|
86409
|
-
const raw2 = JSON.parse(
|
|
86711
|
+
const raw2 = JSON.parse(readFileSync33(path3, "utf8"));
|
|
86410
86712
|
const out2 = /* @__PURE__ */ new Map();
|
|
86411
86713
|
for (const [k, v] of Object.entries(raw2)) {
|
|
86412
86714
|
const off2 = typeof v === "object" && v !== null ? v.offset : void 0;
|
|
@@ -86422,7 +86724,7 @@ function saveTurnCursors(path3, cursors, offsets) {
|
|
|
86422
86724
|
const merged = {};
|
|
86423
86725
|
for (const [k, uuid3] of cursors) merged[k] = { uuid: uuid3, offset: offsets.get(k) ?? 0 };
|
|
86424
86726
|
for (const [k, offset] of offsets) if (!merged[k]) merged[k] = { uuid: "", offset };
|
|
86425
|
-
|
|
86727
|
+
writeFileSync24(path3, JSON.stringify(merged), "utf8");
|
|
86426
86728
|
} catch {
|
|
86427
86729
|
}
|
|
86428
86730
|
}
|
|
@@ -86444,7 +86746,7 @@ function gitSourceWatchTargets(root) {
|
|
|
86444
86746
|
["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
|
|
86445
86747
|
{ encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
|
|
86446
86748
|
);
|
|
86447
|
-
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(
|
|
86749
|
+
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join37(root, d) + sep5));
|
|
86448
86750
|
} catch {
|
|
86449
86751
|
}
|
|
86450
86752
|
const hasIgnoredChild = (dir) => ignoredDirs.some((ig) => ig.startsWith(dir + "/"));
|
|
@@ -86456,19 +86758,19 @@ function gitSourceWatchTargets(root) {
|
|
|
86456
86758
|
if (!f.startsWith(prefix)) continue;
|
|
86457
86759
|
const rest2 = f.slice(prefix.length);
|
|
86458
86760
|
if (rest2.includes("/")) children.add(dir === "" ? rest2.slice(0, rest2.indexOf("/")) : dir + "/" + rest2.slice(0, rest2.indexOf("/")));
|
|
86459
|
-
else targets.add(
|
|
86761
|
+
else targets.add(join37(root, f));
|
|
86460
86762
|
}
|
|
86461
86763
|
for (const c of children) {
|
|
86462
|
-
if (IGNORED_PATH.test(
|
|
86764
|
+
if (IGNORED_PATH.test(join37(root, c) + sep5)) continue;
|
|
86463
86765
|
if (hasIgnoredChild(c)) addUnder(c);
|
|
86464
|
-
else targets.add(
|
|
86766
|
+
else targets.add(join37(root, c));
|
|
86465
86767
|
}
|
|
86466
86768
|
};
|
|
86467
86769
|
addUnder("");
|
|
86468
86770
|
if (targets.size > 0) return [...targets];
|
|
86469
86771
|
} catch {
|
|
86470
86772
|
}
|
|
86471
|
-
return readdirSync11(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(
|
|
86773
|
+
return readdirSync11(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join37(root, String(e.name)) + sep5)).map((e) => join37(root, String(e.name)));
|
|
86472
86774
|
}
|
|
86473
86775
|
function createWorkspaceEngine(opts) {
|
|
86474
86776
|
const paths = workspacePaths(opts.workspaceRoot);
|
|
@@ -86524,6 +86826,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86524
86826
|
let watcher = null;
|
|
86525
86827
|
let watchBreaker = null;
|
|
86526
86828
|
let lastActivityTs = Date.now();
|
|
86829
|
+
let storeReconciled = !!opts.skipWatchers;
|
|
86527
86830
|
let stopGit = null;
|
|
86528
86831
|
let fsReindex;
|
|
86529
86832
|
let stopping = false;
|
|
@@ -86560,7 +86863,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86560
86863
|
}
|
|
86561
86864
|
let size = 0;
|
|
86562
86865
|
try {
|
|
86563
|
-
size =
|
|
86866
|
+
size = statSync11(path3).size;
|
|
86564
86867
|
} catch {
|
|
86565
86868
|
}
|
|
86566
86869
|
lastActivityTs = Date.now();
|
|
@@ -86607,7 +86910,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86607
86910
|
fsReindex = createCoalescedFilePass(REINDEX_DEBOUNCE_MS, async (changed) => {
|
|
86608
86911
|
if (stopping) return;
|
|
86609
86912
|
const t = Date.now();
|
|
86610
|
-
const relChanged = changed.map((p) =>
|
|
86913
|
+
const relChanged = changed.map((p) => relative6(opts.workspaceRoot, p).split(sep5).join("/"));
|
|
86611
86914
|
const causal = causalBuffer.correlate(relChanged, t) ?? void 0;
|
|
86612
86915
|
await runReindexPass(
|
|
86613
86916
|
`fs-reindex:${profile.name} (${changed.length} files)`,
|
|
@@ -86667,7 +86970,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86667
86970
|
const srcPaths = diff.changedPaths.filter((p) => /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p));
|
|
86668
86971
|
let episodeId2;
|
|
86669
86972
|
if (srcPaths.length > 0) {
|
|
86670
|
-
const abs = srcPaths.map((p) =>
|
|
86973
|
+
const abs = srcPaths.map((p) => join37(opts.workspaceRoot, p));
|
|
86671
86974
|
try {
|
|
86672
86975
|
const r = await runReindexPass(
|
|
86673
86976
|
`git-reindex:${profile.name} (${abs.length} files)`,
|
|
@@ -86703,7 +87006,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86703
87006
|
`[errata] git: ${ev.kind} ${ev.newSha.slice(0, 7)} by ${meta3.authorName} \u2014 ${diff.changedPaths.length} file(s), ${diff.renames.length} rename(s)`
|
|
86704
87007
|
);
|
|
86705
87008
|
};
|
|
86706
|
-
const gitDir =
|
|
87009
|
+
const gitDir = join37(opts.workspaceRoot, ".git");
|
|
86707
87010
|
if (existsSync28(gitDir)) {
|
|
86708
87011
|
stopGit = startGitSensor(gitDir, (ev) => {
|
|
86709
87012
|
void handleGitEvent(ev).catch((err2) => {
|
|
@@ -86713,6 +87016,10 @@ function createWorkspaceEngine(opts) {
|
|
|
86713
87016
|
}
|
|
86714
87017
|
setImmediate(() => {
|
|
86715
87018
|
const reconcileStartedAt = Date.now();
|
|
87019
|
+
try {
|
|
87020
|
+
store.pruneChangeLog?.();
|
|
87021
|
+
} catch {
|
|
87022
|
+
}
|
|
86716
87023
|
const reconcile = passWorker ? passWorker.reconcile().catch(() => reconcileStaleFiles(store, opts.workspaceRoot, profile.id)) : reconcileStaleFiles(store, opts.workspaceRoot, profile.id);
|
|
86717
87024
|
void reconcile.then((n) => {
|
|
86718
87025
|
appendPassLedger(paths.configDir, "reconcile", Date.now() - reconcileStartedAt, {
|
|
@@ -86747,6 +87054,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86747
87054
|
} catch (err2) {
|
|
86748
87055
|
console.warn("[errata] orphan reap failed:", err2 instanceof Error ? err2.message : err2);
|
|
86749
87056
|
}
|
|
87057
|
+
storeReconciled = true;
|
|
86750
87058
|
});
|
|
86751
87059
|
});
|
|
86752
87060
|
}
|
|
@@ -86760,7 +87068,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86760
87068
|
},
|
|
86761
87069
|
onAlarms: (alarms) => {
|
|
86762
87070
|
toastLivenessAlarms(
|
|
86763
|
-
sharedAlarmToastGate(
|
|
87071
|
+
sharedAlarmToastGate(join37(globalDir(), "liveness-toasts.json")),
|
|
86764
87072
|
{ root: opts.workspaceRoot, name: profile.name },
|
|
86765
87073
|
alarms,
|
|
86766
87074
|
(body2, key) => notifyEvent("mechanism-stalled", body2, { key }),
|
|
@@ -86777,7 +87085,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86777
87085
|
let subagentBase = null;
|
|
86778
87086
|
let subagentBaseVersion = 0;
|
|
86779
87087
|
const subagentRenders = /* @__PURE__ */ new Map();
|
|
86780
|
-
const sessions = createSessionRegistry({ originsPath:
|
|
87088
|
+
const sessions = createSessionRegistry({ originsPath: join37(paths.configDir, "session-origins.json") });
|
|
86781
87089
|
const sessionRenders = /* @__PURE__ */ new Map();
|
|
86782
87090
|
const selfCiteSkipsBySession = /* @__PURE__ */ new Map();
|
|
86783
87091
|
const toolRuns = createToolRunState();
|
|
@@ -86791,6 +87099,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86791
87099
|
let intentRemoteInFlight = false;
|
|
86792
87100
|
let ctxRefreshInFlight = false;
|
|
86793
87101
|
let ctxRefreshQueued = false;
|
|
87102
|
+
let lastWorkerSnapshot = null;
|
|
86794
87103
|
let lastSelfCiteSkips = 0;
|
|
86795
87104
|
const refreshContextNow = () => {
|
|
86796
87105
|
void refreshContextAsync().catch((err2) => {
|
|
@@ -86869,26 +87178,35 @@ function createWorkspaceEngine(opts) {
|
|
|
86869
87178
|
const elicit = isEdgeElicitationEnabled();
|
|
86870
87179
|
const snapOpts = {
|
|
86871
87180
|
profile,
|
|
86872
|
-
atCommit: readGitRefState(
|
|
87181
|
+
atCommit: readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0,
|
|
86873
87182
|
reviewCount: pendingCount(paths),
|
|
86874
87183
|
reviewUiUrl: opts.reviewUrl(),
|
|
86875
87184
|
workingFile: workingFiles.mostRecent() ?? void 0,
|
|
86876
87185
|
skills: readSkillManifest(paths.skillsManifest),
|
|
86877
87186
|
...lastSelfCiteSkips > 0 ? { selfCiteSkips: lastSelfCiteSkips } : {}
|
|
86878
87187
|
};
|
|
86879
|
-
const
|
|
87188
|
+
const changes = store.changeSeq ? store.changeSeq() - store.changeSeq([EXPOSURE_SCOPE]) : store.changeStamp();
|
|
87189
|
+
const { id, name: name2, stack, languages, domains, goals } = snapOpts.profile;
|
|
87190
|
+
const snapshotKey = `${snapshotCodeIdentity(DAEMON_VERSION)}|${changes}|${JSON.stringify({ ...snapOpts, profile: { id, name: name2, stack, languages, domains, goals } })}`;
|
|
87191
|
+
lastWorkerSnapshot ??= loadHeldSnapshot(heldSnapshotPath(paths.configDir));
|
|
87192
|
+
const held = lastWorkerSnapshot;
|
|
87193
|
+
const prebuilt = snapshotReusable(held, { key: snapshotKey, atCommit: snapOpts.atCommit, workingFile: snapOpts.workingFile }) ? structuredClone(held.snapshot) : passWorker ? await passWorker.snapshot(snapOpts).then((snapshot2) => {
|
|
87194
|
+
lastWorkerSnapshot = { key: snapshotKey, at: Date.now(), atCommit: snapOpts.atCommit, workingFile: snapOpts.workingFile, snapshot: structuredClone(snapshot2) };
|
|
87195
|
+
saveHeldSnapshot(heldSnapshotPath(paths.configDir), lastWorkerSnapshot);
|
|
87196
|
+
return snapshot2;
|
|
87197
|
+
}).catch((err2) => {
|
|
86880
87198
|
console.warn(
|
|
86881
87199
|
`[errata] snapshot worker failed \u2014 rendering INLINE on main:`,
|
|
86882
87200
|
err2 instanceof Error ? err2.message : err2
|
|
86883
87201
|
);
|
|
86884
87202
|
return null;
|
|
86885
87203
|
}) : null;
|
|
86886
|
-
if (snapOpts.atCommit !== (readGitRefState(
|
|
87204
|
+
if (snapOpts.atCommit !== (readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0)) {
|
|
86887
87205
|
contextDirty = true;
|
|
86888
87206
|
return;
|
|
86889
87207
|
}
|
|
86890
87208
|
const doneRender = markPass(`${prebuilt ? "context-render" : "context-render-inline"}:${profile.name}`);
|
|
86891
|
-
const base = prebuilt ?? buildSnapshot({ store, ...snapOpts });
|
|
87209
|
+
const base = freshenRecentBands(prebuilt ?? buildSnapshot({ store, ...snapOpts }), (id2) => store.getNode(id2));
|
|
86892
87210
|
subagentBase = structuredClone(base);
|
|
86893
87211
|
subagentBaseVersion++;
|
|
86894
87212
|
const sharedSnapshot = scopeSnapshot(base, (n) => !isQuarantined(n, sessions));
|
|
@@ -86929,10 +87247,10 @@ function createWorkspaceEngine(opts) {
|
|
|
86929
87247
|
} catch (err2) {
|
|
86930
87248
|
console.warn("[errata] context card failed:", err2.message?.slice(0, 120));
|
|
86931
87249
|
}
|
|
86932
|
-
const target =
|
|
87250
|
+
const target = join37(opts.workspaceRoot, "AGENTS.md");
|
|
86933
87251
|
writeManagedBlock(target, { body: AGENTS_POINTER_BODY, stable: true, force: true });
|
|
86934
87252
|
if (elicit) {
|
|
86935
|
-
writePrimingHandles(
|
|
87253
|
+
writePrimingHandles(join37(paths.configDir, "priming-handles.json"), [
|
|
86936
87254
|
...snapshot.recentProblems.map((r) => r.node),
|
|
86937
87255
|
// Resolved-band handles: the ✓ problem AND its Solution are citable
|
|
86938
87256
|
// (a fix tag on an already-resolved problem no-ops idempotently; the
|
|
@@ -87240,8 +87558,8 @@ function createWorkspaceEngine(opts) {
|
|
|
87240
87558
|
const cached2 = subagentRenders.get(a.agentId);
|
|
87241
87559
|
if (cached2?.key === key) return cached2.block;
|
|
87242
87560
|
const elicit = isEdgeElicitationEnabled();
|
|
87243
|
-
const handlesPath =
|
|
87244
|
-
const atCommit = readGitRefState(
|
|
87561
|
+
const handlesPath = join37(paths.configDir, "priming-handles.json");
|
|
87562
|
+
const atCommit = readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
87245
87563
|
const block = renderSubagentBlock({
|
|
87246
87564
|
store,
|
|
87247
87565
|
entry,
|
|
@@ -87295,7 +87613,7 @@ function createWorkspaceEngine(opts) {
|
|
|
87295
87613
|
const cached2 = sessionRenders.get(sessionId);
|
|
87296
87614
|
if (cached2?.key === key) return cached2.block;
|
|
87297
87615
|
const elicit = isEdgeElicitationEnabled();
|
|
87298
|
-
const atCommit = readGitRefState(
|
|
87616
|
+
const atCommit = readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
87299
87617
|
const scoped = scopeSnapshot(structuredClone(subagentBase), (n) => !hiddenFrom(n, sessionId, sessions, now));
|
|
87300
87618
|
delete scoped.workingFile;
|
|
87301
87619
|
if (workingFile) {
|
|
@@ -87336,7 +87654,7 @@ function createWorkspaceEngine(opts) {
|
|
|
87336
87654
|
]
|
|
87337
87655
|
};
|
|
87338
87656
|
if (elicit && block.handleNodes.length) {
|
|
87339
|
-
writePrimingHandles(
|
|
87657
|
+
writePrimingHandles(join37(paths.configDir, "priming-handles.json"), block.handleNodes);
|
|
87340
87658
|
}
|
|
87341
87659
|
sessionRenders.delete(sessionId);
|
|
87342
87660
|
sessionRenders.set(sessionId, { key, block });
|
|
@@ -87396,7 +87714,7 @@ function createWorkspaceEngine(opts) {
|
|
|
87396
87714
|
resultSummary: { exitCode: e.exitCode ?? 1, errorTokens: e.errorTokens }
|
|
87397
87715
|
});
|
|
87398
87716
|
};
|
|
87399
|
-
const turnCursorPath =
|
|
87717
|
+
const turnCursorPath = join37(paths.configDir, "turn-cursors.json");
|
|
87400
87718
|
const lastTurnUuid = loadTurnCursors(turnCursorPath);
|
|
87401
87719
|
const turnOffset = loadTurnOffsets(turnCursorPath);
|
|
87402
87720
|
const readLosses = { parseFailures: 0, ioFailures: 0, bytesUnreachable: 0, sliceGuardHits: 0 };
|
|
@@ -87458,7 +87776,7 @@ function createWorkspaceEngine(opts) {
|
|
|
87458
87776
|
let processedTurns = 0;
|
|
87459
87777
|
const seqAtStart = store.currentIngestSeq();
|
|
87460
87778
|
const elicit = isEdgeElicitationEnabled();
|
|
87461
|
-
const handleMap = elicit ? readPrimingHandles(
|
|
87779
|
+
const handleMap = elicit ? readPrimingHandles(join37(paths.configDir, "priming-handles.json")) : {};
|
|
87462
87780
|
const wsRoot = (opts.workspaceRoot ?? "").replace(/\\/g, "/");
|
|
87463
87781
|
const toRel = (abs) => {
|
|
87464
87782
|
const p = abs.replace(/\\/g, "/");
|
|
@@ -87669,7 +87987,7 @@ function createWorkspaceEngine(opts) {
|
|
|
87669
87987
|
let anchorReadFailed = false;
|
|
87670
87988
|
if (p.location) {
|
|
87671
87989
|
try {
|
|
87672
|
-
fileText =
|
|
87990
|
+
fileText = readFileSync33(join37(opts.workspaceRoot, p.location.path), "utf8");
|
|
87673
87991
|
} catch {
|
|
87674
87992
|
anchorReadFailed = true;
|
|
87675
87993
|
}
|
|
@@ -87831,10 +88149,10 @@ function createWorkspaceEngine(opts) {
|
|
|
87831
88149
|
let enclosing = {};
|
|
87832
88150
|
if (p.location?.line !== void 0) {
|
|
87833
88151
|
try {
|
|
87834
|
-
const headSha = readGitRefState(
|
|
88152
|
+
const headSha = readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
87835
88153
|
enclosing = {
|
|
87836
88154
|
line: p.location.line,
|
|
87837
|
-
fileText:
|
|
88155
|
+
fileText: readFileSync33(join37(opts.workspaceRoot, anchorPath), "utf8"),
|
|
87838
88156
|
...headSha ? { headSha } : {}
|
|
87839
88157
|
};
|
|
87840
88158
|
} catch {
|
|
@@ -88673,7 +88991,7 @@ B: ${b}`,
|
|
|
88673
88991
|
try {
|
|
88674
88992
|
const inputs = emitInputsFromManifest(paths.configDir, paths.skillsManifest);
|
|
88675
88993
|
emitAndProjectSkills(opts.workspaceRoot, inputs);
|
|
88676
|
-
writePrimingHandles(
|
|
88994
|
+
writePrimingHandles(join37(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
|
|
88677
88995
|
} catch (err2) {
|
|
88678
88996
|
console.warn("[skills] agent-skills projection failed (non-fatal):", err2 instanceof Error ? err2.message : err2);
|
|
88679
88997
|
}
|
|
@@ -88709,6 +89027,7 @@ B: ${b}`,
|
|
|
88709
89027
|
lastActivityAt() {
|
|
88710
89028
|
return lastActivityTs;
|
|
88711
89029
|
},
|
|
89030
|
+
storeReconciled: () => storeReconciled,
|
|
88712
89031
|
quarantinedSessions: () => sessions.originSessions(),
|
|
88713
89032
|
markContextDirty() {
|
|
88714
89033
|
contextDirty = true;
|
|
@@ -88769,7 +89088,46 @@ B: ${b}`,
|
|
|
88769
89088
|
return report;
|
|
88770
89089
|
},
|
|
88771
89090
|
async semanticMaintenance() {
|
|
88772
|
-
const
|
|
89091
|
+
const inputs = passInputs(store, "semantic-maintenance");
|
|
89092
|
+
if (inputs.unchanged && inputs.last) {
|
|
89093
|
+
const last = inputs.last;
|
|
89094
|
+
const report2 = {
|
|
89095
|
+
...last.report,
|
|
89096
|
+
designResolved: 0,
|
|
89097
|
+
revisitsCleared: 0,
|
|
89098
|
+
fixCandidatesSettled: 0,
|
|
89099
|
+
claimsEvaluated: 0,
|
|
89100
|
+
claimsDerived: 0,
|
|
89101
|
+
durationMs: 0,
|
|
89102
|
+
fixCandidates: { ...last.report.fixCandidates, answered: 0, ignored: 0, unsubstantiated: 0 }
|
|
89103
|
+
};
|
|
89104
|
+
appendPassLedger(paths.configDir, "semantic-maintenance", 0, {
|
|
89105
|
+
revisitsCleared: 0,
|
|
89106
|
+
revisitsStanding: report2.revisitsStanding,
|
|
89107
|
+
fixCandidatesSettled: 0,
|
|
89108
|
+
fixCandidatesAnswered: 0,
|
|
89109
|
+
fixCandidatesIgnored: 0,
|
|
89110
|
+
fixCandidatesUnsubstantiated: 0,
|
|
89111
|
+
fixCandidatesStanding: report2.fixCandidates.standing,
|
|
89112
|
+
designResolved: 0,
|
|
89113
|
+
claimsEvaluated: 0,
|
|
89114
|
+
seqAdvanced: 0,
|
|
89115
|
+
anchorHintsUpgraded: 0,
|
|
89116
|
+
anchorHintsStanding: last.hintUpgrade.standing,
|
|
89117
|
+
anchorHintsUnresolvable: last.hintUpgrade.unresolvable,
|
|
89118
|
+
anchorHintsBlocked: last.hintUpgrade.blocked,
|
|
89119
|
+
// Telemetry, not a counter: a descriptor must not gate on it.
|
|
89120
|
+
inputsUnchanged: 1
|
|
89121
|
+
});
|
|
89122
|
+
if (last.calibration) {
|
|
89123
|
+
appendPassLedger(paths.configDir, "wm-calibration", 0, { ...last.calibration, inputsUnchanged: 1 });
|
|
89124
|
+
}
|
|
89125
|
+
await livenessWatch.maybeRun();
|
|
89126
|
+
return report2;
|
|
89127
|
+
}
|
|
89128
|
+
const result = passWorker ? await passWorker.semanticMaintenance() : runWorkspaceMaintenance(store, profile.id);
|
|
89129
|
+
inputs.complete(result);
|
|
89130
|
+
const { report, hintUpgrade, seqAdvanced, calibration, calibrationMs } = result;
|
|
88773
89131
|
appendPassLedger(paths.configDir, "semantic-maintenance", report.durationMs, {
|
|
88774
89132
|
revisitsCleared: report.revisitsCleared,
|
|
88775
89133
|
revisitsStanding: report.revisitsStanding,
|
|
@@ -89116,7 +89474,7 @@ async function startDaemon(opts) {
|
|
|
89116
89474
|
reviewUrl: () => webUiUrl + "/review"
|
|
89117
89475
|
});
|
|
89118
89476
|
const writeLockFile = (url2) => {
|
|
89119
|
-
|
|
89477
|
+
writeFileSync25(
|
|
89120
89478
|
engine.paths.daemonLock,
|
|
89121
89479
|
daemonLockPayload({ pid: process.pid, webUiUrl: url2, processStartedAt, version: DAEMON_VERSION }),
|
|
89122
89480
|
"utf8"
|
|
@@ -89365,8 +89723,8 @@ async function linkRegisteredWorkspaces(cfg, loggedInProfile = cfg.activeInstall
|
|
|
89365
89723
|
}
|
|
89366
89724
|
|
|
89367
89725
|
// src/edge-park.ts
|
|
89368
|
-
import { readFileSync as
|
|
89369
|
-
import { dirname as
|
|
89726
|
+
import { readFileSync as readFileSync34, renameSync as renameSync6, writeFileSync as writeFileSync26 } from "node:fs";
|
|
89727
|
+
import { dirname as dirname14, join as join38 } from "node:path";
|
|
89370
89728
|
var EDGE_PARK_CAP = 2e3;
|
|
89371
89729
|
var EDGE_PARK_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
89372
89730
|
var EDGE_PARK_MAX_ATTEMPTS = 6;
|
|
@@ -89381,12 +89739,12 @@ function wireEdgeKey(from, type, to) {
|
|
|
89381
89739
|
return JSON.stringify([from, type, to]);
|
|
89382
89740
|
}
|
|
89383
89741
|
function edgeParkPath(workspaceConfigDir, destinationKey) {
|
|
89384
|
-
return
|
|
89742
|
+
return join38(workspaceConfigDir, `edge-park.${destinationKey.slice(0, 16)}.json`);
|
|
89385
89743
|
}
|
|
89386
89744
|
function loadEdgePark(path3) {
|
|
89387
89745
|
let raw2;
|
|
89388
89746
|
try {
|
|
89389
|
-
raw2 = JSON.parse(
|
|
89747
|
+
raw2 = JSON.parse(readFileSync34(path3, "utf8"));
|
|
89390
89748
|
} catch {
|
|
89391
89749
|
return [];
|
|
89392
89750
|
}
|
|
@@ -89397,9 +89755,9 @@ function loadEdgePark(path3) {
|
|
|
89397
89755
|
}
|
|
89398
89756
|
function saveEdgePark(path3, queue) {
|
|
89399
89757
|
try {
|
|
89400
|
-
const tmp =
|
|
89401
|
-
|
|
89402
|
-
|
|
89758
|
+
const tmp = join38(dirname14(path3), `.${Date.now()}.edge-park.tmp`);
|
|
89759
|
+
writeFileSync26(tmp, JSON.stringify(queue), "utf8");
|
|
89760
|
+
renameSync6(tmp, path3);
|
|
89403
89761
|
} catch {
|
|
89404
89762
|
}
|
|
89405
89763
|
}
|
|
@@ -89414,6 +89772,14 @@ function edgeHolds(queue, now) {
|
|
|
89414
89772
|
}
|
|
89415
89773
|
return holds;
|
|
89416
89774
|
}
|
|
89775
|
+
function nextEdgeParkChange(queue) {
|
|
89776
|
+
let next = null;
|
|
89777
|
+
for (const e of queue) {
|
|
89778
|
+
const at = e.state === "dropped" ? (e.droppedAt ?? e.ts) + tombstoneTtl(e) : e.dueAt;
|
|
89779
|
+
if (next === null || at < next) next = at;
|
|
89780
|
+
}
|
|
89781
|
+
return next;
|
|
89782
|
+
}
|
|
89417
89783
|
function classifyEdgeVerdict(decision, reason) {
|
|
89418
89784
|
if (decision === "created" || decision === "reinforced") return "landed";
|
|
89419
89785
|
const why = reason ?? "";
|
|
@@ -89711,8 +90077,8 @@ function invalidateInstanceReceipt(current, destination, failedId, mirrorLegacy)
|
|
|
89711
90077
|
// src/multi.ts
|
|
89712
90078
|
init_dist();
|
|
89713
90079
|
init_src5();
|
|
89714
|
-
import { existsSync as existsSync34, writeFileSync as
|
|
89715
|
-
import { resolve as pathResolve } from "node:path";
|
|
90080
|
+
import { existsSync as existsSync34, readFileSync as readFileSync40, writeFileSync as writeFileSync29 } from "node:fs";
|
|
90081
|
+
import { join as join47, resolve as pathResolve } from "node:path";
|
|
89716
90082
|
|
|
89717
90083
|
// src/principle-sync.ts
|
|
89718
90084
|
init_src5();
|
|
@@ -89740,8 +90106,8 @@ init_reconcile();
|
|
|
89740
90106
|
|
|
89741
90107
|
// src/lockfile-auto.ts
|
|
89742
90108
|
init_src();
|
|
89743
|
-
import { existsSync as existsSync30, readFileSync as
|
|
89744
|
-
import { join as
|
|
90109
|
+
import { existsSync as existsSync30, readFileSync as readFileSync35 } from "node:fs";
|
|
90110
|
+
import { join as join39 } from "node:path";
|
|
89745
90111
|
|
|
89746
90112
|
// src/package-index.ts
|
|
89747
90113
|
init_src();
|
|
@@ -89766,10 +90132,23 @@ function buildContextNode(id, label, description, attrs, ts) {
|
|
|
89766
90132
|
attrs
|
|
89767
90133
|
};
|
|
89768
90134
|
}
|
|
90135
|
+
function mintContextNode(store, node2) {
|
|
90136
|
+
const existing = store.getNode(node2.id);
|
|
90137
|
+
if (!existing || (existing.validTo ?? null) !== null) {
|
|
90138
|
+
store.mergeNode(node2);
|
|
90139
|
+
return true;
|
|
90140
|
+
}
|
|
90141
|
+
const facts = Object.keys(node2.attrs);
|
|
90142
|
+
const same = existing.label === node2.label && existing.description === node2.description && facts.every((k) => JSON.stringify(existing.attrs[k]) === JSON.stringify(node2.attrs[k]));
|
|
90143
|
+
if (same) return false;
|
|
90144
|
+
store.updateNode(node2.id, { description: node2.description, attrs: { ...existing.attrs, ...node2.attrs }, lastUpdatedAt: node2.lastUpdatedAt });
|
|
90145
|
+
return true;
|
|
90146
|
+
}
|
|
89769
90147
|
function mintPackageGraph(store, sbom, workspaceId2, ts) {
|
|
89770
90148
|
const minted = /* @__PURE__ */ new Set();
|
|
89771
90149
|
for (const c of sbom.components) {
|
|
89772
|
-
|
|
90150
|
+
mintContextNode(
|
|
90151
|
+
store,
|
|
89773
90152
|
buildContextNode(
|
|
89774
90153
|
c.purl,
|
|
89775
90154
|
"Package",
|
|
@@ -89792,8 +90171,14 @@ function mintPackageGraph(store, sbom, workspaceId2, ts) {
|
|
|
89792
90171
|
if (!minted.has(d.ref)) continue;
|
|
89793
90172
|
for (const to of d.dependsOn) {
|
|
89794
90173
|
if (!minted.has(to)) continue;
|
|
90174
|
+
const id = `edge_${digest({ from: d.ref, type: "DEPENDS_ON", to })}`.slice(0, 24);
|
|
90175
|
+
const live3 = store.getEdge(id);
|
|
90176
|
+
if (live3 && (live3.validTo ?? null) === null) {
|
|
90177
|
+
edges++;
|
|
90178
|
+
continue;
|
|
90179
|
+
}
|
|
89795
90180
|
store.mergeEdge({
|
|
89796
|
-
id
|
|
90181
|
+
id,
|
|
89797
90182
|
from: d.ref,
|
|
89798
90183
|
to,
|
|
89799
90184
|
type: "DEPENDS_ON",
|
|
@@ -89815,9 +90200,7 @@ function mintLanguageNodes(store, languages, workspaceId2, ts) {
|
|
|
89815
90200
|
for (const raw2 of languages) {
|
|
89816
90201
|
const name2 = raw2.trim();
|
|
89817
90202
|
if (!name2) continue;
|
|
89818
|
-
store.
|
|
89819
|
-
buildContextNode(`lang:${name2.toLowerCase()}`, "Language", name2, { name: name2, workspaceId: workspaceId2 }, ts)
|
|
89820
|
-
);
|
|
90203
|
+
mintContextNode(store, buildContextNode(`lang:${name2.toLowerCase()}`, "Language", name2, { name: name2, workspaceId: workspaceId2 }, ts));
|
|
89821
90204
|
n++;
|
|
89822
90205
|
}
|
|
89823
90206
|
return n;
|
|
@@ -89864,10 +90247,14 @@ function buildContextIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
89864
90247
|
}
|
|
89865
90248
|
}
|
|
89866
90249
|
if (nodes.length === 0) return null;
|
|
90250
|
+
const contributed = (id) => {
|
|
90251
|
+
const n = store.getNode(id);
|
|
90252
|
+
return !!n && (n.label === "Package" || n.label === "Language") && n.attrs["source"] !== "cloud" && typeof n.attrs["contributedAtSeq"] === "number" && !ignored(n.description) && !ignored(String(n.attrs["name"] ?? ""));
|
|
90253
|
+
};
|
|
89867
90254
|
const edges = [];
|
|
89868
90255
|
for (const id of seen) {
|
|
89869
90256
|
for (const e of store.outEdges(id, ["DEPENDS_ON"])) {
|
|
89870
|
-
if (seen.has(e.to)) edges.push({ ...e, attrs: {} });
|
|
90257
|
+
if (seen.has(e.to) || contributed(e.to)) edges.push({ ...e, attrs: {} });
|
|
89871
90258
|
}
|
|
89872
90259
|
}
|
|
89873
90260
|
const base = {
|
|
@@ -89893,11 +90280,11 @@ function runLockfilePass(opts) {
|
|
|
89893
90280
|
{ file: "package-lock.json", parse: parsePackageLockJson }
|
|
89894
90281
|
];
|
|
89895
90282
|
for (const c of candidates) {
|
|
89896
|
-
const p =
|
|
90283
|
+
const p = join39(opts.root, c.file);
|
|
89897
90284
|
if (!existsSync30(p)) continue;
|
|
89898
90285
|
let sbom;
|
|
89899
90286
|
try {
|
|
89900
|
-
sbom = c.parse(
|
|
90287
|
+
sbom = c.parse(readFileSync35(p, "utf8"));
|
|
89901
90288
|
} catch {
|
|
89902
90289
|
continue;
|
|
89903
90290
|
}
|
|
@@ -89958,8 +90345,8 @@ init_profile2();
|
|
|
89958
90345
|
init_session_registry();
|
|
89959
90346
|
|
|
89960
90347
|
// src/public-symbols.ts
|
|
89961
|
-
import { readFileSync as
|
|
89962
|
-
import { join as
|
|
90348
|
+
import { readFileSync as readFileSync36, readdirSync as readdirSync12, existsSync as existsSync31 } from "node:fs";
|
|
90349
|
+
import { join as join40 } from "node:path";
|
|
89963
90350
|
var HEAD_BYTES = 8 * 1024;
|
|
89964
90351
|
var INDEX_TTL_MS = 10 * 60 * 1e3;
|
|
89965
90352
|
var MIN_SYMBOL_LEN = 4;
|
|
@@ -89992,20 +90379,20 @@ function bindingNames(clause) {
|
|
|
89992
90379
|
function internalPackageNames(workspaceRoot) {
|
|
89993
90380
|
const names = /* @__PURE__ */ new Set();
|
|
89994
90381
|
const tryRead = (dir) => {
|
|
89995
|
-
const pj =
|
|
90382
|
+
const pj = join40(dir, "package.json");
|
|
89996
90383
|
if (!existsSync31(pj)) return;
|
|
89997
90384
|
try {
|
|
89998
|
-
const name2 = JSON.parse(
|
|
90385
|
+
const name2 = JSON.parse(readFileSync36(pj, "utf8")).name;
|
|
89999
90386
|
if (typeof name2 === "string" && name2.length > 0) names.add(name2);
|
|
90000
90387
|
} catch {
|
|
90001
90388
|
}
|
|
90002
90389
|
};
|
|
90003
90390
|
tryRead(workspaceRoot);
|
|
90004
90391
|
for (const group of ["packages", "apps"]) {
|
|
90005
|
-
const groupDir =
|
|
90392
|
+
const groupDir = join40(workspaceRoot, group);
|
|
90006
90393
|
if (!existsSync31(groupDir)) continue;
|
|
90007
90394
|
try {
|
|
90008
|
-
for (const entry of readdirSync12(groupDir)) tryRead(
|
|
90395
|
+
for (const entry of readdirSync12(groupDir)) tryRead(join40(groupDir, entry));
|
|
90009
90396
|
} catch {
|
|
90010
90397
|
}
|
|
90011
90398
|
}
|
|
@@ -90024,7 +90411,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
|
|
|
90024
90411
|
}
|
|
90025
90412
|
const readHead = deps.readHead ?? ((absPath) => {
|
|
90026
90413
|
try {
|
|
90027
|
-
return
|
|
90414
|
+
return readFileSync36(absPath, "utf8").slice(0, HEAD_BYTES);
|
|
90028
90415
|
} catch {
|
|
90029
90416
|
return "";
|
|
90030
90417
|
}
|
|
@@ -90044,7 +90431,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
|
|
|
90044
90431
|
}
|
|
90045
90432
|
const symbols = /* @__PURE__ */ new Set();
|
|
90046
90433
|
for (const rel of files) {
|
|
90047
|
-
const head2 = readHead(
|
|
90434
|
+
const head2 = readHead(join40(workspaceRoot, rel));
|
|
90048
90435
|
if (!head2) continue;
|
|
90049
90436
|
for (const re of [NAMED_IMPORT_RE, REQUIRE_RE]) {
|
|
90050
90437
|
re.lastIndex = 0;
|
|
@@ -91029,7 +91416,7 @@ init_config();
|
|
|
91029
91416
|
|
|
91030
91417
|
// src/update.ts
|
|
91031
91418
|
import { spawn as spawn2 } from "node:child_process";
|
|
91032
|
-
import { isAbsolute as
|
|
91419
|
+
import { isAbsolute as isAbsolute5, join as join41 } from "node:path";
|
|
91033
91420
|
var PACKAGE_NAME = "@inerrata-corporation/errata";
|
|
91034
91421
|
function parse3(v) {
|
|
91035
91422
|
const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z][0-9A-Za-z.-]*))?/.exec(v.trim());
|
|
@@ -91174,9 +91561,9 @@ async function runInstalledHookRefresh() {
|
|
|
91174
91561
|
child.on("error", () => resolve10(""));
|
|
91175
91562
|
child.on("close", (code) => resolve10(code === 0 ? output.trim() : ""));
|
|
91176
91563
|
});
|
|
91177
|
-
if (!
|
|
91564
|
+
if (!isAbsolute5(root)) return 1;
|
|
91178
91565
|
return new Promise((resolve10) => {
|
|
91179
|
-
const child = spawn2(process.execPath, [
|
|
91566
|
+
const child = spawn2(process.execPath, [join41(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
|
|
91180
91567
|
windowsHide: true,
|
|
91181
91568
|
stdio: "inherit",
|
|
91182
91569
|
timeout: 3e4
|
|
@@ -91322,12 +91709,12 @@ function landCloudEdge(store, e, from, to) {
|
|
|
91322
91709
|
}
|
|
91323
91710
|
|
|
91324
91711
|
// src/causal-edge-queue.ts
|
|
91325
|
-
import { readFileSync as
|
|
91326
|
-
import { dirname as
|
|
91712
|
+
import { readFileSync as readFileSync37, renameSync as renameSync7, writeFileSync as writeFileSync27 } from "node:fs";
|
|
91713
|
+
import { dirname as dirname15, join as join42 } from "node:path";
|
|
91327
91714
|
var CAUSAL_EDGE_QUEUE_CAP = 5e3;
|
|
91328
91715
|
var CAUSAL_EDGE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
91329
91716
|
function causalEdgeQueuePath(workspaceConfigDir) {
|
|
91330
|
-
return
|
|
91717
|
+
return join42(workspaceConfigDir, "causal-edge-queue.json");
|
|
91331
91718
|
}
|
|
91332
91719
|
function parkedEdgeKey(e) {
|
|
91333
91720
|
return `${e.from}|${e.type}|${e.to}`;
|
|
@@ -91335,7 +91722,7 @@ function parkedEdgeKey(e) {
|
|
|
91335
91722
|
function loadCausalEdgeQueue(path3) {
|
|
91336
91723
|
let raw2;
|
|
91337
91724
|
try {
|
|
91338
|
-
raw2 = JSON.parse(
|
|
91725
|
+
raw2 = JSON.parse(readFileSync37(path3, "utf8"));
|
|
91339
91726
|
} catch {
|
|
91340
91727
|
return [];
|
|
91341
91728
|
}
|
|
@@ -91346,9 +91733,9 @@ function loadCausalEdgeQueue(path3) {
|
|
|
91346
91733
|
}
|
|
91347
91734
|
function saveCausalEdgeQueue(path3, queue) {
|
|
91348
91735
|
try {
|
|
91349
|
-
const tmp =
|
|
91350
|
-
|
|
91351
|
-
|
|
91736
|
+
const tmp = join42(dirname15(path3), `.${Date.now()}.causal-edge-queue.tmp`);
|
|
91737
|
+
writeFileSync27(tmp, JSON.stringify(queue), "utf8");
|
|
91738
|
+
renameSync7(tmp, path3);
|
|
91352
91739
|
} catch {
|
|
91353
91740
|
}
|
|
91354
91741
|
}
|
|
@@ -91484,6 +91871,10 @@ async function lookupLive(store, m, id) {
|
|
|
91484
91871
|
const second = (await m.refresh()).get(id);
|
|
91485
91872
|
return second && isLive(store, second) ? second : null;
|
|
91486
91873
|
}
|
|
91874
|
+
function reverseSymbolResolver(opts) {
|
|
91875
|
+
const m = cachedMap(reverseCache, opts.store, `${opts.projectId}|${opts.salt}`, () => buildReverseSymbolMap(opts));
|
|
91876
|
+
return (symbolId) => lookupLive(opts.store, m, symbolId);
|
|
91877
|
+
}
|
|
91487
91878
|
function isLive(store, id) {
|
|
91488
91879
|
const n = store.getNode(id);
|
|
91489
91880
|
return n !== null && (n.validTo === null || n.validTo === void 0);
|
|
@@ -91774,7 +92165,9 @@ init_src11();
|
|
|
91774
92165
|
init_src();
|
|
91775
92166
|
import { execFile as execFile5 } from "node:child_process";
|
|
91776
92167
|
import { promisify as promisify4 } from "node:util";
|
|
91777
|
-
import { extname as extname3 } from "node:path";
|
|
92168
|
+
import { extname as extname3, join as join43 } from "node:path";
|
|
92169
|
+
import { createHash as createHash19 } from "node:crypto";
|
|
92170
|
+
import { readFileSync as readFileSync38 } from "node:fs";
|
|
91778
92171
|
|
|
91779
92172
|
// src/history-dependency-snapshot.ts
|
|
91780
92173
|
init_src();
|
|
@@ -91785,22 +92178,20 @@ async function readHistoryDependencySnapshot(opts) {
|
|
|
91785
92178
|
const git3 = opts.git ?? (async (args2) => (await exec("git", ["-C", opts.root, ...args2], { windowsHide: true, maxBuffer: 16 * 1024 * 1024 })).stdout);
|
|
91786
92179
|
const read2 = opts.readBlob ?? (async (oid) => git3(["show", oid]));
|
|
91787
92180
|
let complete = true;
|
|
91788
|
-
const tree = await git3(["ls-tree", "-r", opts.commit]).catch(() => null);
|
|
92181
|
+
const tree = await git3(["ls-tree", "-r", "-z", opts.commit]).catch(() => null);
|
|
91789
92182
|
if (tree === null) return { schemaVersion: "history-deps-1", complete: false, dependencies: [] };
|
|
91790
|
-
const entries = tree.split("\
|
|
91791
|
-
const match2 = /^\d+ blob ([a-f0-9]+)\t(
|
|
91792
|
-
|
|
91793
|
-
const path3 = match2[2].replace(/^"|"$/g, "");
|
|
91794
|
-
if (path3.includes("\\") || /[\r\n]/.test(path3)) {
|
|
91795
|
-
complete = false;
|
|
91796
|
-
return [];
|
|
91797
|
-
}
|
|
91798
|
-
return [{ path: path3, oid: match2[1] }];
|
|
92183
|
+
const entries = tree.split("\0").flatMap((row) => {
|
|
92184
|
+
const match2 = /^\d+ blob ([a-f0-9]+)\t([^]+)$/.exec(row);
|
|
92185
|
+
return match2 ? [{ path: match2[2], oid: match2[1] }] : [];
|
|
91799
92186
|
});
|
|
91800
92187
|
const manifests = {}, locks = {};
|
|
91801
92188
|
for (const { path: path3, oid } of entries) {
|
|
91802
|
-
const lock = /(?:^|\/)(?:pnpm-lock
|
|
92189
|
+
const lock = /(?:^|\/)(?:pnpm-lock\.yaml|package-lock\.json)$/.test(path3);
|
|
91803
92190
|
if (!lock && (!isManifestPath(path3) || opts.manifestIds && !opts.manifestIds.has(historyManifestId(path3)))) continue;
|
|
92191
|
+
if (path3.includes("\\") || /[\r\n]/.test(path3)) {
|
|
92192
|
+
complete = false;
|
|
92193
|
+
continue;
|
|
92194
|
+
}
|
|
91804
92195
|
if (opts.paths && !Object.values(opts.paths).some((p) => !path3.includes("/") || p.startsWith(path3.slice(0, path3.lastIndexOf("/") + 1)))) continue;
|
|
91805
92196
|
if (opts.allowPath && !opts.allowPath(path3)) {
|
|
91806
92197
|
complete = false;
|
|
@@ -91883,6 +92274,38 @@ init_profile2();
|
|
|
91883
92274
|
var exec2 = promisify4(execFile5);
|
|
91884
92275
|
var KINDS = { function: "Function", class: "Class", method: "Method", interface: "Interface", const: "Const", enum: "Enum", typealias: "TypeAlias", namespace: "Namespace", property: "Property" };
|
|
91885
92276
|
var inFlight = /* @__PURE__ */ new Map();
|
|
92277
|
+
var carryRefused = /* @__PURE__ */ new Set();
|
|
92278
|
+
var carryFailures = /* @__PURE__ */ new Map();
|
|
92279
|
+
var CARRY_ATTEMPTS = 3;
|
|
92280
|
+
var Bounded = class extends Map {
|
|
92281
|
+
constructor(cap) {
|
|
92282
|
+
super();
|
|
92283
|
+
this.cap = cap;
|
|
92284
|
+
}
|
|
92285
|
+
set(key, value) {
|
|
92286
|
+
if (!this.has(key) && this.size >= this.cap) this.delete(this.keys().next().value);
|
|
92287
|
+
return super.set(key, value);
|
|
92288
|
+
}
|
|
92289
|
+
};
|
|
92290
|
+
var DEFAULT_GIT = {};
|
|
92291
|
+
function readFileSafe(path3) {
|
|
92292
|
+
try {
|
|
92293
|
+
return readFileSync38(path3, "utf8");
|
|
92294
|
+
} catch {
|
|
92295
|
+
return "";
|
|
92296
|
+
}
|
|
92297
|
+
}
|
|
92298
|
+
var revisionCaches = /* @__PURE__ */ new WeakMap();
|
|
92299
|
+
function cachesFor(git3) {
|
|
92300
|
+
let caches = revisionCaches.get(git3);
|
|
92301
|
+
if (!caches) {
|
|
92302
|
+
caches = { parents: new Bounded(4), dependencies: new Bounded(8), trees: new Bounded(4), symbols: new Bounded(4e3), diffs: new Bounded(2e3) };
|
|
92303
|
+
revisionCaches.set(git3, caches);
|
|
92304
|
+
}
|
|
92305
|
+
return caches;
|
|
92306
|
+
}
|
|
92307
|
+
var REVISION_DIFF_TOKENS = 4e3;
|
|
92308
|
+
var REVISION_RAW_DIFF_CHARS = REVISION_DIFF_TOKENS * 4 * 4;
|
|
91886
92309
|
async function syncHistoryRevision(opts) {
|
|
91887
92310
|
const current = inFlight.get(opts.root);
|
|
91888
92311
|
if (current) return current;
|
|
@@ -91890,12 +92313,13 @@ async function syncHistoryRevision(opts) {
|
|
|
91890
92313
|
const started2 = Date.now();
|
|
91891
92314
|
let changed = 0, remaining = false;
|
|
91892
92315
|
const pages = Math.min(20, Math.max(1, opts.maxPages ?? 10));
|
|
92316
|
+
const resolve10 = opts.profile.projectId ? reverseSymbolResolver({ store: opts.store, salt: opts.salt, projectId: opts.profile.projectId }) : async () => null;
|
|
91893
92317
|
for (let i2 = 0; i2 < pages; i2++) {
|
|
91894
|
-
const result = await syncHistoryRevisionPage(opts);
|
|
92318
|
+
const result = await syncHistoryRevisionPage(opts, resolve10);
|
|
91895
92319
|
changed += result.changed;
|
|
91896
92320
|
remaining = result.remaining;
|
|
91897
|
-
if (!remaining || Date.now() - started2 >= (opts.budgetMs ?? 45e3)) break;
|
|
91898
|
-
await new Promise((
|
|
92321
|
+
if (!remaining || result.nextBeat || Date.now() - started2 >= (opts.budgetMs ?? 45e3)) break;
|
|
92322
|
+
await new Promise((resolve11) => setImmediate(resolve11));
|
|
91899
92323
|
}
|
|
91900
92324
|
return { changed, remaining };
|
|
91901
92325
|
})();
|
|
@@ -91906,78 +92330,147 @@ async function syncHistoryRevision(opts) {
|
|
|
91906
92330
|
if (inFlight.get(opts.root) === work) inFlight.delete(opts.root);
|
|
91907
92331
|
}
|
|
91908
92332
|
}
|
|
91909
|
-
async function syncHistoryRevisionPage(opts) {
|
|
92333
|
+
async function syncHistoryRevisionPage(opts, resolve10) {
|
|
91910
92334
|
const { root, profile, store, cloud, salt } = opts;
|
|
91911
92335
|
if (!profile.projectId) return { changed: 0, remaining: false };
|
|
91912
92336
|
const projectId = profile.projectId;
|
|
91913
92337
|
const git3 = opts.git ?? (async (args2) => (await exec2("git", ["-C", root, ...args2], { windowsHide: true, maxBuffer: 8 * 1024 * 1024 })).stdout);
|
|
92338
|
+
const caches = cachesFor(opts.git ?? DEFAULT_GIT);
|
|
92339
|
+
const ignoreKey = createHash19("sha256").update(JSON.stringify(profile.ignoreExtra ?? [])).update(readFileSafe(join43(root, ".errataignore"))).digest("hex").slice(0, 16);
|
|
91914
92340
|
const atCommit = (await git3(["rev-parse", "--verify", "HEAD"])).trim();
|
|
91915
92341
|
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(atCommit)) throw new Error("history revision is not a full Git object id");
|
|
91916
92342
|
const oldCursor = profile.historyRevisionCursor;
|
|
91917
|
-
const
|
|
91918
|
-
if (
|
|
91919
|
-
|
|
91920
|
-
|
|
91921
|
-
|
|
92343
|
+
const save = () => (opts.save ?? ((p) => saveProfile(root, p)))(profile);
|
|
92344
|
+
if (oldCursor && oldCursor.ignoreKey !== ignoreKey && oldCursor.reprove !== ignoreKey) {
|
|
92345
|
+
profile.historyRevisionCursor = { ...oldCursor, atCommit, complete: false, after: void 0, reprove: ignoreKey, updatedAt: Date.now() };
|
|
92346
|
+
delete profile.historyRevisionCursor.after;
|
|
92347
|
+
save();
|
|
92348
|
+
}
|
|
92349
|
+
const cursor = profile.historyRevisionCursor;
|
|
92350
|
+
const head2 = cursor?.head ?? cursor?.atCommit;
|
|
92351
|
+
if (cursor && head2 && head2 !== atCommit && cloud.carryHistory && !carryRefused.has(root)) {
|
|
92352
|
+
const range = `${root}|${head2}|${atCommit}`;
|
|
92353
|
+
try {
|
|
92354
|
+
const carry = await carryRequest({
|
|
92355
|
+
git: git3,
|
|
92356
|
+
caches,
|
|
92357
|
+
root,
|
|
92358
|
+
salt,
|
|
92359
|
+
projectId,
|
|
92360
|
+
providers: defaultProviders(),
|
|
92361
|
+
from: head2,
|
|
92362
|
+
at: atCommit,
|
|
92363
|
+
rulesChanged: cursor.ignoreKey !== ignoreKey
|
|
92364
|
+
});
|
|
92365
|
+
await cloud.carryHistory(projectId, carry);
|
|
92366
|
+
carryFailures.delete(range);
|
|
92367
|
+
} catch (err2) {
|
|
92368
|
+
if (err2.status === 404) {
|
|
92369
|
+
carryRefused.add(root);
|
|
92370
|
+
console.warn(`[errata] the cloud predates history carry; every new commit re-proves all history verdicts for ${profile.name}`);
|
|
92371
|
+
} else {
|
|
92372
|
+
const failures = (carryFailures.get(range) ?? 0) + 1;
|
|
92373
|
+
carryFailures.set(range, failures);
|
|
92374
|
+
console.warn(`[errata] history carry ${head2.slice(0, 12)}..${atCommit.slice(0, 12)} failed (${failures}/${CARRY_ATTEMPTS})${failures >= CARRY_ATTEMPTS ? "; re-proving this commit instead" : ""}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
92375
|
+
if (failures < CARRY_ATTEMPTS) return { changed: 0, remaining: true, nextBeat: true };
|
|
92376
|
+
carryFailures.delete(range);
|
|
92377
|
+
}
|
|
92378
|
+
}
|
|
92379
|
+
profile.historyRevisionCursor = { ...cursor, head: atCommit };
|
|
92380
|
+
save();
|
|
92381
|
+
}
|
|
92382
|
+
const current = profile.historyRevisionCursor;
|
|
92383
|
+
const reproving = current?.reprove === ignoreKey;
|
|
92384
|
+
const same = current?.atCommit === atCommit;
|
|
92385
|
+
if (same && current.complete && Date.now() - current.updatedAt < 60 * 6e4) return { changed: 0, remaining: false };
|
|
92386
|
+
const after = current && !current.complete ? current.after : void 0;
|
|
92387
|
+
const sweepCommit = after ? current.atCommit : atCommit;
|
|
92388
|
+
const page = await cloud.getHistoryOccurrences(projectId, atCommit, after, { pendingOnly: !reproving });
|
|
91922
92389
|
if (!Array.isArray(page.occurrences) || page.occurrences.length > 50 || page.occurrences.some((o, i2) => o.occurrenceId <= (page.occurrences[i2 - 1]?.occurrenceId ?? after ?? "")) || page.cursor !== null && page.cursor !== page.occurrences.at(-1)?.occurrenceId) throw new Error("invalid history occurrence page");
|
|
91923
|
-
const
|
|
91924
|
-
|
|
91925
|
-
|
|
91926
|
-
|
|
91927
|
-
|
|
92390
|
+
const toPost = page.occurrences.filter((o) => !settledHistoryReceipt(o.quality["reconciliationEvidence"]) || reproving && o.quality["historicalAnchors"]?.length);
|
|
92391
|
+
let parents = [];
|
|
92392
|
+
if (toPost.length) {
|
|
92393
|
+
const key = `${root}|${atCommit}`;
|
|
92394
|
+
parents = caches.parents.get(key) ?? (await git3(["rev-list", "--parents", "--max-count=8192", atCommit])).trim().split("\n").filter(Boolean).map((row) => {
|
|
92395
|
+
const [commit, ...parents2] = row.trim().split(/\s+/);
|
|
92396
|
+
return { commit, parents: parents2 };
|
|
92397
|
+
});
|
|
92398
|
+
caches.parents.set(key, parents);
|
|
92399
|
+
}
|
|
91928
92400
|
const ignore2 = loadRepoIgnore(root, profile.ignoreExtra ?? []);
|
|
91929
92401
|
const providers = defaultProviders();
|
|
91930
|
-
const parsedFiles = /* @__PURE__ */ new Map();
|
|
91931
92402
|
const observations = [];
|
|
91932
|
-
const contexts =
|
|
92403
|
+
const contexts = toPost.map((o) => HistoryDependencyContextSchema.safeParse(o.quality["dependencyContext"]));
|
|
91933
92404
|
const manifestIds = new Set(contexts.flatMap((c) => c.success ? c.data.dependencies.map((d) => d.manifestId) : []));
|
|
91934
|
-
|
|
91935
|
-
|
|
91936
|
-
|
|
91937
|
-
|
|
91938
|
-
|
|
91939
|
-
|
|
91940
|
-
|
|
91941
|
-
|
|
91942
|
-
|
|
92405
|
+
let currentDependencies;
|
|
92406
|
+
if (manifestIds.size) {
|
|
92407
|
+
const key = `${root}|${atCommit}|${ignoreKey}|${[...manifestIds].sort().join(",")}`;
|
|
92408
|
+
let snapshot = caches.dependencies.get(key);
|
|
92409
|
+
if (!snapshot) {
|
|
92410
|
+
snapshot = readHistoryDependencySnapshot({
|
|
92411
|
+
root,
|
|
92412
|
+
commit: atCommit,
|
|
92413
|
+
side: "after",
|
|
92414
|
+
manifestIds,
|
|
92415
|
+
git: git3,
|
|
92416
|
+
allowPath: (p) => pathAllowedByFloor(p) && !isPathBlocked(ignore2, p)
|
|
92417
|
+
});
|
|
92418
|
+
caches.dependencies.set(key, snapshot);
|
|
92419
|
+
snapshot.catch(() => caches.dependencies.delete(key));
|
|
92420
|
+
}
|
|
92421
|
+
currentDependencies = await snapshot;
|
|
92422
|
+
}
|
|
92423
|
+
const treeKey = `${root}|${atCommit}`;
|
|
92424
|
+
let tree = caches.trees.get(treeKey);
|
|
92425
|
+
if (!tree && toPost.length) {
|
|
92426
|
+
tree = git3(["ls-tree", "-r", "-z", "--full-tree", atCommit]).then((out2) => new Map(out2.split("\0").flatMap((row) => {
|
|
92427
|
+
const tab = row.indexOf(" "), [, type, blob] = row.slice(0, tab).split(" ");
|
|
92428
|
+
return tab > 0 && type === "blob" && blob ? [[row.slice(tab + 1), blob]] : [];
|
|
92429
|
+
})));
|
|
92430
|
+
caches.trees.set(treeKey, tree);
|
|
92431
|
+
tree.catch(() => caches.trees.delete(treeKey));
|
|
92432
|
+
}
|
|
92433
|
+
const blobs = await (tree ?? Promise.resolve(/* @__PURE__ */ new Map())).catch(() => /* @__PURE__ */ new Map());
|
|
92434
|
+
const fileId = (path3) => blobs.get(path3) ?? `commit:${atCommit}`;
|
|
92435
|
+
for (const occurrence of toPost) {
|
|
91943
92436
|
const anchors = occurrence.quality["historicalAnchors"];
|
|
91944
92437
|
const paths = /* @__PURE__ */ new Set(), symbols = [];
|
|
92438
|
+
let partial2 = false;
|
|
91945
92439
|
for (const anchor of anchors ?? []) {
|
|
91946
|
-
const localId =
|
|
92440
|
+
const localId = await resolve10(anchor.symbolId), local = localId ? store.getNode(localId) : null;
|
|
91947
92441
|
const path3 = local?.attrs["relPath"];
|
|
91948
92442
|
if (typeof path3 !== "string" || !pathAllowedByFloor(path3) || isPathBlocked(ignore2, path3) || /[\r\n]/.test(path3)) continue;
|
|
91949
92443
|
paths.add(path3);
|
|
91950
|
-
|
|
91951
|
-
|
|
91952
|
-
|
|
91953
|
-
const provider = providers.find((p) => p.fileExtensions.includes(extname3(path3).toLowerCase()));
|
|
91954
|
-
if (!provider) continue;
|
|
91955
|
-
const source2 = await git3(["show", `${atCommit}:${path3}`]).catch(() => null);
|
|
91956
|
-
if (source2 === null || Buffer.byteLength(source2) > 1e6 || source2.includes("\0")) continue;
|
|
91957
|
-
await provider.preload?.();
|
|
91958
|
-
for (const symbol2 of provider.extractSymbols(source2, path3)) {
|
|
91959
|
-
const kind = KINDS[symbol2.kind];
|
|
91960
|
-
if (kind && symbol2.bodyHash) hashes.set(projectSymbolId(salt, projectId, path3, symbol2.qname ?? symbol2.name, kind), symbol2.bodyHash);
|
|
91961
|
-
}
|
|
91962
|
-
}
|
|
91963
|
-
const bodyHash = parsedFiles.get(path3).get(anchor.symbolId);
|
|
92444
|
+
const hashes = await fileSymbols({ caches, providers, root, salt, projectId }, path3, fileId(path3), () => git3(["show", `${atCommit}:${path3}`]));
|
|
92445
|
+
if (!hashes) partial2 = true;
|
|
92446
|
+
const bodyHash = hashes?.get(anchor.symbolId);
|
|
91964
92447
|
if (bodyHash) symbols.push({ symbolId: anchor.symbolId, bodyHash });
|
|
91965
92448
|
}
|
|
91966
92449
|
const source = occurrenceSourceCommit(occurrence);
|
|
91967
92450
|
let diff;
|
|
91968
92451
|
if (source && source !== atCommit && paths.size) {
|
|
91969
|
-
const
|
|
91970
|
-
|
|
91971
|
-
|
|
91972
|
-
|
|
91973
|
-
|
|
91974
|
-
|
|
91975
|
-
|
|
91976
|
-
|
|
91977
|
-
|
|
91978
|
-
|
|
91979
|
-
|
|
91980
|
-
|
|
92452
|
+
const diffKey = `${root}|${ignoreKey}|${source}|${[...paths].sort().map((path3) => `${path3}\0${fileId(path3)}`).join("\0")}`;
|
|
92453
|
+
if (caches.diffs.has(diffKey)) diff = caches.diffs.get(diffKey);
|
|
92454
|
+
else {
|
|
92455
|
+
const bundle = await buildUnitBundle(
|
|
92456
|
+
root,
|
|
92457
|
+
{
|
|
92458
|
+
sha: atCommit,
|
|
92459
|
+
parents: [source],
|
|
92460
|
+
isMerge: true,
|
|
92461
|
+
index: 0,
|
|
92462
|
+
subIndex: 0,
|
|
92463
|
+
subject: "",
|
|
92464
|
+
body: "",
|
|
92465
|
+
authorDate: "",
|
|
92466
|
+
files: [...paths].map((path3) => ({ path: path3, adds: 1, dels: 1, binary: false }))
|
|
92467
|
+
},
|
|
92468
|
+
{ maxTokens: REVISION_DIFF_TOKENS, maxRawDiffChars: REVISION_RAW_DIFF_CHARS, ignorePatterns: profile.ignoreExtra ?? [] }
|
|
92469
|
+
).catch(() => null);
|
|
92470
|
+
if (bundle && !bundle.truncated) diff = bundle.diff;
|
|
92471
|
+
if (bundle) caches.diffs.set(diffKey, diff);
|
|
92472
|
+
else partial2 = true;
|
|
92473
|
+
}
|
|
91981
92474
|
}
|
|
91982
92475
|
const old = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
|
|
91983
92476
|
const dependencyContext = old.success ? {
|
|
@@ -91985,16 +92478,24 @@ async function syncHistoryRevisionPage(opts) {
|
|
|
91985
92478
|
complete: old.data.dependencies.length === 0 || currentDependencies?.complete === true,
|
|
91986
92479
|
dependencies: currentDependencies?.dependencies.filter((d) => old.data.dependencies.some((o) => o.packageId === d.packageId && o.manifestId === d.manifestId)) ?? []
|
|
91987
92480
|
} : void 0;
|
|
92481
|
+
if (partial2) continue;
|
|
91988
92482
|
observations.push({ occurrenceId: occurrence.occurrenceId, symbols, ...diff ? { diff } : {}, ...dependencyContext ? { dependencyContext } : {} });
|
|
91989
92483
|
}
|
|
91990
|
-
const response =
|
|
91991
|
-
if (response.atCommit !== atCommit || response.receipts.length !==
|
|
92484
|
+
const response = observations.length ? await cloud.reconcileHistory(projectId, { atCommit, parents, observations }) : { atCommit, receipts: [] };
|
|
92485
|
+
if (response.atCommit !== atCommit || response.receipts.length !== observations.length || new Set(response.receipts.map((r) => r.occurrenceId)).size !== response.receipts.length || response.receipts.some((r) => r.atCommit !== atCommit || !observations.some((o) => o.occurrenceId === r.occurrenceId))) throw new Error("incomplete history reconciliation response");
|
|
92486
|
+
const receipts = new Map(response.receipts.map((r) => [r.occurrenceId, r]));
|
|
92487
|
+
for (const o of page.occurrences) {
|
|
92488
|
+
if (!receipts.has(o.occurrenceId) && settledHistoryReceipt(o.quality["reconciliationEvidence"])) {
|
|
92489
|
+
receipts.set(o.occurrenceId, { verdict: o.quality["applicability"], evidence: o.quality["reconciliationEvidence"] });
|
|
92490
|
+
}
|
|
92491
|
+
}
|
|
91992
92492
|
const headChanged = (await git3(["rev-parse", "--verify", "HEAD"])).trim() !== atCommit;
|
|
91993
92493
|
let changed = 0;
|
|
91994
92494
|
for (const occurrence of page.occurrences) {
|
|
91995
|
-
const node2 = store
|
|
92495
|
+
const node2 = historyNode(store, occurrence);
|
|
91996
92496
|
if (!node2 || node2.attrs["source"] !== "cloud" || node2.attrs["historyQuality"]?.["sourceSupport"] === "quarantined") continue;
|
|
91997
|
-
const receipt =
|
|
92497
|
+
const receipt = receipts.get(occurrence.occurrenceId);
|
|
92498
|
+
if (!receipt || unchangedRecord(node2, occurrence, receipt, atCommit)) continue;
|
|
91998
92499
|
const previous = node2.attrs["historyQuality"];
|
|
91999
92500
|
if (previous?.["evaluatedAtCommit"] === atCommit && previous["applicability"] === "applicable" && receipt.verdict !== "applicable" && previous["sourceReviewId"] === occurrence.quality["sourceReviewId"] && previous["dependencyReviewId"] === occurrence.quality["dependencyReviewId"] && historyDependencyIdentity(previous["dependencyContext"]) !== null && historyDependencyIdentity(previous["dependencyContext"]) === historyDependencyIdentity(occurrence.quality["dependencyContext"]) && previous["reconciliationEvidence"]?.["build"] === HISTORY_RECONCILE_BUILD) continue;
|
|
92000
92501
|
const dependencies = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
|
|
@@ -92010,17 +92511,115 @@ async function syncHistoryRevisionPage(opts) {
|
|
|
92010
92511
|
} });
|
|
92011
92512
|
changed++;
|
|
92012
92513
|
}
|
|
92013
|
-
|
|
92014
|
-
|
|
92514
|
+
const complete = page.cursor === null;
|
|
92515
|
+
const proven = reproving && complete && sweepCommit === atCommit;
|
|
92516
|
+
const provenKey = proven || !current ? ignoreKey : current.ignoreKey;
|
|
92517
|
+
profile.historyRevisionCursor = {
|
|
92518
|
+
atCommit: sweepCommit,
|
|
92519
|
+
...page.cursor ? { after: page.cursor } : {},
|
|
92520
|
+
complete,
|
|
92521
|
+
updatedAt: Date.now(),
|
|
92522
|
+
head: atCommit,
|
|
92523
|
+
...provenKey !== void 0 ? { ignoreKey: provenKey } : {},
|
|
92524
|
+
...reproving && !proven ? { reprove: ignoreKey } : {}
|
|
92525
|
+
};
|
|
92526
|
+
save();
|
|
92015
92527
|
return { changed, remaining: page.cursor !== null || headChanged || sweepCommit !== atCommit };
|
|
92016
92528
|
}
|
|
92529
|
+
function historyNode(store, occurrence) {
|
|
92530
|
+
return store.getNode(occurrence.canonicalId) ?? (occurrence.nodeId ? store.getNode(occurrence.nodeId) : null);
|
|
92531
|
+
}
|
|
92532
|
+
function unchangedRecord(node2, occurrence, receipt, atCommit) {
|
|
92533
|
+
const previous = node2.attrs["historyQuality"];
|
|
92534
|
+
if (!previous) return false;
|
|
92535
|
+
const stamp = receipt.verdict === "unknown" && previous["applicability"] === "unknown" ? previous["evaluatedAtCommit"] : atCommit;
|
|
92536
|
+
const dependencies = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
|
|
92537
|
+
const next = compactHistoryQuality({
|
|
92538
|
+
...occurrence.quality,
|
|
92539
|
+
evaluatedAtCommit: stamp,
|
|
92540
|
+
applicability: receipt.verdict,
|
|
92541
|
+
reconciliationEvidence: receipt.evidence
|
|
92542
|
+
});
|
|
92543
|
+
return digest(JSON.parse(JSON.stringify(next))) === digest(previous) && digest(dependencies.success ? historyDependencyVersions(dependencies.data) : null) === digest(node2.attrs["depVersions"] ?? null);
|
|
92544
|
+
}
|
|
92545
|
+
async function fileSymbols(ctx, path3, fileId, read2) {
|
|
92546
|
+
const fileKey = `${ctx.root}|${ctx.salt}|${ctx.projectId}|${fileId}|${path3}`;
|
|
92547
|
+
const cached2 = ctx.caches.symbols.get(fileKey);
|
|
92548
|
+
if (cached2) return cached2;
|
|
92549
|
+
const hashes = /* @__PURE__ */ new Map();
|
|
92550
|
+
const provider = ctx.providers.find((p) => p.fileExtensions.includes(extname3(path3).toLowerCase()));
|
|
92551
|
+
if (!provider) {
|
|
92552
|
+
ctx.caches.symbols.set(fileKey, hashes);
|
|
92553
|
+
return hashes;
|
|
92554
|
+
}
|
|
92555
|
+
const source = await read2().catch(() => null);
|
|
92556
|
+
if (source === null) return void 0;
|
|
92557
|
+
ctx.caches.symbols.set(fileKey, hashes);
|
|
92558
|
+
if (Buffer.byteLength(source) > 1e6 || source.includes("\0")) return hashes;
|
|
92559
|
+
await provider.preload?.();
|
|
92560
|
+
for (const symbol2 of provider.extractSymbols(source, path3)) {
|
|
92561
|
+
const kind = KINDS[symbol2.kind];
|
|
92562
|
+
if (kind && symbol2.bodyHash) hashes.set(projectSymbolId(ctx.salt, ctx.projectId, path3, symbol2.qname ?? symbol2.name, kind), symbol2.bodyHash);
|
|
92563
|
+
}
|
|
92564
|
+
return hashes;
|
|
92565
|
+
}
|
|
92566
|
+
var CARRY_MAX_CODE_FILES = 400;
|
|
92567
|
+
var CARRY_MAX_SYMBOLS = 5e3;
|
|
92568
|
+
var CARRY_MAX_MANIFESTS = 512;
|
|
92569
|
+
var CARRY_MAX_COMMITS = 8192;
|
|
92570
|
+
var LOCKFILE = /(?:^|\/)(?:pnpm-lock\.yaml|package-lock\.json)$/;
|
|
92571
|
+
var NO_BLOB = /^0+$/;
|
|
92572
|
+
async function carryRequest(o) {
|
|
92573
|
+
const { git: git3, from, at } = o;
|
|
92574
|
+
let parents = [];
|
|
92575
|
+
if (await git3(["merge-base", "--is-ancestor", from, at]).then(() => true, () => false)) {
|
|
92576
|
+
const rows = `${await git3(["rev-list", "--parents", "--ancestry-path", `--max-count=${CARRY_MAX_COMMITS}`, `${from}..${at}`])}
|
|
92577
|
+
${await git3(["rev-list", "--parents", "-1", from])}`.split("\n").map((row) => row.trim()).filter(Boolean).map((row) => {
|
|
92578
|
+
const [commit, ...parents2] = row.split(/\s+/);
|
|
92579
|
+
return { commit, parents: parents2 };
|
|
92580
|
+
});
|
|
92581
|
+
if (rows.length <= CARRY_MAX_COMMITS) parents = rows;
|
|
92582
|
+
}
|
|
92583
|
+
const fields = (await git3(["diff", "--raw", "--no-renames", "--no-abbrev", "-z", from, at])).split("\0");
|
|
92584
|
+
const changes = [];
|
|
92585
|
+
for (let i2 = 0; i2 + 1 < fields.length; i2 += 2) {
|
|
92586
|
+
const meta3 = fields[i2].trim().split(/\s+/), path3 = fields[i2 + 1];
|
|
92587
|
+
if (meta3.length >= 4 && path3) changes.push({ path: path3, blobs: [meta3[2], meta3[3]].filter((b) => !NO_BLOB.test(b)) });
|
|
92588
|
+
}
|
|
92589
|
+
const manifests = /* @__PURE__ */ new Set(), symbols = /* @__PURE__ */ new Set();
|
|
92590
|
+
let allManifests = o.rulesChanged, allSymbols = o.rulesChanged;
|
|
92591
|
+
const code = changes.filter((c) => o.providers.some((p) => p.fileExtensions.includes(extname3(c.path).toLowerCase())));
|
|
92592
|
+
if (code.length > CARRY_MAX_CODE_FILES) allSymbols = true;
|
|
92593
|
+
for (const change of changes) {
|
|
92594
|
+
if (LOCKFILE.test(change.path)) allManifests = true;
|
|
92595
|
+
else if (isManifestPath(change.path)) manifests.add(historyManifestId(change.path));
|
|
92596
|
+
}
|
|
92597
|
+
for (const change of allSymbols ? [] : code) {
|
|
92598
|
+
for (const blob of change.blobs) {
|
|
92599
|
+
const hashes = await fileSymbols(o, change.path, blob, () => git3(["show", blob]));
|
|
92600
|
+
if (!hashes) {
|
|
92601
|
+
allSymbols = true;
|
|
92602
|
+
break;
|
|
92603
|
+
}
|
|
92604
|
+
for (const id of hashes.keys()) symbols.add(id);
|
|
92605
|
+
}
|
|
92606
|
+
if (allSymbols) break;
|
|
92607
|
+
}
|
|
92608
|
+
return {
|
|
92609
|
+
fromCommit: from,
|
|
92610
|
+
atCommit: at,
|
|
92611
|
+
parents,
|
|
92612
|
+
changedSymbols: allSymbols || symbols.size > CARRY_MAX_SYMBOLS ? null : [...symbols].sort(),
|
|
92613
|
+
changedManifests: allManifests || manifests.size > CARRY_MAX_MANIFESTS ? null : [...manifests].sort()
|
|
92614
|
+
};
|
|
92615
|
+
}
|
|
92017
92616
|
|
|
92018
92617
|
// src/project-history.ts
|
|
92019
92618
|
init_src7();
|
|
92020
92619
|
init_src();
|
|
92021
92620
|
import { execFile as execFile6 } from "node:child_process";
|
|
92022
|
-
import { readFileSync as
|
|
92023
|
-
import { join as
|
|
92621
|
+
import { readFileSync as readFileSync39 } from "node:fs";
|
|
92622
|
+
import { join as join44 } from "node:path";
|
|
92024
92623
|
import { promisify as promisify5 } from "node:util";
|
|
92025
92624
|
|
|
92026
92625
|
// src/history-walk.ts
|
|
@@ -92572,7 +93171,7 @@ async function defaultGit(root, args2) {
|
|
|
92572
93171
|
function readIgnoreLines(root, profile) {
|
|
92573
93172
|
let lines = [];
|
|
92574
93173
|
try {
|
|
92575
|
-
lines =
|
|
93174
|
+
lines = readFileSync39(join44(root, ".errataignore"), "utf8").split("\n");
|
|
92576
93175
|
} catch {
|
|
92577
93176
|
}
|
|
92578
93177
|
return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
@@ -93146,10 +93745,10 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
|
|
|
93146
93745
|
|
|
93147
93746
|
// src/link-flow.ts
|
|
93148
93747
|
init_cloud_auth();
|
|
93149
|
-
import { createHash as
|
|
93748
|
+
import { createHash as createHash20 } from "node:crypto";
|
|
93150
93749
|
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
93151
|
-
import { existsSync as existsSync32, writeFileSync as
|
|
93152
|
-
import { join as
|
|
93750
|
+
import { existsSync as existsSync32, writeFileSync as writeFileSync28 } from "node:fs";
|
|
93751
|
+
import { join as join45 } from "node:path";
|
|
93153
93752
|
|
|
93154
93753
|
// src/device-poll.ts
|
|
93155
93754
|
var THROTTLED_POLL_MIN_WAIT_MS = 11e3;
|
|
@@ -93441,7 +94040,7 @@ async function loginOAuthLoopback(opts) {
|
|
|
93441
94040
|
|
|
93442
94041
|
// src/link-flow.ts
|
|
93443
94042
|
function remoteFingerprint(locator) {
|
|
93444
|
-
return
|
|
94043
|
+
return createHash20("sha256").update(locator).digest("hex");
|
|
93445
94044
|
}
|
|
93446
94045
|
function isDecision(value) {
|
|
93447
94046
|
if (!value || typeof value !== "object") return false;
|
|
@@ -93608,9 +94207,9 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
|
|
|
93608
94207
|
delete nextProfile.projectLinkHold;
|
|
93609
94208
|
let wroteIgnore = false;
|
|
93610
94209
|
if (decision.writeIgnoreStarter !== false) {
|
|
93611
|
-
const target =
|
|
94210
|
+
const target = join45(root, ".errataignore");
|
|
93612
94211
|
if (!existsSync32(target)) {
|
|
93613
|
-
|
|
94212
|
+
writeFileSync28(target, IGNORE_STARTER, "utf8");
|
|
93614
94213
|
wroteIgnore = true;
|
|
93615
94214
|
}
|
|
93616
94215
|
}
|
|
@@ -93624,12 +94223,12 @@ init_registry();
|
|
|
93624
94223
|
// src/adopt.ts
|
|
93625
94224
|
init_git_remote();
|
|
93626
94225
|
import { existsSync as existsSync33 } from "node:fs";
|
|
93627
|
-
import { dirname as
|
|
94226
|
+
import { dirname as dirname16, join as join46 } from "node:path";
|
|
93628
94227
|
function findGitRoot(absPath) {
|
|
93629
94228
|
let dir = absPath;
|
|
93630
94229
|
for (let depth = 0; depth < 64; depth++) {
|
|
93631
|
-
if (existsSync33(
|
|
93632
|
-
const parent =
|
|
94230
|
+
if (existsSync33(join46(dir, ".git"))) return dir;
|
|
94231
|
+
const parent = dirname16(dir);
|
|
93633
94232
|
if (parent === dir) return null;
|
|
93634
94233
|
dir = parent;
|
|
93635
94234
|
}
|
|
@@ -94103,7 +94702,6 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94103
94702
|
const boundaryListeners = [];
|
|
94104
94703
|
let boundaryFlushing = false;
|
|
94105
94704
|
let pushRequested = false;
|
|
94106
|
-
let shippedFingerprint = "";
|
|
94107
94705
|
let settleRunning = false;
|
|
94108
94706
|
let boundaryFlushStartedAt = 0;
|
|
94109
94707
|
let boundaryFlushStage = "";
|
|
@@ -94184,16 +94782,63 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94184
94782
|
});
|
|
94185
94783
|
}
|
|
94186
94784
|
};
|
|
94187
|
-
const
|
|
94785
|
+
const SHIP_MARK_KEY = "watermark:instance-ship";
|
|
94786
|
+
const sendableSeq = (store) => store.changeSeq ? store.changeSeq() - store.changeSeq([EXPOSURE_SCOPE]) : null;
|
|
94787
|
+
const shipLanes = () => {
|
|
94188
94788
|
const cfg2 = loadConfig();
|
|
94189
|
-
const
|
|
94789
|
+
const lanes = [], destinations = [], held = [];
|
|
94190
94790
|
for (const r of records) {
|
|
94191
|
-
|
|
94192
|
-
|
|
94791
|
+
const consent = effectiveConsent(cfg2, r.engine.profile);
|
|
94792
|
+
if (!consent.sync) continue;
|
|
94793
|
+
const identity = identityFor(liveWorkspaceEntry(r.entry));
|
|
94794
|
+
const destination = `${opts.cloudUrl ?? identity.profile?.cloudUrl ?? cfg2.cloudUrl ?? ""}|${identity.profileName ?? ""}`;
|
|
94795
|
+
destinations.push(destination);
|
|
94796
|
+
const quarantined = r.engine.quarantinedSessions().slice().sort();
|
|
94797
|
+
held.push(...quarantined);
|
|
94798
|
+
let ignoreFile = "";
|
|
94799
|
+
try {
|
|
94800
|
+
ignoreFile = readFileSync40(join47(r.root, ".errataignore"), "utf8");
|
|
94801
|
+
} catch {
|
|
94802
|
+
}
|
|
94803
|
+
const retryInputs = JSON.stringify([
|
|
94804
|
+
quarantined,
|
|
94805
|
+
DAEMON_VERSION,
|
|
94806
|
+
ignoreFile,
|
|
94807
|
+
r.engine.profile.ignoreExtra ?? [],
|
|
94808
|
+
r.engine.profile.projectHistoryCorrectionCursor ?? 0
|
|
94809
|
+
]);
|
|
94810
|
+
const context = JSON.stringify([destination, consent.contributePackages ?? null, loadProfile(r.root)?.projectId ?? r.engine.profile.projectId ?? null]);
|
|
94811
|
+
const fp = r.engine.store.labelFingerprint?.(INSTANCE_LABELS);
|
|
94812
|
+
lanes.push({ store: r.engine.store, fp: fp === void 0 ? null : `${context}#${fp}`, seq: sendableSeq(r.engine.store), held: retryInputs });
|
|
94813
|
+
}
|
|
94814
|
+
if (lanes.length === 0) return lanes;
|
|
94815
|
+
const shared = sharedStore.labelFingerprint?.(["RootCause"]);
|
|
94816
|
+
const sharedContext = JSON.stringify([...new Set(destinations)].sort());
|
|
94817
|
+
lanes.push({ store: sharedStore, fp: shared === void 0 ? null : `${sharedContext}#${shared}`, seq: sendableSeq(sharedStore), held: JSON.stringify([[...new Set(held)].sort(), DAEMON_VERSION]) });
|
|
94818
|
+
return lanes;
|
|
94819
|
+
};
|
|
94820
|
+
const shipMark = (store) => {
|
|
94821
|
+
try {
|
|
94822
|
+
return JSON.parse(store.getMeta?.(SHIP_MARK_KEY) ?? "null");
|
|
94823
|
+
} catch {
|
|
94824
|
+
return null;
|
|
94193
94825
|
}
|
|
94194
|
-
|
|
94195
|
-
|
|
94196
|
-
|
|
94826
|
+
};
|
|
94827
|
+
const unshipped = (lanes, retries) => lanes.filter((l) => {
|
|
94828
|
+
const mark = l.fp === null ? null : shipMark(l.store);
|
|
94829
|
+
if (!mark || mark.fp !== l.fp) return true;
|
|
94830
|
+
if (!retries) return false;
|
|
94831
|
+
return !mark.ok || l.seq === null || mark.seq !== l.seq || mark.held !== l.held || mark.retryAt !== void 0 && mark.retryAt <= Date.now();
|
|
94832
|
+
});
|
|
94833
|
+
const recordShipped = (lanes, result) => {
|
|
94834
|
+
const mark = (l) => ({
|
|
94835
|
+
fp: l.fp,
|
|
94836
|
+
ok: !result.errors?.length,
|
|
94837
|
+
...result.retryAt !== void 0 ? { retryAt: result.retryAt } : {},
|
|
94838
|
+
...l.seq !== null ? { seq: l.seq } : {},
|
|
94839
|
+
held: l.held
|
|
94840
|
+
});
|
|
94841
|
+
for (const l of lanes) if (l.fp !== null) l.store.setMeta?.(SHIP_MARK_KEY, JSON.stringify(mark(l)));
|
|
94197
94842
|
};
|
|
94198
94843
|
const runSettle = async () => {
|
|
94199
94844
|
if (settleRunning) return;
|
|
@@ -94346,7 +94991,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94346
94991
|
records.push(rec);
|
|
94347
94992
|
void ambientLinkAll();
|
|
94348
94993
|
try {
|
|
94349
|
-
|
|
94994
|
+
writeFileSync29(
|
|
94350
94995
|
rec.engine.paths.daemonLock,
|
|
94351
94996
|
daemonLockPayload({
|
|
94352
94997
|
pid: process.pid,
|
|
@@ -94415,11 +95060,19 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94415
95060
|
const strandedCount = (r) => {
|
|
94416
95061
|
const hit = strandedCache.get(r.id);
|
|
94417
95062
|
if (hit && Date.now() - hit.at < STRANDED_TTL_MS) return hit.count;
|
|
95063
|
+
const store = r.engine.store;
|
|
95064
|
+
const standing = standingStrandedCount(store);
|
|
95065
|
+
if (standing !== null) {
|
|
95066
|
+
strandedCache.set(r.id, { at: Date.now(), count: standing });
|
|
95067
|
+
return standing;
|
|
95068
|
+
}
|
|
94418
95069
|
if (!strandedRefreshing.has(r.id)) {
|
|
94419
95070
|
strandedRefreshing.add(r.id);
|
|
95071
|
+
const seq = store.changeSeq?.();
|
|
94420
95072
|
const finish = (count) => {
|
|
94421
95073
|
strandedCache.set(r.id, { at: Date.now(), count });
|
|
94422
95074
|
strandedRefreshing.delete(r.id);
|
|
95075
|
+
recordStrandedCount(store, seq, count);
|
|
94423
95076
|
};
|
|
94424
95077
|
if (consolidateWorker && r.engine.paths.castalia !== ":memory:") {
|
|
94425
95078
|
consolidateWorker.run({ kind: "strandedCount", sharedDbPath, castaliaPath: r.engine.paths.castalia }).then((n) => finish(Number(n))).catch(() => {
|
|
@@ -94725,7 +95378,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94725
95378
|
baseUrl = `http://127.0.0.1:${port}`;
|
|
94726
95379
|
try {
|
|
94727
95380
|
ensureDir(globalDir());
|
|
94728
|
-
|
|
95381
|
+
writeFileSync29(
|
|
94729
95382
|
lockPath,
|
|
94730
95383
|
daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
|
|
94731
95384
|
"utf8"
|
|
@@ -94734,7 +95387,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94734
95387
|
}
|
|
94735
95388
|
for (const r of records) {
|
|
94736
95389
|
try {
|
|
94737
|
-
|
|
95390
|
+
writeFileSync29(
|
|
94738
95391
|
r.engine.paths.daemonLock,
|
|
94739
95392
|
daemonLockPayload({
|
|
94740
95393
|
pid: process.pid,
|
|
@@ -94774,7 +95427,15 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94774
95427
|
});
|
|
94775
95428
|
const revisionBacklog = /* @__PURE__ */ new Set();
|
|
94776
95429
|
const lastAnchorPull = /* @__PURE__ */ new Map();
|
|
94777
|
-
const
|
|
95430
|
+
const anchorPullInFlight = /* @__PURE__ */ new Map();
|
|
95431
|
+
const pullProjectAnchors = (r, client, salt) => {
|
|
95432
|
+
const running = anchorPullInFlight.get(r.root);
|
|
95433
|
+
if (running) return running;
|
|
95434
|
+
const pull = pullProjectAnchorsOnce(r, client, salt).finally(() => anchorPullInFlight.delete(r.root));
|
|
95435
|
+
anchorPullInFlight.set(r.root, pull);
|
|
95436
|
+
return pull;
|
|
95437
|
+
};
|
|
95438
|
+
const pullProjectAnchorsOnce = async (r, client, salt) => {
|
|
94778
95439
|
const donePass = markPass(`anchor-pull:${r.engine.profile.name}`);
|
|
94779
95440
|
const pullStartedAt = Date.now();
|
|
94780
95441
|
const beforeCorrections = r.engine.profile.projectHistoryCorrectionCursor ?? 0;
|
|
@@ -94790,10 +95451,13 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94790
95451
|
for (const record2 of records) record2.engine.markContextDirty();
|
|
94791
95452
|
}
|
|
94792
95453
|
try {
|
|
94793
|
-
|
|
94794
|
-
|
|
94795
|
-
|
|
94796
|
-
|
|
95454
|
+
if (!r.engine.storeReconciled()) revisionBacklog.add(r.root);
|
|
95455
|
+
else {
|
|
95456
|
+
const revision = await syncHistoryRevision({ root: r.root, profile: r.engine.profile, store: r.engine.store, cloud: client, salt });
|
|
95457
|
+
if (revision.remaining) revisionBacklog.add(r.root);
|
|
95458
|
+
else revisionBacklog.delete(r.root);
|
|
95459
|
+
if (revision.changed) r.engine.markContextDirty();
|
|
95460
|
+
}
|
|
94797
95461
|
} catch (err2) {
|
|
94798
95462
|
console.warn(`[errata] history revision reconciliation failed for ${r.engine.profile.name}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
94799
95463
|
}
|
|
@@ -95283,6 +95947,10 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95283
95947
|
};
|
|
95284
95948
|
let uploaded = 0;
|
|
95285
95949
|
const errors = [];
|
|
95950
|
+
let retryAt = null;
|
|
95951
|
+
const retryBy = (at) => {
|
|
95952
|
+
if (at !== null && (retryAt === null || at < retryAt)) retryAt = at;
|
|
95953
|
+
};
|
|
95286
95954
|
const workerFor = (r) => consolidateWorker && r.engine.paths.castalia !== ":memory:" ? consolidateWorker : null;
|
|
95287
95955
|
const buildContextBatch = async (r, input) => {
|
|
95288
95956
|
const w = workerFor(r);
|
|
@@ -95406,6 +96074,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95406
96074
|
}
|
|
95407
96075
|
});
|
|
95408
96076
|
if (p.blockedNodeIds?.length) {
|
|
96077
|
+
retryBy(Date.now());
|
|
95409
96078
|
console.log(
|
|
95410
96079
|
`[sync\u2192cloud] [${projectName}] context: ${p.blockedNodeIds.length} node(s) refused by an edge/CDN filter on content \u2014 left pending, will retry`
|
|
95411
96080
|
);
|
|
@@ -95437,6 +96106,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95437
96106
|
});
|
|
95438
96107
|
const parkPath = edgeParkPath(r.engine.paths.configDir, destinationKey);
|
|
95439
96108
|
const parkQueue = loadEdgePark(parkPath);
|
|
96109
|
+
retryBy(nextEdgeParkChange(parkQueue));
|
|
95440
96110
|
const built = await buildInstanceBatch(r, {
|
|
95441
96111
|
edgeHolds: edgeHolds(parkQueue, Date.now()),
|
|
95442
96112
|
destinationKey,
|
|
@@ -95506,6 +96176,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95506
96176
|
}
|
|
95507
96177
|
});
|
|
95508
96178
|
if (blocked.size > 0) {
|
|
96179
|
+
retryBy(Date.now());
|
|
95509
96180
|
console.log(
|
|
95510
96181
|
`[sync\u2192cloud] [${projectName}] instances: ${blocked.size} node(s) refused by an edge/CDN filter on content \u2014 left pending, will retry. First: ${store.getNode([...blocked][0])?.description.slice(0, 120) ?? [...blocked][0]}`
|
|
95511
96182
|
);
|
|
@@ -95541,6 +96212,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95541
96212
|
Date.now()
|
|
95542
96213
|
);
|
|
95543
96214
|
saveEdgePark(parkPath, settled.queue);
|
|
96215
|
+
retryBy(nextEdgeParkChange(settled.queue));
|
|
95544
96216
|
const edgeCounts = settled.counts;
|
|
95545
96217
|
if (rejectedEdges.length > 0) {
|
|
95546
96218
|
const byReason = /* @__PURE__ */ new Map();
|
|
@@ -95667,7 +96339,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95667
96339
|
});
|
|
95668
96340
|
}
|
|
95669
96341
|
}
|
|
95670
|
-
return { uploaded, ...errors.length > 0 ? { errors } : {} };
|
|
96342
|
+
return { uploaded, ...errors.length > 0 ? { errors } : {}, ...retryAt !== null ? { retryAt } : {} };
|
|
95671
96343
|
},
|
|
95672
96344
|
async backfillCausalEdges() {
|
|
95673
96345
|
if (!loadConfig().consent.sync) return { accepted: 0, rejected: 0, skipped: "consent-off" };
|
|
@@ -95742,9 +96414,9 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95742
96414
|
beginFlush("instances");
|
|
95743
96415
|
try {
|
|
95744
96416
|
flushStage("instances");
|
|
95745
|
-
const
|
|
95746
|
-
const inst = await daemon.syncInstancesPublic();
|
|
95747
|
-
|
|
96417
|
+
const lanes = shipLanes();
|
|
96418
|
+
const inst = lanes.length > 0 && unshipped(lanes, true).length === 0 ? { uploaded: 0, skipped: "unchanged", errors: void 0 } : await daemon.syncInstancesPublic();
|
|
96419
|
+
if (!inst.skipped) recordShipped(lanes, inst);
|
|
95748
96420
|
flushStage("skills");
|
|
95749
96421
|
const skills = await daemon.syncSkillsAll();
|
|
95750
96422
|
return {
|
|
@@ -95758,8 +96430,8 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95758
96430
|
}
|
|
95759
96431
|
},
|
|
95760
96432
|
pendingLiveFingerprint() {
|
|
95761
|
-
const
|
|
95762
|
-
return
|
|
96433
|
+
const pending = unshipped(shipLanes(), false);
|
|
96434
|
+
return pending.length ? pending.map((l) => l.fp ?? `?${Date.now()}`).join("|") : null;
|
|
95763
96435
|
},
|
|
95764
96436
|
async liveShip() {
|
|
95765
96437
|
if (!liveSyncEnabled()) return { uploaded: 0, skipped: "disabled" };
|
|
@@ -95775,9 +96447,9 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95775
96447
|
}
|
|
95776
96448
|
beginFlush("live");
|
|
95777
96449
|
try {
|
|
95778
|
-
const
|
|
96450
|
+
const lanes = shipLanes();
|
|
95779
96451
|
const inst = await daemon.syncInstancesPublic();
|
|
95780
|
-
|
|
96452
|
+
if (!inst.skipped) recordShipped(lanes, inst);
|
|
95781
96453
|
return {
|
|
95782
96454
|
uploaded: inst.uploaded,
|
|
95783
96455
|
...inst.skipped ? { skipped: inst.skipped } : {},
|
|
@@ -95827,7 +96499,9 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95827
96499
|
flushStage("triage");
|
|
95828
96500
|
const triage = await daemon.syncTriagePublic();
|
|
95829
96501
|
flushStage("instances");
|
|
96502
|
+
const lanes = shipLanes();
|
|
95830
96503
|
const instances = await daemon.syncInstancesPublic();
|
|
96504
|
+
if (!instances.skipped) recordShipped(lanes, instances);
|
|
95831
96505
|
flushStage("edge-backfill");
|
|
95832
96506
|
const edgeBackfill = await daemon.backfillCausalEdges();
|
|
95833
96507
|
return c.json({ principles, triage, instances, edgeBackfill });
|
|
@@ -96252,15 +96926,15 @@ function shouldUseOAuthLogin(flags2, env2 = process.env) {
|
|
|
96252
96926
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
96253
96927
|
|
|
96254
96928
|
// src/codex-runtime.ts
|
|
96255
|
-
import { readdirSync as readdirSync13, statSync as
|
|
96256
|
-
import { join as
|
|
96929
|
+
import { readdirSync as readdirSync13, statSync as statSync12 } from "node:fs";
|
|
96930
|
+
import { join as join48 } from "node:path";
|
|
96257
96931
|
function resolveCodexExecutable(options = {}) {
|
|
96258
96932
|
const platform = options.platform ?? process.platform;
|
|
96259
96933
|
const env2 = options.env ?? process.env;
|
|
96260
96934
|
if (platform !== "win32") return "codex";
|
|
96261
96935
|
const fileTime = (path3) => {
|
|
96262
96936
|
try {
|
|
96263
|
-
const s =
|
|
96937
|
+
const s = statSync12(path3);
|
|
96264
96938
|
return s.isFile() ? s.mtimeMs : null;
|
|
96265
96939
|
} catch {
|
|
96266
96940
|
return null;
|
|
@@ -96268,13 +96942,13 @@ function resolveCodexExecutable(options = {}) {
|
|
|
96268
96942
|
};
|
|
96269
96943
|
for (const dir of (env2["PATH"] ?? env2["Path"] ?? "").split(";")) {
|
|
96270
96944
|
if (!dir.trim()) continue;
|
|
96271
|
-
const path3 =
|
|
96945
|
+
const path3 = join48(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
|
|
96272
96946
|
if (fileTime(path3) !== null) return path3;
|
|
96273
96947
|
}
|
|
96274
96948
|
if (!env2["LOCALAPPDATA"]) return "codex";
|
|
96275
|
-
const root =
|
|
96949
|
+
const root = join48(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
|
|
96276
96950
|
try {
|
|
96277
|
-
const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
96951
|
+
const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join48(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));
|
|
96278
96952
|
return candidates[0]?.path ?? "codex";
|
|
96279
96953
|
} catch {
|
|
96280
96954
|
return "codex";
|
|
@@ -96413,14 +97087,14 @@ async function diagnoseInstallation(cfg, dependencies) {
|
|
|
96413
97087
|
}
|
|
96414
97088
|
|
|
96415
97089
|
// src/credential-scan.ts
|
|
96416
|
-
import { readFileSync as
|
|
97090
|
+
import { readFileSync as readFileSync42, statSync as statSync13 } from "node:fs";
|
|
96417
97091
|
import { homedir as homedir8 } from "node:os";
|
|
96418
|
-
import { join as
|
|
97092
|
+
import { join as join50 } from "node:path";
|
|
96419
97093
|
|
|
96420
97094
|
// src/claude-statusline.ts
|
|
96421
|
-
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as
|
|
97095
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync41, writeFileSync as writeFileSync30 } from "node:fs";
|
|
96422
97096
|
import { homedir as homedir7 } from "node:os";
|
|
96423
|
-
import { dirname as
|
|
97097
|
+
import { dirname as dirname17, join as join49 } from "node:path";
|
|
96424
97098
|
var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
|
|
96425
97099
|
import { readFileSync } from 'node:fs';
|
|
96426
97100
|
|
|
@@ -96468,8 +97142,8 @@ function isSameInstall(value, relay) {
|
|
|
96468
97142
|
return command.includes(relay.replace(/\\/g, "/").toLowerCase());
|
|
96469
97143
|
}
|
|
96470
97144
|
function userClaudeSettingsPath() {
|
|
96471
|
-
const base = process.env["CLAUDE_CONFIG_DIR"] ??
|
|
96472
|
-
return
|
|
97145
|
+
const base = process.env["CLAUDE_CONFIG_DIR"] ?? join49(homedir7(), ".claude");
|
|
97146
|
+
return join49(base, "settings.json");
|
|
96473
97147
|
}
|
|
96474
97148
|
function ensureUserStatusLine(opts) {
|
|
96475
97149
|
const env2 = opts.env ?? process.env;
|
|
@@ -96479,21 +97153,21 @@ function ensureUserStatusLine(opts) {
|
|
|
96479
97153
|
let settings = {};
|
|
96480
97154
|
if (existsSync35(settingsPath)) {
|
|
96481
97155
|
try {
|
|
96482
|
-
const parsed = JSON.parse(
|
|
97156
|
+
const parsed = JSON.parse(readFileSync41(settingsPath, "utf8"));
|
|
96483
97157
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
|
|
96484
97158
|
settings = parsed;
|
|
96485
97159
|
} catch {
|
|
96486
97160
|
return "unreadable";
|
|
96487
97161
|
}
|
|
96488
97162
|
}
|
|
96489
|
-
const relay =
|
|
97163
|
+
const relay = join49(opts.relayDir, STATUSLINE_RELAY_FILE);
|
|
96490
97164
|
const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
|
|
96491
97165
|
const ownMain = keep(settings["statusLine"]);
|
|
96492
97166
|
const ownRows = keep(settings["subagentStatusLine"]);
|
|
96493
97167
|
if (ownMain && ownRows) return "kept-own";
|
|
96494
97168
|
mkdirSync9(opts.relayDir, { recursive: true });
|
|
96495
|
-
if (!existsSync35(relay) ||
|
|
96496
|
-
|
|
97169
|
+
if (!existsSync35(relay) || readFileSync41(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
|
|
97170
|
+
writeFileSync30(relay, STATUSLINE_RELAY_SOURCE, "utf8");
|
|
96497
97171
|
}
|
|
96498
97172
|
const nodePath = opts.nodePath ?? process.execPath;
|
|
96499
97173
|
const next = {
|
|
@@ -96504,8 +97178,8 @@ function ensureUserStatusLine(opts) {
|
|
|
96504
97178
|
return ownMain ? "kept-own" : "unchanged";
|
|
96505
97179
|
}
|
|
96506
97180
|
Object.assign(settings, next);
|
|
96507
|
-
mkdirSync9(
|
|
96508
|
-
|
|
97181
|
+
mkdirSync9(dirname17(settingsPath), { recursive: true });
|
|
97182
|
+
writeFileSync30(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
96509
97183
|
return "installed";
|
|
96510
97184
|
}
|
|
96511
97185
|
function describeStatusLineOutcome(outcome) {
|
|
@@ -96546,36 +97220,36 @@ function findCredentialLines(text) {
|
|
|
96546
97220
|
function harnessConfigPaths(root) {
|
|
96547
97221
|
const env2 = process.env;
|
|
96548
97222
|
const home = homedir8();
|
|
96549
|
-
const codexHome = env2["CODEX_HOME"] ||
|
|
96550
|
-
const geminiHome =
|
|
97223
|
+
const codexHome = env2["CODEX_HOME"] || join50(home, ".codex");
|
|
97224
|
+
const geminiHome = join50(env2["GEMINI_CLI_HOME"] ?? home, ".gemini");
|
|
96551
97225
|
return [
|
|
96552
97226
|
// Claude Code: user settings, `claude mcp add` (local/user scope), project.
|
|
96553
97227
|
userClaudeSettingsPath(),
|
|
96554
|
-
|
|
96555
|
-
|
|
96556
|
-
|
|
96557
|
-
|
|
97228
|
+
join50(env2["CLAUDE_CONFIG_DIR"] ?? home, ".claude.json"),
|
|
97229
|
+
join50(root, ".claude", "settings.json"),
|
|
97230
|
+
join50(root, ".claude", "settings.local.json"),
|
|
97231
|
+
join50(root, ".mcp.json"),
|
|
96558
97232
|
// Codex
|
|
96559
|
-
|
|
96560
|
-
|
|
97233
|
+
join50(codexHome, "config.toml"),
|
|
97234
|
+
join50(root, ".codex", "config.toml"),
|
|
96561
97235
|
// Gemini CLI
|
|
96562
|
-
|
|
96563
|
-
|
|
97236
|
+
join50(geminiHome, "settings.json"),
|
|
97237
|
+
join50(root, ".gemini", "settings.json"),
|
|
96564
97238
|
// Cursor
|
|
96565
|
-
|
|
96566
|
-
|
|
97239
|
+
join50(home, ".cursor", "mcp.json"),
|
|
97240
|
+
join50(root, ".cursor", "mcp.json"),
|
|
96567
97241
|
// VS Code (user profile mcp.json + workspace)
|
|
96568
|
-
|
|
96569
|
-
|
|
97242
|
+
join50(vscodeUserDir(home, env2), "mcp.json"),
|
|
97243
|
+
join50(root, ".vscode", "mcp.json"),
|
|
96570
97244
|
// OpenCode (XDG on every platform; the daemon's installer writes the project one)
|
|
96571
|
-
|
|
96572
|
-
|
|
97245
|
+
join50(env2["XDG_CONFIG_HOME"] ?? join50(home, ".config"), "opencode", "opencode.json"),
|
|
97246
|
+
join50(root, "opencode.json")
|
|
96573
97247
|
];
|
|
96574
97248
|
}
|
|
96575
97249
|
function vscodeUserDir(home, env2) {
|
|
96576
|
-
if (process.platform === "win32") return
|
|
96577
|
-
if (process.platform === "darwin") return
|
|
96578
|
-
return
|
|
97250
|
+
if (process.platform === "win32") return join50(env2["APPDATA"] ?? join50(home, "AppData", "Roaming"), "Code", "User");
|
|
97251
|
+
if (process.platform === "darwin") return join50(home, "Library", "Application Support", "Code", "User");
|
|
97252
|
+
return join50(env2["XDG_CONFIG_HOME"] ?? join50(home, ".config"), "Code", "User");
|
|
96579
97253
|
}
|
|
96580
97254
|
function scanHarnessConfigs(paths, read2 = readBounded) {
|
|
96581
97255
|
const findings = [];
|
|
@@ -96590,9 +97264,9 @@ function scanHarnessConfigs(paths, read2 = readBounded) {
|
|
|
96590
97264
|
}
|
|
96591
97265
|
function readBounded(path3) {
|
|
96592
97266
|
try {
|
|
96593
|
-
const stat4 =
|
|
97267
|
+
const stat4 = statSync13(path3);
|
|
96594
97268
|
if (!stat4.isFile() || stat4.size > MAX_SCAN_BYTES) return null;
|
|
96595
|
-
return
|
|
97269
|
+
return readFileSync42(path3, "utf8");
|
|
96596
97270
|
} catch {
|
|
96597
97271
|
return null;
|
|
96598
97272
|
}
|
|
@@ -96617,14 +97291,14 @@ function credentialHygieneCheck(scan2) {
|
|
|
96617
97291
|
|
|
96618
97292
|
// src/codex-doctor.ts
|
|
96619
97293
|
import { spawn as spawn4 } from "node:child_process";
|
|
96620
|
-
import { readFileSync as
|
|
96621
|
-
import { join as
|
|
97294
|
+
import { readFileSync as readFileSync44, statSync as statSync14 } from "node:fs";
|
|
97295
|
+
import { join as join52 } from "node:path";
|
|
96622
97296
|
import { createInterface } from "node:readline";
|
|
96623
97297
|
|
|
96624
97298
|
// src/codex-hooks.ts
|
|
96625
|
-
import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as
|
|
97299
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync43, renameSync as renameSync8, unlinkSync as unlinkSync5, writeFileSync as writeFileSync31 } from "node:fs";
|
|
96626
97300
|
import { homedir as homedir9 } from "node:os";
|
|
96627
|
-
import { join as
|
|
97301
|
+
import { join as join51 } from "node:path";
|
|
96628
97302
|
|
|
96629
97303
|
// src/hook-commands.ts
|
|
96630
97304
|
function hookCurlCommand(port, path3 = "/api/hook") {
|
|
@@ -96828,34 +97502,34 @@ function buildCodexRelaySource(workspaceRoot) {
|
|
|
96828
97502
|
init_checkout_root();
|
|
96829
97503
|
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.";
|
|
96830
97504
|
function writeRelay(file2, source) {
|
|
96831
|
-
if (existsSync36(file2) &&
|
|
97505
|
+
if (existsSync36(file2) && readFileSync43(file2, "utf8") === source) return;
|
|
96832
97506
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
96833
97507
|
try {
|
|
96834
|
-
|
|
96835
|
-
|
|
97508
|
+
writeFileSync31(temp, source, { encoding: "utf8", mode: 384 });
|
|
97509
|
+
renameSync8(temp, file2);
|
|
96836
97510
|
} finally {
|
|
96837
97511
|
if (existsSync36(temp)) unlinkSync5(temp);
|
|
96838
97512
|
}
|
|
96839
97513
|
}
|
|
96840
97514
|
function refreshCodexRelay(root) {
|
|
96841
|
-
const config2 =
|
|
97515
|
+
const config2 = join51(root, ".codex", "config.toml");
|
|
96842
97516
|
if (!existsSync36(config2)) return "absent";
|
|
96843
|
-
const existing =
|
|
97517
|
+
const existing = readFileSync43(config2, "utf8");
|
|
96844
97518
|
if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
|
|
96845
97519
|
replaceCodexHooks(existing, "");
|
|
96846
|
-
const relay =
|
|
96847
|
-
const prior = existsSync36(relay) ?
|
|
97520
|
+
const relay = join51(root, ".codex", "hooks", "errata-relay.mjs");
|
|
97521
|
+
const prior = existsSync36(relay) ? readFileSync43(relay, "utf8") : "";
|
|
96848
97522
|
if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
|
|
96849
97523
|
throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
|
|
96850
97524
|
}
|
|
96851
97525
|
const source = buildCodexRelaySource(checkoutRootOf(root));
|
|
96852
97526
|
if (prior === source) return "current";
|
|
96853
|
-
mkdirSync10(
|
|
97527
|
+
mkdirSync10(join51(root, ".codex", "hooks"), { recursive: true });
|
|
96854
97528
|
writeRelay(relay, source);
|
|
96855
97529
|
return "updated";
|
|
96856
97530
|
}
|
|
96857
|
-
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] ||
|
|
96858
|
-
return existsSync36(
|
|
97531
|
+
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join51(homedir9(), ".codex")) {
|
|
97532
|
+
return existsSync36(join51(root, ".codex")) || existsSync36(codexHome);
|
|
96859
97533
|
}
|
|
96860
97534
|
function replaceCodexHooks(existing, block) {
|
|
96861
97535
|
const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
|
|
@@ -96871,14 +97545,14 @@ function replaceCodexHooks(existing, block) {
|
|
|
96871
97545
|
return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
|
|
96872
97546
|
}
|
|
96873
97547
|
function writeCodexHooks(root, port, nodePath = process.execPath) {
|
|
96874
|
-
const dir =
|
|
96875
|
-
const file2 =
|
|
96876
|
-
const relay =
|
|
97548
|
+
const dir = join51(root, ".codex");
|
|
97549
|
+
const file2 = join51(dir, "config.toml");
|
|
97550
|
+
const relay = join51(dir, "hooks", "errata-relay.mjs");
|
|
96877
97551
|
const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
|
|
96878
|
-
const final = replaceCodexHooks(existsSync36(file2) ?
|
|
96879
|
-
mkdirSync10(
|
|
97552
|
+
const final = replaceCodexHooks(existsSync36(file2) ? readFileSync43(file2, "utf8") : "", block);
|
|
97553
|
+
mkdirSync10(join51(dir, "hooks"), { recursive: true });
|
|
96880
97554
|
writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
|
|
96881
|
-
if (!existsSync36(file2) ||
|
|
97555
|
+
if (!existsSync36(file2) || readFileSync43(file2, "utf8") !== final) writeFileSync31(file2, final, "utf8");
|
|
96882
97556
|
return file2;
|
|
96883
97557
|
}
|
|
96884
97558
|
|
|
@@ -96887,7 +97561,7 @@ init_checkout_root();
|
|
|
96887
97561
|
function inspectCodexRelay(cwd) {
|
|
96888
97562
|
const root = nearestGitRoot(cwd) ?? cwd;
|
|
96889
97563
|
try {
|
|
96890
|
-
const source =
|
|
97564
|
+
const source = readFileSync44(join52(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
|
|
96891
97565
|
if (source === buildCodexRelaySource(checkoutRootOf(root))) {
|
|
96892
97566
|
return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
|
|
96893
97567
|
}
|
|
@@ -96898,8 +97572,8 @@ function inspectCodexRelay(cwd) {
|
|
|
96898
97572
|
function inspectCodexContext(cwd) {
|
|
96899
97573
|
const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
|
|
96900
97574
|
try {
|
|
96901
|
-
const file2 =
|
|
96902
|
-
if (
|
|
97575
|
+
const file2 = join52(root, ".errata", "context.md");
|
|
97576
|
+
if (statSync14(file2).size <= 128 * 1024 && readFileSync44(file2, "utf8").trim()) {
|
|
96903
97577
|
return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
|
|
96904
97578
|
}
|
|
96905
97579
|
} catch {
|
|
@@ -97076,11 +97750,11 @@ function consolidationGapMs(lastPassMs, policy) {
|
|
|
97076
97750
|
}
|
|
97077
97751
|
|
|
97078
97752
|
// src/codex-context-plugin.ts
|
|
97079
|
-
import { createHash as
|
|
97080
|
-
import { cpSync as cpSync2, existsSync as existsSync37, mkdirSync as mkdirSync11, readFileSync as
|
|
97753
|
+
import { createHash as createHash21 } from "node:crypto";
|
|
97754
|
+
import { cpSync as cpSync2, existsSync as existsSync37, mkdirSync as mkdirSync11, readFileSync as readFileSync45, renameSync as renameSync9, writeFileSync as writeFileSync32 } from "node:fs";
|
|
97081
97755
|
import { homedir as homedir10 } from "node:os";
|
|
97082
|
-
import { join as
|
|
97083
|
-
import { fileURLToPath as
|
|
97756
|
+
import { join as join53 } from "node:path";
|
|
97757
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
97084
97758
|
|
|
97085
97759
|
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
|
|
97086
97760
|
function getLineColFromPtr(string4, ptr) {
|
|
@@ -97162,7 +97836,7 @@ function skipVoid(str, ptr, banNewLines, banComments) {
|
|
|
97162
97836
|
}
|
|
97163
97837
|
return ptr;
|
|
97164
97838
|
}
|
|
97165
|
-
function skipUntil(str, ptr,
|
|
97839
|
+
function skipUntil(str, ptr, sep7, end, banNewLines = false) {
|
|
97166
97840
|
if (!end) {
|
|
97167
97841
|
ptr = indexOfNewline(str, ptr);
|
|
97168
97842
|
return ptr < 0 ? str.length : ptr;
|
|
@@ -97171,7 +97845,7 @@ function skipUntil(str, ptr, sep6, end, banNewLines = false) {
|
|
|
97171
97845
|
let c = str[i2];
|
|
97172
97846
|
if (c === "#") {
|
|
97173
97847
|
i2 = indexOfNewline(str, i2);
|
|
97174
|
-
} else if (c ===
|
|
97848
|
+
} else if (c === sep7) {
|
|
97175
97849
|
return i2 + 1;
|
|
97176
97850
|
} else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i2 + 1] === "\n")) {
|
|
97177
97851
|
return i2;
|
|
@@ -97777,23 +98451,23 @@ var NAME = "errata-context";
|
|
|
97777
98451
|
var PREFIX2 = `./.errata/plugins/${NAME}/`;
|
|
97778
98452
|
var object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
97779
98453
|
function readText(file2) {
|
|
97780
|
-
return existsSync37(file2) ?
|
|
98454
|
+
return existsSync37(file2) ? readFileSync45(file2, "utf8") : "";
|
|
97781
98455
|
}
|
|
97782
98456
|
function writeChanged(file2, content) {
|
|
97783
98457
|
if (readText(file2) === content) return;
|
|
97784
98458
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
97785
|
-
|
|
97786
|
-
|
|
98459
|
+
writeFileSync32(temp, content, "utf8");
|
|
98460
|
+
renameSync9(temp, file2);
|
|
97787
98461
|
}
|
|
97788
98462
|
function bundledContextPlugin() {
|
|
97789
|
-
const packaged =
|
|
97790
|
-
if (existsSync37(
|
|
97791
|
-
return
|
|
98463
|
+
const packaged = fileURLToPath3(new URL("./resources/context-plugin/", import.meta.url));
|
|
98464
|
+
if (existsSync37(join53(packaged, ".codex-plugin/plugin.json"))) return packaged;
|
|
98465
|
+
return fileURLToPath3(new URL("../dist/resources/context-plugin/", import.meta.url));
|
|
97792
98466
|
}
|
|
97793
98467
|
function refreshCodexContextPlugin(root) {
|
|
97794
|
-
const file2 =
|
|
98468
|
+
const file2 = join53(root, ".agents", "plugins", "marketplace.json");
|
|
97795
98469
|
if (!existsSync37(file2)) return false;
|
|
97796
|
-
const marketplace = JSON.parse(
|
|
98470
|
+
const marketplace = JSON.parse(readFileSync45(file2, "utf8"));
|
|
97797
98471
|
const entries = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
|
|
97798
98472
|
const entry = entries.map(object2).find((value) => value.name === NAME && String(object2(value.source).path).startsWith(PREFIX2));
|
|
97799
98473
|
if (!entry) return false;
|
|
@@ -97804,24 +98478,24 @@ function refreshCodexContextPlugin(root) {
|
|
|
97804
98478
|
function installCodexContextPlugin(root, options = {}) {
|
|
97805
98479
|
const bundle = options.bundle ?? bundledContextPlugin();
|
|
97806
98480
|
const manifest = JSON.parse(
|
|
97807
|
-
|
|
98481
|
+
readFileSync45(join53(bundle, ".codex-plugin/plugin.json"), "utf8")
|
|
97808
98482
|
);
|
|
97809
98483
|
if (manifest.name !== NAME || typeof manifest.version !== "string" || !/^[\w.-]+$/.test(manifest.version)) {
|
|
97810
98484
|
throw new Error("Invalid bundled Errata Context manifest.");
|
|
97811
98485
|
}
|
|
97812
|
-
const checksums =
|
|
98486
|
+
const checksums = readFileSync45(join53(bundle, "SHA256SUMS"), "utf8");
|
|
97813
98487
|
for (const line of checksums.trim().split("\n")) {
|
|
97814
98488
|
const match2 = /^([a-f0-9]{64}) ([\w./-]+)$/.exec(line);
|
|
97815
98489
|
if (!match2 || match2[2].startsWith("/") || match2[2].split("/").includes("..")) {
|
|
97816
98490
|
throw new Error("Invalid bundled Errata Context checksum manifest.");
|
|
97817
98491
|
}
|
|
97818
|
-
const actual =
|
|
98492
|
+
const actual = createHash21("sha256").update(readFileSync45(join53(bundle, match2[2]))).digest("hex");
|
|
97819
98493
|
if (actual !== match2[1])
|
|
97820
98494
|
throw new Error(`Bundled Errata Context checksum mismatch: ${match2[2]}`);
|
|
97821
98495
|
}
|
|
97822
|
-
const release = `${manifest.version}-${
|
|
97823
|
-
const plugin =
|
|
97824
|
-
const marketplaceFile =
|
|
98496
|
+
const release = `${manifest.version}-${createHash21("sha256").update(checksums).digest("hex").slice(0, 12)}`;
|
|
98497
|
+
const plugin = join53(root, ".errata", "plugins", NAME, release);
|
|
98498
|
+
const marketplaceFile = join53(root, ".agents", "plugins", "marketplace.json");
|
|
97825
98499
|
const priorMarketplace = readText(marketplaceFile);
|
|
97826
98500
|
const marketplace = priorMarketplace ? JSON.parse(priorMarketplace) : {
|
|
97827
98501
|
name: "errata-local",
|
|
@@ -97842,12 +98516,12 @@ function installCodexContextPlugin(root, options = {}) {
|
|
|
97842
98516
|
);
|
|
97843
98517
|
}
|
|
97844
98518
|
const key = `${NAME}@${marketplace.name}`;
|
|
97845
|
-
const configFile =
|
|
98519
|
+
const configFile = join53(root, ".codex", "config.toml");
|
|
97846
98520
|
const config2 = readText(configFile);
|
|
97847
98521
|
const parsed = parse4(config2);
|
|
97848
98522
|
const plugins = object2(parsed.plugins);
|
|
97849
|
-
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ??
|
|
97850
|
-
const globalPlugins = object2(parse4(readText(
|
|
98523
|
+
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join53(homedir10(), ".codex");
|
|
98524
|
+
const globalPlugins = object2(parse4(readText(join53(codexHome, "config.toml"))).plugins);
|
|
97851
98525
|
const disabledGlobally = Object.entries(globalPlugins).some(
|
|
97852
98526
|
([name2, value]) => (name2 === NAME || name2.startsWith(`${NAME}@`)) && object2(value).enabled === false
|
|
97853
98527
|
);
|
|
@@ -97871,13 +98545,13 @@ enabled = ${enabled}
|
|
|
97871
98545
|
mkdirSync11(plugin, { recursive: true });
|
|
97872
98546
|
cpSync2(bundle, plugin, { recursive: true });
|
|
97873
98547
|
writeChanged(
|
|
97874
|
-
|
|
98548
|
+
join53(plugin, ".mcp.json"),
|
|
97875
98549
|
JSON.stringify(
|
|
97876
98550
|
{
|
|
97877
98551
|
mcpServers: {
|
|
97878
98552
|
errata_context: {
|
|
97879
98553
|
command: options.nodePath ?? process.execPath,
|
|
97880
|
-
args: [
|
|
98554
|
+
args: [join53(plugin, "dist", "mcp-server.mjs")],
|
|
97881
98555
|
env: { ERRATA_WORKSPACE: root, ERRATA_CONTEXT_VERSION: manifest.version }
|
|
97882
98556
|
}
|
|
97883
98557
|
}
|
|
@@ -97886,8 +98560,8 @@ enabled = ${enabled}
|
|
|
97886
98560
|
2
|
|
97887
98561
|
) + "\n"
|
|
97888
98562
|
);
|
|
97889
|
-
mkdirSync11(
|
|
97890
|
-
mkdirSync11(
|
|
98563
|
+
mkdirSync11(join53(root, ".agents", "plugins"), { recursive: true });
|
|
98564
|
+
mkdirSync11(join53(root, ".codex"), { recursive: true });
|
|
97891
98565
|
writeChanged(marketplaceFile, JSON.stringify(marketplace, null, 2) + "\n");
|
|
97892
98566
|
writeChanged(configFile, nextConfig);
|
|
97893
98567
|
return { plugin, enabled, marketplace: marketplaceFile };
|
|
@@ -97895,15 +98569,15 @@ enabled = ${enabled}
|
|
|
97895
98569
|
|
|
97896
98570
|
// src/codex-hook-refresh.ts
|
|
97897
98571
|
init_checkout_root();
|
|
97898
|
-
import { existsSync as existsSync38, readdirSync as readdirSync14, readFileSync as
|
|
97899
|
-
import { dirname as
|
|
98572
|
+
import { existsSync as existsSync38, readdirSync as readdirSync14, readFileSync as readFileSync46 } from "node:fs";
|
|
98573
|
+
import { dirname as dirname18, join as join54, resolve as resolve8 } from "node:path";
|
|
97900
98574
|
init_registry();
|
|
97901
98575
|
function codexHookRoots(roots) {
|
|
97902
98576
|
const found = new Set(roots.map((root) => resolve8(root)));
|
|
97903
98577
|
for (const root of [...found]) {
|
|
97904
98578
|
const main2 = mainCheckoutOfWorktree(root) ?? root;
|
|
97905
98579
|
found.add(main2);
|
|
97906
|
-
const dir =
|
|
98580
|
+
const dir = join54(main2, ".git", "worktrees");
|
|
97907
98581
|
if (!existsSync38(dir)) continue;
|
|
97908
98582
|
let names;
|
|
97909
98583
|
try {
|
|
@@ -97913,7 +98587,7 @@ function codexHookRoots(roots) {
|
|
|
97913
98587
|
}
|
|
97914
98588
|
for (const name2 of names) {
|
|
97915
98589
|
try {
|
|
97916
|
-
const checkout =
|
|
98590
|
+
const checkout = dirname18(readFileSync46(join54(dir, name2, "gitdir"), "utf8").trim());
|
|
97917
98591
|
if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
|
|
97918
98592
|
} catch {
|
|
97919
98593
|
}
|
|
@@ -97935,50 +98609,50 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
|
|
|
97935
98609
|
}
|
|
97936
98610
|
|
|
97937
98611
|
// src/claude-mods.ts
|
|
97938
|
-
import { createHash as
|
|
97939
|
-
import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as
|
|
97940
|
-
import { delimiter as delimiter2, dirname as
|
|
97941
|
-
import { fileURLToPath as
|
|
98612
|
+
import { createHash as createHash22 } from "node:crypto";
|
|
98613
|
+
import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync47, readdirSync as readdirSync15, rmSync as rmSync4, statSync as statSync15, writeFileSync as writeFileSync33 } from "node:fs";
|
|
98614
|
+
import { delimiter as delimiter2, dirname as dirname19, join as join55, relative as relative7, resolve as resolve9, sep as sep6 } from "node:path";
|
|
98615
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
97942
98616
|
var CLAUDE_PLUGIN_DIRS_ENV = "CLAUDE_CODE_PLUGIN_DIRS";
|
|
97943
98617
|
var HASH_FILE = ".errata-mod-hash";
|
|
97944
98618
|
function bundledClaudeModsDir() {
|
|
97945
98619
|
const rel = import.meta.url.endsWith(".mjs") ? "./resources/claude-mods/" : "../claude-mods/";
|
|
97946
|
-
return
|
|
98620
|
+
return fileURLToPath4(new URL(rel, import.meta.url));
|
|
97947
98621
|
}
|
|
97948
98622
|
function isEngineOwned(relPath) {
|
|
97949
|
-
const p = relPath.split(
|
|
98623
|
+
const p = relPath.split(sep6).join("/");
|
|
97950
98624
|
return p === ".claude-plugin/types" || p.startsWith(".claude-plugin/types/") || p === HASH_FILE;
|
|
97951
98625
|
}
|
|
97952
98626
|
function listFiles(root, dir = root) {
|
|
97953
98627
|
const out2 = [];
|
|
97954
98628
|
for (const name2 of readdirSync15(dir)) {
|
|
97955
|
-
const abs =
|
|
97956
|
-
if (isEngineOwned(
|
|
97957
|
-
if (
|
|
98629
|
+
const abs = join55(dir, name2);
|
|
98630
|
+
if (isEngineOwned(relative7(root, abs))) continue;
|
|
98631
|
+
if (statSync15(abs).isDirectory()) out2.push(...listFiles(root, abs));
|
|
97958
98632
|
else out2.push(abs);
|
|
97959
98633
|
}
|
|
97960
98634
|
return out2;
|
|
97961
98635
|
}
|
|
97962
98636
|
function modHash(dir) {
|
|
97963
|
-
const h =
|
|
98637
|
+
const h = createHash22("sha256");
|
|
97964
98638
|
for (const abs of listFiles(dir).sort()) {
|
|
97965
|
-
h.update(
|
|
98639
|
+
h.update(relative7(dir, abs).split(sep6).join("/"));
|
|
97966
98640
|
h.update("\0");
|
|
97967
|
-
h.update(
|
|
98641
|
+
h.update(readFileSync47(abs));
|
|
97968
98642
|
h.update("\0");
|
|
97969
98643
|
}
|
|
97970
98644
|
return h.digest("hex");
|
|
97971
98645
|
}
|
|
97972
98646
|
function bundledMods(bundleDir) {
|
|
97973
98647
|
if (!existsSync39(bundleDir)) return [];
|
|
97974
|
-
return readdirSync15(bundleDir).filter((name2) => existsSync39(
|
|
98648
|
+
return readdirSync15(bundleDir).filter((name2) => existsSync39(join55(bundleDir, name2, ".claude-plugin", "plugin.json")));
|
|
97975
98649
|
}
|
|
97976
98650
|
function sameDir(a, b) {
|
|
97977
98651
|
const norm = (p) => resolve9(p).replace(/[\\/]+$/, "").toLowerCase();
|
|
97978
98652
|
return norm(a) === norm(b);
|
|
97979
98653
|
}
|
|
97980
98654
|
function isUnder(path3, root) {
|
|
97981
|
-
const rel =
|
|
98655
|
+
const rel = relative7(resolve9(root), resolve9(path3));
|
|
97982
98656
|
return rel !== "" && !rel.startsWith("..") && !rel.includes(":");
|
|
97983
98657
|
}
|
|
97984
98658
|
function off(env2) {
|
|
@@ -97988,7 +98662,7 @@ function off(env2) {
|
|
|
97988
98662
|
function readSettings(path3) {
|
|
97989
98663
|
if (!existsSync39(path3)) return {};
|
|
97990
98664
|
try {
|
|
97991
|
-
const parsed = JSON.parse(
|
|
98665
|
+
const parsed = JSON.parse(readFileSync47(path3, "utf8"));
|
|
97992
98666
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
97993
98667
|
return parsed;
|
|
97994
98668
|
} catch {
|
|
@@ -98012,13 +98686,13 @@ function currentDirs(settings) {
|
|
|
98012
98686
|
return raw2.split(delimiter2).map((s) => s.trim()).filter(Boolean);
|
|
98013
98687
|
}
|
|
98014
98688
|
function writeSettings(path3, settings) {
|
|
98015
|
-
mkdirSync12(
|
|
98016
|
-
|
|
98689
|
+
mkdirSync12(dirname19(path3), { recursive: true });
|
|
98690
|
+
writeFileSync33(path3, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
98017
98691
|
}
|
|
98018
98692
|
function ensureClaudeMods(opts) {
|
|
98019
98693
|
const env2 = opts.env ?? process.env;
|
|
98020
98694
|
const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
|
|
98021
|
-
const modsRoot =
|
|
98695
|
+
const modsRoot = join55(opts.installRoot, "claude-mods");
|
|
98022
98696
|
if (off(env2)) {
|
|
98023
98697
|
const settings2 = readSettings(settingsPath);
|
|
98024
98698
|
if (!settings2) return { kind: "unreadable" };
|
|
@@ -98035,14 +98709,14 @@ function ensureClaudeMods(opts) {
|
|
|
98035
98709
|
let changed = false;
|
|
98036
98710
|
const installed = [];
|
|
98037
98711
|
for (const name2 of names) {
|
|
98038
|
-
const src =
|
|
98039
|
-
const dest =
|
|
98712
|
+
const src = join55(bundleDir, name2);
|
|
98713
|
+
const dest = join55(modsRoot, name2);
|
|
98040
98714
|
const hash2 = modHash(src);
|
|
98041
|
-
const hashFile =
|
|
98042
|
-
if (!existsSync39(hashFile) ||
|
|
98715
|
+
const hashFile = join55(dest, HASH_FILE);
|
|
98716
|
+
if (!existsSync39(hashFile) || readFileSync47(hashFile, "utf8") !== hash2) {
|
|
98043
98717
|
rmSync4(dest, { recursive: true, force: true });
|
|
98044
|
-
cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(
|
|
98045
|
-
|
|
98718
|
+
cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative7(src, p)) });
|
|
98719
|
+
writeFileSync33(hashFile, hash2, "utf8");
|
|
98046
98720
|
changed = true;
|
|
98047
98721
|
}
|
|
98048
98722
|
installed.push(dest);
|
|
@@ -98445,8 +99119,6 @@ Commands:
|
|
|
98445
99119
|
|
|
98446
99120
|
Environment:
|
|
98447
99121
|
ERRATA_CLOUD_URL Cloud base URL (default ${DEFAULT_CLOUD_URL})
|
|
98448
|
-
ERRATA_ALLOW_DIRECT_V1_CLOUD=1 Staff-only: request direct legacy v1 (bypasses the gateway;
|
|
98449
|
-
also requires ERRATA_DIRECT_V1_ACK=I_ACCEPT_UNMETERED_DIRECT_V1)
|
|
98450
99122
|
${OAUTH_DEFAULT_ENV}=0 Test/dev escape hatch: plain \`errata login\` uses legacy device-code
|
|
98451
99123
|
`);
|
|
98452
99124
|
}
|
|
@@ -98463,9 +99135,9 @@ function resolveHookPort(explicit) {
|
|
|
98463
99135
|
}
|
|
98464
99136
|
}
|
|
98465
99137
|
}
|
|
98466
|
-
const settingsPath =
|
|
99138
|
+
const settingsPath = join56(ROOT, ".claude", "settings.json");
|
|
98467
99139
|
try {
|
|
98468
|
-
if (existsSync40(settingsPath)) return installedHookPort(
|
|
99140
|
+
if (existsSync40(settingsPath)) return installedHookPort(readFileSync48(settingsPath, "utf8")) ?? 7891;
|
|
98469
99141
|
} catch {
|
|
98470
99142
|
}
|
|
98471
99143
|
return 7891;
|
|
@@ -98491,13 +99163,13 @@ async function cmdInit() {
|
|
|
98491
99163
|
console.log("");
|
|
98492
99164
|
console.log("installing harness hooks...");
|
|
98493
99165
|
const { existsSync: existsSync41 } = await import("node:fs");
|
|
98494
|
-
const { join:
|
|
99166
|
+
const { join: join57 } = await import("node:path");
|
|
98495
99167
|
try {
|
|
98496
99168
|
await installClaudeHooks(port);
|
|
98497
99169
|
} catch (err2) {
|
|
98498
99170
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
98499
99171
|
}
|
|
98500
|
-
if (existsSync41(
|
|
99172
|
+
if (existsSync41(join57(ROOT, ".cursor"))) {
|
|
98501
99173
|
try {
|
|
98502
99174
|
await installCursorMcpConfig();
|
|
98503
99175
|
} catch (err2) {
|
|
@@ -99720,7 +100392,7 @@ async function cmdReview() {
|
|
|
99720
100392
|
console.log("(review queue empty)");
|
|
99721
100393
|
return;
|
|
99722
100394
|
}
|
|
99723
|
-
const queue = JSON.parse(
|
|
100395
|
+
const queue = JSON.parse(readFileSync48(paths.reviewQueue, "utf8"));
|
|
99724
100396
|
if (queue.length === 0) {
|
|
99725
100397
|
console.log("(review queue empty)");
|
|
99726
100398
|
return;
|
|
@@ -100459,7 +101131,7 @@ async function gatherReportData(generatedAt) {
|
|
|
100459
101131
|
};
|
|
100460
101132
|
}
|
|
100461
101133
|
async function cmdReport(args2) {
|
|
100462
|
-
const { mkdirSync: mkdirSync13, writeFileSync:
|
|
101134
|
+
const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
100463
101135
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
100464
101136
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
100465
101137
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -100472,8 +101144,8 @@ async function cmdReport(args2) {
|
|
|
100472
101144
|
const outDir = workspacePaths(ROOT).configDir;
|
|
100473
101145
|
mkdirSync13(outDir, { recursive: true });
|
|
100474
101146
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
100475
|
-
for (const f of files)
|
|
100476
|
-
const indexPath =
|
|
101147
|
+
for (const f of files) writeFileSync34(join56(outDir, f.name), f.html, "utf8");
|
|
101148
|
+
const indexPath = join56(outDir, "report.html");
|
|
100477
101149
|
console.log(`report \u2192 ${indexPath}`);
|
|
100478
101150
|
console.log(
|
|
100479
101151
|
` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
|
|
@@ -100529,7 +101201,7 @@ function spawnDaemonDetached(options = {}) {
|
|
|
100529
101201
|
try {
|
|
100530
101202
|
const logPath = daemonLogPath();
|
|
100531
101203
|
try {
|
|
100532
|
-
if (
|
|
101204
|
+
if (statSync16(logPath).size > 5 * 1024 * 1024) renameSync10(logPath, `${logPath}.1`);
|
|
100533
101205
|
} catch {
|
|
100534
101206
|
}
|
|
100535
101207
|
out2 = openSync3(logPath, "a");
|
|
@@ -100598,24 +101270,24 @@ async function cmdInstallHooks(args2) {
|
|
|
100598
101270
|
}
|
|
100599
101271
|
}
|
|
100600
101272
|
async function installOpencodePlugin(port) {
|
|
100601
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100602
|
-
const { join:
|
|
100603
|
-
const dir =
|
|
101273
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
101274
|
+
const { join: join57 } = await import("node:path");
|
|
101275
|
+
const dir = join57(ROOT, ".opencode", "plugin");
|
|
100604
101276
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100605
|
-
const file2 =
|
|
101277
|
+
const file2 = join57(dir, "inerrata.js");
|
|
100606
101278
|
if (existsSync41(file2)) {
|
|
100607
|
-
const head2 =
|
|
101279
|
+
const head2 = readFileSync49(file2, "utf8").split("\n")[0] ?? "";
|
|
100608
101280
|
if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
|
|
100609
101281
|
console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
|
|
100610
101282
|
process.exit(2);
|
|
100611
101283
|
}
|
|
100612
101284
|
}
|
|
100613
|
-
|
|
100614
|
-
const cfgFile =
|
|
101285
|
+
writeFileSync34(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
|
|
101286
|
+
const cfgFile = join57(ROOT, "opencode.json");
|
|
100615
101287
|
let cfg = { $schema: "https://opencode.ai/config.json" };
|
|
100616
101288
|
if (existsSync41(cfgFile)) {
|
|
100617
101289
|
try {
|
|
100618
|
-
cfg = JSON.parse(
|
|
101290
|
+
cfg = JSON.parse(readFileSync49(cfgFile, "utf8"));
|
|
100619
101291
|
} catch {
|
|
100620
101292
|
console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
|
|
100621
101293
|
process.exit(2);
|
|
@@ -100626,7 +101298,7 @@ async function installOpencodePlugin(port) {
|
|
|
100626
101298
|
if (!hadErrata) {
|
|
100627
101299
|
const inv = errataMcpInvocation();
|
|
100628
101300
|
cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
|
|
100629
|
-
|
|
101301
|
+
writeFileSync34(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
100630
101302
|
}
|
|
100631
101303
|
console.log(`installed OpenCode plugin \u2192 ${file2}`);
|
|
100632
101304
|
if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
|
|
@@ -100661,15 +101333,15 @@ function installClaudeMods() {
|
|
|
100661
101333
|
}
|
|
100662
101334
|
}
|
|
100663
101335
|
async function installClaudeHooks(port) {
|
|
100664
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100665
|
-
const { join:
|
|
100666
|
-
const dir =
|
|
101336
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
101337
|
+
const { join: join57 } = await import("node:path");
|
|
101338
|
+
const dir = join57(ROOT, ".claude");
|
|
100667
101339
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100668
|
-
const file2 =
|
|
101340
|
+
const file2 = join57(dir, "settings.json");
|
|
100669
101341
|
let settings = {};
|
|
100670
101342
|
if (existsSync41(file2)) {
|
|
100671
101343
|
try {
|
|
100672
|
-
settings = JSON.parse(
|
|
101344
|
+
settings = JSON.parse(readFileSync49(file2, "utf8"));
|
|
100673
101345
|
} catch {
|
|
100674
101346
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
100675
101347
|
process.exit(2);
|
|
@@ -100718,12 +101390,12 @@ async function installClaudeHooks(port) {
|
|
|
100718
101390
|
list.push({ hooks: [{ type: "command", command: injectCmd }] });
|
|
100719
101391
|
}
|
|
100720
101392
|
removeProjectStatusLine(settings);
|
|
100721
|
-
|
|
101393
|
+
writeFileSync34(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
100722
101394
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
100723
101395
|
console.log(` ${ensureStatusLine(port)}`);
|
|
100724
101396
|
console.log(` ${installClaudeMods().line}`);
|
|
100725
101397
|
await installClaudeMcpConfig();
|
|
100726
|
-
const claudeMd =
|
|
101398
|
+
const claudeMd = join57(ROOT, "CLAUDE.md");
|
|
100727
101399
|
const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
|
|
100728
101400
|
if (recall.kind === "collision") {
|
|
100729
101401
|
console.warn(
|
|
@@ -100735,15 +101407,15 @@ async function installClaudeHooks(port) {
|
|
|
100735
101407
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
100736
101408
|
}
|
|
100737
101409
|
async function installClaudeMcpConfig() {
|
|
100738
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100739
|
-
const { join:
|
|
100740
|
-
const file2 =
|
|
100741
|
-
const dir =
|
|
101410
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
101411
|
+
const { join: join57, dirname: dirname20 } = await import("node:path");
|
|
101412
|
+
const file2 = join57(ROOT, ".mcp.json");
|
|
101413
|
+
const dir = dirname20(file2);
|
|
100742
101414
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100743
101415
|
let cfg = {};
|
|
100744
101416
|
if (existsSync41(file2)) {
|
|
100745
101417
|
try {
|
|
100746
|
-
cfg = JSON.parse(
|
|
101418
|
+
cfg = JSON.parse(readFileSync49(file2, "utf8"));
|
|
100747
101419
|
} catch {
|
|
100748
101420
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
100749
101421
|
process.exit(2);
|
|
@@ -100751,21 +101423,21 @@ async function installClaudeMcpConfig() {
|
|
|
100751
101423
|
}
|
|
100752
101424
|
cfg.mcpServers ??= {};
|
|
100753
101425
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
100754
|
-
|
|
101426
|
+
writeFileSync34(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
100755
101427
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
100756
101428
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
100757
101429
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
100758
101430
|
}
|
|
100759
101431
|
async function installCursorMcpConfig() {
|
|
100760
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100761
|
-
const { join:
|
|
100762
|
-
const dir =
|
|
101432
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
101433
|
+
const { join: join57 } = await import("node:path");
|
|
101434
|
+
const dir = join57(ROOT, ".cursor");
|
|
100763
101435
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100764
|
-
const file2 =
|
|
101436
|
+
const file2 = join57(dir, "mcp.json");
|
|
100765
101437
|
let cfg = {};
|
|
100766
101438
|
if (existsSync41(file2)) {
|
|
100767
101439
|
try {
|
|
100768
|
-
cfg = JSON.parse(
|
|
101440
|
+
cfg = JSON.parse(readFileSync49(file2, "utf8"));
|
|
100769
101441
|
} catch {
|
|
100770
101442
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
100771
101443
|
process.exit(2);
|
|
@@ -100773,7 +101445,7 @@ async function installCursorMcpConfig() {
|
|
|
100773
101445
|
}
|
|
100774
101446
|
cfg.mcpServers ??= {};
|
|
100775
101447
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
100776
|
-
|
|
101448
|
+
writeFileSync34(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
100777
101449
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
100778
101450
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
100779
101451
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -100784,7 +101456,7 @@ async function installCodexHooks(port) {
|
|
|
100784
101456
|
const gitRoot = nearestGitRoot(process.cwd());
|
|
100785
101457
|
const hookRoot = gitRoot && mainCheckoutOfWorktree(gitRoot) ? gitRoot : ROOT;
|
|
100786
101458
|
const file2 = writeCodexHooks(hookRoot, port);
|
|
100787
|
-
const instructions = writeManagedBlock(
|
|
101459
|
+
const instructions = writeManagedBlock(join56(hookRoot, "AGENTS.md"), {
|
|
100788
101460
|
body: AGENTS_POINTER_BODY,
|
|
100789
101461
|
stable: true
|
|
100790
101462
|
});
|
|
@@ -101230,9 +101902,9 @@ async function cmdDash(args2) {
|
|
|
101230
101902
|
await yieldToLoop2();
|
|
101231
101903
|
try {
|
|
101232
101904
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
|
|
101233
|
-
atCommit: readGitRefState(
|
|
101905
|
+
atCommit: readGitRefState(join56(r.root, ".git")).sha ?? void 0
|
|
101234
101906
|
});
|
|
101235
|
-
const res = bleedRules(
|
|
101907
|
+
const res = bleedRules(join56(r.root, ".claude", "rules"), items);
|
|
101236
101908
|
if (res.written || res.pruned) {
|
|
101237
101909
|
console.log(
|
|
101238
101910
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|