@inerrata-corporation/errata 2.0.22-dev.4430 → 2.0.22-dev.4530
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/consolidate-worker.mjs +155 -4
- package/errata.mjs +1244 -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.4530" : "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,38 @@ 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 = { parents: new Bounded(4), dependencies: new Bounded(8), trees: new Bounded(4), symbols: new Bounded(4e3), diffs: new Bounded(2e3) };
|
|
92303
|
+
revisionCaches.set(git3, caches);
|
|
92304
|
+
}
|
|
92305
|
+
return caches;
|
|
92306
|
+
}
|
|
92307
|
+
var REVISION_DIFF_TOKENS = 4e3;
|
|
92308
|
+
var REVISION_RAW_DIFF_CHARS = REVISION_DIFF_TOKENS * 4 * 4;
|
|
91851
92309
|
async function syncHistoryRevision(opts) {
|
|
91852
92310
|
const current = inFlight.get(opts.root);
|
|
91853
92311
|
if (current) return current;
|
|
@@ -91855,12 +92313,13 @@ async function syncHistoryRevision(opts) {
|
|
|
91855
92313
|
const started2 = Date.now();
|
|
91856
92314
|
let changed = 0, remaining = false;
|
|
91857
92315
|
const pages = Math.min(20, Math.max(1, opts.maxPages ?? 10));
|
|
92316
|
+
const resolve10 = opts.profile.projectId ? reverseSymbolResolver({ store: opts.store, salt: opts.salt, projectId: opts.profile.projectId }) : async () => null;
|
|
91858
92317
|
for (let i2 = 0; i2 < pages; i2++) {
|
|
91859
|
-
const result = await syncHistoryRevisionPage(opts);
|
|
92318
|
+
const result = await syncHistoryRevisionPage(opts, resolve10);
|
|
91860
92319
|
changed += result.changed;
|
|
91861
92320
|
remaining = result.remaining;
|
|
91862
|
-
if (!remaining || Date.now() - started2 >= (opts.budgetMs ?? 45e3)) break;
|
|
91863
|
-
await new Promise((
|
|
92321
|
+
if (!remaining || result.nextBeat || Date.now() - started2 >= (opts.budgetMs ?? 45e3)) break;
|
|
92322
|
+
await new Promise((resolve11) => setImmediate(resolve11));
|
|
91864
92323
|
}
|
|
91865
92324
|
return { changed, remaining };
|
|
91866
92325
|
})();
|
|
@@ -91871,78 +92330,147 @@ async function syncHistoryRevision(opts) {
|
|
|
91871
92330
|
if (inFlight.get(opts.root) === work) inFlight.delete(opts.root);
|
|
91872
92331
|
}
|
|
91873
92332
|
}
|
|
91874
|
-
async function syncHistoryRevisionPage(opts) {
|
|
92333
|
+
async function syncHistoryRevisionPage(opts, resolve10) {
|
|
91875
92334
|
const { root, profile, store, cloud, salt } = opts;
|
|
91876
92335
|
if (!profile.projectId) return { changed: 0, remaining: false };
|
|
91877
92336
|
const projectId = profile.projectId;
|
|
91878
92337
|
const git3 = opts.git ?? (async (args2) => (await exec2("git", ["-C", root, ...args2], { windowsHide: true, maxBuffer: 8 * 1024 * 1024 })).stdout);
|
|
92338
|
+
const caches = cachesFor(opts.git ?? DEFAULT_GIT);
|
|
92339
|
+
const ignoreKey = createHash19("sha256").update(JSON.stringify(profile.ignoreExtra ?? [])).update(readFileSafe(join43(root, ".errataignore"))).digest("hex").slice(0, 16);
|
|
91879
92340
|
const atCommit = (await git3(["rev-parse", "--verify", "HEAD"])).trim();
|
|
91880
92341
|
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(atCommit)) throw new Error("history revision is not a full Git object id");
|
|
91881
92342
|
const oldCursor = profile.historyRevisionCursor;
|
|
91882
|
-
const
|
|
91883
|
-
if (
|
|
91884
|
-
|
|
91885
|
-
|
|
91886
|
-
|
|
92343
|
+
const save = () => (opts.save ?? ((p) => saveProfile(root, p)))(profile);
|
|
92344
|
+
if (oldCursor && oldCursor.ignoreKey !== ignoreKey && oldCursor.reprove !== ignoreKey) {
|
|
92345
|
+
profile.historyRevisionCursor = { ...oldCursor, atCommit, complete: false, after: void 0, reprove: ignoreKey, updatedAt: Date.now() };
|
|
92346
|
+
delete profile.historyRevisionCursor.after;
|
|
92347
|
+
save();
|
|
92348
|
+
}
|
|
92349
|
+
const cursor = profile.historyRevisionCursor;
|
|
92350
|
+
const head2 = cursor?.head ?? cursor?.atCommit;
|
|
92351
|
+
if (cursor && head2 && head2 !== atCommit && cloud.carryHistory && !carryRefused.has(root)) {
|
|
92352
|
+
const range = `${root}|${head2}|${atCommit}`;
|
|
92353
|
+
try {
|
|
92354
|
+
const carry = await carryRequest({
|
|
92355
|
+
git: git3,
|
|
92356
|
+
caches,
|
|
92357
|
+
root,
|
|
92358
|
+
salt,
|
|
92359
|
+
projectId,
|
|
92360
|
+
providers: defaultProviders(),
|
|
92361
|
+
from: head2,
|
|
92362
|
+
at: atCommit,
|
|
92363
|
+
rulesChanged: cursor.ignoreKey !== ignoreKey
|
|
92364
|
+
});
|
|
92365
|
+
await cloud.carryHistory(projectId, carry);
|
|
92366
|
+
carryFailures.delete(range);
|
|
92367
|
+
} catch (err2) {
|
|
92368
|
+
if (err2.status === 404) {
|
|
92369
|
+
carryRefused.add(root);
|
|
92370
|
+
console.warn(`[errata] the cloud predates history carry; every new commit re-proves all history verdicts for ${profile.name}`);
|
|
92371
|
+
} else {
|
|
92372
|
+
const failures = (carryFailures.get(range) ?? 0) + 1;
|
|
92373
|
+
carryFailures.set(range, failures);
|
|
92374
|
+
console.warn(`[errata] history carry ${head2.slice(0, 12)}..${atCommit.slice(0, 12)} failed (${failures}/${CARRY_ATTEMPTS})${failures >= CARRY_ATTEMPTS ? "; re-proving this commit instead" : ""}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
92375
|
+
if (failures < CARRY_ATTEMPTS) return { changed: 0, remaining: true, nextBeat: true };
|
|
92376
|
+
carryFailures.delete(range);
|
|
92377
|
+
}
|
|
92378
|
+
}
|
|
92379
|
+
profile.historyRevisionCursor = { ...cursor, head: atCommit };
|
|
92380
|
+
save();
|
|
92381
|
+
}
|
|
92382
|
+
const current = profile.historyRevisionCursor;
|
|
92383
|
+
const reproving = current?.reprove === ignoreKey;
|
|
92384
|
+
const same = current?.atCommit === atCommit;
|
|
92385
|
+
if (same && current.complete && Date.now() - current.updatedAt < 60 * 6e4) return { changed: 0, remaining: false };
|
|
92386
|
+
const after = current && !current.complete ? current.after : void 0;
|
|
92387
|
+
const sweepCommit = after ? current.atCommit : atCommit;
|
|
92388
|
+
const page = await cloud.getHistoryOccurrences(projectId, atCommit, after, { pendingOnly: !reproving });
|
|
91887
92389
|
if (!Array.isArray(page.occurrences) || page.occurrences.length > 50 || page.occurrences.some((o, i2) => o.occurrenceId <= (page.occurrences[i2 - 1]?.occurrenceId ?? after ?? "")) || page.cursor !== null && page.cursor !== page.occurrences.at(-1)?.occurrenceId) throw new Error("invalid history occurrence page");
|
|
91888
|
-
const
|
|
91889
|
-
|
|
91890
|
-
|
|
91891
|
-
|
|
91892
|
-
|
|
92390
|
+
const toPost = page.occurrences.filter((o) => !settledHistoryReceipt(o.quality["reconciliationEvidence"]) || reproving && o.quality["historicalAnchors"]?.length);
|
|
92391
|
+
let parents = [];
|
|
92392
|
+
if (toPost.length) {
|
|
92393
|
+
const key = `${root}|${atCommit}`;
|
|
92394
|
+
parents = caches.parents.get(key) ?? (await git3(["rev-list", "--parents", "--max-count=8192", atCommit])).trim().split("\n").filter(Boolean).map((row) => {
|
|
92395
|
+
const [commit, ...parents2] = row.trim().split(/\s+/);
|
|
92396
|
+
return { commit, parents: parents2 };
|
|
92397
|
+
});
|
|
92398
|
+
caches.parents.set(key, parents);
|
|
92399
|
+
}
|
|
91893
92400
|
const ignore2 = loadRepoIgnore(root, profile.ignoreExtra ?? []);
|
|
91894
92401
|
const providers = defaultProviders();
|
|
91895
|
-
const parsedFiles = /* @__PURE__ */ new Map();
|
|
91896
92402
|
const observations = [];
|
|
91897
|
-
const contexts =
|
|
92403
|
+
const contexts = toPost.map((o) => HistoryDependencyContextSchema.safeParse(o.quality["dependencyContext"]));
|
|
91898
92404
|
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
|
-
|
|
92405
|
+
let currentDependencies;
|
|
92406
|
+
if (manifestIds.size) {
|
|
92407
|
+
const key = `${root}|${atCommit}|${ignoreKey}|${[...manifestIds].sort().join(",")}`;
|
|
92408
|
+
let snapshot = caches.dependencies.get(key);
|
|
92409
|
+
if (!snapshot) {
|
|
92410
|
+
snapshot = readHistoryDependencySnapshot({
|
|
92411
|
+
root,
|
|
92412
|
+
commit: atCommit,
|
|
92413
|
+
side: "after",
|
|
92414
|
+
manifestIds,
|
|
92415
|
+
git: git3,
|
|
92416
|
+
allowPath: (p) => pathAllowedByFloor(p) && !isPathBlocked(ignore2, p)
|
|
92417
|
+
});
|
|
92418
|
+
caches.dependencies.set(key, snapshot);
|
|
92419
|
+
snapshot.catch(() => caches.dependencies.delete(key));
|
|
92420
|
+
}
|
|
92421
|
+
currentDependencies = await snapshot;
|
|
92422
|
+
}
|
|
92423
|
+
const treeKey = `${root}|${atCommit}`;
|
|
92424
|
+
let tree = caches.trees.get(treeKey);
|
|
92425
|
+
if (!tree && toPost.length) {
|
|
92426
|
+
tree = git3(["ls-tree", "-r", "-z", "--full-tree", atCommit]).then((out2) => new Map(out2.split("\0").flatMap((row) => {
|
|
92427
|
+
const tab = row.indexOf(" "), [, type, blob] = row.slice(0, tab).split(" ");
|
|
92428
|
+
return tab > 0 && type === "blob" && blob ? [[row.slice(tab + 1), blob]] : [];
|
|
92429
|
+
})));
|
|
92430
|
+
caches.trees.set(treeKey, tree);
|
|
92431
|
+
tree.catch(() => caches.trees.delete(treeKey));
|
|
92432
|
+
}
|
|
92433
|
+
const blobs = await (tree ?? Promise.resolve(/* @__PURE__ */ new Map())).catch(() => /* @__PURE__ */ new Map());
|
|
92434
|
+
const fileId = (path3) => blobs.get(path3) ?? `commit:${atCommit}`;
|
|
92435
|
+
for (const occurrence of toPost) {
|
|
91908
92436
|
const anchors = occurrence.quality["historicalAnchors"];
|
|
91909
92437
|
const paths = /* @__PURE__ */ new Set(), symbols = [];
|
|
92438
|
+
let partial2 = false;
|
|
91910
92439
|
for (const anchor of anchors ?? []) {
|
|
91911
|
-
const localId =
|
|
92440
|
+
const localId = await resolve10(anchor.symbolId), local = localId ? store.getNode(localId) : null;
|
|
91912
92441
|
const path3 = local?.attrs["relPath"];
|
|
91913
92442
|
if (typeof path3 !== "string" || !pathAllowedByFloor(path3) || isPathBlocked(ignore2, path3) || /[\r\n]/.test(path3)) continue;
|
|
91914
92443
|
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);
|
|
92444
|
+
const hashes = await fileSymbols({ caches, providers, root, salt, projectId }, path3, fileId(path3), () => git3(["show", `${atCommit}:${path3}`]));
|
|
92445
|
+
if (!hashes) partial2 = true;
|
|
92446
|
+
const bodyHash = hashes?.get(anchor.symbolId);
|
|
91929
92447
|
if (bodyHash) symbols.push({ symbolId: anchor.symbolId, bodyHash });
|
|
91930
92448
|
}
|
|
91931
92449
|
const source = occurrenceSourceCommit(occurrence);
|
|
91932
92450
|
let diff;
|
|
91933
92451
|
if (source && source !== atCommit && paths.size) {
|
|
91934
|
-
const
|
|
91935
|
-
|
|
91936
|
-
|
|
91937
|
-
|
|
91938
|
-
|
|
91939
|
-
|
|
91940
|
-
|
|
91941
|
-
|
|
91942
|
-
|
|
91943
|
-
|
|
91944
|
-
|
|
91945
|
-
|
|
92452
|
+
const diffKey = `${root}|${ignoreKey}|${source}|${[...paths].sort().map((path3) => `${path3}\0${fileId(path3)}`).join("\0")}`;
|
|
92453
|
+
if (caches.diffs.has(diffKey)) diff = caches.diffs.get(diffKey);
|
|
92454
|
+
else {
|
|
92455
|
+
const bundle = await buildUnitBundle(
|
|
92456
|
+
root,
|
|
92457
|
+
{
|
|
92458
|
+
sha: atCommit,
|
|
92459
|
+
parents: [source],
|
|
92460
|
+
isMerge: true,
|
|
92461
|
+
index: 0,
|
|
92462
|
+
subIndex: 0,
|
|
92463
|
+
subject: "",
|
|
92464
|
+
body: "",
|
|
92465
|
+
authorDate: "",
|
|
92466
|
+
files: [...paths].map((path3) => ({ path: path3, adds: 1, dels: 1, binary: false }))
|
|
92467
|
+
},
|
|
92468
|
+
{ maxTokens: REVISION_DIFF_TOKENS, maxRawDiffChars: REVISION_RAW_DIFF_CHARS, ignorePatterns: profile.ignoreExtra ?? [] }
|
|
92469
|
+
).catch(() => null);
|
|
92470
|
+
if (bundle && !bundle.truncated) diff = bundle.diff;
|
|
92471
|
+
if (bundle) caches.diffs.set(diffKey, diff);
|
|
92472
|
+
else partial2 = true;
|
|
92473
|
+
}
|
|
91946
92474
|
}
|
|
91947
92475
|
const old = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
|
|
91948
92476
|
const dependencyContext = old.success ? {
|
|
@@ -91950,16 +92478,24 @@ async function syncHistoryRevisionPage(opts) {
|
|
|
91950
92478
|
complete: old.data.dependencies.length === 0 || currentDependencies?.complete === true,
|
|
91951
92479
|
dependencies: currentDependencies?.dependencies.filter((d) => old.data.dependencies.some((o) => o.packageId === d.packageId && o.manifestId === d.manifestId)) ?? []
|
|
91952
92480
|
} : void 0;
|
|
92481
|
+
if (partial2) continue;
|
|
91953
92482
|
observations.push({ occurrenceId: occurrence.occurrenceId, symbols, ...diff ? { diff } : {}, ...dependencyContext ? { dependencyContext } : {} });
|
|
91954
92483
|
}
|
|
91955
|
-
const response =
|
|
91956
|
-
if (response.atCommit !== atCommit || response.receipts.length !==
|
|
92484
|
+
const response = observations.length ? await cloud.reconcileHistory(projectId, { atCommit, parents, observations }) : { atCommit, receipts: [] };
|
|
92485
|
+
if (response.atCommit !== atCommit || response.receipts.length !== observations.length || new Set(response.receipts.map((r) => r.occurrenceId)).size !== response.receipts.length || response.receipts.some((r) => r.atCommit !== atCommit || !observations.some((o) => o.occurrenceId === r.occurrenceId))) throw new Error("incomplete history reconciliation response");
|
|
92486
|
+
const receipts = new Map(response.receipts.map((r) => [r.occurrenceId, r]));
|
|
92487
|
+
for (const o of page.occurrences) {
|
|
92488
|
+
if (!receipts.has(o.occurrenceId) && settledHistoryReceipt(o.quality["reconciliationEvidence"])) {
|
|
92489
|
+
receipts.set(o.occurrenceId, { verdict: o.quality["applicability"], evidence: o.quality["reconciliationEvidence"] });
|
|
92490
|
+
}
|
|
92491
|
+
}
|
|
91957
92492
|
const headChanged = (await git3(["rev-parse", "--verify", "HEAD"])).trim() !== atCommit;
|
|
91958
92493
|
let changed = 0;
|
|
91959
92494
|
for (const occurrence of page.occurrences) {
|
|
91960
|
-
const node2 = store
|
|
92495
|
+
const node2 = historyNode(store, occurrence);
|
|
91961
92496
|
if (!node2 || node2.attrs["source"] !== "cloud" || node2.attrs["historyQuality"]?.["sourceSupport"] === "quarantined") continue;
|
|
91962
|
-
const receipt =
|
|
92497
|
+
const receipt = receipts.get(occurrence.occurrenceId);
|
|
92498
|
+
if (!receipt || unchangedRecord(node2, occurrence, receipt, atCommit)) continue;
|
|
91963
92499
|
const previous = node2.attrs["historyQuality"];
|
|
91964
92500
|
if (previous?.["evaluatedAtCommit"] === atCommit && previous["applicability"] === "applicable" && receipt.verdict !== "applicable" && previous["sourceReviewId"] === occurrence.quality["sourceReviewId"] && previous["dependencyReviewId"] === occurrence.quality["dependencyReviewId"] && historyDependencyIdentity(previous["dependencyContext"]) !== null && historyDependencyIdentity(previous["dependencyContext"]) === historyDependencyIdentity(occurrence.quality["dependencyContext"]) && previous["reconciliationEvidence"]?.["build"] === HISTORY_RECONCILE_BUILD) continue;
|
|
91965
92501
|
const dependencies = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
|
|
@@ -91975,17 +92511,115 @@ async function syncHistoryRevisionPage(opts) {
|
|
|
91975
92511
|
} });
|
|
91976
92512
|
changed++;
|
|
91977
92513
|
}
|
|
91978
|
-
|
|
91979
|
-
|
|
92514
|
+
const complete = page.cursor === null;
|
|
92515
|
+
const proven = reproving && complete && sweepCommit === atCommit;
|
|
92516
|
+
const provenKey = proven || !current ? ignoreKey : current.ignoreKey;
|
|
92517
|
+
profile.historyRevisionCursor = {
|
|
92518
|
+
atCommit: sweepCommit,
|
|
92519
|
+
...page.cursor ? { after: page.cursor } : {},
|
|
92520
|
+
complete,
|
|
92521
|
+
updatedAt: Date.now(),
|
|
92522
|
+
head: atCommit,
|
|
92523
|
+
...provenKey !== void 0 ? { ignoreKey: provenKey } : {},
|
|
92524
|
+
...reproving && !proven ? { reprove: ignoreKey } : {}
|
|
92525
|
+
};
|
|
92526
|
+
save();
|
|
91980
92527
|
return { changed, remaining: page.cursor !== null || headChanged || sweepCommit !== atCommit };
|
|
91981
92528
|
}
|
|
92529
|
+
function historyNode(store, occurrence) {
|
|
92530
|
+
return store.getNode(occurrence.canonicalId) ?? (occurrence.nodeId ? store.getNode(occurrence.nodeId) : null);
|
|
92531
|
+
}
|
|
92532
|
+
function unchangedRecord(node2, occurrence, receipt, atCommit) {
|
|
92533
|
+
const previous = node2.attrs["historyQuality"];
|
|
92534
|
+
if (!previous) return false;
|
|
92535
|
+
const stamp = receipt.verdict === "unknown" && previous["applicability"] === "unknown" ? previous["evaluatedAtCommit"] : atCommit;
|
|
92536
|
+
const dependencies = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
|
|
92537
|
+
const next = compactHistoryQuality({
|
|
92538
|
+
...occurrence.quality,
|
|
92539
|
+
evaluatedAtCommit: stamp,
|
|
92540
|
+
applicability: receipt.verdict,
|
|
92541
|
+
reconciliationEvidence: receipt.evidence
|
|
92542
|
+
});
|
|
92543
|
+
return digest(JSON.parse(JSON.stringify(next))) === digest(previous) && digest(dependencies.success ? historyDependencyVersions(dependencies.data) : null) === digest(node2.attrs["depVersions"] ?? null);
|
|
92544
|
+
}
|
|
92545
|
+
async function fileSymbols(ctx, path3, fileId, read2) {
|
|
92546
|
+
const fileKey = `${ctx.root}|${ctx.salt}|${ctx.projectId}|${fileId}|${path3}`;
|
|
92547
|
+
const cached2 = ctx.caches.symbols.get(fileKey);
|
|
92548
|
+
if (cached2) return cached2;
|
|
92549
|
+
const hashes = /* @__PURE__ */ new Map();
|
|
92550
|
+
const provider = ctx.providers.find((p) => p.fileExtensions.includes(extname3(path3).toLowerCase()));
|
|
92551
|
+
if (!provider) {
|
|
92552
|
+
ctx.caches.symbols.set(fileKey, hashes);
|
|
92553
|
+
return hashes;
|
|
92554
|
+
}
|
|
92555
|
+
const source = await read2().catch(() => null);
|
|
92556
|
+
if (source === null) return void 0;
|
|
92557
|
+
ctx.caches.symbols.set(fileKey, hashes);
|
|
92558
|
+
if (Buffer.byteLength(source) > 1e6 || source.includes("\0")) return hashes;
|
|
92559
|
+
await provider.preload?.();
|
|
92560
|
+
for (const symbol2 of provider.extractSymbols(source, path3)) {
|
|
92561
|
+
const kind = KINDS[symbol2.kind];
|
|
92562
|
+
if (kind && symbol2.bodyHash) hashes.set(projectSymbolId(ctx.salt, ctx.projectId, path3, symbol2.qname ?? symbol2.name, kind), symbol2.bodyHash);
|
|
92563
|
+
}
|
|
92564
|
+
return hashes;
|
|
92565
|
+
}
|
|
92566
|
+
var CARRY_MAX_CODE_FILES = 400;
|
|
92567
|
+
var CARRY_MAX_SYMBOLS = 5e3;
|
|
92568
|
+
var CARRY_MAX_MANIFESTS = 512;
|
|
92569
|
+
var CARRY_MAX_COMMITS = 8192;
|
|
92570
|
+
var LOCKFILE = /(?:^|\/)(?:pnpm-lock\.yaml|package-lock\.json)$/;
|
|
92571
|
+
var NO_BLOB = /^0+$/;
|
|
92572
|
+
async function carryRequest(o) {
|
|
92573
|
+
const { git: git3, from, at } = o;
|
|
92574
|
+
let parents = [];
|
|
92575
|
+
if (await git3(["merge-base", "--is-ancestor", from, at]).then(() => true, () => false)) {
|
|
92576
|
+
const rows = `${await git3(["rev-list", "--parents", "--ancestry-path", `--max-count=${CARRY_MAX_COMMITS}`, `${from}..${at}`])}
|
|
92577
|
+
${await git3(["rev-list", "--parents", "-1", from])}`.split("\n").map((row) => row.trim()).filter(Boolean).map((row) => {
|
|
92578
|
+
const [commit, ...parents2] = row.split(/\s+/);
|
|
92579
|
+
return { commit, parents: parents2 };
|
|
92580
|
+
});
|
|
92581
|
+
if (rows.length <= CARRY_MAX_COMMITS) parents = rows;
|
|
92582
|
+
}
|
|
92583
|
+
const fields = (await git3(["diff", "--raw", "--no-renames", "--no-abbrev", "-z", from, at])).split("\0");
|
|
92584
|
+
const changes = [];
|
|
92585
|
+
for (let i2 = 0; i2 + 1 < fields.length; i2 += 2) {
|
|
92586
|
+
const meta3 = fields[i2].trim().split(/\s+/), path3 = fields[i2 + 1];
|
|
92587
|
+
if (meta3.length >= 4 && path3) changes.push({ path: path3, blobs: [meta3[2], meta3[3]].filter((b) => !NO_BLOB.test(b)) });
|
|
92588
|
+
}
|
|
92589
|
+
const manifests = /* @__PURE__ */ new Set(), symbols = /* @__PURE__ */ new Set();
|
|
92590
|
+
let allManifests = o.rulesChanged, allSymbols = o.rulesChanged;
|
|
92591
|
+
const code = changes.filter((c) => o.providers.some((p) => p.fileExtensions.includes(extname3(c.path).toLowerCase())));
|
|
92592
|
+
if (code.length > CARRY_MAX_CODE_FILES) allSymbols = true;
|
|
92593
|
+
for (const change of changes) {
|
|
92594
|
+
if (LOCKFILE.test(change.path)) allManifests = true;
|
|
92595
|
+
else if (isManifestPath(change.path)) manifests.add(historyManifestId(change.path));
|
|
92596
|
+
}
|
|
92597
|
+
for (const change of allSymbols ? [] : code) {
|
|
92598
|
+
for (const blob of change.blobs) {
|
|
92599
|
+
const hashes = await fileSymbols(o, change.path, blob, () => git3(["show", blob]));
|
|
92600
|
+
if (!hashes) {
|
|
92601
|
+
allSymbols = true;
|
|
92602
|
+
break;
|
|
92603
|
+
}
|
|
92604
|
+
for (const id of hashes.keys()) symbols.add(id);
|
|
92605
|
+
}
|
|
92606
|
+
if (allSymbols) break;
|
|
92607
|
+
}
|
|
92608
|
+
return {
|
|
92609
|
+
fromCommit: from,
|
|
92610
|
+
atCommit: at,
|
|
92611
|
+
parents,
|
|
92612
|
+
changedSymbols: allSymbols || symbols.size > CARRY_MAX_SYMBOLS ? null : [...symbols].sort(),
|
|
92613
|
+
changedManifests: allManifests || manifests.size > CARRY_MAX_MANIFESTS ? null : [...manifests].sort()
|
|
92614
|
+
};
|
|
92615
|
+
}
|
|
91982
92616
|
|
|
91983
92617
|
// src/project-history.ts
|
|
91984
92618
|
init_src7();
|
|
91985
92619
|
init_src();
|
|
91986
92620
|
import { execFile as execFile6 } from "node:child_process";
|
|
91987
|
-
import { readFileSync as
|
|
91988
|
-
import { join as
|
|
92621
|
+
import { readFileSync as readFileSync39 } from "node:fs";
|
|
92622
|
+
import { join as join44 } from "node:path";
|
|
91989
92623
|
import { promisify as promisify5 } from "node:util";
|
|
91990
92624
|
|
|
91991
92625
|
// src/history-walk.ts
|
|
@@ -92537,7 +93171,7 @@ async function defaultGit(root, args2) {
|
|
|
92537
93171
|
function readIgnoreLines(root, profile) {
|
|
92538
93172
|
let lines = [];
|
|
92539
93173
|
try {
|
|
92540
|
-
lines =
|
|
93174
|
+
lines = readFileSync39(join44(root, ".errataignore"), "utf8").split("\n");
|
|
92541
93175
|
} catch {
|
|
92542
93176
|
}
|
|
92543
93177
|
return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
@@ -93111,10 +93745,10 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
|
|
|
93111
93745
|
|
|
93112
93746
|
// src/link-flow.ts
|
|
93113
93747
|
init_cloud_auth();
|
|
93114
|
-
import { createHash as
|
|
93748
|
+
import { createHash as createHash20 } from "node:crypto";
|
|
93115
93749
|
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
93116
|
-
import { existsSync as existsSync32, writeFileSync as
|
|
93117
|
-
import { join as
|
|
93750
|
+
import { existsSync as existsSync32, writeFileSync as writeFileSync28 } from "node:fs";
|
|
93751
|
+
import { join as join45 } from "node:path";
|
|
93118
93752
|
|
|
93119
93753
|
// src/device-poll.ts
|
|
93120
93754
|
var THROTTLED_POLL_MIN_WAIT_MS = 11e3;
|
|
@@ -93406,7 +94040,7 @@ async function loginOAuthLoopback(opts) {
|
|
|
93406
94040
|
|
|
93407
94041
|
// src/link-flow.ts
|
|
93408
94042
|
function remoteFingerprint(locator) {
|
|
93409
|
-
return
|
|
94043
|
+
return createHash20("sha256").update(locator).digest("hex");
|
|
93410
94044
|
}
|
|
93411
94045
|
function isDecision(value) {
|
|
93412
94046
|
if (!value || typeof value !== "object") return false;
|
|
@@ -93573,9 +94207,9 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
|
|
|
93573
94207
|
delete nextProfile.projectLinkHold;
|
|
93574
94208
|
let wroteIgnore = false;
|
|
93575
94209
|
if (decision.writeIgnoreStarter !== false) {
|
|
93576
|
-
const target =
|
|
94210
|
+
const target = join45(root, ".errataignore");
|
|
93577
94211
|
if (!existsSync32(target)) {
|
|
93578
|
-
|
|
94212
|
+
writeFileSync28(target, IGNORE_STARTER, "utf8");
|
|
93579
94213
|
wroteIgnore = true;
|
|
93580
94214
|
}
|
|
93581
94215
|
}
|
|
@@ -93589,12 +94223,12 @@ init_registry();
|
|
|
93589
94223
|
// src/adopt.ts
|
|
93590
94224
|
init_git_remote();
|
|
93591
94225
|
import { existsSync as existsSync33 } from "node:fs";
|
|
93592
|
-
import { dirname as
|
|
94226
|
+
import { dirname as dirname16, join as join46 } from "node:path";
|
|
93593
94227
|
function findGitRoot(absPath) {
|
|
93594
94228
|
let dir = absPath;
|
|
93595
94229
|
for (let depth = 0; depth < 64; depth++) {
|
|
93596
|
-
if (existsSync33(
|
|
93597
|
-
const parent =
|
|
94230
|
+
if (existsSync33(join46(dir, ".git"))) return dir;
|
|
94231
|
+
const parent = dirname16(dir);
|
|
93598
94232
|
if (parent === dir) return null;
|
|
93599
94233
|
dir = parent;
|
|
93600
94234
|
}
|
|
@@ -94068,7 +94702,6 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94068
94702
|
const boundaryListeners = [];
|
|
94069
94703
|
let boundaryFlushing = false;
|
|
94070
94704
|
let pushRequested = false;
|
|
94071
|
-
let shippedFingerprint = "";
|
|
94072
94705
|
let settleRunning = false;
|
|
94073
94706
|
let boundaryFlushStartedAt = 0;
|
|
94074
94707
|
let boundaryFlushStage = "";
|
|
@@ -94149,16 +94782,63 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94149
94782
|
});
|
|
94150
94783
|
}
|
|
94151
94784
|
};
|
|
94152
|
-
const
|
|
94785
|
+
const SHIP_MARK_KEY = "watermark:instance-ship";
|
|
94786
|
+
const sendableSeq = (store) => store.changeSeq ? store.changeSeq() - store.changeSeq([EXPOSURE_SCOPE]) : null;
|
|
94787
|
+
const shipLanes = () => {
|
|
94153
94788
|
const cfg2 = loadConfig();
|
|
94154
|
-
const
|
|
94789
|
+
const lanes = [], destinations = [], held = [];
|
|
94155
94790
|
for (const r of records) {
|
|
94156
|
-
|
|
94157
|
-
|
|
94791
|
+
const consent = effectiveConsent(cfg2, r.engine.profile);
|
|
94792
|
+
if (!consent.sync) continue;
|
|
94793
|
+
const identity = identityFor(liveWorkspaceEntry(r.entry));
|
|
94794
|
+
const destination = `${opts.cloudUrl ?? identity.profile?.cloudUrl ?? cfg2.cloudUrl ?? ""}|${identity.profileName ?? ""}`;
|
|
94795
|
+
destinations.push(destination);
|
|
94796
|
+
const quarantined = r.engine.quarantinedSessions().slice().sort();
|
|
94797
|
+
held.push(...quarantined);
|
|
94798
|
+
let ignoreFile = "";
|
|
94799
|
+
try {
|
|
94800
|
+
ignoreFile = readFileSync40(join47(r.root, ".errataignore"), "utf8");
|
|
94801
|
+
} catch {
|
|
94802
|
+
}
|
|
94803
|
+
const retryInputs = JSON.stringify([
|
|
94804
|
+
quarantined,
|
|
94805
|
+
DAEMON_VERSION,
|
|
94806
|
+
ignoreFile,
|
|
94807
|
+
r.engine.profile.ignoreExtra ?? [],
|
|
94808
|
+
r.engine.profile.projectHistoryCorrectionCursor ?? 0
|
|
94809
|
+
]);
|
|
94810
|
+
const context = JSON.stringify([destination, consent.contributePackages ?? null, loadProfile(r.root)?.projectId ?? r.engine.profile.projectId ?? null]);
|
|
94811
|
+
const fp = r.engine.store.labelFingerprint?.(INSTANCE_LABELS);
|
|
94812
|
+
lanes.push({ store: r.engine.store, fp: fp === void 0 ? null : `${context}#${fp}`, seq: sendableSeq(r.engine.store), held: retryInputs });
|
|
94813
|
+
}
|
|
94814
|
+
if (lanes.length === 0) return lanes;
|
|
94815
|
+
const shared = sharedStore.labelFingerprint?.(["RootCause"]);
|
|
94816
|
+
const sharedContext = JSON.stringify([...new Set(destinations)].sort());
|
|
94817
|
+
lanes.push({ store: sharedStore, fp: shared === void 0 ? null : `${sharedContext}#${shared}`, seq: sendableSeq(sharedStore), held: JSON.stringify([[...new Set(held)].sort(), DAEMON_VERSION]) });
|
|
94818
|
+
return lanes;
|
|
94819
|
+
};
|
|
94820
|
+
const shipMark = (store) => {
|
|
94821
|
+
try {
|
|
94822
|
+
return JSON.parse(store.getMeta?.(SHIP_MARK_KEY) ?? "null");
|
|
94823
|
+
} catch {
|
|
94824
|
+
return null;
|
|
94158
94825
|
}
|
|
94159
|
-
|
|
94160
|
-
|
|
94161
|
-
|
|
94826
|
+
};
|
|
94827
|
+
const unshipped = (lanes, retries) => lanes.filter((l) => {
|
|
94828
|
+
const mark = l.fp === null ? null : shipMark(l.store);
|
|
94829
|
+
if (!mark || mark.fp !== l.fp) return true;
|
|
94830
|
+
if (!retries) return false;
|
|
94831
|
+
return !mark.ok || l.seq === null || mark.seq !== l.seq || mark.held !== l.held || mark.retryAt !== void 0 && mark.retryAt <= Date.now();
|
|
94832
|
+
});
|
|
94833
|
+
const recordShipped = (lanes, result) => {
|
|
94834
|
+
const mark = (l) => ({
|
|
94835
|
+
fp: l.fp,
|
|
94836
|
+
ok: !result.errors?.length,
|
|
94837
|
+
...result.retryAt !== void 0 ? { retryAt: result.retryAt } : {},
|
|
94838
|
+
...l.seq !== null ? { seq: l.seq } : {},
|
|
94839
|
+
held: l.held
|
|
94840
|
+
});
|
|
94841
|
+
for (const l of lanes) if (l.fp !== null) l.store.setMeta?.(SHIP_MARK_KEY, JSON.stringify(mark(l)));
|
|
94162
94842
|
};
|
|
94163
94843
|
const runSettle = async () => {
|
|
94164
94844
|
if (settleRunning) return;
|
|
@@ -94311,7 +94991,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94311
94991
|
records.push(rec);
|
|
94312
94992
|
void ambientLinkAll();
|
|
94313
94993
|
try {
|
|
94314
|
-
|
|
94994
|
+
writeFileSync29(
|
|
94315
94995
|
rec.engine.paths.daemonLock,
|
|
94316
94996
|
daemonLockPayload({
|
|
94317
94997
|
pid: process.pid,
|
|
@@ -94380,11 +95060,19 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94380
95060
|
const strandedCount = (r) => {
|
|
94381
95061
|
const hit = strandedCache.get(r.id);
|
|
94382
95062
|
if (hit && Date.now() - hit.at < STRANDED_TTL_MS) return hit.count;
|
|
95063
|
+
const store = r.engine.store;
|
|
95064
|
+
const standing = standingStrandedCount(store);
|
|
95065
|
+
if (standing !== null) {
|
|
95066
|
+
strandedCache.set(r.id, { at: Date.now(), count: standing });
|
|
95067
|
+
return standing;
|
|
95068
|
+
}
|
|
94383
95069
|
if (!strandedRefreshing.has(r.id)) {
|
|
94384
95070
|
strandedRefreshing.add(r.id);
|
|
95071
|
+
const seq = store.changeSeq?.();
|
|
94385
95072
|
const finish = (count) => {
|
|
94386
95073
|
strandedCache.set(r.id, { at: Date.now(), count });
|
|
94387
95074
|
strandedRefreshing.delete(r.id);
|
|
95075
|
+
recordStrandedCount(store, seq, count);
|
|
94388
95076
|
};
|
|
94389
95077
|
if (consolidateWorker && r.engine.paths.castalia !== ":memory:") {
|
|
94390
95078
|
consolidateWorker.run({ kind: "strandedCount", sharedDbPath, castaliaPath: r.engine.paths.castalia }).then((n) => finish(Number(n))).catch(() => {
|
|
@@ -94690,7 +95378,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94690
95378
|
baseUrl = `http://127.0.0.1:${port}`;
|
|
94691
95379
|
try {
|
|
94692
95380
|
ensureDir(globalDir());
|
|
94693
|
-
|
|
95381
|
+
writeFileSync29(
|
|
94694
95382
|
lockPath,
|
|
94695
95383
|
daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
|
|
94696
95384
|
"utf8"
|
|
@@ -94699,7 +95387,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94699
95387
|
}
|
|
94700
95388
|
for (const r of records) {
|
|
94701
95389
|
try {
|
|
94702
|
-
|
|
95390
|
+
writeFileSync29(
|
|
94703
95391
|
r.engine.paths.daemonLock,
|
|
94704
95392
|
daemonLockPayload({
|
|
94705
95393
|
pid: process.pid,
|
|
@@ -94739,7 +95427,15 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94739
95427
|
});
|
|
94740
95428
|
const revisionBacklog = /* @__PURE__ */ new Set();
|
|
94741
95429
|
const lastAnchorPull = /* @__PURE__ */ new Map();
|
|
94742
|
-
const
|
|
95430
|
+
const anchorPullInFlight = /* @__PURE__ */ new Map();
|
|
95431
|
+
const pullProjectAnchors = (r, client, salt) => {
|
|
95432
|
+
const running = anchorPullInFlight.get(r.root);
|
|
95433
|
+
if (running) return running;
|
|
95434
|
+
const pull = pullProjectAnchorsOnce(r, client, salt).finally(() => anchorPullInFlight.delete(r.root));
|
|
95435
|
+
anchorPullInFlight.set(r.root, pull);
|
|
95436
|
+
return pull;
|
|
95437
|
+
};
|
|
95438
|
+
const pullProjectAnchorsOnce = async (r, client, salt) => {
|
|
94743
95439
|
const donePass = markPass(`anchor-pull:${r.engine.profile.name}`);
|
|
94744
95440
|
const pullStartedAt = Date.now();
|
|
94745
95441
|
const beforeCorrections = r.engine.profile.projectHistoryCorrectionCursor ?? 0;
|
|
@@ -94755,10 +95451,13 @@ async function startMultiDaemon(opts = {}) {
|
|
|
94755
95451
|
for (const record2 of records) record2.engine.markContextDirty();
|
|
94756
95452
|
}
|
|
94757
95453
|
try {
|
|
94758
|
-
|
|
94759
|
-
|
|
94760
|
-
|
|
94761
|
-
|
|
95454
|
+
if (!r.engine.storeReconciled()) revisionBacklog.add(r.root);
|
|
95455
|
+
else {
|
|
95456
|
+
const revision = await syncHistoryRevision({ root: r.root, profile: r.engine.profile, store: r.engine.store, cloud: client, salt });
|
|
95457
|
+
if (revision.remaining) revisionBacklog.add(r.root);
|
|
95458
|
+
else revisionBacklog.delete(r.root);
|
|
95459
|
+
if (revision.changed) r.engine.markContextDirty();
|
|
95460
|
+
}
|
|
94762
95461
|
} catch (err2) {
|
|
94763
95462
|
console.warn(`[errata] history revision reconciliation failed for ${r.engine.profile.name}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
94764
95463
|
}
|
|
@@ -95248,6 +95947,10 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95248
95947
|
};
|
|
95249
95948
|
let uploaded = 0;
|
|
95250
95949
|
const errors = [];
|
|
95950
|
+
let retryAt = null;
|
|
95951
|
+
const retryBy = (at) => {
|
|
95952
|
+
if (at !== null && (retryAt === null || at < retryAt)) retryAt = at;
|
|
95953
|
+
};
|
|
95251
95954
|
const workerFor = (r) => consolidateWorker && r.engine.paths.castalia !== ":memory:" ? consolidateWorker : null;
|
|
95252
95955
|
const buildContextBatch = async (r, input) => {
|
|
95253
95956
|
const w = workerFor(r);
|
|
@@ -95371,6 +96074,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95371
96074
|
}
|
|
95372
96075
|
});
|
|
95373
96076
|
if (p.blockedNodeIds?.length) {
|
|
96077
|
+
retryBy(Date.now());
|
|
95374
96078
|
console.log(
|
|
95375
96079
|
`[sync\u2192cloud] [${projectName}] context: ${p.blockedNodeIds.length} node(s) refused by an edge/CDN filter on content \u2014 left pending, will retry`
|
|
95376
96080
|
);
|
|
@@ -95402,6 +96106,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95402
96106
|
});
|
|
95403
96107
|
const parkPath = edgeParkPath(r.engine.paths.configDir, destinationKey);
|
|
95404
96108
|
const parkQueue = loadEdgePark(parkPath);
|
|
96109
|
+
retryBy(nextEdgeParkChange(parkQueue));
|
|
95405
96110
|
const built = await buildInstanceBatch(r, {
|
|
95406
96111
|
edgeHolds: edgeHolds(parkQueue, Date.now()),
|
|
95407
96112
|
destinationKey,
|
|
@@ -95471,6 +96176,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95471
96176
|
}
|
|
95472
96177
|
});
|
|
95473
96178
|
if (blocked.size > 0) {
|
|
96179
|
+
retryBy(Date.now());
|
|
95474
96180
|
console.log(
|
|
95475
96181
|
`[sync\u2192cloud] [${projectName}] instances: ${blocked.size} node(s) refused by an edge/CDN filter on content \u2014 left pending, will retry. First: ${store.getNode([...blocked][0])?.description.slice(0, 120) ?? [...blocked][0]}`
|
|
95476
96182
|
);
|
|
@@ -95506,6 +96212,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95506
96212
|
Date.now()
|
|
95507
96213
|
);
|
|
95508
96214
|
saveEdgePark(parkPath, settled.queue);
|
|
96215
|
+
retryBy(nextEdgeParkChange(settled.queue));
|
|
95509
96216
|
const edgeCounts = settled.counts;
|
|
95510
96217
|
if (rejectedEdges.length > 0) {
|
|
95511
96218
|
const byReason = /* @__PURE__ */ new Map();
|
|
@@ -95632,7 +96339,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95632
96339
|
});
|
|
95633
96340
|
}
|
|
95634
96341
|
}
|
|
95635
|
-
return { uploaded, ...errors.length > 0 ? { errors } : {} };
|
|
96342
|
+
return { uploaded, ...errors.length > 0 ? { errors } : {}, ...retryAt !== null ? { retryAt } : {} };
|
|
95636
96343
|
},
|
|
95637
96344
|
async backfillCausalEdges() {
|
|
95638
96345
|
if (!loadConfig().consent.sync) return { accepted: 0, rejected: 0, skipped: "consent-off" };
|
|
@@ -95707,9 +96414,9 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95707
96414
|
beginFlush("instances");
|
|
95708
96415
|
try {
|
|
95709
96416
|
flushStage("instances");
|
|
95710
|
-
const
|
|
95711
|
-
const inst = await daemon.syncInstancesPublic();
|
|
95712
|
-
|
|
96417
|
+
const lanes = shipLanes();
|
|
96418
|
+
const inst = lanes.length > 0 && unshipped(lanes, true).length === 0 ? { uploaded: 0, skipped: "unchanged", errors: void 0 } : await daemon.syncInstancesPublic();
|
|
96419
|
+
if (!inst.skipped) recordShipped(lanes, inst);
|
|
95713
96420
|
flushStage("skills");
|
|
95714
96421
|
const skills = await daemon.syncSkillsAll();
|
|
95715
96422
|
return {
|
|
@@ -95723,8 +96430,8 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95723
96430
|
}
|
|
95724
96431
|
},
|
|
95725
96432
|
pendingLiveFingerprint() {
|
|
95726
|
-
const
|
|
95727
|
-
return
|
|
96433
|
+
const pending = unshipped(shipLanes(), false);
|
|
96434
|
+
return pending.length ? pending.map((l) => l.fp ?? `?${Date.now()}`).join("|") : null;
|
|
95728
96435
|
},
|
|
95729
96436
|
async liveShip() {
|
|
95730
96437
|
if (!liveSyncEnabled()) return { uploaded: 0, skipped: "disabled" };
|
|
@@ -95740,9 +96447,9 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95740
96447
|
}
|
|
95741
96448
|
beginFlush("live");
|
|
95742
96449
|
try {
|
|
95743
|
-
const
|
|
96450
|
+
const lanes = shipLanes();
|
|
95744
96451
|
const inst = await daemon.syncInstancesPublic();
|
|
95745
|
-
|
|
96452
|
+
if (!inst.skipped) recordShipped(lanes, inst);
|
|
95746
96453
|
return {
|
|
95747
96454
|
uploaded: inst.uploaded,
|
|
95748
96455
|
...inst.skipped ? { skipped: inst.skipped } : {},
|
|
@@ -95792,7 +96499,9 @@ async function startMultiDaemon(opts = {}) {
|
|
|
95792
96499
|
flushStage("triage");
|
|
95793
96500
|
const triage = await daemon.syncTriagePublic();
|
|
95794
96501
|
flushStage("instances");
|
|
96502
|
+
const lanes = shipLanes();
|
|
95795
96503
|
const instances = await daemon.syncInstancesPublic();
|
|
96504
|
+
if (!instances.skipped) recordShipped(lanes, instances);
|
|
95796
96505
|
flushStage("edge-backfill");
|
|
95797
96506
|
const edgeBackfill = await daemon.backfillCausalEdges();
|
|
95798
96507
|
return c.json({ principles, triage, instances, edgeBackfill });
|
|
@@ -96217,15 +96926,15 @@ function shouldUseOAuthLogin(flags2, env2 = process.env) {
|
|
|
96217
96926
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
96218
96927
|
|
|
96219
96928
|
// src/codex-runtime.ts
|
|
96220
|
-
import { readdirSync as readdirSync13, statSync as
|
|
96221
|
-
import { join as
|
|
96929
|
+
import { readdirSync as readdirSync13, statSync as statSync12 } from "node:fs";
|
|
96930
|
+
import { join as join48 } from "node:path";
|
|
96222
96931
|
function resolveCodexExecutable(options = {}) {
|
|
96223
96932
|
const platform = options.platform ?? process.platform;
|
|
96224
96933
|
const env2 = options.env ?? process.env;
|
|
96225
96934
|
if (platform !== "win32") return "codex";
|
|
96226
96935
|
const fileTime = (path3) => {
|
|
96227
96936
|
try {
|
|
96228
|
-
const s =
|
|
96937
|
+
const s = statSync12(path3);
|
|
96229
96938
|
return s.isFile() ? s.mtimeMs : null;
|
|
96230
96939
|
} catch {
|
|
96231
96940
|
return null;
|
|
@@ -96233,13 +96942,13 @@ function resolveCodexExecutable(options = {}) {
|
|
|
96233
96942
|
};
|
|
96234
96943
|
for (const dir of (env2["PATH"] ?? env2["Path"] ?? "").split(";")) {
|
|
96235
96944
|
if (!dir.trim()) continue;
|
|
96236
|
-
const path3 =
|
|
96945
|
+
const path3 = join48(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
|
|
96237
96946
|
if (fileTime(path3) !== null) return path3;
|
|
96238
96947
|
}
|
|
96239
96948
|
if (!env2["LOCALAPPDATA"]) return "codex";
|
|
96240
|
-
const root =
|
|
96949
|
+
const root = join48(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
|
|
96241
96950
|
try {
|
|
96242
|
-
const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
96951
|
+
const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join48(root, entry.name, "codex.exe")).map((path3) => ({ path: path3, mtime: fileTime(path3) })).filter((candidate) => candidate.mtime !== null).sort((a, b) => b.mtime - a.mtime || a.path.localeCompare(b.path));
|
|
96243
96952
|
return candidates[0]?.path ?? "codex";
|
|
96244
96953
|
} catch {
|
|
96245
96954
|
return "codex";
|
|
@@ -96378,14 +97087,14 @@ async function diagnoseInstallation(cfg, dependencies) {
|
|
|
96378
97087
|
}
|
|
96379
97088
|
|
|
96380
97089
|
// src/credential-scan.ts
|
|
96381
|
-
import { readFileSync as
|
|
97090
|
+
import { readFileSync as readFileSync42, statSync as statSync13 } from "node:fs";
|
|
96382
97091
|
import { homedir as homedir8 } from "node:os";
|
|
96383
|
-
import { join as
|
|
97092
|
+
import { join as join50 } from "node:path";
|
|
96384
97093
|
|
|
96385
97094
|
// src/claude-statusline.ts
|
|
96386
|
-
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as
|
|
97095
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync41, writeFileSync as writeFileSync30 } from "node:fs";
|
|
96387
97096
|
import { homedir as homedir7 } from "node:os";
|
|
96388
|
-
import { dirname as
|
|
97097
|
+
import { dirname as dirname17, join as join49 } from "node:path";
|
|
96389
97098
|
var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
|
|
96390
97099
|
import { readFileSync } from 'node:fs';
|
|
96391
97100
|
|
|
@@ -96433,8 +97142,8 @@ function isSameInstall(value, relay) {
|
|
|
96433
97142
|
return command.includes(relay.replace(/\\/g, "/").toLowerCase());
|
|
96434
97143
|
}
|
|
96435
97144
|
function userClaudeSettingsPath() {
|
|
96436
|
-
const base = process.env["CLAUDE_CONFIG_DIR"] ??
|
|
96437
|
-
return
|
|
97145
|
+
const base = process.env["CLAUDE_CONFIG_DIR"] ?? join49(homedir7(), ".claude");
|
|
97146
|
+
return join49(base, "settings.json");
|
|
96438
97147
|
}
|
|
96439
97148
|
function ensureUserStatusLine(opts) {
|
|
96440
97149
|
const env2 = opts.env ?? process.env;
|
|
@@ -96444,21 +97153,21 @@ function ensureUserStatusLine(opts) {
|
|
|
96444
97153
|
let settings = {};
|
|
96445
97154
|
if (existsSync35(settingsPath)) {
|
|
96446
97155
|
try {
|
|
96447
|
-
const parsed = JSON.parse(
|
|
97156
|
+
const parsed = JSON.parse(readFileSync41(settingsPath, "utf8"));
|
|
96448
97157
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
|
|
96449
97158
|
settings = parsed;
|
|
96450
97159
|
} catch {
|
|
96451
97160
|
return "unreadable";
|
|
96452
97161
|
}
|
|
96453
97162
|
}
|
|
96454
|
-
const relay =
|
|
97163
|
+
const relay = join49(opts.relayDir, STATUSLINE_RELAY_FILE);
|
|
96455
97164
|
const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
|
|
96456
97165
|
const ownMain = keep(settings["statusLine"]);
|
|
96457
97166
|
const ownRows = keep(settings["subagentStatusLine"]);
|
|
96458
97167
|
if (ownMain && ownRows) return "kept-own";
|
|
96459
97168
|
mkdirSync9(opts.relayDir, { recursive: true });
|
|
96460
|
-
if (!existsSync35(relay) ||
|
|
96461
|
-
|
|
97169
|
+
if (!existsSync35(relay) || readFileSync41(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
|
|
97170
|
+
writeFileSync30(relay, STATUSLINE_RELAY_SOURCE, "utf8");
|
|
96462
97171
|
}
|
|
96463
97172
|
const nodePath = opts.nodePath ?? process.execPath;
|
|
96464
97173
|
const next = {
|
|
@@ -96469,8 +97178,8 @@ function ensureUserStatusLine(opts) {
|
|
|
96469
97178
|
return ownMain ? "kept-own" : "unchanged";
|
|
96470
97179
|
}
|
|
96471
97180
|
Object.assign(settings, next);
|
|
96472
|
-
mkdirSync9(
|
|
96473
|
-
|
|
97181
|
+
mkdirSync9(dirname17(settingsPath), { recursive: true });
|
|
97182
|
+
writeFileSync30(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
96474
97183
|
return "installed";
|
|
96475
97184
|
}
|
|
96476
97185
|
function describeStatusLineOutcome(outcome) {
|
|
@@ -96511,36 +97220,36 @@ function findCredentialLines(text) {
|
|
|
96511
97220
|
function harnessConfigPaths(root) {
|
|
96512
97221
|
const env2 = process.env;
|
|
96513
97222
|
const home = homedir8();
|
|
96514
|
-
const codexHome = env2["CODEX_HOME"] ||
|
|
96515
|
-
const geminiHome =
|
|
97223
|
+
const codexHome = env2["CODEX_HOME"] || join50(home, ".codex");
|
|
97224
|
+
const geminiHome = join50(env2["GEMINI_CLI_HOME"] ?? home, ".gemini");
|
|
96516
97225
|
return [
|
|
96517
97226
|
// Claude Code: user settings, `claude mcp add` (local/user scope), project.
|
|
96518
97227
|
userClaudeSettingsPath(),
|
|
96519
|
-
|
|
96520
|
-
|
|
96521
|
-
|
|
96522
|
-
|
|
97228
|
+
join50(env2["CLAUDE_CONFIG_DIR"] ?? home, ".claude.json"),
|
|
97229
|
+
join50(root, ".claude", "settings.json"),
|
|
97230
|
+
join50(root, ".claude", "settings.local.json"),
|
|
97231
|
+
join50(root, ".mcp.json"),
|
|
96523
97232
|
// Codex
|
|
96524
|
-
|
|
96525
|
-
|
|
97233
|
+
join50(codexHome, "config.toml"),
|
|
97234
|
+
join50(root, ".codex", "config.toml"),
|
|
96526
97235
|
// Gemini CLI
|
|
96527
|
-
|
|
96528
|
-
|
|
97236
|
+
join50(geminiHome, "settings.json"),
|
|
97237
|
+
join50(root, ".gemini", "settings.json"),
|
|
96529
97238
|
// Cursor
|
|
96530
|
-
|
|
96531
|
-
|
|
97239
|
+
join50(home, ".cursor", "mcp.json"),
|
|
97240
|
+
join50(root, ".cursor", "mcp.json"),
|
|
96532
97241
|
// VS Code (user profile mcp.json + workspace)
|
|
96533
|
-
|
|
96534
|
-
|
|
97242
|
+
join50(vscodeUserDir(home, env2), "mcp.json"),
|
|
97243
|
+
join50(root, ".vscode", "mcp.json"),
|
|
96535
97244
|
// OpenCode (XDG on every platform; the daemon's installer writes the project one)
|
|
96536
|
-
|
|
96537
|
-
|
|
97245
|
+
join50(env2["XDG_CONFIG_HOME"] ?? join50(home, ".config"), "opencode", "opencode.json"),
|
|
97246
|
+
join50(root, "opencode.json")
|
|
96538
97247
|
];
|
|
96539
97248
|
}
|
|
96540
97249
|
function vscodeUserDir(home, env2) {
|
|
96541
|
-
if (process.platform === "win32") return
|
|
96542
|
-
if (process.platform === "darwin") return
|
|
96543
|
-
return
|
|
97250
|
+
if (process.platform === "win32") return join50(env2["APPDATA"] ?? join50(home, "AppData", "Roaming"), "Code", "User");
|
|
97251
|
+
if (process.platform === "darwin") return join50(home, "Library", "Application Support", "Code", "User");
|
|
97252
|
+
return join50(env2["XDG_CONFIG_HOME"] ?? join50(home, ".config"), "Code", "User");
|
|
96544
97253
|
}
|
|
96545
97254
|
function scanHarnessConfigs(paths, read2 = readBounded) {
|
|
96546
97255
|
const findings = [];
|
|
@@ -96555,9 +97264,9 @@ function scanHarnessConfigs(paths, read2 = readBounded) {
|
|
|
96555
97264
|
}
|
|
96556
97265
|
function readBounded(path3) {
|
|
96557
97266
|
try {
|
|
96558
|
-
const stat4 =
|
|
97267
|
+
const stat4 = statSync13(path3);
|
|
96559
97268
|
if (!stat4.isFile() || stat4.size > MAX_SCAN_BYTES) return null;
|
|
96560
|
-
return
|
|
97269
|
+
return readFileSync42(path3, "utf8");
|
|
96561
97270
|
} catch {
|
|
96562
97271
|
return null;
|
|
96563
97272
|
}
|
|
@@ -96582,14 +97291,14 @@ function credentialHygieneCheck(scan2) {
|
|
|
96582
97291
|
|
|
96583
97292
|
// src/codex-doctor.ts
|
|
96584
97293
|
import { spawn as spawn4 } from "node:child_process";
|
|
96585
|
-
import { readFileSync as
|
|
96586
|
-
import { join as
|
|
97294
|
+
import { readFileSync as readFileSync44, statSync as statSync14 } from "node:fs";
|
|
97295
|
+
import { join as join52 } from "node:path";
|
|
96587
97296
|
import { createInterface } from "node:readline";
|
|
96588
97297
|
|
|
96589
97298
|
// src/codex-hooks.ts
|
|
96590
|
-
import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as
|
|
97299
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync43, renameSync as renameSync8, unlinkSync as unlinkSync5, writeFileSync as writeFileSync31 } from "node:fs";
|
|
96591
97300
|
import { homedir as homedir9 } from "node:os";
|
|
96592
|
-
import { join as
|
|
97301
|
+
import { join as join51 } from "node:path";
|
|
96593
97302
|
|
|
96594
97303
|
// src/hook-commands.ts
|
|
96595
97304
|
function hookCurlCommand(port, path3 = "/api/hook") {
|
|
@@ -96793,34 +97502,34 @@ function buildCodexRelaySource(workspaceRoot) {
|
|
|
96793
97502
|
init_checkout_root();
|
|
96794
97503
|
var CODEX_HOOK_REVIEW_HELP = "Codex desktop: Settings > Hooks, select this project, expand each event and Trust the Errata hook. CLI users can use /hooks.";
|
|
96795
97504
|
function writeRelay(file2, source) {
|
|
96796
|
-
if (existsSync36(file2) &&
|
|
97505
|
+
if (existsSync36(file2) && readFileSync43(file2, "utf8") === source) return;
|
|
96797
97506
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
96798
97507
|
try {
|
|
96799
|
-
|
|
96800
|
-
|
|
97508
|
+
writeFileSync31(temp, source, { encoding: "utf8", mode: 384 });
|
|
97509
|
+
renameSync8(temp, file2);
|
|
96801
97510
|
} finally {
|
|
96802
97511
|
if (existsSync36(temp)) unlinkSync5(temp);
|
|
96803
97512
|
}
|
|
96804
97513
|
}
|
|
96805
97514
|
function refreshCodexRelay(root) {
|
|
96806
|
-
const config2 =
|
|
97515
|
+
const config2 = join51(root, ".codex", "config.toml");
|
|
96807
97516
|
if (!existsSync36(config2)) return "absent";
|
|
96808
|
-
const existing =
|
|
97517
|
+
const existing = readFileSync43(config2, "utf8");
|
|
96809
97518
|
if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
|
|
96810
97519
|
replaceCodexHooks(existing, "");
|
|
96811
|
-
const relay =
|
|
96812
|
-
const prior = existsSync36(relay) ?
|
|
97520
|
+
const relay = join51(root, ".codex", "hooks", "errata-relay.mjs");
|
|
97521
|
+
const prior = existsSync36(relay) ? readFileSync43(relay, "utf8") : "";
|
|
96813
97522
|
if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
|
|
96814
97523
|
throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
|
|
96815
97524
|
}
|
|
96816
97525
|
const source = buildCodexRelaySource(checkoutRootOf(root));
|
|
96817
97526
|
if (prior === source) return "current";
|
|
96818
|
-
mkdirSync10(
|
|
97527
|
+
mkdirSync10(join51(root, ".codex", "hooks"), { recursive: true });
|
|
96819
97528
|
writeRelay(relay, source);
|
|
96820
97529
|
return "updated";
|
|
96821
97530
|
}
|
|
96822
|
-
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] ||
|
|
96823
|
-
return existsSync36(
|
|
97531
|
+
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join51(homedir9(), ".codex")) {
|
|
97532
|
+
return existsSync36(join51(root, ".codex")) || existsSync36(codexHome);
|
|
96824
97533
|
}
|
|
96825
97534
|
function replaceCodexHooks(existing, block) {
|
|
96826
97535
|
const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
|
|
@@ -96836,14 +97545,14 @@ function replaceCodexHooks(existing, block) {
|
|
|
96836
97545
|
return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
|
|
96837
97546
|
}
|
|
96838
97547
|
function writeCodexHooks(root, port, nodePath = process.execPath) {
|
|
96839
|
-
const dir =
|
|
96840
|
-
const file2 =
|
|
96841
|
-
const relay =
|
|
97548
|
+
const dir = join51(root, ".codex");
|
|
97549
|
+
const file2 = join51(dir, "config.toml");
|
|
97550
|
+
const relay = join51(dir, "hooks", "errata-relay.mjs");
|
|
96842
97551
|
const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
|
|
96843
|
-
const final = replaceCodexHooks(existsSync36(file2) ?
|
|
96844
|
-
mkdirSync10(
|
|
97552
|
+
const final = replaceCodexHooks(existsSync36(file2) ? readFileSync43(file2, "utf8") : "", block);
|
|
97553
|
+
mkdirSync10(join51(dir, "hooks"), { recursive: true });
|
|
96845
97554
|
writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
|
|
96846
|
-
if (!existsSync36(file2) ||
|
|
97555
|
+
if (!existsSync36(file2) || readFileSync43(file2, "utf8") !== final) writeFileSync31(file2, final, "utf8");
|
|
96847
97556
|
return file2;
|
|
96848
97557
|
}
|
|
96849
97558
|
|
|
@@ -96852,7 +97561,7 @@ init_checkout_root();
|
|
|
96852
97561
|
function inspectCodexRelay(cwd) {
|
|
96853
97562
|
const root = nearestGitRoot(cwd) ?? cwd;
|
|
96854
97563
|
try {
|
|
96855
|
-
const source =
|
|
97564
|
+
const source = readFileSync44(join52(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
|
|
96856
97565
|
if (source === buildCodexRelaySource(checkoutRootOf(root))) {
|
|
96857
97566
|
return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
|
|
96858
97567
|
}
|
|
@@ -96863,8 +97572,8 @@ function inspectCodexRelay(cwd) {
|
|
|
96863
97572
|
function inspectCodexContext(cwd) {
|
|
96864
97573
|
const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
|
|
96865
97574
|
try {
|
|
96866
|
-
const file2 =
|
|
96867
|
-
if (
|
|
97575
|
+
const file2 = join52(root, ".errata", "context.md");
|
|
97576
|
+
if (statSync14(file2).size <= 128 * 1024 && readFileSync44(file2, "utf8").trim()) {
|
|
96868
97577
|
return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
|
|
96869
97578
|
}
|
|
96870
97579
|
} catch {
|
|
@@ -97041,11 +97750,11 @@ function consolidationGapMs(lastPassMs, policy) {
|
|
|
97041
97750
|
}
|
|
97042
97751
|
|
|
97043
97752
|
// src/codex-context-plugin.ts
|
|
97044
|
-
import { createHash as
|
|
97045
|
-
import { cpSync as cpSync2, existsSync as existsSync37, mkdirSync as mkdirSync11, readFileSync as
|
|
97753
|
+
import { createHash as createHash21 } from "node:crypto";
|
|
97754
|
+
import { cpSync as cpSync2, existsSync as existsSync37, mkdirSync as mkdirSync11, readFileSync as readFileSync45, renameSync as renameSync9, writeFileSync as writeFileSync32 } from "node:fs";
|
|
97046
97755
|
import { homedir as homedir10 } from "node:os";
|
|
97047
|
-
import { join as
|
|
97048
|
-
import { fileURLToPath as
|
|
97756
|
+
import { join as join53 } from "node:path";
|
|
97757
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
97049
97758
|
|
|
97050
97759
|
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
|
|
97051
97760
|
function getLineColFromPtr(string4, ptr) {
|
|
@@ -97127,7 +97836,7 @@ function skipVoid(str, ptr, banNewLines, banComments) {
|
|
|
97127
97836
|
}
|
|
97128
97837
|
return ptr;
|
|
97129
97838
|
}
|
|
97130
|
-
function skipUntil(str, ptr,
|
|
97839
|
+
function skipUntil(str, ptr, sep7, end, banNewLines = false) {
|
|
97131
97840
|
if (!end) {
|
|
97132
97841
|
ptr = indexOfNewline(str, ptr);
|
|
97133
97842
|
return ptr < 0 ? str.length : ptr;
|
|
@@ -97136,7 +97845,7 @@ function skipUntil(str, ptr, sep6, end, banNewLines = false) {
|
|
|
97136
97845
|
let c = str[i2];
|
|
97137
97846
|
if (c === "#") {
|
|
97138
97847
|
i2 = indexOfNewline(str, i2);
|
|
97139
|
-
} else if (c ===
|
|
97848
|
+
} else if (c === sep7) {
|
|
97140
97849
|
return i2 + 1;
|
|
97141
97850
|
} else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i2 + 1] === "\n")) {
|
|
97142
97851
|
return i2;
|
|
@@ -97742,23 +98451,23 @@ var NAME = "errata-context";
|
|
|
97742
98451
|
var PREFIX2 = `./.errata/plugins/${NAME}/`;
|
|
97743
98452
|
var object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
97744
98453
|
function readText(file2) {
|
|
97745
|
-
return existsSync37(file2) ?
|
|
98454
|
+
return existsSync37(file2) ? readFileSync45(file2, "utf8") : "";
|
|
97746
98455
|
}
|
|
97747
98456
|
function writeChanged(file2, content) {
|
|
97748
98457
|
if (readText(file2) === content) return;
|
|
97749
98458
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
97750
|
-
|
|
97751
|
-
|
|
98459
|
+
writeFileSync32(temp, content, "utf8");
|
|
98460
|
+
renameSync9(temp, file2);
|
|
97752
98461
|
}
|
|
97753
98462
|
function bundledContextPlugin() {
|
|
97754
|
-
const packaged =
|
|
97755
|
-
if (existsSync37(
|
|
97756
|
-
return
|
|
98463
|
+
const packaged = fileURLToPath3(new URL("./resources/context-plugin/", import.meta.url));
|
|
98464
|
+
if (existsSync37(join53(packaged, ".codex-plugin/plugin.json"))) return packaged;
|
|
98465
|
+
return fileURLToPath3(new URL("../dist/resources/context-plugin/", import.meta.url));
|
|
97757
98466
|
}
|
|
97758
98467
|
function refreshCodexContextPlugin(root) {
|
|
97759
|
-
const file2 =
|
|
98468
|
+
const file2 = join53(root, ".agents", "plugins", "marketplace.json");
|
|
97760
98469
|
if (!existsSync37(file2)) return false;
|
|
97761
|
-
const marketplace = JSON.parse(
|
|
98470
|
+
const marketplace = JSON.parse(readFileSync45(file2, "utf8"));
|
|
97762
98471
|
const entries = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
|
|
97763
98472
|
const entry = entries.map(object2).find((value) => value.name === NAME && String(object2(value.source).path).startsWith(PREFIX2));
|
|
97764
98473
|
if (!entry) return false;
|
|
@@ -97769,24 +98478,24 @@ function refreshCodexContextPlugin(root) {
|
|
|
97769
98478
|
function installCodexContextPlugin(root, options = {}) {
|
|
97770
98479
|
const bundle = options.bundle ?? bundledContextPlugin();
|
|
97771
98480
|
const manifest = JSON.parse(
|
|
97772
|
-
|
|
98481
|
+
readFileSync45(join53(bundle, ".codex-plugin/plugin.json"), "utf8")
|
|
97773
98482
|
);
|
|
97774
98483
|
if (manifest.name !== NAME || typeof manifest.version !== "string" || !/^[\w.-]+$/.test(manifest.version)) {
|
|
97775
98484
|
throw new Error("Invalid bundled Errata Context manifest.");
|
|
97776
98485
|
}
|
|
97777
|
-
const checksums =
|
|
98486
|
+
const checksums = readFileSync45(join53(bundle, "SHA256SUMS"), "utf8");
|
|
97778
98487
|
for (const line of checksums.trim().split("\n")) {
|
|
97779
98488
|
const match2 = /^([a-f0-9]{64}) ([\w./-]+)$/.exec(line);
|
|
97780
98489
|
if (!match2 || match2[2].startsWith("/") || match2[2].split("/").includes("..")) {
|
|
97781
98490
|
throw new Error("Invalid bundled Errata Context checksum manifest.");
|
|
97782
98491
|
}
|
|
97783
|
-
const actual =
|
|
98492
|
+
const actual = createHash21("sha256").update(readFileSync45(join53(bundle, match2[2]))).digest("hex");
|
|
97784
98493
|
if (actual !== match2[1])
|
|
97785
98494
|
throw new Error(`Bundled Errata Context checksum mismatch: ${match2[2]}`);
|
|
97786
98495
|
}
|
|
97787
|
-
const release = `${manifest.version}-${
|
|
97788
|
-
const plugin =
|
|
97789
|
-
const marketplaceFile =
|
|
98496
|
+
const release = `${manifest.version}-${createHash21("sha256").update(checksums).digest("hex").slice(0, 12)}`;
|
|
98497
|
+
const plugin = join53(root, ".errata", "plugins", NAME, release);
|
|
98498
|
+
const marketplaceFile = join53(root, ".agents", "plugins", "marketplace.json");
|
|
97790
98499
|
const priorMarketplace = readText(marketplaceFile);
|
|
97791
98500
|
const marketplace = priorMarketplace ? JSON.parse(priorMarketplace) : {
|
|
97792
98501
|
name: "errata-local",
|
|
@@ -97807,12 +98516,12 @@ function installCodexContextPlugin(root, options = {}) {
|
|
|
97807
98516
|
);
|
|
97808
98517
|
}
|
|
97809
98518
|
const key = `${NAME}@${marketplace.name}`;
|
|
97810
|
-
const configFile =
|
|
98519
|
+
const configFile = join53(root, ".codex", "config.toml");
|
|
97811
98520
|
const config2 = readText(configFile);
|
|
97812
98521
|
const parsed = parse4(config2);
|
|
97813
98522
|
const plugins = object2(parsed.plugins);
|
|
97814
|
-
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ??
|
|
97815
|
-
const globalPlugins = object2(parse4(readText(
|
|
98523
|
+
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join53(homedir10(), ".codex");
|
|
98524
|
+
const globalPlugins = object2(parse4(readText(join53(codexHome, "config.toml"))).plugins);
|
|
97816
98525
|
const disabledGlobally = Object.entries(globalPlugins).some(
|
|
97817
98526
|
([name2, value]) => (name2 === NAME || name2.startsWith(`${NAME}@`)) && object2(value).enabled === false
|
|
97818
98527
|
);
|
|
@@ -97836,13 +98545,13 @@ enabled = ${enabled}
|
|
|
97836
98545
|
mkdirSync11(plugin, { recursive: true });
|
|
97837
98546
|
cpSync2(bundle, plugin, { recursive: true });
|
|
97838
98547
|
writeChanged(
|
|
97839
|
-
|
|
98548
|
+
join53(plugin, ".mcp.json"),
|
|
97840
98549
|
JSON.stringify(
|
|
97841
98550
|
{
|
|
97842
98551
|
mcpServers: {
|
|
97843
98552
|
errata_context: {
|
|
97844
98553
|
command: options.nodePath ?? process.execPath,
|
|
97845
|
-
args: [
|
|
98554
|
+
args: [join53(plugin, "dist", "mcp-server.mjs")],
|
|
97846
98555
|
env: { ERRATA_WORKSPACE: root, ERRATA_CONTEXT_VERSION: manifest.version }
|
|
97847
98556
|
}
|
|
97848
98557
|
}
|
|
@@ -97851,8 +98560,8 @@ enabled = ${enabled}
|
|
|
97851
98560
|
2
|
|
97852
98561
|
) + "\n"
|
|
97853
98562
|
);
|
|
97854
|
-
mkdirSync11(
|
|
97855
|
-
mkdirSync11(
|
|
98563
|
+
mkdirSync11(join53(root, ".agents", "plugins"), { recursive: true });
|
|
98564
|
+
mkdirSync11(join53(root, ".codex"), { recursive: true });
|
|
97856
98565
|
writeChanged(marketplaceFile, JSON.stringify(marketplace, null, 2) + "\n");
|
|
97857
98566
|
writeChanged(configFile, nextConfig);
|
|
97858
98567
|
return { plugin, enabled, marketplace: marketplaceFile };
|
|
@@ -97860,15 +98569,15 @@ enabled = ${enabled}
|
|
|
97860
98569
|
|
|
97861
98570
|
// src/codex-hook-refresh.ts
|
|
97862
98571
|
init_checkout_root();
|
|
97863
|
-
import { existsSync as existsSync38, readdirSync as readdirSync14, readFileSync as
|
|
97864
|
-
import { dirname as
|
|
98572
|
+
import { existsSync as existsSync38, readdirSync as readdirSync14, readFileSync as readFileSync46 } from "node:fs";
|
|
98573
|
+
import { dirname as dirname18, join as join54, resolve as resolve8 } from "node:path";
|
|
97865
98574
|
init_registry();
|
|
97866
98575
|
function codexHookRoots(roots) {
|
|
97867
98576
|
const found = new Set(roots.map((root) => resolve8(root)));
|
|
97868
98577
|
for (const root of [...found]) {
|
|
97869
98578
|
const main2 = mainCheckoutOfWorktree(root) ?? root;
|
|
97870
98579
|
found.add(main2);
|
|
97871
|
-
const dir =
|
|
98580
|
+
const dir = join54(main2, ".git", "worktrees");
|
|
97872
98581
|
if (!existsSync38(dir)) continue;
|
|
97873
98582
|
let names;
|
|
97874
98583
|
try {
|
|
@@ -97878,7 +98587,7 @@ function codexHookRoots(roots) {
|
|
|
97878
98587
|
}
|
|
97879
98588
|
for (const name2 of names) {
|
|
97880
98589
|
try {
|
|
97881
|
-
const checkout =
|
|
98590
|
+
const checkout = dirname18(readFileSync46(join54(dir, name2, "gitdir"), "utf8").trim());
|
|
97882
98591
|
if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
|
|
97883
98592
|
} catch {
|
|
97884
98593
|
}
|
|
@@ -97900,50 +98609,50 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
|
|
|
97900
98609
|
}
|
|
97901
98610
|
|
|
97902
98611
|
// 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
|
|
98612
|
+
import { createHash as createHash22 } from "node:crypto";
|
|
98613
|
+
import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync47, readdirSync as readdirSync15, rmSync as rmSync4, statSync as statSync15, writeFileSync as writeFileSync33 } from "node:fs";
|
|
98614
|
+
import { delimiter as delimiter2, dirname as dirname19, join as join55, relative as relative7, resolve as resolve9, sep as sep6 } from "node:path";
|
|
98615
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
97907
98616
|
var CLAUDE_PLUGIN_DIRS_ENV = "CLAUDE_CODE_PLUGIN_DIRS";
|
|
97908
98617
|
var HASH_FILE = ".errata-mod-hash";
|
|
97909
98618
|
function bundledClaudeModsDir() {
|
|
97910
98619
|
const rel = import.meta.url.endsWith(".mjs") ? "./resources/claude-mods/" : "../claude-mods/";
|
|
97911
|
-
return
|
|
98620
|
+
return fileURLToPath4(new URL(rel, import.meta.url));
|
|
97912
98621
|
}
|
|
97913
98622
|
function isEngineOwned(relPath) {
|
|
97914
|
-
const p = relPath.split(
|
|
98623
|
+
const p = relPath.split(sep6).join("/");
|
|
97915
98624
|
return p === ".claude-plugin/types" || p.startsWith(".claude-plugin/types/") || p === HASH_FILE;
|
|
97916
98625
|
}
|
|
97917
98626
|
function listFiles(root, dir = root) {
|
|
97918
98627
|
const out2 = [];
|
|
97919
98628
|
for (const name2 of readdirSync15(dir)) {
|
|
97920
|
-
const abs =
|
|
97921
|
-
if (isEngineOwned(
|
|
97922
|
-
if (
|
|
98629
|
+
const abs = join55(dir, name2);
|
|
98630
|
+
if (isEngineOwned(relative7(root, abs))) continue;
|
|
98631
|
+
if (statSync15(abs).isDirectory()) out2.push(...listFiles(root, abs));
|
|
97923
98632
|
else out2.push(abs);
|
|
97924
98633
|
}
|
|
97925
98634
|
return out2;
|
|
97926
98635
|
}
|
|
97927
98636
|
function modHash(dir) {
|
|
97928
|
-
const h =
|
|
98637
|
+
const h = createHash22("sha256");
|
|
97929
98638
|
for (const abs of listFiles(dir).sort()) {
|
|
97930
|
-
h.update(
|
|
98639
|
+
h.update(relative7(dir, abs).split(sep6).join("/"));
|
|
97931
98640
|
h.update("\0");
|
|
97932
|
-
h.update(
|
|
98641
|
+
h.update(readFileSync47(abs));
|
|
97933
98642
|
h.update("\0");
|
|
97934
98643
|
}
|
|
97935
98644
|
return h.digest("hex");
|
|
97936
98645
|
}
|
|
97937
98646
|
function bundledMods(bundleDir) {
|
|
97938
98647
|
if (!existsSync39(bundleDir)) return [];
|
|
97939
|
-
return readdirSync15(bundleDir).filter((name2) => existsSync39(
|
|
98648
|
+
return readdirSync15(bundleDir).filter((name2) => existsSync39(join55(bundleDir, name2, ".claude-plugin", "plugin.json")));
|
|
97940
98649
|
}
|
|
97941
98650
|
function sameDir(a, b) {
|
|
97942
98651
|
const norm = (p) => resolve9(p).replace(/[\\/]+$/, "").toLowerCase();
|
|
97943
98652
|
return norm(a) === norm(b);
|
|
97944
98653
|
}
|
|
97945
98654
|
function isUnder(path3, root) {
|
|
97946
|
-
const rel =
|
|
98655
|
+
const rel = relative7(resolve9(root), resolve9(path3));
|
|
97947
98656
|
return rel !== "" && !rel.startsWith("..") && !rel.includes(":");
|
|
97948
98657
|
}
|
|
97949
98658
|
function off(env2) {
|
|
@@ -97953,7 +98662,7 @@ function off(env2) {
|
|
|
97953
98662
|
function readSettings(path3) {
|
|
97954
98663
|
if (!existsSync39(path3)) return {};
|
|
97955
98664
|
try {
|
|
97956
|
-
const parsed = JSON.parse(
|
|
98665
|
+
const parsed = JSON.parse(readFileSync47(path3, "utf8"));
|
|
97957
98666
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
97958
98667
|
return parsed;
|
|
97959
98668
|
} catch {
|
|
@@ -97977,13 +98686,13 @@ function currentDirs(settings) {
|
|
|
97977
98686
|
return raw2.split(delimiter2).map((s) => s.trim()).filter(Boolean);
|
|
97978
98687
|
}
|
|
97979
98688
|
function writeSettings(path3, settings) {
|
|
97980
|
-
mkdirSync12(
|
|
97981
|
-
|
|
98689
|
+
mkdirSync12(dirname19(path3), { recursive: true });
|
|
98690
|
+
writeFileSync33(path3, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
97982
98691
|
}
|
|
97983
98692
|
function ensureClaudeMods(opts) {
|
|
97984
98693
|
const env2 = opts.env ?? process.env;
|
|
97985
98694
|
const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
|
|
97986
|
-
const modsRoot =
|
|
98695
|
+
const modsRoot = join55(opts.installRoot, "claude-mods");
|
|
97987
98696
|
if (off(env2)) {
|
|
97988
98697
|
const settings2 = readSettings(settingsPath);
|
|
97989
98698
|
if (!settings2) return { kind: "unreadable" };
|
|
@@ -98000,14 +98709,14 @@ function ensureClaudeMods(opts) {
|
|
|
98000
98709
|
let changed = false;
|
|
98001
98710
|
const installed = [];
|
|
98002
98711
|
for (const name2 of names) {
|
|
98003
|
-
const src =
|
|
98004
|
-
const dest =
|
|
98712
|
+
const src = join55(bundleDir, name2);
|
|
98713
|
+
const dest = join55(modsRoot, name2);
|
|
98005
98714
|
const hash2 = modHash(src);
|
|
98006
|
-
const hashFile =
|
|
98007
|
-
if (!existsSync39(hashFile) ||
|
|
98715
|
+
const hashFile = join55(dest, HASH_FILE);
|
|
98716
|
+
if (!existsSync39(hashFile) || readFileSync47(hashFile, "utf8") !== hash2) {
|
|
98008
98717
|
rmSync4(dest, { recursive: true, force: true });
|
|
98009
|
-
cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(
|
|
98010
|
-
|
|
98718
|
+
cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative7(src, p)) });
|
|
98719
|
+
writeFileSync33(hashFile, hash2, "utf8");
|
|
98011
98720
|
changed = true;
|
|
98012
98721
|
}
|
|
98013
98722
|
installed.push(dest);
|
|
@@ -98426,9 +99135,9 @@ function resolveHookPort(explicit) {
|
|
|
98426
99135
|
}
|
|
98427
99136
|
}
|
|
98428
99137
|
}
|
|
98429
|
-
const settingsPath =
|
|
99138
|
+
const settingsPath = join56(ROOT, ".claude", "settings.json");
|
|
98430
99139
|
try {
|
|
98431
|
-
if (existsSync40(settingsPath)) return installedHookPort(
|
|
99140
|
+
if (existsSync40(settingsPath)) return installedHookPort(readFileSync48(settingsPath, "utf8")) ?? 7891;
|
|
98432
99141
|
} catch {
|
|
98433
99142
|
}
|
|
98434
99143
|
return 7891;
|
|
@@ -98454,13 +99163,13 @@ async function cmdInit() {
|
|
|
98454
99163
|
console.log("");
|
|
98455
99164
|
console.log("installing harness hooks...");
|
|
98456
99165
|
const { existsSync: existsSync41 } = await import("node:fs");
|
|
98457
|
-
const { join:
|
|
99166
|
+
const { join: join57 } = await import("node:path");
|
|
98458
99167
|
try {
|
|
98459
99168
|
await installClaudeHooks(port);
|
|
98460
99169
|
} catch (err2) {
|
|
98461
99170
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
98462
99171
|
}
|
|
98463
|
-
if (existsSync41(
|
|
99172
|
+
if (existsSync41(join57(ROOT, ".cursor"))) {
|
|
98464
99173
|
try {
|
|
98465
99174
|
await installCursorMcpConfig();
|
|
98466
99175
|
} catch (err2) {
|
|
@@ -99683,7 +100392,7 @@ async function cmdReview() {
|
|
|
99683
100392
|
console.log("(review queue empty)");
|
|
99684
100393
|
return;
|
|
99685
100394
|
}
|
|
99686
|
-
const queue = JSON.parse(
|
|
100395
|
+
const queue = JSON.parse(readFileSync48(paths.reviewQueue, "utf8"));
|
|
99687
100396
|
if (queue.length === 0) {
|
|
99688
100397
|
console.log("(review queue empty)");
|
|
99689
100398
|
return;
|
|
@@ -100422,7 +101131,7 @@ async function gatherReportData(generatedAt) {
|
|
|
100422
101131
|
};
|
|
100423
101132
|
}
|
|
100424
101133
|
async function cmdReport(args2) {
|
|
100425
|
-
const { mkdirSync: mkdirSync13, writeFileSync:
|
|
101134
|
+
const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
100426
101135
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
100427
101136
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
100428
101137
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -100435,8 +101144,8 @@ async function cmdReport(args2) {
|
|
|
100435
101144
|
const outDir = workspacePaths(ROOT).configDir;
|
|
100436
101145
|
mkdirSync13(outDir, { recursive: true });
|
|
100437
101146
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
100438
|
-
for (const f of files)
|
|
100439
|
-
const indexPath =
|
|
101147
|
+
for (const f of files) writeFileSync34(join56(outDir, f.name), f.html, "utf8");
|
|
101148
|
+
const indexPath = join56(outDir, "report.html");
|
|
100440
101149
|
console.log(`report \u2192 ${indexPath}`);
|
|
100441
101150
|
console.log(
|
|
100442
101151
|
` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
|
|
@@ -100492,7 +101201,7 @@ function spawnDaemonDetached(options = {}) {
|
|
|
100492
101201
|
try {
|
|
100493
101202
|
const logPath = daemonLogPath();
|
|
100494
101203
|
try {
|
|
100495
|
-
if (
|
|
101204
|
+
if (statSync16(logPath).size > 5 * 1024 * 1024) renameSync10(logPath, `${logPath}.1`);
|
|
100496
101205
|
} catch {
|
|
100497
101206
|
}
|
|
100498
101207
|
out2 = openSync3(logPath, "a");
|
|
@@ -100561,24 +101270,24 @@ async function cmdInstallHooks(args2) {
|
|
|
100561
101270
|
}
|
|
100562
101271
|
}
|
|
100563
101272
|
async function installOpencodePlugin(port) {
|
|
100564
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100565
|
-
const { join:
|
|
100566
|
-
const dir =
|
|
101273
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
101274
|
+
const { join: join57 } = await import("node:path");
|
|
101275
|
+
const dir = join57(ROOT, ".opencode", "plugin");
|
|
100567
101276
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100568
|
-
const file2 =
|
|
101277
|
+
const file2 = join57(dir, "inerrata.js");
|
|
100569
101278
|
if (existsSync41(file2)) {
|
|
100570
|
-
const head2 =
|
|
101279
|
+
const head2 = readFileSync49(file2, "utf8").split("\n")[0] ?? "";
|
|
100571
101280
|
if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
|
|
100572
101281
|
console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
|
|
100573
101282
|
process.exit(2);
|
|
100574
101283
|
}
|
|
100575
101284
|
}
|
|
100576
|
-
|
|
100577
|
-
const cfgFile =
|
|
101285
|
+
writeFileSync34(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
|
|
101286
|
+
const cfgFile = join57(ROOT, "opencode.json");
|
|
100578
101287
|
let cfg = { $schema: "https://opencode.ai/config.json" };
|
|
100579
101288
|
if (existsSync41(cfgFile)) {
|
|
100580
101289
|
try {
|
|
100581
|
-
cfg = JSON.parse(
|
|
101290
|
+
cfg = JSON.parse(readFileSync49(cfgFile, "utf8"));
|
|
100582
101291
|
} catch {
|
|
100583
101292
|
console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
|
|
100584
101293
|
process.exit(2);
|
|
@@ -100589,7 +101298,7 @@ async function installOpencodePlugin(port) {
|
|
|
100589
101298
|
if (!hadErrata) {
|
|
100590
101299
|
const inv = errataMcpInvocation();
|
|
100591
101300
|
cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
|
|
100592
|
-
|
|
101301
|
+
writeFileSync34(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
100593
101302
|
}
|
|
100594
101303
|
console.log(`installed OpenCode plugin \u2192 ${file2}`);
|
|
100595
101304
|
if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
|
|
@@ -100624,15 +101333,15 @@ function installClaudeMods() {
|
|
|
100624
101333
|
}
|
|
100625
101334
|
}
|
|
100626
101335
|
async function installClaudeHooks(port) {
|
|
100627
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100628
|
-
const { join:
|
|
100629
|
-
const dir =
|
|
101336
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
101337
|
+
const { join: join57 } = await import("node:path");
|
|
101338
|
+
const dir = join57(ROOT, ".claude");
|
|
100630
101339
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100631
|
-
const file2 =
|
|
101340
|
+
const file2 = join57(dir, "settings.json");
|
|
100632
101341
|
let settings = {};
|
|
100633
101342
|
if (existsSync41(file2)) {
|
|
100634
101343
|
try {
|
|
100635
|
-
settings = JSON.parse(
|
|
101344
|
+
settings = JSON.parse(readFileSync49(file2, "utf8"));
|
|
100636
101345
|
} catch {
|
|
100637
101346
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
100638
101347
|
process.exit(2);
|
|
@@ -100681,12 +101390,12 @@ async function installClaudeHooks(port) {
|
|
|
100681
101390
|
list.push({ hooks: [{ type: "command", command: injectCmd }] });
|
|
100682
101391
|
}
|
|
100683
101392
|
removeProjectStatusLine(settings);
|
|
100684
|
-
|
|
101393
|
+
writeFileSync34(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
100685
101394
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
100686
101395
|
console.log(` ${ensureStatusLine(port)}`);
|
|
100687
101396
|
console.log(` ${installClaudeMods().line}`);
|
|
100688
101397
|
await installClaudeMcpConfig();
|
|
100689
|
-
const claudeMd =
|
|
101398
|
+
const claudeMd = join57(ROOT, "CLAUDE.md");
|
|
100690
101399
|
const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
|
|
100691
101400
|
if (recall.kind === "collision") {
|
|
100692
101401
|
console.warn(
|
|
@@ -100698,15 +101407,15 @@ async function installClaudeHooks(port) {
|
|
|
100698
101407
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
100699
101408
|
}
|
|
100700
101409
|
async function installClaudeMcpConfig() {
|
|
100701
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100702
|
-
const { join:
|
|
100703
|
-
const file2 =
|
|
100704
|
-
const dir =
|
|
101410
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
101411
|
+
const { join: join57, dirname: dirname20 } = await import("node:path");
|
|
101412
|
+
const file2 = join57(ROOT, ".mcp.json");
|
|
101413
|
+
const dir = dirname20(file2);
|
|
100705
101414
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100706
101415
|
let cfg = {};
|
|
100707
101416
|
if (existsSync41(file2)) {
|
|
100708
101417
|
try {
|
|
100709
|
-
cfg = JSON.parse(
|
|
101418
|
+
cfg = JSON.parse(readFileSync49(file2, "utf8"));
|
|
100710
101419
|
} catch {
|
|
100711
101420
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
100712
101421
|
process.exit(2);
|
|
@@ -100714,21 +101423,21 @@ async function installClaudeMcpConfig() {
|
|
|
100714
101423
|
}
|
|
100715
101424
|
cfg.mcpServers ??= {};
|
|
100716
101425
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
100717
|
-
|
|
101426
|
+
writeFileSync34(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
100718
101427
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
100719
101428
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
100720
101429
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
100721
101430
|
}
|
|
100722
101431
|
async function installCursorMcpConfig() {
|
|
100723
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync:
|
|
100724
|
-
const { join:
|
|
100725
|
-
const dir =
|
|
101432
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
|
|
101433
|
+
const { join: join57 } = await import("node:path");
|
|
101434
|
+
const dir = join57(ROOT, ".cursor");
|
|
100726
101435
|
if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
|
|
100727
|
-
const file2 =
|
|
101436
|
+
const file2 = join57(dir, "mcp.json");
|
|
100728
101437
|
let cfg = {};
|
|
100729
101438
|
if (existsSync41(file2)) {
|
|
100730
101439
|
try {
|
|
100731
|
-
cfg = JSON.parse(
|
|
101440
|
+
cfg = JSON.parse(readFileSync49(file2, "utf8"));
|
|
100732
101441
|
} catch {
|
|
100733
101442
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
100734
101443
|
process.exit(2);
|
|
@@ -100736,7 +101445,7 @@ async function installCursorMcpConfig() {
|
|
|
100736
101445
|
}
|
|
100737
101446
|
cfg.mcpServers ??= {};
|
|
100738
101447
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
100739
|
-
|
|
101448
|
+
writeFileSync34(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
100740
101449
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
100741
101450
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
100742
101451
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -100747,7 +101456,7 @@ async function installCodexHooks(port) {
|
|
|
100747
101456
|
const gitRoot = nearestGitRoot(process.cwd());
|
|
100748
101457
|
const hookRoot = gitRoot && mainCheckoutOfWorktree(gitRoot) ? gitRoot : ROOT;
|
|
100749
101458
|
const file2 = writeCodexHooks(hookRoot, port);
|
|
100750
|
-
const instructions = writeManagedBlock(
|
|
101459
|
+
const instructions = writeManagedBlock(join56(hookRoot, "AGENTS.md"), {
|
|
100751
101460
|
body: AGENTS_POINTER_BODY,
|
|
100752
101461
|
stable: true
|
|
100753
101462
|
});
|
|
@@ -101193,9 +101902,9 @@ async function cmdDash(args2) {
|
|
|
101193
101902
|
await yieldToLoop2();
|
|
101194
101903
|
try {
|
|
101195
101904
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
|
|
101196
|
-
atCommit: readGitRefState(
|
|
101905
|
+
atCommit: readGitRefState(join56(r.root, ".git")).sha ?? void 0
|
|
101197
101906
|
});
|
|
101198
|
-
const res = bleedRules(
|
|
101907
|
+
const res = bleedRules(join56(r.root, ".claude", "rules"), items);
|
|
101199
101908
|
if (res.written || res.pruned) {
|
|
101200
101909
|
console.log(
|
|
101201
101910
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|