@inerrata-corporation/errata 2.0.17-dev.3421 → 2.0.17-dev.3433

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/errata.mjs CHANGED
@@ -960,7 +960,7 @@ function lemma(token) {
960
960
  }
961
961
  return token;
962
962
  }
963
- function tokenize(text, resolve8) {
963
+ function tokenize(text, resolve9) {
964
964
  const matches = text.normalize("NFC").toLowerCase().match(TOKEN_RE) ?? [];
965
965
  const out2 = /* @__PURE__ */ new Set();
966
966
  for (const raw2 of matches) {
@@ -970,7 +970,7 @@ function tokenize(text, resolve8) {
970
970
  out2.add(token);
971
971
  continue;
972
972
  }
973
- const canonical = resolve8(token);
973
+ const canonical = resolve9(token);
974
974
  out2.add(canonical ?? lemma(token));
975
975
  }
976
976
  return [...out2].sort();
@@ -17838,13 +17838,13 @@ function loadNodeSqlite() {
17838
17838
  process.emitWarning = original;
17839
17839
  }
17840
17840
  }
17841
- function openDatabase(path2) {
17842
- const db = new DatabaseSync(path2);
17841
+ function openDatabase(path2, opts) {
17842
+ const db = opts ? new DatabaseSync(path2, opts) : new DatabaseSync(path2);
17843
17843
  try {
17844
17844
  db.exec("PRAGMA foreign_keys = ON");
17845
17845
  } catch {
17846
17846
  }
17847
- if (path2 !== ":memory:") {
17847
+ if (path2 !== ":memory:" && !opts?.readOnly) {
17848
17848
  try {
17849
17849
  db.exec("PRAGMA journal_mode = WAL");
17850
17850
  db.exec("PRAGMA synchronous = NORMAL");
@@ -17945,7 +17945,7 @@ var init_src2 = __esm({
17945
17945
 
17946
17946
  // ../../packages/local-graph/src/history-cache-floor.ts
17947
17947
  function installHistoryCacheFloor(db) {
17948
- const key = "history-cache-withdrawal-floor-3";
17948
+ const key = HISTORY_CACHE_FLOOR_KEY;
17949
17949
  if (db.prepare("SELECT value FROM store_meta WHERE key = ?").get(key)) return;
17950
17950
  db.transaction(() => {
17951
17951
  db.exec("DROP TRIGGER IF EXISTS history_cache_nodes_insert; DROP TRIGGER IF EXISTS history_cache_nodes_update;");
@@ -18001,9 +18001,11 @@ function installHistoryCacheFloor(db) {
18001
18001
  db.prepare("INSERT INTO store_meta(key,value) VALUES (?,?)").run(key, "installed");
18002
18002
  });
18003
18003
  }
18004
+ var HISTORY_CACHE_FLOOR_KEY;
18004
18005
  var init_history_cache_floor = __esm({
18005
18006
  "../../packages/local-graph/src/history-cache-floor.ts"() {
18006
18007
  "use strict";
18008
+ HISTORY_CACHE_FLOOR_KEY = "history-cache-withdrawal-floor-3";
18007
18009
  }
18008
18010
  });
18009
18011
 
@@ -18095,6 +18097,23 @@ function localEdgeViolation(fromLabel, type, toLabel) {
18095
18097
  const verdict = isValidEdge(fromLabel, type, toLabel);
18096
18098
  return verdict.ok ? null : verdict.reason ?? "edge rule violation";
18097
18099
  }
18100
+ function graphStoreNeedsPreparation(path2) {
18101
+ if (path2 === ":memory:") return false;
18102
+ let db;
18103
+ try {
18104
+ db = openDatabase(path2, { readOnly: true });
18105
+ if (db.prepare("SELECT version FROM schema_version LIMIT 1").get()?.["version"] !== SCHEMA_VERSION) return true;
18106
+ const indexes = new Set(db.prepare("SELECT name FROM sqlite_master WHERE type = 'index'").all().map((r) => r["name"]));
18107
+ for (const match2 of (SCHEMA_SQL + TEMPORAL_INDEX_SQL).matchAll(/CREATE INDEX IF NOT EXISTS (\w+)/g)) {
18108
+ if (!indexes.has(match2[1])) return true;
18109
+ }
18110
+ return [SESSION_REPAIR_KEY, HISTORY_CACHE_FLOOR_KEY].some((key) => !db.prepare("SELECT value FROM store_meta WHERE key = ?").get(key));
18111
+ } catch {
18112
+ return true;
18113
+ } finally {
18114
+ db?.close();
18115
+ }
18116
+ }
18098
18117
  function encodeEmbedding(emb) {
18099
18118
  if (!emb || emb.length === 0) return null;
18100
18119
  const f = Float32Array.from(emb);
@@ -18155,7 +18174,7 @@ function rowToEdge(r) {
18155
18174
  function openGraphStore(opts) {
18156
18175
  return new SqliteGraphStore(opts);
18157
18176
  }
18158
- var LOCAL_RULE_OVERRIDES, SCHEMA_VERSION, SESSION_EVIDENCE_PREDICATE, SCHEMA_SQL, TEMPORAL_INDEX_SQL, FINGERPRINT_INDEXED_LABELS, SqliteGraphStore;
18177
+ var LOCAL_RULE_OVERRIDES, SCHEMA_VERSION, SESSION_REPAIR_KEY, SESSION_EVIDENCE_PREDICATE, SCHEMA_SQL, TEMPORAL_INDEX_SQL, FINGERPRINT_INDEXED_LABELS, SqliteGraphStore;
18159
18178
  var init_store = __esm({
18160
18179
  "../../packages/local-graph/src/store.ts"() {
18161
18180
  "use strict";
@@ -18186,6 +18205,7 @@ var init_store = __esm({
18186
18205
  REGRESSION_OF: { from: ["Problem"], to: ["Problem"] }
18187
18206
  };
18188
18207
  SCHEMA_VERSION = 6;
18208
+ SESSION_REPAIR_KEY = "session-evidence-v1";
18189
18209
  SESSION_EVIDENCE_PREDICATE = SESSION_EVIDENCE_FIELDS.map((field) => `instr(attrs_json, '${JSON.stringify(field)}') > 0`).join(" OR ");
18190
18210
  SCHEMA_SQL = `
18191
18211
  CREATE TABLE IF NOT EXISTS schema_version (
@@ -18340,10 +18360,10 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
18340
18360
  }
18341
18361
  this.db.exec(TEMPORAL_INDEX_SQL);
18342
18362
  installHistoryCacheFloor(this.db);
18343
- if (!this.db.prepare("SELECT value FROM store_meta WHERE key = 'session-evidence-v1'").get()) {
18363
+ if (!this.db.prepare("SELECT value FROM store_meta WHERE key = ?").get(SESSION_REPAIR_KEY)) {
18344
18364
  this.db.transaction(() => {
18345
18365
  this.repairSessionAliases();
18346
- this.db.prepare("INSERT OR REPLACE INTO store_meta (key, value) VALUES ('session-evidence-v1', 'done')").run();
18366
+ this.db.prepare("INSERT OR REPLACE INTO store_meta (key, value) VALUES (?, 'done')").run(SESSION_REPAIR_KEY);
18347
18367
  });
18348
18368
  }
18349
18369
  this.stmts = {
@@ -18538,6 +18558,34 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
18538
18558
  const seqRow = this.db.prepare("SELECT value FROM store_meta WHERE key = 'ingest_seq'").get();
18539
18559
  this.ingestSeq = seqRow ? Number(seqRow.value) : 0;
18540
18560
  }
18561
+ strandedSymbols() {
18562
+ return this.db.prepare(`
18563
+ SELECT f.id AS fileId, e.to_id AS symbolId
18564
+ -- Start from the small File population. An unconstrained JOIN lets
18565
+ -- SQLite start at edges_live and visit every live edge in the graph.
18566
+ FROM nodes f CROSS JOIN edges e ON e.from_id = f.id
18567
+ LEFT JOIN nodes t ON t.id = e.to_id
18568
+ WHERE f.label = 'File' AND f.valid_to IS NULL AND e.valid_to IS NULL
18569
+ AND e.type IN ('DEFINES', 'CONTAINS')
18570
+ AND (t.id IS NULL OR t.valid_to IS NOT NULL)
18571
+ `).all();
18572
+ }
18573
+ fileIndexStates(ids) {
18574
+ if (ids.length === 0) return [];
18575
+ if (ids.length > 500) throw new RangeError("fileIndexStates accepts at most 500 ids per read");
18576
+ const rows = this.db.prepare(`
18577
+ SELECT f.id, f.last_updated_at AS lastUpdatedAt, f.valid_to AS validTo,
18578
+ CASE WHEN count(e.id) = 0 THEN
18579
+ (json_type(f.attrs_json, '$.symbolCount') IN ('integer','real') AND json_extract(f.attrs_json, '$.symbolCount') = 0)
18580
+ OR json_type(f.attrs_json, '$.indexSkipped') = 'text'
18581
+ ELSE max(CASE WHEN t.id IS NULL OR t.valid_to IS NOT NULL THEN 1 ELSE 0 END) = 0 END AS complete
18582
+ FROM nodes f
18583
+ LEFT JOIN edges e ON e.from_id = f.id AND e.valid_to IS NULL AND e.type IN ('DEFINES','CONTAINS')
18584
+ LEFT JOIN nodes t ON t.id = e.to_id
18585
+ WHERE f.id IN (${ids.map(() => "?").join(",")}) GROUP BY f.id
18586
+ `).all(...ids);
18587
+ return rows.map((row) => ({ ...row, complete: row.complete === 1 }));
18588
+ }
18541
18589
  /** Forward-migrate the on-disk schema to the current SCHEMA_VERSION. */
18542
18590
  migrate(from) {
18543
18591
  this.db.transaction(() => {
@@ -23353,7 +23401,7 @@ function triageOf(l2, q, mathOpts) {
23353
23401
  if (!triage) return { triage: "", presenting: presentingId, routes: [] };
23354
23402
  const seen = triage.attrs["perContextSeen"] ?? {};
23355
23403
  const buckets = q.context ? triageContextBuckets(canonicalizeContext(q.context)) : [];
23356
- const active2 = new Set(q.activeProblemIds ?? []);
23404
+ const active3 = new Set(q.activeProblemIds ?? []);
23357
23405
  const routes = [];
23358
23406
  for (const e of l2.outEdges(triageId, [...ROUTE_EDGE_TYPES])) {
23359
23407
  const perContext = e.attrs["perContext"] ?? {};
@@ -23374,13 +23422,13 @@ function triageOf(l2, q, mathOpts) {
23374
23422
  }
23375
23423
  const post = triagePosterior(counts, buckets, mathOpts);
23376
23424
  let probability = post.probability;
23377
- if (active2.size > 0) {
23425
+ if (active3.size > 0) {
23378
23426
  const neighbors = /* @__PURE__ */ new Set([
23379
23427
  ...l2.outEdges(e.to).map((x) => x.to),
23380
23428
  ...l2.inEdges(e.to).map((x) => x.from)
23381
23429
  ]);
23382
23430
  let hits = 0;
23383
- for (const id of active2) if (neighbors.has(id)) hits++;
23431
+ for (const id of active3) if (neighbors.has(id)) hits++;
23384
23432
  if (hits > 0) probability = Math.min(1, probability * (1 + COOCCUR_BONUS * Math.tanh(hits)));
23385
23433
  }
23386
23434
  const cause = l2.getNode(e.to);
@@ -24990,6 +25038,7 @@ __export(src_exports2, {
24990
25038
  foldSameAnchorProblem: () => foldSameAnchorProblem,
24991
25039
  formatMechanismStatus: () => formatMechanismStatus,
24992
25040
  getClaim: () => getClaim,
25041
+ graphStoreNeedsPreparation: () => graphStoreNeedsPreparation,
24993
25042
  harvestAbstractionFences: () => harvestAbstractionFences,
24994
25043
  harvestTriageFences: () => harvestTriageFences,
24995
25044
  hasStarvedMechanism: () => hasStarvedMechanism,
@@ -25119,11 +25168,13 @@ function buildSnapshot(opts) {
25119
25168
  const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
25120
25169
  const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
25121
25170
  allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
25122
- const recent3 = allProblems.slice(0, 8).map((p) => ({
25171
+ const openPool = allProblems.slice(0, RECENT_OPEN * SCOPE_POOL_FACTOR).map((p) => ({
25123
25172
  node: p,
25124
25173
  anchors: opts.store.outEdges(p.id, ["MANIFESTED_IN", "EVIDENCED_BY"])
25125
25174
  }));
25126
- const recentConstraints = stillOpen.filter((p) => isConstraintProblem(p)).sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, 3);
25175
+ const recent4 = openPool.slice(0, RECENT_OPEN);
25176
+ const constraintPool = stillOpen.filter((p) => isConstraintProblem(p)).sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR);
25177
+ const recentConstraints = constraintPool.slice(0, RECENT_CONSTRAINTS);
25127
25178
  const regressions = problems.filter((p) => p.attrs["resolvedAt"] == null && p.attrs["mergedInto"] === void 0).flatMap(
25128
25179
  (open2) => opts.store.outEdges(open2.id, ["REGRESSION_OF"]).flatMap((e) => {
25129
25180
  const closed = opts.store.getNode(e.to);
@@ -25136,11 +25187,12 @@ function buildSnapshot(opts) {
25136
25187
  })
25137
25188
  ).sort((a, b) => Number(b.closed.attrs["recurredAt"] ?? 0) - Number(a.closed.attrs["recurredAt"] ?? 0)).slice(0, 2);
25138
25189
  const regressionClosedIds = new Set(regressions.map((r) => r.closed.id));
25139
- const recentResolved = problems.filter((p) => p.attrs["resolvedAt"] != null && p.attrs["resolvedAs"] == null).filter((p) => !regressionClosedIds.has(p.id)).sort((a, b) => Number(b.attrs["resolvedAt"] ?? 0) - Number(a.attrs["resolvedAt"] ?? 0)).slice(0, 4).map((p) => {
25190
+ const resolvedPool = problems.filter((p) => p.attrs["resolvedAt"] != null && p.attrs["resolvedAs"] == null).filter((p) => !regressionClosedIds.has(p.id)).sort((a, b) => Number(b.attrs["resolvedAt"] ?? 0) - Number(a.attrs["resolvedAt"] ?? 0)).slice(0, RECENT_RESOLVED * SCOPE_POOL_FACTOR).map((p) => {
25140
25191
  const solEdge = opts.store.outEdges(p.id, ["SOLVED_BY"])[0];
25141
25192
  const solution = solEdge ? opts.store.getNode(solEdge.to) ?? void 0 : void 0;
25142
25193
  return { node: p, ...solution ? { solution } : {} };
25143
25194
  });
25195
+ const recentResolved = resolvedPool.slice(0, RECENT_RESOLVED);
25144
25196
  const motifs = [
25145
25197
  ...opts.store.findNodesByLabel("Pattern"),
25146
25198
  ...opts.store.findNodesByLabel("Technique"),
@@ -25192,10 +25244,10 @@ function buildSnapshot(opts) {
25192
25244
  packages: opts.profile.stack.map((name2) => ({ name: name2, node: matchNode(pkgNodes, pkgBase(name2)) })),
25193
25245
  tools: toolNodes.map((node2) => ({ name: String(node2.attrs["name"] ?? node2.description), node: node2 }))
25194
25246
  };
25195
- const causalNudge = recent3.length >= 2 && recent3.every(
25247
+ const causalNudge = recent4.length >= 2 && recent4.every(
25196
25248
  (r) => opts.store.outEdges(r.node.id, ["CAUSED_BY"]).length === 0 && opts.store.inEdges(r.node.id, ["CAUSED_BY"]).length === 0
25197
25249
  );
25198
- const abstractUndomained = recent3.filter((r) => {
25250
+ const abstractUndomained = recent4.filter((r) => {
25199
25251
  const grounded = opts.store.outEdges(r.node.id, ["ANCHORED_AT", "OCCURS_IN", "DEPENDS_ON"]).length > 0;
25200
25252
  const hasDomain = opts.store.outEdges(r.node.id, ["PERTAIN_TO"]).length > 0;
25201
25253
  return !grounded && !hasDomain;
@@ -25204,7 +25256,7 @@ function buildSnapshot(opts) {
25204
25256
  return {
25205
25257
  profile: opts.profile,
25206
25258
  profileContext,
25207
- recentProblems: recent3,
25259
+ recentProblems: recent4,
25208
25260
  recentResolved,
25209
25261
  recentConstraints,
25210
25262
  regressions,
@@ -25218,9 +25270,23 @@ function buildSnapshot(opts) {
25218
25270
  pendingEnrichment,
25219
25271
  skills: opts.skills ?? [],
25220
25272
  needsRevisit,
25273
+ scopePool: { open: openPool, resolved: resolvedPool, constraints: constraintPool },
25221
25274
  generatedAt: (opts.now ?? /* @__PURE__ */ new Date()).toISOString()
25222
25275
  };
25223
25276
  }
25277
+ function scopeSnapshot(s, keep) {
25278
+ const pool = s.scopePool;
25279
+ if (!pool) return s;
25280
+ const open2 = pool.open.filter((r) => keep(r.node));
25281
+ return {
25282
+ ...s,
25283
+ recentProblems: open2.slice(0, RECENT_OPEN),
25284
+ recentResolved: pool.resolved.filter((r) => keep(r.node)).slice(0, RECENT_RESOLVED),
25285
+ recentConstraints: pool.constraints.filter(keep).slice(0, RECENT_CONSTRAINTS),
25286
+ regressions: s.regressions.filter((r) => keep(r.open)),
25287
+ scopePool: { ...pool, open: open2 }
25288
+ };
25289
+ }
25224
25290
  function sliceForFile(store, relPath, atCommit) {
25225
25291
  const candidates = store.findNodesByLabel("File");
25226
25292
  const file2 = candidates.find((n) => n.description === relPath);
@@ -25688,6 +25754,7 @@ function isolateSnapshot(s) {
25688
25754
  causalNudge: _causalNudge,
25689
25755
  domainNudge: _domainNudge,
25690
25756
  sharedPriors: _sharedPriors,
25757
+ scopePool: _scopePool,
25691
25758
  ...graphWide
25692
25759
  } = s;
25693
25760
  return {
@@ -25773,13 +25840,17 @@ function diffRenderLedger(before, after) {
25773
25840
  for (const i2 of before) (survived.has(key(i2)) ? shown : evicted).push(i2);
25774
25841
  return { shown, evicted };
25775
25842
  }
25776
- var RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, SPAWN_SHARE_HINT, SUBAGENT_OWN_BLOCK_NOTE, EVICTION_ORDER, MOTIF_FLOOR, REMOTE_FLOOR, PROBLEM_FLOOR, REVIEW_ITEM_FLOOR, DEFAULT_AGENT_CONTEXT_BUDGET;
25843
+ var RECENT_OPEN, RECENT_RESOLVED, RECENT_CONSTRAINTS, SCOPE_POOL_FACTOR, RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, SPAWN_SHARE_HINT, SUBAGENT_OWN_BLOCK_NOTE, EVICTION_ORDER, MOTIF_FLOOR, REMOTE_FLOOR, PROBLEM_FLOOR, REVIEW_ITEM_FLOOR, DEFAULT_AGENT_CONTEXT_BUDGET;
25777
25844
  var init_render = __esm({
25778
25845
  "../../packages/context-writer/src/render.ts"() {
25779
25846
  "use strict";
25780
25847
  init_src5();
25781
25848
  init_src2();
25782
25849
  init_src();
25850
+ RECENT_OPEN = 8;
25851
+ RECENT_RESOLVED = 4;
25852
+ RECENT_CONSTRAINTS = 3;
25853
+ SCOPE_POOL_FACTOR = 3;
25783
25854
  RECALL_FIRST_HEADER = "## errata \u2014 recall before you work";
25784
25855
  RECALL_FIRST_BODY = "Before investigating any bug or error, your FIRST tool call must be `mcp__errata__errata_search` with a few words describing the problem. This machine's knowledge graph records previously solved problems \u2014 the answer may already be recorded. Read what it returns before touching any files.";
25785
25856
  RECALL_FIRST_BLOCK = `${RECALL_FIRST_HEADER}
@@ -26575,11 +26646,27 @@ var init_client = __esm({
26575
26646
  }
26576
26647
  }
26577
26648
  for (const edgeChunk of chunkArray(pendingEdges, MAX_EDGES_PER_PAYLOAD)) {
26578
- const rewritten = edgeChunk.map((e) => ({
26649
+ const projected = edgeChunk.map((e) => ({
26579
26650
  ...e,
26580
26651
  from: echoedCloudId.get(e.from) ?? e.from,
26581
26652
  to: echoedCloudId.get(e.to) ?? e.to
26582
26653
  }));
26654
+ const rewritten = projected.filter((e, i2) => {
26655
+ if (e.from !== e.to) return true;
26656
+ const original = edgeChunk[i2];
26657
+ merged.edges.push({
26658
+ from: original.from,
26659
+ to: original.to,
26660
+ type: original.type,
26661
+ decision: "rejected",
26662
+ reason: "endpoints collapsed to the same cloud node"
26663
+ });
26664
+ return false;
26665
+ });
26666
+ if (rewritten.length === 0) {
26667
+ emit([], 0);
26668
+ continue;
26669
+ }
26583
26670
  const r = await this.ingestWire(toWirePayload({ ...batch, nodes: [], edges: rewritten }, randomUUID()));
26584
26671
  emit([], summarizeIngestResult(r).accepted);
26585
26672
  merged.edges.push(...r.edges);
@@ -32330,18 +32417,141 @@ var init_recall_signal = __esm({
32330
32417
  }
32331
32418
  });
32332
32419
 
32420
+ // src/session-registry.ts
32421
+ import { existsSync as existsSync8, readFileSync as readFileSync6, realpathSync, writeFileSync as writeFileSync7 } from "node:fs";
32422
+ import { tmpdir as tmpdir2 } from "node:os";
32423
+ import { resolve } from "node:path";
32424
+ function shipsFromWorkspace(root, env2 = process.env) {
32425
+ return Boolean(env2["VITEST"]) || !isScratchWorkspace(root);
32426
+ }
32427
+ function isScratchWorkspace(root, tmp = tmpdir2()) {
32428
+ const norm = (p) => {
32429
+ let real = p;
32430
+ try {
32431
+ real = realpathSync.native(p);
32432
+ } catch {
32433
+ }
32434
+ return resolve(real).replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
32435
+ };
32436
+ const r = norm(root);
32437
+ const t = norm(tmp);
32438
+ return r === t || r.startsWith(`${t}/`);
32439
+ }
32440
+ function parseOrigin(raw2) {
32441
+ if (typeof raw2 !== "string") return void 0;
32442
+ const v = raw2.trim();
32443
+ if (!v || v.includes("%")) return void 0;
32444
+ return /^[\w.:-]{1,64}$/.test(v) ? v : void 0;
32445
+ }
32446
+ function createSessionRegistry(opts = {}) {
32447
+ const idleMs = opts.idleMs ?? SESSION_IDLE_MS;
32448
+ const lastSeen = /* @__PURE__ */ new Map();
32449
+ const parentOf = /* @__PURE__ */ new Map();
32450
+ const ended = /* @__PURE__ */ new Set();
32451
+ const origins = new Map(loadOrigins(opts.originsPath));
32452
+ let ver = 0;
32453
+ let lastLiveCount = -1;
32454
+ const persist = () => {
32455
+ if (!opts.originsPath) return;
32456
+ try {
32457
+ while (origins.size > MAX_ORIGINS) origins.delete(origins.keys().next().value);
32458
+ writeFileSync7(opts.originsPath, JSON.stringify(Object.fromEntries(origins)));
32459
+ } catch {
32460
+ }
32461
+ };
32462
+ const ownLive = (id, nowMs) => {
32463
+ const seen = lastSeen.get(id);
32464
+ return seen !== void 0 && !ended.has(id) && nowMs - seen < idleMs;
32465
+ };
32466
+ const registry2 = {
32467
+ touch(sessionId, nowMs, o = {}) {
32468
+ if (!sessionId) return;
32469
+ const wasLive = ownLive(sessionId, nowMs);
32470
+ lastSeen.set(sessionId, nowMs);
32471
+ ended.delete(sessionId);
32472
+ if (o.parent) parentOf.set(sessionId, o.parent);
32473
+ const origin = o.origin ?? (o.parent ? origins.get(o.parent) : void 0);
32474
+ if (origin && origins.get(sessionId) !== origin) {
32475
+ origins.set(sessionId, origin);
32476
+ persist();
32477
+ ver++;
32478
+ }
32479
+ if (!wasLive) ver++;
32480
+ },
32481
+ end(sessionId) {
32482
+ if (!sessionId || ended.has(sessionId)) return;
32483
+ ended.add(sessionId);
32484
+ ver++;
32485
+ },
32486
+ isLive(sessionId, nowMs) {
32487
+ if (ownLive(sessionId, nowMs)) return true;
32488
+ const parent = parentOf.get(sessionId);
32489
+ return parent !== void 0 && ownLive(parent, nowMs);
32490
+ },
32491
+ originOf: (sessionId) => origins.get(sessionId) ?? origins.get(parentOf.get(sessionId) ?? ""),
32492
+ originSessions: () => [...origins.keys()],
32493
+ isOwn: (sessionId, viewer) => sessionId === viewer || parentOf.get(sessionId) === viewer,
32494
+ version(nowMs) {
32495
+ let live3 = 0;
32496
+ for (const id of lastSeen.keys()) if (ownLive(id, nowMs)) live3++;
32497
+ if (live3 !== lastLiveCount) {
32498
+ lastLiveCount = live3;
32499
+ ver++;
32500
+ }
32501
+ return ver;
32502
+ }
32503
+ };
32504
+ return registry2;
32505
+ }
32506
+ function loadOrigins(path2) {
32507
+ if (!path2 || !existsSync8(path2)) return [];
32508
+ try {
32509
+ const raw2 = JSON.parse(readFileSync6(path2, "utf8"));
32510
+ return Object.entries(raw2).flatMap(([k, v]) => typeof v === "string" ? [[k, v]] : []);
32511
+ } catch {
32512
+ return [];
32513
+ }
32514
+ }
32515
+ function sessionsOf(node2) {
32516
+ const s = node2.attrs["sources"];
32517
+ return Array.isArray(s) ? s.filter((x) => typeof x === "string" && x.length > 0) : [];
32518
+ }
32519
+ function capturedOnlyBy(node2, sessions) {
32520
+ const recorded = sessionsOf(node2);
32521
+ return recorded.length > 0 && recorded.every((s) => sessions.has(s));
32522
+ }
32523
+ function isQuarantined(node2, reg) {
32524
+ const sessions = sessionsOf(node2);
32525
+ return sessions.length > 0 && sessions.every((s) => reg.originOf(s) !== void 0);
32526
+ }
32527
+ function hiddenFrom(node2, viewer, reg, nowMs) {
32528
+ const sessions = sessionsOf(node2);
32529
+ if (sessions.length === 0 || sessions.some((s) => reg.isOwn(s, viewer))) return false;
32530
+ if (isQuarantined(node2, reg)) return true;
32531
+ return sessions.every((s) => reg.isLive(s, nowMs));
32532
+ }
32533
+ var ORIGIN_HEADER, SESSION_IDLE_MS, MAX_ORIGINS;
32534
+ var init_session_registry = __esm({
32535
+ "src/session-registry.ts"() {
32536
+ "use strict";
32537
+ ORIGIN_HEADER = "x-errata-origin";
32538
+ SESSION_IDLE_MS = 20 * 6e4;
32539
+ MAX_ORIGINS = 5e4;
32540
+ }
32541
+ });
32542
+
32333
32543
  // src/review.ts
32334
- import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync7 } from "node:fs";
32544
+ import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync8 } from "node:fs";
32335
32545
  function loadReviewQueue(paths) {
32336
- if (!existsSync8(paths.reviewQueue)) return [];
32546
+ if (!existsSync9(paths.reviewQueue)) return [];
32337
32547
  try {
32338
- return JSON.parse(readFileSync6(paths.reviewQueue, "utf8"));
32548
+ return JSON.parse(readFileSync7(paths.reviewQueue, "utf8"));
32339
32549
  } catch {
32340
32550
  return [];
32341
32551
  }
32342
32552
  }
32343
32553
  function saveReviewQueue(paths, queue) {
32344
- writeFileSync7(paths.reviewQueue, JSON.stringify(queue, null, 2), "utf8");
32554
+ writeFileSync8(paths.reviewQueue, JSON.stringify(queue, null, 2), "utf8");
32345
32555
  }
32346
32556
  function addProposal(paths, store, node2, reason, surprise) {
32347
32557
  const queue = loadReviewQueue(paths);
@@ -32411,26 +32621,26 @@ var init_consent = __esm({
32411
32621
  });
32412
32622
 
32413
32623
  // src/git-remote.ts
32414
- import { existsSync as existsSync9, readFileSync as readFileSync7, statSync } from "node:fs";
32415
- import { isAbsolute as isAbsolute2, join as join8, resolve } from "node:path";
32624
+ import { existsSync as existsSync10, readFileSync as readFileSync8, statSync } from "node:fs";
32625
+ import { isAbsolute as isAbsolute2, join as join8, resolve as resolve2 } from "node:path";
32416
32626
  function resolveGitDir(root) {
32417
32627
  const dotGit = join8(root, ".git");
32418
32628
  try {
32419
32629
  const st = statSync(dotGit);
32420
32630
  if (st.isDirectory()) return dotGit;
32421
- const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync7(dotGit, "utf8"));
32631
+ const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync8(dotGit, "utf8"));
32422
32632
  if (!m) return null;
32423
32633
  const dir = m[1];
32424
- return isAbsolute2(dir) ? dir : resolve(root, dir);
32634
+ return isAbsolute2(dir) ? dir : resolve2(root, dir);
32425
32635
  } catch {
32426
32636
  return null;
32427
32637
  }
32428
32638
  }
32429
32639
  function gitConfigPath(gitDir) {
32430
32640
  const commondirFile = join8(gitDir, "commondir");
32431
- if (existsSync9(commondirFile)) {
32432
- const common = readFileSync7(commondirFile, "utf8").trim();
32433
- const commonDir = isAbsolute2(common) ? common : resolve(gitDir, common);
32641
+ if (existsSync10(commondirFile)) {
32642
+ const common = readFileSync8(commondirFile, "utf8").trim();
32643
+ const commonDir = isAbsolute2(common) ? common : resolve2(gitDir, common);
32434
32644
  return join8(commonDir, "config");
32435
32645
  }
32436
32646
  return join8(gitDir, "config");
@@ -32439,10 +32649,10 @@ function readRemotes(root) {
32439
32649
  const gitDir = resolveGitDir(root);
32440
32650
  if (!gitDir) return [];
32441
32651
  const cfgPath = gitConfigPath(gitDir);
32442
- if (!existsSync9(cfgPath)) return [];
32652
+ if (!existsSync10(cfgPath)) return [];
32443
32653
  let txt;
32444
32654
  try {
32445
- txt = readFileSync7(cfgPath, "utf8");
32655
+ txt = readFileSync8(cfgPath, "utf8");
32446
32656
  } catch {
32447
32657
  return [];
32448
32658
  }
@@ -32468,7 +32678,7 @@ var init_git_remote = __esm({
32468
32678
  });
32469
32679
 
32470
32680
  // src/profile.ts
32471
- import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync8 } from "node:fs";
32681
+ import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "node:fs";
32472
32682
  import { createHash as createHash5 } from "node:crypto";
32473
32683
  import { join as join9 } from "node:path";
32474
32684
  function workspaceId(root) {
@@ -32493,13 +32703,13 @@ function refreshRepoLocator(root, profile) {
32493
32703
  }
32494
32704
  function loadProfile(root) {
32495
32705
  const p = workspacePaths(root);
32496
- if (!existsSync10(p.workspaceJson)) return null;
32497
- return JSON.parse(readFileSync8(p.workspaceJson, "utf8"));
32706
+ if (!existsSync11(p.workspaceJson)) return null;
32707
+ return JSON.parse(readFileSync9(p.workspaceJson, "utf8"));
32498
32708
  }
32499
32709
  function saveProfile(root, profile) {
32500
32710
  const p = workspacePaths(root);
32501
32711
  ensureDir(p.configDir);
32502
- writeFileSync8(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
32712
+ writeFileSync9(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
32503
32713
  }
32504
32714
  function autodetectProfile(root) {
32505
32715
  const id = workspaceId(root);
@@ -32508,12 +32718,12 @@ function autodetectProfile(root) {
32508
32718
  const locator = detectRepoLocator(root);
32509
32719
  if (locator) p.repoLocator = locator;
32510
32720
  const pkgPath = join9(root, "package.json");
32511
- if (existsSync10(pkgPath)) {
32721
+ if (existsSync11(pkgPath)) {
32512
32722
  try {
32513
- const pkg = JSON.parse(readFileSync8(pkgPath, "utf8"));
32723
+ const pkg = JSON.parse(readFileSync9(pkgPath, "utf8"));
32514
32724
  const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
32515
32725
  p.languages.push("javascript");
32516
- if (existsSync10(join9(root, "tsconfig.json")) || deps["typescript"]) {
32726
+ if (existsSync11(join9(root, "tsconfig.json")) || deps["typescript"]) {
32517
32727
  p.languages.push("typescript");
32518
32728
  }
32519
32729
  const nodeVer = pkg.engines?.node?.trim();
@@ -32535,9 +32745,9 @@ function autodetectProfile(root) {
32535
32745
  }
32536
32746
  }
32537
32747
  const pyproject = join9(root, "pyproject.toml");
32538
- if (existsSync10(pyproject)) {
32748
+ if (existsSync11(pyproject)) {
32539
32749
  try {
32540
- const txt = readFileSync8(pyproject, "utf8");
32750
+ const txt = readFileSync9(pyproject, "utf8");
32541
32751
  const py = /python\s*=\s*"([^"]+)"/.exec(txt)?.[1];
32542
32752
  p.languages.push("python");
32543
32753
  p.stack.push(`python@${py ?? "3"}`);
@@ -32549,15 +32759,15 @@ function autodetectProfile(root) {
32549
32759
  }
32550
32760
  }
32551
32761
  const reqs = join9(root, "requirements.txt");
32552
- if (existsSync10(reqs)) {
32762
+ if (existsSync11(reqs)) {
32553
32763
  if (!p.languages.includes("python")) p.languages.push("python");
32554
32764
  if (!p.stack.includes("python@3")) p.stack.push("python@3");
32555
32765
  }
32556
- if (existsSync10(join9(root, "go.mod"))) {
32766
+ if (existsSync11(join9(root, "go.mod"))) {
32557
32767
  p.languages.push("go");
32558
32768
  p.stack.push("go");
32559
32769
  }
32560
- if (existsSync10(join9(root, "Cargo.toml"))) {
32770
+ if (existsSync11(join9(root, "Cargo.toml"))) {
32561
32771
  p.languages.push("rust");
32562
32772
  p.stack.push("rust");
32563
32773
  }
@@ -32662,12 +32872,12 @@ var init_identity2 = __esm({
32662
32872
  });
32663
32873
 
32664
32874
  // src/checkout-root.ts
32665
- import { existsSync as existsSync11, readFileSync as readFileSync9 } from "node:fs";
32666
- import { basename as basename2, dirname as dirname6, isAbsolute as isAbsolute3, join as join10, resolve as resolve2 } from "node:path";
32875
+ import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
32876
+ import { basename as basename2, dirname as dirname6, isAbsolute as isAbsolute3, join as join10, resolve as resolve3 } from "node:path";
32667
32877
  function nearestGitRoot(dir) {
32668
- let cur = resolve2(dir);
32878
+ let cur = resolve3(dir);
32669
32879
  for (; ; ) {
32670
- if (existsSync11(join10(cur, ".git"))) return cur;
32880
+ if (existsSync12(join10(cur, ".git"))) return cur;
32671
32881
  const parent = dirname6(cur);
32672
32882
  if (parent === cur) return null;
32673
32883
  cur = parent;
@@ -32677,22 +32887,22 @@ function mainCheckoutOfWorktree(root) {
32677
32887
  const gitDir = resolveGitDir(root);
32678
32888
  if (!gitDir || gitDir === join10(root, ".git")) return null;
32679
32889
  const commondirFile = join10(gitDir, "commondir");
32680
- if (!existsSync11(commondirFile)) return null;
32890
+ if (!existsSync12(commondirFile)) return null;
32681
32891
  let common;
32682
32892
  try {
32683
- common = readFileSync9(commondirFile, "utf8").trim();
32893
+ common = readFileSync10(commondirFile, "utf8").trim();
32684
32894
  } catch {
32685
32895
  return null;
32686
32896
  }
32687
- const commonDir = resolve2(isAbsolute3(common) ? common : resolve2(gitDir, common));
32897
+ const commonDir = resolve3(isAbsolute3(common) ? common : resolve3(gitDir, common));
32688
32898
  if (basename2(commonDir) !== ".git") return null;
32689
32899
  const main2 = dirname6(commonDir);
32690
- return existsSync11(join10(main2, ".git")) ? main2 : null;
32900
+ return existsSync12(join10(main2, ".git")) ? main2 : null;
32691
32901
  }
32692
32902
  function checkoutRootOf(cwd) {
32693
32903
  const root = nearestGitRoot(cwd);
32694
32904
  const main2 = root ? mainCheckoutOfWorktree(root) : null;
32695
- return main2 ?? resolve2(cwd);
32905
+ return main2 ?? resolve3(cwd);
32696
32906
  }
32697
32907
  function isLinkedWorktree(root) {
32698
32908
  return mainCheckoutOfWorktree(root) !== null;
@@ -32706,7 +32916,7 @@ var init_checkout_root = __esm({
32706
32916
 
32707
32917
  // src/process-identity.ts
32708
32918
  import { execFileSync } from "node:child_process";
32709
- import { readFileSync as readFileSync10 } from "node:fs";
32919
+ import { readFileSync as readFileSync11 } from "node:fs";
32710
32920
  function readProcessIdentity(pid, fresh = false) {
32711
32921
  if (!Number.isSafeInteger(pid) || pid <= 0) return null;
32712
32922
  if (pid === process.pid && self) return self;
@@ -32731,10 +32941,10 @@ function readProcessIdentity(pid, fresh = false) {
32731
32941
  if (!/^\d+$/.test(ticks)) return null;
32732
32942
  value = { key: `win32:${ticks}`, bornAt: Number((BigInt(ticks) - 621355968000000000n) / 10000n) };
32733
32943
  } else if (process.platform === "linux") {
32734
- const stat4 = readFileSync10(`/proc/${pid}/stat`, "utf8");
32944
+ const stat4 = readFileSync11(`/proc/${pid}/stat`, "utf8");
32735
32945
  const ticks = stat4.slice(stat4.lastIndexOf(")") + 2).split(" ")[19];
32736
- const bootId = readFileSync10("/proc/sys/kernel/random/boot_id", "utf8").trim();
32737
- const boot = /^btime (\d+)$/m.exec(readFileSync10("/proc/stat", "utf8"))?.[1];
32946
+ const bootId = readFileSync11("/proc/sys/kernel/random/boot_id", "utf8").trim();
32947
+ const boot = /^btime (\d+)$/m.exec(readFileSync11("/proc/stat", "utf8"))?.[1];
32738
32948
  const hz = Number(run3("getconf", ["CLK_TCK"]));
32739
32949
  if (!boot || !/^\d+$/.test(ticks) || !Number.isFinite(hz) || hz <= 0) return null;
32740
32950
  value = { key: `linux:${bootId}:${ticks}`, bornAt: Number(boot) * 1e3 + Number(ticks) * 1e3 / hz };
@@ -32760,7 +32970,7 @@ var init_process_identity = __esm({
32760
32970
  });
32761
32971
 
32762
32972
  // src/lock.ts
32763
- import { existsSync as existsSync12, readFileSync as readFileSync11, unlinkSync as unlinkSync2 } from "node:fs";
32973
+ import { existsSync as existsSync13, readFileSync as readFileSync12, unlinkSync as unlinkSync2 } from "node:fs";
32764
32974
  function daemonLockPayload(lock) {
32765
32975
  return JSON.stringify({
32766
32976
  pid: lock.pid,
@@ -32795,9 +33005,9 @@ function isProcessAlive(pid) {
32795
33005
  }
32796
33006
  }
32797
33007
  function readDaemonLock(lockPath) {
32798
- if (!existsSync12(lockPath)) return null;
33008
+ if (!existsSync13(lockPath)) return null;
32799
33009
  try {
32800
- return parseDaemonLock(readFileSync11(lockPath, "utf8"));
33010
+ return parseDaemonLock(readFileSync12(lockPath, "utf8"));
32801
33011
  } catch {
32802
33012
  return null;
32803
33013
  }
@@ -32827,7 +33037,7 @@ function daemonLockBlocksStartup(lockPath) {
32827
33037
  function stopLockedDaemon(lockPath) {
32828
33038
  let original;
32829
33039
  try {
32830
- original = readFileSync11(lockPath, "utf8");
33040
+ original = readFileSync12(lockPath, "utf8");
32831
33041
  } catch {
32832
33042
  return "missing";
32833
33043
  }
@@ -32835,7 +33045,7 @@ function stopLockedDaemon(lockPath) {
32835
33045
  if (!lock) return "unknown";
32836
33046
  const state = daemonLockState(lock, true);
32837
33047
  try {
32838
- if (readFileSync11(lockPath, "utf8") !== original) return "changed";
33048
+ if (readFileSync12(lockPath, "utf8") !== original) return "changed";
32839
33049
  } catch {
32840
33050
  return "changed";
32841
33051
  }
@@ -32860,16 +33070,16 @@ var init_lock = __esm({
32860
33070
  });
32861
33071
 
32862
33072
  // src/registry.ts
32863
- import { existsSync as existsSync13, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
33073
+ import { existsSync as existsSync14, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "node:fs";
32864
33074
  import { join as join11 } from "node:path";
32865
33075
  function registryPath() {
32866
33076
  return process.env["ERRATA_REGISTRY_PATH"] ?? join11(globalDir(), "workspaces.json");
32867
33077
  }
32868
33078
  function read() {
32869
33079
  const p = registryPath();
32870
- if (!existsSync13(p)) return { version: 1, workspaces: {} };
33080
+ if (!existsSync14(p)) return { version: 1, workspaces: {} };
32871
33081
  try {
32872
- const parsed = JSON.parse(readFileSync12(p, "utf8"));
33082
+ const parsed = JSON.parse(readFileSync13(p, "utf8"));
32873
33083
  return { version: 1, workspaces: parsed.workspaces ?? {} };
32874
33084
  } catch {
32875
33085
  return { version: 1, workspaces: {} };
@@ -32877,9 +33087,9 @@ function read() {
32877
33087
  }
32878
33088
  function registryCorrupt() {
32879
33089
  const p = registryPath();
32880
- if (!existsSync13(p)) return false;
33090
+ if (!existsSync14(p)) return false;
32881
33091
  try {
32882
- JSON.parse(readFileSync12(p, "utf8"));
33092
+ JSON.parse(readFileSync13(p, "utf8"));
32883
33093
  return false;
32884
33094
  } catch {
32885
33095
  return true;
@@ -32887,7 +33097,7 @@ function registryCorrupt() {
32887
33097
  }
32888
33098
  function write(reg) {
32889
33099
  ensureDir(globalDir());
32890
- writeFileSync9(registryPath(), JSON.stringify(reg, null, 2), "utf8");
33100
+ writeFileSync10(registryPath(), JSON.stringify(reg, null, 2), "utf8");
32891
33101
  }
32892
33102
  function registerWorkspace(profile, root, now = Date.now()) {
32893
33103
  if (isLinkedWorktree(root)) return;
@@ -32932,7 +33142,7 @@ function pruneMissingWorkspaces() {
32932
33142
  const reg = read();
32933
33143
  const removed = [];
32934
33144
  for (const [id, entry] of Object.entries(reg.workspaces)) {
32935
- if (!existsSync13(entry.path)) {
33145
+ if (!existsSync14(entry.path)) {
32936
33146
  removed.push(entry);
32937
33147
  delete reg.workspaces[id];
32938
33148
  }
@@ -32941,7 +33151,7 @@ function pruneMissingWorkspaces() {
32941
33151
  return removed;
32942
33152
  }
32943
33153
  function workspaceStatus(entry) {
32944
- const missing = !existsSync13(entry.path);
33154
+ const missing = !existsSync14(entry.path);
32945
33155
  const lockPath = workspacePaths(entry.path).daemonLock;
32946
33156
  let running = false;
32947
33157
  let webUiUrl = null;
@@ -34260,7 +34470,7 @@ var init_dual_augment = __esm({
34260
34470
 
34261
34471
  // ../../packages/indexer/src/parse-cache.ts
34262
34472
  import { createHash as createHash6 } from "node:crypto";
34263
- import { existsSync as existsSync14, mkdirSync as mkdirSync6, readFileSync as readFileSync13, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync10 } from "node:fs";
34473
+ import { existsSync as existsSync15, mkdirSync as mkdirSync6, readFileSync as readFileSync14, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync11 } from "node:fs";
34264
34474
  import { homedir as homedir3 } from "node:os";
34265
34475
  import { join as join12 } from "node:path";
34266
34476
  function parseCacheDir() {
@@ -34275,7 +34485,7 @@ function entryPath(dir, key) {
34275
34485
  function readParseCache(dir, key) {
34276
34486
  const file2 = entryPath(dir, key);
34277
34487
  try {
34278
- const raw2 = readFileSync13(file2, "utf8");
34488
+ const raw2 = readFileSync14(file2, "utf8");
34279
34489
  const parsed = JSON.parse(raw2);
34280
34490
  if (parsed.v !== PARSE_CACHE_VERSION || !Array.isArray(parsed.symbols)) return null;
34281
34491
  return { symbols: parsed.symbols, reExports: parsed.reExports ?? [] };
@@ -34295,7 +34505,7 @@ function writeParseCache(dir, key, providerId, value) {
34295
34505
  if (body2.length > MAX_ENTRY_BYTES) return;
34296
34506
  const file2 = entryPath(dir, key);
34297
34507
  mkdirSync6(join12(dir, key.slice(0, 2)), { recursive: true });
34298
- writeFileSync10(file2, body2);
34508
+ writeFileSync11(file2, body2);
34299
34509
  } catch {
34300
34510
  }
34301
34511
  }
@@ -34304,7 +34514,7 @@ function sweepParseCacheOnce(dir, now = Date.now()) {
34304
34514
  sweptThisProcess = true;
34305
34515
  let removed = 0;
34306
34516
  try {
34307
- if (!existsSync14(dir)) return 0;
34517
+ if (!existsSync15(dir)) return 0;
34308
34518
  for (const bucket of readdirSync2(dir)) {
34309
34519
  const bucketDir = join12(dir, bucket);
34310
34520
  let names;
@@ -34562,7 +34772,7 @@ var init_identity3 = __esm({
34562
34772
  });
34563
34773
 
34564
34774
  // ../../packages/indexer/src/pipeline.ts
34565
- import { appendFileSync, readFileSync as readFileSync14, statSync as statSync3 } from "node:fs";
34775
+ import { appendFileSync, readFileSync as readFileSync15, statSync as statSync3 } from "node:fs";
34566
34776
  import { readdir } from "node:fs/promises";
34567
34777
  import { extname, join as join13, relative as relative2, sep } from "node:path";
34568
34778
  import { createHash as createHash7 } from "node:crypto";
@@ -34702,7 +34912,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
34702
34912
  for (const rel of [...changedRelPaths]) {
34703
34913
  let h;
34704
34914
  try {
34705
- h = createHash7("sha256").update(readFileSync14(join13(rootPath, rel))).digest("hex");
34915
+ h = createHash7("sha256").update(readFileSync15(join13(rootPath, rel))).digest("hex");
34706
34916
  } catch {
34707
34917
  continue;
34708
34918
  }
@@ -34757,7 +34967,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
34757
34967
  if (!provider) continue;
34758
34968
  let symbols;
34759
34969
  try {
34760
- symbols = provider.extractSymbols(readFileSync14(abs, "utf8"), abs);
34970
+ symbols = provider.extractSymbols(readFileSync15(abs, "utf8"), abs);
34761
34971
  } catch {
34762
34972
  continue;
34763
34973
  }
@@ -35077,7 +35287,7 @@ async function runIndexer(store, opts) {
35077
35287
  report.filesSkipped++;
35078
35288
  continue;
35079
35289
  }
35080
- source = readFileSync14(f.absPath, "utf8");
35290
+ source = readFileSync15(f.absPath, "utf8");
35081
35291
  } catch {
35082
35292
  report.filesSkipped++;
35083
35293
  continue;
@@ -35149,7 +35359,7 @@ async function runIndexer(store, opts) {
35149
35359
  const depth = fileNode.relPath.split("/").length;
35150
35360
  if (depth !== 3) continue;
35151
35361
  try {
35152
- const pkg = JSON.parse(readFileSync14(fileNode.absPath, "utf8"));
35362
+ const pkg = JSON.parse(readFileSync15(fileNode.absPath, "utf8"));
35153
35363
  if (!pkg.name) continue;
35154
35364
  const pkgDir = fileNode.relPath.replace(/\/package\.json$/, "");
35155
35365
  const candidates = [
@@ -35625,7 +35835,7 @@ function upsertFile(store, id, f, workspaceId2, skip) {
35625
35835
  if (existing && fileUnchanged(existing.attrs, f, skip)) return;
35626
35836
  let contentHash;
35627
35837
  try {
35628
- contentHash = createHash7("sha256").update(readFileSync14(f.absPath)).digest("hex");
35838
+ contentHash = createHash7("sha256").update(readFileSync15(f.absPath)).digest("hex");
35629
35839
  } catch {
35630
35840
  }
35631
35841
  const carried = { ...existing?.attrs ?? {} };
@@ -36242,13 +36452,13 @@ async function Module2(moduleArg = {}) {
36242
36452
  }
36243
36453
  readAsync = /* @__PURE__ */ __name(async (url2) => {
36244
36454
  if (isFileURI(url2)) {
36245
- return new Promise((resolve8, reject) => {
36455
+ return new Promise((resolve9, reject) => {
36246
36456
  var xhr = new XMLHttpRequest();
36247
36457
  xhr.open("GET", url2, true);
36248
36458
  xhr.responseType = "arraybuffer";
36249
36459
  xhr.onload = () => {
36250
36460
  if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
36251
- resolve8(xhr.response);
36461
+ resolve9(xhr.response);
36252
36462
  return;
36253
36463
  }
36254
36464
  reject(xhr.status);
@@ -36444,9 +36654,9 @@ async function Module2(moduleArg = {}) {
36444
36654
  __name(receiveInstantiationResult, "receiveInstantiationResult");
36445
36655
  var info2 = getWasmImports();
36446
36656
  if (Module["instantiateWasm"]) {
36447
- return new Promise((resolve8, reject) => {
36657
+ return new Promise((resolve9, reject) => {
36448
36658
  Module["instantiateWasm"](info2, (mod, inst) => {
36449
- resolve8(receiveInstance(mod, inst));
36659
+ resolve9(receiveInstance(mod, inst));
36450
36660
  });
36451
36661
  });
36452
36662
  }
@@ -37777,8 +37987,8 @@ async function Module2(moduleArg = {}) {
37777
37987
  if (runtimeInitialized) {
37778
37988
  moduleRtn = Module;
37779
37989
  } else {
37780
- moduleRtn = new Promise((resolve8, reject) => {
37781
- readyPromiseResolve = resolve8;
37990
+ moduleRtn = new Promise((resolve9, reject) => {
37991
+ readyPromiseResolve = resolve9;
37782
37992
  readyPromiseReject = reject;
37783
37993
  });
37784
37994
  }
@@ -40009,7 +40219,7 @@ ${JSON.stringify(symbolNames, null, 2)}`);
40009
40219
  // ../../packages/indexer/src/languages/tree-sitter-loader.ts
40010
40220
  import { fileURLToPath } from "node:url";
40011
40221
  import { dirname as dirname7, join as join14 } from "node:path";
40012
- import { existsSync as existsSync15, readdirSync as readdirSync3 } from "node:fs";
40222
+ import { existsSync as existsSync16, readdirSync as readdirSync3 } from "node:fs";
40013
40223
  import { createRequire as createRequire2 } from "node:module";
40014
40224
  function entryDir() {
40015
40225
  try {
@@ -40024,7 +40234,7 @@ function entryDir() {
40024
40234
  function findWasmDir() {
40025
40235
  const here = entryDir();
40026
40236
  const seaWasm = join14(here, "resources", "wasm");
40027
- if (existsSync15(join14(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
40237
+ if (existsSync16(join14(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
40028
40238
  let dir = here;
40029
40239
  for (let i2 = 0; i2 < 6; i2++) {
40030
40240
  const flat = join14(
@@ -40034,13 +40244,13 @@ function findWasmDir() {
40034
40244
  "tree-sitter-wasm",
40035
40245
  "wasm"
40036
40246
  );
40037
- if (existsSync15(join14(flat, "tree-sitter-typescript.wasm"))) return flat;
40247
+ if (existsSync16(join14(flat, "tree-sitter-typescript.wasm"))) return flat;
40038
40248
  dir = dirname7(dir);
40039
40249
  }
40040
40250
  let root = here;
40041
40251
  for (let i2 = 0; i2 < 6; i2++) {
40042
40252
  const pnpmDir = join14(root, "node_modules", ".pnpm");
40043
- if (existsSync15(pnpmDir)) {
40253
+ if (existsSync16(pnpmDir)) {
40044
40254
  for (const entry of readdirSync3(pnpmDir)) {
40045
40255
  if (entry.startsWith("@vscode+tree-sitter-wasm@")) {
40046
40256
  const candidate = join14(
@@ -40051,7 +40261,7 @@ function findWasmDir() {
40051
40261
  "tree-sitter-wasm",
40052
40262
  "wasm"
40053
40263
  );
40054
- if (existsSync15(join14(candidate, "tree-sitter-typescript.wasm"))) {
40264
+ if (existsSync16(join14(candidate, "tree-sitter-typescript.wasm"))) {
40055
40265
  return candidate;
40056
40266
  }
40057
40267
  }
@@ -40066,17 +40276,17 @@ function findWasmDir() {
40066
40276
  function findRuntimeDir() {
40067
40277
  const here = entryDir();
40068
40278
  const seaRuntime = join14(here, "resources", "wasm");
40069
- if (existsSync15(join14(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
40279
+ if (existsSync16(join14(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
40070
40280
  let dir = here;
40071
40281
  for (let i2 = 0; i2 < 6; i2++) {
40072
40282
  const flat = join14(dir, "node_modules", "web-tree-sitter");
40073
- if (existsSync15(join14(flat, "web-tree-sitter.wasm"))) return flat;
40283
+ if (existsSync16(join14(flat, "web-tree-sitter.wasm"))) return flat;
40074
40284
  dir = dirname7(dir);
40075
40285
  }
40076
40286
  let root = here;
40077
40287
  for (let i2 = 0; i2 < 6; i2++) {
40078
40288
  const pnpmDir = join14(root, "node_modules", ".pnpm");
40079
- if (existsSync15(pnpmDir)) {
40289
+ if (existsSync16(pnpmDir)) {
40080
40290
  for (const entry of readdirSync3(pnpmDir)) {
40081
40291
  if (entry.startsWith("web-tree-sitter@")) {
40082
40292
  const candidate = join14(
@@ -40085,7 +40295,7 @@ function findRuntimeDir() {
40085
40295
  "node_modules",
40086
40296
  "web-tree-sitter"
40087
40297
  );
40088
- if (existsSync15(join14(candidate, "web-tree-sitter.wasm"))) {
40298
+ if (existsSync16(join14(candidate, "web-tree-sitter.wasm"))) {
40089
40299
  return candidate;
40090
40300
  }
40091
40301
  }
@@ -43086,58 +43296,32 @@ function listSourceFiles(root) {
43086
43296
  }
43087
43297
  async function findStaleFiles(store, rootPath, workspaceId2) {
43088
43298
  const stale = [];
43089
- const pending = [];
43090
- const allTargets = [];
43299
+ let pending = [];
43300
+ const check2 = () => {
43301
+ const states = new Map(store.fileIndexStates(pending.map((f) => f.id)).map((s) => [s.id, s]));
43302
+ for (const f of pending) {
43303
+ const state = states.get(f.id);
43304
+ if (!state || state.validTo !== null || state.lastUpdatedAt < f.mtimeMs || !state.complete) stale.push(f.abs);
43305
+ }
43306
+ pending = [];
43307
+ };
43091
43308
  let scanned = 0;
43092
43309
  for (const abs of listSourceFiles(rootPath)) {
43093
- if (++scanned % SCAN_YIELD_EVERY === 0) await new Promise((r) => setImmediate(r));
43094
- let mtimeMs;
43095
43310
  try {
43096
- mtimeMs = statSync4(abs).mtimeMs;
43311
+ const rel = relative3(rootPath, abs).split(sep2).join("/");
43312
+ pending.push({ abs, id: fileNodeId(workspaceId2, rel), mtimeMs: statSync4(abs).mtimeMs });
43097
43313
  } catch {
43098
- continue;
43099
43314
  }
43100
- const rel = relative3(rootPath, abs).split(sep2).join("/");
43101
- const fnode = store.getNode(fileNodeId(workspaceId2, rel));
43102
- if (!fnode) {
43103
- stale.push(abs);
43104
- } else if ((fnode.validTo ?? null) !== null) {
43105
- stale.push(abs);
43106
- } else if (fnode.lastUpdatedAt < mtimeMs) {
43107
- stale.push(abs);
43108
- } else {
43109
- const edges = store.outEdges(fnode.id, ["DEFINES", "CONTAINS"]);
43110
- if (edges.length === 0) {
43111
- const converged = fnode.attrs["symbolCount"] === 0 || typeof fnode.attrs["indexSkipped"] === "string";
43112
- if (!converged) stale.push(abs);
43113
- } else {
43114
- const targets = edges.map((e) => e.to);
43115
- pending.push({ abs, targets });
43116
- allTargets.push(...targets);
43117
- }
43315
+ if (++scanned % SCAN_YIELD_EVERY === 0) {
43316
+ check2();
43317
+ await new Promise((resolve9) => setImmediate(resolve9));
43118
43318
  }
43119
43319
  }
43120
- const live3 = /* @__PURE__ */ new Set();
43121
- for (let i2 = 0; i2 < allTargets.length; i2 += LIVENESS_CHUNK) {
43122
- for (const id of store.liveNodeIds(allTargets.slice(i2, i2 + LIVENESS_CHUNK))) live3.add(id);
43123
- if (i2 + LIVENESS_CHUNK < allTargets.length) await new Promise((r) => setImmediate(r));
43124
- }
43125
- for (const { abs, targets } of pending) {
43126
- if (targets.some((id) => !live3.has(id))) stale.push(abs);
43127
- }
43320
+ check2();
43128
43321
  return stale;
43129
43322
  }
43130
- function isLive(n) {
43131
- return n != null && (n.validTo ?? null) === null;
43132
- }
43133
43323
  function findStrandedSymbols(store) {
43134
- const stranded = [];
43135
- for (const file2 of store.findNodesByLabel("File")) {
43136
- for (const e of store.outEdges(file2.id, ["DEFINES", "CONTAINS"])) {
43137
- if (!isLive(store.getNode(e.to))) stranded.push({ fileId: file2.id, symbolId: e.to });
43138
- }
43139
- }
43140
- return stranded;
43324
+ return store.strandedSymbols();
43141
43325
  }
43142
43326
  function reapOrphanedFiles(store, rootPath, workspaceId2, ignoreDirs = []) {
43143
43327
  const ignores = /* @__PURE__ */ new Set([...DEFAULT_IGNORES, ...ignoreDirs]);
@@ -43199,7 +43383,7 @@ async function reconcileStaleFiles(store, rootPath, workspaceId2) {
43199
43383
  }
43200
43384
  return total;
43201
43385
  }
43202
- var IGNORED, SOURCE_RE, SCAN_YIELD_EVERY, LIVENESS_CHUNK, ORPHAN_REAP_MAX_FRACTION, ORPHAN_REAP_MIN_ALLOWANCE;
43386
+ var IGNORED, SOURCE_RE, SCAN_YIELD_EVERY, ORPHAN_REAP_MAX_FRACTION, ORPHAN_REAP_MIN_ALLOWANCE;
43203
43387
  var init_reconcile = __esm({
43204
43388
  "src/reconcile.ts"() {
43205
43389
  "use strict";
@@ -43207,7 +43391,6 @@ var init_reconcile = __esm({
43207
43391
  IGNORED = /[\\/](?:\.git|node_modules|\.errata|dist|__pycache__)(?:[\\/]|$)/;
43208
43392
  SOURCE_RE = /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i;
43209
43393
  SCAN_YIELD_EVERY = 100;
43210
- LIVENESS_CHUNK = 4e3;
43211
43394
  ORPHAN_REAP_MAX_FRACTION = 0.25;
43212
43395
  ORPHAN_REAP_MIN_ALLOWANCE = 50;
43213
43396
  }
@@ -43224,8 +43407,8 @@ __export(mcp_exports, {
43224
43407
  runTool: () => runTool,
43225
43408
  searchGraph: () => searchGraph
43226
43409
  });
43227
- import { existsSync as existsSync16, readFileSync as readFileSync15 } from "node:fs";
43228
- import { resolve as resolve3 } from "node:path";
43410
+ import { existsSync as existsSync17, readFileSync as readFileSync16 } from "node:fs";
43411
+ import { resolve as resolve4 } from "node:path";
43229
43412
  function collectEnrichmentPulls(store, opts = {}) {
43230
43413
  const pending = store.findNodesByLabel("Solution").filter((s) => s.attrs["enrichmentPending"] === true).filter((s) => !opts.onlyUnsurfaced || s.attrs["enrichmentSurfaced"] !== true);
43231
43414
  const byEpisode = /* @__PURE__ */ new Map();
@@ -43261,7 +43444,7 @@ function takeEnrichmentNudge(store) {
43261
43444
  ` + items;
43262
43445
  }
43263
43446
  function takeDiscriminatorNudge(path2) {
43264
- if (!path2 || !existsSync16(path2)) return null;
43447
+ if (!path2 || !existsSync17(path2)) return null;
43265
43448
  let shared;
43266
43449
  try {
43267
43450
  shared = openGraphStore({ path: path2 });
@@ -43391,11 +43574,11 @@ function showNode(store, node2, maxLines) {
43391
43574
  const relPath = ownerFilePath(store, node2);
43392
43575
  if (!relPath) return { found: false, reason: "no file owner for node" };
43393
43576
  const workspaceRoot = process.cwd();
43394
- const absPath = resolve3(workspaceRoot, relPath);
43395
- if (!existsSync16(absPath)) {
43577
+ const absPath = resolve4(workspaceRoot, relPath);
43578
+ if (!existsSync17(absPath)) {
43396
43579
  return { found: false, reason: `file not found on disk: ${absPath}` };
43397
43580
  }
43398
- const source = readFileSync15(absPath, "utf8");
43581
+ const source = readFileSync16(absPath, "utf8");
43399
43582
  const attrs = node2.attrs;
43400
43583
  let startByte = attrs["bodyStartByte"] ?? attrs["startByte"];
43401
43584
  let endByte = attrs["bodyEndByte"] ?? attrs["endByte"];
@@ -43621,7 +43804,7 @@ function buildToolContext(workspaceRoot) {
43621
43804
  const base = { switchInstallationProfile: useInstallationProfile };
43622
43805
  try {
43623
43806
  const cfg = loadConfig();
43624
- const entry = workspaceRoot ? workspaceEntryForPath(resolve3(workspaceRoot)) : null;
43807
+ const entry = workspaceRoot ? workspaceEntryForPath(resolve4(workspaceRoot)) : null;
43625
43808
  const syncOk = effectiveConsent(cfg, entry ? loadProfile(entry.path) : null).sync;
43626
43809
  const identity = resolveWorkspaceIdentity(cfg, entry);
43627
43810
  if (identity.invalid) {
@@ -44114,7 +44297,7 @@ var init_mcp = __esm({
44114
44297
  const local = causalChain(store, { seedId: id, direction: "both", maxHops, limit });
44115
44298
  try {
44116
44299
  const path2 = sharedStorePath();
44117
- if (!existsSync16(path2)) return { found: true, ...local };
44300
+ if (!existsSync17(path2)) return { found: true, ...local };
44118
44301
  const shared = openGraphStore({ path: path2 });
44119
44302
  try {
44120
44303
  if (!shared.getNode(id)) return { found: true, ...local };
@@ -44717,7 +44900,7 @@ var init_mcp = __esm({
44717
44900
  inputSchema: { type: "object", properties: {} },
44718
44901
  handler: () => {
44719
44902
  const path2 = sharedStorePath();
44720
- if (!existsSync16(path2)) return { count: 0, pending: [] };
44903
+ if (!existsSync17(path2)) return { count: 0, pending: [] };
44721
44904
  const shared = openGraphStore({ path: path2 });
44722
44905
  try {
44723
44906
  const pending = pendingAbstractions(shared);
@@ -44745,7 +44928,7 @@ var init_mcp = __esm({
44745
44928
  },
44746
44929
  handler: (args2) => {
44747
44930
  const path2 = sharedStorePath();
44748
- if (!existsSync16(path2)) return { count: 0, pending: [] };
44931
+ if (!existsSync17(path2)) return { count: 0, pending: [] };
44749
44932
  const shared = openGraphStore({ path: path2 });
44750
44933
  try {
44751
44934
  const pending = pendingDiscriminators(shared, {
@@ -44789,7 +44972,7 @@ var init_mcp = __esm({
44789
44972
  },
44790
44973
  handler: (args2) => {
44791
44974
  const path2 = sharedStorePath();
44792
- if (!existsSync16(path2)) return { count: 0, routes: [] };
44975
+ if (!existsSync17(path2)) return { count: 0, routes: [] };
44793
44976
  const shared = openGraphStore({ path: path2 });
44794
44977
  try {
44795
44978
  const result = triageOf(shared, {
@@ -45174,8 +45357,8 @@ __export(vfile_exports, {
45174
45357
  resolvePath: () => resolvePath,
45175
45358
  segmentsOf: () => segmentsOf
45176
45359
  });
45177
- import { writeFileSync as writeFileSync11 } from "node:fs";
45178
- import { join as join16, resolve as resolve4, sep as sep3 } from "node:path";
45360
+ import { writeFileSync as writeFileSync12 } from "node:fs";
45361
+ import { join as join16, resolve as resolve5, sep as sep3 } from "node:path";
45179
45362
  function segmentsOf(rawPath) {
45180
45363
  let p = rawPath.replace(/\\/g, "/");
45181
45364
  p = p.replace(/^.*\.errata\/g\//, "").replace(/^\/?g\//, "").replace(/^\/+/, "");
@@ -45250,13 +45433,13 @@ async function renderVFile(rawPath, store, ctx = {}) {
45250
45433
  async function materializeVFile(rawPath, workspaceRoot, store, ctx = {}) {
45251
45434
  const segs = segmentsOf(rawPath);
45252
45435
  const gRoot = join16(workspaceRoot, ".errata", "g");
45253
- const abs = resolve4(gRoot, ...segs.length ? segs : ["index"]);
45436
+ const abs = resolve5(gRoot, ...segs.length ? segs : ["index"]);
45254
45437
  if (abs !== gRoot && !abs.startsWith(gRoot + sep3)) {
45255
45438
  throw new Error(`refusing to materialize outside .errata/g: ${rawPath}`);
45256
45439
  }
45257
45440
  const text = await renderVFile(rawPath, store, ctx);
45258
45441
  ensureParent(abs);
45259
- writeFileSync11(abs, text, "utf8");
45442
+ writeFileSync12(abs, text, "utf8");
45260
45443
  return abs;
45261
45444
  }
45262
45445
  async function materializeOverview(workspaceRoot, store, ctx = {}) {
@@ -52676,12 +52859,12 @@ var init_tool_index = __esm({
52676
52859
 
52677
52860
  // src/outbox.ts
52678
52861
  import {
52679
- existsSync as existsSync17,
52862
+ existsSync as existsSync18,
52680
52863
  readdirSync as readdirSync5,
52681
- readFileSync as readFileSync16,
52864
+ readFileSync as readFileSync17,
52682
52865
  renameSync as renameSync2,
52683
52866
  unlinkSync as unlinkSync3,
52684
- writeFileSync as writeFileSync12
52867
+ writeFileSync as writeFileSync13
52685
52868
  } from "node:fs";
52686
52869
  import { join as join17 } from "node:path";
52687
52870
  import { createHash as createHash15 } from "node:crypto";
@@ -52689,12 +52872,12 @@ function enqueueOutbox(paths, payload) {
52689
52872
  ensureDir(paths.outbox);
52690
52873
  const id = createHash15("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
52691
52874
  const file2 = join17(paths.outbox, `${Date.now()}-${id}.json`);
52692
- writeFileSync12(file2, JSON.stringify(payload, null, 2), "utf8");
52875
+ writeFileSync13(file2, JSON.stringify(payload, null, 2), "utf8");
52693
52876
  return file2;
52694
52877
  }
52695
52878
  async function flushOutbox(paths, client, store) {
52696
52879
  ensureDir(paths.outbox);
52697
- const entries = existsSync17(paths.outbox) ? readdirSync5(paths.outbox) : [];
52880
+ const entries = existsSync18(paths.outbox) ? readdirSync5(paths.outbox) : [];
52698
52881
  let uploaded = 0;
52699
52882
  let failed = 0;
52700
52883
  const quarantine = (abs, reason) => {
@@ -52708,7 +52891,7 @@ async function flushOutbox(paths, client, store) {
52708
52891
  const abs = join17(paths.outbox, f);
52709
52892
  let payload;
52710
52893
  try {
52711
- payload = JSON.parse(readFileSync16(abs, "utf8"));
52894
+ payload = JSON.parse(readFileSync17(abs, "utf8"));
52712
52895
  } catch {
52713
52896
  failed++;
52714
52897
  quarantine(abs, "unparseable JSON");
@@ -52753,7 +52936,7 @@ async function flushOutbox(paths, client, store) {
52753
52936
  }
52754
52937
  }
52755
52938
  }
52756
- const remainingFiles = existsSync17(paths.outbox) ? readdirSync5(paths.outbox).filter((e) => e.endsWith(".json")) : [];
52939
+ const remainingFiles = existsSync18(paths.outbox) ? readdirSync5(paths.outbox).filter((e) => e.endsWith(".json")) : [];
52757
52940
  return { uploaded, failed, remaining: remainingFiles.length };
52758
52941
  }
52759
52942
  var init_outbox = __esm({
@@ -52993,6 +53176,20 @@ function buildWebUi(deps) {
52993
53176
  const lastInjectedHash = /* @__PURE__ */ new Map();
52994
53177
  const fileRecallSeen = /* @__PURE__ */ new Map();
52995
53178
  const lastSubagentInjectAt = /* @__PURE__ */ new Map();
53179
+ const noteSessionFrom = (headerOrigin, body2, ended = false) => {
53180
+ const { sessionId, agentId } = hookAudience(body2);
53181
+ if (!sessionId || !deps.noteSession) return;
53182
+ const origin = parseOrigin(headerOrigin) ?? parseOrigin(body2["errata_origin"]);
53183
+ try {
53184
+ deps.noteSession({
53185
+ sessionId,
53186
+ ...agentId ? { agentId } : {},
53187
+ ...origin ? { origin } : {},
53188
+ ...ended ? { ended } : {}
53189
+ });
53190
+ } catch {
53191
+ }
53192
+ };
52996
53193
  app.get(
52997
53194
  "/",
52998
53195
  (c) => c.json({
@@ -53136,6 +53333,7 @@ function buildWebUi(deps) {
53136
53333
  const event = hookEvent === "PostToolUseFailure" ? "PostToolUse" : hookEvent;
53137
53334
  let recall = null;
53138
53335
  const audience = hookAudience(body2);
53336
+ noteSessionFrom(c.req.header(ORIGIN_HEADER), body2);
53139
53337
  if (event === "PreToolUse" && (tool === "Agent" || tool === "Task") && audience.subagent === null) {
53140
53338
  try {
53141
53339
  deps.onSubagentSpawn?.(audience.sessionId, input);
@@ -53323,6 +53521,9 @@ function buildWebUi(deps) {
53323
53521
  }
53324
53522
  if (body2["hook_event_name"] === "SubagentStop" && typeof body2["agent_id"] === "string" && body2["agent_id"]) {
53325
53523
  deps.onSubagentStop?.(body2["agent_id"]);
53524
+ noteSessionFrom(c.req.header(ORIGIN_HEADER), body2, true);
53525
+ } else {
53526
+ noteSessionFrom(c.req.header(ORIGIN_HEADER), body2);
53326
53527
  }
53327
53528
  return c.json({ ok: true });
53328
53529
  });
@@ -53335,6 +53536,7 @@ function buildWebUi(deps) {
53335
53536
  }
53336
53537
  const delta = String(body2["delta"] ?? "");
53337
53538
  const sessionId = String(body2["session_id"] ?? "");
53539
+ noteSessionFrom(c.req.header(ORIGIN_HEADER), body2);
53338
53540
  const messageId = typeof body2["message_id"] === "string" ? body2["message_id"] : void 0;
53339
53541
  const index = typeof body2["index"] === "number" ? body2["index"] : 0;
53340
53542
  const isFinal = body2["final"] !== false;
@@ -53362,6 +53564,7 @@ function buildWebUi(deps) {
53362
53564
  if (transcriptPath && deps.onSessionEnd) {
53363
53565
  deps.onSessionEnd({ sessionId, transcriptPath });
53364
53566
  }
53567
+ noteSessionFrom(c.req.header(ORIGIN_HEADER), body2, true);
53365
53568
  return c.json({ ok: true });
53366
53569
  });
53367
53570
  app.post("/api/context-inject", async (c) => {
@@ -53372,6 +53575,7 @@ function buildWebUi(deps) {
53372
53575
  return c.json({});
53373
53576
  }
53374
53577
  const { sessionId: sid, contextKey: contextKey2, subagent, agentId } = hookAudience(body2);
53578
+ noteSessionFrom(c.req.header(ORIGIN_HEADER), body2);
53375
53579
  const hookEvent = String(body2["hook_event_name"] ?? "UserPromptSubmit");
53376
53580
  const atPrompt = hookEvent === "UserPromptSubmit" || hookEvent === "SessionStart" || hookEvent === "SubagentStart";
53377
53581
  if (sid && recallCardEnabled() && atPrompt) {
@@ -53395,8 +53599,9 @@ function buildWebUi(deps) {
53395
53599
  block = own;
53396
53600
  storedCard = own?.card ?? null;
53397
53601
  } else {
53398
- block = readContextFileWithHash(deps.paths.root);
53399
- storedCard = block ? readContextCard(deps.paths.root, block.hash) : null;
53602
+ const own = sid ? deps.sessionContext?.(sid) ?? null : null;
53603
+ block = own ?? readContextFileWithHash(deps.paths.root);
53604
+ storedCard = own ? own.card : block ? readContextCard(deps.paths.root, block.hash) : null;
53400
53605
  }
53401
53606
  const decision = decideContextInject({
53402
53607
  event: hookEvent,
@@ -53610,6 +53815,7 @@ var init_webui = __esm({
53610
53815
  init_agent_signals();
53611
53816
  init_recall_signal();
53612
53817
  init_recall_card();
53818
+ init_session_registry();
53613
53819
  init_review2();
53614
53820
  init_vfile();
53615
53821
  init_tool_index();
@@ -54944,7 +55150,7 @@ var require_util = __commonJS({
54944
55150
  }
54945
55151
  return url2;
54946
55152
  }
54947
- function parseOrigin(url2) {
55153
+ function parseOrigin2(url2) {
54948
55154
  url2 = parseURL(url2);
54949
55155
  if (url2.pathname !== "/" || url2.search || url2.hash) {
54950
55156
  throw new InvalidArgumentError("invalid url");
@@ -55279,7 +55485,7 @@ var require_util = __commonJS({
55279
55485
  toUSVString,
55280
55486
  isUSVString,
55281
55487
  isBlobLike,
55282
- parseOrigin,
55488
+ parseOrigin: parseOrigin2,
55283
55489
  parseURL,
55284
55490
  getServerName,
55285
55491
  isStream,
@@ -55937,9 +56143,9 @@ var require_dispatcher_base = __commonJS({
55937
56143
  }
55938
56144
  close(callback) {
55939
56145
  if (callback === void 0) {
55940
- return new Promise((resolve8, reject) => {
56146
+ return new Promise((resolve9, reject) => {
55941
56147
  this.close((err2, data) => {
55942
- return err2 ? reject(err2) : resolve8(data);
56148
+ return err2 ? reject(err2) : resolve9(data);
55943
56149
  });
55944
56150
  });
55945
56151
  }
@@ -55977,12 +56183,12 @@ var require_dispatcher_base = __commonJS({
55977
56183
  err2 = null;
55978
56184
  }
55979
56185
  if (callback === void 0) {
55980
- return new Promise((resolve8, reject) => {
56186
+ return new Promise((resolve9, reject) => {
55981
56187
  this.destroy(err2, (err3, data) => {
55982
56188
  return err3 ? (
55983
56189
  /* istanbul ignore next: should never error */
55984
56190
  reject(err3)
55985
- ) : resolve8(data);
56191
+ ) : resolve9(data);
55986
56192
  });
55987
56193
  });
55988
56194
  }
@@ -58249,8 +58455,8 @@ var require_util2 = __commonJS({
58249
58455
  function createDeferredPromise() {
58250
58456
  let res;
58251
58457
  let rej;
58252
- const promise2 = new Promise((resolve8, reject) => {
58253
- res = resolve8;
58458
+ const promise2 = new Promise((resolve9, reject) => {
58459
+ res = resolve9;
58254
58460
  rej = reject;
58255
58461
  });
58256
58462
  return { promise: promise2, resolve: res, reject: rej };
@@ -60391,12 +60597,12 @@ upgrade: ${upgrade}\r
60391
60597
  cb();
60392
60598
  }
60393
60599
  }
60394
- const waitForDrain = () => new Promise((resolve8, reject) => {
60600
+ const waitForDrain = () => new Promise((resolve9, reject) => {
60395
60601
  assert2(callback === null);
60396
60602
  if (socket[kError]) {
60397
60603
  reject(socket[kError]);
60398
60604
  } else {
60399
- callback = resolve8;
60605
+ callback = resolve9;
60400
60606
  }
60401
60607
  });
60402
60608
  socket.on("close", onDrain).on("drain", onDrain);
@@ -61033,12 +61239,12 @@ var require_client_h2 = __commonJS({
61033
61239
  cb();
61034
61240
  }
61035
61241
  }
61036
- const waitForDrain = () => new Promise((resolve8, reject) => {
61242
+ const waitForDrain = () => new Promise((resolve9, reject) => {
61037
61243
  assert2(callback === null);
61038
61244
  if (socket[kError]) {
61039
61245
  reject(socket[kError]);
61040
61246
  } else {
61041
- callback = resolve8;
61247
+ callback = resolve9;
61042
61248
  }
61043
61249
  });
61044
61250
  h2stream.on("close", onDrain).on("drain", onDrain);
@@ -61515,16 +61721,16 @@ var require_client = __commonJS({
61515
61721
  return this[kNeedDrain] < 2;
61516
61722
  }
61517
61723
  async [kClose]() {
61518
- return new Promise((resolve8) => {
61724
+ return new Promise((resolve9) => {
61519
61725
  if (this[kSize]) {
61520
- this[kClosedResolve] = resolve8;
61726
+ this[kClosedResolve] = resolve9;
61521
61727
  } else {
61522
- resolve8(null);
61728
+ resolve9(null);
61523
61729
  }
61524
61730
  });
61525
61731
  }
61526
61732
  async [kDestroy](err2) {
61527
- return new Promise((resolve8) => {
61733
+ return new Promise((resolve9) => {
61528
61734
  const requests = this[kQueue].splice(this[kPendingIdx]);
61529
61735
  for (let i2 = 0; i2 < requests.length; i2++) {
61530
61736
  const request = requests[i2];
@@ -61535,7 +61741,7 @@ var require_client = __commonJS({
61535
61741
  this[kClosedResolve]();
61536
61742
  this[kClosedResolve] = null;
61537
61743
  }
61538
- resolve8(null);
61744
+ resolve9(null);
61539
61745
  };
61540
61746
  if (this[kHTTPContext]) {
61541
61747
  this[kHTTPContext].destroy(err2, callback);
@@ -61586,7 +61792,7 @@ var require_client = __commonJS({
61586
61792
  });
61587
61793
  }
61588
61794
  try {
61589
- const socket = await new Promise((resolve8, reject) => {
61795
+ const socket = await new Promise((resolve9, reject) => {
61590
61796
  client[kConnector]({
61591
61797
  host,
61592
61798
  hostname: hostname3,
@@ -61598,7 +61804,7 @@ var require_client = __commonJS({
61598
61804
  if (err2) {
61599
61805
  reject(err2);
61600
61806
  } else {
61601
- resolve8(socket2);
61807
+ resolve9(socket2);
61602
61808
  }
61603
61809
  });
61604
61810
  });
@@ -61934,8 +62140,8 @@ var require_pool_base = __commonJS({
61934
62140
  if (this[kQueue].isEmpty()) {
61935
62141
  await Promise.all(this[kClients].map((c) => c.close()));
61936
62142
  } else {
61937
- await new Promise((resolve8) => {
61938
- this[kClosedResolve] = resolve8;
62143
+ await new Promise((resolve9) => {
62144
+ this[kClosedResolve] = resolve9;
61939
62145
  });
61940
62146
  }
61941
62147
  }
@@ -62103,7 +62309,7 @@ var require_balanced_pool = __commonJS({
62103
62309
  } = require_pool_base();
62104
62310
  var Pool = require_pool();
62105
62311
  var { kUrl, kInterceptors } = require_symbols();
62106
- var { parseOrigin } = require_util();
62312
+ var { parseOrigin: parseOrigin2 } = require_util();
62107
62313
  var kFactory = Symbol("factory");
62108
62314
  var kOptions = Symbol("options");
62109
62315
  var kGreatestCommonDivisor = Symbol("kGreatestCommonDivisor");
@@ -62146,7 +62352,7 @@ var require_balanced_pool = __commonJS({
62146
62352
  this._updateBalancedPoolStats();
62147
62353
  }
62148
62354
  addUpstream(upstream) {
62149
- const upstreamOrigin = parseOrigin(upstream).origin;
62355
+ const upstreamOrigin = parseOrigin2(upstream).origin;
62150
62356
  if (this[kClients].find((pool2) => pool2[kUrl].origin === upstreamOrigin && pool2.closed !== true && pool2.destroyed !== true)) {
62151
62357
  return this;
62152
62358
  }
@@ -62180,7 +62386,7 @@ var require_balanced_pool = __commonJS({
62180
62386
  this[kGreatestCommonDivisor] = result;
62181
62387
  }
62182
62388
  removeUpstream(upstream) {
62183
- const upstreamOrigin = parseOrigin(upstream).origin;
62389
+ const upstreamOrigin = parseOrigin2(upstream).origin;
62184
62390
  const pool = this[kClients].find((pool2) => pool2[kUrl].origin === upstreamOrigin && pool2.closed !== true && pool2.destroyed !== true);
62185
62391
  if (pool) {
62186
62392
  this[kRemoveClient](pool);
@@ -63150,7 +63356,7 @@ var require_readable = __commonJS({
63150
63356
  if (this._readableState.closeEmitted) {
63151
63357
  return null;
63152
63358
  }
63153
- return await new Promise((resolve8, reject) => {
63359
+ return await new Promise((resolve9, reject) => {
63154
63360
  if (this[kContentLength] > limit) {
63155
63361
  this.destroy(new AbortError());
63156
63362
  }
@@ -63163,7 +63369,7 @@ var require_readable = __commonJS({
63163
63369
  if (signal?.aborted) {
63164
63370
  reject(signal.reason ?? new AbortError());
63165
63371
  } else {
63166
- resolve8(null);
63372
+ resolve9(null);
63167
63373
  }
63168
63374
  }).on("error", noop).on("data", function(chunk) {
63169
63375
  limit -= chunk.length;
@@ -63182,7 +63388,7 @@ var require_readable = __commonJS({
63182
63388
  }
63183
63389
  async function consume(stream, type) {
63184
63390
  assert2(!stream[kConsume]);
63185
- return new Promise((resolve8, reject) => {
63391
+ return new Promise((resolve9, reject) => {
63186
63392
  if (isUnusable(stream)) {
63187
63393
  const rState = stream._readableState;
63188
63394
  if (rState.destroyed && rState.closeEmitted === false) {
@@ -63199,7 +63405,7 @@ var require_readable = __commonJS({
63199
63405
  stream[kConsume] = {
63200
63406
  type,
63201
63407
  stream,
63202
- resolve: resolve8,
63408
+ resolve: resolve9,
63203
63409
  reject,
63204
63410
  length: 0,
63205
63411
  body: []
@@ -63269,18 +63475,18 @@ var require_readable = __commonJS({
63269
63475
  return buffer;
63270
63476
  }
63271
63477
  function consumeEnd(consume2) {
63272
- const { type, body: body2, resolve: resolve8, stream, length } = consume2;
63478
+ const { type, body: body2, resolve: resolve9, stream, length } = consume2;
63273
63479
  try {
63274
63480
  if (type === "text") {
63275
- resolve8(chunksDecode(body2, length));
63481
+ resolve9(chunksDecode(body2, length));
63276
63482
  } else if (type === "json") {
63277
- resolve8(JSON.parse(chunksDecode(body2, length)));
63483
+ resolve9(JSON.parse(chunksDecode(body2, length)));
63278
63484
  } else if (type === "arrayBuffer") {
63279
- resolve8(chunksConcat(body2, length).buffer);
63485
+ resolve9(chunksConcat(body2, length).buffer);
63280
63486
  } else if (type === "blob") {
63281
- resolve8(new Blob(body2, { type: stream[kContentType] }));
63487
+ resolve9(new Blob(body2, { type: stream[kContentType] }));
63282
63488
  } else if (type === "bytes") {
63283
- resolve8(chunksConcat(body2, length));
63489
+ resolve9(chunksConcat(body2, length));
63284
63490
  }
63285
63491
  consumeFinish(consume2);
63286
63492
  } catch (err2) {
@@ -63537,9 +63743,9 @@ var require_api_request = __commonJS({
63537
63743
  };
63538
63744
  function request(opts, callback) {
63539
63745
  if (callback === void 0) {
63540
- return new Promise((resolve8, reject) => {
63746
+ return new Promise((resolve9, reject) => {
63541
63747
  request.call(this, opts, (err2, data) => {
63542
- return err2 ? reject(err2) : resolve8(data);
63748
+ return err2 ? reject(err2) : resolve9(data);
63543
63749
  });
63544
63750
  });
63545
63751
  }
@@ -63762,9 +63968,9 @@ var require_api_stream = __commonJS({
63762
63968
  };
63763
63969
  function stream(opts, factory, callback) {
63764
63970
  if (callback === void 0) {
63765
- return new Promise((resolve8, reject) => {
63971
+ return new Promise((resolve9, reject) => {
63766
63972
  stream.call(this, opts, factory, (err2, data) => {
63767
- return err2 ? reject(err2) : resolve8(data);
63973
+ return err2 ? reject(err2) : resolve9(data);
63768
63974
  });
63769
63975
  });
63770
63976
  }
@@ -64049,9 +64255,9 @@ var require_api_upgrade = __commonJS({
64049
64255
  };
64050
64256
  function upgrade(opts, callback) {
64051
64257
  if (callback === void 0) {
64052
- return new Promise((resolve8, reject) => {
64258
+ return new Promise((resolve9, reject) => {
64053
64259
  upgrade.call(this, opts, (err2, data) => {
64054
- return err2 ? reject(err2) : resolve8(data);
64260
+ return err2 ? reject(err2) : resolve9(data);
64055
64261
  });
64056
64262
  });
64057
64263
  }
@@ -64143,9 +64349,9 @@ var require_api_connect = __commonJS({
64143
64349
  };
64144
64350
  function connect(opts, callback) {
64145
64351
  if (callback === void 0) {
64146
- return new Promise((resolve8, reject) => {
64352
+ return new Promise((resolve9, reject) => {
64147
64353
  connect.call(this, opts, (err2, data) => {
64148
- return err2 ? reject(err2) : resolve8(data);
64354
+ return err2 ? reject(err2) : resolve9(data);
64149
64355
  });
64150
64356
  });
64151
64357
  }
@@ -68007,7 +68213,7 @@ var require_fetch = __commonJS({
68007
68213
  function dispatch({ body: body2 }) {
68008
68214
  const url2 = requestCurrentURL(request);
68009
68215
  const agent = fetchParams.controller.dispatcher;
68010
- return new Promise((resolve8, reject) => agent.dispatch(
68216
+ return new Promise((resolve9, reject) => agent.dispatch(
68011
68217
  {
68012
68218
  path: url2.pathname + url2.search,
68013
68219
  origin: url2.origin,
@@ -68083,7 +68289,7 @@ var require_fetch = __commonJS({
68083
68289
  }
68084
68290
  }
68085
68291
  const onError = this.onError.bind(this);
68086
- resolve8({
68292
+ resolve9({
68087
68293
  status,
68088
68294
  statusText,
68089
68295
  headersList,
@@ -68129,7 +68335,7 @@ var require_fetch = __commonJS({
68129
68335
  for (let i2 = 0; i2 < rawHeaders.length; i2 += 2) {
68130
68336
  headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i2]), rawHeaders[i2 + 1].toString("latin1"), true);
68131
68337
  }
68132
- resolve8({
68338
+ resolve9({
68133
68339
  status,
68134
68340
  statusText: STATUS_CODES[status],
68135
68341
  headersList,
@@ -71768,8 +71974,8 @@ var require_util8 = __commonJS({
71768
71974
  return true;
71769
71975
  }
71770
71976
  function delay(ms) {
71771
- return new Promise((resolve8) => {
71772
- setTimeout(resolve8, ms).unref();
71977
+ return new Promise((resolve9) => {
71978
+ setTimeout(resolve9, ms).unref();
71773
71979
  });
71774
71980
  }
71775
71981
  module2.exports = {
@@ -72457,7 +72663,7 @@ __export(witness_ledger_exports, {
72457
72663
  summarizeWitnessLedger: () => summarizeWitnessLedger,
72458
72664
  witnessLedgerPath: () => witnessLedgerPath
72459
72665
  });
72460
- import { appendFileSync as appendFileSync3, existsSync as existsSync26, readFileSync as readFileSync29, writeFileSync as writeFileSync20 } from "node:fs";
72666
+ import { appendFileSync as appendFileSync3, existsSync as existsSync27, readFileSync as readFileSync30, writeFileSync as writeFileSync21 } from "node:fs";
72461
72667
  import { join as join33 } from "node:path";
72462
72668
  function witnessLedgerPath(configDir) {
72463
72669
  return join33(configDir, "witness-ledger.jsonl");
@@ -72466,18 +72672,18 @@ function appendWitnessLedger(configDir, entry) {
72466
72672
  const path2 = witnessLedgerPath(configDir);
72467
72673
  try {
72468
72674
  appendFileSync3(path2, JSON.stringify(entry) + "\n");
72469
- const lines = readFileSync29(path2, "utf8").split("\n").filter(Boolean);
72675
+ const lines = readFileSync30(path2, "utf8").split("\n").filter(Boolean);
72470
72676
  if (lines.length > LEDGER_MAX_LINES) {
72471
- writeFileSync20(path2, lines.slice(-Math.floor(LEDGER_MAX_LINES / 2)).join("\n") + "\n");
72677
+ writeFileSync21(path2, lines.slice(-Math.floor(LEDGER_MAX_LINES / 2)).join("\n") + "\n");
72472
72678
  }
72473
72679
  } catch {
72474
72680
  }
72475
72681
  }
72476
72682
  function readWitnessLedger(configDir) {
72477
72683
  const path2 = witnessLedgerPath(configDir);
72478
- if (!existsSync26(path2)) return [];
72684
+ if (!existsSync27(path2)) return [];
72479
72685
  try {
72480
- return readFileSync29(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter((e) => typeof e.ts === "number" && typeof e.channel === "string");
72686
+ return readFileSync30(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter((e) => typeof e.ts === "number" && typeof e.channel === "string");
72481
72687
  } catch {
72482
72688
  return [];
72483
72689
  }
@@ -72541,13 +72747,13 @@ function esc3(s) {
72541
72747
  function slug(name2) {
72542
72748
  return name2.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
72543
72749
  }
72544
- function isLive3(verb) {
72750
+ function isLive2(verb) {
72545
72751
  return LIVE_VERBS.has(verb);
72546
72752
  }
72547
72753
  function nextHtml(n, opts) {
72548
72754
  if (!n) return "";
72549
72755
  const cmd2 = `errata ${n.verb}${n.arg ? " " + n.arg : ""}`;
72550
- const live3 = isLive3(n.verb);
72756
+ const live3 = isLive2(n.verb);
72551
72757
  if (!live3 && !opts.includeFutureVerbs) return "";
72552
72758
  const hint = n.hint ? ` \u2014 ${esc3(n.hint)}` : "";
72553
72759
  const cls = live3 ? "next" : "next soon";
@@ -72916,12 +73122,12 @@ var init_report_render = __esm({
72916
73122
 
72917
73123
  // src/cli.ts
72918
73124
  init_src6();
72919
- import { closeSync as closeSync2, existsSync as existsSync37, openSync as openSync2, readFileSync as readFileSync40, renameSync as renameSync6, statSync as statSync11 } from "node:fs";
73125
+ import { closeSync as closeSync2, existsSync as existsSync38, openSync as openSync2, readFileSync as readFileSync41, renameSync as renameSync6, statSync as statSync11 } from "node:fs";
72920
73126
  import { join as join47, resolve as pathResolve2 } from "node:path";
72921
73127
  import { spawn as spawn5 } from "node:child_process";
72922
73128
 
72923
73129
  // src/daemon.ts
72924
- import { existsSync as existsSync28, writeFileSync as writeFileSync23 } from "node:fs";
73130
+ import { existsSync as existsSync29, writeFileSync as writeFileSync24 } from "node:fs";
72925
73131
 
72926
73132
  // ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.8/node_modules/@hono/node-server/dist/index.mjs
72927
73133
  import { createServer as createServerHTTP } from "http";
@@ -73351,7 +73557,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
73351
73557
  });
73352
73558
  if (!chunk) {
73353
73559
  if (i2 === 1) {
73354
- await new Promise((resolve8) => setTimeout(resolve8));
73560
+ await new Promise((resolve9) => setTimeout(resolve9));
73355
73561
  maxReadCount = 3;
73356
73562
  continue;
73357
73563
  }
@@ -73502,7 +73708,7 @@ init_lock();
73502
73708
 
73503
73709
  // src/engine.ts
73504
73710
  import { execFileSync as execFileSync5 } from "node:child_process";
73505
- import { existsSync as existsSync27, statSync as statSync8, appendFileSync as appendFileSync4, readdirSync as readdirSync10, renameSync as renameSync4, readFileSync as readFileSync31, writeFileSync as writeFileSync22 } from "node:fs";
73711
+ import { existsSync as existsSync28, statSync as statSync8, appendFileSync as appendFileSync4, readdirSync as readdirSync10, renameSync as renameSync4, readFileSync as readFileSync32, writeFileSync as writeFileSync23 } from "node:fs";
73506
73712
  import { basename as basename7, join as join35, relative as relative6, sep as sep4 } from "node:path";
73507
73713
 
73508
73714
  // src/source-watcher.ts
@@ -74364,7 +74570,7 @@ var NodeFsHandler = class {
74364
74570
  this._addToNodeFs(path2, initialAdd, wh, depth + 1);
74365
74571
  }
74366
74572
  }).on(EV.ERROR, this._boundHandleError);
74367
- return new Promise((resolve8, reject) => {
74573
+ return new Promise((resolve9, reject) => {
74368
74574
  if (!stream)
74369
74575
  return reject();
74370
74576
  stream.once(STR_END, () => {
@@ -74373,7 +74579,7 @@ var NodeFsHandler = class {
74373
74579
  return;
74374
74580
  }
74375
74581
  const wasThrottled = throttler ? throttler.clear() : false;
74376
- resolve8(void 0);
74582
+ resolve9(void 0);
74377
74583
  previous.getChildren().filter((item2) => {
74378
74584
  return item2 !== directory && !current.has(item2);
74379
74585
  }).forEach((item2) => {
@@ -75541,6 +75747,7 @@ async function chat(req) {
75541
75747
  // src/engine.ts
75542
75748
  init_src11();
75543
75749
  init_src6();
75750
+ init_session_registry();
75544
75751
  init_recall_signal();
75545
75752
 
75546
75753
  // src/subagent-state.ts
@@ -75695,7 +75902,7 @@ init_review2();
75695
75902
 
75696
75903
  // src/turn.ts
75697
75904
  init_checkout_root();
75698
- import { closeSync, existsSync as existsSync18, fstatSync, openSync, readdirSync as readdirSync6, readSync, realpathSync, statSync as statSync6 } from "node:fs";
75905
+ import { closeSync, existsSync as existsSync19, fstatSync, openSync, readdirSync as readdirSync6, readSync, realpathSync as realpathSync2, statSync as statSync6 } from "node:fs";
75699
75906
  import { basename as basename5, delimiter, dirname as dirname10, join as join21, normalize as normalize3 } from "node:path";
75700
75907
  import { homedir as homedir4 } from "node:os";
75701
75908
  import { createHash as createHash16 } from "node:crypto";
@@ -76088,7 +76295,7 @@ function claudeProjectDir(cwd, home = homedir4()) {
76088
76295
  }
76089
76296
  function recentTranscripts(cwd, opts = {}) {
76090
76297
  const dir = claudeProjectDir(cwd, opts.home ?? homedir4());
76091
- if (!existsSync18(dir)) return [];
76298
+ if (!existsSync19(dir)) return [];
76092
76299
  let names;
76093
76300
  try {
76094
76301
  names = readdirSync6(dir);
@@ -76115,7 +76322,7 @@ function recentTranscripts(cwd, opts = {}) {
76115
76322
  function subagentTranscripts(mainTranscriptPath, sessionId) {
76116
76323
  if (!mainTranscriptPath || !sessionId) return [];
76117
76324
  const dir = join21(dirname10(mainTranscriptPath), sessionId, "subagents");
76118
- if (!existsSync18(dir)) return [];
76325
+ if (!existsSync19(dir)) return [];
76119
76326
  let names;
76120
76327
  try {
76121
76328
  names = readdirSync6(dir);
@@ -76199,7 +76406,7 @@ function codexRolloutsForCwd(cwd, opts = {}) {
76199
76406
  const owner = checkoutRootOf(cwd);
76200
76407
  const owners = /* @__PURE__ */ new Map();
76201
76408
  for (const root of codexSessionRoots(opts.env, opts.home)) {
76202
- if (!existsSync18(root)) {
76409
+ if (!existsSync19(root)) {
76203
76410
  codexRolloutActivity.delete(root);
76204
76411
  continue;
76205
76412
  }
@@ -76269,7 +76476,7 @@ function geminiProjectHash(cwd) {
76269
76476
  function geminiHashesFor(cwd) {
76270
76477
  const variants = /* @__PURE__ */ new Set([cwd, cwd.replace(/\/+$/, "")]);
76271
76478
  try {
76272
- variants.add(realpathSync(cwd));
76479
+ variants.add(realpathSync2(cwd));
76273
76480
  } catch {
76274
76481
  }
76275
76482
  return new Set([...variants].map(geminiProjectHash));
@@ -76300,7 +76507,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
76300
76507
  const hashes = geminiHashesFor(cwd);
76301
76508
  const out2 = [];
76302
76509
  for (const root of geminiSessionRoots(opts.env, opts.home)) {
76303
- if (!existsSync18(root)) continue;
76510
+ if (!existsSync19(root)) continue;
76304
76511
  let slugs;
76305
76512
  try {
76306
76513
  slugs = readdirSync6(root);
@@ -76366,12 +76573,12 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
76366
76573
  const limit = opts.limit ?? 25;
76367
76574
  const want = /* @__PURE__ */ new Set([cwd, cwd.replace(/\/+$/, "")]);
76368
76575
  try {
76369
- want.add(realpathSync(cwd));
76576
+ want.add(realpathSync2(cwd));
76370
76577
  } catch {
76371
76578
  }
76372
76579
  const out2 = [];
76373
76580
  for (const root of opencodeSessionRoots(opts.env, opts.home)) {
76374
- if (!existsSync18(root)) continue;
76581
+ if (!existsSync19(root)) continue;
76375
76582
  let names;
76376
76583
  try {
76377
76584
  names = readdirSync6(root);
@@ -76403,7 +76610,7 @@ init_src2();
76403
76610
  init_agent_signals();
76404
76611
  init_tool_index();
76405
76612
  init_src5();
76406
- import { readFileSync as readFileSync17, writeFileSync as writeFileSync13 } from "node:fs";
76613
+ import { readFileSync as readFileSync18, writeFileSync as writeFileSync14 } from "node:fs";
76407
76614
  var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
76408
76615
  var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
76409
76616
  var HANDLE_RE = /\[([a-z0-9][\w-]{0,80})\]|((?:pat|sol|drc|dcause|dfix|dprob|dvuln|prob|claim|err)_[0-9a-f]{6,})/gi;
@@ -77136,13 +77343,13 @@ function writePrimingHandles(path2, nodes, now = Date.now()) {
77136
77343
  entries.sort((a, b) => (b[1].seenAt ?? 0) - (a[1].seenAt ?? 0));
77137
77344
  entries.length = HANDLE_MAP_MAX;
77138
77345
  }
77139
- writeFileSync13(path2, JSON.stringify(Object.fromEntries(entries)));
77346
+ writeFileSync14(path2, JSON.stringify(Object.fromEntries(entries)));
77140
77347
  } catch {
77141
77348
  }
77142
77349
  }
77143
77350
  function readPrimingHandles(path2) {
77144
77351
  try {
77145
- return JSON.parse(readFileSync17(path2, "utf8"));
77352
+ return JSON.parse(readFileSync18(path2, "utf8"));
77146
77353
  } catch {
77147
77354
  return {};
77148
77355
  }
@@ -77622,7 +77829,7 @@ ${conversation}` }]
77622
77829
  // src/constraint-backfill.ts
77623
77830
  init_src5();
77624
77831
  init_src2();
77625
- import { existsSync as existsSync19, readFileSync as readFileSync18, readdirSync as readdirSync7, writeFileSync as writeFileSync14 } from "node:fs";
77832
+ import { existsSync as existsSync20, readFileSync as readFileSync19, readdirSync as readdirSync7, writeFileSync as writeFileSync15 } from "node:fs";
77626
77833
  import { join as join22 } from "node:path";
77627
77834
  import { homedir as homedir5 } from "node:os";
77628
77835
  var BACKFILL_VERSION = 1;
@@ -77641,9 +77848,9 @@ function markerPath(configDir) {
77641
77848
  }
77642
77849
  function alreadyDone(configDir) {
77643
77850
  const p = markerPath(configDir);
77644
- if (!existsSync19(p)) return false;
77851
+ if (!existsSync20(p)) return false;
77645
77852
  try {
77646
- const raw2 = JSON.parse(readFileSync18(p, "utf8"));
77853
+ const raw2 = JSON.parse(readFileSync19(p, "utf8"));
77647
77854
  return raw2?.version === BACKFILL_VERSION;
77648
77855
  } catch {
77649
77856
  return false;
@@ -77653,7 +77860,7 @@ function replay(root) {
77653
77860
  const statements = /* @__PURE__ */ new Set();
77654
77861
  const citedByFix = /* @__PURE__ */ new Set();
77655
77862
  const dir = claudeProjectDir(root, homedir5());
77656
- if (!existsSync19(dir)) return { statements, citedByFix };
77863
+ if (!existsSync20(dir)) return { statements, citedByFix };
77657
77864
  let names;
77658
77865
  try {
77659
77866
  names = readdirSync7(dir).filter((n) => n.endsWith(".jsonl"));
@@ -77663,7 +77870,7 @@ function replay(root) {
77663
77870
  for (const f of names) {
77664
77871
  let lines;
77665
77872
  try {
77666
- lines = readFileSync18(join22(dir, f), "utf8").split("\n");
77873
+ lines = readFileSync19(join22(dir, f), "utf8").split("\n");
77667
77874
  } catch {
77668
77875
  continue;
77669
77876
  }
@@ -77777,7 +77984,7 @@ function backfillConstraintKind(store, opts) {
77777
77984
  }
77778
77985
  });
77779
77986
  try {
77780
- writeFileSync14(
77987
+ writeFileSync15(
77781
77988
  markerPath(opts.configDir),
77782
77989
  JSON.stringify({ version: BACKFILL_VERSION, at: opts.now, ...report, cloudTwins: report.cloudTwins.length }, null, 2),
77783
77990
  "utf8"
@@ -77790,7 +77997,7 @@ function backfillConstraintKind(store, opts) {
77790
77997
  // src/edge-repair.ts
77791
77998
  init_src();
77792
77999
  init_src5();
77793
- import { existsSync as existsSync20, readFileSync as readFileSync19, writeFileSync as writeFileSync15 } from "node:fs";
78000
+ import { existsSync as existsSync21, readFileSync as readFileSync20, writeFileSync as writeFileSync16 } from "node:fs";
77794
78001
  import { join as join23 } from "node:path";
77795
78002
  function citeEdgeId(from, type, to) {
77796
78003
  return `edge_${digest({ from, type, to })}`.slice(0, 24);
@@ -77810,9 +78017,9 @@ function markerPath2(configDir) {
77810
78017
  }
77811
78018
  function alreadyDone2(configDir) {
77812
78019
  const p = markerPath2(configDir);
77813
- if (!existsSync20(p)) return false;
78020
+ if (!existsSync21(p)) return false;
77814
78021
  try {
77815
- return JSON.parse(readFileSync19(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
78022
+ return JSON.parse(readFileSync20(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
77816
78023
  } catch {
77817
78024
  return false;
77818
78025
  }
@@ -77861,7 +78068,7 @@ function repairInvalidEdges(store, opts) {
77861
78068
  });
77862
78069
  store.pruneEdgeRejections(opts.now - REJECTION_RETENTION_MS);
77863
78070
  try {
77864
- writeFileSync15(
78071
+ writeFileSync16(
77865
78072
  markerPath2(opts.configDir),
77866
78073
  JSON.stringify({ version: EDGE_REPAIR_VERSION, at: opts.now, ...report }, null, 2),
77867
78074
  "utf8"
@@ -77875,7 +78082,7 @@ function repairInvalidEdges(store, opts) {
77875
78082
  init_reconcile();
77876
78083
 
77877
78084
  // src/pass-ledger.ts
77878
- import { appendFileSync as appendFileSync2, existsSync as existsSync21, readFileSync as readFileSync20, writeFileSync as writeFileSync16 } from "node:fs";
78085
+ import { appendFileSync as appendFileSync2, existsSync as existsSync22, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "node:fs";
77879
78086
  import { join as join24 } from "node:path";
77880
78087
 
77881
78088
  // src/isolate-census.ts
@@ -77928,7 +78135,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
77928
78135
  return;
77929
78136
  }
77930
78137
  appendsSinceTrim.set(path2, 0);
77931
- const lines = readFileSync20(path2, "utf8").split("\n").filter(Boolean);
78138
+ const lines = readFileSync21(path2, "utf8").split("\n").filter(Boolean);
77932
78139
  const keptByKind = /* @__PURE__ */ new Map();
77933
78140
  const kept = [];
77934
78141
  for (let i2 = lines.length - 1; i2 >= 0; i2--) {
@@ -77944,16 +78151,16 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
77944
78151
  kept.push(lines[i2]);
77945
78152
  }
77946
78153
  if (kept.length < lines.length) {
77947
- writeFileSync16(path2, kept.reverse().join("\n") + "\n");
78154
+ writeFileSync17(path2, kept.reverse().join("\n") + "\n");
77948
78155
  }
77949
78156
  } catch {
77950
78157
  }
77951
78158
  }
77952
78159
  function readPassLedger(configDir) {
77953
78160
  const path2 = passLedgerPath(configDir);
77954
- if (!existsSync21(path2)) return [];
78161
+ if (!existsSync22(path2)) return [];
77955
78162
  try {
77956
- return readFileSync20(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
78163
+ return readFileSync21(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
77957
78164
  (e) => typeof e?.ts === "number" && typeof e?.kind === "string" && typeof e?.durationMs === "number"
77958
78165
  ).map((e) => ({ ...e, counts: e.counts ?? {} }));
77959
78166
  } catch {
@@ -78183,14 +78390,42 @@ import { Worker } from "node:worker_threads";
78183
78390
  // src/pass-gate.ts
78184
78391
  var QUEUE_WARN_MS = 12e4;
78185
78392
  var chain = Promise.resolve();
78393
+ var nextId = 0;
78394
+ var waiting = /* @__PURE__ */ new Map();
78395
+ var active = null;
78396
+ var recent2 = [];
78397
+ function heavyPassState() {
78398
+ const now = Date.now();
78399
+ return {
78400
+ active: active ? { label: active.label, runningMs: now - active.startedAt, waitedMs: active.waitedMs } : null,
78401
+ waiting: waiting.size,
78402
+ pending: [...waiting.values()].slice(0, 32).map((p) => ({ label: p.label, waitedMs: now - p.queuedAt })),
78403
+ recent: [...recent2]
78404
+ };
78405
+ }
78186
78406
  function withHeavyPassSlot(label, fn) {
78187
78407
  const queuedAt = Date.now();
78188
- const run3 = chain.then(() => {
78408
+ const id = nextId++;
78409
+ waiting.set(id, { label, queuedAt });
78410
+ const run3 = chain.then(async () => {
78189
78411
  const waited = Date.now() - queuedAt;
78412
+ waiting.delete(id);
78413
+ const startedAt = Date.now();
78414
+ active = { label, startedAt, waitedMs: waited };
78190
78415
  if (waited > QUEUE_WARN_MS) {
78191
78416
  console.warn(`[errata] heavy-pass slot: ${label} waited ${Math.round(waited / 1e3)}s`);
78192
78417
  }
78193
- return fn();
78418
+ let failed = false;
78419
+ try {
78420
+ return await fn();
78421
+ } catch (err2) {
78422
+ failed = true;
78423
+ throw err2;
78424
+ } finally {
78425
+ recent2.push({ label, waitedMs: waited, durationMs: Date.now() - startedAt, failed });
78426
+ if (recent2.length > 16) recent2.shift();
78427
+ active = null;
78428
+ }
78194
78429
  });
78195
78430
  chain = run3.then(
78196
78431
  () => void 0,
@@ -78209,6 +78444,12 @@ var PassWorker = class {
78209
78444
  pending = /* @__PURE__ */ new Map();
78210
78445
  nextId = 1;
78211
78446
  stopped = false;
78447
+ /** Open/migrate/index the database on the worker before the serving thread
78448
+ * opens its connection. Additive indexes and one-time repairs can take tens
78449
+ * of seconds on an existing workspace; a prepared reopen is cheap. */
78450
+ prepareStore() {
78451
+ return this.call("prepareStore");
78452
+ }
78212
78453
  /** Run the nightly graph-math + induction pass on the worker. */
78213
78454
  nightly() {
78214
78455
  return this.call("nightly");
@@ -78249,8 +78490,8 @@ var PassWorker = class {
78249
78490
  const id = this.nextId++;
78250
78491
  try {
78251
78492
  await this.ready;
78252
- return await new Promise((resolve8, reject) => {
78253
- this.pending.set(id, { resolve: resolve8, reject });
78493
+ return await new Promise((resolve9, reject) => {
78494
+ this.pending.set(id, { resolve: resolve9, reject });
78254
78495
  this.worker.postMessage({ id, kind, ...payload !== void 0 ? { payload } : {} });
78255
78496
  });
78256
78497
  } finally {
@@ -78284,12 +78525,12 @@ var PassWorker = class {
78284
78525
  });
78285
78526
  noteIsolateSpawned();
78286
78527
  this.worker = worker;
78287
- this.ready = new Promise((resolve8, reject) => {
78528
+ this.ready = new Promise((resolve9, reject) => {
78288
78529
  const onReady = (m) => {
78289
78530
  if (m?.ready) {
78290
78531
  worker.off("message", onReady);
78291
78532
  worker.off("error", onErr);
78292
- resolve8();
78533
+ resolve9();
78293
78534
  }
78294
78535
  };
78295
78536
  const onErr = (err2) => reject(err2);
@@ -78334,11 +78575,11 @@ init_outbox();
78334
78575
  init_src10();
78335
78576
  init_src();
78336
78577
  init_src2();
78337
- import { readFileSync as readFileSync21 } from "node:fs";
78578
+ import { readFileSync as readFileSync22 } from "node:fs";
78338
78579
  import { join as join25 } from "node:path";
78339
78580
  function loadClaimIgnorePatterns(workspaceRoot) {
78340
78581
  try {
78341
- return readFileSync21(join25(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
78582
+ return readFileSync22(join25(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
78342
78583
  } catch {
78343
78584
  return [];
78344
78585
  }
@@ -78716,7 +78957,7 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
78716
78957
  // src/retrieval-stack.ts
78717
78958
  init_src();
78718
78959
  import { execFileSync as execFileSync4 } from "node:child_process";
78719
- import { existsSync as existsSync22, readFileSync as readFileSync22, statSync as statSync7 } from "node:fs";
78960
+ import { existsSync as existsSync23, readFileSync as readFileSync23, statSync as statSync7 } from "node:fs";
78720
78961
  import { homedir as homedir6 } from "node:os";
78721
78962
  import { join as join26 } from "node:path";
78722
78963
  var RETRIEVAL_STACK_CAP = 24;
@@ -79008,7 +79249,7 @@ function mavenGroupIsSelfDisclosing(name2, selfTokens) {
79008
79249
  function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
79009
79250
  const read2 = (p) => {
79010
79251
  try {
79011
- return readFileSync22(p, "utf8");
79252
+ return readFileSync23(p, "utf8");
79012
79253
  } catch {
79013
79254
  return null;
79014
79255
  }
@@ -79234,7 +79475,7 @@ function readDirectDependencies(root) {
79234
79475
  for (const c of LOCKFILES) {
79235
79476
  if (familiesSeen.has(c.family)) continue;
79236
79477
  const p = join26(root, c.file);
79237
- if (!existsSync22(p)) continue;
79478
+ if (!existsSync23(p)) continue;
79238
79479
  try {
79239
79480
  const s = statSync7(p);
79240
79481
  stamps.push(`${c.file}:${s.mtimeMs}:${s.size}`);
@@ -79254,7 +79495,7 @@ function readDirectDependencies(root) {
79254
79495
  const direct = [];
79255
79496
  for (const { c, path: path2 } of found) {
79256
79497
  try {
79257
- direct.push(...c.parse(readFileSync22(path2, "utf8")).direct ?? []);
79498
+ direct.push(...c.parse(readFileSync23(path2, "utf8")).direct ?? []);
79258
79499
  } catch {
79259
79500
  }
79260
79501
  }
@@ -79297,14 +79538,14 @@ function manifestPaths(root) {
79297
79538
  "project.godot"
79298
79539
  ];
79299
79540
  return {
79300
- paths: ROOT_MANIFESTS.filter((f) => existsSync22(join26(root, f))),
79541
+ paths: ROOT_MANIFESTS.filter((f) => existsSync23(join26(root, f))),
79301
79542
  tracked: false,
79302
79543
  truncated: false
79303
79544
  };
79304
79545
  }
79305
79546
  var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
79306
79547
  function rootDeclaresWorkspace(root, texts) {
79307
- if (WORKSPACE_MARKERS.some((f) => existsSync22(join26(root, f)))) return true;
79548
+ if (WORKSPACE_MARKERS.some((f) => existsSync23(join26(root, f)))) return true;
79308
79549
  return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
79309
79550
  }
79310
79551
  var EMPTY_SCAN = { deps: [], self: [], complete: true };
@@ -79322,7 +79563,7 @@ function scanManifests(root) {
79322
79563
  try {
79323
79564
  const s = statSync7(abs);
79324
79565
  stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
79325
- texts.set(rel, readFileSync22(abs, "utf8"));
79566
+ texts.set(rel, readFileSync23(abs, "utf8"));
79326
79567
  } catch {
79327
79568
  }
79328
79569
  }
@@ -79358,11 +79599,11 @@ function readRetrievalInputs(root, repoLocator) {
79358
79599
  }
79359
79600
 
79360
79601
  // src/git-sensor.ts
79361
- import { existsSync as existsSync23, readFileSync as readFileSync23, watch as fsWatch } from "node:fs";
79602
+ import { existsSync as existsSync24, readFileSync as readFileSync24, watch as fsWatch } from "node:fs";
79362
79603
  import { join as join27 } from "node:path";
79363
79604
  function readFirstLine(path2) {
79364
79605
  try {
79365
- return readFileSync23(path2, "utf8").split(/\r?\n/, 1)[0].trim();
79606
+ return readFileSync24(path2, "utf8").split(/\r?\n/, 1)[0].trim();
79366
79607
  } catch {
79367
79608
  return null;
79368
79609
  }
@@ -79381,13 +79622,13 @@ function readGitRefState(gitDir) {
79381
79622
  return {
79382
79623
  branch,
79383
79624
  sha: sha2,
79384
- mergeHeadExists: existsSync23(join27(gitDir, "MERGE_HEAD")),
79385
- origHeadExists: existsSync23(join27(gitDir, "ORIG_HEAD"))
79625
+ mergeHeadExists: existsSync24(join27(gitDir, "MERGE_HEAD")),
79626
+ origHeadExists: existsSync24(join27(gitDir, "ORIG_HEAD"))
79386
79627
  };
79387
79628
  }
79388
79629
  function shaFromPackedRefs(gitDir, ref) {
79389
79630
  try {
79390
- for (const line of readFileSync23(join27(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
79631
+ for (const line of readFileSync24(join27(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
79391
79632
  const [sha2, name2] = line.split(/\s+/);
79392
79633
  if (name2 === ref && sha2) return sha2;
79393
79634
  }
@@ -79421,7 +79662,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
79421
79662
  const settle = () => {
79422
79663
  if (timer) clearTimeout(timer);
79423
79664
  timer = setTimeout(() => {
79424
- if (existsSync23(join27(gitDir, "index.lock"))) {
79665
+ if (existsSync24(join27(gitDir, "index.lock"))) {
79425
79666
  settle();
79426
79667
  return;
79427
79668
  }
@@ -79452,7 +79693,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
79452
79693
  // src/git-delta.ts
79453
79694
  import { execFile } from "node:child_process";
79454
79695
  function git(repoDir, args2) {
79455
- return new Promise((resolve8, reject) => {
79696
+ return new Promise((resolve9, reject) => {
79456
79697
  execFile(
79457
79698
  "git",
79458
79699
  ["-C", repoDir, ...args2],
@@ -79463,7 +79704,7 @@ function git(repoDir, args2) {
79463
79704
  // git-sensor runs on every commit/checkout.
79464
79705
  windowsHide: true
79465
79706
  },
79466
- (err2, stdout) => err2 ? reject(err2) : resolve8(stdout)
79707
+ (err2, stdout) => err2 ? reject(err2) : resolve9(stdout)
79467
79708
  );
79468
79709
  });
79469
79710
  }
@@ -79656,7 +79897,7 @@ var TelemetryRecorder = class {
79656
79897
  };
79657
79898
 
79658
79899
  // src/file-activity.ts
79659
- import { readFileSync as readFileSync25 } from "node:fs";
79900
+ import { readFileSync as readFileSync26 } from "node:fs";
79660
79901
  import { join as join29 } from "node:path";
79661
79902
  import { createHash as createHash17 } from "node:crypto";
79662
79903
 
@@ -80409,7 +80650,7 @@ init_git_remote();
80409
80650
  // src/history-bundle.ts
80410
80651
  init_src();
80411
80652
  import { execFile as execFile2 } from "node:child_process";
80412
- import { readFileSync as readFileSync24 } from "node:fs";
80653
+ import { readFileSync as readFileSync25 } from "node:fs";
80413
80654
  import { join as join28 } from "node:path";
80414
80655
  var DEFAULT_MAX_TOKENS = 6e3;
80415
80656
  var FILE_LIST_CAP = 60;
@@ -80445,7 +80686,7 @@ function pathAllowedByFloor(path2) {
80445
80686
  function loadRepoIgnore(root, extraPatterns = []) {
80446
80687
  let source = "";
80447
80688
  try {
80448
- source = readFileSync24(join28(root, ".errataignore"), "utf8");
80689
+ source = readFileSync25(join28(root, ".errataignore"), "utf8");
80449
80690
  } catch {
80450
80691
  source = "";
80451
80692
  }
@@ -80621,12 +80862,12 @@ function headerPaths(diff) {
80621
80862
  return out2.filter((p) => p !== "/dev/null");
80622
80863
  }
80623
80864
  function git2(repoDir, args2) {
80624
- return new Promise((resolve8, reject) => {
80865
+ return new Promise((resolve9, reject) => {
80625
80866
  execFile2(
80626
80867
  "git",
80627
80868
  ["-C", repoDir, ...args2],
80628
80869
  { encoding: "utf8", maxBuffer: 64 * 1024 * 1024, windowsHide: true },
80629
- (err2, stdout) => err2 ? reject(err2) : resolve8(stdout)
80870
+ (err2, stdout) => err2 ? reject(err2) : resolve9(stdout)
80630
80871
  );
80631
80872
  });
80632
80873
  }
@@ -80738,7 +80979,7 @@ function readActivityBranch(root) {
80738
80979
  try {
80739
80980
  const gitDir = resolveGitDir(root);
80740
80981
  if (!gitDir) return null;
80741
- const head2 = readFileSync25(join29(gitDir, "HEAD"), "utf8").trim();
80982
+ const head2 = readFileSync26(join29(gitDir, "HEAD"), "utf8").trim();
80742
80983
  const branch = head2.startsWith("ref: refs/heads/") ? head2.slice(16) : /^[a-f0-9]{40,64}$/i.test(head2) ? "HEAD" : null;
80743
80984
  return branch && branch.length <= 256 && !/[\x00-\x1f\x7f]/.test(branch) ? branch : null;
80744
80985
  } catch {
@@ -80895,21 +81136,21 @@ var FileActivityReporter = class {
80895
81136
 
80896
81137
  // src/skills.ts
80897
81138
  import {
80898
- existsSync as existsSync24,
81139
+ existsSync as existsSync25,
80899
81140
  mkdirSync as mkdirSync7,
80900
- readFileSync as readFileSync26,
81141
+ readFileSync as readFileSync27,
80901
81142
  readdirSync as readdirSync8,
80902
81143
  unlinkSync as unlinkSync4,
80903
- writeFileSync as writeFileSync17
81144
+ writeFileSync as writeFileSync18
80904
81145
  } from "node:fs";
80905
81146
  import { basename as basename6, join as join30 } from "node:path";
80906
81147
  function skillFileName(id) {
80907
81148
  return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
80908
81149
  }
80909
81150
  function readSkillManifest(manifestPath) {
80910
- if (!existsSync24(manifestPath)) return [];
81151
+ if (!existsSync25(manifestPath)) return [];
80911
81152
  try {
80912
- const parsed = JSON.parse(readFileSync26(manifestPath, "utf8"));
81153
+ const parsed = JSON.parse(readFileSync27(manifestPath, "utf8"));
80913
81154
  return (parsed.skills ?? []).map((s) => ({
80914
81155
  title: s.title ?? "",
80915
81156
  layer: s.layer ?? "technique",
@@ -80933,7 +81174,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
80933
81174
  for (const s of res.skills) {
80934
81175
  const fileName = skillFileName(s.id);
80935
81176
  keep.add(fileName);
80936
- writeFileSync17(join30(paths.skillsDir, fileName), s.markdown, "utf8");
81177
+ writeFileSync18(join30(paths.skillsDir, fileName), s.markdown, "utf8");
80937
81178
  rows.push({
80938
81179
  id: s.id,
80939
81180
  title: s.title,
@@ -80946,7 +81187,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
80946
81187
  const fileName = skillFileName(p.id);
80947
81188
  if (keep.has(fileName)) continue;
80948
81189
  keep.add(fileName);
80949
- writeFileSync17(join30(paths.skillsDir, fileName), p.markdown, "utf8");
81190
+ writeFileSync18(join30(paths.skillsDir, fileName), p.markdown, "utf8");
80950
81191
  rows.push({
80951
81192
  id: p.id,
80952
81193
  title: p.title,
@@ -80966,7 +81207,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
80966
81207
  }
80967
81208
  }
80968
81209
  rows.sort((a, b) => a.id.localeCompare(b.id));
80969
- writeFileSync17(
81210
+ writeFileSync18(
80970
81211
  paths.skillsManifest,
80971
81212
  JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
80972
81213
  "utf8"
@@ -80978,14 +81219,14 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
80978
81219
  init_src2();
80979
81220
  import {
80980
81221
  cpSync,
80981
- existsSync as existsSync25,
81222
+ existsSync as existsSync26,
80982
81223
  lstatSync,
80983
81224
  mkdirSync as mkdirSync8,
80984
- readFileSync as readFileSync27,
81225
+ readFileSync as readFileSync28,
80985
81226
  readdirSync as readdirSync9,
80986
81227
  rmSync as rmSync3,
80987
81228
  symlinkSync,
80988
- writeFileSync as writeFileSync18
81229
+ writeFileSync as writeFileSync19
80989
81230
  } from "node:fs";
80990
81231
  import { join as join31 } from "node:path";
80991
81232
  var SKILL_NS = "errata-";
@@ -81038,7 +81279,7 @@ function skillCiteHandle(s) {
81038
81279
  return priorHandle({ id: s.id, description: s.title });
81039
81280
  }
81040
81281
  function reconcileNamespaced(dir, keep) {
81041
- if (!existsSync25(dir)) return 0;
81282
+ if (!existsSync26(dir)) return 0;
81042
81283
  let pruned = 0;
81043
81284
  for (const name2 of readdirSync9(dir)) {
81044
81285
  if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
@@ -81052,7 +81293,7 @@ function reconcileNamespaced(dir, keep) {
81052
81293
  }
81053
81294
  function linkOrCopy(linkPath, target) {
81054
81295
  try {
81055
- if (existsSync25(linkPath) || safeLstat(linkPath)) rmSync3(linkPath, { recursive: true, force: true });
81296
+ if (existsSync26(linkPath) || safeLstat(linkPath)) rmSync3(linkPath, { recursive: true, force: true });
81056
81297
  } catch {
81057
81298
  }
81058
81299
  try {
@@ -81081,7 +81322,7 @@ function emitAndProjectSkills(root, skills) {
81081
81322
  for (const s of skills) {
81082
81323
  let body2;
81083
81324
  try {
81084
- body2 = readFileSync27(s.bodyPath, "utf8");
81325
+ body2 = readFileSync28(s.bodyPath, "utf8");
81085
81326
  } catch {
81086
81327
  continue;
81087
81328
  }
@@ -81091,7 +81332,7 @@ function emitAndProjectSkills(root, skills) {
81091
81332
  slugs.push(slug2);
81092
81333
  const description = deriveDescription(s.title, s.layer, body2);
81093
81334
  mkdirSync8(join31(agentsSkillsDir, slug2), { recursive: true });
81094
- writeFileSync18(
81335
+ writeFileSync19(
81095
81336
  join31(agentsSkillsDir, slug2, "SKILL.md"),
81096
81337
  renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
81097
81338
  "utf8"
@@ -81101,7 +81342,7 @@ function emitAndProjectSkills(root, skills) {
81101
81342
  reconcileNamespaced(agentsSkillsDir, keep);
81102
81343
  let projected = 0;
81103
81344
  for (const h of HARNESS_SKILL_DIRS) {
81104
- if (!existsSync25(join31(root, h.configDir))) continue;
81345
+ if (!existsSync26(join31(root, h.configDir))) continue;
81105
81346
  const dir = join31(root, h.skillsDir);
81106
81347
  mkdirSync8(dir, { recursive: true });
81107
81348
  for (const slug2 of slugs) {
@@ -81114,9 +81355,9 @@ function emitAndProjectSkills(root, skills) {
81114
81355
  return { slugs, emitted, projected };
81115
81356
  }
81116
81357
  function emitInputsFromManifest(erretaDir, manifestPath) {
81117
- if (!existsSync25(manifestPath)) return [];
81358
+ if (!existsSync26(manifestPath)) return [];
81118
81359
  try {
81119
- const parsed = JSON.parse(readFileSync27(manifestPath, "utf8"));
81360
+ const parsed = JSON.parse(readFileSync28(manifestPath, "utf8"));
81120
81361
  return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
81121
81362
  id: s.id,
81122
81363
  title: s.title ?? s.id,
@@ -81139,14 +81380,14 @@ function ensureSkillGitignore(root) {
81139
81380
  const path2 = join31(root, ".gitignore");
81140
81381
  let current = "";
81141
81382
  try {
81142
- current = existsSync25(path2) ? readFileSync27(path2, "utf8") : "";
81383
+ current = existsSync26(path2) ? readFileSync28(path2, "utf8") : "";
81143
81384
  } catch {
81144
81385
  return;
81145
81386
  }
81146
81387
  if (current.includes(GITIGNORE_MARK)) return;
81147
81388
  const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
81148
81389
  try {
81149
- writeFileSync18(path2, `${current}${prefix}
81390
+ writeFileSync19(path2, `${current}${prefix}
81150
81391
  ${GITIGNORE_LINES.join("\n")}
81151
81392
  `, "utf8");
81152
81393
  } catch {
@@ -81157,7 +81398,7 @@ ${GITIGNORE_LINES.join("\n")}
81157
81398
  var INTENT_TTL_MS = 15 * 60 * 1e3;
81158
81399
  function createIntentState(ttlMs = INTENT_TTL_MS) {
81159
81400
  const bySession = /* @__PURE__ */ new Map();
81160
- let recent3 = null;
81401
+ let recent4 = null;
81161
81402
  const live3 = (s, nowMs) => s !== void 0 && nowMs - s.atMs < ttlMs;
81162
81403
  return {
81163
81404
  set(sessionId, text, nowMs) {
@@ -81165,8 +81406,8 @@ function createIntentState(ttlMs = INTENT_TTL_MS) {
81165
81406
  if (!trimmed) return false;
81166
81407
  const prev = bySession.get(sessionId);
81167
81408
  bySession.set(sessionId, { text: trimmed, atMs: nowMs });
81168
- const changed = !(recent3 && recent3.text === trimmed);
81169
- recent3 = { sessionId, text: trimmed, atMs: nowMs };
81409
+ const changed = !(recent4 && recent4.text === trimmed);
81410
+ recent4 = { sessionId, text: trimmed, atMs: nowMs };
81170
81411
  if (!changed && prev && prev.text === trimmed) return false;
81171
81412
  return changed;
81172
81413
  },
@@ -81175,12 +81416,12 @@ function createIntentState(ttlMs = INTENT_TTL_MS) {
81175
81416
  return live3(s, nowMs) ? s.text : void 0;
81176
81417
  },
81177
81418
  mostRecent(nowMs) {
81178
- if (!recent3) return void 0;
81179
- return nowMs - recent3.atMs < ttlMs ? recent3.text : void 0;
81419
+ if (!recent4) return void 0;
81420
+ return nowMs - recent4.atMs < ttlMs ? recent4.text : void 0;
81180
81421
  },
81181
81422
  clear(sessionId) {
81182
81423
  bySession.delete(sessionId);
81183
- if (recent3?.sessionId === sessionId) recent3 = null;
81424
+ if (recent4?.sessionId === sessionId) recent4 = null;
81184
81425
  }
81185
81426
  };
81186
81427
  }
@@ -81188,19 +81429,19 @@ function createIntentState(ttlMs = INTENT_TTL_MS) {
81188
81429
  // src/working-file-state.ts
81189
81430
  function createWorkingFileState() {
81190
81431
  const bySession = /* @__PURE__ */ new Map();
81191
- let recent3 = null;
81432
+ let recent4 = null;
81192
81433
  return {
81193
81434
  set(sessionId, rel) {
81194
81435
  bySession.set(sessionId, rel);
81195
- if (rel === recent3) return false;
81196
- recent3 = rel;
81436
+ if (rel === recent4) return false;
81437
+ recent4 = rel;
81197
81438
  return true;
81198
81439
  },
81199
81440
  get(sessionId) {
81200
81441
  return bySession.get(sessionId);
81201
81442
  },
81202
81443
  mostRecent() {
81203
- return recent3;
81444
+ return recent4;
81204
81445
  }
81205
81446
  };
81206
81447
  }
@@ -81242,7 +81483,7 @@ init_paths();
81242
81483
  init_profile2();
81243
81484
 
81244
81485
  // src/witness-queue.ts
81245
- import { readFileSync as readFileSync28, renameSync as renameSync3, writeFileSync as writeFileSync19 } from "node:fs";
81486
+ import { readFileSync as readFileSync29, renameSync as renameSync3, writeFileSync as writeFileSync20 } from "node:fs";
81246
81487
  import { dirname as dirname11, join as join32 } from "node:path";
81247
81488
  var WITNESS_QUEUE_CAP = 500;
81248
81489
  var WITNESS_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
@@ -81253,7 +81494,7 @@ function witnessQueuePath(workspaceConfigDir) {
81253
81494
  function loadWitnessQueueWithLosses(path2) {
81254
81495
  let raw2;
81255
81496
  try {
81256
- raw2 = JSON.parse(readFileSync28(path2, "utf8"));
81497
+ raw2 = JSON.parse(readFileSync29(path2, "utf8"));
81257
81498
  } catch (err2) {
81258
81499
  const absent = err2?.code === "ENOENT";
81259
81500
  return { queue: [], fileUnreadable: !absent, malformedEntries: 0 };
@@ -81267,7 +81508,7 @@ function loadWitnessQueueWithLosses(path2) {
81267
81508
  function saveWitnessQueue(path2, queue) {
81268
81509
  try {
81269
81510
  const tmp = join32(dirname11(path2), `.${Date.now()}.witness-queue.tmp`);
81270
- writeFileSync19(tmp, JSON.stringify(queue), "utf8");
81511
+ writeFileSync20(tmp, JSON.stringify(queue), "utf8");
81271
81512
  renameSync3(tmp, path2);
81272
81513
  } catch {
81273
81514
  }
@@ -81306,11 +81547,11 @@ function pendingFor(queue, channel) {
81306
81547
  }
81307
81548
  function partitionReplayable(queue, channel, isShipped) {
81308
81549
  const replay2 = [];
81309
- const waiting = [];
81550
+ const waiting2 = [];
81310
81551
  for (const w of pendingFor(queue, channel)) {
81311
- (isShipped(w.nodeId) ? replay2 : waiting).push(w);
81552
+ (isShipped(w.nodeId) ? replay2 : waiting2).push(w);
81312
81553
  }
81313
- return { replay: replay2, waiting };
81554
+ return { replay: replay2, waiting: waiting2 };
81314
81555
  }
81315
81556
  function retireWitnesses(queue, channel, settledKeys) {
81316
81557
  return queue.filter((w) => !(w.channel === channel && settledKeys.has(w.witnessKey)));
@@ -81574,31 +81815,31 @@ function maybeFlushDigests() {
81574
81815
 
81575
81816
  // src/liveness-watch.ts
81576
81817
  init_src5();
81577
- import { readFileSync as readFileSync30, writeFileSync as writeFileSync21 } from "node:fs";
81818
+ import { readFileSync as readFileSync31, writeFileSync as writeFileSync22 } from "node:fs";
81578
81819
  import { join as join34 } from "node:path";
81579
81820
 
81580
81821
  // src/loop-lag.ts
81581
81822
  var HEARTBEAT_MS = 500;
81582
81823
  var RECENT_PASS_LIMIT = 12;
81583
- var active = /* @__PURE__ */ new Map();
81824
+ var active2 = /* @__PURE__ */ new Map();
81584
81825
  var nextPassId = 1;
81585
81826
  var started = false;
81586
- var recent2 = [];
81827
+ var recent3 = [];
81587
81828
  function markPass(name2) {
81588
81829
  const id = nextPassId++;
81589
81830
  const startedAt = Date.now();
81590
- active.set(id, { name: name2, startedAt });
81831
+ active2.set(id, { name: name2, startedAt });
81591
81832
  let ended = false;
81592
81833
  return () => {
81593
81834
  if (ended) return;
81594
81835
  ended = true;
81595
- active.delete(id);
81596
- recent2.unshift({ name: name2, ms: Date.now() - startedAt, endedAt: Date.now() });
81597
- if (recent2.length > RECENT_PASS_LIMIT) recent2.pop();
81836
+ active2.delete(id);
81837
+ recent3.unshift({ name: name2, ms: Date.now() - startedAt, endedAt: Date.now() });
81838
+ if (recent3.length > RECENT_PASS_LIMIT) recent3.pop();
81598
81839
  };
81599
81840
  }
81600
81841
  function oldestActive() {
81601
- for (const p of active.values()) return p;
81842
+ for (const p of active2.values()) return p;
81602
81843
  return null;
81603
81844
  }
81604
81845
  function passState() {
@@ -81607,8 +81848,8 @@ function passState() {
81607
81848
  return {
81608
81849
  current: oldest?.name ?? "idle",
81609
81850
  runningMs: oldest === null ? null : now - oldest.startedAt,
81610
- active: [...active.values()].map((p) => ({ name: p.name, runningMs: now - p.startedAt })),
81611
- recent: [...recent2]
81851
+ active: [...active2.values()].map((p) => ({ name: p.name, runningMs: now - p.startedAt })),
81852
+ recent: [...recent3]
81612
81853
  };
81613
81854
  }
81614
81855
  function describeHolders(running, finished, windowStart, now) {
@@ -81627,7 +81868,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
81627
81868
  const now = Date.now();
81628
81869
  const lag = now - last - HEARTBEAT_MS;
81629
81870
  if (lag > thresholdMs) {
81630
- const who = describeHolders(active.values(), recent2, last, now);
81871
+ const who = describeHolders(active2.values(), recent3, last, now);
81631
81872
  console.warn(
81632
81873
  `[loop-lag] ${(/* @__PURE__ */ new Date()).toISOString()} event loop held ~${(lag / 1e3).toFixed(1)}s during "${who}"`
81633
81874
  );
@@ -81710,7 +81951,7 @@ function alarmStatePath(configDir) {
81710
81951
  }
81711
81952
  function loadAlarmState(configDir) {
81712
81953
  try {
81713
- const raw2 = JSON.parse(readFileSync30(alarmStatePath(configDir), "utf8"));
81954
+ const raw2 = JSON.parse(readFileSync31(alarmStatePath(configDir), "utf8"));
81714
81955
  return new Map(Object.entries(raw2).filter((e) => typeof e[1] === "number"));
81715
81956
  } catch {
81716
81957
  return /* @__PURE__ */ new Map();
@@ -81718,7 +81959,7 @@ function loadAlarmState(configDir) {
81718
81959
  }
81719
81960
  function saveAlarmState(configDir, state) {
81720
81961
  try {
81721
- writeFileSync21(alarmStatePath(configDir), JSON.stringify(Object.fromEntries(state)));
81962
+ writeFileSync22(alarmStatePath(configDir), JSON.stringify(Object.fromEntries(state)));
81722
81963
  } catch {
81723
81964
  }
81724
81965
  }
@@ -81918,7 +82159,7 @@ function createWatchBreaker(deps) {
81918
82159
  }
81919
82160
 
81920
82161
  // src/engine.ts
81921
- var DAEMON_VERSION = true ? "2.0.17-dev.3421" : "2.0.0-alpha.0";
82162
+ var DAEMON_VERSION = true ? "2.0.17-dev.3433" : "2.0.0-alpha.0";
81922
82163
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
81923
82164
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
81924
82165
  var GIT_OP_MUTE_MS = 4e3;
@@ -81930,7 +82171,7 @@ var CODEX_SWEEP_LOOKBACK_MS = 10 * 6e4;
81930
82171
  function appendIdentityAudit(path2, record2, line) {
81931
82172
  if (!record2.accepted && record2.score <= 0) return;
81932
82173
  try {
81933
- if (existsSync27(path2) && statSync8(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
82174
+ if (existsSync28(path2) && statSync8(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
81934
82175
  renameSync4(path2, `${path2}.1`);
81935
82176
  }
81936
82177
  appendFileSync4(path2, line);
@@ -81940,7 +82181,7 @@ function appendIdentityAudit(path2, record2, line) {
81940
82181
  var yieldToLoop = () => new Promise((r) => setImmediate(r));
81941
82182
  function loadTurnCursors(path2) {
81942
82183
  try {
81943
- const raw2 = JSON.parse(readFileSync31(path2, "utf8"));
82184
+ const raw2 = JSON.parse(readFileSync32(path2, "utf8"));
81944
82185
  return new Map(
81945
82186
  Object.entries(raw2).map(([k, v]) => [k, typeof v === "string" ? v : String(v?.uuid ?? "")])
81946
82187
  );
@@ -81950,7 +82191,7 @@ function loadTurnCursors(path2) {
81950
82191
  }
81951
82192
  function loadTurnOffsets(path2) {
81952
82193
  try {
81953
- const raw2 = JSON.parse(readFileSync31(path2, "utf8"));
82194
+ const raw2 = JSON.parse(readFileSync32(path2, "utf8"));
81954
82195
  const out2 = /* @__PURE__ */ new Map();
81955
82196
  for (const [k, v] of Object.entries(raw2)) {
81956
82197
  const off = typeof v === "object" && v !== null ? v.offset : void 0;
@@ -81966,7 +82207,7 @@ function saveTurnCursors(path2, cursors, offsets) {
81966
82207
  const merged = {};
81967
82208
  for (const [k, uuid3] of cursors) merged[k] = { uuid: uuid3, offset: offsets.get(k) ?? 0 };
81968
82209
  for (const [k, offset] of offsets) if (!merged[k]) merged[k] = { uuid: "", offset };
81969
- writeFileSync22(path2, JSON.stringify(merged), "utf8");
82210
+ writeFileSync23(path2, JSON.stringify(merged), "utf8");
81970
82211
  } catch {
81971
82212
  }
81972
82213
  }
@@ -82255,7 +82496,7 @@ function createWorkspaceEngine(opts) {
82255
82496
  );
82256
82497
  };
82257
82498
  const gitDir = join35(opts.workspaceRoot, ".git");
82258
- if (existsSync27(gitDir)) {
82499
+ if (existsSync28(gitDir)) {
82259
82500
  stopGit = startGitSensor(gitDir, (ev) => {
82260
82501
  void handleGitEvent(ev).catch((err2) => {
82261
82502
  console.warn("[errata] git event handler failed:", err2);
@@ -82320,6 +82561,9 @@ function createWorkspaceEngine(opts) {
82320
82561
  let subagentBase = null;
82321
82562
  let subagentBaseVersion = 0;
82322
82563
  const subagentRenders = /* @__PURE__ */ new Map();
82564
+ const sessions = createSessionRegistry({ originsPath: join35(paths.configDir, "session-origins.json") });
82565
+ const sessionRenders = /* @__PURE__ */ new Map();
82566
+ const selfCiteSkipsBySession = /* @__PURE__ */ new Map();
82323
82567
  const toolRuns = createToolRunState();
82324
82568
  let ctxRefreshTimer = null;
82325
82569
  let contextDirty = false;
@@ -82375,6 +82619,22 @@ function createWorkspaceEngine(opts) {
82375
82619
  return [];
82376
82620
  }
82377
82621
  };
82622
+ const statedIntentFor = (intent) => {
82623
+ const collective = intentRemote?.forIntent === intent ? intentRemote : null;
82624
+ return {
82625
+ text: intent,
82626
+ hits: searchByIntent(store, intent, { limit: 4 }).map((h) => ({
82627
+ id: h.node.id,
82628
+ label: h.node.label,
82629
+ description: h.node.description,
82630
+ coverage: h.coverage
82631
+ })),
82632
+ ...collective && collective.hits.length > 0 ? {
82633
+ remoteHits: collective.hits.slice(0, 4).map((n) => ({ id: n.id, label: n.label, description: n.description }))
82634
+ } : {},
82635
+ ...collective?.voidSignal ? { knownGap: collective.voidSignal } : {}
82636
+ };
82637
+ };
82378
82638
  const refreshContextOnce = async () => {
82379
82639
  const elicit = isEdgeElicitationEnabled();
82380
82640
  const snapOpts = {
@@ -82397,47 +82657,29 @@ function createWorkspaceEngine(opts) {
82397
82657
  contextDirty = true;
82398
82658
  return;
82399
82659
  }
82400
- const baseForSubagents = prebuilt ? structuredClone(prebuilt) : null;
82401
82660
  const doneRender = markPass(`${prebuilt ? "context-render" : "context-render-inline"}:${profile.name}`);
82661
+ const base = prebuilt ?? buildSnapshot({ store, ...snapOpts });
82662
+ subagentBase = structuredClone(base);
82663
+ subagentBaseVersion++;
82664
+ const sharedSnapshot = scopeSnapshot(base, (n) => !isQuarantined(n, sessions));
82402
82665
  const pendingUpdate = opts.pendingUpdate?.() ?? null;
82403
82666
  const daemonDistress = opts.daemonDistress?.() ?? null;
82404
82667
  const reviewItems = pickReviewItems();
82405
82668
  const liveIntent = intents.mostRecent(Date.now());
82406
82669
  maybeRefreshIntentPriors(liveIntent ?? null);
82407
- const intentHits = liveIntent ? searchByIntent(store, liveIntent, { limit: 4 }).map((h) => ({
82408
- id: h.node.id,
82409
- label: h.node.label,
82410
- description: h.node.description,
82411
- coverage: h.coverage
82412
- })) : [];
82413
- const intentCollective = liveIntent && intentRemote?.forIntent === liveIntent ? intentRemote : null;
82670
+ const statedIntent = liveIntent ? statedIntentFor(liveIntent) : null;
82414
82671
  const { body: body2, snapshot, ledger } = assembleAgentContext({
82415
82672
  store,
82416
82673
  ...snapOpts,
82417
82674
  remote: remotePriors,
82418
82675
  ...elicit ? { edgeElicitation: { instruction: PRIOR_TAG_INSTRUCTION } } : {},
82419
- ...prebuilt ? { snapshot: prebuilt } : {},
82676
+ snapshot: sharedSnapshot,
82420
82677
  ...pendingUpdate ? { pendingUpdate } : {},
82421
82678
  ...daemonDistress ? { daemonDistress } : {},
82422
82679
  ...reviewItems.length ? { reviewItems } : {},
82423
- ...liveIntent ? {
82424
- statedIntent: {
82425
- text: liveIntent,
82426
- hits: intentHits,
82427
- ...intentCollective && intentCollective.hits.length > 0 ? {
82428
- remoteHits: intentCollective.hits.slice(0, 4).map((n) => ({
82429
- id: n.id,
82430
- label: n.label,
82431
- description: n.description
82432
- }))
82433
- } : {},
82434
- ...intentCollective?.voidSignal ? { knownGap: intentCollective.voidSignal } : {}
82435
- }
82436
- } : {}
82680
+ ...statedIntent ? { statedIntent } : {}
82437
82681
  });
82438
82682
  doneRender();
82439
- subagentBase = baseForSubagents ?? structuredClone(snapshot);
82440
- subagentBaseVersion++;
82441
82683
  try {
82442
82684
  const seq = store.currentIngestSeq();
82443
82685
  const stamped = recordRenderLedger(store, ledger, seq, Date.now());
@@ -82797,6 +83039,83 @@ function createWorkspaceEngine(opts) {
82797
83039
  subagents.stop(agentId);
82798
83040
  subagentRenders.delete(agentId);
82799
83041
  };
83042
+ const noteSession = (e) => {
83043
+ const now = Date.now();
83044
+ if (!e.sessionId) return;
83045
+ const origin = e.origin ? { origin: e.origin } : {};
83046
+ if (e.agentId) {
83047
+ const sub = `agent-${e.agentId}`;
83048
+ if (e.ended) sessions.end(sub);
83049
+ else sessions.touch(sub, now, { parent: e.sessionId, ...origin });
83050
+ sessions.touch(e.sessionId, now, origin);
83051
+ return;
83052
+ }
83053
+ if (e.ended) sessions.end(e.sessionId);
83054
+ else sessions.touch(e.sessionId, now, origin);
83055
+ };
83056
+ const sessionContext = (sessionId) => {
83057
+ if (!sessionId || !subagentBase) return null;
83058
+ const now = Date.now();
83059
+ const intent = intents.get(sessionId, now);
83060
+ const workingFile = workingFiles.get(sessionId);
83061
+ const skips = selfCiteSkipsBySession.get(sessionId) ?? 0;
83062
+ const key = JSON.stringify([
83063
+ subagentBaseVersion,
83064
+ lastRemoteAt,
83065
+ sessions.version(now),
83066
+ intent,
83067
+ workingFile,
83068
+ intentRemote?.forIntent === intent ? intentRemote?.hits.length : -1,
83069
+ skips
83070
+ ]);
83071
+ const cached2 = sessionRenders.get(sessionId);
83072
+ if (cached2?.key === key) return cached2.block;
83073
+ const elicit = isEdgeElicitationEnabled();
83074
+ const atCommit = readGitRefState(join35(opts.workspaceRoot, ".git")).sha ?? void 0;
83075
+ const scoped = scopeSnapshot(structuredClone(subagentBase), (n) => !hiddenFrom(n, sessionId, sessions, now));
83076
+ delete scoped.workingFile;
83077
+ if (workingFile) {
83078
+ const slice = sliceForFile(store, workingFile, atCommit);
83079
+ if (slice) scoped.workingFile = slice;
83080
+ }
83081
+ delete scoped.selfCiteSkips;
83082
+ if (skips > 0) scoped.selfCiteSkips = skips;
83083
+ const pendingUpdate = opts.pendingUpdate?.() ?? null;
83084
+ const daemonDistress = opts.daemonDistress?.() ?? null;
83085
+ const reviewItems = pickReviewItems();
83086
+ const { body: body2, snapshot } = assembleAgentContext({
83087
+ store,
83088
+ profile,
83089
+ ...atCommit ? { atCommit } : {},
83090
+ reviewCount: pendingCount(paths),
83091
+ reviewUiUrl: opts.reviewUrl(),
83092
+ remote: remotePriors,
83093
+ snapshot: scoped,
83094
+ ...elicit ? { edgeElicitation: { instruction: PRIOR_TAG_INSTRUCTION } } : {},
83095
+ ...pendingUpdate ? { pendingUpdate } : {},
83096
+ ...daemonDistress ? { daemonDistress } : {},
83097
+ ...reviewItems.length ? { reviewItems } : {},
83098
+ ...intent ? { statedIntent: statedIntentFor(intent) } : {}
83099
+ });
83100
+ const block = {
83101
+ body: body2,
83102
+ hash: contextHash(body2),
83103
+ card: contextCard(store, snapshot),
83104
+ handleNodes: [
83105
+ ...snapshot.recentProblems.map((r) => r.node),
83106
+ ...snapshot.recentResolved.flatMap((r) => r.solution ? [r.node, r.solution] : [r.node]),
83107
+ ...snapshot.motifs,
83108
+ ...snapshot.remote ?? []
83109
+ ]
83110
+ };
83111
+ if (elicit && block.handleNodes.length) {
83112
+ writePrimingHandles(join35(paths.configDir, "priming-handles.json"), block.handleNodes);
83113
+ }
83114
+ sessionRenders.delete(sessionId);
83115
+ sessionRenders.set(sessionId, { key, block });
83116
+ if (sessionRenders.size > 200) sessionRenders.delete(sessionRenders.keys().next().value);
83117
+ return block;
83118
+ };
82800
83119
  const onHookEvent = (e) => {
82801
83120
  const intentHints = deriveIntentHints(e.tool, e.oldString, e.newString);
82802
83121
  const operation = /(?:edit|write|patch)/i.test(e.tool) ? "write" : /read/i.test(e.tool) ? "read" : null;
@@ -83116,7 +83435,7 @@ function createWorkspaceEngine(opts) {
83116
83435
  let anchorReadFailed = false;
83117
83436
  if (p.location) {
83118
83437
  try {
83119
- fileText = readFileSync31(join35(opts.workspaceRoot, p.location.path), "utf8");
83438
+ fileText = readFileSync32(join35(opts.workspaceRoot, p.location.path), "utf8");
83120
83439
  } catch {
83121
83440
  anchorReadFailed = true;
83122
83441
  }
@@ -83276,7 +83595,7 @@ function createWorkspaceEngine(opts) {
83276
83595
  const headSha = readGitRefState(join35(opts.workspaceRoot, ".git")).sha ?? void 0;
83277
83596
  enclosing = {
83278
83597
  line: p.location.line,
83279
- fileText: readFileSync31(join35(opts.workspaceRoot, anchorPath), "utf8"),
83598
+ fileText: readFileSync32(join35(opts.workspaceRoot, anchorPath), "utf8"),
83280
83599
  ...headSha ? { headSha } : {}
83281
83600
  };
83282
83601
  } catch {
@@ -83537,6 +83856,12 @@ function createWorkspaceEngine(opts) {
83537
83856
  }
83538
83857
  const citingSession = sessionOriginKey(sessionId);
83539
83858
  const mintedHere = (nodeId) => store.getNode(nodeId)?.attrs["sources"]?.[0] === sessionId;
83859
+ const synthetic = sessions.originOf(sessionId) !== void 0;
83860
+ if (synthetic && plan.corroborations.length + plan.refutes.length > 0) {
83861
+ console.log(
83862
+ `[errata] witnesses: ${plan.corroborations.length + plan.refutes.length} withheld (session ${sessionId.slice(0, 8)} is ${sessions.originOf(sessionId)})`
83863
+ );
83864
+ }
83540
83865
  const sendWitnesses = async (channel, fresh, send) => {
83541
83866
  const isShipped = (nodeId) => {
83542
83867
  const n = store.getNode(nodeId);
@@ -83568,15 +83893,15 @@ function createWorkspaceEngine(opts) {
83568
83893
  }
83569
83894
  witnessQueue = healed;
83570
83895
  fresh = routedFresh;
83571
- const { replay: queued, waiting } = partitionReplayable(witnessQueue, channel, isShipped);
83896
+ const { replay: queued, waiting: waiting2 } = partitionReplayable(witnessQueue, channel, isShipped);
83572
83897
  if (fresh.length === 0 && queued.length === 0) {
83573
83898
  if (undeliverable > 0) {
83574
83899
  saveWitnessQueue(witnessQueuePath(paths.configDir), witnessQueue);
83575
83900
  appendWitnessLedger(paths.configDir, { ts: Date.now(), channel, undeliverable, parked: pendingFor(witnessQueue, channel).length });
83576
83901
  console.log(`[errata] ${channel}: ${undeliverable} witness(es) retired \u2014 cited node class never ships (counted, not parked)`);
83577
83902
  }
83578
- if (waiting.length > 0) {
83579
- console.log(`[errata] ${channel}: ${waiting.length} parked awaiting node drain`);
83903
+ if (waiting2.length > 0) {
83904
+ console.log(`[errata] ${channel}: ${waiting2.length} parked awaiting node drain`);
83580
83905
  }
83581
83906
  return;
83582
83907
  }
@@ -83635,7 +83960,7 @@ function createWorkspaceEngine(opts) {
83635
83960
  appendPassLedger(paths.configDir, "witness-queue", 0, {
83636
83961
  recovered,
83637
83962
  replayed: queued.length,
83638
- awaitingDrain: waiting.length,
83963
+ awaitingDrain: waiting2.length,
83639
83964
  parked: pendingFor(witnessQueue, channel).length,
83640
83965
  expiredTtl: enq.dropped.expiredTtl,
83641
83966
  exhaustedAttempts: enq.dropped.exhaustedAttempts,
@@ -83644,7 +83969,7 @@ function createWorkspaceEngine(opts) {
83644
83969
  });
83645
83970
  }
83646
83971
  console.log(
83647
- `[errata] ${channel}: ${formatDisposition({ recorded, unmatched, duplicate, selfGated })}` + (queued.length > 0 ? ` (incl. ${queued.length} replayed)` : "") + (waiting.length > 0 ? ` (${waiting.length} awaiting drain)` : "")
83972
+ `[errata] ${channel}: ${formatDisposition({ recorded, unmatched, duplicate, selfGated })}` + (queued.length > 0 ? ` (incl. ${queued.length} replayed)` : "") + (waiting2.length > 0 ? ` (${waiting2.length} awaiting drain)` : "")
83648
83973
  );
83649
83974
  appendWitnessLedger(paths.configDir, {
83650
83975
  ts: Date.now(),
@@ -83654,14 +83979,14 @@ function createWorkspaceEngine(opts) {
83654
83979
  duplicate,
83655
83980
  selfGated,
83656
83981
  parked: pendingFor(witnessQueue, channel).length,
83657
- awaitingDrain: waiting.length,
83982
+ awaitingDrain: waiting2.length,
83658
83983
  ...undeliverable > 0 ? { undeliverable } : {}
83659
83984
  });
83660
83985
  };
83661
83986
  if (typeof cloud.reportContradictions === "function") {
83662
83987
  await sendWitnesses(
83663
83988
  "contradict",
83664
- wireWitnessItems(plan.refutes),
83989
+ synthetic ? [] : wireWitnessItems(plan.refutes),
83665
83990
  (items2, session) => cloud.reportContradictions({
83666
83991
  daemonVersion: DAEMON_VERSION,
83667
83992
  projectId: profile.id,
@@ -83671,12 +83996,13 @@ function createWorkspaceEngine(opts) {
83671
83996
  );
83672
83997
  }
83673
83998
  if (typeof cloud.reportCorroborations === "function") {
83674
- const emit = plan.corroborations.filter((c) => !mintedHere(c.nodeId));
83999
+ const emit = synthetic ? [] : plan.corroborations.filter((c) => !mintedHere(c.nodeId));
83675
84000
  const skipped = plan.corroborations.length - emit.length;
83676
84001
  if (skipped > 0) {
83677
84002
  console.log(`[errata] corroborate: ${skipped} skipped (this session authored the node)`);
83678
84003
  appendWitnessLedger(paths.configDir, { ts: Date.now(), channel: "corroborate", clientSelfSkipped: skipped });
83679
84004
  lastSelfCiteSkips = skipped;
84005
+ selfCiteSkipsBySession.set(sessionId, skipped);
83680
84006
  refreshContextNow();
83681
84007
  }
83682
84008
  await sendWitnesses(
@@ -83858,7 +84184,7 @@ function createWorkspaceEngine(opts) {
83858
84184
  }
83859
84185
  turns = next.turns;
83860
84186
  nextOffset = next.nextOffset;
83861
- await new Promise((resolve8) => setImmediate(resolve8));
84187
+ await new Promise((resolve9) => setImmediate(resolve9));
83862
84188
  }
83863
84189
  };
83864
84190
  const seenMessageIds = /* @__PURE__ */ new Set();
@@ -84115,6 +84441,8 @@ B: ${b}`,
84115
84441
  onSubagentSpawn,
84116
84442
  subagentContext,
84117
84443
  onSubagentStop,
84444
+ noteSession,
84445
+ sessionContext,
84118
84446
  onHook: () => telemetry.count("hooks_fired"),
84119
84447
  onToolsObserved: (sessionId, toolNodeIds) => toolRuns.record(sessionId, toolNodeIds),
84120
84448
  onHookEvent,
@@ -84132,6 +84460,7 @@ B: ${b}`,
84132
84460
  lastActivityAt() {
84133
84461
  return lastActivityTs;
84134
84462
  },
84463
+ quarantinedSessions: () => sessions.originSessions(),
84135
84464
  markContextDirty() {
84136
84465
  contextDirty = true;
84137
84466
  refreshContextNow();
@@ -84396,15 +84725,19 @@ B: ${b}`,
84396
84725
  console.log(
84397
84726
  "[errata] sync skipped \u2014 cloud sync consent is off (enable with `errata consent sync on`)"
84398
84727
  );
84399
- const pending = existsSync27(paths.outbox) ? readdirSync10(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
84728
+ const pending = existsSync28(paths.outbox) ? readdirSync10(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
84400
84729
  return { uploaded: 0, failed: 0, remaining: pending };
84401
84730
  }
84731
+ if (!shipsFromWorkspace(opts.workspaceRoot)) {
84732
+ console.log("[errata] sync skipped \u2014 scratch workspace (under the OS temp dir); its captures stay local");
84733
+ return { uploaded: 0, failed: 0, remaining: 0 };
84734
+ }
84402
84735
  const onDisk = loadProfile(opts.workspaceRoot);
84403
84736
  if (!onDisk?.projectId && onDisk?.projectLinkHold) {
84404
84737
  console.log(
84405
84738
  "[errata] sync held \u2014 this repo is already on errata in another workspace; run `errata link` to join it or create your own project"
84406
84739
  );
84407
- const pending = existsSync27(paths.outbox) ? readdirSync10(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
84740
+ const pending = existsSync28(paths.outbox) ? readdirSync10(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
84408
84741
  return { uploaded: 0, failed: 0, remaining: pending };
84409
84742
  }
84410
84743
  try {
@@ -84498,7 +84831,7 @@ async function startDaemon(opts) {
84498
84831
  reviewUrl: () => webUiUrl + "/review"
84499
84832
  });
84500
84833
  const writeLockFile = (url2) => {
84501
- writeFileSync23(
84834
+ writeFileSync24(
84502
84835
  engine.paths.daemonLock,
84503
84836
  daemonLockPayload({ pid: process.pid, webUiUrl: url2, processStartedAt, version: DAEMON_VERSION }),
84504
84837
  "utf8"
@@ -84515,6 +84848,8 @@ async function startDaemon(opts) {
84515
84848
  onSubagentSpawn: engine.webHooks.onSubagentSpawn,
84516
84849
  subagentContext: engine.webHooks.subagentContext,
84517
84850
  onSubagentStop: engine.webHooks.onSubagentStop,
84851
+ noteSession: engine.webHooks.noteSession,
84852
+ sessionContext: engine.webHooks.sessionContext,
84518
84853
  onHook: engine.webHooks.onHook,
84519
84854
  onHookEvent: engine.webHooks.onHookEvent,
84520
84855
  onShellEvent: engine.webHooks.onShellEvent,
@@ -84544,7 +84879,7 @@ async function startDaemon(opts) {
84544
84879
  );
84545
84880
  await engine.stop();
84546
84881
  try {
84547
- if (existsSync28(engine.paths.daemonLock)) {
84882
+ if (existsSync29(engine.paths.daemonLock)) {
84548
84883
  }
84549
84884
  } catch {
84550
84885
  }
@@ -84552,9 +84887,9 @@ async function startDaemon(opts) {
84552
84887
  };
84553
84888
  }
84554
84889
  async function listenServer(fetchFn, port) {
84555
- return new Promise((resolve8) => {
84890
+ return new Promise((resolve9) => {
84556
84891
  const server = serve({ fetch: fetchFn, hostname: "127.0.0.1", port }, (info2) => {
84557
- resolve8({ server, port: info2.port });
84892
+ resolve9({ server, port: info2.port });
84558
84893
  });
84559
84894
  });
84560
84895
  }
@@ -84745,7 +85080,7 @@ function instanceReceiptSequence(n) {
84745
85080
  // src/multi.ts
84746
85081
  init_dist();
84747
85082
  init_src5();
84748
- import { existsSync as existsSync33, readFileSync as readFileSync35, unlinkSync as unlinkSync5, writeFileSync as writeFileSync25 } from "node:fs";
85083
+ import { existsSync as existsSync34, readFileSync as readFileSync36, unlinkSync as unlinkSync5, writeFileSync as writeFileSync26 } from "node:fs";
84749
85084
  import { resolve as pathResolve } from "node:path";
84750
85085
 
84751
85086
  // src/principle-sync.ts
@@ -84774,7 +85109,7 @@ init_reconcile();
84774
85109
 
84775
85110
  // src/lockfile-auto.ts
84776
85111
  init_src();
84777
- import { existsSync as existsSync29, readFileSync as readFileSync32 } from "node:fs";
85112
+ import { existsSync as existsSync30, readFileSync as readFileSync33 } from "node:fs";
84778
85113
  import { join as join36 } from "node:path";
84779
85114
 
84780
85115
  // src/package-index.ts
@@ -84925,10 +85260,10 @@ function runLockfilePass(opts) {
84925
85260
  ];
84926
85261
  for (const c of candidates) {
84927
85262
  const p = join36(opts.root, c.file);
84928
- if (!existsSync29(p)) continue;
85263
+ if (!existsSync30(p)) continue;
84929
85264
  let sbom;
84930
85265
  try {
84931
- sbom = c.parse(readFileSync32(p, "utf8"));
85266
+ sbom = c.parse(readFileSync33(p, "utf8"));
84932
85267
  } catch {
84933
85268
  continue;
84934
85269
  }
@@ -84986,9 +85321,10 @@ function noveltyAgainst(node2, neighbors, opts = {}) {
84986
85321
 
84987
85322
  // src/instance-ingest.ts
84988
85323
  init_profile2();
85324
+ init_session_registry();
84989
85325
 
84990
85326
  // src/public-symbols.ts
84991
- import { readFileSync as readFileSync33, readdirSync as readdirSync11, existsSync as existsSync30 } from "node:fs";
85327
+ import { readFileSync as readFileSync34, readdirSync as readdirSync11, existsSync as existsSync31 } from "node:fs";
84992
85328
  import { join as join37 } from "node:path";
84993
85329
  var HEAD_BYTES = 8 * 1024;
84994
85330
  var INDEX_TTL_MS = 10 * 60 * 1e3;
@@ -85023,9 +85359,9 @@ function internalPackageNames(workspaceRoot) {
85023
85359
  const names = /* @__PURE__ */ new Set();
85024
85360
  const tryRead = (dir) => {
85025
85361
  const pj = join37(dir, "package.json");
85026
- if (!existsSync30(pj)) return;
85362
+ if (!existsSync31(pj)) return;
85027
85363
  try {
85028
- const name2 = JSON.parse(readFileSync33(pj, "utf8")).name;
85364
+ const name2 = JSON.parse(readFileSync34(pj, "utf8")).name;
85029
85365
  if (typeof name2 === "string" && name2.length > 0) names.add(name2);
85030
85366
  } catch {
85031
85367
  }
@@ -85033,7 +85369,7 @@ function internalPackageNames(workspaceRoot) {
85033
85369
  tryRead(workspaceRoot);
85034
85370
  for (const group of ["packages", "apps"]) {
85035
85371
  const groupDir = join37(workspaceRoot, group);
85036
- if (!existsSync30(groupDir)) continue;
85372
+ if (!existsSync31(groupDir)) continue;
85037
85373
  try {
85038
85374
  for (const entry of readdirSync11(groupDir)) tryRead(join37(groupDir, entry));
85039
85375
  } catch {
@@ -85054,7 +85390,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
85054
85390
  }
85055
85391
  const readHead = deps.readHead ?? ((absPath) => {
85056
85392
  try {
85057
- return readFileSync33(absPath, "utf8").slice(0, HEAD_BYTES);
85393
+ return readFileSync34(absPath, "utf8").slice(0, HEAD_BYTES);
85058
85394
  } catch {
85059
85395
  return "";
85060
85396
  }
@@ -85211,6 +85547,7 @@ function shareableContext(n, wireId) {
85211
85547
  function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [], opts = {}) {
85212
85548
  const level = opts.level ?? 1;
85213
85549
  const noveltyOpts = opts.dedupCosine != null ? { dedupCosine: opts.dedupCosine } : {};
85550
+ const quarantine = opts.quarantinedSessions?.length ? new Set(opts.quarantinedSessions) : null;
85214
85551
  const ignored = (text) => ignorePatterns.length > 0 && ignorePatterns.some((p) => text.toLowerCase().includes(p));
85215
85552
  const originSessionOf = (n) => {
85216
85553
  const key = sessionOriginKey(n.attrs["sources"]?.[0]);
@@ -85279,6 +85616,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
85279
85616
  candidates: 0,
85280
85617
  shipped: 0,
85281
85618
  cloudSourced: 0,
85619
+ quarantined: 0,
85282
85620
  falsePositive: 0,
85283
85621
  ignored: 0,
85284
85622
  watermarked: 0,
@@ -85294,7 +85632,8 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
85294
85632
  sidecarNoLexicon: 0,
85295
85633
  sidecarNoSummary: 0,
85296
85634
  fileRefsSubstituted: 0,
85297
- fileRefLexiconMisses: 0
85635
+ fileRefLexiconMisses: 0,
85636
+ collapsedEdges: 0
85298
85637
  };
85299
85638
  const sharedCauses = /* @__PURE__ */ new Map();
85300
85639
  const causalQueue = store.findNodesByLabel("Problem").filter(
@@ -85329,6 +85668,10 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
85329
85668
  composition.cloudSourced++;
85330
85669
  continue;
85331
85670
  }
85671
+ if (quarantine && capturedOnlyBy(n, quarantine)) {
85672
+ composition.quarantined++;
85673
+ continue;
85674
+ }
85332
85675
  if (n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) {
85333
85676
  composition.falsePositive++;
85334
85677
  continue;
@@ -85515,7 +85858,13 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
85515
85858
  ];
85516
85859
  const dedup = /* @__PURE__ */ new Map();
85517
85860
  for (const e of rawOuts) dedup.set(`${e.type}>${e.to}`, e);
85518
- const outs = [...dedup.values()].map((e) => ({ e, wireTo: semanticEndpoints.get(e.to) })).filter((x) => x.wireTo != null);
85861
+ const outs = [...dedup.values()].map((e) => ({ e, wireTo: semanticEndpoints.get(e.to) })).filter((x) => {
85862
+ if (x.wireTo === wireFrom) {
85863
+ composition.collapsedEdges++;
85864
+ return false;
85865
+ }
85866
+ return x.wireTo != null;
85867
+ });
85519
85868
  if (outs.length === 0) continue;
85520
85869
  const dg = digest(outs.map(({ e, wireTo }) => `${e.type}>${wireTo}`).sort());
85521
85870
  const owner = nodeOf(sourceId);
@@ -85736,7 +86085,8 @@ function buildDrainInstances(store, sharedStore, input) {
85736
86085
  },
85737
86086
  ...lexicon ? { lexicon } : {},
85738
86087
  ...fileLexicon ? { fileLexicon } : {},
85739
- ...input.project ? { project: input.project } : {}
86088
+ ...input.project ? { project: input.project } : {},
86089
+ ...input.quarantinedSessions?.length ? { quarantinedSessions: input.quarantinedSessions } : {}
85740
86090
  });
85741
86091
  return {
85742
86092
  batch,
@@ -85748,6 +86098,7 @@ function buildDrainInstances(store, sharedStore, input) {
85748
86098
  // src/multi.ts
85749
86099
  init_webui();
85750
86100
  init_recall_card();
86101
+ init_session_registry();
85751
86102
 
85752
86103
  // src/consolidate-worker-client.ts
85753
86104
  import { Worker as Worker2 } from "node:worker_threads";
@@ -85767,8 +86118,8 @@ var ConsolidateWorker = class {
85767
86118
  const id = this.nextId++;
85768
86119
  try {
85769
86120
  await this.ready;
85770
- return await new Promise((resolve8, reject) => {
85771
- this.pending.set(id, { resolve: resolve8, reject });
86121
+ return await new Promise((resolve9, reject) => {
86122
+ this.pending.set(id, { resolve: resolve9, reject });
85772
86123
  this.worker.postMessage({ ...req, id });
85773
86124
  });
85774
86125
  } finally {
@@ -85797,12 +86148,12 @@ var ConsolidateWorker = class {
85797
86148
  });
85798
86149
  noteIsolateSpawned();
85799
86150
  this.worker = worker;
85800
- this.ready = new Promise((resolve8, reject) => {
86151
+ this.ready = new Promise((resolve9, reject) => {
85801
86152
  const onReady = (m) => {
85802
86153
  if (m?.ready) {
85803
86154
  worker.off("message", onReady);
85804
86155
  worker.off("error", onErr);
85805
- resolve8();
86156
+ resolve9();
85806
86157
  }
85807
86158
  };
85808
86159
  const onErr = (err2) => {
@@ -85843,6 +86194,19 @@ var ConsolidateWorker = class {
85843
86194
  }
85844
86195
  };
85845
86196
 
86197
+ // src/prepare-store.ts
86198
+ init_src5();
86199
+ async function prepareStore(path2, root, workspaceId2) {
86200
+ if (!import.meta.url.endsWith(".mjs") || path2 === ":memory:") return;
86201
+ if (!graphStoreNeedsPreparation(path2)) return;
86202
+ const worker = new PassWorker({ castaliaPath: path2, workspaceRoot: root, workspaceId: workspaceId2 });
86203
+ try {
86204
+ await worker.prepareStore();
86205
+ } finally {
86206
+ await worker.stop();
86207
+ }
86208
+ }
86209
+
85846
86210
  // src/multi.ts
85847
86211
  init_paths();
85848
86212
 
@@ -86007,17 +86371,17 @@ function startUpdatePoller(opts) {
86007
86371
  };
86008
86372
  }
86009
86373
  function runNpmInstall(channel) {
86010
- return new Promise((resolve8) => {
86374
+ return new Promise((resolve9) => {
86011
86375
  const child = spawn2("npm", ["install", "-g", `${PACKAGE_NAME}@${channel}`], {
86012
86376
  stdio: "inherit",
86013
86377
  shell: true
86014
86378
  });
86015
- child.on("close", (code) => resolve8(code ?? 1));
86016
- child.on("error", () => resolve8(1));
86379
+ child.on("close", (code) => resolve9(code ?? 1));
86380
+ child.on("error", () => resolve9(1));
86017
86381
  });
86018
86382
  }
86019
86383
  async function runInstalledHookRefresh() {
86020
- const root = await new Promise((resolve8) => {
86384
+ const root = await new Promise((resolve9) => {
86021
86385
  const child = spawn2("npm", ["root", "-g"], {
86022
86386
  shell: true,
86023
86387
  windowsHide: true,
@@ -86029,18 +86393,18 @@ async function runInstalledHookRefresh() {
86029
86393
  output += chunk;
86030
86394
  if (output.length > 32768) child.kill();
86031
86395
  });
86032
- child.on("error", () => resolve8(""));
86033
- child.on("close", (code) => resolve8(code === 0 ? output.trim() : ""));
86396
+ child.on("error", () => resolve9(""));
86397
+ child.on("close", (code) => resolve9(code === 0 ? output.trim() : ""));
86034
86398
  });
86035
86399
  if (!isAbsolute5(root)) return 1;
86036
- return new Promise((resolve8) => {
86400
+ return new Promise((resolve9) => {
86037
86401
  const child = spawn2(process.execPath, [join38(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
86038
86402
  windowsHide: true,
86039
86403
  stdio: "inherit",
86040
86404
  timeout: 3e4
86041
86405
  });
86042
- child.on("error", () => resolve8(1));
86043
- child.on("close", (code) => resolve8(code ?? 1));
86406
+ child.on("error", () => resolve9(1));
86407
+ child.on("close", (code) => resolve9(code ?? 1));
86044
86408
  });
86045
86409
  }
86046
86410
 
@@ -86055,7 +86419,7 @@ function liveCloudClient(src) {
86055
86419
  let current = null;
86056
86420
  let currentKey = "";
86057
86421
  let checkedAt = -Infinity;
86058
- const resolve8 = () => {
86422
+ const resolve9 = () => {
86059
86423
  const t = now();
86060
86424
  if (current && t - checkedAt < recheckMs) return current;
86061
86425
  checkedAt = t;
@@ -86075,7 +86439,7 @@ function liveCloudClient(src) {
86075
86439
  };
86076
86440
  return new Proxy({}, {
86077
86441
  get(_target, prop) {
86078
- const client = resolve8();
86442
+ const client = resolve9();
86079
86443
  const value = Reflect.get(client, prop, client);
86080
86444
  return typeof value === "function" ? value.bind(client) : value;
86081
86445
  }
@@ -86279,11 +86643,11 @@ function cachedMap(cache2, store, key, build) {
86279
86643
  }
86280
86644
  async function lookupLive(store, m, id) {
86281
86645
  const first = (await m.get()).get(id);
86282
- if (first && isLive2(store, first)) return first;
86646
+ if (first && isLive(store, first)) return first;
86283
86647
  const second = (await m.refresh()).get(id);
86284
- return second && isLive2(store, second) ? second : null;
86648
+ return second && isLive(store, second) ? second : null;
86285
86649
  }
86286
- function isLive2(store, id) {
86650
+ function isLive(store, id) {
86287
86651
  const n = store.getNode(id);
86288
86652
  return n !== null && (n.validTo === null || n.validTo === void 0);
86289
86653
  }
@@ -86513,7 +86877,7 @@ async function syncHistoryRevision(opts) {
86513
86877
  changed += result.changed;
86514
86878
  remaining = result.remaining;
86515
86879
  if (!remaining || Date.now() - started2 >= (opts.budgetMs ?? 45e3)) break;
86516
- await new Promise((resolve8) => setImmediate(resolve8));
86880
+ await new Promise((resolve9) => setImmediate(resolve9));
86517
86881
  }
86518
86882
  return { changed, remaining };
86519
86883
  })();
@@ -86616,7 +86980,7 @@ async function syncHistoryRevisionPage(opts) {
86616
86980
  init_src7();
86617
86981
  init_src();
86618
86982
  import { execFile as execFile5 } from "node:child_process";
86619
- import { readFileSync as readFileSync34 } from "node:fs";
86983
+ import { readFileSync as readFileSync35 } from "node:fs";
86620
86984
  import { join as join39 } from "node:path";
86621
86985
  import { promisify as promisify3 } from "node:util";
86622
86986
 
@@ -87017,8 +87381,8 @@ var GitBlobReader = class {
87017
87381
  if (this.failed) return Promise.reject(this.failed);
87018
87382
  if (/[\r\n]/.test(spec)) return Promise.resolve(null);
87019
87383
  const proc = this.start();
87020
- return new Promise((resolve8, reject) => {
87021
- this.queue.push({ resolve: resolve8, reject });
87384
+ return new Promise((resolve9, reject) => {
87385
+ this.queue.push({ resolve: resolve9, reject });
87022
87386
  proc.stdin.write(`${spec}
87023
87387
  `);
87024
87388
  });
@@ -87032,14 +87396,14 @@ var GitBlobReader = class {
87032
87396
  const proc = this.proc;
87033
87397
  this.proc = null;
87034
87398
  if (!proc || proc.exitCode !== null) return Promise.resolve();
87035
- return new Promise((resolve8) => {
87399
+ return new Promise((resolve9) => {
87036
87400
  const timer = setTimeout(() => {
87037
87401
  proc.kill();
87038
- resolve8();
87402
+ resolve9();
87039
87403
  }, timeoutMs);
87040
87404
  proc.once("exit", () => {
87041
87405
  clearTimeout(timer);
87042
- resolve8();
87406
+ resolve9();
87043
87407
  });
87044
87408
  proc.stdin.end();
87045
87409
  });
@@ -87164,7 +87528,7 @@ async function defaultGit(root, args2) {
87164
87528
  function readIgnoreLines(root, profile) {
87165
87529
  let lines = [];
87166
87530
  try {
87167
- lines = readFileSync34(join39(root, ".errataignore"), "utf8").split("\n");
87531
+ lines = readFileSync35(join39(root, ".errataignore"), "utf8").split("\n");
87168
87532
  } catch {
87169
87533
  }
87170
87534
  return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
@@ -87629,7 +87993,7 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
87629
87993
  init_cloud_auth();
87630
87994
  import { createHash as createHash19 } from "node:crypto";
87631
87995
  import { execFileSync as execFileSync6 } from "node:child_process";
87632
- import { existsSync as existsSync31, writeFileSync as writeFileSync24 } from "node:fs";
87996
+ import { existsSync as existsSync32, writeFileSync as writeFileSync25 } from "node:fs";
87633
87997
  import { join as join40 } from "node:path";
87634
87998
 
87635
87999
  // src/device-poll.ts
@@ -87719,7 +88083,7 @@ async function loginOAuthDevice(opts) {
87719
88083
  let deviceSession = null;
87720
88084
  let approvedInstallation = null;
87721
88085
  while (Date.now() < deadline) {
87722
- await (opts.sleep ?? ((ms) => new Promise((resolve8) => setTimeout(resolve8, ms))))(waitMs);
88086
+ await (opts.sleep ?? ((ms) => new Promise((resolve9) => setTimeout(resolve9, ms))))(waitMs);
87723
88087
  waitMs = intervalMs;
87724
88088
  const poll = await fetchDevicePoll(fetchFn, device.token, {
87725
88089
  method: "POST",
@@ -87844,7 +88208,7 @@ async function loginOAuthLoopback(opts) {
87844
88208
  const state = randomState();
87845
88209
  const scope = opts.scope ?? DEFAULT_OAUTH_SCOPE;
87846
88210
  const { code, redirectUri, clientId } = await new Promise(
87847
- (resolve8, reject) => {
88211
+ (resolve9, reject) => {
87848
88212
  const server = createServer((req, res) => {
87849
88213
  const u = new URL(req.url ?? "/", "http://127.0.0.1");
87850
88214
  if (u.pathname !== "/callback") {
@@ -87867,7 +88231,7 @@ async function loginOAuthLoopback(opts) {
87867
88231
  res.writeHead(200, { "content-type": "text/html" });
87868
88232
  res.end("<html><body>inErrata: you're logged in. You can close this tab.</body></html>");
87869
88233
  server.close();
87870
- resolve8({ code: code2, redirectUri: `http://127.0.0.1:${port}/callback`, clientId: activeClientId });
88234
+ resolve9({ code: code2, redirectUri: `http://127.0.0.1:${port}/callback`, clientId: activeClientId });
87871
88235
  });
87872
88236
  let activeClientId = oauthClientId();
87873
88237
  server.on("error", reject);
@@ -87966,7 +88330,7 @@ async function linkThroughConsole(opts) {
87966
88330
  const deadline = Date.now() + Math.min(code.expires_in * 1e3, opts.timeoutMs ?? Number.POSITIVE_INFINITY);
87967
88331
  let intervalMs = Math.max(2, code.interval ?? 5) * 1e3;
87968
88332
  let waitMs = intervalMs;
87969
- const sleep = opts.sleep ?? ((ms) => new Promise((resolve8) => setTimeout(resolve8, ms)));
88333
+ const sleep = opts.sleep ?? ((ms) => new Promise((resolve9) => setTimeout(resolve9, ms)));
87970
88334
  while (Date.now() < deadline) {
87971
88335
  await sleep(waitMs);
87972
88336
  waitMs = intervalMs;
@@ -88089,8 +88453,8 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
88089
88453
  let wroteIgnore = false;
88090
88454
  if (decision.writeIgnoreStarter !== false) {
88091
88455
  const target = join40(root, ".errataignore");
88092
- if (!existsSync31(target)) {
88093
- writeFileSync24(target, IGNORE_STARTER, "utf8");
88456
+ if (!existsSync32(target)) {
88457
+ writeFileSync25(target, IGNORE_STARTER, "utf8");
88094
88458
  wroteIgnore = true;
88095
88459
  }
88096
88460
  }
@@ -88103,12 +88467,12 @@ init_registry();
88103
88467
 
88104
88468
  // src/adopt.ts
88105
88469
  init_git_remote();
88106
- import { existsSync as existsSync32 } from "node:fs";
88470
+ import { existsSync as existsSync33 } from "node:fs";
88107
88471
  import { dirname as dirname12, join as join41 } from "node:path";
88108
88472
  function findGitRoot(absPath) {
88109
88473
  let dir = absPath;
88110
88474
  for (let depth = 0; depth < 64; depth++) {
88111
- if (existsSync32(join41(dir, ".git"))) return dir;
88475
+ if (existsSync33(join41(dir, ".git"))) return dir;
88112
88476
  const parent = dirname12(dir);
88113
88477
  if (parent === dir) return null;
88114
88478
  dir = parent;
@@ -88534,6 +88898,7 @@ async function startMultiDaemon(opts = {}) {
88534
88898
  };
88535
88899
  const sharedDbPath = sharedStorePath();
88536
88900
  ensureParent(sharedDbPath);
88901
+ await prepareStore(sharedDbPath, process.cwd(), "shared");
88537
88902
  const sharedStore = openGraphStore({ path: sharedDbPath });
88538
88903
  const bundledRun = import.meta.url.endsWith(".mjs");
88539
88904
  const consolidateWorker = bundledRun && sharedDbPath !== ":memory:" ? new ConsolidateWorker() : null;
@@ -88692,8 +89057,13 @@ async function startMultiDaemon(opts = {}) {
88692
89057
  }
88693
89058
  }
88694
89059
  };
88695
- const buildRecord = (entry) => {
89060
+ let stopping = false;
89061
+ const buildRecord = async (entry) => {
88696
89062
  const id = entry.id;
89063
+ const castaliaPath = workspacePaths(entry.path).castalia;
89064
+ ensureParent(castaliaPath);
89065
+ await prepareStore(castaliaPath, entry.path, id);
89066
+ if (stopping) throw new Error("daemon stopping");
88697
89067
  const wsIdentity = identityFor(entry);
88698
89068
  let wsCloud = cloud;
88699
89069
  if (wsIdentity.rule === "workspace-binding") {
@@ -88738,6 +89108,9 @@ async function startMultiDaemon(opts = {}) {
88738
89108
  onSubagentSpawn: engine.webHooks.onSubagentSpawn,
88739
89109
  subagentContext: engine.webHooks.subagentContext,
88740
89110
  onSubagentStop: engine.webHooks.onSubagentStop,
89111
+ // CAP-session-scope: per-session blocks + harness/fixture quarantine.
89112
+ noteSession: engine.webHooks.noteSession,
89113
+ sessionContext: engine.webHooks.sessionContext,
88741
89114
  onHook: engine.webHooks.onHook,
88742
89115
  onHookEvent: engine.webHooks.onHookEvent,
88743
89116
  onShellEvent: engine.webHooks.onShellEvent,
@@ -88773,7 +89146,7 @@ async function startMultiDaemon(opts = {}) {
88773
89146
  if (opts.eagerWorkspaces ?? EAGER_WORKSPACES_AT_BOOT) {
88774
89147
  for (const entry of entries) {
88775
89148
  try {
88776
- records.push(buildRecord(entry));
89149
+ records.push(await buildRecord(entry));
88777
89150
  } catch (err2) {
88778
89151
  console.warn(`[errata] skipping ${entry.name} (${entry.path}): ${err2 instanceof Error ? err2.message : err2}`);
88779
89152
  }
@@ -88791,21 +89164,31 @@ async function startMultiDaemon(opts = {}) {
88791
89164
  }
88792
89165
  const app = new Hono2();
88793
89166
  const enqueueWakeIndex = serialQueue();
89167
+ const attaching = /* @__PURE__ */ new Map();
88794
89168
  const attachWorkspace = (root) => {
89169
+ const norm = normPath(root);
89170
+ const pending = attaching.get(norm);
89171
+ if (pending) return pending;
89172
+ const run3 = attachWorkspaceOnce(root).finally(() => attaching.delete(norm));
89173
+ attaching.set(norm, run3);
89174
+ return run3;
89175
+ };
89176
+ const attachWorkspaceOnce = async (root) => {
89177
+ if (stopping) return { attached: false, id: null, reason: "daemon-stopping" };
88795
89178
  const norm = normPath(root);
88796
89179
  if (records.some((r) => normPath(r.root) === norm)) return { attached: false, id: null, reason: "already-watched" };
88797
89180
  const entry = listWorkspaceEntries().find((e) => normPath(e.path) === norm);
88798
89181
  if (!entry) return { attached: false, id: null, reason: "not-registered" };
88799
89182
  let rec;
88800
89183
  try {
88801
- rec = buildRecord(entry);
89184
+ rec = await buildRecord(entry);
88802
89185
  } catch (err2) {
88803
89186
  return { attached: false, id: null, reason: err2 instanceof Error ? err2.message : "build-failed" };
88804
89187
  }
88805
89188
  records.push(rec);
88806
89189
  void ambientLinkAll();
88807
89190
  try {
88808
- writeFileSync25(
89191
+ writeFileSync26(
88809
89192
  rec.engine.paths.daemonLock,
88810
89193
  daemonLockPayload({
88811
89194
  pid: process.pid,
@@ -88842,7 +89225,7 @@ async function startMultiDaemon(opts = {}) {
88842
89225
  }
88843
89226
  const root = typeof body2["path"] === "string" ? body2["path"] : null;
88844
89227
  if (!root) return c.json({ error: "path-required" }, 400);
88845
- return c.json(attachWorkspace(root));
89228
+ return c.json(await attachWorkspace(root));
88846
89229
  });
88847
89230
  app.post("/api/notify-test", (c) => {
88848
89231
  notify("Errata \xB7 test", "Fired from the daemon \u2014 if you see this, daemon toasts render.");
@@ -88927,6 +89310,7 @@ async function startMultiDaemon(opts = {}) {
88927
89310
  // pegged daemon is only diagnosable by attaching a CPU profiler to the
88928
89311
  // live process — see watch-census.ts for the incident that proved it.
88929
89312
  pass: passState(),
89313
+ heavyPass: heavyPassState(),
88930
89314
  watch: watchCensus(),
88931
89315
  // Registered but with no engine running (WS-cold-start). Listed so a cold
88932
89316
  // daemon is legible as "nothing has needed waking yet" rather than as
@@ -88970,7 +89354,7 @@ async function startMultiDaemon(opts = {}) {
88970
89354
  if (!main2) continue;
88971
89355
  owner = ownerOf(records, main2);
88972
89356
  if (!owner && listWorkspaceEntries().some((e) => pickOwnerRoot([e.path], main2))) {
88973
- if (attachWorkspace(main2).attached) owner = ownerOf(records, main2);
89357
+ if ((await attachWorkspace(main2)).attached) owner = ownerOf(records, main2);
88974
89358
  }
88975
89359
  if (owner) break;
88976
89360
  }
@@ -88978,7 +89362,7 @@ async function startMultiDaemon(opts = {}) {
88978
89362
  if (!owner && others.length > 0) {
88979
89363
  const registryRoots = listWorkspaceEntries().map((e) => e.path);
88980
89364
  const registered = others.map((p) => pickOwnerRoot(registryRoots, p)).find((r) => r != null);
88981
- if (registered && attachWorkspace(registered).attached) {
89365
+ if (registered && (await attachWorkspace(registered)).attached) {
88982
89366
  owner = records.find((r) => r.root === registered) ?? null;
88983
89367
  if (owner) console.log(`[errata] woke workspace ${owner.entry.name}`);
88984
89368
  }
@@ -88987,7 +89371,7 @@ async function startMultiDaemon(opts = {}) {
88987
89371
  const missPath = pathInBody(body2);
88988
89372
  const registeredRoot = missPath ? pickOwnerRoot(listWorkspaceEntries().map((e) => e.path), missPath) : null;
88989
89373
  const wakeRoot = registeredRoot ?? (missPath ? findGitRoot(missPath) : null);
88990
- if (wakeRoot && attachWorkspace(wakeRoot).attached) {
89374
+ if (wakeRoot && (await attachWorkspace(wakeRoot)).attached) {
88991
89375
  owner = ownerOf(records, missPath) ?? null;
88992
89376
  if (owner) console.log(`[errata] woke workspace ${owner.entry.name}`);
88993
89377
  }
@@ -88996,7 +89380,7 @@ async function startMultiDaemon(opts = {}) {
88996
89380
  const root = sessionAffinity.rootFor(body2["session_id"]);
88997
89381
  if (root) {
88998
89382
  owner = records.find((r) => r.root === root) ?? null;
88999
- if (!owner && attachWorkspace(root).attached) owner = records.find((r) => r.root === root) ?? null;
89383
+ if (!owner && (await attachWorkspace(root)).attached) owner = records.find((r) => r.root === root) ?? null;
89000
89384
  }
89001
89385
  }
89002
89386
  if (!owner) {
@@ -89012,7 +89396,12 @@ async function startMultiDaemon(opts = {}) {
89012
89396
  return await owner.webApp.fetch(
89013
89397
  new Request(`http://local${sub}`, {
89014
89398
  method: "POST",
89015
- headers: { "content-type": "application/json" },
89399
+ // The origin header (harness/fixture quarantine, session-registry.ts)
89400
+ // is the one caller header the sub-app needs; nothing else crosses.
89401
+ headers: {
89402
+ "content-type": "application/json",
89403
+ ...c.req.header(ORIGIN_HEADER) ? { [ORIGIN_HEADER]: c.req.header(ORIGIN_HEADER) } : {}
89404
+ },
89016
89405
  body: raw2
89017
89406
  })
89018
89407
  );
@@ -89104,7 +89493,7 @@ async function startMultiDaemon(opts = {}) {
89104
89493
  lastActiveAt = Math.max(lastActiveAt, rec.engine.lastActivityAt());
89105
89494
  } catch {
89106
89495
  }
89107
- const reason = retireDecision({ exists: existsSync33(rec.root), lastActiveAt, now });
89496
+ const reason = retireDecision({ exists: existsSync34(rec.root), lastActiveAt, now });
89108
89497
  if (reason) void retireWorkspace(rec, reason);
89109
89498
  }
89110
89499
  };
@@ -89129,9 +89518,11 @@ async function startMultiDaemon(opts = {}) {
89129
89518
  });
89130
89519
  candidates.forEach((c, i2) => {
89131
89520
  const wake = setTimeout(() => {
89132
- if (attachWorkspace(c.path).attached) {
89133
- console.log(`[errata] woke workspace ${c.name} \u2014 recent Codex/Gemini/OpenCode transcript (headless capture)`);
89134
- }
89521
+ void attachWorkspace(c.path).then((result) => {
89522
+ if (result.attached) {
89523
+ console.log(`[errata] woke workspace ${c.name} \u2014 recent Codex/Gemini/OpenCode transcript (headless capture)`);
89524
+ }
89525
+ });
89135
89526
  }, wakeDelay(i2));
89136
89527
  wake.unref?.();
89137
89528
  });
@@ -89175,7 +89566,7 @@ async function startMultiDaemon(opts = {}) {
89175
89566
  baseUrl = `http://127.0.0.1:${port}`;
89176
89567
  try {
89177
89568
  ensureDir(globalDir());
89178
- writeFileSync25(
89569
+ writeFileSync26(
89179
89570
  lockPath,
89180
89571
  daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
89181
89572
  "utf8"
@@ -89184,7 +89575,7 @@ async function startMultiDaemon(opts = {}) {
89184
89575
  }
89185
89576
  for (const r of records) {
89186
89577
  try {
89187
- writeFileSync25(
89578
+ writeFileSync26(
89188
89579
  r.engine.paths.daemonLock,
89189
89580
  daemonLockPayload({
89190
89581
  pid: process.pid,
@@ -89217,7 +89608,7 @@ async function startMultiDaemon(opts = {}) {
89217
89608
  saveProfile(root, profile);
89218
89609
  }
89219
89610
  registerWorkspace(profile, root);
89220
- attachWorkspace(root);
89611
+ await attachWorkspace(root);
89221
89612
  },
89222
89613
  // eslint-disable-next-line no-console
89223
89614
  log: (line) => console.log(line)
@@ -89418,7 +89809,7 @@ async function startMultiDaemon(opts = {}) {
89418
89809
  const packageAutoAll = async () => {
89419
89810
  const out2 = /* @__PURE__ */ new Map();
89420
89811
  for (const r of records) {
89421
- await new Promise((resolve8) => setImmediate(resolve8));
89812
+ await new Promise((resolve9) => setImmediate(resolve9));
89422
89813
  const done = markPass(`package-index:${r.entry.name}`);
89423
89814
  try {
89424
89815
  out2.set(
@@ -89727,7 +90118,9 @@ async function startMultiDaemon(opts = {}) {
89727
90118
  done();
89728
90119
  }
89729
90120
  };
89730
- const buildInstanceBatch = async (r, input) => {
90121
+ const buildInstanceBatch = async (r, laneInput) => {
90122
+ const quarantinedSessions = r.engine.quarantinedSessions();
90123
+ const input = quarantinedSessions.length ? { ...laneInput, quarantinedSessions } : laneInput;
89731
90124
  const w = workerFor(r);
89732
90125
  if (w) {
89733
90126
  try {
@@ -89762,6 +90155,7 @@ async function startMultiDaemon(opts = {}) {
89762
90155
  for (const r of records) {
89763
90156
  const recordConsent = effectiveConsent(cfg2, r.engine.profile);
89764
90157
  if (!recordConsent.sync) continue;
90158
+ if (!shipsFromWorkspace(r.root)) continue;
89765
90159
  const recordIdentity = identityFor(liveWorkspaceEntry(r.entry));
89766
90160
  if (recordIdentity.invalid) {
89767
90161
  noteIdentityBlock(r.id, r.entry.name, recordIdentity);
@@ -90151,12 +90545,13 @@ async function startMultiDaemon(opts = {}) {
90151
90545
  boundaryListeners.push(cb);
90152
90546
  },
90153
90547
  async stop() {
90548
+ stopping = true;
90154
90549
  clearInterval(idleSweep);
90155
90550
  clearInterval(codexWake);
90156
90551
  clearInterval(anchorPull);
90157
90552
  clearTimeout(codexWakeBoot);
90158
90553
  try {
90159
- const cur = readFileSync35(lockPath, "utf8");
90554
+ const cur = readFileSync36(lockPath, "utf8");
90160
90555
  if (JSON.parse(cur).pid === process.pid) unlinkSync5(lockPath);
90161
90556
  } catch {
90162
90557
  }
@@ -90165,6 +90560,7 @@ async function startMultiDaemon(opts = {}) {
90165
90560
  );
90166
90561
  updatePoller?.stop();
90167
90562
  healthSentinel.stop();
90563
+ await Promise.allSettled(attaching.values());
90168
90564
  for (const r of records) await r.engine.stop();
90169
90565
  if (consolidateWorker) await consolidateWorker.stop();
90170
90566
  try {
@@ -90245,18 +90641,18 @@ async function runUse(action, ctx) {
90245
90641
  }
90246
90642
  }
90247
90643
  function runClear(ctx) {
90248
- const active2 = ctx.getActiveAgent();
90644
+ const active3 = ctx.getActiveAgent();
90249
90645
  ctx.clearActiveAgent();
90250
- if (active2) {
90251
- ctx.log(`no longer acting as ${active2.handle} \u2014 the daemon acts as your default identity`);
90646
+ if (active3) {
90647
+ ctx.log(`no longer acting as ${active3.handle} \u2014 the daemon acts as your default identity`);
90252
90648
  } else {
90253
90649
  ctx.log(`already on the default identity \u2014 nothing to clear`);
90254
90650
  }
90255
90651
  return 0;
90256
90652
  }
90257
90653
  async function runShow(ctx) {
90258
- const active2 = ctx.getActiveAgent();
90259
- ctx.log(active2 ? `active agent: ${active2.handle} (id ${active2.id})` : `active agent: (default identity)`);
90654
+ const active3 = ctx.getActiveAgent();
90655
+ ctx.log(active3 ? `active agent: ${active3.handle} (id ${active3.id})` : `active agent: (default identity)`);
90260
90656
  if (!ctx.loggedIn) {
90261
90657
  ctx.log(` log in to list the agents you can act as: errata login`);
90262
90658
  return 0;
@@ -90268,7 +90664,7 @@ async function runShow(ctx) {
90268
90664
  ctx.log(` couldn't list actable agents: ${errText(err2)}`);
90269
90665
  return 1;
90270
90666
  }
90271
- printActable(resp, active2, ctx);
90667
+ printActable(resp, active3, ctx);
90272
90668
  return 0;
90273
90669
  }
90274
90670
  async function runSet(handle2, ctx) {
@@ -90297,7 +90693,7 @@ async function runSet(handle2, ctx) {
90297
90693
  ctx.log(`now acting as ${match2.handle} (id ${match2.id}) \u2014 saved; persists across daemon restarts`);
90298
90694
  return 0;
90299
90695
  }
90300
- function printActable(resp, active2, ctx) {
90696
+ function printActable(resp, active3, ctx) {
90301
90697
  if (resp.agents.length === 0) {
90302
90698
  ctx.log(` (no agents you can act as)`);
90303
90699
  return;
@@ -90305,7 +90701,7 @@ function printActable(resp, active2, ctx) {
90305
90701
  ctx.log(` agents you can act as:`);
90306
90702
  for (const a of resp.agents) {
90307
90703
  const marks = [];
90308
- if (active2 && a.id === active2.id) marks.push("active");
90704
+ if (active3 && a.id === active3.id) marks.push("active");
90309
90705
  if (a.id === resp.defaultAgentId) marks.push("default");
90310
90706
  const suffix = marks.length ? ` (${marks.join(", ")})` : "";
90311
90707
  const scope = a.scope ? ` \xB7 ${a.scope}` : "";
@@ -90717,23 +91113,25 @@ async function diagnoseInstallation(cfg, dependencies) {
90717
91113
 
90718
91114
  // src/codex-doctor.ts
90719
91115
  import { spawn as spawn4 } from "node:child_process";
90720
- import { readFileSync as readFileSync37, statSync as statSync10 } from "node:fs";
91116
+ import { readFileSync as readFileSync38, statSync as statSync10 } from "node:fs";
90721
91117
  import { join as join44 } from "node:path";
90722
91118
  import { createInterface } from "node:readline";
90723
91119
 
90724
91120
  // src/codex-hooks.ts
90725
- import { existsSync as existsSync34, mkdirSync as mkdirSync9, readFileSync as readFileSync36, renameSync as renameSync5, unlinkSync as unlinkSync6, writeFileSync as writeFileSync26 } from "node:fs";
91121
+ import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync37, renameSync as renameSync5, unlinkSync as unlinkSync6, writeFileSync as writeFileSync27 } from "node:fs";
90726
91122
  import { homedir as homedir7 } from "node:os";
90727
91123
  import { join as join43 } from "node:path";
90728
91124
 
90729
91125
  // src/hook-commands.ts
90730
91126
  function hookCurlCommand(port, path2 = "/api/hook") {
90731
91127
  const url2 = `http://127.0.0.1:${port}${path2}`;
90732
- return process.platform === "win32" ? `cmd //c "curl -s --connect-timeout 1 --max-time 3 -X POST -H \\"Content-Type: application/json\\" --data-binary @- ${url2} >NUL 2>NUL || exit /b 0"` : `curl -s --connect-timeout 1 --max-time 3 -X POST -H 'Content-Type: application/json' --data-binary @- ${url2} >/dev/null 2>&1 || true`;
91128
+ return process.platform === "win32" ? `cmd //c "curl -s --connect-timeout 1 --max-time 3 -X POST ${HEADERS_WIN} --data-binary @- ${url2} >NUL 2>NUL || exit /b 0"` : `curl -s --connect-timeout 1 --max-time 3 -X POST -H 'Content-Type: application/json' ${ORIGIN_HEADER_POSIX} --data-binary @- ${url2} >/dev/null 2>&1 || true`;
90733
91129
  }
91130
+ var HEADERS_WIN = `-H Content-Type:application/json -H x-errata-origin:%ERRATA_ORIGIN%`;
91131
+ var ORIGIN_HEADER_POSIX = `-H "x-errata-origin: \${ERRATA_ORIGIN:-}"`;
90734
91132
  function hookRelayCommand(port, path2) {
90735
91133
  const url2 = `http://127.0.0.1:${port}${path2}`;
90736
- return process.platform === "win32" ? `cmd //c "curl -s --connect-timeout 1 --max-time 2 -X POST -H \\"Content-Type: application/json\\" --data-binary @- ${url2} 2>NUL || echo {}"` : `curl -s --connect-timeout 1 --max-time 2 -X POST -H 'Content-Type: application/json' --data-binary @- ${url2} 2>/dev/null || echo '{}'`;
91134
+ return process.platform === "win32" ? `cmd //c "curl -s --connect-timeout 1 --max-time 2 -X POST ${HEADERS_WIN} --data-binary @- ${url2} 2>NUL || echo {}"` : `curl -s --connect-timeout 1 --max-time 2 -X POST -H 'Content-Type: application/json' ${ORIGIN_HEADER_POSIX} --data-binary @- ${url2} 2>/dev/null || echo '{}'`;
90737
91135
  }
90738
91136
  var CODEX_HOOKS_BEGIN = `# >>> errata hooks (errata-managed)`;
90739
91137
  var CODEX_HOOKS_END = `# <<< errata hooks`;
@@ -90870,23 +91268,23 @@ function buildCodexRelaySource(workspaceRoot) {
90870
91268
  init_checkout_root();
90871
91269
  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.";
90872
91270
  function writeRelay(file2, source) {
90873
- if (existsSync34(file2) && readFileSync36(file2, "utf8") === source) return;
91271
+ if (existsSync35(file2) && readFileSync37(file2, "utf8") === source) return;
90874
91272
  const temp = `${file2}.${process.pid}.tmp`;
90875
91273
  try {
90876
- writeFileSync26(temp, source, { encoding: "utf8", mode: 384 });
91274
+ writeFileSync27(temp, source, { encoding: "utf8", mode: 384 });
90877
91275
  renameSync5(temp, file2);
90878
91276
  } finally {
90879
- if (existsSync34(temp)) unlinkSync6(temp);
91277
+ if (existsSync35(temp)) unlinkSync6(temp);
90880
91278
  }
90881
91279
  }
90882
91280
  function refreshCodexRelay(root) {
90883
91281
  const config2 = join43(root, ".codex", "config.toml");
90884
- if (!existsSync34(config2)) return "absent";
90885
- const existing = readFileSync36(config2, "utf8");
91282
+ if (!existsSync35(config2)) return "absent";
91283
+ const existing = readFileSync37(config2, "utf8");
90886
91284
  if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
90887
91285
  replaceCodexHooks(existing, "");
90888
91286
  const relay = join43(root, ".codex", "hooks", "errata-relay.mjs");
90889
- const prior = existsSync34(relay) ? readFileSync36(relay, "utf8") : "";
91287
+ const prior = existsSync35(relay) ? readFileSync37(relay, "utf8") : "";
90890
91288
  if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
90891
91289
  throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
90892
91290
  }
@@ -90897,7 +91295,7 @@ function refreshCodexRelay(root) {
90897
91295
  return "updated";
90898
91296
  }
90899
91297
  function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join43(homedir7(), ".codex")) {
90900
- return existsSync34(join43(root, ".codex")) || existsSync34(codexHome);
91298
+ return existsSync35(join43(root, ".codex")) || existsSync35(codexHome);
90901
91299
  }
90902
91300
  function replaceCodexHooks(existing, block) {
90903
91301
  const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
@@ -90917,10 +91315,10 @@ function writeCodexHooks(root, port, nodePath = process.execPath) {
90917
91315
  const file2 = join43(dir, "config.toml");
90918
91316
  const relay = join43(dir, "hooks", "errata-relay.mjs");
90919
91317
  const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
90920
- const final = replaceCodexHooks(existsSync34(file2) ? readFileSync36(file2, "utf8") : "", block);
91318
+ const final = replaceCodexHooks(existsSync35(file2) ? readFileSync37(file2, "utf8") : "", block);
90921
91319
  mkdirSync9(join43(dir, "hooks"), { recursive: true });
90922
91320
  writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
90923
- if (!existsSync34(file2) || readFileSync36(file2, "utf8") !== final) writeFileSync26(file2, final, "utf8");
91321
+ if (!existsSync35(file2) || readFileSync37(file2, "utf8") !== final) writeFileSync27(file2, final, "utf8");
90924
91322
  return file2;
90925
91323
  }
90926
91324
 
@@ -90929,7 +91327,7 @@ init_checkout_root();
90929
91327
  function inspectCodexRelay(cwd) {
90930
91328
  const root = nearestGitRoot(cwd) ?? cwd;
90931
91329
  try {
90932
- const source = readFileSync37(join44(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
91330
+ const source = readFileSync38(join44(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
90933
91331
  if (source === buildCodexRelaySource(checkoutRootOf(root))) {
90934
91332
  return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
90935
91333
  }
@@ -90941,7 +91339,7 @@ function inspectCodexContext(cwd) {
90941
91339
  const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
90942
91340
  try {
90943
91341
  const file2 = join44(root, ".errata", "context.md");
90944
- if (statSync10(file2).size <= 128 * 1024 && readFileSync37(file2, "utf8").trim()) {
91342
+ if (statSync10(file2).size <= 128 * 1024 && readFileSync38(file2, "utf8").trim()) {
90945
91343
  return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
90946
91344
  }
90947
91345
  } catch {
@@ -90949,7 +91347,7 @@ function inspectCodexContext(cwd) {
90949
91347
  return { id: "codex_context", status: "fail", detail: "No usable saved workspace context; run errata start here and check the daemon log if context.md remains unavailable" };
90950
91348
  }
90951
91349
  function readCodexHookState(cwd, options = {}) {
90952
- return new Promise((resolve8, reject) => {
91350
+ return new Promise((resolve9, reject) => {
90953
91351
  const child = spawn4(options.bin ?? resolveCodexExecutable(), options.args ?? ["app-server", "--stdio"], {
90954
91352
  cwd,
90955
91353
  windowsHide: true,
@@ -90970,7 +91368,7 @@ function readCodexHookState(cwd, options = {}) {
90970
91368
  child.once("close", () => {
90971
91369
  clearTimeout(reap);
90972
91370
  if (error48) reject(error48);
90973
- else resolve8({ ...hooks, features });
91371
+ else resolve9({ ...hooks, features });
90974
91372
  });
90975
91373
  child.kill();
90976
91374
  };
@@ -91117,16 +91515,16 @@ function consolidationGapMs(lastPassMs, policy) {
91117
91515
 
91118
91516
  // src/codex-hook-refresh.ts
91119
91517
  init_checkout_root();
91120
- import { existsSync as existsSync35, readdirSync as readdirSync13, readFileSync as readFileSync38 } from "node:fs";
91121
- import { dirname as dirname13, join as join45, resolve as resolve7 } from "node:path";
91518
+ import { existsSync as existsSync36, readdirSync as readdirSync13, readFileSync as readFileSync39 } from "node:fs";
91519
+ import { dirname as dirname13, join as join45, resolve as resolve8 } from "node:path";
91122
91520
  init_registry();
91123
91521
  function codexHookRoots(roots) {
91124
- const found = new Set(roots.map((root) => resolve7(root)));
91522
+ const found = new Set(roots.map((root) => resolve8(root)));
91125
91523
  for (const root of [...found]) {
91126
91524
  const main2 = mainCheckoutOfWorktree(root) ?? root;
91127
91525
  found.add(main2);
91128
91526
  const dir = join45(main2, ".git", "worktrees");
91129
- if (!existsSync35(dir)) continue;
91527
+ if (!existsSync36(dir)) continue;
91130
91528
  let names;
91131
91529
  try {
91132
91530
  names = readdirSync13(dir);
@@ -91135,7 +91533,7 @@ function codexHookRoots(roots) {
91135
91533
  }
91136
91534
  for (const name2 of names) {
91137
91535
  try {
91138
- const checkout = dirname13(readFileSync38(join45(dir, name2, "gitdir"), "utf8").trim());
91536
+ const checkout = dirname13(readFileSync39(join45(dir, name2, "gitdir"), "utf8").trim());
91139
91537
  if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
91140
91538
  } catch {
91141
91539
  }
@@ -91157,7 +91555,7 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
91157
91555
  }
91158
91556
 
91159
91557
  // src/claude-statusline.ts
91160
- import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync39, writeFileSync as writeFileSync27 } from "node:fs";
91558
+ import { existsSync as existsSync37, mkdirSync as mkdirSync10, readFileSync as readFileSync40, writeFileSync as writeFileSync28 } from "node:fs";
91161
91559
  import { homedir as homedir8 } from "node:os";
91162
91560
  import { dirname as dirname14, join as join46 } from "node:path";
91163
91561
  var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
@@ -91212,9 +91610,9 @@ function ensureUserStatusLine(opts) {
91212
91610
  if (off === "0" || off === "off" || off === "false" || off === "no") return "disabled";
91213
91611
  const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
91214
91612
  let settings = {};
91215
- if (existsSync36(settingsPath)) {
91613
+ if (existsSync37(settingsPath)) {
91216
91614
  try {
91217
- const parsed = JSON.parse(readFileSync39(settingsPath, "utf8"));
91615
+ const parsed = JSON.parse(readFileSync40(settingsPath, "utf8"));
91218
91616
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
91219
91617
  settings = parsed;
91220
91618
  } catch {
@@ -91226,8 +91624,8 @@ function ensureUserStatusLine(opts) {
91226
91624
  if (ownMain && ownRows) return "kept-own";
91227
91625
  const relay = join46(opts.relayDir, STATUSLINE_RELAY_FILE);
91228
91626
  mkdirSync10(opts.relayDir, { recursive: true });
91229
- if (!existsSync36(relay) || readFileSync39(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
91230
- writeFileSync27(relay, STATUSLINE_RELAY_SOURCE, "utf8");
91627
+ if (!existsSync37(relay) || readFileSync40(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
91628
+ writeFileSync28(relay, STATUSLINE_RELAY_SOURCE, "utf8");
91231
91629
  }
91232
91630
  const nodePath = opts.nodePath ?? process.execPath;
91233
91631
  const next = {
@@ -91239,7 +91637,7 @@ function ensureUserStatusLine(opts) {
91239
91637
  }
91240
91638
  Object.assign(settings, next);
91241
91639
  mkdirSync10(dirname14(settingsPath), { recursive: true });
91242
- writeFileSync27(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
91640
+ writeFileSync28(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
91243
91641
  return "installed";
91244
91642
  }
91245
91643
  function describeStatusLineOutcome(outcome) {
@@ -91662,14 +92060,14 @@ async function cmdInit() {
91662
92060
  if (!skipHooks) {
91663
92061
  console.log("");
91664
92062
  console.log("installing harness hooks...");
91665
- const { existsSync: existsSync38 } = await import("node:fs");
92063
+ const { existsSync: existsSync39 } = await import("node:fs");
91666
92064
  const { join: join48 } = await import("node:path");
91667
92065
  try {
91668
92066
  await installClaudeHooks(port);
91669
92067
  } catch (err2) {
91670
92068
  console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
91671
92069
  }
91672
- if (existsSync38(join48(ROOT, ".cursor"))) {
92070
+ if (existsSync39(join48(ROOT, ".cursor"))) {
91673
92071
  try {
91674
92072
  await installCursorMcpConfig();
91675
92073
  } catch (err2) {
@@ -91863,9 +92261,9 @@ async function cmdStatus() {
91863
92261
  console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
91864
92262
  console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
91865
92263
  }
91866
- console.log(` graph db: ${existsSync37(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
91867
- console.log(` event log: ${existsSync37(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
91868
- if (existsSync37(paths.castalia)) {
92264
+ console.log(` graph db: ${existsSync38(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
92265
+ console.log(` event log: ${existsSync38(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
92266
+ if (existsSync38(paths.castalia)) {
91869
92267
  try {
91870
92268
  const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
91871
92269
  const store = openGraphStore2({ path: paths.castalia });
@@ -91986,9 +92384,9 @@ async function cmdStatus() {
91986
92384
  } else {
91987
92385
  console.log(` logged in: yes (${cfg.email}) \u2014 key capability enforced by Console installation/scopes`);
91988
92386
  }
91989
- const active2 = getActiveAgent(cfg);
92387
+ const active3 = getActiveAgent(cfg);
91990
92388
  console.log(
91991
- ` active agent: ${active2 ? `${active2.handle} (acting-as; \`errata use --none\` to clear)` : "default identity"}`
92389
+ ` active agent: ${active3 ? `${active3.handle} (acting-as; \`errata use --none\` to clear)` : "default identity"}`
91992
92390
  );
91993
92391
  const inspection = await inspectCloudEndpoint(cfg.cloudUrl);
91994
92392
  const decision = evaluateCloudEndpoint(cfg.cloudUrl, inspection);
@@ -92108,8 +92506,8 @@ async function cmdWhoami(args2) {
92108
92506
  return;
92109
92507
  }
92110
92508
  try {
92111
- const active2 = getActiveAgent(cfg);
92112
- const response = await resolveWhoami(authedCloudClient(cfg), active2?.handle ?? null);
92509
+ const active3 = getActiveAgent(cfg);
92510
+ const response = await resolveWhoami(authedCloudClient(cfg), active3?.handle ?? null);
92113
92511
  if (args2.includes("--json")) {
92114
92512
  console.log(JSON.stringify(response, null, 2));
92115
92513
  return;
@@ -92836,11 +93234,11 @@ async function cmdInstallationProfile(args2) {
92836
93234
  }
92837
93235
  async function cmdReview() {
92838
93236
  const paths = workspacePaths(ROOT);
92839
- if (!existsSync37(paths.reviewQueue)) {
93237
+ if (!existsSync38(paths.reviewQueue)) {
92840
93238
  console.log("(review queue empty)");
92841
93239
  return;
92842
93240
  }
92843
- const queue = JSON.parse(readFileSync40(paths.reviewQueue, "utf8"));
93241
+ const queue = JSON.parse(readFileSync41(paths.reviewQueue, "utf8"));
92844
93242
  if (queue.length === 0) {
92845
93243
  console.log("(review queue empty)");
92846
93244
  return;
@@ -93511,7 +93909,7 @@ async function gatherRepo(store, ws) {
93511
93909
  };
93512
93910
  }
93513
93911
  async function gatherReportData(generatedAt) {
93514
- const { existsSync: existsSync38 } = await import("node:fs");
93912
+ const { existsSync: existsSync39 } = await import("node:fs");
93515
93913
  const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
93516
93914
  const cfg = loadConfig();
93517
93915
  const outbound = cfg.consent.sync ? "auto" : "off";
@@ -93519,7 +93917,7 @@ async function gatherReportData(generatedAt) {
93519
93917
  for (const ws of listWorkspaces()) {
93520
93918
  if (ws.missing) continue;
93521
93919
  const dbPath = workspacePaths(ws.path).castalia;
93522
- if (!existsSync38(dbPath)) continue;
93920
+ if (!existsSync39(dbPath)) continue;
93523
93921
  let store = null;
93524
93922
  try {
93525
93923
  store = openGraphStore2({ path: dbPath });
@@ -93550,7 +93948,7 @@ async function gatherReportData(generatedAt) {
93550
93948
  };
93551
93949
  }
93552
93950
  async function cmdReport(args2) {
93553
- const { mkdirSync: mkdirSync11, writeFileSync: writeFileSync28 } = await import("node:fs");
93951
+ const { mkdirSync: mkdirSync11, writeFileSync: writeFileSync29 } = await import("node:fs");
93554
93952
  const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
93555
93953
  const includeFutureVerbs = args2.includes("--future-verbs");
93556
93954
  const now = /* @__PURE__ */ new Date();
@@ -93563,7 +93961,7 @@ async function cmdReport(args2) {
93563
93961
  const outDir = workspacePaths(ROOT).configDir;
93564
93962
  mkdirSync11(outDir, { recursive: true });
93565
93963
  const files = renderReport2(data, { includeFutureVerbs });
93566
- for (const f of files) writeFileSync28(join47(outDir, f.name), f.html, "utf8");
93964
+ for (const f of files) writeFileSync29(join47(outDir, f.name), f.html, "utf8");
93567
93965
  const indexPath = join47(outDir, "report.html");
93568
93966
  console.log(`report \u2192 ${indexPath}`);
93569
93967
  console.log(
@@ -93677,24 +94075,24 @@ async function cmdInstallHooks(args2) {
93677
94075
  }
93678
94076
  }
93679
94077
  async function installOpencodePlugin(port) {
93680
- const { mkdirSync: mkdirSync11, existsSync: existsSync38, readFileSync: readFileSync41, writeFileSync: writeFileSync28 } = await import("node:fs");
94078
+ const { mkdirSync: mkdirSync11, existsSync: existsSync39, readFileSync: readFileSync42, writeFileSync: writeFileSync29 } = await import("node:fs");
93681
94079
  const { join: join48 } = await import("node:path");
93682
94080
  const dir = join48(ROOT, ".opencode", "plugin");
93683
- if (!existsSync38(dir)) mkdirSync11(dir, { recursive: true });
94081
+ if (!existsSync39(dir)) mkdirSync11(dir, { recursive: true });
93684
94082
  const file2 = join48(dir, "inerrata.js");
93685
- if (existsSync38(file2)) {
93686
- const head2 = readFileSync41(file2, "utf8").split("\n")[0] ?? "";
94083
+ if (existsSync39(file2)) {
94084
+ const head2 = readFileSync42(file2, "utf8").split("\n")[0] ?? "";
93687
94085
  if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
93688
94086
  console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
93689
94087
  process.exit(2);
93690
94088
  }
93691
94089
  }
93692
- writeFileSync28(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
94090
+ writeFileSync29(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
93693
94091
  const cfgFile = join48(ROOT, "opencode.json");
93694
94092
  let cfg = { $schema: "https://opencode.ai/config.json" };
93695
- if (existsSync38(cfgFile)) {
94093
+ if (existsSync39(cfgFile)) {
93696
94094
  try {
93697
- cfg = JSON.parse(readFileSync41(cfgFile, "utf8"));
94095
+ cfg = JSON.parse(readFileSync42(cfgFile, "utf8"));
93698
94096
  } catch {
93699
94097
  console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
93700
94098
  process.exit(2);
@@ -93705,7 +94103,7 @@ async function installOpencodePlugin(port) {
93705
94103
  if (!hadErrata) {
93706
94104
  const inv = errataMcpInvocation();
93707
94105
  cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
93708
- writeFileSync28(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
94106
+ writeFileSync29(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
93709
94107
  }
93710
94108
  console.log(`installed OpenCode plugin \u2192 ${file2}`);
93711
94109
  if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
@@ -93732,15 +94130,15 @@ function ensureStatusLine(port) {
93732
94130
  }
93733
94131
  }
93734
94132
  async function installClaudeHooks(port) {
93735
- const { mkdirSync: mkdirSync11, existsSync: existsSync38, readFileSync: readFileSync41, writeFileSync: writeFileSync28 } = await import("node:fs");
94133
+ const { mkdirSync: mkdirSync11, existsSync: existsSync39, readFileSync: readFileSync42, writeFileSync: writeFileSync29 } = await import("node:fs");
93736
94134
  const { join: join48 } = await import("node:path");
93737
94135
  const dir = join48(ROOT, ".claude");
93738
- if (!existsSync38(dir)) mkdirSync11(dir, { recursive: true });
94136
+ if (!existsSync39(dir)) mkdirSync11(dir, { recursive: true });
93739
94137
  const file2 = join48(dir, "settings.json");
93740
94138
  let settings = {};
93741
- if (existsSync38(file2)) {
94139
+ if (existsSync39(file2)) {
93742
94140
  try {
93743
- settings = JSON.parse(readFileSync41(file2, "utf8"));
94141
+ settings = JSON.parse(readFileSync42(file2, "utf8"));
93744
94142
  } catch {
93745
94143
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
93746
94144
  process.exit(2);
@@ -93789,7 +94187,7 @@ async function installClaudeHooks(port) {
93789
94187
  list.push({ hooks: [{ type: "command", command: injectCmd }] });
93790
94188
  }
93791
94189
  removeProjectStatusLine(settings);
93792
- writeFileSync28(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
94190
+ writeFileSync29(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
93793
94191
  console.log(`installed Claude Code hooks \u2192 ${file2}`);
93794
94192
  console.log(` ${ensureStatusLine(port)}`);
93795
94193
  await installClaudeMcpConfig();
@@ -93805,15 +94203,15 @@ async function installClaudeHooks(port) {
93805
94203
  console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
93806
94204
  }
93807
94205
  async function installClaudeMcpConfig() {
93808
- const { mkdirSync: mkdirSync11, existsSync: existsSync38, readFileSync: readFileSync41, writeFileSync: writeFileSync28 } = await import("node:fs");
94206
+ const { mkdirSync: mkdirSync11, existsSync: existsSync39, readFileSync: readFileSync42, writeFileSync: writeFileSync29 } = await import("node:fs");
93809
94207
  const { join: join48, dirname: dirname15 } = await import("node:path");
93810
94208
  const file2 = join48(ROOT, ".mcp.json");
93811
94209
  const dir = dirname15(file2);
93812
- if (!existsSync38(dir)) mkdirSync11(dir, { recursive: true });
94210
+ if (!existsSync39(dir)) mkdirSync11(dir, { recursive: true });
93813
94211
  let cfg = {};
93814
- if (existsSync38(file2)) {
94212
+ if (existsSync39(file2)) {
93815
94213
  try {
93816
- cfg = JSON.parse(readFileSync41(file2, "utf8"));
94214
+ cfg = JSON.parse(readFileSync42(file2, "utf8"));
93817
94215
  } catch {
93818
94216
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
93819
94217
  process.exit(2);
@@ -93821,21 +94219,21 @@ async function installClaudeMcpConfig() {
93821
94219
  }
93822
94220
  cfg.mcpServers ??= {};
93823
94221
  cfg.mcpServers["errata"] = errataMcpInvocation();
93824
- writeFileSync28(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
94222
+ writeFileSync29(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
93825
94223
  console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
93826
94224
  console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
93827
94225
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
93828
94226
  }
93829
94227
  async function installCursorMcpConfig() {
93830
- const { mkdirSync: mkdirSync11, existsSync: existsSync38, readFileSync: readFileSync41, writeFileSync: writeFileSync28 } = await import("node:fs");
94228
+ const { mkdirSync: mkdirSync11, existsSync: existsSync39, readFileSync: readFileSync42, writeFileSync: writeFileSync29 } = await import("node:fs");
93831
94229
  const { join: join48 } = await import("node:path");
93832
94230
  const dir = join48(ROOT, ".cursor");
93833
- if (!existsSync38(dir)) mkdirSync11(dir, { recursive: true });
94231
+ if (!existsSync39(dir)) mkdirSync11(dir, { recursive: true });
93834
94232
  const file2 = join48(dir, "mcp.json");
93835
94233
  let cfg = {};
93836
- if (existsSync38(file2)) {
94234
+ if (existsSync39(file2)) {
93837
94235
  try {
93838
- cfg = JSON.parse(readFileSync41(file2, "utf8"));
94236
+ cfg = JSON.parse(readFileSync42(file2, "utf8"));
93839
94237
  } catch {
93840
94238
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
93841
94239
  process.exit(2);
@@ -93843,7 +94241,7 @@ async function installCursorMcpConfig() {
93843
94241
  }
93844
94242
  cfg.mcpServers ??= {};
93845
94243
  cfg.mcpServers["errata"] = errataMcpInvocation();
93846
- writeFileSync28(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
94244
+ writeFileSync29(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
93847
94245
  console.log(`installed Cursor MCP server config \u2192 ${file2}`);
93848
94246
  console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
93849
94247
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
@@ -94196,7 +94594,7 @@ async function cmdDash(args2) {
94196
94594
  const hotspotScanMark = /* @__PURE__ */ new Map();
94197
94595
  const HOTSPOT_FANIN = 20;
94198
94596
  const runNightlyPass = async (dueIds) => {
94199
- const yieldToLoop2 = () => new Promise((resolve8) => setImmediate(resolve8));
94597
+ const yieldToLoop2 = () => new Promise((resolve9) => setImmediate(resolve9));
94200
94598
  const fullReclusterPass = nightlyCount++ % FULL_RECLUSTER_EVERY === 0;
94201
94599
  const m = dueIds ? await handle2.nightlyFor(dueIds) : await handle2.nightlyAll();
94202
94600
  let skillsLearned = 0;