@inerrata-corporation/errata 2.0.22-dev.4430 → 2.0.22-dev.4534
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 +1276 -535
- 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
|
}
|
|
@@ -35158,7 +35361,7 @@ function rememberAgentCard(sessionId, agentId, card, now = Date.now()) {
|
|
|
35158
35361
|
function subagentRows(body2, now = Date.now()) {
|
|
35159
35362
|
const sessionId = typeof body2["session_id"] === "string" ? body2["session_id"] : "";
|
|
35160
35363
|
const tasks = Array.isArray(body2["tasks"]) ? body2["tasks"] : [];
|
|
35161
|
-
const
|
|
35364
|
+
const columns2 = typeof body2["columns"] === "number" && body2["columns"] > 20 ? body2["columns"] : 100;
|
|
35162
35365
|
const lines = [];
|
|
35163
35366
|
for (const task of tasks) {
|
|
35164
35367
|
const id = typeof task["id"] === "string" ? task["id"] : "";
|
|
@@ -35168,7 +35371,7 @@ function subagentRows(body2, now = Date.now()) {
|
|
|
35168
35371
|
const title = String(task["description"] ?? task["label"] ?? "").trim();
|
|
35169
35372
|
const plain = clip(
|
|
35170
35373
|
`${title ? `${title} \xB7 ` : ""}\u26A1 errata \xB7 ${hit.card.headline}${lead2 ? ` \u2014 ${labelName(lead2.label)}: ${lead2.text}` : ""}`,
|
|
35171
|
-
|
|
35374
|
+
columns2 - 2
|
|
35172
35375
|
);
|
|
35173
35376
|
lines.push(JSON.stringify({ id, content: plain.replace("\u26A1", `${AMBER}\u26A1${RESET}`) }));
|
|
35174
35377
|
}
|
|
@@ -38216,8 +38419,8 @@ import { execFileSync as execFileSync3 } from "node:child_process";
|
|
|
38216
38419
|
function nowTs() {
|
|
38217
38420
|
return indexNow ?? Date.now();
|
|
38218
38421
|
}
|
|
38219
|
-
function fingerprintOf(
|
|
38220
|
-
return `${
|
|
38422
|
+
function fingerprintOf(signature2, bodyHash) {
|
|
38423
|
+
return `${signature2 ?? ""}|${bodyHash ?? ""}`;
|
|
38221
38424
|
}
|
|
38222
38425
|
function sha(s) {
|
|
38223
38426
|
return createHash7("sha256").update(s).digest("hex").slice(0, 16);
|
|
@@ -46733,11 +46936,20 @@ function* walkSource(dir) {
|
|
|
46733
46936
|
function listSourceFiles(root) {
|
|
46734
46937
|
return gitSourceFiles(root) ?? walkSource(root);
|
|
46735
46938
|
}
|
|
46736
|
-
async function findStaleFiles(store, rootPath, workspaceId2) {
|
|
46939
|
+
async function findStaleFiles(store, rootPath, workspaceId2, lineageVerifiedAt) {
|
|
46737
46940
|
const stale = [];
|
|
46941
|
+
const changed = lineageVerifiedAt !== void 0 && store.fileRowStates ? store.lineageChangedFiles?.(lineageVerifiedAt) : null;
|
|
46942
|
+
const relineage = changed ? new Set(changed) : null;
|
|
46738
46943
|
let pending = [];
|
|
46739
46944
|
const check2 = () => {
|
|
46740
|
-
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
|
+
}
|
|
46741
46953
|
for (const f of pending) {
|
|
46742
46954
|
const state = states.get(f.id);
|
|
46743
46955
|
if (!state || state.validTo !== null || state.lastUpdatedAt < f.mtimeMs || !state.complete) stale.push(f.abs);
|
|
@@ -46762,6 +46974,19 @@ async function findStaleFiles(store, rootPath, workspaceId2) {
|
|
|
46762
46974
|
function findStrandedSymbols(store) {
|
|
46763
46975
|
return store.strandedSymbols();
|
|
46764
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
|
+
}
|
|
46765
46990
|
function reapOrphanedFiles(store, rootPath, workspaceId2, ignoreDirs = []) {
|
|
46766
46991
|
const ignores = /* @__PURE__ */ new Set([...DEFAULT_IGNORES, ...ignoreDirs]);
|
|
46767
46992
|
const listed = gitListRelPaths(rootPath, ignores);
|
|
@@ -46800,8 +47025,16 @@ function reapOrphanedFiles(store, rootPath, workspaceId2, ignoreDirs = []) {
|
|
|
46800
47025
|
return { reaped: orphans.length, symbolsClosed };
|
|
46801
47026
|
}
|
|
46802
47027
|
async function reconcileStaleFiles(store, rootPath, workspaceId2) {
|
|
46803
|
-
const
|
|
46804
|
-
|
|
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
|
+
}
|
|
46805
47038
|
let total = 0;
|
|
46806
47039
|
let failedBatches = 0;
|
|
46807
47040
|
const BATCH = 20;
|
|
@@ -46819,10 +47052,12 @@ async function reconcileStaleFiles(store, rootPath, workspaceId2) {
|
|
|
46819
47052
|
}
|
|
46820
47053
|
if (failedBatches > 0) {
|
|
46821
47054
|
console.warn(`[errata] reconcile: ${failedBatches} batch(es) failed; ${total} file(s) reindexed`);
|
|
47055
|
+
} else {
|
|
47056
|
+
verify();
|
|
46822
47057
|
}
|
|
46823
47058
|
return total;
|
|
46824
47059
|
}
|
|
46825
|
-
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;
|
|
46826
47061
|
var init_reconcile = __esm({
|
|
46827
47062
|
"src/reconcile.ts"() {
|
|
46828
47063
|
"use strict";
|
|
@@ -46830,8 +47065,11 @@ var init_reconcile = __esm({
|
|
|
46830
47065
|
IGNORED = /[\\/](?:\.git|node_modules|\.errata|dist|__pycache__)(?:[\\/]|$)/;
|
|
46831
47066
|
SOURCE_RE = /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i;
|
|
46832
47067
|
SCAN_YIELD_EVERY = 100;
|
|
47068
|
+
STRANDED_KEY = "pass-inputs:stranded";
|
|
47069
|
+
STRANDED_WINDOW_MAX = 2e4;
|
|
46833
47070
|
ORPHAN_REAP_MAX_FRACTION = 0.25;
|
|
46834
47071
|
ORPHAN_REAP_MIN_ALLOWANCE = 50;
|
|
47072
|
+
LINEAGE_VERIFIED_KEY = "pass-inputs:reconcile-lineage";
|
|
46835
47073
|
}
|
|
46836
47074
|
});
|
|
46837
47075
|
|
|
@@ -76471,18 +76709,18 @@ __export(witness_ledger_exports, {
|
|
|
76471
76709
|
summarizeWitnessLedger: () => summarizeWitnessLedger,
|
|
76472
76710
|
witnessLedgerPath: () => witnessLedgerPath
|
|
76473
76711
|
});
|
|
76474
|
-
import { appendFileSync as appendFileSync3, existsSync as existsSync27, readFileSync as
|
|
76475
|
-
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";
|
|
76476
76714
|
function witnessLedgerPath(configDir) {
|
|
76477
|
-
return
|
|
76715
|
+
return join35(configDir, "witness-ledger.jsonl");
|
|
76478
76716
|
}
|
|
76479
76717
|
function appendWitnessLedger(configDir, entry) {
|
|
76480
76718
|
const path3 = witnessLedgerPath(configDir);
|
|
76481
76719
|
try {
|
|
76482
76720
|
appendFileSync3(path3, JSON.stringify(entry) + "\n");
|
|
76483
|
-
const lines =
|
|
76721
|
+
const lines = readFileSync31(path3, "utf8").split("\n").filter(Boolean);
|
|
76484
76722
|
if (lines.length > LEDGER_MAX_LINES) {
|
|
76485
|
-
|
|
76723
|
+
writeFileSync22(path3, lines.slice(-Math.floor(LEDGER_MAX_LINES / 2)).join("\n") + "\n");
|
|
76486
76724
|
}
|
|
76487
76725
|
} catch {
|
|
76488
76726
|
}
|
|
@@ -76491,7 +76729,7 @@ function readWitnessLedger(configDir) {
|
|
|
76491
76729
|
const path3 = witnessLedgerPath(configDir);
|
|
76492
76730
|
if (!existsSync27(path3)) return [];
|
|
76493
76731
|
try {
|
|
76494
|
-
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");
|
|
76495
76733
|
} catch {
|
|
76496
76734
|
return [];
|
|
76497
76735
|
}
|
|
@@ -76930,12 +77168,12 @@ var init_report_render = __esm({
|
|
|
76930
77168
|
|
|
76931
77169
|
// src/cli.ts
|
|
76932
77170
|
init_src6();
|
|
76933
|
-
import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as
|
|
76934
|
-
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";
|
|
76935
77173
|
import { spawn as spawn5 } from "node:child_process";
|
|
76936
77174
|
|
|
76937
77175
|
// src/daemon.ts
|
|
76938
|
-
import { existsSync as existsSync29, writeFileSync as
|
|
77176
|
+
import { existsSync as existsSync29, writeFileSync as writeFileSync25 } from "node:fs";
|
|
76939
77177
|
|
|
76940
77178
|
// ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.34/node_modules/@hono/node-server/dist/index.mjs
|
|
76941
77179
|
import { createServer as createServerHTTP } from "http";
|
|
@@ -77619,8 +77857,8 @@ function knowledgeTag(label, attrs) {
|
|
|
77619
77857
|
|
|
77620
77858
|
// src/engine.ts
|
|
77621
77859
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
77622
|
-
import { existsSync as existsSync28, statSync as
|
|
77623
|
-
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";
|
|
77624
77862
|
|
|
77625
77863
|
// src/coalesced-file-pass.ts
|
|
77626
77864
|
function createCoalescedFilePass(delayMs, run3, onError) {
|
|
@@ -77665,7 +77903,7 @@ function createCoalescedFilePass(delayMs, run3, onError) {
|
|
|
77665
77903
|
// src/source-watcher.ts
|
|
77666
77904
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
77667
77905
|
import { readdirSync as readdirSync6, statSync as statSync7, watch as watch2 } from "node:fs";
|
|
77668
|
-
import {
|
|
77906
|
+
import { join as join21, sep as sep4 } from "node:path";
|
|
77669
77907
|
|
|
77670
77908
|
// ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
|
|
77671
77909
|
import { stat as statcb } from "fs";
|
|
@@ -78396,9 +78634,9 @@ var NodeFsHandler = class {
|
|
|
78396
78634
|
if (this.fsw.closed) {
|
|
78397
78635
|
return;
|
|
78398
78636
|
}
|
|
78399
|
-
const
|
|
78637
|
+
const dirname20 = sysPath.dirname(file2);
|
|
78400
78638
|
const basename10 = sysPath.basename(file2);
|
|
78401
|
-
const parent = this.fsw._getWatchedDir(
|
|
78639
|
+
const parent = this.fsw._getWatchedDir(dirname20);
|
|
78402
78640
|
let prevStats = stats;
|
|
78403
78641
|
if (parent.has(basename10))
|
|
78404
78642
|
return;
|
|
@@ -78425,7 +78663,7 @@ var NodeFsHandler = class {
|
|
|
78425
78663
|
prevStats = newStats2;
|
|
78426
78664
|
}
|
|
78427
78665
|
} catch (error48) {
|
|
78428
|
-
this.fsw._remove(
|
|
78666
|
+
this.fsw._remove(dirname20, basename10);
|
|
78429
78667
|
}
|
|
78430
78668
|
} else if (parent.has(basename10)) {
|
|
78431
78669
|
const at = newStats.atimeMs;
|
|
@@ -78674,11 +78912,11 @@ function createPattern(matcher) {
|
|
|
78674
78912
|
if (matcher.path === string4)
|
|
78675
78913
|
return true;
|
|
78676
78914
|
if (matcher.recursive) {
|
|
78677
|
-
const
|
|
78678
|
-
if (!
|
|
78915
|
+
const relative8 = sysPath2.relative(matcher.path, string4);
|
|
78916
|
+
if (!relative8) {
|
|
78679
78917
|
return false;
|
|
78680
78918
|
}
|
|
78681
|
-
return !
|
|
78919
|
+
return !relative8.startsWith("..") && !sysPath2.isAbsolute(relative8);
|
|
78682
78920
|
}
|
|
78683
78921
|
return false;
|
|
78684
78922
|
};
|
|
@@ -79387,7 +79625,9 @@ var NativeSourceWatcher = class extends EventEmitter2 {
|
|
|
79387
79625
|
handles = /* @__PURE__ */ new Map();
|
|
79388
79626
|
pending = /* @__PURE__ */ new Map();
|
|
79389
79627
|
rescans = /* @__PURE__ */ new Map();
|
|
79390
|
-
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();
|
|
79391
79631
|
closed = false;
|
|
79392
79632
|
add(target) {
|
|
79393
79633
|
if (this.closed || this.handles.has(target)) return;
|
|
@@ -79441,21 +79681,35 @@ var NativeSourceWatcher = class extends EventEmitter2 {
|
|
|
79441
79681
|
this.pending.set(path3, { timer, renamed: renamed || (prev?.renamed ?? false) });
|
|
79442
79682
|
}
|
|
79443
79683
|
seedKnown(target, isDir) {
|
|
79444
|
-
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);
|
|
79445
79685
|
}
|
|
79446
79686
|
filesUnder(target, isDir) {
|
|
79447
|
-
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
|
+
};
|
|
79448
79694
|
if (!isDir) {
|
|
79449
|
-
if (!this.ignored(target))
|
|
79695
|
+
if (!this.ignored(target)) add(target);
|
|
79450
79696
|
return files;
|
|
79451
79697
|
}
|
|
79452
|
-
|
|
79453
|
-
|
|
79454
|
-
|
|
79455
|
-
|
|
79456
|
-
|
|
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);
|
|
79457
79712
|
}
|
|
79458
|
-
} catch {
|
|
79459
79713
|
}
|
|
79460
79714
|
return files;
|
|
79461
79715
|
}
|
|
@@ -79466,19 +79720,17 @@ var NativeSourceWatcher = class extends EventEmitter2 {
|
|
|
79466
79720
|
this.rescans.delete(target);
|
|
79467
79721
|
if (this.closed || !this.handles.has(target)) return;
|
|
79468
79722
|
const current = this.filesUnder(target, isDir);
|
|
79469
|
-
const
|
|
79470
|
-
|
|
79471
|
-
|
|
79472
|
-
};
|
|
79473
|
-
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()]) {
|
|
79474
79726
|
if (belongsToTarget(path3) && !current.has(path3)) {
|
|
79475
79727
|
this.known.delete(path3);
|
|
79476
79728
|
this.emit("unlink", path3);
|
|
79477
79729
|
}
|
|
79478
79730
|
}
|
|
79479
|
-
for (const path3 of current) {
|
|
79731
|
+
for (const [path3, sig] of current) {
|
|
79480
79732
|
if (!this.known.has(path3)) {
|
|
79481
|
-
this.known.
|
|
79733
|
+
this.known.set(path3, sig);
|
|
79482
79734
|
this.emit("add", path3);
|
|
79483
79735
|
}
|
|
79484
79736
|
}
|
|
@@ -79488,21 +79740,27 @@ var NativeSourceWatcher = class extends EventEmitter2 {
|
|
|
79488
79740
|
classify(path3, renamed) {
|
|
79489
79741
|
if (this.closed) return;
|
|
79490
79742
|
let isFile;
|
|
79743
|
+
let sig;
|
|
79491
79744
|
try {
|
|
79492
79745
|
const s = statSync7(path3);
|
|
79493
79746
|
if (s.isDirectory()) return;
|
|
79494
79747
|
isFile = s.isFile();
|
|
79748
|
+
sig = signature(s);
|
|
79495
79749
|
} catch {
|
|
79496
79750
|
this.known.delete(path3);
|
|
79497
79751
|
this.emit("unlink", path3);
|
|
79498
79752
|
return;
|
|
79499
79753
|
}
|
|
79500
79754
|
if (!isFile) return;
|
|
79501
|
-
const
|
|
79502
|
-
|
|
79503
|
-
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);
|
|
79504
79759
|
}
|
|
79505
79760
|
};
|
|
79761
|
+
function signature(s) {
|
|
79762
|
+
return `${Math.trunc(s.mtimeMs)}:${s.size}:${Math.trunc(s.ctimeMs)}`;
|
|
79763
|
+
}
|
|
79506
79764
|
|
|
79507
79765
|
// src/engine.ts
|
|
79508
79766
|
init_generalize_graph();
|
|
@@ -79756,6 +80014,47 @@ async function chat(req) {
|
|
|
79756
80014
|
init_src11();
|
|
79757
80015
|
init_src6();
|
|
79758
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
|
|
79759
80058
|
init_recall_signal();
|
|
79760
80059
|
|
|
79761
80060
|
// src/subagent-state.ts
|
|
@@ -79944,8 +80243,8 @@ init_review2();
|
|
|
79944
80243
|
|
|
79945
80244
|
// src/turn.ts
|
|
79946
80245
|
init_checkout_root();
|
|
79947
|
-
import { closeSync as closeSync2, existsSync as existsSync19, fstatSync, openSync as openSync2, readdirSync as readdirSync7, readSync as readSync2, realpathSync as realpathSync2, statSync as
|
|
79948
|
-
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";
|
|
79949
80248
|
import { homedir as homedir4 } from "node:os";
|
|
79950
80249
|
import { createHash as createHash16 } from "node:crypto";
|
|
79951
80250
|
function completeJsonlPrefix(buf) {
|
|
@@ -80333,7 +80632,7 @@ function turnsSince(turns, mark) {
|
|
|
80333
80632
|
return at >= 0 ? turns.slice(at + 1) : turns;
|
|
80334
80633
|
}
|
|
80335
80634
|
function claudeProjectDir(cwd, home = homedir4()) {
|
|
80336
|
-
return
|
|
80635
|
+
return join23(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
|
|
80337
80636
|
}
|
|
80338
80637
|
function recentTranscripts(cwd, opts = {}) {
|
|
80339
80638
|
const dir = claudeProjectDir(cwd, opts.home ?? homedir4());
|
|
@@ -80348,10 +80647,10 @@ function recentTranscripts(cwd, opts = {}) {
|
|
|
80348
80647
|
const refs = [];
|
|
80349
80648
|
for (const name2 of names) {
|
|
80350
80649
|
if (!name2.endsWith(".jsonl")) continue;
|
|
80351
|
-
const path3 =
|
|
80650
|
+
const path3 = join23(dir, name2);
|
|
80352
80651
|
let mtimeMs;
|
|
80353
80652
|
try {
|
|
80354
|
-
mtimeMs =
|
|
80653
|
+
mtimeMs = statSync9(path3).mtimeMs;
|
|
80355
80654
|
} catch {
|
|
80356
80655
|
continue;
|
|
80357
80656
|
}
|
|
@@ -80363,7 +80662,7 @@ function recentTranscripts(cwd, opts = {}) {
|
|
|
80363
80662
|
}
|
|
80364
80663
|
function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
80365
80664
|
if (!mainTranscriptPath || !sessionId) return [];
|
|
80366
|
-
const dir =
|
|
80665
|
+
const dir = join23(dirname12(mainTranscriptPath), sessionId, "subagents");
|
|
80367
80666
|
if (!existsSync19(dir)) return [];
|
|
80368
80667
|
let names;
|
|
80369
80668
|
try {
|
|
@@ -80374,10 +80673,10 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
|
80374
80673
|
const refs = [];
|
|
80375
80674
|
for (const name2 of names) {
|
|
80376
80675
|
if (!name2.endsWith(".jsonl")) continue;
|
|
80377
|
-
const path3 =
|
|
80676
|
+
const path3 = join23(dir, name2);
|
|
80378
80677
|
let mtimeMs;
|
|
80379
80678
|
try {
|
|
80380
|
-
mtimeMs =
|
|
80679
|
+
mtimeMs = statSync9(path3).mtimeMs;
|
|
80381
80680
|
} catch {
|
|
80382
80681
|
continue;
|
|
80383
80682
|
}
|
|
@@ -80386,15 +80685,15 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
|
80386
80685
|
refs.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
80387
80686
|
return refs;
|
|
80388
80687
|
}
|
|
80389
|
-
function splitPathList(value,
|
|
80688
|
+
function splitPathList(value, sep7 = delimiter) {
|
|
80390
80689
|
if (!value) return [];
|
|
80391
|
-
return value.split(
|
|
80690
|
+
return value.split(sep7).map((d) => d.trim()).filter(Boolean).map((d) => normalize3(d));
|
|
80392
80691
|
}
|
|
80393
80692
|
function codexSessionRoots(env2 = process.env, home = homedir4()) {
|
|
80394
80693
|
const roots = /* @__PURE__ */ new Set();
|
|
80395
80694
|
for (const d of splitPathList(env2["ERRATA_CODEX_SESSIONS_DIRS"])) roots.add(d);
|
|
80396
|
-
if (env2["CODEX_HOME"]) roots.add(
|
|
80397
|
-
roots.add(
|
|
80695
|
+
if (env2["CODEX_HOME"]) roots.add(join23(env2["CODEX_HOME"], "sessions"));
|
|
80696
|
+
roots.add(join23(home, ".codex", "sessions"));
|
|
80398
80697
|
return [...roots];
|
|
80399
80698
|
}
|
|
80400
80699
|
function readCodexRolloutIdentity(path3) {
|
|
@@ -80466,10 +80765,10 @@ function codexRolloutsForCwd(cwd, opts = {}) {
|
|
|
80466
80765
|
continue;
|
|
80467
80766
|
}
|
|
80468
80767
|
for (const name2 of names) {
|
|
80469
|
-
const full =
|
|
80768
|
+
const full = join23(dir, name2);
|
|
80470
80769
|
let st;
|
|
80471
80770
|
try {
|
|
80472
|
-
st =
|
|
80771
|
+
st = statSync9(full);
|
|
80473
80772
|
} catch {
|
|
80474
80773
|
continue;
|
|
80475
80774
|
}
|
|
@@ -80508,8 +80807,8 @@ function codexRolloutsForCwd(cwd, opts = {}) {
|
|
|
80508
80807
|
function geminiSessionRoots(env2 = process.env, home = homedir4()) {
|
|
80509
80808
|
const roots = /* @__PURE__ */ new Set();
|
|
80510
80809
|
for (const d of splitPathList(env2["ERRATA_GEMINI_SESSIONS_DIRS"])) roots.add(d);
|
|
80511
|
-
if (env2["GEMINI_CLI_HOME"]) roots.add(
|
|
80512
|
-
roots.add(
|
|
80810
|
+
if (env2["GEMINI_CLI_HOME"]) roots.add(join23(env2["GEMINI_CLI_HOME"], ".gemini", "tmp"));
|
|
80811
|
+
roots.add(join23(home, ".gemini", "tmp"));
|
|
80513
80812
|
return [...roots];
|
|
80514
80813
|
}
|
|
80515
80814
|
function geminiProjectHash(cwd) {
|
|
@@ -80557,7 +80856,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
|
|
|
80557
80856
|
continue;
|
|
80558
80857
|
}
|
|
80559
80858
|
for (const slug2 of slugs) {
|
|
80560
|
-
const chats =
|
|
80859
|
+
const chats = join23(root, slug2, "chats");
|
|
80561
80860
|
let names;
|
|
80562
80861
|
try {
|
|
80563
80862
|
names = readdirSync7(chats);
|
|
@@ -80566,10 +80865,10 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
|
|
|
80566
80865
|
}
|
|
80567
80866
|
for (const name2 of names) {
|
|
80568
80867
|
if (!name2.startsWith("session-") || !name2.endsWith(".jsonl")) continue;
|
|
80569
|
-
const full =
|
|
80868
|
+
const full = join23(chats, name2);
|
|
80570
80869
|
let st;
|
|
80571
80870
|
try {
|
|
80572
|
-
st =
|
|
80871
|
+
st = statSync9(full);
|
|
80573
80872
|
} catch {
|
|
80574
80873
|
continue;
|
|
80575
80874
|
}
|
|
@@ -80586,8 +80885,8 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
|
|
|
80586
80885
|
function opencodeSessionRoots(env2 = process.env, home = homedir4()) {
|
|
80587
80886
|
const roots = /* @__PURE__ */ new Set();
|
|
80588
80887
|
for (const d of splitPathList(env2["ERRATA_OPENCODE_SESSIONS_DIRS"])) roots.add(d);
|
|
80589
|
-
if (env2["XDG_DATA_HOME"]) roots.add(
|
|
80590
|
-
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"));
|
|
80591
80890
|
return [...roots];
|
|
80592
80891
|
}
|
|
80593
80892
|
function readOpencodeTranscriptDirectory(path3) {
|
|
@@ -80629,10 +80928,10 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
|
|
|
80629
80928
|
}
|
|
80630
80929
|
for (const name2 of names) {
|
|
80631
80930
|
if (!name2.endsWith(".jsonl")) continue;
|
|
80632
|
-
const full =
|
|
80931
|
+
const full = join23(root, name2);
|
|
80633
80932
|
let st;
|
|
80634
80933
|
try {
|
|
80635
|
-
st =
|
|
80934
|
+
st = statSync9(full);
|
|
80636
80935
|
} catch {
|
|
80637
80936
|
continue;
|
|
80638
80937
|
}
|
|
@@ -80652,7 +80951,7 @@ init_src2();
|
|
|
80652
80951
|
init_agent_signals();
|
|
80653
80952
|
init_tool_index();
|
|
80654
80953
|
init_src5();
|
|
80655
|
-
import { readFileSync as
|
|
80954
|
+
import { readFileSync as readFileSync19, writeFileSync as writeFileSync15 } from "node:fs";
|
|
80656
80955
|
var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
|
|
80657
80956
|
var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
|
|
80658
80957
|
var HANDLE_RE2 = new RegExp(TAG_HANDLE_SOURCE, "gi");
|
|
@@ -81452,13 +81751,13 @@ function writePrimingHandles(path3, nodes, now = Date.now()) {
|
|
|
81452
81751
|
entries.sort((a, b) => (b[1].seenAt ?? 0) - (a[1].seenAt ?? 0));
|
|
81453
81752
|
entries.length = HANDLE_MAP_MAX;
|
|
81454
81753
|
}
|
|
81455
|
-
|
|
81754
|
+
writeFileSync15(path3, JSON.stringify(Object.fromEntries(entries)));
|
|
81456
81755
|
} catch {
|
|
81457
81756
|
}
|
|
81458
81757
|
}
|
|
81459
81758
|
function readPrimingHandles(path3) {
|
|
81460
81759
|
try {
|
|
81461
|
-
return JSON.parse(
|
|
81760
|
+
return JSON.parse(readFileSync19(path3, "utf8"));
|
|
81462
81761
|
} catch {
|
|
81463
81762
|
return {};
|
|
81464
81763
|
}
|
|
@@ -81947,8 +82246,8 @@ ${conversation}` }]
|
|
|
81947
82246
|
// src/constraint-backfill.ts
|
|
81948
82247
|
init_src5();
|
|
81949
82248
|
init_src2();
|
|
81950
|
-
import { existsSync as existsSync20, readFileSync as
|
|
81951
|
-
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";
|
|
81952
82251
|
import { homedir as homedir5 } from "node:os";
|
|
81953
82252
|
var BACKFILL_VERSION = 1;
|
|
81954
82253
|
var EMPTY = {
|
|
@@ -81962,13 +82261,13 @@ var EMPTY = {
|
|
|
81962
82261
|
recoverable: 0
|
|
81963
82262
|
};
|
|
81964
82263
|
function markerPath(configDir) {
|
|
81965
|
-
return
|
|
82264
|
+
return join24(configDir, "constraint-backfill.json");
|
|
81966
82265
|
}
|
|
81967
82266
|
function alreadyDone(configDir) {
|
|
81968
82267
|
const p = markerPath(configDir);
|
|
81969
82268
|
if (!existsSync20(p)) return false;
|
|
81970
82269
|
try {
|
|
81971
|
-
const raw2 = JSON.parse(
|
|
82270
|
+
const raw2 = JSON.parse(readFileSync20(p, "utf8"));
|
|
81972
82271
|
return raw2?.version === BACKFILL_VERSION;
|
|
81973
82272
|
} catch {
|
|
81974
82273
|
return false;
|
|
@@ -81988,7 +82287,7 @@ function replay(root) {
|
|
|
81988
82287
|
for (const f of names) {
|
|
81989
82288
|
let lines;
|
|
81990
82289
|
try {
|
|
81991
|
-
lines =
|
|
82290
|
+
lines = readFileSync20(join24(dir, f), "utf8").split("\n");
|
|
81992
82291
|
} catch {
|
|
81993
82292
|
continue;
|
|
81994
82293
|
}
|
|
@@ -82102,7 +82401,7 @@ function backfillConstraintKind(store, opts) {
|
|
|
82102
82401
|
}
|
|
82103
82402
|
});
|
|
82104
82403
|
try {
|
|
82105
|
-
|
|
82404
|
+
writeFileSync16(
|
|
82106
82405
|
markerPath(opts.configDir),
|
|
82107
82406
|
JSON.stringify({ version: BACKFILL_VERSION, at: opts.now, ...report, cloudTwins: report.cloudTwins.length }, null, 2),
|
|
82108
82407
|
"utf8"
|
|
@@ -82115,8 +82414,8 @@ function backfillConstraintKind(store, opts) {
|
|
|
82115
82414
|
// src/edge-repair.ts
|
|
82116
82415
|
init_src();
|
|
82117
82416
|
init_src5();
|
|
82118
|
-
import { existsSync as existsSync21, readFileSync as
|
|
82119
|
-
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";
|
|
82120
82419
|
function citeEdgeId(from, type, to) {
|
|
82121
82420
|
return `edge_${digest({ from, type, to })}`.slice(0, 24);
|
|
82122
82421
|
}
|
|
@@ -82131,13 +82430,13 @@ var EMPTY2 = {
|
|
|
82131
82430
|
byType: {}
|
|
82132
82431
|
};
|
|
82133
82432
|
function markerPath2(configDir) {
|
|
82134
|
-
return
|
|
82433
|
+
return join25(configDir, "edge-repair.json");
|
|
82135
82434
|
}
|
|
82136
82435
|
function alreadyDone2(configDir) {
|
|
82137
82436
|
const p = markerPath2(configDir);
|
|
82138
82437
|
if (!existsSync21(p)) return false;
|
|
82139
82438
|
try {
|
|
82140
|
-
return JSON.parse(
|
|
82439
|
+
return JSON.parse(readFileSync21(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
|
|
82141
82440
|
} catch {
|
|
82142
82441
|
return false;
|
|
82143
82442
|
}
|
|
@@ -82186,7 +82485,7 @@ function repairInvalidEdges(store, opts) {
|
|
|
82186
82485
|
});
|
|
82187
82486
|
store.pruneEdgeRejections(opts.now - REJECTION_RETENTION_MS);
|
|
82188
82487
|
try {
|
|
82189
|
-
|
|
82488
|
+
writeFileSync17(
|
|
82190
82489
|
markerPath2(opts.configDir),
|
|
82191
82490
|
JSON.stringify({ version: EDGE_REPAIR_VERSION, at: opts.now, ...report }, null, 2),
|
|
82192
82491
|
"utf8"
|
|
@@ -82200,8 +82499,8 @@ function repairInvalidEdges(store, opts) {
|
|
|
82200
82499
|
init_reconcile();
|
|
82201
82500
|
|
|
82202
82501
|
// src/pass-ledger.ts
|
|
82203
|
-
import { appendFileSync as appendFileSync2, existsSync as existsSync22, readFileSync as
|
|
82204
|
-
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";
|
|
82205
82504
|
|
|
82206
82505
|
// src/isolate-census.ts
|
|
82207
82506
|
var live2 = 0;
|
|
@@ -82219,6 +82518,11 @@ function isolateCensus() {
|
|
|
82219
82518
|
return { live: live2, spawnedTotal, peak };
|
|
82220
82519
|
}
|
|
82221
82520
|
|
|
82521
|
+
// src/io-reads.ts
|
|
82522
|
+
function ioReadOps() {
|
|
82523
|
+
return process.resourceUsage().fsRead;
|
|
82524
|
+
}
|
|
82525
|
+
|
|
82222
82526
|
// src/pass-ledger.ts
|
|
82223
82527
|
var PER_KIND_MAX = 100;
|
|
82224
82528
|
var LEVEL_TAIL_KINDS = /* @__PURE__ */ new Set(["wm-calibration"]);
|
|
@@ -82227,7 +82531,7 @@ var HOUR_MS = 36e5;
|
|
|
82227
82531
|
var TRIM_EVERY = 50;
|
|
82228
82532
|
var appendsSinceTrim = /* @__PURE__ */ new Map();
|
|
82229
82533
|
function passLedgerPath(configDir) {
|
|
82230
|
-
return
|
|
82534
|
+
return join26(configDir, "pass-ledger.jsonl");
|
|
82231
82535
|
}
|
|
82232
82536
|
function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
82233
82537
|
const path3 = passLedgerPath(configDir);
|
|
@@ -82246,7 +82550,10 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
|
82246
82550
|
arrayBuffersMB: Math.round(mem.arrayBuffers / 1048576),
|
|
82247
82551
|
isolatesLive: census2.live,
|
|
82248
82552
|
isolatesSpawned: census2.spawnedTotal,
|
|
82249
|
-
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()
|
|
82250
82557
|
}
|
|
82251
82558
|
};
|
|
82252
82559
|
appendFileSync2(path3, JSON.stringify(entry) + "\n");
|
|
@@ -82256,7 +82563,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
|
82256
82563
|
return;
|
|
82257
82564
|
}
|
|
82258
82565
|
appendsSinceTrim.set(path3, 0);
|
|
82259
|
-
const lines =
|
|
82566
|
+
const lines = readFileSync22(path3, "utf8").split("\n").filter(Boolean);
|
|
82260
82567
|
const keptByKind = /* @__PURE__ */ new Map();
|
|
82261
82568
|
const tailHours = /* @__PURE__ */ new Map();
|
|
82262
82569
|
const tailFloor = Date.now() - LEVEL_TAIL_DAYS * 24 * HOUR_MS;
|
|
@@ -82284,7 +82591,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
|
82284
82591
|
kept.push(lines[i2]);
|
|
82285
82592
|
}
|
|
82286
82593
|
if (kept.length < lines.length) {
|
|
82287
|
-
|
|
82594
|
+
writeFileSync18(path3, kept.reverse().join("\n") + "\n");
|
|
82288
82595
|
}
|
|
82289
82596
|
} catch {
|
|
82290
82597
|
}
|
|
@@ -82293,7 +82600,7 @@ function readPassLedger(configDir) {
|
|
|
82293
82600
|
const path3 = passLedgerPath(configDir);
|
|
82294
82601
|
if (!existsSync22(path3)) return [];
|
|
82295
82602
|
try {
|
|
82296
|
-
return
|
|
82603
|
+
return readFileSync22(path3, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
|
|
82297
82604
|
(e) => typeof e?.ts === "number" && typeof e?.kind === "string" && typeof e?.durationMs === "number"
|
|
82298
82605
|
).map((e) => ({ ...e, counts: e.counts ?? {} }));
|
|
82299
82606
|
} catch {
|
|
@@ -82540,6 +82847,7 @@ function withHeavyPassSlot(label, fn) {
|
|
|
82540
82847
|
const waited = Date.now() - queuedAt;
|
|
82541
82848
|
waiting.delete(id);
|
|
82542
82849
|
const startedAt = Date.now();
|
|
82850
|
+
const readsAtStart = ioReadOps();
|
|
82543
82851
|
active = { label, startedAt, waitedMs: waited };
|
|
82544
82852
|
if (waited > QUEUE_WARN_MS) {
|
|
82545
82853
|
console.warn(`[errata] heavy-pass slot: ${label} waited ${Math.round(waited / 1e3)}s`);
|
|
@@ -82551,7 +82859,7 @@ function withHeavyPassSlot(label, fn) {
|
|
|
82551
82859
|
failed = true;
|
|
82552
82860
|
throw err2;
|
|
82553
82861
|
} finally {
|
|
82554
|
-
recent2.push({ label, waitedMs: waited, durationMs: Date.now() - startedAt, failed });
|
|
82862
|
+
recent2.push({ label, waitedMs: waited, durationMs: Date.now() - startedAt, readOps: ioReadOps() - readsAtStart, failed });
|
|
82555
82863
|
if (recent2.length > 16) recent2.shift();
|
|
82556
82864
|
active = null;
|
|
82557
82865
|
}
|
|
@@ -82704,11 +83012,11 @@ init_outbox();
|
|
|
82704
83012
|
init_src10();
|
|
82705
83013
|
init_src();
|
|
82706
83014
|
init_src2();
|
|
82707
|
-
import { readFileSync as
|
|
82708
|
-
import { join as
|
|
83015
|
+
import { readFileSync as readFileSync23 } from "node:fs";
|
|
83016
|
+
import { join as join27 } from "node:path";
|
|
82709
83017
|
function loadClaimIgnorePatterns(workspaceRoot) {
|
|
82710
83018
|
try {
|
|
82711
|
-
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());
|
|
82712
83020
|
} catch {
|
|
82713
83021
|
return [];
|
|
82714
83022
|
}
|
|
@@ -83091,9 +83399,9 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
|
|
|
83091
83399
|
// src/retrieval-stack.ts
|
|
83092
83400
|
init_src();
|
|
83093
83401
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
83094
|
-
import { existsSync as existsSync23, readFileSync as
|
|
83402
|
+
import { existsSync as existsSync23, readFileSync as readFileSync24, statSync as statSync10 } from "node:fs";
|
|
83095
83403
|
import { homedir as homedir6 } from "node:os";
|
|
83096
|
-
import { join as
|
|
83404
|
+
import { join as join28 } from "node:path";
|
|
83097
83405
|
var RETRIEVAL_STACK_CAP = 24;
|
|
83098
83406
|
var MANIFEST_SCAN_CAP = 400;
|
|
83099
83407
|
var RUNTIME_TOKENS = /* @__PURE__ */ new Set([
|
|
@@ -83383,51 +83691,51 @@ function mavenGroupIsSelfDisclosing(name2, selfTokens) {
|
|
|
83383
83691
|
function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
|
|
83384
83692
|
const read2 = (p) => {
|
|
83385
83693
|
try {
|
|
83386
|
-
return
|
|
83694
|
+
return readFileSync24(p, "utf8");
|
|
83387
83695
|
} catch {
|
|
83388
83696
|
return null;
|
|
83389
83697
|
}
|
|
83390
83698
|
};
|
|
83391
83699
|
const texts = (...paths) => paths.map(read2).filter((t) => t !== null);
|
|
83392
83700
|
const home = homedir6();
|
|
83393
|
-
const npm = parseNpmrcPolicy(texts(
|
|
83701
|
+
const npm = parseNpmrcPolicy(texts(join28(root, ".npmrc"), join28(home, ".npmrc")));
|
|
83394
83702
|
const blocked = /* @__PURE__ */ new Set();
|
|
83395
83703
|
if (!npm.defaultPublic) blocked.add("npm");
|
|
83396
83704
|
if (pypiIndexIsPrivate(
|
|
83397
83705
|
texts(
|
|
83398
|
-
|
|
83399
|
-
|
|
83400
|
-
|
|
83401
|
-
|
|
83402
|
-
|
|
83403
|
-
|
|
83404
|
-
|
|
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")
|
|
83405
83713
|
)
|
|
83406
83714
|
)) {
|
|
83407
83715
|
blocked.add("pypi");
|
|
83408
83716
|
}
|
|
83409
83717
|
if (cargoRegistryIsPrivate(
|
|
83410
83718
|
texts(
|
|
83411
|
-
|
|
83412
|
-
|
|
83413
|
-
|
|
83414
|
-
|
|
83719
|
+
join28(root, ".cargo", "config.toml"),
|
|
83720
|
+
join28(root, ".cargo", "config"),
|
|
83721
|
+
join28(home, ".cargo", "config.toml"),
|
|
83722
|
+
join28(home, ".cargo", "config")
|
|
83415
83723
|
)
|
|
83416
83724
|
)) {
|
|
83417
83725
|
blocked.add("cargo");
|
|
83418
83726
|
}
|
|
83419
83727
|
if (nugetSourcesArePrivate(
|
|
83420
83728
|
texts(
|
|
83421
|
-
|
|
83422
|
-
|
|
83423
|
-
|
|
83424
|
-
|
|
83425
|
-
|
|
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")
|
|
83426
83734
|
)
|
|
83427
83735
|
)) {
|
|
83428
83736
|
blocked.add("nuget");
|
|
83429
83737
|
}
|
|
83430
|
-
const goEnvFile = env2["GOENV"] ??
|
|
83738
|
+
const goEnvFile = env2["GOENV"] ?? join28(env2["APPDATA"] ?? join28(home, ".config"), "go", "env");
|
|
83431
83739
|
const goEnvText = read2(goEnvFile) ?? "";
|
|
83432
83740
|
const fromFile = ["GOPRIVATE", "GONOSUMDB", "GONOSUMCHECK"].map(
|
|
83433
83741
|
(k) => new RegExp(`^${k}=(.*)$`, "m").exec(goEnvText)?.[1]
|
|
@@ -83438,10 +83746,10 @@ function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
|
|
|
83438
83746
|
env2["GONOSUMCHECK"],
|
|
83439
83747
|
...fromFile
|
|
83440
83748
|
]);
|
|
83441
|
-
const gemfiles = texts(
|
|
83749
|
+
const gemfiles = texts(join28(root, "Gemfile"));
|
|
83442
83750
|
if (gemSourceIsPrivate(gemfiles)) blocked.add("gem");
|
|
83443
83751
|
if (mavenReposArePrivate(
|
|
83444
|
-
texts(
|
|
83752
|
+
texts(join28(root, "pom.xml"), join28(home, ".m2", "settings.xml"))
|
|
83445
83753
|
)) {
|
|
83446
83754
|
blocked.add("maven");
|
|
83447
83755
|
}
|
|
@@ -83608,10 +83916,10 @@ function readDirectDependencies(root) {
|
|
|
83608
83916
|
const familiesSeen = /* @__PURE__ */ new Set();
|
|
83609
83917
|
for (const c of LOCKFILES) {
|
|
83610
83918
|
if (familiesSeen.has(c.family)) continue;
|
|
83611
|
-
const p =
|
|
83919
|
+
const p = join28(root, c.file);
|
|
83612
83920
|
if (!existsSync23(p)) continue;
|
|
83613
83921
|
try {
|
|
83614
|
-
const s =
|
|
83922
|
+
const s = statSync10(p);
|
|
83615
83923
|
stamps.push(`${c.file}:${s.mtimeMs}:${s.size}`);
|
|
83616
83924
|
} catch {
|
|
83617
83925
|
continue;
|
|
@@ -83629,7 +83937,7 @@ function readDirectDependencies(root) {
|
|
|
83629
83937
|
const direct = [];
|
|
83630
83938
|
for (const { c, path: path3 } of found) {
|
|
83631
83939
|
try {
|
|
83632
|
-
direct.push(...c.parse(
|
|
83940
|
+
direct.push(...c.parse(readFileSync24(path3, "utf8")).direct ?? []);
|
|
83633
83941
|
} catch {
|
|
83634
83942
|
}
|
|
83635
83943
|
}
|
|
@@ -83672,14 +83980,14 @@ function manifestPaths(root) {
|
|
|
83672
83980
|
"project.godot"
|
|
83673
83981
|
];
|
|
83674
83982
|
return {
|
|
83675
|
-
paths: ROOT_MANIFESTS.filter((f) => existsSync23(
|
|
83983
|
+
paths: ROOT_MANIFESTS.filter((f) => existsSync23(join28(root, f))),
|
|
83676
83984
|
tracked: false,
|
|
83677
83985
|
truncated: false
|
|
83678
83986
|
};
|
|
83679
83987
|
}
|
|
83680
83988
|
var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
|
|
83681
83989
|
function rootDeclaresWorkspace(root, texts) {
|
|
83682
|
-
if (WORKSPACE_MARKERS.some((f) => existsSync23(
|
|
83990
|
+
if (WORKSPACE_MARKERS.some((f) => existsSync23(join28(root, f)))) return true;
|
|
83683
83991
|
return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
|
|
83684
83992
|
}
|
|
83685
83993
|
var EMPTY_SCAN = { deps: [], self: [], complete: true };
|
|
@@ -83693,11 +84001,11 @@ function scanManifests(root) {
|
|
|
83693
84001
|
const texts = /* @__PURE__ */ new Map();
|
|
83694
84002
|
const stamps = [];
|
|
83695
84003
|
for (const rel of paths) {
|
|
83696
|
-
const abs =
|
|
84004
|
+
const abs = join28(root, rel);
|
|
83697
84005
|
try {
|
|
83698
|
-
const s =
|
|
84006
|
+
const s = statSync10(abs);
|
|
83699
84007
|
stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
|
|
83700
|
-
texts.set(rel,
|
|
84008
|
+
texts.set(rel, readFileSync24(abs, "utf8"));
|
|
83701
84009
|
} catch {
|
|
83702
84010
|
}
|
|
83703
84011
|
}
|
|
@@ -83733,22 +84041,22 @@ function readRetrievalInputs(root, repoLocator) {
|
|
|
83733
84041
|
}
|
|
83734
84042
|
|
|
83735
84043
|
// src/git-sensor.ts
|
|
83736
|
-
import { existsSync as existsSync24, readFileSync as
|
|
83737
|
-
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";
|
|
83738
84046
|
function readFirstLine(path3) {
|
|
83739
84047
|
try {
|
|
83740
|
-
return
|
|
84048
|
+
return readFileSync25(path3, "utf8").split(/\r?\n/, 1)[0].trim();
|
|
83741
84049
|
} catch {
|
|
83742
84050
|
return null;
|
|
83743
84051
|
}
|
|
83744
84052
|
}
|
|
83745
84053
|
function readGitRefState(gitDir) {
|
|
83746
|
-
const head2 = readFirstLine(
|
|
84054
|
+
const head2 = readFirstLine(join29(gitDir, "HEAD"));
|
|
83747
84055
|
const m = head2 ? /^ref:\s*refs\/heads\/(.+)$/.exec(head2) : null;
|
|
83748
84056
|
const branch = m ? m[1] : null;
|
|
83749
84057
|
let sha2 = null;
|
|
83750
84058
|
if (branch) {
|
|
83751
|
-
sha2 = readFirstLine(
|
|
84059
|
+
sha2 = readFirstLine(join29(gitDir, "refs", "heads", branch));
|
|
83752
84060
|
if (!sha2) sha2 = shaFromPackedRefs(gitDir, `refs/heads/${branch}`);
|
|
83753
84061
|
} else if (head2 && /^[0-9a-f]{7,40}$/i.test(head2)) {
|
|
83754
84062
|
sha2 = head2;
|
|
@@ -83756,13 +84064,13 @@ function readGitRefState(gitDir) {
|
|
|
83756
84064
|
return {
|
|
83757
84065
|
branch,
|
|
83758
84066
|
sha: sha2,
|
|
83759
|
-
mergeHeadExists: existsSync24(
|
|
83760
|
-
origHeadExists: existsSync24(
|
|
84067
|
+
mergeHeadExists: existsSync24(join29(gitDir, "MERGE_HEAD")),
|
|
84068
|
+
origHeadExists: existsSync24(join29(gitDir, "ORIG_HEAD"))
|
|
83761
84069
|
};
|
|
83762
84070
|
}
|
|
83763
84071
|
function shaFromPackedRefs(gitDir, ref) {
|
|
83764
84072
|
try {
|
|
83765
|
-
for (const line of
|
|
84073
|
+
for (const line of readFileSync25(join29(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
|
|
83766
84074
|
const [sha2, name2] = line.split(/\s+/);
|
|
83767
84075
|
if (name2 === ref && sha2) return sha2;
|
|
83768
84076
|
}
|
|
@@ -83796,7 +84104,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
83796
84104
|
const settle = () => {
|
|
83797
84105
|
if (timer) clearTimeout(timer);
|
|
83798
84106
|
timer = setTimeout(() => {
|
|
83799
|
-
if (existsSync24(
|
|
84107
|
+
if (existsSync24(join29(gitDir, "index.lock"))) {
|
|
83800
84108
|
settle();
|
|
83801
84109
|
return;
|
|
83802
84110
|
}
|
|
@@ -83807,7 +84115,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
83807
84115
|
}, debounceMs);
|
|
83808
84116
|
};
|
|
83809
84117
|
for (const sub of ["HEAD", "logs/HEAD", "MERGE_HEAD", "ORIG_HEAD"]) {
|
|
83810
|
-
const p =
|
|
84118
|
+
const p = join29(gitDir, sub);
|
|
83811
84119
|
try {
|
|
83812
84120
|
watchers.push(fsWatch(p, settle));
|
|
83813
84121
|
} catch {
|
|
@@ -84037,8 +84345,8 @@ var TelemetryRecorder = class {
|
|
|
84037
84345
|
};
|
|
84038
84346
|
|
|
84039
84347
|
// src/file-activity.ts
|
|
84040
|
-
import { readFileSync as
|
|
84041
|
-
import { join as
|
|
84348
|
+
import { readFileSync as readFileSync27 } from "node:fs";
|
|
84349
|
+
import { join as join31 } from "node:path";
|
|
84042
84350
|
import { createHash as createHash17 } from "node:crypto";
|
|
84043
84351
|
|
|
84044
84352
|
// ../../packages/privacy/src/patterns/credentials.ts
|
|
@@ -84790,8 +85098,8 @@ init_git_remote();
|
|
|
84790
85098
|
// src/history-bundle.ts
|
|
84791
85099
|
init_src();
|
|
84792
85100
|
import { execFile as execFile2 } from "node:child_process";
|
|
84793
|
-
import { readFileSync as
|
|
84794
|
-
import { join as
|
|
85101
|
+
import { readFileSync as readFileSync26 } from "node:fs";
|
|
85102
|
+
import { join as join30 } from "node:path";
|
|
84795
85103
|
var DEFAULT_MAX_TOKENS = 6e3;
|
|
84796
85104
|
var FILE_LIST_CAP = 60;
|
|
84797
85105
|
var DIFF_FILE_CAP = 40;
|
|
@@ -84830,7 +85138,7 @@ function pathAllowedByFloor(path3) {
|
|
|
84830
85138
|
function loadRepoIgnore(root, extraPatterns = []) {
|
|
84831
85139
|
let source = "";
|
|
84832
85140
|
try {
|
|
84833
|
-
source =
|
|
85141
|
+
source = readFileSync26(join30(root, ".errataignore"), "utf8");
|
|
84834
85142
|
} catch {
|
|
84835
85143
|
source = "";
|
|
84836
85144
|
}
|
|
@@ -85005,24 +85313,28 @@ function headerPaths(diff) {
|
|
|
85005
85313
|
}
|
|
85006
85314
|
return out2.filter((p) => p !== "/dev/null");
|
|
85007
85315
|
}
|
|
85008
|
-
|
|
85316
|
+
var GIT_MAX_BUFFER = 64 * 1024 * 1024;
|
|
85317
|
+
function git2(repoDir, args2, maxBuffer = GIT_MAX_BUFFER) {
|
|
85009
85318
|
return new Promise((resolve10, reject) => {
|
|
85010
85319
|
execFile2(
|
|
85011
85320
|
"git",
|
|
85012
85321
|
["-C", repoDir, ...args2],
|
|
85013
|
-
{ encoding: "utf8", maxBuffer
|
|
85322
|
+
{ encoding: "utf8", maxBuffer, windowsHide: true },
|
|
85014
85323
|
(err2, stdout) => err2 ? reject(err2) : resolve10(stdout)
|
|
85015
85324
|
);
|
|
85016
85325
|
});
|
|
85017
85326
|
}
|
|
85018
|
-
async function unitDiff(root, unit, paths) {
|
|
85327
|
+
async function unitDiff(root, unit, paths, maxChars = GIT_MAX_BUFFER) {
|
|
85019
85328
|
if (paths.length === 0) return "";
|
|
85020
85329
|
const common = ["--unified=3", "--no-color", "-M", "--no-ext-diff"];
|
|
85021
85330
|
const firstParent = unit.parents[0];
|
|
85022
|
-
|
|
85023
|
-
|
|
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;
|
|
85024
85337
|
}
|
|
85025
|
-
return git2(root, ["show", "--format=", ...common, unit.sha, "--", ...paths]);
|
|
85026
85338
|
}
|
|
85027
85339
|
function fileRow(token, f) {
|
|
85028
85340
|
const tag = f.binary ? "bin" : `+${f.adds}/-${f.dels}`;
|
|
@@ -85059,7 +85371,9 @@ async function buildUnitBundle(root, unit, opts = {}) {
|
|
|
85059
85371
|
const sourceFiles = ordered.filter(isSourceFile);
|
|
85060
85372
|
const diffPaths = sourceFiles.slice(0, DIFF_FILE_CAP).map((f) => f.path);
|
|
85061
85373
|
if (sourceFiles.length > DIFF_FILE_CAP) truncated = true;
|
|
85062
|
-
const
|
|
85374
|
+
const cappedDiff = await unitDiff(root, unit, diffPaths, opts.maxRawDiffChars);
|
|
85375
|
+
if (cappedDiff === null) truncated = true;
|
|
85376
|
+
const rawDiff = cappedDiff ?? "";
|
|
85063
85377
|
for (const p of headerPaths(rawDiff)) tokens.token(p);
|
|
85064
85378
|
const narrativeRaw = opts.narrative ?? [unit.subject.trim(), stripTrailers(unit.body)].filter((s) => s.length > 0).join("\n\n");
|
|
85065
85379
|
const n = scrubHistoryText(tokens.apply(stripTrailers(narrativeRaw)));
|
|
@@ -85129,7 +85443,7 @@ function readActivityBranch(root) {
|
|
|
85129
85443
|
try {
|
|
85130
85444
|
const gitDir = resolveGitDir(root);
|
|
85131
85445
|
if (!gitDir) return null;
|
|
85132
|
-
const head2 =
|
|
85446
|
+
const head2 = readFileSync27(join31(gitDir, "HEAD"), "utf8").trim();
|
|
85133
85447
|
const branch = head2.startsWith("ref: refs/heads/") ? head2.slice(16) : /^[a-f0-9]{40,64}$/i.test(head2) ? "HEAD" : null;
|
|
85134
85448
|
return branch && branch.length <= 256 && !/[\x00-\x1f\x7f]/.test(branch) ? branch : null;
|
|
85135
85449
|
} catch {
|
|
@@ -85288,19 +85602,19 @@ var FileActivityReporter = class {
|
|
|
85288
85602
|
import {
|
|
85289
85603
|
existsSync as existsSync25,
|
|
85290
85604
|
mkdirSync as mkdirSync7,
|
|
85291
|
-
readFileSync as
|
|
85605
|
+
readFileSync as readFileSync28,
|
|
85292
85606
|
readdirSync as readdirSync9,
|
|
85293
85607
|
unlinkSync as unlinkSync4,
|
|
85294
|
-
writeFileSync as
|
|
85608
|
+
writeFileSync as writeFileSync19
|
|
85295
85609
|
} from "node:fs";
|
|
85296
|
-
import { basename as basename7, join as
|
|
85610
|
+
import { basename as basename7, join as join32 } from "node:path";
|
|
85297
85611
|
function skillFileName(id) {
|
|
85298
85612
|
return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
|
|
85299
85613
|
}
|
|
85300
85614
|
function readSkillManifest(manifestPath) {
|
|
85301
85615
|
if (!existsSync25(manifestPath)) return [];
|
|
85302
85616
|
try {
|
|
85303
|
-
const parsed = JSON.parse(
|
|
85617
|
+
const parsed = JSON.parse(readFileSync28(manifestPath, "utf8"));
|
|
85304
85618
|
return (parsed.skills ?? []).map((s) => ({
|
|
85305
85619
|
title: s.title ?? "",
|
|
85306
85620
|
layer: s.layer ?? "technique",
|
|
@@ -85324,7 +85638,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
85324
85638
|
for (const s of res.skills) {
|
|
85325
85639
|
const fileName = skillFileName(s.id);
|
|
85326
85640
|
keep.add(fileName);
|
|
85327
|
-
|
|
85641
|
+
writeFileSync19(join32(paths.skillsDir, fileName), s.markdown, "utf8");
|
|
85328
85642
|
rows.push({
|
|
85329
85643
|
id: s.id,
|
|
85330
85644
|
title: s.title,
|
|
@@ -85337,7 +85651,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
85337
85651
|
const fileName = skillFileName(p.id);
|
|
85338
85652
|
if (keep.has(fileName)) continue;
|
|
85339
85653
|
keep.add(fileName);
|
|
85340
|
-
|
|
85654
|
+
writeFileSync19(join32(paths.skillsDir, fileName), p.markdown, "utf8");
|
|
85341
85655
|
rows.push({
|
|
85342
85656
|
id: p.id,
|
|
85343
85657
|
title: p.title,
|
|
@@ -85351,13 +85665,13 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
85351
85665
|
if (!f.endsWith(".md")) continue;
|
|
85352
85666
|
if (keep.has(basename7(f))) continue;
|
|
85353
85667
|
try {
|
|
85354
|
-
unlinkSync4(
|
|
85668
|
+
unlinkSync4(join32(paths.skillsDir, f));
|
|
85355
85669
|
pruned++;
|
|
85356
85670
|
} catch {
|
|
85357
85671
|
}
|
|
85358
85672
|
}
|
|
85359
85673
|
rows.sort((a, b) => a.id.localeCompare(b.id));
|
|
85360
|
-
|
|
85674
|
+
writeFileSync19(
|
|
85361
85675
|
paths.skillsManifest,
|
|
85362
85676
|
JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
|
|
85363
85677
|
"utf8"
|
|
@@ -85372,19 +85686,19 @@ import {
|
|
|
85372
85686
|
existsSync as existsSync26,
|
|
85373
85687
|
lstatSync,
|
|
85374
85688
|
mkdirSync as mkdirSync8,
|
|
85375
|
-
readFileSync as
|
|
85689
|
+
readFileSync as readFileSync29,
|
|
85376
85690
|
readdirSync as readdirSync10,
|
|
85377
85691
|
rmSync as rmSync3,
|
|
85378
85692
|
symlinkSync,
|
|
85379
|
-
writeFileSync as
|
|
85693
|
+
writeFileSync as writeFileSync20
|
|
85380
85694
|
} from "node:fs";
|
|
85381
|
-
import { join as
|
|
85695
|
+
import { join as join33 } from "node:path";
|
|
85382
85696
|
var SKILL_NS = "errata-";
|
|
85383
85697
|
var HARNESS_SKILL_DIRS = [
|
|
85384
|
-
{ configDir: ".claude", skillsDir:
|
|
85698
|
+
{ configDir: ".claude", skillsDir: join33(".claude", "skills") },
|
|
85385
85699
|
// Cursor adopted the standard; its exact project dir is still moving — kept
|
|
85386
85700
|
// best-effort and gated on `.cursor/` presence so we never create it blind.
|
|
85387
|
-
{ configDir: ".cursor", skillsDir:
|
|
85701
|
+
{ configDir: ".cursor", skillsDir: join33(".cursor", "skills") }
|
|
85388
85702
|
];
|
|
85389
85703
|
function skillSlug(title, id) {
|
|
85390
85704
|
const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
|
|
@@ -85434,7 +85748,7 @@ function reconcileNamespaced(dir, keep) {
|
|
|
85434
85748
|
for (const name2 of readdirSync10(dir)) {
|
|
85435
85749
|
if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
|
|
85436
85750
|
try {
|
|
85437
|
-
rmSync3(
|
|
85751
|
+
rmSync3(join33(dir, name2), { recursive: true, force: true });
|
|
85438
85752
|
pruned++;
|
|
85439
85753
|
} catch {
|
|
85440
85754
|
}
|
|
@@ -85464,7 +85778,7 @@ function safeLstat(p) {
|
|
|
85464
85778
|
}
|
|
85465
85779
|
}
|
|
85466
85780
|
function emitAndProjectSkills(root, skills) {
|
|
85467
|
-
const agentsSkillsDir =
|
|
85781
|
+
const agentsSkillsDir = join33(root, ".agents", "skills");
|
|
85468
85782
|
mkdirSync8(agentsSkillsDir, { recursive: true });
|
|
85469
85783
|
const slugs = [];
|
|
85470
85784
|
const keep = /* @__PURE__ */ new Set();
|
|
@@ -85472,7 +85786,7 @@ function emitAndProjectSkills(root, skills) {
|
|
|
85472
85786
|
for (const s of skills) {
|
|
85473
85787
|
let body2;
|
|
85474
85788
|
try {
|
|
85475
|
-
body2 =
|
|
85789
|
+
body2 = readFileSync29(s.bodyPath, "utf8");
|
|
85476
85790
|
} catch {
|
|
85477
85791
|
continue;
|
|
85478
85792
|
}
|
|
@@ -85481,9 +85795,9 @@ function emitAndProjectSkills(root, skills) {
|
|
|
85481
85795
|
keep.add(slug2);
|
|
85482
85796
|
slugs.push(slug2);
|
|
85483
85797
|
const description = deriveDescription(s.title, s.layer, body2);
|
|
85484
|
-
mkdirSync8(
|
|
85485
|
-
|
|
85486
|
-
|
|
85798
|
+
mkdirSync8(join33(agentsSkillsDir, slug2), { recursive: true });
|
|
85799
|
+
writeFileSync20(
|
|
85800
|
+
join33(agentsSkillsDir, slug2, "SKILL.md"),
|
|
85487
85801
|
renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
|
|
85488
85802
|
"utf8"
|
|
85489
85803
|
);
|
|
@@ -85492,11 +85806,11 @@ function emitAndProjectSkills(root, skills) {
|
|
|
85492
85806
|
reconcileNamespaced(agentsSkillsDir, keep);
|
|
85493
85807
|
let projected = 0;
|
|
85494
85808
|
for (const h of HARNESS_SKILL_DIRS) {
|
|
85495
|
-
if (!existsSync26(
|
|
85496
|
-
const dir =
|
|
85809
|
+
if (!existsSync26(join33(root, h.configDir))) continue;
|
|
85810
|
+
const dir = join33(root, h.skillsDir);
|
|
85497
85811
|
mkdirSync8(dir, { recursive: true });
|
|
85498
85812
|
for (const slug2 of slugs) {
|
|
85499
|
-
linkOrCopy(
|
|
85813
|
+
linkOrCopy(join33(dir, slug2), join33(agentsSkillsDir, slug2));
|
|
85500
85814
|
projected++;
|
|
85501
85815
|
}
|
|
85502
85816
|
reconcileNamespaced(dir, keep);
|
|
@@ -85507,13 +85821,13 @@ function emitAndProjectSkills(root, skills) {
|
|
|
85507
85821
|
function emitInputsFromManifest(erretaDir, manifestPath) {
|
|
85508
85822
|
if (!existsSync26(manifestPath)) return [];
|
|
85509
85823
|
try {
|
|
85510
|
-
const parsed = JSON.parse(
|
|
85824
|
+
const parsed = JSON.parse(readFileSync29(manifestPath, "utf8"));
|
|
85511
85825
|
return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
|
|
85512
85826
|
id: s.id,
|
|
85513
85827
|
title: s.title ?? s.id,
|
|
85514
85828
|
layer: s.layer ?? "technique",
|
|
85515
85829
|
confidence: s.confidence ?? 0,
|
|
85516
|
-
bodyPath:
|
|
85830
|
+
bodyPath: join33(erretaDir, s.file)
|
|
85517
85831
|
}));
|
|
85518
85832
|
} catch {
|
|
85519
85833
|
return [];
|
|
@@ -85527,17 +85841,17 @@ var GITIGNORE_LINES = [
|
|
|
85527
85841
|
".cursor/skills/errata-*/"
|
|
85528
85842
|
];
|
|
85529
85843
|
function ensureSkillGitignore(root) {
|
|
85530
|
-
const path3 =
|
|
85844
|
+
const path3 = join33(root, ".gitignore");
|
|
85531
85845
|
let current = "";
|
|
85532
85846
|
try {
|
|
85533
|
-
current = existsSync26(path3) ?
|
|
85847
|
+
current = existsSync26(path3) ? readFileSync29(path3, "utf8") : "";
|
|
85534
85848
|
} catch {
|
|
85535
85849
|
return;
|
|
85536
85850
|
}
|
|
85537
85851
|
if (current.includes(GITIGNORE_MARK)) return;
|
|
85538
85852
|
const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
|
|
85539
85853
|
try {
|
|
85540
|
-
|
|
85854
|
+
writeFileSync20(path3, `${current}${prefix}
|
|
85541
85855
|
${GITIGNORE_LINES.join("\n")}
|
|
85542
85856
|
`, "utf8");
|
|
85543
85857
|
} catch {
|
|
@@ -85633,18 +85947,18 @@ init_paths();
|
|
|
85633
85947
|
init_profile2();
|
|
85634
85948
|
|
|
85635
85949
|
// src/witness-queue.ts
|
|
85636
|
-
import { readFileSync as
|
|
85637
|
-
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";
|
|
85638
85952
|
var WITNESS_QUEUE_CAP = 500;
|
|
85639
85953
|
var WITNESS_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
85640
85954
|
var WITNESS_MAX_ATTEMPTS = 5;
|
|
85641
85955
|
function witnessQueuePath(workspaceConfigDir) {
|
|
85642
|
-
return
|
|
85956
|
+
return join34(workspaceConfigDir, "witness-queue.json");
|
|
85643
85957
|
}
|
|
85644
85958
|
function loadWitnessQueueWithLosses(path3) {
|
|
85645
85959
|
let raw2;
|
|
85646
85960
|
try {
|
|
85647
|
-
raw2 = JSON.parse(
|
|
85961
|
+
raw2 = JSON.parse(readFileSync30(path3, "utf8"));
|
|
85648
85962
|
} catch (err2) {
|
|
85649
85963
|
const absent = err2?.code === "ENOENT";
|
|
85650
85964
|
return { queue: [], fileUnreadable: !absent, malformedEntries: 0 };
|
|
@@ -85657,9 +85971,9 @@ function loadWitnessQueueWithLosses(path3) {
|
|
|
85657
85971
|
}
|
|
85658
85972
|
function saveWitnessQueue(path3, queue) {
|
|
85659
85973
|
try {
|
|
85660
|
-
const tmp =
|
|
85661
|
-
|
|
85662
|
-
|
|
85974
|
+
const tmp = join34(dirname13(path3), `.${Date.now()}.witness-queue.tmp`);
|
|
85975
|
+
writeFileSync21(tmp, JSON.stringify(queue), "utf8");
|
|
85976
|
+
renameSync4(tmp, path3);
|
|
85663
85977
|
} catch {
|
|
85664
85978
|
}
|
|
85665
85979
|
}
|
|
@@ -85967,8 +86281,8 @@ function maybeFlushDigests() {
|
|
|
85967
86281
|
|
|
85968
86282
|
// src/liveness-watch.ts
|
|
85969
86283
|
init_src5();
|
|
85970
|
-
import { readFileSync as
|
|
85971
|
-
import { join as
|
|
86284
|
+
import { readFileSync as readFileSync32, writeFileSync as writeFileSync23 } from "node:fs";
|
|
86285
|
+
import { join as join36 } from "node:path";
|
|
85972
86286
|
|
|
85973
86287
|
// src/loop-lag.ts
|
|
85974
86288
|
var HEARTBEAT_MS = 500;
|
|
@@ -85980,13 +86294,14 @@ var recent3 = [];
|
|
|
85980
86294
|
function markPass(name2) {
|
|
85981
86295
|
const id = nextPassId++;
|
|
85982
86296
|
const startedAt = Date.now();
|
|
86297
|
+
const readsAtStart = ioReadOps();
|
|
85983
86298
|
active2.set(id, { name: name2, startedAt });
|
|
85984
86299
|
let ended = false;
|
|
85985
86300
|
return () => {
|
|
85986
86301
|
if (ended) return;
|
|
85987
86302
|
ended = true;
|
|
85988
86303
|
active2.delete(id);
|
|
85989
|
-
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 });
|
|
85990
86305
|
if (recent3.length > RECENT_PASS_LIMIT) recent3.pop();
|
|
85991
86306
|
};
|
|
85992
86307
|
}
|
|
@@ -86099,11 +86414,11 @@ function watchCensusLine(c = watchCensus(), now = Date.now()) {
|
|
|
86099
86414
|
var LIVENESS_WATCH_INTERVAL_MS = 60 * 60 * 1e3;
|
|
86100
86415
|
var ALARM_RENOTIFY_MS = 24 * 60 * 60 * 1e3;
|
|
86101
86416
|
function alarmStatePath(configDir) {
|
|
86102
|
-
return
|
|
86417
|
+
return join36(configDir, "liveness-alarms.json");
|
|
86103
86418
|
}
|
|
86104
86419
|
function loadAlarmState(path3) {
|
|
86105
86420
|
try {
|
|
86106
|
-
const raw2 = JSON.parse(
|
|
86421
|
+
const raw2 = JSON.parse(readFileSync32(path3, "utf8"));
|
|
86107
86422
|
return new Map(Object.entries(raw2).filter((e) => typeof e[1] === "number"));
|
|
86108
86423
|
} catch {
|
|
86109
86424
|
return /* @__PURE__ */ new Map();
|
|
@@ -86111,7 +86426,7 @@ function loadAlarmState(path3) {
|
|
|
86111
86426
|
}
|
|
86112
86427
|
function saveAlarmState(path3, state) {
|
|
86113
86428
|
try {
|
|
86114
|
-
|
|
86429
|
+
writeFileSync23(path3, JSON.stringify(Object.fromEntries(state)));
|
|
86115
86430
|
} catch {
|
|
86116
86431
|
}
|
|
86117
86432
|
}
|
|
@@ -86141,12 +86456,15 @@ function toastLivenessAlarms(gate, workspace, alarms, deliver, nowMs) {
|
|
|
86141
86456
|
return fresh;
|
|
86142
86457
|
}
|
|
86143
86458
|
function createLivenessWatch(deps) {
|
|
86144
|
-
let lastRunAt =
|
|
86459
|
+
let lastRunAt = null;
|
|
86145
86460
|
let running = false;
|
|
86146
86461
|
const lastAlarmedAt = loadAlarmState(alarmStatePath(deps.configDir));
|
|
86147
86462
|
return {
|
|
86148
86463
|
async maybeRun(nowMs = Date.now()) {
|
|
86149
|
-
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;
|
|
86150
86468
|
lastRunAt = nowMs;
|
|
86151
86469
|
running = true;
|
|
86152
86470
|
try {
|
|
@@ -86238,6 +86556,25 @@ function runWorkspaceMaintenance(store, workspaceId2) {
|
|
|
86238
86556
|
};
|
|
86239
86557
|
}
|
|
86240
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
|
+
|
|
86241
86578
|
// src/watch-breaker.ts
|
|
86242
86579
|
function numEnv3(key, fallback) {
|
|
86243
86580
|
const n = Number(process.env[key]);
|
|
@@ -86339,7 +86676,7 @@ function createWatchBreaker(deps) {
|
|
|
86339
86676
|
}
|
|
86340
86677
|
|
|
86341
86678
|
// src/engine.ts
|
|
86342
|
-
var DAEMON_VERSION = true ? "2.0.22-dev.
|
|
86679
|
+
var DAEMON_VERSION = true ? "2.0.22-dev.4534" : "2.0.0-alpha.0";
|
|
86343
86680
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
86344
86681
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
86345
86682
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -86351,8 +86688,8 @@ var CODEX_SWEEP_LOOKBACK_MS = 10 * 6e4;
|
|
|
86351
86688
|
function appendIdentityAudit(path3, record2, line) {
|
|
86352
86689
|
if (!record2.accepted && record2.score <= 0) return;
|
|
86353
86690
|
try {
|
|
86354
|
-
if (existsSync28(path3) &&
|
|
86355
|
-
|
|
86691
|
+
if (existsSync28(path3) && statSync11(path3).size >= IDENTITY_AUDIT_MAX_BYTES) {
|
|
86692
|
+
renameSync5(path3, `${path3}.1`);
|
|
86356
86693
|
}
|
|
86357
86694
|
appendFileSync4(path3, line);
|
|
86358
86695
|
} catch {
|
|
@@ -86361,7 +86698,7 @@ function appendIdentityAudit(path3, record2, line) {
|
|
|
86361
86698
|
var yieldToLoop = () => new Promise((r) => setImmediate(r));
|
|
86362
86699
|
function loadTurnCursors(path3) {
|
|
86363
86700
|
try {
|
|
86364
|
-
const raw2 = JSON.parse(
|
|
86701
|
+
const raw2 = JSON.parse(readFileSync33(path3, "utf8"));
|
|
86365
86702
|
return new Map(
|
|
86366
86703
|
Object.entries(raw2).map(([k, v]) => [k, typeof v === "string" ? v : String(v?.uuid ?? "")])
|
|
86367
86704
|
);
|
|
@@ -86371,7 +86708,7 @@ function loadTurnCursors(path3) {
|
|
|
86371
86708
|
}
|
|
86372
86709
|
function loadTurnOffsets(path3) {
|
|
86373
86710
|
try {
|
|
86374
|
-
const raw2 = JSON.parse(
|
|
86711
|
+
const raw2 = JSON.parse(readFileSync33(path3, "utf8"));
|
|
86375
86712
|
const out2 = /* @__PURE__ */ new Map();
|
|
86376
86713
|
for (const [k, v] of Object.entries(raw2)) {
|
|
86377
86714
|
const off2 = typeof v === "object" && v !== null ? v.offset : void 0;
|
|
@@ -86387,7 +86724,7 @@ function saveTurnCursors(path3, cursors, offsets) {
|
|
|
86387
86724
|
const merged = {};
|
|
86388
86725
|
for (const [k, uuid3] of cursors) merged[k] = { uuid: uuid3, offset: offsets.get(k) ?? 0 };
|
|
86389
86726
|
for (const [k, offset] of offsets) if (!merged[k]) merged[k] = { uuid: "", offset };
|
|
86390
|
-
|
|
86727
|
+
writeFileSync24(path3, JSON.stringify(merged), "utf8");
|
|
86391
86728
|
} catch {
|
|
86392
86729
|
}
|
|
86393
86730
|
}
|
|
@@ -86409,7 +86746,7 @@ function gitSourceWatchTargets(root) {
|
|
|
86409
86746
|
["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
|
|
86410
86747
|
{ encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
|
|
86411
86748
|
);
|
|
86412
|
-
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));
|
|
86413
86750
|
} catch {
|
|
86414
86751
|
}
|
|
86415
86752
|
const hasIgnoredChild = (dir) => ignoredDirs.some((ig) => ig.startsWith(dir + "/"));
|
|
@@ -86421,19 +86758,19 @@ function gitSourceWatchTargets(root) {
|
|
|
86421
86758
|
if (!f.startsWith(prefix)) continue;
|
|
86422
86759
|
const rest2 = f.slice(prefix.length);
|
|
86423
86760
|
if (rest2.includes("/")) children.add(dir === "" ? rest2.slice(0, rest2.indexOf("/")) : dir + "/" + rest2.slice(0, rest2.indexOf("/")));
|
|
86424
|
-
else targets.add(
|
|
86761
|
+
else targets.add(join37(root, f));
|
|
86425
86762
|
}
|
|
86426
86763
|
for (const c of children) {
|
|
86427
|
-
if (IGNORED_PATH.test(
|
|
86764
|
+
if (IGNORED_PATH.test(join37(root, c) + sep5)) continue;
|
|
86428
86765
|
if (hasIgnoredChild(c)) addUnder(c);
|
|
86429
|
-
else targets.add(
|
|
86766
|
+
else targets.add(join37(root, c));
|
|
86430
86767
|
}
|
|
86431
86768
|
};
|
|
86432
86769
|
addUnder("");
|
|
86433
86770
|
if (targets.size > 0) return [...targets];
|
|
86434
86771
|
} catch {
|
|
86435
86772
|
}
|
|
86436
|
-
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)));
|
|
86437
86774
|
}
|
|
86438
86775
|
function createWorkspaceEngine(opts) {
|
|
86439
86776
|
const paths = workspacePaths(opts.workspaceRoot);
|
|
@@ -86489,6 +86826,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86489
86826
|
let watcher = null;
|
|
86490
86827
|
let watchBreaker = null;
|
|
86491
86828
|
let lastActivityTs = Date.now();
|
|
86829
|
+
let storeReconciled = !!opts.skipWatchers;
|
|
86492
86830
|
let stopGit = null;
|
|
86493
86831
|
let fsReindex;
|
|
86494
86832
|
let stopping = false;
|
|
@@ -86525,7 +86863,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86525
86863
|
}
|
|
86526
86864
|
let size = 0;
|
|
86527
86865
|
try {
|
|
86528
|
-
size =
|
|
86866
|
+
size = statSync11(path3).size;
|
|
86529
86867
|
} catch {
|
|
86530
86868
|
}
|
|
86531
86869
|
lastActivityTs = Date.now();
|
|
@@ -86572,7 +86910,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86572
86910
|
fsReindex = createCoalescedFilePass(REINDEX_DEBOUNCE_MS, async (changed) => {
|
|
86573
86911
|
if (stopping) return;
|
|
86574
86912
|
const t = Date.now();
|
|
86575
|
-
const relChanged = changed.map((p) =>
|
|
86913
|
+
const relChanged = changed.map((p) => relative6(opts.workspaceRoot, p).split(sep5).join("/"));
|
|
86576
86914
|
const causal = causalBuffer.correlate(relChanged, t) ?? void 0;
|
|
86577
86915
|
await runReindexPass(
|
|
86578
86916
|
`fs-reindex:${profile.name} (${changed.length} files)`,
|
|
@@ -86632,7 +86970,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86632
86970
|
const srcPaths = diff.changedPaths.filter((p) => /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p));
|
|
86633
86971
|
let episodeId2;
|
|
86634
86972
|
if (srcPaths.length > 0) {
|
|
86635
|
-
const abs = srcPaths.map((p) =>
|
|
86973
|
+
const abs = srcPaths.map((p) => join37(opts.workspaceRoot, p));
|
|
86636
86974
|
try {
|
|
86637
86975
|
const r = await runReindexPass(
|
|
86638
86976
|
`git-reindex:${profile.name} (${abs.length} files)`,
|
|
@@ -86668,7 +87006,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86668
87006
|
`[errata] git: ${ev.kind} ${ev.newSha.slice(0, 7)} by ${meta3.authorName} \u2014 ${diff.changedPaths.length} file(s), ${diff.renames.length} rename(s)`
|
|
86669
87007
|
);
|
|
86670
87008
|
};
|
|
86671
|
-
const gitDir =
|
|
87009
|
+
const gitDir = join37(opts.workspaceRoot, ".git");
|
|
86672
87010
|
if (existsSync28(gitDir)) {
|
|
86673
87011
|
stopGit = startGitSensor(gitDir, (ev) => {
|
|
86674
87012
|
void handleGitEvent(ev).catch((err2) => {
|
|
@@ -86678,6 +87016,10 @@ function createWorkspaceEngine(opts) {
|
|
|
86678
87016
|
}
|
|
86679
87017
|
setImmediate(() => {
|
|
86680
87018
|
const reconcileStartedAt = Date.now();
|
|
87019
|
+
try {
|
|
87020
|
+
store.pruneChangeLog?.();
|
|
87021
|
+
} catch {
|
|
87022
|
+
}
|
|
86681
87023
|
const reconcile = passWorker ? passWorker.reconcile().catch(() => reconcileStaleFiles(store, opts.workspaceRoot, profile.id)) : reconcileStaleFiles(store, opts.workspaceRoot, profile.id);
|
|
86682
87024
|
void reconcile.then((n) => {
|
|
86683
87025
|
appendPassLedger(paths.configDir, "reconcile", Date.now() - reconcileStartedAt, {
|
|
@@ -86712,6 +87054,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86712
87054
|
} catch (err2) {
|
|
86713
87055
|
console.warn("[errata] orphan reap failed:", err2 instanceof Error ? err2.message : err2);
|
|
86714
87056
|
}
|
|
87057
|
+
storeReconciled = true;
|
|
86715
87058
|
});
|
|
86716
87059
|
});
|
|
86717
87060
|
}
|
|
@@ -86725,7 +87068,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86725
87068
|
},
|
|
86726
87069
|
onAlarms: (alarms) => {
|
|
86727
87070
|
toastLivenessAlarms(
|
|
86728
|
-
sharedAlarmToastGate(
|
|
87071
|
+
sharedAlarmToastGate(join37(globalDir(), "liveness-toasts.json")),
|
|
86729
87072
|
{ root: opts.workspaceRoot, name: profile.name },
|
|
86730
87073
|
alarms,
|
|
86731
87074
|
(body2, key) => notifyEvent("mechanism-stalled", body2, { key }),
|
|
@@ -86742,7 +87085,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86742
87085
|
let subagentBase = null;
|
|
86743
87086
|
let subagentBaseVersion = 0;
|
|
86744
87087
|
const subagentRenders = /* @__PURE__ */ new Map();
|
|
86745
|
-
const sessions = createSessionRegistry({ originsPath:
|
|
87088
|
+
const sessions = createSessionRegistry({ originsPath: join37(paths.configDir, "session-origins.json") });
|
|
86746
87089
|
const sessionRenders = /* @__PURE__ */ new Map();
|
|
86747
87090
|
const selfCiteSkipsBySession = /* @__PURE__ */ new Map();
|
|
86748
87091
|
const toolRuns = createToolRunState();
|
|
@@ -86756,6 +87099,7 @@ function createWorkspaceEngine(opts) {
|
|
|
86756
87099
|
let intentRemoteInFlight = false;
|
|
86757
87100
|
let ctxRefreshInFlight = false;
|
|
86758
87101
|
let ctxRefreshQueued = false;
|
|
87102
|
+
let lastWorkerSnapshot = null;
|
|
86759
87103
|
let lastSelfCiteSkips = 0;
|
|
86760
87104
|
const refreshContextNow = () => {
|
|
86761
87105
|
void refreshContextAsync().catch((err2) => {
|
|
@@ -86834,26 +87178,35 @@ function createWorkspaceEngine(opts) {
|
|
|
86834
87178
|
const elicit = isEdgeElicitationEnabled();
|
|
86835
87179
|
const snapOpts = {
|
|
86836
87180
|
profile,
|
|
86837
|
-
atCommit: readGitRefState(
|
|
87181
|
+
atCommit: readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0,
|
|
86838
87182
|
reviewCount: pendingCount(paths),
|
|
86839
87183
|
reviewUiUrl: opts.reviewUrl(),
|
|
86840
87184
|
workingFile: workingFiles.mostRecent() ?? void 0,
|
|
86841
87185
|
skills: readSkillManifest(paths.skillsManifest),
|
|
86842
87186
|
...lastSelfCiteSkips > 0 ? { selfCiteSkips: lastSelfCiteSkips } : {}
|
|
86843
87187
|
};
|
|
86844
|
-
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) => {
|
|
86845
87198
|
console.warn(
|
|
86846
87199
|
`[errata] snapshot worker failed \u2014 rendering INLINE on main:`,
|
|
86847
87200
|
err2 instanceof Error ? err2.message : err2
|
|
86848
87201
|
);
|
|
86849
87202
|
return null;
|
|
86850
87203
|
}) : null;
|
|
86851
|
-
if (snapOpts.atCommit !== (readGitRefState(
|
|
87204
|
+
if (snapOpts.atCommit !== (readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0)) {
|
|
86852
87205
|
contextDirty = true;
|
|
86853
87206
|
return;
|
|
86854
87207
|
}
|
|
86855
87208
|
const doneRender = markPass(`${prebuilt ? "context-render" : "context-render-inline"}:${profile.name}`);
|
|
86856
|
-
const base = prebuilt ?? buildSnapshot({ store, ...snapOpts });
|
|
87209
|
+
const base = freshenRecentBands(prebuilt ?? buildSnapshot({ store, ...snapOpts }), (id2) => store.getNode(id2));
|
|
86857
87210
|
subagentBase = structuredClone(base);
|
|
86858
87211
|
subagentBaseVersion++;
|
|
86859
87212
|
const sharedSnapshot = scopeSnapshot(base, (n) => !isQuarantined(n, sessions));
|
|
@@ -86894,10 +87247,10 @@ function createWorkspaceEngine(opts) {
|
|
|
86894
87247
|
} catch (err2) {
|
|
86895
87248
|
console.warn("[errata] context card failed:", err2.message?.slice(0, 120));
|
|
86896
87249
|
}
|
|
86897
|
-
const target =
|
|
87250
|
+
const target = join37(opts.workspaceRoot, "AGENTS.md");
|
|
86898
87251
|
writeManagedBlock(target, { body: AGENTS_POINTER_BODY, stable: true, force: true });
|
|
86899
87252
|
if (elicit) {
|
|
86900
|
-
writePrimingHandles(
|
|
87253
|
+
writePrimingHandles(join37(paths.configDir, "priming-handles.json"), [
|
|
86901
87254
|
...snapshot.recentProblems.map((r) => r.node),
|
|
86902
87255
|
// Resolved-band handles: the ✓ problem AND its Solution are citable
|
|
86903
87256
|
// (a fix tag on an already-resolved problem no-ops idempotently; the
|
|
@@ -87205,8 +87558,8 @@ function createWorkspaceEngine(opts) {
|
|
|
87205
87558
|
const cached2 = subagentRenders.get(a.agentId);
|
|
87206
87559
|
if (cached2?.key === key) return cached2.block;
|
|
87207
87560
|
const elicit = isEdgeElicitationEnabled();
|
|
87208
|
-
const handlesPath =
|
|
87209
|
-
const atCommit = readGitRefState(
|
|
87561
|
+
const handlesPath = join37(paths.configDir, "priming-handles.json");
|
|
87562
|
+
const atCommit = readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
87210
87563
|
const block = renderSubagentBlock({
|
|
87211
87564
|
store,
|
|
87212
87565
|
entry,
|
|
@@ -87260,7 +87613,7 @@ function createWorkspaceEngine(opts) {
|
|
|
87260
87613
|
const cached2 = sessionRenders.get(sessionId);
|
|
87261
87614
|
if (cached2?.key === key) return cached2.block;
|
|
87262
87615
|
const elicit = isEdgeElicitationEnabled();
|
|
87263
|
-
const atCommit = readGitRefState(
|
|
87616
|
+
const atCommit = readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
87264
87617
|
const scoped = scopeSnapshot(structuredClone(subagentBase), (n) => !hiddenFrom(n, sessionId, sessions, now));
|
|
87265
87618
|
delete scoped.workingFile;
|
|
87266
87619
|
if (workingFile) {
|
|
@@ -87301,7 +87654,7 @@ function createWorkspaceEngine(opts) {
|
|
|
87301
87654
|
]
|
|
87302
87655
|
};
|
|
87303
87656
|
if (elicit && block.handleNodes.length) {
|
|
87304
|
-
writePrimingHandles(
|
|
87657
|
+
writePrimingHandles(join37(paths.configDir, "priming-handles.json"), block.handleNodes);
|
|
87305
87658
|
}
|
|
87306
87659
|
sessionRenders.delete(sessionId);
|
|
87307
87660
|
sessionRenders.set(sessionId, { key, block });
|
|
@@ -87361,7 +87714,7 @@ function createWorkspaceEngine(opts) {
|
|
|
87361
87714
|
resultSummary: { exitCode: e.exitCode ?? 1, errorTokens: e.errorTokens }
|
|
87362
87715
|
});
|
|
87363
87716
|
};
|
|
87364
|
-
const turnCursorPath =
|
|
87717
|
+
const turnCursorPath = join37(paths.configDir, "turn-cursors.json");
|
|
87365
87718
|
const lastTurnUuid = loadTurnCursors(turnCursorPath);
|
|
87366
87719
|
const turnOffset = loadTurnOffsets(turnCursorPath);
|
|
87367
87720
|
const readLosses = { parseFailures: 0, ioFailures: 0, bytesUnreachable: 0, sliceGuardHits: 0 };
|
|
@@ -87423,7 +87776,7 @@ function createWorkspaceEngine(opts) {
|
|
|
87423
87776
|
let processedTurns = 0;
|
|
87424
87777
|
const seqAtStart = store.currentIngestSeq();
|
|
87425
87778
|
const elicit = isEdgeElicitationEnabled();
|
|
87426
|
-
const handleMap = elicit ? readPrimingHandles(
|
|
87779
|
+
const handleMap = elicit ? readPrimingHandles(join37(paths.configDir, "priming-handles.json")) : {};
|
|
87427
87780
|
const wsRoot = (opts.workspaceRoot ?? "").replace(/\\/g, "/");
|
|
87428
87781
|
const toRel = (abs) => {
|
|
87429
87782
|
const p = abs.replace(/\\/g, "/");
|
|
@@ -87634,7 +87987,7 @@ function createWorkspaceEngine(opts) {
|
|
|
87634
87987
|
let anchorReadFailed = false;
|
|
87635
87988
|
if (p.location) {
|
|
87636
87989
|
try {
|
|
87637
|
-
fileText =
|
|
87990
|
+
fileText = readFileSync33(join37(opts.workspaceRoot, p.location.path), "utf8");
|
|
87638
87991
|
} catch {
|
|
87639
87992
|
anchorReadFailed = true;
|
|
87640
87993
|
}
|
|
@@ -87796,10 +88149,10 @@ function createWorkspaceEngine(opts) {
|
|
|
87796
88149
|
let enclosing = {};
|
|
87797
88150
|
if (p.location?.line !== void 0) {
|
|
87798
88151
|
try {
|
|
87799
|
-
const headSha = readGitRefState(
|
|
88152
|
+
const headSha = readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
87800
88153
|
enclosing = {
|
|
87801
88154
|
line: p.location.line,
|
|
87802
|
-
fileText:
|
|
88155
|
+
fileText: readFileSync33(join37(opts.workspaceRoot, anchorPath), "utf8"),
|
|
87803
88156
|
...headSha ? { headSha } : {}
|
|
87804
88157
|
};
|
|
87805
88158
|
} catch {
|
|
@@ -88638,7 +88991,7 @@ B: ${b}`,
|
|
|
88638
88991
|
try {
|
|
88639
88992
|
const inputs = emitInputsFromManifest(paths.configDir, paths.skillsManifest);
|
|
88640
88993
|
emitAndProjectSkills(opts.workspaceRoot, inputs);
|
|
88641
|
-
writePrimingHandles(
|
|
88994
|
+
writePrimingHandles(join37(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
|
|
88642
88995
|
} catch (err2) {
|
|
88643
88996
|
console.warn("[skills] agent-skills projection failed (non-fatal):", err2 instanceof Error ? err2.message : err2);
|
|
88644
88997
|
}
|
|
@@ -88674,6 +89027,7 @@ B: ${b}`,
|
|
|
88674
89027
|
lastActivityAt() {
|
|
88675
89028
|
return lastActivityTs;
|
|
88676
89029
|
},
|
|
89030
|
+
storeReconciled: () => storeReconciled,
|
|
88677
89031
|
quarantinedSessions: () => sessions.originSessions(),
|
|
88678
89032
|
markContextDirty() {
|
|
88679
89033
|
contextDirty = true;
|
|
@@ -88734,7 +89088,46 @@ B: ${b}`,
|
|
|
88734
89088
|
return report;
|
|
88735
89089
|
},
|
|
88736
89090
|
async semanticMaintenance() {
|
|
88737
|
-
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;
|
|
88738
89131
|
appendPassLedger(paths.configDir, "semantic-maintenance", report.durationMs, {
|
|
88739
89132
|
revisitsCleared: report.revisitsCleared,
|
|
88740
89133
|
revisitsStanding: report.revisitsStanding,
|
|
@@ -89081,7 +89474,7 @@ async function startDaemon(opts) {
|
|
|
89081
89474
|
reviewUrl: () => webUiUrl + "/review"
|
|
89082
89475
|
});
|
|
89083
89476
|
const writeLockFile = (url2) => {
|
|
89084
|
-
|
|
89477
|
+
writeFileSync25(
|
|
89085
89478
|
engine.paths.daemonLock,
|
|
89086
89479
|
daemonLockPayload({ pid: process.pid, webUiUrl: url2, processStartedAt, version: DAEMON_VERSION }),
|
|
89087
89480
|
"utf8"
|
|
@@ -89330,8 +89723,8 @@ async function linkRegisteredWorkspaces(cfg, loggedInProfile = cfg.activeInstall
|
|
|
89330
89723
|
}
|
|
89331
89724
|
|
|
89332
89725
|
// src/edge-park.ts
|
|
89333
|
-
import { readFileSync as
|
|
89334
|
-
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";
|
|
89335
89728
|
var EDGE_PARK_CAP = 2e3;
|
|
89336
89729
|
var EDGE_PARK_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
89337
89730
|
var EDGE_PARK_MAX_ATTEMPTS = 6;
|
|
@@ -89346,12 +89739,12 @@ function wireEdgeKey(from, type, to) {
|
|
|
89346
89739
|
return JSON.stringify([from, type, to]);
|
|
89347
89740
|
}
|
|
89348
89741
|
function edgeParkPath(workspaceConfigDir, destinationKey) {
|
|
89349
|
-
return
|
|
89742
|
+
return join38(workspaceConfigDir, `edge-park.${destinationKey.slice(0, 16)}.json`);
|
|
89350
89743
|
}
|
|
89351
89744
|
function loadEdgePark(path3) {
|
|
89352
89745
|
let raw2;
|
|
89353
89746
|
try {
|
|
89354
|
-
raw2 = JSON.parse(
|
|
89747
|
+
raw2 = JSON.parse(readFileSync34(path3, "utf8"));
|
|
89355
89748
|
} catch {
|
|
89356
89749
|
return [];
|
|
89357
89750
|
}
|
|
@@ -89362,9 +89755,9 @@ function loadEdgePark(path3) {
|
|
|
89362
89755
|
}
|
|
89363
89756
|
function saveEdgePark(path3, queue) {
|
|
89364
89757
|
try {
|
|
89365
|
-
const tmp =
|
|
89366
|
-
|
|
89367
|
-
|
|
89758
|
+
const tmp = join38(dirname14(path3), `.${Date.now()}.edge-park.tmp`);
|
|
89759
|
+
writeFileSync26(tmp, JSON.stringify(queue), "utf8");
|
|
89760
|
+
renameSync6(tmp, path3);
|
|
89368
89761
|
} catch {
|
|
89369
89762
|
}
|
|
89370
89763
|
}
|
|
@@ -89379,6 +89772,14 @@ function edgeHolds(queue, now) {
|
|
|
89379
89772
|
}
|
|
89380
89773
|
return holds;
|
|
89381
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
|
+
}
|
|
89382
89783
|
function classifyEdgeVerdict(decision, reason) {
|
|
89383
89784
|
if (decision === "created" || decision === "reinforced") return "landed";
|
|
89384
89785
|
const why = reason ?? "";
|
|
@@ -89676,8 +90077,8 @@ function invalidateInstanceReceipt(current, destination, failedId, mirrorLegacy)
|
|
|
89676
90077
|
// src/multi.ts
|
|
89677
90078
|
init_dist();
|
|
89678
90079
|
init_src5();
|
|
89679
|
-
import { existsSync as existsSync34, writeFileSync as
|
|
89680
|
-
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";
|
|
89681
90082
|
|
|
89682
90083
|
// src/principle-sync.ts
|
|
89683
90084
|
init_src5();
|
|
@@ -89705,8 +90106,8 @@ init_reconcile();
|
|
|
89705
90106
|
|
|
89706
90107
|
// src/lockfile-auto.ts
|
|
89707
90108
|
init_src();
|
|
89708
|
-
import { existsSync as existsSync30, readFileSync as
|
|
89709
|
-
import { join as
|
|
90109
|
+
import { existsSync as existsSync30, readFileSync as readFileSync35 } from "node:fs";
|
|
90110
|
+
import { join as join39 } from "node:path";
|
|
89710
90111
|
|
|
89711
90112
|
// src/package-index.ts
|
|
89712
90113
|
init_src();
|
|
@@ -89731,10 +90132,23 @@ function buildContextNode(id, label, description, attrs, ts) {
|
|
|
89731
90132
|
attrs
|
|
89732
90133
|
};
|
|
89733
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
|
+
}
|
|
89734
90147
|
function mintPackageGraph(store, sbom, workspaceId2, ts) {
|
|
89735
90148
|
const minted = /* @__PURE__ */ new Set();
|
|
89736
90149
|
for (const c of sbom.components) {
|
|
89737
|
-
|
|
90150
|
+
mintContextNode(
|
|
90151
|
+
store,
|
|
89738
90152
|
buildContextNode(
|
|
89739
90153
|
c.purl,
|
|
89740
90154
|
"Package",
|
|
@@ -89757,8 +90171,14 @@ function mintPackageGraph(store, sbom, workspaceId2, ts) {
|
|
|
89757
90171
|
if (!minted.has(d.ref)) continue;
|
|
89758
90172
|
for (const to of d.dependsOn) {
|
|
89759
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
|
+
}
|
|
89760
90180
|
store.mergeEdge({
|
|
89761
|
-
id
|
|
90181
|
+
id,
|
|
89762
90182
|
from: d.ref,
|
|
89763
90183
|
to,
|
|
89764
90184
|
type: "DEPENDS_ON",
|
|
@@ -89780,9 +90200,7 @@ function mintLanguageNodes(store, languages, workspaceId2, ts) {
|
|
|
89780
90200
|
for (const raw2 of languages) {
|
|
89781
90201
|
const name2 = raw2.trim();
|
|
89782
90202
|
if (!name2) continue;
|
|
89783
|
-
store.
|
|
89784
|
-
buildContextNode(`lang:${name2.toLowerCase()}`, "Language", name2, { name: name2, workspaceId: workspaceId2 }, ts)
|
|
89785
|
-
);
|
|
90203
|
+
mintContextNode(store, buildContextNode(`lang:${name2.toLowerCase()}`, "Language", name2, { name: name2, workspaceId: workspaceId2 }, ts));
|
|
89786
90204
|
n++;
|
|
89787
90205
|
}
|
|
89788
90206
|
return n;
|
|
@@ -89829,10 +90247,14 @@ function buildContextIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
89829
90247
|
}
|
|
89830
90248
|
}
|
|
89831
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
|
+
};
|
|
89832
90254
|
const edges = [];
|
|
89833
90255
|
for (const id of seen) {
|
|
89834
90256
|
for (const e of store.outEdges(id, ["DEPENDS_ON"])) {
|
|
89835
|
-
if (seen.has(e.to)) edges.push({ ...e, attrs: {} });
|
|
90257
|
+
if (seen.has(e.to) || contributed(e.to)) edges.push({ ...e, attrs: {} });
|
|
89836
90258
|
}
|
|
89837
90259
|
}
|
|
89838
90260
|
const base = {
|
|
@@ -89858,11 +90280,11 @@ function runLockfilePass(opts) {
|
|
|
89858
90280
|
{ file: "package-lock.json", parse: parsePackageLockJson }
|
|
89859
90281
|
];
|
|
89860
90282
|
for (const c of candidates) {
|
|
89861
|
-
const p =
|
|
90283
|
+
const p = join39(opts.root, c.file);
|
|
89862
90284
|
if (!existsSync30(p)) continue;
|
|
89863
90285
|
let sbom;
|
|
89864
90286
|
try {
|
|
89865
|
-
sbom = c.parse(
|
|
90287
|
+
sbom = c.parse(readFileSync35(p, "utf8"));
|
|
89866
90288
|
} catch {
|
|
89867
90289
|
continue;
|
|
89868
90290
|
}
|
|
@@ -89923,8 +90345,8 @@ init_profile2();
|
|
|
89923
90345
|
init_session_registry();
|
|
89924
90346
|
|
|
89925
90347
|
// src/public-symbols.ts
|
|
89926
|
-
import { readFileSync as
|
|
89927
|
-
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";
|
|
89928
90350
|
var HEAD_BYTES = 8 * 1024;
|
|
89929
90351
|
var INDEX_TTL_MS = 10 * 60 * 1e3;
|
|
89930
90352
|
var MIN_SYMBOL_LEN = 4;
|
|
@@ -89957,20 +90379,20 @@ function bindingNames(clause) {
|
|
|
89957
90379
|
function internalPackageNames(workspaceRoot) {
|
|
89958
90380
|
const names = /* @__PURE__ */ new Set();
|
|
89959
90381
|
const tryRead = (dir) => {
|
|
89960
|
-
const pj =
|
|
90382
|
+
const pj = join40(dir, "package.json");
|
|
89961
90383
|
if (!existsSync31(pj)) return;
|
|
89962
90384
|
try {
|
|
89963
|
-
const name2 = JSON.parse(
|
|
90385
|
+
const name2 = JSON.parse(readFileSync36(pj, "utf8")).name;
|
|
89964
90386
|
if (typeof name2 === "string" && name2.length > 0) names.add(name2);
|
|
89965
90387
|
} catch {
|
|
89966
90388
|
}
|
|
89967
90389
|
};
|
|
89968
90390
|
tryRead(workspaceRoot);
|
|
89969
90391
|
for (const group of ["packages", "apps"]) {
|
|
89970
|
-
const groupDir =
|
|
90392
|
+
const groupDir = join40(workspaceRoot, group);
|
|
89971
90393
|
if (!existsSync31(groupDir)) continue;
|
|
89972
90394
|
try {
|
|
89973
|
-
for (const entry of readdirSync12(groupDir)) tryRead(
|
|
90395
|
+
for (const entry of readdirSync12(groupDir)) tryRead(join40(groupDir, entry));
|
|
89974
90396
|
} catch {
|
|
89975
90397
|
}
|
|
89976
90398
|
}
|
|
@@ -89989,7 +90411,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
|
|
|
89989
90411
|
}
|
|
89990
90412
|
const readHead = deps.readHead ?? ((absPath) => {
|
|
89991
90413
|
try {
|
|
89992
|
-
return
|
|
90414
|
+
return readFileSync36(absPath, "utf8").slice(0, HEAD_BYTES);
|
|
89993
90415
|
} catch {
|
|
89994
90416
|
return "";
|
|
89995
90417
|
}
|
|
@@ -90009,7 +90431,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
|
|
|
90009
90431
|
}
|
|
90010
90432
|
const symbols = /* @__PURE__ */ new Set();
|
|
90011
90433
|
for (const rel of files) {
|
|
90012
|
-
const head2 = readHead(
|
|
90434
|
+
const head2 = readHead(join40(workspaceRoot, rel));
|
|
90013
90435
|
if (!head2) continue;
|
|
90014
90436
|
for (const re of [NAMED_IMPORT_RE, REQUIRE_RE]) {
|
|
90015
90437
|
re.lastIndex = 0;
|
|
@@ -90994,7 +91416,7 @@ init_config();
|
|
|
90994
91416
|
|
|
90995
91417
|
// src/update.ts
|
|
90996
91418
|
import { spawn as spawn2 } from "node:child_process";
|
|
90997
|
-
import { isAbsolute as
|
|
91419
|
+
import { isAbsolute as isAbsolute5, join as join41 } from "node:path";
|
|
90998
91420
|
var PACKAGE_NAME = "@inerrata-corporation/errata";
|
|
90999
91421
|
function parse3(v) {
|
|
91000
91422
|
const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z][0-9A-Za-z.-]*))?/.exec(v.trim());
|
|
@@ -91139,9 +91561,9 @@ async function runInstalledHookRefresh() {
|
|
|
91139
91561
|
child.on("error", () => resolve10(""));
|
|
91140
91562
|
child.on("close", (code) => resolve10(code === 0 ? output.trim() : ""));
|
|
91141
91563
|
});
|
|
91142
|
-
if (!
|
|
91564
|
+
if (!isAbsolute5(root)) return 1;
|
|
91143
91565
|
return new Promise((resolve10) => {
|
|
91144
|
-
const child = spawn2(process.execPath, [
|
|
91566
|
+
const child = spawn2(process.execPath, [join41(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
|
|
91145
91567
|
windowsHide: true,
|
|
91146
91568
|
stdio: "inherit",
|
|
91147
91569
|
timeout: 3e4
|
|
@@ -91287,12 +91709,12 @@ function landCloudEdge(store, e, from, to) {
|
|
|
91287
91709
|
}
|
|
91288
91710
|
|
|
91289
91711
|
// src/causal-edge-queue.ts
|
|
91290
|
-
import { readFileSync as
|
|
91291
|
-
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";
|
|
91292
91714
|
var CAUSAL_EDGE_QUEUE_CAP = 5e3;
|
|
91293
91715
|
var CAUSAL_EDGE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
91294
91716
|
function causalEdgeQueuePath(workspaceConfigDir) {
|
|
91295
|
-
return
|
|
91717
|
+
return join42(workspaceConfigDir, "causal-edge-queue.json");
|
|
91296
91718
|
}
|
|
91297
91719
|
function parkedEdgeKey(e) {
|
|
91298
91720
|
return `${e.from}|${e.type}|${e.to}`;
|
|
@@ -91300,7 +91722,7 @@ function parkedEdgeKey(e) {
|
|
|
91300
91722
|
function loadCausalEdgeQueue(path3) {
|
|
91301
91723
|
let raw2;
|
|
91302
91724
|
try {
|
|
91303
|
-
raw2 = JSON.parse(
|
|
91725
|
+
raw2 = JSON.parse(readFileSync37(path3, "utf8"));
|
|
91304
91726
|
} catch {
|
|
91305
91727
|
return [];
|
|
91306
91728
|
}
|
|
@@ -91311,9 +91733,9 @@ function loadCausalEdgeQueue(path3) {
|
|
|
91311
91733
|
}
|
|
91312
91734
|
function saveCausalEdgeQueue(path3, queue) {
|
|
91313
91735
|
try {
|
|
91314
|
-
const tmp =
|
|
91315
|
-
|
|
91316
|
-
|
|
91736
|
+
const tmp = join42(dirname15(path3), `.${Date.now()}.causal-edge-queue.tmp`);
|
|
91737
|
+
writeFileSync27(tmp, JSON.stringify(queue), "utf8");
|
|
91738
|
+
renameSync7(tmp, path3);
|
|
91317
91739
|
} catch {
|
|
91318
91740
|
}
|
|
91319
91741
|
}
|
|
@@ -91449,6 +91871,10 @@ async function lookupLive(store, m, id) {
|
|
|
91449
91871
|
const second = (await m.refresh()).get(id);
|
|
91450
91872
|
return second && isLive(store, second) ? second : null;
|
|
91451
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
|
+
}
|
|
91452
91878
|
function isLive(store, id) {
|
|
91453
91879
|
const n = store.getNode(id);
|
|
91454
91880
|
return n !== null && (n.validTo === null || n.validTo === void 0);
|
|
@@ -91739,7 +92165,9 @@ init_src11();
|
|
|
91739
92165
|
init_src();
|
|
91740
92166
|
import { execFile as execFile5 } from "node:child_process";
|
|
91741
92167
|
import { promisify as promisify4 } from "node:util";
|
|
91742
|
-
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";
|
|
91743
92171
|
|
|
91744
92172
|
// src/history-dependency-snapshot.ts
|
|
91745
92173
|
init_src();
|
|
@@ -91750,22 +92178,20 @@ async function readHistoryDependencySnapshot(opts) {
|
|
|
91750
92178
|
const git3 = opts.git ?? (async (args2) => (await exec("git", ["-C", opts.root, ...args2], { windowsHide: true, maxBuffer: 16 * 1024 * 1024 })).stdout);
|
|
91751
92179
|
const read2 = opts.readBlob ?? (async (oid) => git3(["show", oid]));
|
|
91752
92180
|
let complete = true;
|
|
91753
|
-
const tree = await git3(["ls-tree", "-r", opts.commit]).catch(() => null);
|
|
92181
|
+
const tree = await git3(["ls-tree", "-r", "-z", opts.commit]).catch(() => null);
|
|
91754
92182
|
if (tree === null) return { schemaVersion: "history-deps-1", complete: false, dependencies: [] };
|
|
91755
|
-
const entries = tree.split("\
|
|
91756
|
-
const match2 = /^\d+ blob ([a-f0-9]+)\t(
|
|
91757
|
-
|
|
91758
|
-
const path3 = match2[2].replace(/^"|"$/g, "");
|
|
91759
|
-
if (path3.includes("\\") || /[\r\n]/.test(path3)) {
|
|
91760
|
-
complete = false;
|
|
91761
|
-
return [];
|
|
91762
|
-
}
|
|
91763
|
-
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] }] : [];
|
|
91764
92186
|
});
|
|
91765
92187
|
const manifests = {}, locks = {};
|
|
91766
92188
|
for (const { path: path3, oid } of entries) {
|
|
91767
|
-
const lock = /(?:^|\/)(?:pnpm-lock
|
|
92189
|
+
const lock = /(?:^|\/)(?:pnpm-lock\.yaml|package-lock\.json)$/.test(path3);
|
|
91768
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
|
+
}
|
|
91769
92195
|
if (opts.paths && !Object.values(opts.paths).some((p) => !path3.includes("/") || p.startsWith(path3.slice(0, path3.lastIndexOf("/") + 1)))) continue;
|
|
91770
92196
|
if (opts.allowPath && !opts.allowPath(path3)) {
|
|
91771
92197
|
complete = false;
|
|
@@ -91848,6 +92274,46 @@ init_profile2();
|
|
|
91848
92274
|
var exec2 = promisify4(execFile5);
|
|
91849
92275
|
var KINDS = { function: "Function", class: "Class", method: "Method", interface: "Interface", const: "Const", enum: "Enum", typealias: "TypeAlias", namespace: "Namespace", property: "Property" };
|
|
91850
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 = {
|
|
92303
|
+
parents: new Bounded(4),
|
|
92304
|
+
dependencies: new Bounded(8),
|
|
92305
|
+
trees: new Bounded(4),
|
|
92306
|
+
symbols: new Bounded(4e3),
|
|
92307
|
+
diffs: new Bounded(2e3),
|
|
92308
|
+
listings: new Bounded(4),
|
|
92309
|
+
blobs: new Bounded(256)
|
|
92310
|
+
};
|
|
92311
|
+
revisionCaches.set(git3, caches);
|
|
92312
|
+
}
|
|
92313
|
+
return caches;
|
|
92314
|
+
}
|
|
92315
|
+
var REVISION_DIFF_TOKENS = 4e3;
|
|
92316
|
+
var REVISION_RAW_DIFF_CHARS = REVISION_DIFF_TOKENS * 4 * 4;
|
|
91851
92317
|
async function syncHistoryRevision(opts) {
|
|
91852
92318
|
const current = inFlight.get(opts.root);
|
|
91853
92319
|
if (current) return current;
|
|
@@ -91855,12 +92321,13 @@ async function syncHistoryRevision(opts) {
|
|
|
91855
92321
|
const started2 = Date.now();
|
|
91856
92322
|
let changed = 0, remaining = false;
|
|
91857
92323
|
const pages = Math.min(20, Math.max(1, opts.maxPages ?? 10));
|
|
92324
|
+
const resolve10 = opts.profile.projectId ? reverseSymbolResolver({ store: opts.store, salt: opts.salt, projectId: opts.profile.projectId }) : async () => null;
|
|
91858
92325
|
for (let i2 = 0; i2 < pages; i2++) {
|
|
91859
|
-
const result = await syncHistoryRevisionPage(opts);
|
|
92326
|
+
const result = await syncHistoryRevisionPage(opts, resolve10);
|
|
91860
92327
|
changed += result.changed;
|
|
91861
92328
|
remaining = result.remaining;
|
|
91862
|
-
if (!remaining || Date.now() - started2 >= (opts.budgetMs ?? 45e3)) break;
|
|
91863
|
-
await new Promise((
|
|
92329
|
+
if (!remaining || result.nextBeat || Date.now() - started2 >= (opts.budgetMs ?? 45e3)) break;
|
|
92330
|
+
await new Promise((resolve11) => setImmediate(resolve11));
|
|
91864
92331
|
}
|
|
91865
92332
|
return { changed, remaining };
|
|
91866
92333
|
})();
|
|
@@ -91871,78 +92338,169 @@ async function syncHistoryRevision(opts) {
|
|
|
91871
92338
|
if (inFlight.get(opts.root) === work) inFlight.delete(opts.root);
|
|
91872
92339
|
}
|
|
91873
92340
|
}
|
|
91874
|
-
async function syncHistoryRevisionPage(opts) {
|
|
92341
|
+
async function syncHistoryRevisionPage(opts, resolve10) {
|
|
91875
92342
|
const { root, profile, store, cloud, salt } = opts;
|
|
91876
92343
|
if (!profile.projectId) return { changed: 0, remaining: false };
|
|
91877
92344
|
const projectId = profile.projectId;
|
|
91878
92345
|
const git3 = opts.git ?? (async (args2) => (await exec2("git", ["-C", root, ...args2], { windowsHide: true, maxBuffer: 8 * 1024 * 1024 })).stdout);
|
|
92346
|
+
const caches = cachesFor(opts.git ?? DEFAULT_GIT);
|
|
92347
|
+
const ignoreKey = createHash19("sha256").update(JSON.stringify(profile.ignoreExtra ?? [])).update(readFileSafe(join43(root, ".errataignore"))).digest("hex").slice(0, 16);
|
|
91879
92348
|
const atCommit = (await git3(["rev-parse", "--verify", "HEAD"])).trim();
|
|
91880
92349
|
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(atCommit)) throw new Error("history revision is not a full Git object id");
|
|
91881
92350
|
const oldCursor = profile.historyRevisionCursor;
|
|
91882
|
-
const
|
|
91883
|
-
if (
|
|
91884
|
-
|
|
91885
|
-
|
|
91886
|
-
|
|
92351
|
+
const save = () => (opts.save ?? ((p) => saveProfile(root, p)))(profile);
|
|
92352
|
+
if (oldCursor && oldCursor.ignoreKey !== ignoreKey && oldCursor.reprove !== ignoreKey) {
|
|
92353
|
+
profile.historyRevisionCursor = { ...oldCursor, atCommit, complete: false, after: void 0, reprove: ignoreKey, updatedAt: Date.now() };
|
|
92354
|
+
delete profile.historyRevisionCursor.after;
|
|
92355
|
+
save();
|
|
92356
|
+
}
|
|
92357
|
+
const cursor = profile.historyRevisionCursor;
|
|
92358
|
+
const head2 = cursor?.head ?? cursor?.atCommit;
|
|
92359
|
+
if (cursor && head2 && head2 !== atCommit && cloud.carryHistory && !carryRefused.has(root)) {
|
|
92360
|
+
const range = `${root}|${head2}|${atCommit}`;
|
|
92361
|
+
try {
|
|
92362
|
+
const carry = await carryRequest({
|
|
92363
|
+
git: git3,
|
|
92364
|
+
caches,
|
|
92365
|
+
root,
|
|
92366
|
+
salt,
|
|
92367
|
+
projectId,
|
|
92368
|
+
providers: defaultProviders(),
|
|
92369
|
+
from: head2,
|
|
92370
|
+
at: atCommit,
|
|
92371
|
+
rulesChanged: cursor.ignoreKey !== ignoreKey
|
|
92372
|
+
});
|
|
92373
|
+
await cloud.carryHistory(projectId, carry);
|
|
92374
|
+
carryFailures.delete(range);
|
|
92375
|
+
} catch (err2) {
|
|
92376
|
+
if (err2.status === 404) {
|
|
92377
|
+
carryRefused.add(root);
|
|
92378
|
+
console.warn(`[errata] the cloud predates history carry; every new commit re-proves all history verdicts for ${profile.name}`);
|
|
92379
|
+
} else {
|
|
92380
|
+
const failures = (carryFailures.get(range) ?? 0) + 1;
|
|
92381
|
+
carryFailures.set(range, failures);
|
|
92382
|
+
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)}`);
|
|
92383
|
+
if (failures < CARRY_ATTEMPTS) return { changed: 0, remaining: true, nextBeat: true };
|
|
92384
|
+
carryFailures.delete(range);
|
|
92385
|
+
}
|
|
92386
|
+
}
|
|
92387
|
+
profile.historyRevisionCursor = { ...cursor, head: atCommit };
|
|
92388
|
+
save();
|
|
92389
|
+
}
|
|
92390
|
+
const current = profile.historyRevisionCursor;
|
|
92391
|
+
const reproving = current?.reprove === ignoreKey;
|
|
92392
|
+
const same = current?.atCommit === atCommit;
|
|
92393
|
+
if (same && current.complete && Date.now() - current.updatedAt < 60 * 6e4) return { changed: 0, remaining: false };
|
|
92394
|
+
const after = current && !current.complete ? current.after : void 0;
|
|
92395
|
+
const sweepCommit = after ? current.atCommit : atCommit;
|
|
92396
|
+
const page = await cloud.getHistoryOccurrences(projectId, atCommit, after, { pendingOnly: !reproving });
|
|
91887
92397
|
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");
|
|
91888
|
-
const
|
|
91889
|
-
|
|
91890
|
-
|
|
91891
|
-
|
|
91892
|
-
|
|
92398
|
+
const toPost = page.occurrences.filter((o) => !settledHistoryReceipt(o.quality["reconciliationEvidence"]) || reproving && o.quality["historicalAnchors"]?.length);
|
|
92399
|
+
let parents = [];
|
|
92400
|
+
if (toPost.length) {
|
|
92401
|
+
const key = `${root}|${atCommit}`;
|
|
92402
|
+
parents = caches.parents.get(key) ?? (await git3(["rev-list", "--parents", "--max-count=8192", atCommit])).trim().split("\n").filter(Boolean).map((row) => {
|
|
92403
|
+
const [commit, ...parents2] = row.trim().split(/\s+/);
|
|
92404
|
+
return { commit, parents: parents2 };
|
|
92405
|
+
});
|
|
92406
|
+
caches.parents.set(key, parents);
|
|
92407
|
+
}
|
|
91893
92408
|
const ignore2 = loadRepoIgnore(root, profile.ignoreExtra ?? []);
|
|
91894
92409
|
const providers = defaultProviders();
|
|
91895
|
-
const parsedFiles = /* @__PURE__ */ new Map();
|
|
91896
92410
|
const observations = [];
|
|
91897
|
-
const contexts =
|
|
92411
|
+
const contexts = toPost.map((o) => HistoryDependencyContextSchema.safeParse(o.quality["dependencyContext"]));
|
|
91898
92412
|
const manifestIds = new Set(contexts.flatMap((c) => c.success ? c.data.dependencies.map((d) => d.manifestId) : []));
|
|
91899
|
-
|
|
91900
|
-
|
|
91901
|
-
|
|
91902
|
-
|
|
91903
|
-
|
|
91904
|
-
|
|
91905
|
-
|
|
91906
|
-
|
|
91907
|
-
|
|
92413
|
+
let currentDependencies;
|
|
92414
|
+
if (manifestIds.size) {
|
|
92415
|
+
const key = `${root}|${atCommit}|${ignoreKey}|${[...manifestIds].sort().join(",")}`;
|
|
92416
|
+
let snapshot = caches.dependencies.get(key);
|
|
92417
|
+
if (!snapshot) {
|
|
92418
|
+
const listed = (args2) => {
|
|
92419
|
+
if (args2[0] !== "ls-tree") return git3(args2);
|
|
92420
|
+
const k = `${root}|${args2.join(" ")}`;
|
|
92421
|
+
let out2 = caches.listings.get(k);
|
|
92422
|
+
if (!out2) {
|
|
92423
|
+
out2 = git3(args2);
|
|
92424
|
+
caches.listings.set(k, out2);
|
|
92425
|
+
out2.catch(() => caches.listings.delete(k));
|
|
92426
|
+
}
|
|
92427
|
+
return out2;
|
|
92428
|
+
};
|
|
92429
|
+
const blob = (oid) => {
|
|
92430
|
+
const k = `${root}|${oid}`;
|
|
92431
|
+
let out2 = caches.blobs.get(k);
|
|
92432
|
+
if (!out2) {
|
|
92433
|
+
out2 = git3(["show", oid]);
|
|
92434
|
+
caches.blobs.set(k, out2);
|
|
92435
|
+
out2.catch(() => caches.blobs.delete(k));
|
|
92436
|
+
}
|
|
92437
|
+
return out2;
|
|
92438
|
+
};
|
|
92439
|
+
snapshot = readHistoryDependencySnapshot({
|
|
92440
|
+
root,
|
|
92441
|
+
commit: atCommit,
|
|
92442
|
+
side: "after",
|
|
92443
|
+
manifestIds,
|
|
92444
|
+
git: listed,
|
|
92445
|
+
readBlob: blob,
|
|
92446
|
+
allowPath: (p) => pathAllowedByFloor(p) && !isPathBlocked(ignore2, p)
|
|
92447
|
+
});
|
|
92448
|
+
caches.dependencies.set(key, snapshot);
|
|
92449
|
+
snapshot.catch(() => caches.dependencies.delete(key));
|
|
92450
|
+
}
|
|
92451
|
+
currentDependencies = await snapshot;
|
|
92452
|
+
}
|
|
92453
|
+
const treeKey = `${root}|${atCommit}`;
|
|
92454
|
+
let tree = caches.trees.get(treeKey);
|
|
92455
|
+
if (!tree && toPost.length) {
|
|
92456
|
+
tree = git3(["ls-tree", "-r", "-z", "--full-tree", atCommit]).then((out2) => new Map(out2.split("\0").flatMap((row) => {
|
|
92457
|
+
const tab = row.indexOf(" "), [, type, blob] = row.slice(0, tab).split(" ");
|
|
92458
|
+
return tab > 0 && type === "blob" && blob ? [[row.slice(tab + 1), blob]] : [];
|
|
92459
|
+
})));
|
|
92460
|
+
caches.trees.set(treeKey, tree);
|
|
92461
|
+
tree.catch(() => caches.trees.delete(treeKey));
|
|
92462
|
+
}
|
|
92463
|
+
const blobs = await (tree ?? Promise.resolve(/* @__PURE__ */ new Map())).catch(() => /* @__PURE__ */ new Map());
|
|
92464
|
+
const fileId = (path3) => blobs.get(path3) ?? `commit:${atCommit}`;
|
|
92465
|
+
for (const occurrence of toPost) {
|
|
91908
92466
|
const anchors = occurrence.quality["historicalAnchors"];
|
|
91909
92467
|
const paths = /* @__PURE__ */ new Set(), symbols = [];
|
|
92468
|
+
let partial2 = false;
|
|
91910
92469
|
for (const anchor of anchors ?? []) {
|
|
91911
|
-
const localId =
|
|
92470
|
+
const localId = await resolve10(anchor.symbolId), local = localId ? store.getNode(localId) : null;
|
|
91912
92471
|
const path3 = local?.attrs["relPath"];
|
|
91913
92472
|
if (typeof path3 !== "string" || !pathAllowedByFloor(path3) || isPathBlocked(ignore2, path3) || /[\r\n]/.test(path3)) continue;
|
|
91914
92473
|
paths.add(path3);
|
|
91915
|
-
|
|
91916
|
-
|
|
91917
|
-
|
|
91918
|
-
const provider = providers.find((p) => p.fileExtensions.includes(extname3(path3).toLowerCase()));
|
|
91919
|
-
if (!provider) continue;
|
|
91920
|
-
const source2 = await git3(["show", `${atCommit}:${path3}`]).catch(() => null);
|
|
91921
|
-
if (source2 === null || Buffer.byteLength(source2) > 1e6 || source2.includes("\0")) continue;
|
|
91922
|
-
await provider.preload?.();
|
|
91923
|
-
for (const symbol2 of provider.extractSymbols(source2, path3)) {
|
|
91924
|
-
const kind = KINDS[symbol2.kind];
|
|
91925
|
-
if (kind && symbol2.bodyHash) hashes.set(projectSymbolId(salt, projectId, path3, symbol2.qname ?? symbol2.name, kind), symbol2.bodyHash);
|
|
91926
|
-
}
|
|
91927
|
-
}
|
|
91928
|
-
const bodyHash = parsedFiles.get(path3).get(anchor.symbolId);
|
|
92474
|
+
const hashes = await fileSymbols({ caches, providers, root, salt, projectId }, path3, fileId(path3), () => git3(["show", `${atCommit}:${path3}`]));
|
|
92475
|
+
if (!hashes) partial2 = true;
|
|
92476
|
+
const bodyHash = hashes?.get(anchor.symbolId);
|
|
91929
92477
|
if (bodyHash) symbols.push({ symbolId: anchor.symbolId, bodyHash });
|
|
91930
92478
|
}
|
|
91931
92479
|
const source = occurrenceSourceCommit(occurrence);
|
|
91932
92480
|
let diff;
|
|
91933
92481
|
if (source && source !== atCommit && paths.size) {
|
|
91934
|
-
const
|
|
91935
|
-
|
|
91936
|
-
|
|
91937
|
-
|
|
91938
|
-
|
|
91939
|
-
|
|
91940
|
-
|
|
91941
|
-
|
|
91942
|
-
|
|
91943
|
-
|
|
91944
|
-
|
|
91945
|
-
|
|
92482
|
+
const diffKey = `${root}|${ignoreKey}|${source}|${[...paths].sort().map((path3) => `${path3}\0${fileId(path3)}`).join("\0")}`;
|
|
92483
|
+
if (caches.diffs.has(diffKey)) diff = caches.diffs.get(diffKey);
|
|
92484
|
+
else {
|
|
92485
|
+
const bundle = await buildUnitBundle(
|
|
92486
|
+
root,
|
|
92487
|
+
{
|
|
92488
|
+
sha: atCommit,
|
|
92489
|
+
parents: [source],
|
|
92490
|
+
isMerge: true,
|
|
92491
|
+
index: 0,
|
|
92492
|
+
subIndex: 0,
|
|
92493
|
+
subject: "",
|
|
92494
|
+
body: "",
|
|
92495
|
+
authorDate: "",
|
|
92496
|
+
files: [...paths].map((path3) => ({ path: path3, adds: 1, dels: 1, binary: false }))
|
|
92497
|
+
},
|
|
92498
|
+
{ maxTokens: REVISION_DIFF_TOKENS, maxRawDiffChars: REVISION_RAW_DIFF_CHARS, ignorePatterns: profile.ignoreExtra ?? [] }
|
|
92499
|
+
).catch(() => null);
|
|
92500
|
+
if (bundle && !bundle.truncated) diff = bundle.diff;
|
|
92501
|
+
if (bundle) caches.diffs.set(diffKey, diff);
|
|
92502
|
+
else partial2 = true;
|
|
92503
|
+
}
|
|
91946
92504
|
}
|
|
91947
92505
|
const old = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
|
|
91948
92506
|
const dependencyContext = old.success ? {
|
|
@@ -91950,16 +92508,24 @@ async function syncHistoryRevisionPage(opts) {
|
|
|
91950
92508
|
complete: old.data.dependencies.length === 0 || currentDependencies?.complete === true,
|
|
91951
92509
|
dependencies: currentDependencies?.dependencies.filter((d) => old.data.dependencies.some((o) => o.packageId === d.packageId && o.manifestId === d.manifestId)) ?? []
|
|
91952
92510
|
} : void 0;
|
|
92511
|
+
if (partial2) continue;
|
|
91953
92512
|
observations.push({ occurrenceId: occurrence.occurrenceId, symbols, ...diff ? { diff } : {}, ...dependencyContext ? { dependencyContext } : {} });
|
|
91954
92513
|
}
|
|
91955
|
-
const response =
|
|
91956
|
-
if (response.atCommit !== atCommit || response.receipts.length !==
|
|
92514
|
+
const response = observations.length ? await cloud.reconcileHistory(projectId, { atCommit, parents, observations }) : { atCommit, receipts: [] };
|
|
92515
|
+
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");
|
|
92516
|
+
const receipts = new Map(response.receipts.map((r) => [r.occurrenceId, r]));
|
|
92517
|
+
for (const o of page.occurrences) {
|
|
92518
|
+
if (!receipts.has(o.occurrenceId) && settledHistoryReceipt(o.quality["reconciliationEvidence"])) {
|
|
92519
|
+
receipts.set(o.occurrenceId, { verdict: o.quality["applicability"], evidence: o.quality["reconciliationEvidence"] });
|
|
92520
|
+
}
|
|
92521
|
+
}
|
|
91957
92522
|
const headChanged = (await git3(["rev-parse", "--verify", "HEAD"])).trim() !== atCommit;
|
|
91958
92523
|
let changed = 0;
|
|
91959
92524
|
for (const occurrence of page.occurrences) {
|
|
91960
|
-
const node2 = store
|
|
92525
|
+
const node2 = historyNode(store, occurrence);
|
|
91961
92526
|
if (!node2 || node2.attrs["source"] !== "cloud" || node2.attrs["historyQuality"]?.["sourceSupport"] === "quarantined") continue;
|
|
91962
|
-
const receipt =
|
|
92527
|
+
const receipt = receipts.get(occurrence.occurrenceId);
|
|
92528
|
+
if (!receipt || unchangedRecord(node2, occurrence, receipt, atCommit)) continue;
|
|
91963
92529
|
const previous = node2.attrs["historyQuality"];
|
|
91964
92530
|
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;
|
|
91965
92531
|
const dependencies = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
|
|
@@ -91975,17 +92541,115 @@ async function syncHistoryRevisionPage(opts) {
|
|
|
91975
92541
|
} });
|
|
91976
92542
|
changed++;
|
|
91977
92543
|
}
|
|
91978
|
-
|
|
91979
|
-
|
|
92544
|
+
const complete = page.cursor === null;
|
|
92545
|
+
const proven = reproving && complete && sweepCommit === atCommit;
|
|
92546
|
+
const provenKey = proven || !current ? ignoreKey : current.ignoreKey;
|
|
92547
|
+
profile.historyRevisionCursor = {
|
|
92548
|
+
atCommit: sweepCommit,
|
|
92549
|
+
...page.cursor ? { after: page.cursor } : {},
|
|
92550
|
+
complete,
|
|
92551
|
+
updatedAt: Date.now(),
|
|
92552
|
+
head: atCommit,
|
|
92553
|
+
...provenKey !== void 0 ? { ignoreKey: provenKey } : {},
|
|
92554
|
+
...reproving && !proven ? { reprove: ignoreKey } : {}
|
|
92555
|
+
};
|
|
92556
|
+
save();
|
|
91980
92557
|
return { changed, remaining: page.cursor !== null || headChanged || sweepCommit !== atCommit };
|
|
91981
92558
|
}
|
|
92559
|
+
function historyNode(store, occurrence) {
|
|
92560
|
+
return store.getNode(occurrence.canonicalId) ?? (occurrence.nodeId ? store.getNode(occurrence.nodeId) : null);
|
|
92561
|
+
}
|
|
92562
|
+
function unchangedRecord(node2, occurrence, receipt, atCommit) {
|
|
92563
|
+
const previous = node2.attrs["historyQuality"];
|
|
92564
|
+
if (!previous) return false;
|
|
92565
|
+
const stamp = receipt.verdict === "unknown" && previous["applicability"] === "unknown" ? previous["evaluatedAtCommit"] : atCommit;
|
|
92566
|
+
const dependencies = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
|
|
92567
|
+
const next = compactHistoryQuality({
|
|
92568
|
+
...occurrence.quality,
|
|
92569
|
+
evaluatedAtCommit: stamp,
|
|
92570
|
+
applicability: receipt.verdict,
|
|
92571
|
+
reconciliationEvidence: receipt.evidence
|
|
92572
|
+
});
|
|
92573
|
+
return digest(JSON.parse(JSON.stringify(next))) === digest(previous) && digest(dependencies.success ? historyDependencyVersions(dependencies.data) : null) === digest(node2.attrs["depVersions"] ?? null);
|
|
92574
|
+
}
|
|
92575
|
+
async function fileSymbols(ctx, path3, fileId, read2) {
|
|
92576
|
+
const fileKey = `${ctx.root}|${ctx.salt}|${ctx.projectId}|${fileId}|${path3}`;
|
|
92577
|
+
const cached2 = ctx.caches.symbols.get(fileKey);
|
|
92578
|
+
if (cached2) return cached2;
|
|
92579
|
+
const hashes = /* @__PURE__ */ new Map();
|
|
92580
|
+
const provider = ctx.providers.find((p) => p.fileExtensions.includes(extname3(path3).toLowerCase()));
|
|
92581
|
+
if (!provider) {
|
|
92582
|
+
ctx.caches.symbols.set(fileKey, hashes);
|
|
92583
|
+
return hashes;
|
|
92584
|
+
}
|
|
92585
|
+
const source = await read2().catch(() => null);
|
|
92586
|
+
if (source === null) return void 0;
|
|
92587
|
+
ctx.caches.symbols.set(fileKey, hashes);
|
|
92588
|
+
if (Buffer.byteLength(source) > 1e6 || source.includes("\0")) return hashes;
|
|
92589
|
+
await provider.preload?.();
|
|
92590
|
+
for (const symbol2 of provider.extractSymbols(source, path3)) {
|
|
92591
|
+
const kind = KINDS[symbol2.kind];
|
|
92592
|
+
if (kind && symbol2.bodyHash) hashes.set(projectSymbolId(ctx.salt, ctx.projectId, path3, symbol2.qname ?? symbol2.name, kind), symbol2.bodyHash);
|
|
92593
|
+
}
|
|
92594
|
+
return hashes;
|
|
92595
|
+
}
|
|
92596
|
+
var CARRY_MAX_CODE_FILES = 400;
|
|
92597
|
+
var CARRY_MAX_SYMBOLS = 5e3;
|
|
92598
|
+
var CARRY_MAX_MANIFESTS = 512;
|
|
92599
|
+
var CARRY_MAX_COMMITS = 8192;
|
|
92600
|
+
var LOCKFILE = /(?:^|\/)(?:pnpm-lock\.yaml|package-lock\.json)$/;
|
|
92601
|
+
var NO_BLOB = /^0+$/;
|
|
92602
|
+
async function carryRequest(o) {
|
|
92603
|
+
const { git: git3, from, at } = o;
|
|
92604
|
+
let parents = [];
|
|
92605
|
+
if (await git3(["merge-base", "--is-ancestor", from, at]).then(() => true, () => false)) {
|
|
92606
|
+
const rows = `${await git3(["rev-list", "--parents", "--ancestry-path", `--max-count=${CARRY_MAX_COMMITS}`, `${from}..${at}`])}
|
|
92607
|
+
${await git3(["rev-list", "--parents", "-1", from])}`.split("\n").map((row) => row.trim()).filter(Boolean).map((row) => {
|
|
92608
|
+
const [commit, ...parents2] = row.split(/\s+/);
|
|
92609
|
+
return { commit, parents: parents2 };
|
|
92610
|
+
});
|
|
92611
|
+
if (rows.length <= CARRY_MAX_COMMITS) parents = rows;
|
|
92612
|
+
}
|
|
92613
|
+
const fields = (await git3(["diff", "--raw", "--no-renames", "--no-abbrev", "-z", from, at])).split("\0");
|
|
92614
|
+
const changes = [];
|
|
92615
|
+
for (let i2 = 0; i2 + 1 < fields.length; i2 += 2) {
|
|
92616
|
+
const meta3 = fields[i2].trim().split(/\s+/), path3 = fields[i2 + 1];
|
|
92617
|
+
if (meta3.length >= 4 && path3) changes.push({ path: path3, blobs: [meta3[2], meta3[3]].filter((b) => !NO_BLOB.test(b)) });
|
|
92618
|
+
}
|
|
92619
|
+
const manifests = /* @__PURE__ */ new Set(), symbols = /* @__PURE__ */ new Set();
|
|
92620
|
+
let allManifests = o.rulesChanged, allSymbols = o.rulesChanged;
|
|
92621
|
+
const code = changes.filter((c) => o.providers.some((p) => p.fileExtensions.includes(extname3(c.path).toLowerCase())));
|
|
92622
|
+
if (code.length > CARRY_MAX_CODE_FILES) allSymbols = true;
|
|
92623
|
+
for (const change of changes) {
|
|
92624
|
+
if (LOCKFILE.test(change.path)) allManifests = true;
|
|
92625
|
+
else if (isManifestPath(change.path)) manifests.add(historyManifestId(change.path));
|
|
92626
|
+
}
|
|
92627
|
+
for (const change of allSymbols ? [] : code) {
|
|
92628
|
+
for (const blob of change.blobs) {
|
|
92629
|
+
const hashes = await fileSymbols(o, change.path, blob, () => git3(["show", blob]));
|
|
92630
|
+
if (!hashes) {
|
|
92631
|
+
allSymbols = true;
|
|
92632
|
+
break;
|
|
92633
|
+
}
|
|
92634
|
+
for (const id of hashes.keys()) symbols.add(id);
|
|
92635
|
+
}
|
|
92636
|
+
if (allSymbols) break;
|
|
92637
|
+
}
|
|
92638
|
+
return {
|
|
92639
|
+
fromCommit: from,
|
|
92640
|
+
atCommit: at,
|
|
92641
|
+
parents,
|
|
92642
|
+
changedSymbols: allSymbols || symbols.size > CARRY_MAX_SYMBOLS ? null : [...symbols].sort(),
|
|
92643
|
+
changedManifests: allManifests || manifests.size > CARRY_MAX_MANIFESTS ? null : [...manifests].sort()
|
|
92644
|
+
};
|
|
92645
|
+
}
|
|
91982
92646
|
|
|
91983
92647
|
// src/project-history.ts
|
|
91984
92648
|
init_src7();
|
|
91985
92649
|
init_src();
|
|
91986
92650
|
import { execFile as execFile6 } from "node:child_process";
|
|
91987
|
-
import { readFileSync as
|
|
91988
|
-
import { join as
|
|
92651
|
+
import { readFileSync as readFileSync39 } from "node:fs";
|
|
92652
|
+
import { join as join44 } from "node:path";
|
|
91989
92653
|
import { promisify as promisify5 } from "node:util";
|
|
91990
92654
|
|
|
91991
92655
|
// src/history-walk.ts
|
|
@@ -92537,7 +93201,7 @@ async function defaultGit(root, args2) {
|
|
|
92537
93201
|
function readIgnoreLines(root, profile) {
|
|
92538
93202
|
let lines = [];
|
|
92539
93203
|
try {
|
|
92540
|
-
lines =
|
|
93204
|
+
lines = readFileSync39(join44(root, ".errataignore"), "utf8").split("\n");
|
|
92541
93205
|
} catch {
|
|
92542
93206
|
}
|
|
92543
93207
|
return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
@@ -93111,10 +93775,10 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
|
|
|
93111
93775
|
|
|
93112
93776
|
// src/link-flow.ts
|
|
93113
93777
|
init_cloud_auth();
|
|
93114
|
-
import { createHash as
|
|
93778
|
+
import { createHash as createHash20 } from "node:crypto";
|
|
93115
93779
|
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
93116
|
-
import { existsSync as existsSync32, writeFileSync as
|
|
93117
|
-
import { join as
|
|
93780
|
+
import { existsSync as existsSync32, writeFileSync as writeFileSync28 } from "node:fs";
|
|
93781
|
+
import { join as join45 } from "node:path";
|
|
93118
93782
|
|
|
93119
93783
|
// src/device-poll.ts
|
|
93120
93784
|
var THROTTLED_POLL_MIN_WAIT_MS = 11e3;
|
|
@@ -93406,7 +94070,7 @@ async function loginOAuthLoopback(opts) {
|
|
|
93406
94070
|
|
|
93407
94071
|
// src/link-flow.ts
|
|
93408
94072
|
function remoteFingerprint(locator) {
|
|
93409
|
-
return
|
|
94073
|
+
return createHash20("sha256").update(locator).digest("hex");
|
|
93410
94074
|
}
|
|
93411
94075
|
function isDecision(value) {
|
|
93412
94076
|
if (!value || typeof value !== "object") return false;
|
|
@@ -93573,9 +94237,9 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
|
|
|
93573
94237
|
delete nextProfile.projectLinkHold;
|
|
93574
94238
|
let wroteIgnore = false;
|
|
93575
94239
|
if (decision.writeIgnoreStarter !== false) {
|
|
93576
|
-
const target =
|
|
94240
|
+
const target = join45(root, ".errataignore");
|
|
93577
94241
|
if (!existsSync32(target)) {
|
|
93578
|
-
|
|
94242
|
+
writeFileSync28(target, IGNORE_STARTER, "utf8");
|
|
93579
94243
|
wroteIgnore = true;
|
|
93580
94244
|
}
|
|
93581
94245
|
}
|
|
@@ -93589,12 +94253,12 @@ init_registry();
|
|
|
93589
94253
|
// src/adopt.ts
|
|
93590
94254
|
init_git_remote();
|
|
93591
94255
|
import { existsSync as existsSync33 } from "node:fs";
|
|
93592
|
-
import { dirname as
|
|
94256
|
+
import { dirname as dirname16, join as join46 } from "node:path";
|
|
93593
94257
|
function findGitRoot(absPath) {
|
|
93594
94258
|
let dir = absPath;
|
|
93595
94259
|
for (let depth = 0; depth < 64; depth++) {
|
|
93596
|
-
if (existsSync33(
|
|
93597
|
-
const parent =
|
|
94260
|
+
if (existsSync33(join46(dir, ".git"))) return dir;
|
|
94261
|
+
const parent = dirname16(dir);
|
|
93598
94262
|
if (parent === dir) return null;
|
|
93599
94263
|
dir = parent;
|
|
93600
94264
|
}
|
|
@@ -94068,7 +94732,6 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94068
94732
|
const boundaryListeners = [];
|
|
94069
94733
|
let boundaryFlushing = false;
|
|
94070
94734
|
let pushRequested = false;
|
|
94071
|
-
let shippedFingerprint = "";
|
|
94072
94735
|
let settleRunning = false;
|
|
94073
94736
|
let boundaryFlushStartedAt = 0;
|
|
94074
94737
|
let boundaryFlushStage = "";
|
|
@@ -94149,16 +94812,63 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94149
94812
|
});
|
|
94150
94813
|
}
|
|
94151
94814
|
};
|
|
94152
|
-
const
|
|
94815
|
+
const SHIP_MARK_KEY = "watermark:instance-ship";
|
|
94816
|
+
const sendableSeq = (store) => store.changeSeq ? store.changeSeq() - store.changeSeq([EXPOSURE_SCOPE]) : null;
|
|
94817
|
+
const shipLanes = () => {
|
|
94153
94818
|
const cfg2 = loadConfig();
|
|
94154
|
-
const
|
|
94819
|
+
const lanes = [], destinations = [], held = [];
|
|
94155
94820
|
for (const r of records) {
|
|
94156
|
-
|
|
94157
|
-
|
|
94821
|
+
const consent = effectiveConsent(cfg2, r.engine.profile);
|
|
94822
|
+
if (!consent.sync) continue;
|
|
94823
|
+
const identity = identityFor(liveWorkspaceEntry(r.entry));
|
|
94824
|
+
const destination = `${opts.cloudUrl ?? identity.profile?.cloudUrl ?? cfg2.cloudUrl ?? ""}|${identity.profileName ?? ""}`;
|
|
94825
|
+
destinations.push(destination);
|
|
94826
|
+
const quarantined = r.engine.quarantinedSessions().slice().sort();
|
|
94827
|
+
held.push(...quarantined);
|
|
94828
|
+
let ignoreFile = "";
|
|
94829
|
+
try {
|
|
94830
|
+
ignoreFile = readFileSync40(join47(r.root, ".errataignore"), "utf8");
|
|
94831
|
+
} catch {
|
|
94832
|
+
}
|
|
94833
|
+
const retryInputs = JSON.stringify([
|
|
94834
|
+
quarantined,
|
|
94835
|
+
DAEMON_VERSION,
|
|
94836
|
+
ignoreFile,
|
|
94837
|
+
r.engine.profile.ignoreExtra ?? [],
|
|
94838
|
+
r.engine.profile.projectHistoryCorrectionCursor ?? 0
|
|
94839
|
+
]);
|
|
94840
|
+
const context = JSON.stringify([destination, consent.contributePackages ?? null, loadProfile(r.root)?.projectId ?? r.engine.profile.projectId ?? null]);
|
|
94841
|
+
const fp = r.engine.store.labelFingerprint?.(INSTANCE_LABELS);
|
|
94842
|
+
lanes.push({ store: r.engine.store, fp: fp === void 0 ? null : `${context}#${fp}`, seq: sendableSeq(r.engine.store), held: retryInputs });
|
|
94843
|
+
}
|
|
94844
|
+
if (lanes.length === 0) return lanes;
|
|
94845
|
+
const shared = sharedStore.labelFingerprint?.(["RootCause"]);
|
|
94846
|
+
const sharedContext = JSON.stringify([...new Set(destinations)].sort());
|
|
94847
|
+
lanes.push({ store: sharedStore, fp: shared === void 0 ? null : `${sharedContext}#${shared}`, seq: sendableSeq(sharedStore), held: JSON.stringify([[...new Set(held)].sort(), DAEMON_VERSION]) });
|
|
94848
|
+
return lanes;
|
|
94849
|
+
};
|
|
94850
|
+
const shipMark = (store) => {
|
|
94851
|
+
try {
|
|
94852
|
+
return JSON.parse(store.getMeta?.(SHIP_MARK_KEY) ?? "null");
|
|
94853
|
+
} catch {
|
|
94854
|
+
return null;
|
|
94158
94855
|
}
|
|
94159
|
-
|
|
94160
|
-
|
|
94161
|
-
|
|
94856
|
+
};
|
|
94857
|
+
const unshipped = (lanes, retries) => lanes.filter((l) => {
|
|
94858
|
+
const mark = l.fp === null ? null : shipMark(l.store);
|
|
94859
|
+
if (!mark || mark.fp !== l.fp) return true;
|
|
94860
|
+
if (!retries) return false;
|
|
94861
|
+
return !mark.ok || l.seq === null || mark.seq !== l.seq || mark.held !== l.held || mark.retryAt !== void 0 && mark.retryAt <= Date.now();
|
|
94862
|
+
});
|
|
94863
|
+
const recordShipped = (lanes, result) => {
|
|
94864
|
+
const mark = (l) => ({
|
|
94865
|
+
fp: l.fp,
|
|
94866
|
+
ok: !result.errors?.length,
|
|
94867
|
+
...result.retryAt !== void 0 ? { retryAt: result.retryAt } : {},
|
|
94868
|
+
...l.seq !== null ? { seq: l.seq } : {},
|
|
94869
|
+
held: l.held
|
|
94870
|
+
});
|
|
94871
|
+
for (const l of lanes) if (l.fp !== null) l.store.setMeta?.(SHIP_MARK_KEY, JSON.stringify(mark(l)));
|
|
94162
94872
|
};
|
|
94163
94873
|
const runSettle = async () => {
|
|
94164
94874
|
if (settleRunning) return;
|
|
@@ -94311,7 +95021,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94311
95021
|
records.push(rec);
|
|
94312
95022
|
void ambientLinkAll();
|
|
94313
95023
|
try {
|
|
94314
|
-
|
|
95024
|
+
writeFileSync29(
|
|
94315
95025
|
rec.engine.paths.daemonLock,
|
|
94316
95026
|
daemonLockPayload({
|
|
94317
95027
|
pid: process.pid,
|
|
@@ -94380,11 +95090,19 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94380
95090
|
const strandedCount = (r) => {
|
|
94381
95091
|
const hit = strandedCache.get(r.id);
|
|
94382
95092
|
if (hit && Date.now() - hit.at < STRANDED_TTL_MS) return hit.count;
|
|
95093
|
+
const store = r.engine.store;
|
|
95094
|
+
const standing = standingStrandedCount(store);
|
|
95095
|
+
if (standing !== null) {
|
|
95096
|
+
strandedCache.set(r.id, { at: Date.now(), count: standing });
|
|
95097
|
+
return standing;
|
|
95098
|
+
}
|
|
94383
95099
|
if (!strandedRefreshing.has(r.id)) {
|
|
94384
95100
|
strandedRefreshing.add(r.id);
|
|
95101
|
+
const seq = store.changeSeq?.();
|
|
94385
95102
|
const finish = (count) => {
|
|
94386
95103
|
strandedCache.set(r.id, { at: Date.now(), count });
|
|
94387
95104
|
strandedRefreshing.delete(r.id);
|
|
95105
|
+
recordStrandedCount(store, seq, count);
|
|
94388
95106
|
};
|
|
94389
95107
|
if (consolidateWorker && r.engine.paths.castalia !== ":memory:") {
|
|
94390
95108
|
consolidateWorker.run({ kind: "strandedCount", sharedDbPath, castaliaPath: r.engine.paths.castalia }).then((n) => finish(Number(n))).catch(() => {
|
|
@@ -94596,10 +95314,13 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94596
95314
|
};
|
|
94597
95315
|
app.all("/ws/:id", dispatchHot);
|
|
94598
95316
|
app.all("/ws/:id/*", dispatchHot);
|
|
95317
|
+
const anchorPullInFlight = /* @__PURE__ */ new Map();
|
|
94599
95318
|
const retireWorkspace = async (rec, reason) => {
|
|
94600
95319
|
const idx = records.indexOf(rec);
|
|
94601
95320
|
if (idx === -1) return;
|
|
94602
95321
|
records.splice(idx, 1);
|
|
95322
|
+
await anchorPullInFlight.get(rec.root)?.catch(() => {
|
|
95323
|
+
});
|
|
94603
95324
|
try {
|
|
94604
95325
|
await rec.engine.stop();
|
|
94605
95326
|
} catch (err2) {
|
|
@@ -94690,7 +95411,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94690
95411
|
baseUrl = `http://127.0.0.1:${port}`;
|
|
94691
95412
|
try {
|
|
94692
95413
|
ensureDir(globalDir());
|
|
94693
|
-
|
|
95414
|
+
writeFileSync29(
|
|
94694
95415
|
lockPath,
|
|
94695
95416
|
daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
|
|
94696
95417
|
"utf8"
|
|
@@ -94699,7 +95420,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94699
95420
|
}
|
|
94700
95421
|
for (const r of records) {
|
|
94701
95422
|
try {
|
|
94702
|
-
|
|
95423
|
+
writeFileSync29(
|
|
94703
95424
|
r.engine.paths.daemonLock,
|
|
94704
95425
|
daemonLockPayload({
|
|
94705
95426
|
pid: process.pid,
|
|
@@ -94739,7 +95460,14 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94739
95460
|
});
|
|
94740
95461
|
const revisionBacklog = /* @__PURE__ */ new Set();
|
|
94741
95462
|
const lastAnchorPull = /* @__PURE__ */ new Map();
|
|
94742
|
-
const pullProjectAnchors =
|
|
95463
|
+
const pullProjectAnchors = (r, client, salt) => {
|
|
95464
|
+
const running = anchorPullInFlight.get(r.root);
|
|
95465
|
+
if (running) return running;
|
|
95466
|
+
const pull = pullProjectAnchorsOnce(r, client, salt).finally(() => anchorPullInFlight.delete(r.root));
|
|
95467
|
+
anchorPullInFlight.set(r.root, pull);
|
|
95468
|
+
return pull;
|
|
95469
|
+
};
|
|
95470
|
+
const pullProjectAnchorsOnce = async (r, client, salt) => {
|
|
94743
95471
|
const donePass = markPass(`anchor-pull:${r.engine.profile.name}`);
|
|
94744
95472
|
const pullStartedAt = Date.now();
|
|
94745
95473
|
const beforeCorrections = r.engine.profile.projectHistoryCorrectionCursor ?? 0;
|
|
@@ -94755,10 +95483,13 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94755
95483
|
for (const record2 of records) record2.engine.markContextDirty();
|
|
94756
95484
|
}
|
|
94757
95485
|
try {
|
|
94758
|
-
|
|
94759
|
-
|
|
94760
|
-
|
|
94761
|
-
|
|
95486
|
+
if (!r.engine.storeReconciled()) revisionBacklog.add(r.root);
|
|
95487
|
+
else {
|
|
95488
|
+
const revision = await syncHistoryRevision({ root: r.root, profile: r.engine.profile, store: r.engine.store, cloud: client, salt });
|
|
95489
|
+
if (revision.remaining) revisionBacklog.add(r.root);
|
|
95490
|
+
else revisionBacklog.delete(r.root);
|
|
95491
|
+
if (revision.changed) r.engine.markContextDirty();
|
|
95492
|
+
}
|
|
94762
95493
|
} catch (err2) {
|
|
94763
95494
|
console.warn(`[errata] history revision reconciliation failed for ${r.engine.profile.name}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
94764
95495
|
}
|
|
@@ -95248,6 +95979,10 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95248
95979
|
};
|
|
95249
95980
|
let uploaded = 0;
|
|
95250
95981
|
const errors = [];
|
|
95982
|
+
let retryAt = null;
|
|
95983
|
+
const retryBy = (at) => {
|
|
95984
|
+
if (at !== null && (retryAt === null || at < retryAt)) retryAt = at;
|
|
95985
|
+
};
|
|
95251
95986
|
const workerFor = (r) => consolidateWorker && r.engine.paths.castalia !== ":memory:" ? consolidateWorker : null;
|
|
95252
95987
|
const buildContextBatch = async (r, input) => {
|
|
95253
95988
|
const w = workerFor(r);
|
|
@@ -95371,6 +96106,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95371
96106
|
}
|
|
95372
96107
|
});
|
|
95373
96108
|
if (p.blockedNodeIds?.length) {
|
|
96109
|
+
retryBy(Date.now());
|
|
95374
96110
|
console.log(
|
|
95375
96111
|
`[sync\u2192cloud] [${projectName}] context: ${p.blockedNodeIds.length} node(s) refused by an edge/CDN filter on content \u2014 left pending, will retry`
|
|
95376
96112
|
);
|
|
@@ -95402,6 +96138,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95402
96138
|
});
|
|
95403
96139
|
const parkPath = edgeParkPath(r.engine.paths.configDir, destinationKey);
|
|
95404
96140
|
const parkQueue = loadEdgePark(parkPath);
|
|
96141
|
+
retryBy(nextEdgeParkChange(parkQueue));
|
|
95405
96142
|
const built = await buildInstanceBatch(r, {
|
|
95406
96143
|
edgeHolds: edgeHolds(parkQueue, Date.now()),
|
|
95407
96144
|
destinationKey,
|
|
@@ -95471,6 +96208,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95471
96208
|
}
|
|
95472
96209
|
});
|
|
95473
96210
|
if (blocked.size > 0) {
|
|
96211
|
+
retryBy(Date.now());
|
|
95474
96212
|
console.log(
|
|
95475
96213
|
`[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]}`
|
|
95476
96214
|
);
|
|
@@ -95506,6 +96244,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95506
96244
|
Date.now()
|
|
95507
96245
|
);
|
|
95508
96246
|
saveEdgePark(parkPath, settled.queue);
|
|
96247
|
+
retryBy(nextEdgeParkChange(settled.queue));
|
|
95509
96248
|
const edgeCounts = settled.counts;
|
|
95510
96249
|
if (rejectedEdges.length > 0) {
|
|
95511
96250
|
const byReason = /* @__PURE__ */ new Map();
|
|
@@ -95632,7 +96371,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95632
96371
|
});
|
|
95633
96372
|
}
|
|
95634
96373
|
}
|
|
95635
|
-
return { uploaded, ...errors.length > 0 ? { errors } : {} };
|
|
96374
|
+
return { uploaded, ...errors.length > 0 ? { errors } : {}, ...retryAt !== null ? { retryAt } : {} };
|
|
95636
96375
|
},
|
|
95637
96376
|
async backfillCausalEdges() {
|
|
95638
96377
|
if (!loadConfig().consent.sync) return { accepted: 0, rejected: 0, skipped: "consent-off" };
|
|
@@ -95707,9 +96446,9 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95707
96446
|
beginFlush("instances");
|
|
95708
96447
|
try {
|
|
95709
96448
|
flushStage("instances");
|
|
95710
|
-
const
|
|
95711
|
-
const inst = await daemon.syncInstancesPublic();
|
|
95712
|
-
|
|
96449
|
+
const lanes = shipLanes();
|
|
96450
|
+
const inst = lanes.length > 0 && unshipped(lanes, true).length === 0 ? { uploaded: 0, skipped: "unchanged", errors: void 0 } : await daemon.syncInstancesPublic();
|
|
96451
|
+
if (!inst.skipped) recordShipped(lanes, inst);
|
|
95713
96452
|
flushStage("skills");
|
|
95714
96453
|
const skills = await daemon.syncSkillsAll();
|
|
95715
96454
|
return {
|
|
@@ -95723,8 +96462,8 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95723
96462
|
}
|
|
95724
96463
|
},
|
|
95725
96464
|
pendingLiveFingerprint() {
|
|
95726
|
-
const
|
|
95727
|
-
return
|
|
96465
|
+
const pending = unshipped(shipLanes(), false);
|
|
96466
|
+
return pending.length ? pending.map((l) => l.fp ?? `?${Date.now()}`).join("|") : null;
|
|
95728
96467
|
},
|
|
95729
96468
|
async liveShip() {
|
|
95730
96469
|
if (!liveSyncEnabled()) return { uploaded: 0, skipped: "disabled" };
|
|
@@ -95740,9 +96479,9 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95740
96479
|
}
|
|
95741
96480
|
beginFlush("live");
|
|
95742
96481
|
try {
|
|
95743
|
-
const
|
|
96482
|
+
const lanes = shipLanes();
|
|
95744
96483
|
const inst = await daemon.syncInstancesPublic();
|
|
95745
|
-
|
|
96484
|
+
if (!inst.skipped) recordShipped(lanes, inst);
|
|
95746
96485
|
return {
|
|
95747
96486
|
uploaded: inst.uploaded,
|
|
95748
96487
|
...inst.skipped ? { skipped: inst.skipped } : {},
|
|
@@ -95792,7 +96531,9 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95792
96531
|
flushStage("triage");
|
|
95793
96532
|
const triage = await daemon.syncTriagePublic();
|
|
95794
96533
|
flushStage("instances");
|
|
96534
|
+
const lanes = shipLanes();
|
|
95795
96535
|
const instances = await daemon.syncInstancesPublic();
|
|
96536
|
+
if (!instances.skipped) recordShipped(lanes, instances);
|
|
95796
96537
|
flushStage("edge-backfill");
|
|
95797
96538
|
const edgeBackfill = await daemon.backfillCausalEdges();
|
|
95798
96539
|
return c.json({ principles, triage, instances, edgeBackfill });
|
|
@@ -96217,15 +96958,15 @@ function shouldUseOAuthLogin(flags2, env2 = process.env) {
|
|
|
96217
96958
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
96218
96959
|
|
|
96219
96960
|
// src/codex-runtime.ts
|
|
96220
|
-
import { readdirSync as readdirSync13, statSync as
|
|
96221
|
-
import { join as
|
|
96961
|
+
import { readdirSync as readdirSync13, statSync as statSync12 } from "node:fs";
|
|
96962
|
+
import { join as join48 } from "node:path";
|
|
96222
96963
|
function resolveCodexExecutable(options = {}) {
|
|
96223
96964
|
const platform = options.platform ?? process.platform;
|
|
96224
96965
|
const env2 = options.env ?? process.env;
|
|
96225
96966
|
if (platform !== "win32") return "codex";
|
|
96226
96967
|
const fileTime = (path3) => {
|
|
96227
96968
|
try {
|
|
96228
|
-
const s =
|
|
96969
|
+
const s = statSync12(path3);
|
|
96229
96970
|
return s.isFile() ? s.mtimeMs : null;
|
|
96230
96971
|
} catch {
|
|
96231
96972
|
return null;
|
|
@@ -96233,13 +96974,13 @@ function resolveCodexExecutable(options = {}) {
|
|
|
96233
96974
|
};
|
|
96234
96975
|
for (const dir of (env2["PATH"] ?? env2["Path"] ?? "").split(";")) {
|
|
96235
96976
|
if (!dir.trim()) continue;
|
|
96236
|
-
const path3 =
|
|
96977
|
+
const path3 = join48(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
|
|
96237
96978
|
if (fileTime(path3) !== null) return path3;
|
|
96238
96979
|
}
|
|
96239
96980
|
if (!env2["LOCALAPPDATA"]) return "codex";
|
|
96240
|
-
const root =
|
|
96981
|
+
const root = join48(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
|
|
96241
96982
|
try {
|
|
96242
|
-
const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
96983
|
+
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));
|
|
96243
96984
|
return candidates[0]?.path ?? "codex";
|
|
96244
96985
|
} catch {
|
|
96245
96986
|
return "codex";
|
|
@@ -96378,14 +97119,14 @@ async function diagnoseInstallation(cfg, dependencies) {
|
|
|
96378
97119
|
}
|
|
96379
97120
|
|
|
96380
97121
|
// src/credential-scan.ts
|
|
96381
|
-
import { readFileSync as
|
|
97122
|
+
import { readFileSync as readFileSync42, statSync as statSync13 } from "node:fs";
|
|
96382
97123
|
import { homedir as homedir8 } from "node:os";
|
|
96383
|
-
import { join as
|
|
97124
|
+
import { join as join50 } from "node:path";
|
|
96384
97125
|
|
|
96385
97126
|
// src/claude-statusline.ts
|
|
96386
|
-
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as
|
|
97127
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync41, writeFileSync as writeFileSync30 } from "node:fs";
|
|
96387
97128
|
import { homedir as homedir7 } from "node:os";
|
|
96388
|
-
import { dirname as
|
|
97129
|
+
import { dirname as dirname17, join as join49 } from "node:path";
|
|
96389
97130
|
var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
|
|
96390
97131
|
import { readFileSync } from 'node:fs';
|
|
96391
97132
|
|
|
@@ -96433,8 +97174,8 @@ function isSameInstall(value, relay) {
|
|
|
96433
97174
|
return command.includes(relay.replace(/\\/g, "/").toLowerCase());
|
|
96434
97175
|
}
|
|
96435
97176
|
function userClaudeSettingsPath() {
|
|
96436
|
-
const base = process.env["CLAUDE_CONFIG_DIR"] ??
|
|
96437
|
-
return
|
|
97177
|
+
const base = process.env["CLAUDE_CONFIG_DIR"] ?? join49(homedir7(), ".claude");
|
|
97178
|
+
return join49(base, "settings.json");
|
|
96438
97179
|
}
|
|
96439
97180
|
function ensureUserStatusLine(opts) {
|
|
96440
97181
|
const env2 = opts.env ?? process.env;
|
|
@@ -96444,21 +97185,21 @@ function ensureUserStatusLine(opts) {
|
|
|
96444
97185
|
let settings = {};
|
|
96445
97186
|
if (existsSync35(settingsPath)) {
|
|
96446
97187
|
try {
|
|
96447
|
-
const parsed = JSON.parse(
|
|
97188
|
+
const parsed = JSON.parse(readFileSync41(settingsPath, "utf8"));
|
|
96448
97189
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
|
|
96449
97190
|
settings = parsed;
|
|
96450
97191
|
} catch {
|
|
96451
97192
|
return "unreadable";
|
|
96452
97193
|
}
|
|
96453
97194
|
}
|
|
96454
|
-
const relay =
|
|
97195
|
+
const relay = join49(opts.relayDir, STATUSLINE_RELAY_FILE);
|
|
96455
97196
|
const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
|
|
96456
97197
|
const ownMain = keep(settings["statusLine"]);
|
|
96457
97198
|
const ownRows = keep(settings["subagentStatusLine"]);
|
|
96458
97199
|
if (ownMain && ownRows) return "kept-own";
|
|
96459
97200
|
mkdirSync9(opts.relayDir, { recursive: true });
|
|
96460
|
-
if (!existsSync35(relay) ||
|
|
96461
|
-
|
|
97201
|
+
if (!existsSync35(relay) || readFileSync41(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
|
|
97202
|
+
writeFileSync30(relay, STATUSLINE_RELAY_SOURCE, "utf8");
|
|
96462
97203
|
}
|
|
96463
97204
|
const nodePath = opts.nodePath ?? process.execPath;
|
|
96464
97205
|
const next = {
|
|
@@ -96469,8 +97210,8 @@ function ensureUserStatusLine(opts) {
|
|
|
96469
97210
|
return ownMain ? "kept-own" : "unchanged";
|
|
96470
97211
|
}
|
|
96471
97212
|
Object.assign(settings, next);
|
|
96472
|
-
mkdirSync9(
|
|
96473
|
-
|
|
97213
|
+
mkdirSync9(dirname17(settingsPath), { recursive: true });
|
|
97214
|
+
writeFileSync30(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
96474
97215
|
return "installed";
|
|
96475
97216
|
}
|
|
96476
97217
|
function describeStatusLineOutcome(outcome) {
|
|
@@ -96511,36 +97252,36 @@ function findCredentialLines(text) {
|
|
|
96511
97252
|
function harnessConfigPaths(root) {
|
|
96512
97253
|
const env2 = process.env;
|
|
96513
97254
|
const home = homedir8();
|
|
96514
|
-
const codexHome = env2["CODEX_HOME"] ||
|
|
96515
|
-
const geminiHome =
|
|
97255
|
+
const codexHome = env2["CODEX_HOME"] || join50(home, ".codex");
|
|
97256
|
+
const geminiHome = join50(env2["GEMINI_CLI_HOME"] ?? home, ".gemini");
|
|
96516
97257
|
return [
|
|
96517
97258
|
// Claude Code: user settings, `claude mcp add` (local/user scope), project.
|
|
96518
97259
|
userClaudeSettingsPath(),
|
|
96519
|
-
|
|
96520
|
-
|
|
96521
|
-
|
|
96522
|
-
|
|
97260
|
+
join50(env2["CLAUDE_CONFIG_DIR"] ?? home, ".claude.json"),
|
|
97261
|
+
join50(root, ".claude", "settings.json"),
|
|
97262
|
+
join50(root, ".claude", "settings.local.json"),
|
|
97263
|
+
join50(root, ".mcp.json"),
|
|
96523
97264
|
// Codex
|
|
96524
|
-
|
|
96525
|
-
|
|
97265
|
+
join50(codexHome, "config.toml"),
|
|
97266
|
+
join50(root, ".codex", "config.toml"),
|
|
96526
97267
|
// Gemini CLI
|
|
96527
|
-
|
|
96528
|
-
|
|
97268
|
+
join50(geminiHome, "settings.json"),
|
|
97269
|
+
join50(root, ".gemini", "settings.json"),
|
|
96529
97270
|
// Cursor
|
|
96530
|
-
|
|
96531
|
-
|
|
97271
|
+
join50(home, ".cursor", "mcp.json"),
|
|
97272
|
+
join50(root, ".cursor", "mcp.json"),
|
|
96532
97273
|
// VS Code (user profile mcp.json + workspace)
|
|
96533
|
-
|
|
96534
|
-
|
|
97274
|
+
join50(vscodeUserDir(home, env2), "mcp.json"),
|
|
97275
|
+
join50(root, ".vscode", "mcp.json"),
|
|
96535
97276
|
// OpenCode (XDG on every platform; the daemon's installer writes the project one)
|
|
96536
|
-
|
|
96537
|
-
|
|
97277
|
+
join50(env2["XDG_CONFIG_HOME"] ?? join50(home, ".config"), "opencode", "opencode.json"),
|
|
97278
|
+
join50(root, "opencode.json")
|
|
96538
97279
|
];
|
|
96539
97280
|
}
|
|
96540
97281
|
function vscodeUserDir(home, env2) {
|
|
96541
|
-
if (process.platform === "win32") return
|
|
96542
|
-
if (process.platform === "darwin") return
|
|
96543
|
-
return
|
|
97282
|
+
if (process.platform === "win32") return join50(env2["APPDATA"] ?? join50(home, "AppData", "Roaming"), "Code", "User");
|
|
97283
|
+
if (process.platform === "darwin") return join50(home, "Library", "Application Support", "Code", "User");
|
|
97284
|
+
return join50(env2["XDG_CONFIG_HOME"] ?? join50(home, ".config"), "Code", "User");
|
|
96544
97285
|
}
|
|
96545
97286
|
function scanHarnessConfigs(paths, read2 = readBounded) {
|
|
96546
97287
|
const findings = [];
|
|
@@ -96555,9 +97296,9 @@ function scanHarnessConfigs(paths, read2 = readBounded) {
|
|
|
96555
97296
|
}
|
|
96556
97297
|
function readBounded(path3) {
|
|
96557
97298
|
try {
|
|
96558
|
-
const stat4 =
|
|
97299
|
+
const stat4 = statSync13(path3);
|
|
96559
97300
|
if (!stat4.isFile() || stat4.size > MAX_SCAN_BYTES) return null;
|
|
96560
|
-
return
|
|
97301
|
+
return readFileSync42(path3, "utf8");
|
|
96561
97302
|
} catch {
|
|
96562
97303
|
return null;
|
|
96563
97304
|
}
|
|
@@ -96582,14 +97323,14 @@ function credentialHygieneCheck(scan2) {
|
|
|
96582
97323
|
|
|
96583
97324
|
// src/codex-doctor.ts
|
|
96584
97325
|
import { spawn as spawn4 } from "node:child_process";
|
|
96585
|
-
import { readFileSync as
|
|
96586
|
-
import { join as
|
|
97326
|
+
import { readFileSync as readFileSync44, statSync as statSync14 } from "node:fs";
|
|
97327
|
+
import { join as join52 } from "node:path";
|
|
96587
97328
|
import { createInterface } from "node:readline";
|
|
96588
97329
|
|
|
96589
97330
|
// src/codex-hooks.ts
|
|
96590
|
-
import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as
|
|
97331
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync43, renameSync as renameSync8, unlinkSync as unlinkSync5, writeFileSync as writeFileSync31 } from "node:fs";
|
|
96591
97332
|
import { homedir as homedir9 } from "node:os";
|
|
96592
|
-
import { join as
|
|
97333
|
+
import { join as join51 } from "node:path";
|
|
96593
97334
|
|
|
96594
97335
|
// src/hook-commands.ts
|
|
96595
97336
|
function hookCurlCommand(port, path3 = "/api/hook") {
|
|
@@ -96793,34 +97534,34 @@ function buildCodexRelaySource(workspaceRoot) {
|
|
|
96793
97534
|
init_checkout_root();
|
|
96794
97535
|
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.";
|
|
96795
97536
|
function writeRelay(file2, source) {
|
|
96796
|
-
if (existsSync36(file2) &&
|
|
97537
|
+
if (existsSync36(file2) && readFileSync43(file2, "utf8") === source) return;
|
|
96797
97538
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
96798
97539
|
try {
|
|
96799
|
-
|
|
96800
|
-
|
|
97540
|
+
writeFileSync31(temp, source, { encoding: "utf8", mode: 384 });
|
|
97541
|
+
renameSync8(temp, file2);
|
|
96801
97542
|
} finally {
|
|
96802
97543
|
if (existsSync36(temp)) unlinkSync5(temp);
|
|
96803
97544
|
}
|
|
96804
97545
|
}
|
|
96805
97546
|
function refreshCodexRelay(root) {
|
|
96806
|
-
const config2 =
|
|
97547
|
+
const config2 = join51(root, ".codex", "config.toml");
|
|
96807
97548
|
if (!existsSync36(config2)) return "absent";
|
|
96808
|
-
const existing =
|
|
97549
|
+
const existing = readFileSync43(config2, "utf8");
|
|
96809
97550
|
if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
|
|
96810
97551
|
replaceCodexHooks(existing, "");
|
|
96811
|
-
const relay =
|
|
96812
|
-
const prior = existsSync36(relay) ?
|
|
97552
|
+
const relay = join51(root, ".codex", "hooks", "errata-relay.mjs");
|
|
97553
|
+
const prior = existsSync36(relay) ? readFileSync43(relay, "utf8") : "";
|
|
96813
97554
|
if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
|
|
96814
97555
|
throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
|
|
96815
97556
|
}
|
|
96816
97557
|
const source = buildCodexRelaySource(checkoutRootOf(root));
|
|
96817
97558
|
if (prior === source) return "current";
|
|
96818
|
-
mkdirSync10(
|
|
97559
|
+
mkdirSync10(join51(root, ".codex", "hooks"), { recursive: true });
|
|
96819
97560
|
writeRelay(relay, source);
|
|
96820
97561
|
return "updated";
|
|
96821
97562
|
}
|
|
96822
|
-
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] ||
|
|
96823
|
-
return existsSync36(
|
|
97563
|
+
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join51(homedir9(), ".codex")) {
|
|
97564
|
+
return existsSync36(join51(root, ".codex")) || existsSync36(codexHome);
|
|
96824
97565
|
}
|
|
96825
97566
|
function replaceCodexHooks(existing, block) {
|
|
96826
97567
|
const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
|
|
@@ -96836,14 +97577,14 @@ function replaceCodexHooks(existing, block) {
|
|
|
96836
97577
|
return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
|
|
96837
97578
|
}
|
|
96838
97579
|
function writeCodexHooks(root, port, nodePath = process.execPath) {
|
|
96839
|
-
const dir =
|
|
96840
|
-
const file2 =
|
|
96841
|
-
const relay =
|
|
97580
|
+
const dir = join51(root, ".codex");
|
|
97581
|
+
const file2 = join51(dir, "config.toml");
|
|
97582
|
+
const relay = join51(dir, "hooks", "errata-relay.mjs");
|
|
96842
97583
|
const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
|
|
96843
|
-
const final = replaceCodexHooks(existsSync36(file2) ?
|
|
96844
|
-
mkdirSync10(
|
|
97584
|
+
const final = replaceCodexHooks(existsSync36(file2) ? readFileSync43(file2, "utf8") : "", block);
|
|
97585
|
+
mkdirSync10(join51(dir, "hooks"), { recursive: true });
|
|
96845
97586
|
writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
|
|
96846
|
-
if (!existsSync36(file2) ||
|
|
97587
|
+
if (!existsSync36(file2) || readFileSync43(file2, "utf8") !== final) writeFileSync31(file2, final, "utf8");
|
|
96847
97588
|
return file2;
|
|
96848
97589
|
}
|
|
96849
97590
|
|
|
@@ -96852,7 +97593,7 @@ init_checkout_root();
|
|
|
96852
97593
|
function inspectCodexRelay(cwd) {
|
|
96853
97594
|
const root = nearestGitRoot(cwd) ?? cwd;
|
|
96854
97595
|
try {
|
|
96855
|
-
const source =
|
|
97596
|
+
const source = readFileSync44(join52(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
|
|
96856
97597
|
if (source === buildCodexRelaySource(checkoutRootOf(root))) {
|
|
96857
97598
|
return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
|
|
96858
97599
|
}
|
|
@@ -96863,8 +97604,8 @@ function inspectCodexRelay(cwd) {
|
|
|
96863
97604
|
function inspectCodexContext(cwd) {
|
|
96864
97605
|
const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
|
|
96865
97606
|
try {
|
|
96866
|
-
const file2 =
|
|
96867
|
-
if (
|
|
97607
|
+
const file2 = join52(root, ".errata", "context.md");
|
|
97608
|
+
if (statSync14(file2).size <= 128 * 1024 && readFileSync44(file2, "utf8").trim()) {
|
|
96868
97609
|
return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
|
|
96869
97610
|
}
|
|
96870
97611
|
} catch {
|
|
@@ -97041,11 +97782,11 @@ function consolidationGapMs(lastPassMs, policy) {
|
|
|
97041
97782
|
}
|
|
97042
97783
|
|
|
97043
97784
|
// src/codex-context-plugin.ts
|
|
97044
|
-
import { createHash as
|
|
97045
|
-
import { cpSync as cpSync2, existsSync as existsSync37, mkdirSync as mkdirSync11, readFileSync as
|
|
97785
|
+
import { createHash as createHash21 } from "node:crypto";
|
|
97786
|
+
import { cpSync as cpSync2, existsSync as existsSync37, mkdirSync as mkdirSync11, readFileSync as readFileSync45, renameSync as renameSync9, writeFileSync as writeFileSync32 } from "node:fs";
|
|
97046
97787
|
import { homedir as homedir10 } from "node:os";
|
|
97047
|
-
import { join as
|
|
97048
|
-
import { fileURLToPath as
|
|
97788
|
+
import { join as join53 } from "node:path";
|
|
97789
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
97049
97790
|
|
|
97050
97791
|
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
|
|
97051
97792
|
function getLineColFromPtr(string4, ptr) {
|
|
@@ -97127,7 +97868,7 @@ function skipVoid(str, ptr, banNewLines, banComments) {
|
|
|
97127
97868
|
}
|
|
97128
97869
|
return ptr;
|
|
97129
97870
|
}
|
|
97130
|
-
function skipUntil(str, ptr,
|
|
97871
|
+
function skipUntil(str, ptr, sep7, end, banNewLines = false) {
|
|
97131
97872
|
if (!end) {
|
|
97132
97873
|
ptr = indexOfNewline(str, ptr);
|
|
97133
97874
|
return ptr < 0 ? str.length : ptr;
|
|
@@ -97136,7 +97877,7 @@ function skipUntil(str, ptr, sep6, end, banNewLines = false) {
|
|
|
97136
97877
|
let c = str[i2];
|
|
97137
97878
|
if (c === "#") {
|
|
97138
97879
|
i2 = indexOfNewline(str, i2);
|
|
97139
|
-
} else if (c ===
|
|
97880
|
+
} else if (c === sep7) {
|
|
97140
97881
|
return i2 + 1;
|
|
97141
97882
|
} else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i2 + 1] === "\n")) {
|
|
97142
97883
|
return i2;
|
|
@@ -97742,23 +98483,23 @@ var NAME = "errata-context";
|
|
|
97742
98483
|
var PREFIX2 = `./.errata/plugins/${NAME}/`;
|
|
97743
98484
|
var object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
97744
98485
|
function readText(file2) {
|
|
97745
|
-
return existsSync37(file2) ?
|
|
98486
|
+
return existsSync37(file2) ? readFileSync45(file2, "utf8") : "";
|
|
97746
98487
|
}
|
|
97747
98488
|
function writeChanged(file2, content) {
|
|
97748
98489
|
if (readText(file2) === content) return;
|
|
97749
98490
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
97750
|
-
|
|
97751
|
-
|
|
98491
|
+
writeFileSync32(temp, content, "utf8");
|
|
98492
|
+
renameSync9(temp, file2);
|
|
97752
98493
|
}
|
|
97753
98494
|
function bundledContextPlugin() {
|
|
97754
|
-
const packaged =
|
|
97755
|
-
if (existsSync37(
|
|
97756
|
-
return
|
|
98495
|
+
const packaged = fileURLToPath3(new URL("./resources/context-plugin/", import.meta.url));
|
|
98496
|
+
if (existsSync37(join53(packaged, ".codex-plugin/plugin.json"))) return packaged;
|
|
98497
|
+
return fileURLToPath3(new URL("../dist/resources/context-plugin/", import.meta.url));
|
|
97757
98498
|
}
|
|
97758
98499
|
function refreshCodexContextPlugin(root) {
|
|
97759
|
-
const file2 =
|
|
98500
|
+
const file2 = join53(root, ".agents", "plugins", "marketplace.json");
|
|
97760
98501
|
if (!existsSync37(file2)) return false;
|
|
97761
|
-
const marketplace = JSON.parse(
|
|
98502
|
+
const marketplace = JSON.parse(readFileSync45(file2, "utf8"));
|
|
97762
98503
|
const entries = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
|
|
97763
98504
|
const entry = entries.map(object2).find((value) => value.name === NAME && String(object2(value.source).path).startsWith(PREFIX2));
|
|
97764
98505
|
if (!entry) return false;
|
|
@@ -97769,24 +98510,24 @@ function refreshCodexContextPlugin(root) {
|
|
|
97769
98510
|
function installCodexContextPlugin(root, options = {}) {
|
|
97770
98511
|
const bundle = options.bundle ?? bundledContextPlugin();
|
|
97771
98512
|
const manifest = JSON.parse(
|
|
97772
|
-
|
|
98513
|
+
readFileSync45(join53(bundle, ".codex-plugin/plugin.json"), "utf8")
|
|
97773
98514
|
);
|
|
97774
98515
|
if (manifest.name !== NAME || typeof manifest.version !== "string" || !/^[\w.-]+$/.test(manifest.version)) {
|
|
97775
98516
|
throw new Error("Invalid bundled Errata Context manifest.");
|
|
97776
98517
|
}
|
|
97777
|
-
const checksums =
|
|
98518
|
+
const checksums = readFileSync45(join53(bundle, "SHA256SUMS"), "utf8");
|
|
97778
98519
|
for (const line of checksums.trim().split("\n")) {
|
|
97779
98520
|
const match2 = /^([a-f0-9]{64}) ([\w./-]+)$/.exec(line);
|
|
97780
98521
|
if (!match2 || match2[2].startsWith("/") || match2[2].split("/").includes("..")) {
|
|
97781
98522
|
throw new Error("Invalid bundled Errata Context checksum manifest.");
|
|
97782
98523
|
}
|
|
97783
|
-
const actual =
|
|
98524
|
+
const actual = createHash21("sha256").update(readFileSync45(join53(bundle, match2[2]))).digest("hex");
|
|
97784
98525
|
if (actual !== match2[1])
|
|
97785
98526
|
throw new Error(`Bundled Errata Context checksum mismatch: ${match2[2]}`);
|
|
97786
98527
|
}
|
|
97787
|
-
const release = `${manifest.version}-${
|
|
97788
|
-
const plugin =
|
|
97789
|
-
const marketplaceFile =
|
|
98528
|
+
const release = `${manifest.version}-${createHash21("sha256").update(checksums).digest("hex").slice(0, 12)}`;
|
|
98529
|
+
const plugin = join53(root, ".errata", "plugins", NAME, release);
|
|
98530
|
+
const marketplaceFile = join53(root, ".agents", "plugins", "marketplace.json");
|
|
97790
98531
|
const priorMarketplace = readText(marketplaceFile);
|
|
97791
98532
|
const marketplace = priorMarketplace ? JSON.parse(priorMarketplace) : {
|
|
97792
98533
|
name: "errata-local",
|
|
@@ -97807,12 +98548,12 @@ function installCodexContextPlugin(root, options = {}) {
|
|
|
97807
98548
|
);
|
|
97808
98549
|
}
|
|
97809
98550
|
const key = `${NAME}@${marketplace.name}`;
|
|
97810
|
-
const configFile =
|
|
98551
|
+
const configFile = join53(root, ".codex", "config.toml");
|
|
97811
98552
|
const config2 = readText(configFile);
|
|
97812
98553
|
const parsed = parse4(config2);
|
|
97813
98554
|
const plugins = object2(parsed.plugins);
|
|
97814
|
-
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ??
|
|
97815
|
-
const globalPlugins = object2(parse4(readText(
|
|
98555
|
+
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join53(homedir10(), ".codex");
|
|
98556
|
+
const globalPlugins = object2(parse4(readText(join53(codexHome, "config.toml"))).plugins);
|
|
97816
98557
|
const disabledGlobally = Object.entries(globalPlugins).some(
|
|
97817
98558
|
([name2, value]) => (name2 === NAME || name2.startsWith(`${NAME}@`)) && object2(value).enabled === false
|
|
97818
98559
|
);
|
|
@@ -97836,13 +98577,13 @@ enabled = ${enabled}
|
|
|
97836
98577
|
mkdirSync11(plugin, { recursive: true });
|
|
97837
98578
|
cpSync2(bundle, plugin, { recursive: true });
|
|
97838
98579
|
writeChanged(
|
|
97839
|
-
|
|
98580
|
+
join53(plugin, ".mcp.json"),
|
|
97840
98581
|
JSON.stringify(
|
|
97841
98582
|
{
|
|
97842
98583
|
mcpServers: {
|
|
97843
98584
|
errata_context: {
|
|
97844
98585
|
command: options.nodePath ?? process.execPath,
|
|
97845
|
-
args: [
|
|
98586
|
+
args: [join53(plugin, "dist", "mcp-server.mjs")],
|
|
97846
98587
|
env: { ERRATA_WORKSPACE: root, ERRATA_CONTEXT_VERSION: manifest.version }
|
|
97847
98588
|
}
|
|
97848
98589
|
}
|
|
@@ -97851,8 +98592,8 @@ enabled = ${enabled}
|
|
|
97851
98592
|
2
|
|
97852
98593
|
) + "\n"
|
|
97853
98594
|
);
|
|
97854
|
-
mkdirSync11(
|
|
97855
|
-
mkdirSync11(
|
|
98595
|
+
mkdirSync11(join53(root, ".agents", "plugins"), { recursive: true });
|
|
98596
|
+
mkdirSync11(join53(root, ".codex"), { recursive: true });
|
|
97856
98597
|
writeChanged(marketplaceFile, JSON.stringify(marketplace, null, 2) + "\n");
|
|
97857
98598
|
writeChanged(configFile, nextConfig);
|
|
97858
98599
|
return { plugin, enabled, marketplace: marketplaceFile };
|
|
@@ -97860,15 +98601,15 @@ enabled = ${enabled}
|
|
|
97860
98601
|
|
|
97861
98602
|
// src/codex-hook-refresh.ts
|
|
97862
98603
|
init_checkout_root();
|
|
97863
|
-
import { existsSync as existsSync38, readdirSync as readdirSync14, readFileSync as
|
|
97864
|
-
import { dirname as
|
|
98604
|
+
import { existsSync as existsSync38, readdirSync as readdirSync14, readFileSync as readFileSync46 } from "node:fs";
|
|
98605
|
+
import { dirname as dirname18, join as join54, resolve as resolve8 } from "node:path";
|
|
97865
98606
|
init_registry();
|
|
97866
98607
|
function codexHookRoots(roots) {
|
|
97867
98608
|
const found = new Set(roots.map((root) => resolve8(root)));
|
|
97868
98609
|
for (const root of [...found]) {
|
|
97869
98610
|
const main2 = mainCheckoutOfWorktree(root) ?? root;
|
|
97870
98611
|
found.add(main2);
|
|
97871
|
-
const dir =
|
|
98612
|
+
const dir = join54(main2, ".git", "worktrees");
|
|
97872
98613
|
if (!existsSync38(dir)) continue;
|
|
97873
98614
|
let names;
|
|
97874
98615
|
try {
|
|
@@ -97878,7 +98619,7 @@ function codexHookRoots(roots) {
|
|
|
97878
98619
|
}
|
|
97879
98620
|
for (const name2 of names) {
|
|
97880
98621
|
try {
|
|
97881
|
-
const checkout =
|
|
98622
|
+
const checkout = dirname18(readFileSync46(join54(dir, name2, "gitdir"), "utf8").trim());
|
|
97882
98623
|
if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
|
|
97883
98624
|
} catch {
|
|
97884
98625
|
}
|
|
@@ -97900,50 +98641,50 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
|
|
|
97900
98641
|
}
|
|
97901
98642
|
|
|
97902
98643
|
// src/claude-mods.ts
|
|
97903
|
-
import { createHash as
|
|
97904
|
-
import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as
|
|
97905
|
-
import { delimiter as delimiter2, dirname as
|
|
97906
|
-
import { fileURLToPath as
|
|
98644
|
+
import { createHash as createHash22 } from "node:crypto";
|
|
98645
|
+
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";
|
|
98646
|
+
import { delimiter as delimiter2, dirname as dirname19, join as join55, relative as relative7, resolve as resolve9, sep as sep6 } from "node:path";
|
|
98647
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
97907
98648
|
var CLAUDE_PLUGIN_DIRS_ENV = "CLAUDE_CODE_PLUGIN_DIRS";
|
|
97908
98649
|
var HASH_FILE = ".errata-mod-hash";
|
|
97909
98650
|
function bundledClaudeModsDir() {
|
|
97910
98651
|
const rel = import.meta.url.endsWith(".mjs") ? "./resources/claude-mods/" : "../claude-mods/";
|
|
97911
|
-
return
|
|
98652
|
+
return fileURLToPath4(new URL(rel, import.meta.url));
|
|
97912
98653
|
}
|
|
97913
98654
|
function isEngineOwned(relPath) {
|
|
97914
|
-
const p = relPath.split(
|
|
98655
|
+
const p = relPath.split(sep6).join("/");
|
|
97915
98656
|
return p === ".claude-plugin/types" || p.startsWith(".claude-plugin/types/") || p === HASH_FILE;
|
|
97916
98657
|
}
|
|
97917
98658
|
function listFiles(root, dir = root) {
|
|
97918
98659
|
const out2 = [];
|
|
97919
98660
|
for (const name2 of readdirSync15(dir)) {
|
|
97920
|
-
const abs =
|
|
97921
|
-
if (isEngineOwned(
|
|
97922
|
-
if (
|
|
98661
|
+
const abs = join55(dir, name2);
|
|
98662
|
+
if (isEngineOwned(relative7(root, abs))) continue;
|
|
98663
|
+
if (statSync15(abs).isDirectory()) out2.push(...listFiles(root, abs));
|
|
97923
98664
|
else out2.push(abs);
|
|
97924
98665
|
}
|
|
97925
98666
|
return out2;
|
|
97926
98667
|
}
|
|
97927
98668
|
function modHash(dir) {
|
|
97928
|
-
const h =
|
|
98669
|
+
const h = createHash22("sha256");
|
|
97929
98670
|
for (const abs of listFiles(dir).sort()) {
|
|
97930
|
-
h.update(
|
|
98671
|
+
h.update(relative7(dir, abs).split(sep6).join("/"));
|
|
97931
98672
|
h.update("\0");
|
|
97932
|
-
h.update(
|
|
98673
|
+
h.update(readFileSync47(abs));
|
|
97933
98674
|
h.update("\0");
|
|
97934
98675
|
}
|
|
97935
98676
|
return h.digest("hex");
|
|
97936
98677
|
}
|
|
97937
98678
|
function bundledMods(bundleDir) {
|
|
97938
98679
|
if (!existsSync39(bundleDir)) return [];
|
|
97939
|
-
return readdirSync15(bundleDir).filter((name2) => existsSync39(
|
|
98680
|
+
return readdirSync15(bundleDir).filter((name2) => existsSync39(join55(bundleDir, name2, ".claude-plugin", "plugin.json")));
|
|
97940
98681
|
}
|
|
97941
98682
|
function sameDir(a, b) {
|
|
97942
98683
|
const norm = (p) => resolve9(p).replace(/[\\/]+$/, "").toLowerCase();
|
|
97943
98684
|
return norm(a) === norm(b);
|
|
97944
98685
|
}
|
|
97945
98686
|
function isUnder(path3, root) {
|
|
97946
|
-
const rel =
|
|
98687
|
+
const rel = relative7(resolve9(root), resolve9(path3));
|
|
97947
98688
|
return rel !== "" && !rel.startsWith("..") && !rel.includes(":");
|
|
97948
98689
|
}
|
|
97949
98690
|
function off(env2) {
|
|
@@ -97953,7 +98694,7 @@ function off(env2) {
|
|
|
97953
98694
|
function readSettings(path3) {
|
|
97954
98695
|
if (!existsSync39(path3)) return {};
|
|
97955
98696
|
try {
|
|
97956
|
-
const parsed = JSON.parse(
|
|
98697
|
+
const parsed = JSON.parse(readFileSync47(path3, "utf8"));
|
|
97957
98698
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
97958
98699
|
return parsed;
|
|
97959
98700
|
} catch {
|
|
@@ -97977,13 +98718,13 @@ function currentDirs(settings) {
|
|
|
97977
98718
|
return raw2.split(delimiter2).map((s) => s.trim()).filter(Boolean);
|
|
97978
98719
|
}
|
|
97979
98720
|
function writeSettings(path3, settings) {
|
|
97980
|
-
mkdirSync12(
|
|
97981
|
-
|
|
98721
|
+
mkdirSync12(dirname19(path3), { recursive: true });
|
|
98722
|
+
writeFileSync33(path3, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
97982
98723
|
}
|
|
97983
98724
|
function ensureClaudeMods(opts) {
|
|
97984
98725
|
const env2 = opts.env ?? process.env;
|
|
97985
98726
|
const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
|
|
97986
|
-
const modsRoot =
|
|
98727
|
+
const modsRoot = join55(opts.installRoot, "claude-mods");
|
|
97987
98728
|
if (off(env2)) {
|
|
97988
98729
|
const settings2 = readSettings(settingsPath);
|
|
97989
98730
|
if (!settings2) return { kind: "unreadable" };
|
|
@@ -98000,14 +98741,14 @@ function ensureClaudeMods(opts) {
|
|
|
98000
98741
|
let changed = false;
|
|
98001
98742
|
const installed = [];
|
|
98002
98743
|
for (const name2 of names) {
|
|
98003
|
-
const src =
|
|
98004
|
-
const dest =
|
|
98744
|
+
const src = join55(bundleDir, name2);
|
|
98745
|
+
const dest = join55(modsRoot, name2);
|
|
98005
98746
|
const hash2 = modHash(src);
|
|
98006
|
-
const hashFile =
|
|
98007
|
-
if (!existsSync39(hashFile) ||
|
|
98747
|
+
const hashFile = join55(dest, HASH_FILE);
|
|
98748
|
+
if (!existsSync39(hashFile) || readFileSync47(hashFile, "utf8") !== hash2) {
|
|
98008
98749
|
rmSync4(dest, { recursive: true, force: true });
|
|
98009
|
-
cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(
|
|
98010
|
-
|
|
98750
|
+
cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative7(src, p)) });
|
|
98751
|
+
writeFileSync33(hashFile, hash2, "utf8");
|
|
98011
98752
|
changed = true;
|
|
98012
98753
|
}
|
|
98013
98754
|
installed.push(dest);
|
|
@@ -98426,9 +99167,9 @@ function resolveHookPort(explicit) {
|
|
|
98426
99167
|
}
|
|
98427
99168
|
}
|
|
98428
99169
|
}
|
|
98429
|
-
const settingsPath =
|
|
99170
|
+
const settingsPath = join56(ROOT, ".claude", "settings.json");
|
|
98430
99171
|
try {
|
|
98431
|
-
if (existsSync40(settingsPath)) return installedHookPort(
|
|
99172
|
+
if (existsSync40(settingsPath)) return installedHookPort(readFileSync48(settingsPath, "utf8")) ?? 7891;
|
|
98432
99173
|
} catch {
|
|
98433
99174
|
}
|
|
98434
99175
|
return 7891;
|
|
@@ -98454,13 +99195,13 @@ async function cmdInit() {
|
|
|
98454
99195
|
console.log("");
|
|
98455
99196
|
console.log("installing harness hooks...");
|
|
98456
99197
|
const { existsSync: existsSync41 } = await import("node:fs");
|
|
98457
|
-
const { join:
|
|
99198
|
+
const { join: join57 } = await import("node:path");
|
|
98458
99199
|
try {
|
|
98459
99200
|
await installClaudeHooks(port);
|
|
98460
99201
|
} catch (err2) {
|
|
98461
99202
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
98462
99203
|
}
|
|
98463
|
-
if (existsSync41(
|
|
99204
|
+
if (existsSync41(join57(ROOT, ".cursor"))) {
|
|
98464
99205
|
try {
|
|
98465
99206
|
await installCursorMcpConfig();
|
|
98466
99207
|
} catch (err2) {
|
|
@@ -99683,7 +100424,7 @@ async function cmdReview() {
|
|
|
99683
100424
|
console.log("(review queue empty)");
|
|
99684
100425
|
return;
|
|
99685
100426
|
}
|
|
99686
|
-
const queue = JSON.parse(
|
|
100427
|
+
const queue = JSON.parse(readFileSync48(paths.reviewQueue, "utf8"));
|
|
99687
100428
|
if (queue.length === 0) {
|
|
99688
100429
|
console.log("(review queue empty)");
|
|
99689
100430
|
return;
|
|
@@ -100422,7 +101163,7 @@ async function gatherReportData(generatedAt) {
|
|
|
100422
101163
|
};
|
|
100423
101164
|
}
|
|
100424
101165
|
async function cmdReport(args2) {
|
|
100425
|
-
const { mkdirSync: mkdirSync13, writeFileSync:
|
|
101166
|
+
const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
100426
101167
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
100427
101168
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
100428
101169
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -100435,8 +101176,8 @@ async function cmdReport(args2) {
|
|
|
100435
101176
|
const outDir = workspacePaths(ROOT).configDir;
|
|
100436
101177
|
mkdirSync13(outDir, { recursive: true });
|
|
100437
101178
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
100438
|
-
for (const f of files)
|
|
100439
|
-
const indexPath =
|
|
101179
|
+
for (const f of files) writeFileSync34(join56(outDir, f.name), f.html, "utf8");
|
|
101180
|
+
const indexPath = join56(outDir, "report.html");
|
|
100440
101181
|
console.log(`report \u2192 ${indexPath}`);
|
|
100441
101182
|
console.log(
|
|
100442
101183
|
` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
|
|
@@ -100492,7 +101233,7 @@ function spawnDaemonDetached(options = {}) {
|
|
|
100492
101233
|
try {
|
|
100493
101234
|
const logPath = daemonLogPath();
|
|
100494
101235
|
try {
|
|
100495
|
-
if (
|
|
101236
|
+
if (statSync16(logPath).size > 5 * 1024 * 1024) renameSync10(logPath, `${logPath}.1`);
|
|
100496
101237
|
} catch {
|
|
100497
101238
|
}
|
|
100498
101239
|
out2 = openSync3(logPath, "a");
|
|
@@ -100561,24 +101302,24 @@ async function cmdInstallHooks(args2) {
|
|
|
100561
101302
|
}
|
|
100562
101303
|
}
|
|
100563
101304
|
async function installOpencodePlugin(port) {
|
|
100564
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100565
|
-
const { join:
|
|
100566
|
-
const dir =
|
|
101305
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
101306
|
+
const { join: join57 } = await import("node:path");
|
|
101307
|
+
const dir = join57(ROOT, ".opencode", "plugin");
|
|
100567
101308
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100568
|
-
const file2 =
|
|
101309
|
+
const file2 = join57(dir, "inerrata.js");
|
|
100569
101310
|
if (existsSync41(file2)) {
|
|
100570
|
-
const head2 =
|
|
101311
|
+
const head2 = readFileSync49(file2, "utf8").split("\n")[0] ?? "";
|
|
100571
101312
|
if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
|
|
100572
101313
|
console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
|
|
100573
101314
|
process.exit(2);
|
|
100574
101315
|
}
|
|
100575
101316
|
}
|
|
100576
|
-
|
|
100577
|
-
const cfgFile =
|
|
101317
|
+
writeFileSync34(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
|
|
101318
|
+
const cfgFile = join57(ROOT, "opencode.json");
|
|
100578
101319
|
let cfg = { $schema: "https://opencode.ai/config.json" };
|
|
100579
101320
|
if (existsSync41(cfgFile)) {
|
|
100580
101321
|
try {
|
|
100581
|
-
cfg = JSON.parse(
|
|
101322
|
+
cfg = JSON.parse(readFileSync49(cfgFile, "utf8"));
|
|
100582
101323
|
} catch {
|
|
100583
101324
|
console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
|
|
100584
101325
|
process.exit(2);
|
|
@@ -100589,7 +101330,7 @@ async function installOpencodePlugin(port) {
|
|
|
100589
101330
|
if (!hadErrata) {
|
|
100590
101331
|
const inv = errataMcpInvocation();
|
|
100591
101332
|
cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
|
|
100592
|
-
|
|
101333
|
+
writeFileSync34(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
100593
101334
|
}
|
|
100594
101335
|
console.log(`installed OpenCode plugin \u2192 ${file2}`);
|
|
100595
101336
|
if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
|
|
@@ -100624,15 +101365,15 @@ function installClaudeMods() {
|
|
|
100624
101365
|
}
|
|
100625
101366
|
}
|
|
100626
101367
|
async function installClaudeHooks(port) {
|
|
100627
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100628
|
-
const { join:
|
|
100629
|
-
const dir =
|
|
101368
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
101369
|
+
const { join: join57 } = await import("node:path");
|
|
101370
|
+
const dir = join57(ROOT, ".claude");
|
|
100630
101371
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100631
|
-
const file2 =
|
|
101372
|
+
const file2 = join57(dir, "settings.json");
|
|
100632
101373
|
let settings = {};
|
|
100633
101374
|
if (existsSync41(file2)) {
|
|
100634
101375
|
try {
|
|
100635
|
-
settings = JSON.parse(
|
|
101376
|
+
settings = JSON.parse(readFileSync49(file2, "utf8"));
|
|
100636
101377
|
} catch {
|
|
100637
101378
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
100638
101379
|
process.exit(2);
|
|
@@ -100681,12 +101422,12 @@ async function installClaudeHooks(port) {
|
|
|
100681
101422
|
list.push({ hooks: [{ type: "command", command: injectCmd }] });
|
|
100682
101423
|
}
|
|
100683
101424
|
removeProjectStatusLine(settings);
|
|
100684
|
-
|
|
101425
|
+
writeFileSync34(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
100685
101426
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
100686
101427
|
console.log(` ${ensureStatusLine(port)}`);
|
|
100687
101428
|
console.log(` ${installClaudeMods().line}`);
|
|
100688
101429
|
await installClaudeMcpConfig();
|
|
100689
|
-
const claudeMd =
|
|
101430
|
+
const claudeMd = join57(ROOT, "CLAUDE.md");
|
|
100690
101431
|
const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
|
|
100691
101432
|
if (recall.kind === "collision") {
|
|
100692
101433
|
console.warn(
|
|
@@ -100698,15 +101439,15 @@ async function installClaudeHooks(port) {
|
|
|
100698
101439
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
100699
101440
|
}
|
|
100700
101441
|
async function installClaudeMcpConfig() {
|
|
100701
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100702
|
-
const { join:
|
|
100703
|
-
const file2 =
|
|
100704
|
-
const dir =
|
|
101442
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
101443
|
+
const { join: join57, dirname: dirname20 } = await import("node:path");
|
|
101444
|
+
const file2 = join57(ROOT, ".mcp.json");
|
|
101445
|
+
const dir = dirname20(file2);
|
|
100705
101446
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100706
101447
|
let cfg = {};
|
|
100707
101448
|
if (existsSync41(file2)) {
|
|
100708
101449
|
try {
|
|
100709
|
-
cfg = JSON.parse(
|
|
101450
|
+
cfg = JSON.parse(readFileSync49(file2, "utf8"));
|
|
100710
101451
|
} catch {
|
|
100711
101452
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
100712
101453
|
process.exit(2);
|
|
@@ -100714,21 +101455,21 @@ async function installClaudeMcpConfig() {
|
|
|
100714
101455
|
}
|
|
100715
101456
|
cfg.mcpServers ??= {};
|
|
100716
101457
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
100717
|
-
|
|
101458
|
+
writeFileSync34(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
100718
101459
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
100719
101460
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
100720
101461
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
100721
101462
|
}
|
|
100722
101463
|
async function installCursorMcpConfig() {
|
|
100723
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100724
|
-
const { join:
|
|
100725
|
-
const dir =
|
|
101464
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
101465
|
+
const { join: join57 } = await import("node:path");
|
|
101466
|
+
const dir = join57(ROOT, ".cursor");
|
|
100726
101467
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100727
|
-
const file2 =
|
|
101468
|
+
const file2 = join57(dir, "mcp.json");
|
|
100728
101469
|
let cfg = {};
|
|
100729
101470
|
if (existsSync41(file2)) {
|
|
100730
101471
|
try {
|
|
100731
|
-
cfg = JSON.parse(
|
|
101472
|
+
cfg = JSON.parse(readFileSync49(file2, "utf8"));
|
|
100732
101473
|
} catch {
|
|
100733
101474
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
100734
101475
|
process.exit(2);
|
|
@@ -100736,7 +101477,7 @@ async function installCursorMcpConfig() {
|
|
|
100736
101477
|
}
|
|
100737
101478
|
cfg.mcpServers ??= {};
|
|
100738
101479
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
100739
|
-
|
|
101480
|
+
writeFileSync34(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
100740
101481
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
100741
101482
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
100742
101483
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -100747,7 +101488,7 @@ async function installCodexHooks(port) {
|
|
|
100747
101488
|
const gitRoot = nearestGitRoot(process.cwd());
|
|
100748
101489
|
const hookRoot = gitRoot && mainCheckoutOfWorktree(gitRoot) ? gitRoot : ROOT;
|
|
100749
101490
|
const file2 = writeCodexHooks(hookRoot, port);
|
|
100750
|
-
const instructions = writeManagedBlock(
|
|
101491
|
+
const instructions = writeManagedBlock(join56(hookRoot, "AGENTS.md"), {
|
|
100751
101492
|
body: AGENTS_POINTER_BODY,
|
|
100752
101493
|
stable: true
|
|
100753
101494
|
});
|
|
@@ -101193,9 +101934,9 @@ async function cmdDash(args2) {
|
|
|
101193
101934
|
await yieldToLoop2();
|
|
101194
101935
|
try {
|
|
101195
101936
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
|
|
101196
|
-
atCommit: readGitRefState(
|
|
101937
|
+
atCommit: readGitRefState(join56(r.root, ".git")).sha ?? void 0
|
|
101197
101938
|
});
|
|
101198
|
-
const res = bleedRules(
|
|
101939
|
+
const res = bleedRules(join56(r.root, ".claude", "rules"), items);
|
|
101199
101940
|
if (res.written || res.pruned) {
|
|
101200
101941
|
console.log(
|
|
101201
101942
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|