@cortexkit/pi-magic-context 0.41.1 → 0.41.2

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.
@@ -8422,8 +8422,8 @@ function formatFailClosedBlockingMessage(reason) {
8422
8422
  ].join(" ");
8423
8423
  }
8424
8424
  return [
8425
- `Magic Context cannot migrate the shared database because ${formatFailClosedBlockingProcesses(reason.blockingProcesses)} may be running an older Magic Context build that would fail against the migrated database.`,
8426
- "Restart the blocking process (it will pick up the new build and migrate on start), or shut it down and retry.",
8425
+ `Magic Context cannot migrate the shared database (one database serves every project on this machine) because ${formatFailClosedBlockingProcesses(reason.blockingProcesses)} may be running an older Magic Context build that would fail against the migrated database.`,
8426
+ "Restart the blocking process — even one from a different project — and it will pick up the new build and migrate on start; or shut it down and retry.",
8427
8427
  `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
8428
8428
  ].join(" ");
8429
8429
  }
@@ -9356,8 +9356,19 @@ function isPidAlive(pid) {
9356
9356
  var RPC_IDENTITY_SKEW_TOLERANCE_MS = 120000;
9357
9357
  var LINUX_CLOCK_TICKS_PER_SECOND = 100;
9358
9358
  var PS_PROBE_TIMEOUT_MS = 1000;
9359
+ var WINDOWS_CIM_PROBE_TIMEOUT_MS = 5000;
9360
+ var MAX_ANCESTOR_WALK_DEPTH = 16;
9359
9361
  var OPEN_CODE_COMMAND_MARKERS = ["opencode", "node", "bun", "electron"];
9360
9362
  var TASKLIST_NO_TASKS_PATTERN = /^INFO:\s+No tasks are running which match the specified criteria\.?$/im;
9363
+ var WINDOWS_CIM_COMMAND = "Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,CommandLine,CreationDate | ConvertTo-Json -Compress";
9364
+ var PI_HARNESS_ARC_MARKERS = [
9365
+ "pi-coding-agent",
9366
+ "oh-my-pi",
9367
+ "@oh-my-pi",
9368
+ "cljs/dist",
9369
+ "dist/bundle/cli"
9370
+ ];
9371
+ var PI_IMAGE_NAMES = new Set(["pi", "pi.cmd", "omp", "oh-my-pi"]);
9361
9372
  var rpcIdentityReadFileSync = readFileSync3;
9362
9373
  var rpcIdentityExecFileSync = execFileSync2;
9363
9374
  var rpcIdentityProcessKill = process.kill;
@@ -9402,7 +9413,7 @@ function readPsProcessStartTime(pid) {
9402
9413
  function readProcessStartTime(pid) {
9403
9414
  if (!Number.isInteger(pid) || pid <= 0)
9404
9415
  return null;
9405
- return rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(pid) : rpcIdentityPlatform === "win32" ? null : readPsProcessStartTime(pid);
9416
+ return rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(pid) : rpcIdentityPlatform === "win32" ? readWindowsProcessStartTime(pid) : readPsProcessStartTime(pid);
9406
9417
  }
9407
9418
  function readProcessProbeEvidence(pid) {
9408
9419
  return {
@@ -9410,6 +9421,10 @@ function readProcessProbeEvidence(pid) {
9410
9421
  commandLine: readProcessCommand(pid)
9411
9422
  };
9412
9423
  }
9424
+ var windowsProcessFactsCache = null;
9425
+ function rememberWindowsProcessFacts(facts) {
9426
+ windowsProcessFactsCache = new Map(facts.map((fact) => [fact.pid, fact]));
9427
+ }
9413
9428
  function parseCsvLine(line) {
9414
9429
  const fields = [];
9415
9430
  let field = "";
@@ -9474,6 +9489,16 @@ function readWindowsProcess(pid) {
9474
9489
  return { state: "inconclusive" };
9475
9490
  }
9476
9491
  }
9492
+ function readWindowsProcessStartTime(pid) {
9493
+ const cached = windowsProcessFactsCache?.get(pid);
9494
+ if (cached)
9495
+ return cached.startTime;
9496
+ const snapshot = tryReadWindowsCimSnapshot(rpcIdentityExecFileSync);
9497
+ if (!snapshot)
9498
+ return null;
9499
+ rememberWindowsProcessFacts(snapshot.facts);
9500
+ return windowsProcessFactsCache?.get(pid)?.startTime ?? null;
9501
+ }
9477
9502
  function readLinuxProcessCommand(pid) {
9478
9503
  try {
9479
9504
  return String(rpcIdentityReadFileSync(`/proc/${pid}/cmdline`, "utf8"));
@@ -9496,7 +9521,15 @@ function readPsProcessCommand(pid) {
9496
9521
  function readProcessCommand(pid) {
9497
9522
  if (!Number.isInteger(pid) || pid <= 0)
9498
9523
  return null;
9499
- return rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(pid) : rpcIdentityPlatform === "win32" ? readWindowsProcess(pid).command ?? null : readPsProcessCommand(pid);
9524
+ if (rpcIdentityPlatform === "linux")
9525
+ return readLinuxProcessCommand(pid);
9526
+ if (rpcIdentityPlatform === "win32") {
9527
+ const cached = windowsProcessFactsCache?.get(pid);
9528
+ if (cached?.commandLine)
9529
+ return cached.commandLine;
9530
+ return readWindowsProcess(pid).command ?? null;
9531
+ }
9532
+ return readPsProcessCommand(pid);
9500
9533
  }
9501
9534
  function executableName(token) {
9502
9535
  return (token ?? "").replace(/^['"]|['"]$/g, "").split("/").at(-1) ?? "";
@@ -9556,57 +9589,262 @@ function isPidIdentityPlausible(record, evidence) {
9556
9589
  return "inconclusive";
9557
9590
  return commandLooksLikeOpenCode(command) ? "plausible" : "implausible";
9558
9591
  }
9559
- function commandLooksLikePi(command) {
9560
- const normalized = command.trim().toLowerCase().replaceAll("\\", "/");
9561
- const tokens = normalized.split(/\s+/).filter(Boolean);
9562
- const executableName2 = (token) => (token ?? "").split("/").at(-1) ?? "";
9563
- const first = executableName2(tokens[0]).replace(/\.exe$/, "");
9564
- if (["pi", "pi.cmd", "omp", "oh-my-pi"].includes(first))
9592
+ function commandLooksLikePiImage(command) {
9593
+ const tokens = commandTokens(command);
9594
+ const first = executableName(tokens[0]).replace(/\.(?:exe|cmd)$/, "");
9595
+ return PI_IMAGE_NAMES.has(first);
9596
+ }
9597
+ function commandHasPiHarnessArc(command) {
9598
+ const normalized = command.trim().toLowerCase().replaceAll("\\", "/").replaceAll("\x00", " ");
9599
+ if (!normalized)
9600
+ return false;
9601
+ const tokens = commandTokens(command);
9602
+ if (tokens.length === 0)
9603
+ return false;
9604
+ const hasArc = PI_HARNESS_ARC_MARKERS.some((marker) => normalized.includes(marker));
9605
+ const first = executableName(tokens[0]).replace(/\.(?:exe|cmd)$/, "");
9606
+ if (hasArc && ["pi", "omp", "oh-my-pi", "node", "bun", "deno", "cmd"].includes(first)) {
9607
+ return true;
9608
+ }
9609
+ if (hasArc && PI_HARNESS_ARC_MARKERS.some((marker) => tokens[0].includes(marker))) {
9565
9610
  return true;
9611
+ }
9566
9612
  if (["node", "bun", "deno"].includes(first)) {
9567
- const script = executableName2(tokens[1]);
9568
- return ["pi", "pi.js", "pi.mjs", "pi.cjs"].includes(script) || normalized.includes("pi-coding-agent");
9613
+ const script = executableName(tokens[1]).replace(/\.(?:exe|cmd)$/, "");
9614
+ if (["pi", "pi.js", "pi.mjs", "pi.cjs"].includes(script))
9615
+ return true;
9616
+ if (hasArc)
9617
+ return true;
9569
9618
  }
9570
9619
  return false;
9571
9620
  }
9621
+ function execProcessList(exec, file, args, timeout = PS_PROBE_TIMEOUT_MS) {
9622
+ return String(exec(file, [...args], {
9623
+ encoding: "utf8",
9624
+ timeout,
9625
+ stdio: ["ignore", "pipe", "pipe"]
9626
+ }));
9627
+ }
9628
+ function parseWindowsCreationDate(value) {
9629
+ if (typeof value === "number" && Number.isFinite(value)) {
9630
+ return value > 1000000000000 ? value : value * 1000;
9631
+ }
9632
+ if (typeof value !== "string")
9633
+ return null;
9634
+ const trimmed = value.trim();
9635
+ if (!trimmed)
9636
+ return null;
9637
+ const wmi = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})\.(\d{6})([+-])(\d{3})$/.exec(trimmed);
9638
+ if (wmi) {
9639
+ const utcMs = Date.UTC(Number(wmi[1]), Number(wmi[2]) - 1, Number(wmi[3]), Number(wmi[4]), Number(wmi[5]), Number(wmi[6]), Number(wmi[7]) / 1000);
9640
+ if (!Number.isFinite(utcMs))
9641
+ return null;
9642
+ const offsetMinutes = Number(wmi[9]);
9643
+ const sign = wmi[8] === "+" ? 1 : -1;
9644
+ return utcMs - sign * offsetMinutes * 60000;
9645
+ }
9646
+ const dotNet = /^\/Date\((-?\d+)\)\/$/.exec(trimmed);
9647
+ if (dotNet) {
9648
+ const milliseconds = Number(dotNet[1]);
9649
+ return Number.isFinite(milliseconds) ? milliseconds : null;
9650
+ }
9651
+ const parsed = Date.parse(trimmed);
9652
+ return Number.isFinite(parsed) ? parsed : null;
9653
+ }
9654
+ function parseWindowsCimOutput(output) {
9655
+ const trimmed = output.trim();
9656
+ if (!trimmed)
9657
+ return null;
9658
+ const bracket = trimmed.indexOf("[");
9659
+ const brace = trimmed.indexOf("{");
9660
+ const start = Math.min(bracket === -1 ? Number.POSITIVE_INFINITY : bracket, brace === -1 ? Number.POSITIVE_INFINITY : brace);
9661
+ if (!Number.isFinite(start))
9662
+ return null;
9663
+ let parsed;
9664
+ try {
9665
+ parsed = JSON.parse(trimmed.slice(start));
9666
+ } catch {
9667
+ return null;
9668
+ }
9669
+ if (parsed == null)
9670
+ return null;
9671
+ const rows = Array.isArray(parsed) ? parsed : [parsed];
9672
+ const facts = [];
9673
+ for (const row of rows) {
9674
+ if (!row || typeof row !== "object")
9675
+ continue;
9676
+ const record = row;
9677
+ const pid = Number(record.ProcessId);
9678
+ if (!Number.isInteger(pid) || pid <= 0)
9679
+ continue;
9680
+ const parentRaw = record.ParentProcessId;
9681
+ const parentPid = parentRaw == null || parentRaw === "" ? Number.NaN : Number(parentRaw);
9682
+ const commandLine = typeof record.CommandLine === "string" ? record.CommandLine : null;
9683
+ facts.push({
9684
+ pid,
9685
+ parentPid: Number.isInteger(parentPid) && parentPid > 0 ? parentPid : null,
9686
+ commandLine,
9687
+ imageName: commandLine ? executableName(commandTokens(commandLine)[0]) : null,
9688
+ startTime: parseWindowsCreationDate(record.CreationDate)
9689
+ });
9690
+ }
9691
+ return facts.length > 0 ? facts : null;
9692
+ }
9693
+ function snapshotFromFacts(facts, source) {
9694
+ const parentByPid = new Map;
9695
+ for (const fact of facts) {
9696
+ if (fact.parentPid != null)
9697
+ parentByPid.set(fact.pid, fact.parentPid);
9698
+ }
9699
+ return { facts, parentByPid, source };
9700
+ }
9701
+ function tryReadWindowsCimSnapshot(exec) {
9702
+ try {
9703
+ const output = execProcessList(exec, "powershell", ["-NoProfile", "-Command", WINDOWS_CIM_COMMAND], WINDOWS_CIM_PROBE_TIMEOUT_MS);
9704
+ const facts = parseWindowsCimOutput(output);
9705
+ return facts ? snapshotFromFacts(facts, "cim") : null;
9706
+ } catch {
9707
+ return null;
9708
+ }
9709
+ }
9710
+ function tryReadWindowsTasklistSnapshot() {
9711
+ try {
9712
+ const output = execProcessList(rpcProcessListExecFileSync, "tasklist", ["/FO", "CSV"]);
9713
+ const entries = parseTasklistOutput(output);
9714
+ if (entries === null)
9715
+ return null;
9716
+ const facts = entries.map((entry) => ({
9717
+ pid: entry.pid,
9718
+ parentPid: null,
9719
+ commandLine: null,
9720
+ imageName: entry.command,
9721
+ startTime: null
9722
+ }));
9723
+ return snapshotFromFacts(facts, "tasklist");
9724
+ } catch {
9725
+ return null;
9726
+ }
9727
+ }
9728
+ function readPosixProcessSnapshot() {
9729
+ const output = execProcessList(rpcProcessListExecFileSync, "ps", ["-axo", "pid=,command="]);
9730
+ const facts = [];
9731
+ for (const line of output.split(/\r?\n/)) {
9732
+ const match = /^\s*(\d+)\s+(.+)$/.exec(line);
9733
+ if (!match)
9734
+ continue;
9735
+ const pid = Number(match[1]);
9736
+ if (!Number.isInteger(pid) || pid <= 0)
9737
+ continue;
9738
+ facts.push({
9739
+ pid,
9740
+ parentPid: null,
9741
+ commandLine: match[2],
9742
+ imageName: executableName(commandTokens(match[2])[0]),
9743
+ startTime: null
9744
+ });
9745
+ }
9746
+ return snapshotFromFacts(facts, "ps");
9747
+ }
9748
+ function readPosixParentPid(pid) {
9749
+ try {
9750
+ const output = execProcessList(rpcProcessListExecFileSync, "ps", [
9751
+ "-o",
9752
+ "ppid=",
9753
+ "-p",
9754
+ String(pid)
9755
+ ]);
9756
+ const match = /^\s*(\d+)\s*$/.exec(output);
9757
+ if (!match)
9758
+ return null;
9759
+ const ppid = Number(match[1]);
9760
+ return Number.isInteger(ppid) && ppid > 0 ? ppid : null;
9761
+ } catch {
9762
+ return null;
9763
+ }
9764
+ }
9765
+ function collectAncestorPids(selfPid, parentByPid) {
9766
+ const ancestors = new Set;
9767
+ let current = selfPid;
9768
+ for (let depth = 0;depth < MAX_ANCESTOR_WALK_DEPTH; depth += 1) {
9769
+ let ppid = null;
9770
+ if (parentByPid.has(current)) {
9771
+ ppid = parentByPid.get(current) ?? null;
9772
+ } else if (rpcIdentityPlatform !== "win32") {
9773
+ ppid = readPosixParentPid(current);
9774
+ if (ppid == null && current === process.pid && process.ppid > 0) {
9775
+ ppid = process.ppid;
9776
+ }
9777
+ } else if (current === process.pid && process.ppid > 0) {
9778
+ ppid = process.ppid;
9779
+ } else {
9780
+ break;
9781
+ }
9782
+ if (ppid == null || ppid <= 0 || ppid === current || ancestors.has(ppid))
9783
+ break;
9784
+ ancestors.add(ppid);
9785
+ current = ppid;
9786
+ }
9787
+ return ancestors;
9788
+ }
9789
+ function classifyLivePiSnapshot(snapshot) {
9790
+ const ancestors = collectAncestorPids(process.pid, snapshot.parentByPid);
9791
+ const processIds = new Set;
9792
+ const inconclusivePids = new Set;
9793
+ const skippedAncestorPids = [];
9794
+ for (const fact of snapshot.facts) {
9795
+ if (fact.pid === process.pid)
9796
+ continue;
9797
+ const command = fact.commandLine ?? fact.imageName ?? "";
9798
+ const looksLikeHarness = commandHasPiHarnessArc(command) || commandLooksLikePiImage(command);
9799
+ if (!looksLikeHarness)
9800
+ continue;
9801
+ if (ancestors.has(fact.pid)) {
9802
+ skippedAncestorPids.push(fact.pid);
9803
+ log(`[magic-context] Pi process scan: skipping ancestor PID ${fact.pid} (session launcher shim)`);
9804
+ continue;
9805
+ }
9806
+ if (commandHasPiHarnessArc(command)) {
9807
+ processIds.add(fact.pid);
9808
+ continue;
9809
+ }
9810
+ inconclusivePids.add(fact.pid);
9811
+ log(`[magic-context] Pi process scan: PID ${fact.pid} command line is ambiguous (image-name or missing Pi/OMP arc); treating as inconclusive`);
9812
+ }
9813
+ skippedAncestorPids.sort((left, right) => left - right);
9814
+ const verified = [...processIds].sort((left, right) => left - right);
9815
+ const inconclusive = [...inconclusivePids].sort((left, right) => left - right);
9816
+ if (verified.length === 0 && inconclusive.length > 0) {
9817
+ return {
9818
+ state: "inconclusive",
9819
+ processIds: [],
9820
+ inconclusivePids: inconclusive,
9821
+ ...skippedAncestorPids.length > 0 ? { skippedAncestorPids } : {}
9822
+ };
9823
+ }
9824
+ return {
9825
+ state: "known",
9826
+ processIds: verified,
9827
+ ...inconclusive.length > 0 ? { inconclusivePids: inconclusive } : {},
9828
+ ...skippedAncestorPids.length > 0 ? { skippedAncestorPids } : {}
9829
+ };
9830
+ }
9572
9831
  function inspectLivePiProcesses() {
9573
9832
  if (false) {}
9574
9833
  try {
9575
- const isWindows = rpcIdentityPlatform === "win32";
9576
- const output = String(rpcProcessListExecFileSync(isWindows ? "tasklist" : "ps", isWindows ? ["/FO", "CSV"] : ["-axo", "pid=,command="], {
9577
- encoding: "utf8",
9578
- timeout: PS_PROBE_TIMEOUT_MS,
9579
- stdio: ["ignore", "pipe", "pipe"]
9580
- }));
9581
- const pids = new Set;
9582
- if (isWindows) {
9583
- const entries = parseTasklistOutput(output);
9584
- if (entries === null) {
9834
+ if (rpcIdentityPlatform === "win32") {
9835
+ const cim = tryReadWindowsCimSnapshot(rpcProcessListExecFileSync);
9836
+ const snapshot = cim ?? tryReadWindowsTasklistSnapshot();
9837
+ if (!snapshot) {
9585
9838
  return {
9586
9839
  state: "unreadable",
9587
9840
  processIds: [],
9588
- error: "tasklist output unavailable"
9841
+ error: "process list unavailable"
9589
9842
  };
9590
9843
  }
9591
- for (const entry of entries) {
9592
- if (entry.pid === process.pid)
9593
- continue;
9594
- if (commandLooksLikePi(entry.command))
9595
- pids.add(entry.pid);
9596
- }
9597
- } else {
9598
- for (const line of output.split(/\r?\n/)) {
9599
- const match = /^\s*(\d+)\s+(.+)$/.exec(line);
9600
- if (!match)
9601
- continue;
9602
- const pid = Number(match[1]);
9603
- if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid)
9604
- continue;
9605
- if (commandLooksLikePi(match[2]))
9606
- pids.add(pid);
9607
- }
9844
+ rememberWindowsProcessFacts(snapshot.facts);
9845
+ return classifyLivePiSnapshot(snapshot);
9608
9846
  }
9609
- return { state: "known", processIds: [...pids].sort((left, right) => left - right) };
9847
+ return classifyLivePiSnapshot(readPosixProcessSnapshot());
9610
9848
  } catch (error) {
9611
9849
  return {
9612
9850
  state: "unreadable",
@@ -9842,6 +10080,135 @@ function ensureContextStoreUuid(db) {
9842
10080
  var MAX_AUTHORITY_SEED_FRAME_BYTES = 900 * 1024;
9843
10081
  var mirrorFlights = new WeakMap;
9844
10082
 
10083
+ // ../plugin/src/features/magic-context/message-fts-rowid-map.ts
10084
+ import { createHash as createHash3 } from "node:crypto";
10085
+ var MESSAGE_FTS_ROWID_MAP_BACKFILL_BATCH_SIZE = 500;
10086
+ var BACKFILL_STATE_ID = 1;
10087
+ var EMPTY_INDEX_CONTENT_HASH = createHash3("sha256").update("").digest("hex");
10088
+ var upsertMapStatements = new WeakMap;
10089
+ var rangeReadyStatements = new WeakMap;
10090
+ var activeBackfills = new WeakMap;
10091
+ function getUpsertMapStatement(db) {
10092
+ let statement = upsertMapStatements.get(db);
10093
+ if (!statement) {
10094
+ statement = db.prepare(`INSERT INTO message_fts_rowid_map (session_id, message_ordinal, fts_rowid)
10095
+ VALUES (?, ?, ?)
10096
+ ON CONFLICT(session_id, message_ordinal) DO UPDATE SET
10097
+ fts_rowid = excluded.fts_rowid`);
10098
+ upsertMapStatements.set(db, statement);
10099
+ }
10100
+ return statement;
10101
+ }
10102
+ function getBackfillState(db) {
10103
+ const row = db.prepare(`SELECT watermark_rowid AS watermarkRowid, completed
10104
+ FROM message_fts_rowid_map_backfill_state
10105
+ WHERE id = ?`).get(BACKFILL_STATE_ID);
10106
+ return {
10107
+ processed: 0,
10108
+ watermarkRowid: typeof row?.watermarkRowid === "number" && Number.isSafeInteger(row.watermarkRowid) ? row.watermarkRowid : 0,
10109
+ completed: row?.completed === 1
10110
+ };
10111
+ }
10112
+ function recordMessageFtsRowid(db, sessionId, messageOrdinal, ftsRowid) {
10113
+ const numericRowid = Number(ftsRowid);
10114
+ if (!Number.isSafeInteger(numericRowid) || numericRowid <= 0) {
10115
+ throw new Error(`invalid message FTS rowid: ${String(ftsRowid)}`);
10116
+ }
10117
+ getUpsertMapStatement(db).run(sessionId, messageOrdinal, numericRowid);
10118
+ }
10119
+ function backfillMessageFtsRowidMapBatch(db, batchSize = MESSAGE_FTS_ROWID_MAP_BACKFILL_BATCH_SIZE) {
10120
+ const boundedBatchSize = Math.max(1, Math.floor(batchSize));
10121
+ let progress = {
10122
+ processed: 0,
10123
+ watermarkRowid: 0,
10124
+ completed: false
10125
+ };
10126
+ db.transaction(() => {
10127
+ const state = getBackfillState(db);
10128
+ if (state.completed) {
10129
+ progress = state;
10130
+ return;
10131
+ }
10132
+ const rows = db.prepare(`SELECT rowid AS ftsRowid,
10133
+ session_id AS sessionId,
10134
+ message_ordinal AS messageOrdinal
10135
+ FROM message_history_fts
10136
+ WHERE rowid > ?
10137
+ ORDER BY rowid ASC
10138
+ LIMIT ?`).all(state.watermarkRowid, boundedBatchSize);
10139
+ let watermarkRowid = state.watermarkRowid;
10140
+ for (const row of rows) {
10141
+ const ftsRowid = Number(row.ftsRowid);
10142
+ const messageOrdinal = Number(row.messageOrdinal);
10143
+ if (Number.isSafeInteger(ftsRowid) && ftsRowid > watermarkRowid) {
10144
+ watermarkRowid = ftsRowid;
10145
+ }
10146
+ if (typeof row.sessionId === "string" && Number.isSafeInteger(messageOrdinal) && messageOrdinal >= 0 && Number.isSafeInteger(ftsRowid) && ftsRowid > 0) {
10147
+ recordMessageFtsRowid(db, row.sessionId, messageOrdinal, ftsRowid);
10148
+ }
10149
+ }
10150
+ const completed = rows.length < boundedBatchSize;
10151
+ db.prepare(`UPDATE message_fts_rowid_map_backfill_state
10152
+ SET watermark_rowid = ?, completed = ?, updated_at = ?
10153
+ WHERE id = ?`).run(watermarkRowid, completed ? 1 : 0, Date.now(), BACKFILL_STATE_ID);
10154
+ progress = {
10155
+ processed: rows.length,
10156
+ watermarkRowid,
10157
+ completed
10158
+ };
10159
+ })();
10160
+ return progress;
10161
+ }
10162
+ async function runMessageFtsRowidMapBackfill(db) {
10163
+ for (;; ) {
10164
+ const progress = backfillMessageFtsRowidMapBatch(db);
10165
+ if (progress.completed)
10166
+ return;
10167
+ await new Promise((resolve2) => setTimeout(resolve2, 0));
10168
+ }
10169
+ }
10170
+ function startMessageFtsRowidMapBackfill(db) {
10171
+ const active = activeBackfills.get(db);
10172
+ if (active)
10173
+ return active;
10174
+ const run = runMessageFtsRowidMapBackfill(db).finally(() => {
10175
+ activeBackfills.delete(db);
10176
+ });
10177
+ activeBackfills.set(db, run);
10178
+ return run;
10179
+ }
10180
+ function messageFtsOrdinalRangeIsMapped(db, sessionId, startOrdinal, endOrdinal) {
10181
+ if (endOrdinal < startOrdinal)
10182
+ return true;
10183
+ if (getBackfillState(db).completed)
10184
+ return true;
10185
+ let statement = rangeReadyStatements.get(db);
10186
+ if (!statement) {
10187
+ statement = db.prepare(`SELECT COUNT(DISTINCT source.message_ordinal) AS sourceOrdinalCount,
10188
+ COUNT(DISTINCT CASE
10189
+ WHEN source.role IN ('user', 'assistant')
10190
+ AND source.normalized_content_hash != ?
10191
+ THEN source.message_ordinal
10192
+ END) AS expectedMapCount,
10193
+ COUNT(DISTINCT CASE
10194
+ WHEN source.role IN ('user', 'assistant')
10195
+ AND source.normalized_content_hash != ?
10196
+ AND map.fts_rowid IS NOT NULL
10197
+ THEN source.message_ordinal
10198
+ END) AS mappedCount
10199
+ FROM message_history_source AS source
10200
+ LEFT JOIN message_fts_rowid_map AS map
10201
+ ON map.session_id = source.session_id
10202
+ AND map.message_ordinal = source.message_ordinal
10203
+ WHERE source.session_id = ?
10204
+ AND source.message_ordinal BETWEEN ? AND ?`);
10205
+ rangeReadyStatements.set(db, statement);
10206
+ }
10207
+ const row = statement.get(EMPTY_INDEX_CONTENT_HASH, EMPTY_INDEX_CONTENT_HASH, sessionId, startOrdinal, endOrdinal);
10208
+ const ordinalCount = endOrdinal - startOrdinal + 1;
10209
+ return row?.sourceOrdinalCount === ordinalCount && row.expectedMapCount === row.mappedCount;
10210
+ }
10211
+
9845
10212
  // ../plugin/src/hooks/magic-context/compartment-parser.ts
9846
10213
  var COMPARTMENT_REGEX = /<compartment\s+([^>]*?)\s*>(.*?)<\/compartment>/gs;
9847
10214
  var ATTR_START_REGEX = /\bstart="(\d+)"/;
@@ -10074,6 +10441,7 @@ function healAllNullColumns(db) {
10074
10441
  ["stale_reduce_stripped_ids", ""],
10075
10442
  ["processed_image_stripped_ids", ""],
10076
10443
  ["merged_reasoning_stripped_ids", ""],
10444
+ ["thinking_binding_recovery_target", ""],
10077
10445
  ["trailing_blank_decisions", ""],
10078
10446
  ["memory_block_cache", ""],
10079
10447
  ["memory_block_ids", ""],
@@ -10125,7 +10493,7 @@ function healMissingMemoryBlockIds(db, columns) {
10125
10493
  }
10126
10494
 
10127
10495
  // ../plugin/src/features/magic-context/workspaces.ts
10128
- import { createHash as createHash3 } from "node:crypto";
10496
+ import { createHash as createHash4 } from "node:crypto";
10129
10497
 
10130
10498
  // ../plugin/src/features/magic-context/memory/constants.ts
10131
10499
  var V2_MEMORY_CATEGORIES = [
@@ -10362,7 +10730,7 @@ function computeWorkspaceEpochFingerprint(db, identities) {
10362
10730
  const canonical = uniqueSorted(identities.filter((identity) => identity.length > 0));
10363
10731
  const epochs = getEpochMap(db, canonical);
10364
10732
  const shareCategories = selectWorkspaceShareCategories(db, canonical);
10365
- const hash = createHash3("sha256");
10733
+ const hash = createHash4("sha256");
10366
10734
  hash.update("share_categories", "utf8");
10367
10735
  hash.update("\x00");
10368
10736
  hash.update(shareCategories === null ? "NO_WORKSPACE" : JSON.stringify(shareCategories), "utf8");
@@ -12587,6 +12955,30 @@ var MIGRATIONS = [
12587
12955
  return;
12588
12956
  ensureColumn(db, "memory_verifications", "mapping_origin", "TEXT NOT NULL DEFAULT 'mapper'");
12589
12957
  }
12958
+ },
12959
+ {
12960
+ version: 83,
12961
+ description: "add indexed rowid access for message FTS content",
12962
+ up(db) {
12963
+ db.exec(`
12964
+ CREATE TABLE IF NOT EXISTS message_fts_rowid_map (
12965
+ session_id TEXT NOT NULL,
12966
+ message_ordinal INTEGER NOT NULL,
12967
+ fts_rowid INTEGER NOT NULL,
12968
+ PRIMARY KEY(session_id, message_ordinal)
12969
+ );
12970
+
12971
+ CREATE TABLE IF NOT EXISTS message_fts_rowid_map_backfill_state (
12972
+ id INTEGER PRIMARY KEY CHECK(id = 1),
12973
+ watermark_rowid INTEGER NOT NULL DEFAULT 0,
12974
+ completed INTEGER NOT NULL DEFAULT 0 CHECK(completed IN (0, 1)),
12975
+ updated_at INTEGER NOT NULL DEFAULT 0
12976
+ );
12977
+ INSERT OR IGNORE INTO message_fts_rowid_map_backfill_state
12978
+ (id, watermark_rowid, completed, updated_at)
12979
+ VALUES (1, 0, 0, 0);
12980
+ `);
12981
+ }
12590
12982
  }
12591
12983
  ];
12592
12984
  var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
@@ -13025,7 +13417,7 @@ function getSchemaFenceRejection() {
13025
13417
  function getMigrationOnOpenRefusal() {
13026
13418
  return lastMigrationOnOpenRefusal;
13027
13419
  }
13028
- var LATEST_SUPPORTED_VERSION = 82;
13420
+ var LATEST_SUPPORTED_VERSION = 83;
13029
13421
  var PERMISSIONS_ENFORCEABLE = process.platform !== "win32";
13030
13422
  var defaultStoragePermissionFs = { chmodSync, mkdirSync: mkdirSync2 };
13031
13423
  var storagePermissionFs = defaultStoragePermissionFs;
@@ -13324,13 +13716,18 @@ function createPiBlockingProcess(pid) {
13324
13716
  function formatInconclusiveOpenCodeMigrationWarning(dbPath, pids) {
13325
13717
  return `[magic-context] storage warning: continuing migration for ${dbPath}; OpenCode server PID ${pids.join(", ")} was not confirmed because its liveness or identity check could not run. This commonly means an OS sandbox denied kill(0) or ps. No live OpenCode server was confirmed.`;
13326
13718
  }
13327
- function logInconclusiveMigrationProbes(dbPath, discovery, piProbeState) {
13719
+ function formatInconclusivePiMigrationWarning(dbPath, pids) {
13720
+ return `[magic-context] storage warning: continuing migration for ${dbPath}; Pi/OMP PID ${pids.join(", ")} was not confirmed as a live harness because the process image or command line was ambiguous. No live Pi harness was confirmed.`;
13721
+ }
13722
+ function logInconclusiveMigrationProbes(dbPath, discovery, piDiscovery) {
13328
13723
  const uncertainPids = discovery.inconclusivePids ?? [];
13329
13724
  if (uncertainPids.length > 0) {
13330
13725
  log(formatInconclusiveOpenCodeMigrationWarning(dbPath, uncertainPids));
13331
13726
  }
13332
- if (piProbeState === "unreadable") {
13727
+ if (piDiscovery.state === "unreadable") {
13333
13728
  log(`[magic-context] storage warning: continuing migration for ${dbPath}; the Pi/OMP process-list probe could not run, which commonly means an OS sandbox denied ps. No live Pi harness was confirmed.`);
13729
+ } else if ((piDiscovery.inconclusivePids?.length ?? 0) > 0) {
13730
+ log(formatInconclusivePiMigrationWarning(dbPath, piDiscovery.inconclusivePids ?? []));
13334
13731
  }
13335
13732
  }
13336
13733
  function isDefaultSharedDatabasePath(dbPath) {
@@ -13365,7 +13762,7 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
13365
13762
  const blockingProcesses = [...serverProcesses, ...piPids.map(createPiBlockingProcess)];
13366
13763
  if ((discovery.state === "absent" || discovery.state === "stale" || discovery.state === "inconclusive") && piPids.length === 0) {
13367
13764
  lastMigrationOnOpenRefusal = null;
13368
- logInconclusiveMigrationProbes(dbPath, discovery, piDiscovery.state);
13765
+ logInconclusiveMigrationProbes(dbPath, discovery, piDiscovery);
13369
13766
  return true;
13370
13767
  }
13371
13768
  const blockingPids = [...new Set([...discovery.serverPids, ...piPids])].sort((left, right) => left - right);
@@ -13412,17 +13809,20 @@ function finishDatabaseOpen(db, dbPath, explicitDbPath, latestSupportedVersion)
13412
13809
  }
13413
13810
  healWedgedChannel2Claims(db);
13414
13811
  if (!explicitDbPath) {
13415
- const runBackfill = () => {
13812
+ const runBackfills = () => {
13416
13813
  try {
13417
13814
  runToolOwnerBackfill(db);
13418
13815
  } catch (error) {
13419
13816
  log(`[magic-context] tool-owner backfill failed (continuing with lazy adoption fallback): ${getErrorMessage(error)}`);
13420
13817
  }
13818
+ startMessageFtsRowidMapBackfill(db).catch((error) => {
13819
+ log(`[magic-context] message FTS rowid-map backfill failed (will resume next startup): ${getErrorMessage(error)}`);
13820
+ });
13421
13821
  };
13422
13822
  if (bootQuietRemainingMs() > 0)
13423
- scheduleAfterBootQuiet(runBackfill);
13823
+ scheduleAfterBootQuiet(runBackfills);
13424
13824
  else
13425
- runBackfill();
13825
+ runBackfills();
13426
13826
  }
13427
13827
  setDatabase(db);
13428
13828
  loadToolDefinitionMeasurements(db);
@@ -13962,6 +14362,23 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
13962
14362
  tokenize='porter unicode61'
13963
14363
  );
13964
14364
 
14365
+ CREATE TABLE IF NOT EXISTS message_fts_rowid_map (
14366
+ session_id TEXT NOT NULL,
14367
+ message_ordinal INTEGER NOT NULL,
14368
+ fts_rowid INTEGER NOT NULL,
14369
+ PRIMARY KEY(session_id, message_ordinal)
14370
+ );
14371
+
14372
+ CREATE TABLE IF NOT EXISTS message_fts_rowid_map_backfill_state (
14373
+ id INTEGER PRIMARY KEY CHECK(id = 1),
14374
+ watermark_rowid INTEGER NOT NULL DEFAULT 0,
14375
+ completed INTEGER NOT NULL DEFAULT 0 CHECK(completed IN (0, 1)),
14376
+ updated_at INTEGER NOT NULL DEFAULT 0
14377
+ );
14378
+ INSERT OR IGNORE INTO message_fts_rowid_map_backfill_state
14379
+ (id, watermark_rowid, completed, updated_at)
14380
+ VALUES (1, 0, 0, 0);
14381
+
13965
14382
  CREATE TABLE IF NOT EXISTS message_history_index (
13966
14383
  session_id TEXT PRIMARY KEY,
13967
14384
  last_indexed_ordinal INTEGER NOT NULL DEFAULT 0,
@@ -14105,8 +14522,9 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
14105
14522
  cached_m0_system_hash TEXT,
14106
14523
  cached_m0_tool_set_hash TEXT,
14107
14524
  cached_m0_model_key TEXT,
14108
- cached_m0_project_identity TEXT,
14109
- cached_m0_last_baseline_end_message_id TEXT,
14525
+ cached_m0_project_identity TEXT,
14526
+ cached_m0_last_baseline_end_message_id TEXT,
14527
+ thinking_binding_recovery_target TEXT NOT NULL DEFAULT '',
14110
14528
  upgrade_reminded_at INTEGER,
14111
14529
  pi_stable_id_scheme INTEGER
14112
14530
  );
@@ -14328,6 +14746,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
14328
14746
  ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
14329
14747
  ensureColumn(db, "session_meta", "processed_image_stripped_ids", "TEXT DEFAULT ''");
14330
14748
  ensureColumn(db, "session_meta", "merged_reasoning_stripped_ids", "TEXT DEFAULT ''");
14749
+ ensureColumn(db, "session_meta", "thinking_binding_recovery_target", "TEXT DEFAULT ''");
14331
14750
  ensureColumn(db, "session_meta", "trailing_blank_decisions", "TEXT DEFAULT ''");
14332
14751
  ensureColumn(db, "compartments", "start_message_id", "TEXT DEFAULT ''");
14333
14752
  ensureColumn(db, "compartments", "end_message_id", "TEXT DEFAULT ''");
@@ -16069,7 +16488,7 @@ function clearPendingCompactionMarkerStateIf(db, sessionId, expected) {
16069
16488
  return result.changes > 0;
16070
16489
  }
16071
16490
  function isPendingPiCompactionMarker(value) {
16072
- return typeof value === "object" && value !== null && typeof value.firstKeptEntryId === "string" && typeof value.endMessageId === "string" && typeof value.ordinal === "number" && typeof value.tokensBefore === "number" && typeof value.summary === "string" && typeof value.publishedAt === "number";
16491
+ return typeof value === "object" && value !== null && (value.firstKeptEntryId === null || typeof value.firstKeptEntryId === "string") && typeof value.endMessageId === "string" && typeof value.ordinal === "number" && typeof value.tokensBefore === "number" && typeof value.summary === "string" && typeof value.publishedAt === "number";
16073
16492
  }
16074
16493
  function getPendingPiCompactionMarkerState(db, sessionId) {
16075
16494
  const row = db.prepare("SELECT pending_pi_compaction_marker_state FROM session_meta WHERE session_id = ?").get(sessionId);
@@ -16284,15 +16703,38 @@ var SESSION_SCOPED_TABLES = [
16284
16703
  { table: "embedding_measurement_corpus" },
16285
16704
  { table: "pending_session_cleanup", harnessScoped: true },
16286
16705
  { table: "message_history_fts" },
16706
+ { table: "message_fts_rowid_map" },
16287
16707
  { table: "message_history_source", harnessScoped: true },
16288
16708
  { table: "message_history_index", harnessScoped: true },
16289
16709
  { table: "lkg_slots" }
16290
16710
  ];
16291
- function deleteSessionScopedRows(db, sessionIds, harness) {
16711
+ function deleteSessionScopedRows(db, sessionIds, harness, options = {}) {
16292
16712
  if (sessionIds.length === 0)
16293
- return;
16294
- const placeholders2 = sessionIds.map(() => "?").join(", ");
16713
+ return 0;
16714
+ let deletableSessionIds = [...sessionIds];
16715
+ if (options.rustModuleCleanupAcknowledged !== true) {
16716
+ const placeholders3 = sessionIds.map(() => "?").join(", ");
16717
+ const harnessPredicate = harness === undefined ? "" : " AND harness = ?";
16718
+ const protectedRows = db.prepare(`SELECT session_id
16719
+ FROM pending_session_cleanup
16720
+ WHERE session_id IN (${placeholders3})
16721
+ AND harness LIKE '%:rust'${harnessPredicate}`).all(...sessionIds, ...harness === undefined ? [] : [`${harness}:rust`]);
16722
+ const protectedSessionIds = new Set(protectedRows.map((row) => row.session_id));
16723
+ deletableSessionIds = sessionIds.filter((sessionId) => !protectedSessionIds.has(sessionId));
16724
+ }
16725
+ if (deletableSessionIds.length === 0)
16726
+ return 0;
16727
+ const placeholders2 = deletableSessionIds.map(() => "?").join(", ");
16295
16728
  for (const definition of SESSION_SCOPED_TABLES) {
16729
+ if (definition.table === "message_history_fts") {
16730
+ db.prepare(`DELETE FROM message_history_fts
16731
+ WHERE rowid IN (
16732
+ SELECT fts_rowid
16733
+ FROM message_fts_rowid_map
16734
+ WHERE session_id IN (${placeholders2})
16735
+ )`).run(...deletableSessionIds);
16736
+ continue;
16737
+ }
16296
16738
  const predicates = [`session_id IN (${placeholders2})`];
16297
16739
  if (definition.extraPredicate)
16298
16740
  predicates.push(definition.extraPredicate);
@@ -16301,10 +16743,11 @@ function deleteSessionScopedRows(db, sessionIds, harness) {
16301
16743
  predicates.push("harness = ?");
16302
16744
  const statement = db.prepare(`DELETE FROM ${definition.table} WHERE ${predicates.join(" AND ")}`);
16303
16745
  if (bindHarness)
16304
- statement.run(...sessionIds, harness);
16746
+ statement.run(...deletableSessionIds, harness);
16305
16747
  else
16306
- statement.run(...sessionIds);
16748
+ statement.run(...deletableSessionIds);
16307
16749
  }
16750
+ return deletableSessionIds.length;
16308
16751
  }
16309
16752
 
16310
16753
  // ../plugin/src/features/magic-context/storage-meta-session.ts
@@ -16405,8 +16848,15 @@ function advanceToolReclaimWatermark(db, sessionId, maxTagNumber) {
16405
16848
  db.prepare("UPDATE session_meta SET tool_reclaim_watermark = MAX(COALESCE(tool_reclaim_watermark, 0), ?) WHERE session_id = ?").run(maxTagNumber, sessionId);
16406
16849
  })();
16407
16850
  }
16851
+ function rustCleanupHarness() {
16852
+ return `${getHarness()}:rust`;
16853
+ }
16408
16854
  function retryPendingSessionCleanups(db, limit = 200) {
16409
- const rows = db.prepare("SELECT session_id FROM pending_session_cleanup ORDER BY requested_at ASC, session_id ASC LIMIT ?").all(Math.max(1, Math.floor(limit)));
16855
+ const rows = db.prepare(`SELECT session_id
16856
+ FROM pending_session_cleanup
16857
+ WHERE harness NOT LIKE '%:rust'
16858
+ ORDER BY requested_at ASC, session_id ASC
16859
+ LIMIT ?`).all(Math.max(1, Math.floor(limit)));
16410
16860
  const failedSessionIds = [];
16411
16861
  let cleared = 0;
16412
16862
  for (const row of rows) {
@@ -16420,15 +16870,42 @@ function retryPendingSessionCleanups(db, limit = 200) {
16420
16870
  }
16421
16871
  return { attempted: rows.length, cleared, failedSessionIds };
16422
16872
  }
16423
- function clearSession(db, sessionId) {
16873
+ async function retryPendingRustSessionCleanupsForProject(db, projectPath, deleteSession, limit = 200) {
16874
+ const harness = getHarness();
16875
+ const rows = db.prepare(`SELECT pending.session_id
16876
+ FROM pending_session_cleanup pending
16877
+ JOIN session_projects projects
16878
+ ON projects.session_id = pending.session_id
16879
+ AND projects.harness = ?
16880
+ WHERE pending.harness = ?
16881
+ AND projects.project_path = ?
16882
+ ORDER BY pending.requested_at ASC, pending.session_id ASC
16883
+ LIMIT ?`).all(harness, rustCleanupHarness(), projectPath, Math.max(1, Math.floor(limit)));
16884
+ const failedSessionIds = [];
16885
+ let cleared = 0;
16886
+ for (const row of rows) {
16887
+ try {
16888
+ db.prepare("UPDATE pending_session_cleanup SET last_attempt_at = ? WHERE session_id = ?").run(Date.now(), row.session_id);
16889
+ await deleteSession(row.session_id);
16890
+ clearSession(db, row.session_id, true);
16891
+ cleared += 1;
16892
+ } catch {
16893
+ failedSessionIds.push(row.session_id);
16894
+ }
16895
+ }
16896
+ return { attempted: rows.length, cleared, failedSessionIds };
16897
+ }
16898
+ function clearSession(db, sessionId, rustModuleCleanupAcknowledged = false) {
16424
16899
  const transactionStartedAt = performance.now();
16425
16900
  db.transaction(() => {
16426
- deleteSessionScopedRows(db, [sessionId]);
16901
+ deleteSessionScopedRows(db, [sessionId], undefined, {
16902
+ rustModuleCleanupAcknowledged
16903
+ });
16427
16904
  })();
16428
16905
  logSlowWriteTransaction("clear-session", transactionStartedAt);
16429
16906
  }
16430
16907
  // ../plugin/src/hooks/magic-context/todo-view.ts
16431
- import { createHash as createHash4 } from "node:crypto";
16908
+ import { createHash as createHash5 } from "node:crypto";
16432
16909
  var TODO_STATUS_PENDING = "pending";
16433
16910
  var TODO_STATUS_IN_PROGRESS = "in_progress";
16434
16911
  var TODO_STATUS_COMPLETED = "completed";
@@ -16496,7 +16973,7 @@ function buildSyntheticTodoPart(stateJson) {
16496
16973
  };
16497
16974
  }
16498
16975
  function computeSyntheticCallId(stateJson) {
16499
- const hash = createHash4("sha256").update(stateJson).digest("hex").slice(0, 16);
16976
+ const hash = createHash5("sha256").update(stateJson).digest("hex").slice(0, 16);
16500
16977
  return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
16501
16978
  }
16502
16979
  function parseTodoState(stateJson) {
@@ -16757,7 +17234,7 @@ function escapeXmlContent(s) {
16757
17234
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
16758
17235
  }
16759
17236
  // ../plugin/src/features/magic-context/message-index.ts
16760
- import { createHash as createHash5 } from "node:crypto";
17237
+ import { createHash as createHash6 } from "node:crypto";
16761
17238
 
16762
17239
  // ../plugin/src/hooks/magic-context/read-session-raw.ts
16763
17240
  function isRawMessageRow(row) {
@@ -17988,6 +18465,9 @@ var upsertMessageSourceStatements = new WeakMap;
17988
18465
  var deleteMessageSourceStatements = new WeakMap;
17989
18466
  var deleteMessageSourceRangeStatements = new WeakMap;
17990
18467
  var deleteMessageFtsStatements = new WeakMap;
18468
+ var deleteFtsMapStatements = new WeakMap;
18469
+ var deleteFtsMapRangeStatements = new WeakMap;
18470
+ var deleteMessageFtsMapStatements = new WeakMap;
17991
18471
  function normalizeIndexText(text) {
17992
18472
  return text.replace(/\s+/g, " ").trim();
17993
18473
  }
@@ -18026,7 +18506,12 @@ function getUpsertDirtyFloorStatement(db) {
18026
18506
  function getDeleteFtsRangeStatement(db) {
18027
18507
  let stmt = deleteFtsRangeStatements.get(db);
18028
18508
  if (!stmt) {
18029
- stmt = db.prepare("DELETE FROM message_history_fts WHERE session_id = ? AND CAST(message_ordinal AS INTEGER) BETWEEN ? AND ?");
18509
+ stmt = db.prepare(`DELETE FROM message_history_fts
18510
+ WHERE rowid IN (
18511
+ SELECT fts_rowid
18512
+ FROM message_fts_rowid_map
18513
+ WHERE session_id = ? AND message_ordinal BETWEEN ? AND ?
18514
+ )`);
18030
18515
  deleteFtsRangeStatements.set(db, stmt);
18031
18516
  }
18032
18517
  return stmt;
@@ -18034,7 +18519,12 @@ function getDeleteFtsRangeStatement(db) {
18034
18519
  function getCountIndexedMessageStatement(db) {
18035
18520
  let stmt = countIndexedMessageStatements.get(db);
18036
18521
  if (!stmt) {
18037
- stmt = db.prepare("SELECT COUNT(*) AS count FROM message_history_fts WHERE session_id = ? AND message_id = ?");
18522
+ stmt = db.prepare(`SELECT COUNT(*) AS count
18523
+ FROM message_history_source AS source
18524
+ JOIN message_fts_rowid_map AS map
18525
+ ON map.session_id = source.session_id
18526
+ AND map.message_ordinal = source.message_ordinal
18527
+ WHERE source.session_id = ? AND source.message_id = ?`);
18038
18528
  countIndexedMessageStatements.set(db, stmt);
18039
18529
  }
18040
18530
  return stmt;
@@ -18076,11 +18566,45 @@ function getDeleteMessageSourceRangeStatement(db) {
18076
18566
  function getDeleteMessageFtsStatement(db) {
18077
18567
  let stmt = deleteMessageFtsStatements.get(db);
18078
18568
  if (!stmt) {
18079
- stmt = db.prepare("DELETE FROM message_history_fts WHERE session_id = ? AND message_id = ?");
18569
+ stmt = db.prepare(`DELETE FROM message_history_fts
18570
+ WHERE rowid IN (
18571
+ SELECT map.fts_rowid
18572
+ FROM message_history_source AS source
18573
+ JOIN message_fts_rowid_map AS map
18574
+ ON map.session_id = source.session_id
18575
+ AND map.message_ordinal = source.message_ordinal
18576
+ WHERE source.session_id = ? AND source.message_id = ?
18577
+ )`);
18080
18578
  deleteMessageFtsStatements.set(db, stmt);
18081
18579
  }
18082
18580
  return stmt;
18083
18581
  }
18582
+ function getDeleteFtsMapRangeStatement(db) {
18583
+ let stmt = deleteFtsMapRangeStatements.get(db);
18584
+ if (!stmt) {
18585
+ stmt = db.prepare("DELETE FROM message_fts_rowid_map WHERE session_id = ? AND message_ordinal BETWEEN ? AND ?");
18586
+ deleteFtsMapRangeStatements.set(db, stmt);
18587
+ }
18588
+ return stmt;
18589
+ }
18590
+ function getDeleteMessageFtsMapStatement(db) {
18591
+ let stmt = deleteMessageFtsMapStatements.get(db);
18592
+ if (!stmt) {
18593
+ stmt = db.prepare(`DELETE FROM message_fts_rowid_map
18594
+ WHERE session_id = ?
18595
+ AND message_ordinal = (
18596
+ SELECT message_ordinal
18597
+ FROM message_history_source
18598
+ WHERE session_id = ? AND message_id = ?
18599
+ )`);
18600
+ deleteMessageFtsMapStatements.set(db, stmt);
18601
+ }
18602
+ return stmt;
18603
+ }
18604
+ function insertMessageFtsRow(db, sessionId, messageOrdinal, messageId, role, content) {
18605
+ const result = getInsertMessageStatement(db).run(sessionId, messageOrdinal, messageId, role, content);
18606
+ recordMessageFtsRowid(db, sessionId, messageOrdinal, result.lastInsertRowid);
18607
+ }
18084
18608
  function normalizeSourceVersion(version) {
18085
18609
  if (typeof version === "number")
18086
18610
  return `number:${version}`;
@@ -18093,7 +18617,7 @@ function getMessageSourceSnapshot(message) {
18093
18617
  return {
18094
18618
  ordinal: message.ordinal,
18095
18619
  sourceVersion: normalizeSourceVersion(message.version),
18096
- contentHash: createHash5("sha256").update(content).digest("hex"),
18620
+ contentHash: createHash6("sha256").update(content).digest("hex"),
18097
18621
  role: message.role,
18098
18622
  content
18099
18623
  };
@@ -18163,10 +18687,14 @@ function indexSingleMessageInTransaction(db, sessionId, message, now, dirtyFloor
18163
18687
  if (isMessageIndexSourceCurrent(db, sessionId, message)) {
18164
18688
  return false;
18165
18689
  }
18690
+ if (!messageFtsOrdinalRangeIsMapped(db, sessionId, message.ordinal, message.ordinal)) {
18691
+ return false;
18692
+ }
18166
18693
  getDeleteMessageFtsStatement(db).run(sessionId, message.id);
18694
+ getDeleteMessageFtsMapStatement(db).run(sessionId, sessionId, message.id);
18167
18695
  const content2 = setMessageSource(db, sessionId, message, now);
18168
18696
  if (content2.length > 0 && (message.role === "user" || message.role === "assistant")) {
18169
- getInsertMessageStatement(db).run(sessionId, message.ordinal, message.id, message.role, content2);
18697
+ insertMessageFtsRow(db, sessionId, message.ordinal, message.id, message.role, content2);
18170
18698
  }
18171
18699
  setIndexProgress(db, sessionId, currentWatermark, dirtyFloorBeforeAttempt === message.ordinal ? null : dirtyFloorBeforeAttempt, now);
18172
18700
  return true;
@@ -18177,7 +18705,7 @@ function indexSingleMessageInTransaction(db, sessionId, message, now, dirtyFloor
18177
18705
  const content = setMessageSource(db, sessionId, message, now);
18178
18706
  let inserted = false;
18179
18707
  if (content.length > 0 && (message.role === "user" || message.role === "assistant") && !isMessageAlreadyIndexed(db, sessionId, message.id)) {
18180
- getInsertMessageStatement(db).run(sessionId, message.ordinal, message.id, message.role, content);
18708
+ insertMessageFtsRow(db, sessionId, message.ordinal, message.id, message.role, content);
18181
18709
  inserted = true;
18182
18710
  }
18183
18711
  setIndexProgress(db, sessionId, message.ordinal, dirtyFloorBeforeAttempt === message.ordinal ? null : dirtyFloorBeforeAttempt, now);
@@ -18214,8 +18742,14 @@ function indexMessagesAfterOrdinal(db, sessionId, messages, _lastIndexedOrdinal,
18214
18742
  const currentWatermark = getLastIndexedOrdinal(db, sessionId);
18215
18743
  const dirtyFloor = getDirtyIndexFloor(db, sessionId);
18216
18744
  const effectiveWatermark = dirtyFloor === null ? currentWatermark : Math.min(currentWatermark, Math.max(0, dirtyFloor - 1));
18745
+ if (dirtyFloor !== null && dirtyFloor <= currentWatermark && !messageFtsOrdinalRangeIsMapped(db, sessionId, dirtyFloor, Math.min(currentWatermark, finalWatermark))) {
18746
+ db.exec("COMMIT");
18747
+ committed = true;
18748
+ return 0;
18749
+ }
18217
18750
  if (dirtyFloor !== null && dirtyFloor <= finalWatermark) {
18218
18751
  getDeleteFtsRangeStatement(db).run(sessionId, dirtyFloor, finalWatermark);
18752
+ getDeleteFtsMapRangeStatement(db).run(sessionId, dirtyFloor, finalWatermark);
18219
18753
  getDeleteMessageSourceRangeStatement(db).run(sessionId, dirtyFloor, finalWatermark);
18220
18754
  }
18221
18755
  const messagesByOrdinal = new Map;
@@ -18236,7 +18770,7 @@ function indexMessagesAfterOrdinal(db, sessionId, messages, _lastIndexedOrdinal,
18236
18770
  if (content.length === 0 || message.role !== "user" && message.role !== "assistant" || isMessageAlreadyIndexed(db, sessionId, message.id)) {
18237
18771
  continue;
18238
18772
  }
18239
- getInsertMessageStatement(db).run(sessionId, message.ordinal, message.id, message.role, content);
18773
+ insertMessageFtsRow(db, sessionId, message.ordinal, message.id, message.role, content);
18240
18774
  inserted += 1;
18241
18775
  }
18242
18776
  const missingFloor = coveredWatermark < finalWatermark ? coveredWatermark + 1 : null;
@@ -18330,8 +18864,7 @@ function sweepOrphanedOpenCodeMessageIndexes(db, openReadableOpenCodeDb, options
18330
18864
  )
18331
18865
  LIMIT 1`);
18332
18866
  const eligibleSessionIds = missingSessionIds.filter((sessionId) => stillEligible.get(sessionId, cutoff));
18333
- deleteSessionScopedRows(db, eligibleSessionIds, "opencode");
18334
- deleted = eligibleSessionIds.length;
18867
+ deleted = deleteSessionScopedRows(db, eligibleSessionIds, "opencode");
18335
18868
  persistMessageHistoryOrphanSweepState(db, nextCursor, completedAt);
18336
18869
  db.exec("COMMIT");
18337
18870
  committed = true;
@@ -18353,7 +18886,7 @@ function sweepOrphanedOpenCodeMessageIndexes(db, openReadableOpenCodeDb, options
18353
18886
  }
18354
18887
  }
18355
18888
  // ../plugin/src/features/magic-context/project-docs-hash.ts
18356
- import { createHash as createHash6 } from "node:crypto";
18889
+ import { createHash as createHash7 } from "node:crypto";
18357
18890
  import { lstatSync, readFileSync as readFileSync5, statSync as statSync4 } from "node:fs";
18358
18891
  import path2 from "node:path";
18359
18892
  var PROJECT_DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
@@ -18451,7 +18984,7 @@ function hashCanonicalPieces(hashPieces) {
18451
18984
  if (hashPieces.length === 0) {
18452
18985
  return "";
18453
18986
  }
18454
- return createHash6("sha256").update(hashPieces.join(PROJECT_DOCS_DELIMITER), "utf8").digest("hex");
18987
+ return createHash7("sha256").update(hashPieces.join(PROJECT_DOCS_DELIMITER), "utf8").digest("hex");
18455
18988
  }
18456
18989
  function readProjectDocsCanonical(projectDirectory) {
18457
18990
  const canonicalDirectory = path2.resolve(projectDirectory);
@@ -18722,10 +19255,10 @@ function copySessionStateForClone(db, sourceSessionId, destinationSessionId, fil
18722
19255
  });
18723
19256
  }
18724
19257
  // ../plugin/src/features/magic-context/storage-embedding-measurements.ts
18725
- import { createHash as createHash7 } from "node:crypto";
19258
+ import { createHash as createHash8 } from "node:crypto";
18726
19259
  function normalizedQueryHash(query) {
18727
19260
  const normalized = query.trim().replace(/\s+/g, " ").toLowerCase();
18728
- return createHash7("sha256").update(normalized).digest("hex");
19261
+ return createHash8("sha256").update(normalized).digest("hex");
18729
19262
  }
18730
19263
  var MEASUREMENT_CORPUS_SESSION_ROW_CAP = 2000;
18731
19264
  function recordEmbeddingMeasurement(db, input, cap = MEASUREMENT_CORPUS_SESSION_ROW_CAP) {
@@ -20096,7 +20629,10 @@ var getTagNumbersByMessageIdStatements = new WeakMap;
20096
20629
  var deleteTagsByMessageIdStatements = new WeakMap;
20097
20630
  var getMaxTagNumberBySessionStatements = new WeakMap;
20098
20631
  var getTagNumberByMessageIdStatements = new WeakMap;
20632
+ var getAssignableTagNumberByMessageIdStatements = new WeakMap;
20099
20633
  var hasPiFallbackMessageTagStatements = new WeakMap;
20634
+ var WHITESPACE_ASSISTANT_INERT_MESSAGE_PREFIX = "__mc_whitespace_assistant_inert__:";
20635
+ var WHITESPACE_ASSISTANT_INERT_FINGERPRINT_PREFIX = "mc:whitespace-assistant:";
20100
20636
  function getInsertTagStatement(db) {
20101
20637
  let stmt = insertTagStatements.get(db);
20102
20638
  if (!stmt) {
@@ -20322,6 +20858,25 @@ function getTagNumberByMessageIdStatement(db) {
20322
20858
  }
20323
20859
  return stmt;
20324
20860
  }
20861
+ function getAssignableTagNumberByMessageIdStatement(db) {
20862
+ let stmt = getAssignableTagNumberByMessageIdStatements.get(db);
20863
+ if (!stmt) {
20864
+ stmt = db.prepare(`SELECT tag_number FROM tags
20865
+ WHERE session_id = ?
20866
+ AND message_id = ?
20867
+ AND NOT (
20868
+ status = 'compacted'
20869
+ AND COALESCE(
20870
+ entry_fingerprint LIKE '${WHITESPACE_ASSISTANT_INERT_FINGERPRINT_PREFIX}%',
20871
+ 0
20872
+ ) = 1
20873
+ )
20874
+ ORDER BY tag_number ASC
20875
+ LIMIT 1`);
20876
+ getAssignableTagNumberByMessageIdStatements.set(db, stmt);
20877
+ }
20878
+ return stmt;
20879
+ }
20325
20880
  function isTagRow(row) {
20326
20881
  if (row === null || typeof row !== "object")
20327
20882
  return false;
@@ -20365,6 +20920,18 @@ function insertTag(db, sessionId, messageId, type, byteSize2, tagNumber, reasoni
20365
20920
  function updateTagStatus(db, sessionId, tagId, status) {
20366
20921
  getUpdateTagStatusStatement(db).run(status, sessionId, tagId);
20367
20922
  }
20923
+ function getInertWhitespaceAssistantTags(db, sessionId) {
20924
+ const rows = db.prepare(`SELECT tag_number AS tagNumber, entry_fingerprint AS entryFingerprint
20925
+ FROM tags
20926
+ WHERE session_id = ?
20927
+ AND type = 'message'
20928
+ AND status = 'compacted'
20929
+ AND entry_fingerprint LIKE ?`).all(sessionId, `${WHITESPACE_ASSISTANT_INERT_FINGERPRINT_PREFIX}%`);
20930
+ return rows.flatMap((row) => {
20931
+ const contentId = row.entryFingerprint.slice(WHITESPACE_ASSISTANT_INERT_FINGERPRINT_PREFIX.length);
20932
+ return contentId.length > 0 ? [{ tagNumber: row.tagNumber, contentId }] : [];
20933
+ });
20934
+ }
20368
20935
  function updateTagDropMode(db, sessionId, tagNumber, dropMode) {
20369
20936
  getUpdateTagDropModeStatement(db).run(dropMode, sessionId, tagNumber);
20370
20937
  }
@@ -20574,6 +21141,9 @@ function adoptPiFallbackToolOwnerTag(db, sessionId, tagNumber, callId, oldOwnerM
20574
21141
  };
20575
21142
  }
20576
21143
  function adoptPiFallbackMessageTag(db, sessionId, tagNumber, oldFallbackMessageId, newRealMessageId) {
21144
+ if (oldFallbackMessageId.startsWith(WHITESPACE_ASSISTANT_INERT_MESSAGE_PREFIX)) {
21145
+ return { action: "skipped" };
21146
+ }
20577
21147
  const survivor = getPiFallbackFoldTagRowByNumber(db, sessionId, tagNumber);
20578
21148
  if (survivor === null || survivor.type !== "message" || survivor.messageId !== oldFallbackMessageId) {
20579
21149
  return { action: "skipped" };
@@ -20612,6 +21182,10 @@ function getTagNumberByMessageId(db, sessionId, messageId) {
20612
21182
  const row = getTagNumberByMessageIdStatement(db).get(sessionId, messageId);
20613
21183
  return isTagNumberRow(row) ? row.tag_number : null;
20614
21184
  }
21185
+ function getAssignableTagNumberByMessageId(db, sessionId, messageId) {
21186
+ const row = getAssignableTagNumberByMessageIdStatement(db).get(sessionId, messageId);
21187
+ return isTagNumberRow(row) ? row.tag_number : null;
21188
+ }
20615
21189
  var getMinMessageTagNumberForRawIdStatements = new WeakMap;
20616
21190
  function isMinTagNumberRow(row) {
20617
21191
  return row !== null && typeof row === "object" && "m" in row;
@@ -20806,8 +21380,392 @@ var ERROR_CLASSES = new Set([
20806
21380
  "permission_denied",
20807
21381
  "unknown"
20808
21382
  ]);
21383
+ // ../plugin/src/shared/window-geometry.ts
21384
+ import { readFileSync as readFileSync6 } from "node:fs";
21385
+ import { join as join6 } from "node:path";
21386
+ var WINDOW_OVERLAY_SCHEMA = "fusiform-window-overlay/v1";
21387
+ var PROMPT_WALL_MARGIN = 4096;
21388
+ var PI_OUTPUT_FLOOR = 4096;
21389
+ var OPENCODE_OUTPUT_CAP = 32000;
21390
+ var MIN_PLAUSIBLE_CONTEXT_LIMIT = 1024;
21391
+ var OUTPUT_RESERVE_CAP_RATIO = 0.25;
21392
+ var PROVIDER_GEOMETRY = {
21393
+ anthropic: "shared_truncating",
21394
+ xai: "shared_truncating",
21395
+ google: "separate",
21396
+ "google-antigravity": "separate"
21397
+ };
21398
+ var GRADES = new Set([
21399
+ "provider_asserted_runtime",
21400
+ "measured",
21401
+ "provider_asserted_doc",
21402
+ "catalog",
21403
+ "unknown"
21404
+ ]);
21405
+ var UNITS = new Set(["provider", "estimate"]);
21406
+ var BOUNDARIES = new Set(["Observed", "Asserted", "Corrected"]);
21407
+ var UNKNOWN_REASONS = new Set([
21408
+ "placeholder_output_equals_context",
21409
+ "placeholder_zero",
21410
+ "never_measured",
21411
+ "not_single_valued_at_key",
21412
+ "retracted"
21413
+ ]);
21414
+ var NUMERIC_FACT_KEYS = new Set([
21415
+ "window.advertised",
21416
+ "window.enforced",
21417
+ "output.advertised",
21418
+ "output.enforced",
21419
+ "output.default"
21420
+ ]);
21421
+ var configuredOverlayPath;
21422
+ var loadedOverlayPath;
21423
+ var loadedOverlay;
21424
+ var geometryClampLogSeen = new Set;
21425
+ function isRecord2(value) {
21426
+ return typeof value === "object" && value !== null && !Array.isArray(value);
21427
+ }
21428
+ function isFinitePositive(value) {
21429
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
21430
+ }
21431
+ function scalarizeFact(value) {
21432
+ if (value.kind === "stated")
21433
+ return isFinitePositive(value.value) ? value.value : undefined;
21434
+ if (value.kind === "bracket") {
21435
+ return isFinitePositive(value.at_least) ? value.at_least : undefined;
21436
+ }
21437
+ return;
21438
+ }
21439
+ function parseFactValue(value) {
21440
+ if (!isRecord2(value) || typeof value.kind !== "string")
21441
+ return;
21442
+ if (value.kind === "stated") {
21443
+ if ((typeof value.value !== "number" || !Number.isFinite(value.value)) && typeof value.value !== "string") {
21444
+ return;
21445
+ }
21446
+ return { kind: "stated", value: value.value };
21447
+ }
21448
+ if (value.kind === "bracket") {
21449
+ const atLeast = value.at_least;
21450
+ const below = value.below;
21451
+ if (atLeast === undefined && below === undefined)
21452
+ return { kind: "bracket" };
21453
+ if (atLeast !== undefined && !isFinitePositive(atLeast))
21454
+ return;
21455
+ if (below !== undefined && !isFinitePositive(below))
21456
+ return;
21457
+ if (isFinitePositive(atLeast) && isFinitePositive(below) && below <= atLeast) {
21458
+ return;
21459
+ }
21460
+ return {
21461
+ kind: "bracket",
21462
+ ...isFinitePositive(atLeast) ? { at_least: atLeast } : {},
21463
+ ...isFinitePositive(below) ? { below } : {}
21464
+ };
21465
+ }
21466
+ if (value.kind === "unknown" && UNKNOWN_REASONS.has(value.why)) {
21467
+ return { kind: "unknown", why: value.why };
21468
+ }
21469
+ return;
21470
+ }
21471
+ function parseFact(key, value) {
21472
+ if (!isRecord2(value))
21473
+ return;
21474
+ const parsedValue = parseFactValue(value.value);
21475
+ if (!parsedValue || !GRADES.has(value.grade) || !UNITS.has(value.units) || !BOUNDARIES.has(value.boundary) || typeof value.source_ref !== "string" || value.source_ref.length === 0 || typeof value.observed_at !== "string" || value.observed_at.length === 0) {
21476
+ return;
21477
+ }
21478
+ if (NUMERIC_FACT_KEYS.has(key) && parsedValue.kind === "stated" && !isFinitePositive(parsedValue.value)) {
21479
+ return;
21480
+ }
21481
+ if (key === "geometry" && parsedValue.kind === "stated" && !["shared_upfront", "shared_truncating", "separate"].includes(String(parsedValue.value))) {
21482
+ return;
21483
+ }
21484
+ return {
21485
+ ...value,
21486
+ value: parsedValue,
21487
+ grade: value.grade,
21488
+ units: value.units,
21489
+ boundary: value.boundary,
21490
+ source_ref: value.source_ref,
21491
+ observed_at: value.observed_at
21492
+ };
21493
+ }
21494
+ function parseWindowOverlay(value) {
21495
+ if (!isRecord2(value)) {
21496
+ return { badCells: 0, refusal: "overlay root is not an object" };
21497
+ }
21498
+ if (value.schema !== WINDOW_OVERLAY_SCHEMA) {
21499
+ return {
21500
+ badCells: 0,
21501
+ refusal: `unrecognized schema ${JSON.stringify(value.schema)}`
21502
+ };
21503
+ }
21504
+ if (typeof value.generated_at !== "string" || !Array.isArray(value.minted_provider_ids) || !value.minted_provider_ids.every((id) => typeof id === "string" && id.length > 0) || !Array.isArray(value.cells)) {
21505
+ return { badCells: 0, refusal: "invalid v1 envelope" };
21506
+ }
21507
+ const cells = [];
21508
+ let badCells = 0;
21509
+ for (const rawCell of value.cells) {
21510
+ if (!isRecord2(rawCell) || typeof rawCell.provider_id !== "string" || rawCell.provider_id.length === 0 || typeof rawCell.model_id !== "string" || rawCell.model_id.length === 0 || !isRecord2(rawCell.facts)) {
21511
+ badCells++;
21512
+ continue;
21513
+ }
21514
+ const facts = {};
21515
+ let valid = true;
21516
+ for (const [key, rawFact] of Object.entries(rawCell.facts)) {
21517
+ const fact = parseFact(key, rawFact);
21518
+ if (!fact) {
21519
+ valid = false;
21520
+ break;
21521
+ }
21522
+ facts[key] = fact;
21523
+ }
21524
+ if (!valid) {
21525
+ badCells++;
21526
+ continue;
21527
+ }
21528
+ cells.push({
21529
+ provider_id: rawCell.provider_id,
21530
+ model_id: rawCell.model_id,
21531
+ facts
21532
+ });
21533
+ }
21534
+ return {
21535
+ overlay: {
21536
+ schema: WINDOW_OVERLAY_SCHEMA,
21537
+ generated_at: value.generated_at,
21538
+ minted_provider_ids: [...value.minted_provider_ids],
21539
+ cells
21540
+ },
21541
+ badCells
21542
+ };
21543
+ }
21544
+ function defaultWindowOverlayPath() {
21545
+ return join6(getDataDir(), "fusiform", "window-overlay.json");
21546
+ }
21547
+ function readWindowOverlayFile(path3, log2 = (message) => sessionLog("global", message)) {
21548
+ let raw;
21549
+ try {
21550
+ raw = readFileSync6(path3, "utf8");
21551
+ } catch (error) {
21552
+ if (error.code === "ENOENT")
21553
+ return;
21554
+ log2(`window-overlay: unable to read ${path3}; overlay ignored`);
21555
+ return;
21556
+ }
21557
+ let decoded;
21558
+ try {
21559
+ decoded = JSON.parse(raw);
21560
+ } catch {
21561
+ log2(`window-overlay: invalid JSON in ${path3}; overlay ignored`);
21562
+ return;
21563
+ }
21564
+ const parsed = parseWindowOverlay(decoded);
21565
+ if (parsed.refusal) {
21566
+ log2(`window-overlay: ${parsed.refusal} in ${path3}; entire overlay ignored`);
21567
+ return;
21568
+ }
21569
+ if (parsed.badCells > 0) {
21570
+ log2(`window-overlay: skipped ${parsed.badCells} invalid cell(s) from ${path3}`);
21571
+ }
21572
+ return parsed.overlay;
21573
+ }
21574
+ function setWindowOverlayPath(path3) {
21575
+ if (configuredOverlayPath === path3)
21576
+ return;
21577
+ reloadWindowOverlay(path3);
21578
+ }
21579
+ function reloadWindowOverlay(path3) {
21580
+ configuredOverlayPath = path3;
21581
+ loadedOverlayPath = undefined;
21582
+ loadedOverlay = undefined;
21583
+ }
21584
+ function getWindowOverlay() {
21585
+ const path3 = configuredOverlayPath ?? defaultWindowOverlayPath();
21586
+ if (loadedOverlayPath === path3 && loadedOverlay !== undefined) {
21587
+ return loadedOverlay ?? undefined;
21588
+ }
21589
+ loadedOverlayPath = path3;
21590
+ loadedOverlay = readWindowOverlayFile(path3) ?? null;
21591
+ return loadedOverlay ?? undefined;
21592
+ }
21593
+ function resolveWindowOverlayFacts(providerID, modelID, overlay = getWindowOverlay()) {
21594
+ if (!overlay)
21595
+ return;
21596
+ const modelRefs = modelRefLookupOrder(`${providerID}/${modelID}`);
21597
+ const providerCandidates = new Set(modelRefs.map((ref) => ref.slice(0, ref.indexOf("/"))));
21598
+ const modelCandidates = new Set([
21599
+ modelID,
21600
+ ...modelRefs.map((ref) => ref.slice(ref.indexOf("/") + 1))
21601
+ ]);
21602
+ const colon = modelID.lastIndexOf(":");
21603
+ if (colon > 0)
21604
+ modelCandidates.add(modelID.slice(0, colon));
21605
+ const wildcardFacts = {};
21606
+ const specificFacts = {};
21607
+ for (const cell of overlay.cells) {
21608
+ if (!providerCandidates.has(cell.provider_id))
21609
+ continue;
21610
+ if (cell.model_id === "*")
21611
+ Object.assign(wildcardFacts, cell.facts);
21612
+ else if (modelCandidates.has(cell.model_id))
21613
+ Object.assign(specificFacts, cell.facts);
21614
+ }
21615
+ const facts = { ...wildcardFacts, ...specificFacts };
21616
+ return Object.keys(facts).length > 0 ? { facts } : undefined;
21617
+ }
21618
+ function numericOverlayFact(overlay, key) {
21619
+ const fact = overlay?.facts[key];
21620
+ return fact ? scalarizeFact(fact.value) : undefined;
21621
+ }
21622
+ function overlayGeometry(overlay) {
21623
+ const fact = overlay?.facts.geometry;
21624
+ if (fact === undefined)
21625
+ return;
21626
+ if (fact.value.kind === "unknown")
21627
+ return { kind: "unknown" };
21628
+ if (fact.value.kind !== "stated")
21629
+ return;
21630
+ const value = fact.value.value;
21631
+ return value === "shared_upfront" || value === "shared_truncating" || value === "separate" ? { kind: "stated", value } : undefined;
21632
+ }
21633
+ function placeholderFilteredOutput(output, context) {
21634
+ if (!isFinitePositive(output))
21635
+ return;
21636
+ if (isFinitePositive(context) && output >= context)
21637
+ return;
21638
+ return output;
21639
+ }
21640
+ function mergePositive(overlayValue, providerValue) {
21641
+ return isFinitePositive(providerValue) ? providerValue : overlayValue;
21642
+ }
21643
+ function logGeometryClampOnce(key, message, log2) {
21644
+ if (geometryClampLogSeen.has(key))
21645
+ return;
21646
+ geometryClampLogSeen.add(key);
21647
+ (log2 ?? ((entry) => sessionLog("global", `window-geometry: ${entry}`)))(message);
21648
+ }
21649
+ function deriveWindowGeometry(providerID, modelID, catalogLimit, options = {}) {
21650
+ if (!catalogLimit && !options.providerLimit)
21651
+ return;
21652
+ const providerLimit = options.providerLimit;
21653
+ const catalogContext = isFinitePositive(catalogLimit?.context) ? catalogLimit.context : undefined;
21654
+ const advertised = numericOverlayFact(options.overlay, "window.advertised");
21655
+ const enforced = numericOverlayFact(options.overlay, "window.enforced");
21656
+ let softContext = mergePositive(enforced ?? advertised ?? catalogContext, providerLimit?.context);
21657
+ let hardContext = mergePositive(enforced ?? softContext, providerLimit?.context);
21658
+ if (isFinitePositive(options.contextCap)) {
21659
+ softContext = isFinitePositive(softContext) ? Math.min(softContext, options.contextCap) : options.contextCap;
21660
+ hardContext = isFinitePositive(hardContext) ? Math.min(hardContext, options.contextCap) : options.contextCap;
21661
+ }
21662
+ const input = mergePositive(isFinitePositive(catalogLimit?.input) ? catalogLimit.input : undefined, providerLimit?.input);
21663
+ if (!isFinitePositive(softContext) && !isFinitePositive(input))
21664
+ return;
21665
+ const catalogOutput = options.overlay === undefined && options.providerLimit === undefined ? isFinitePositive(catalogLimit?.output) ? catalogLimit.output : undefined : placeholderFilteredOutput(catalogLimit?.output, softContext);
21666
+ const overlayOutput = placeholderFilteredOutput(numericOverlayFact(options.overlay, "output.enforced") ?? numericOverlayFact(options.overlay, "output.default") ?? numericOverlayFact(options.overlay, "output.advertised"), softContext);
21667
+ const providerOutput = placeholderFilteredOutput(providerLimit?.output, softContext);
21668
+ const output = providerOutput ?? overlayOutput ?? catalogOutput;
21669
+ const geometryFact = overlayGeometry(options.overlay);
21670
+ const geometry = geometryFact?.kind === "stated" ? geometryFact.value : geometryFact?.kind === "unknown" ? "shared_upfront" : PROVIDER_GEOMETRY[providerID] ?? "shared_upfront";
21671
+ const geometryOverride = geometryFact?.kind === "stated" ? geometryFact.value : undefined;
21672
+ const preCarvedInput = isFinitePositive(input) && (!isFinitePositive(softContext) || input < softContext);
21673
+ const outputReserveOverride = typeof options.outputReserveOverride === "number" && Number.isFinite(options.outputReserveOverride) && options.outputReserveOverride >= 0 ? options.outputReserveOverride : undefined;
21674
+ let derivationWindow = softContext ?? input;
21675
+ let usableSoft;
21676
+ let softReserve = 0;
21677
+ let reserveSource = "none";
21678
+ if (outputReserveOverride !== undefined) {
21679
+ const reserveWindow = preCarvedInput ? input : softContext ?? input;
21680
+ if (!isFinitePositive(reserveWindow))
21681
+ return;
21682
+ derivationWindow = reserveWindow;
21683
+ softReserve = outputReserveOverride;
21684
+ reserveSource = "output_config";
21685
+ const floor = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, reserveWindow * 0.5);
21686
+ const flooredReserve = Math.min(softReserve, Math.max(0, reserveWindow - floor));
21687
+ if (flooredReserve < softReserve) {
21688
+ logGeometryClampOnce(`soft-floor|${providerID}/${modelID}|${softReserve}|${flooredReserve}`, `output reserve clamped by the half-window floor for ${providerID}/${modelID}: reserve ${softReserve} → ${flooredReserve}`, options.log);
21689
+ }
21690
+ softReserve = flooredReserve;
21691
+ usableSoft = Math.floor(reserveWindow - softReserve);
21692
+ } else if (preCarvedInput) {
21693
+ usableSoft = input;
21694
+ if (isFinitePositive(softContext)) {
21695
+ softReserve = Math.max(0, softContext - input);
21696
+ reserveSource = "output_catalog";
21697
+ }
21698
+ } else if (isFinitePositive(softContext)) {
21699
+ if (geometry === "separate" && (options.overlay === undefined || options.harness === "pi" || geometryOverride !== undefined)) {
21700
+ softReserve = 0;
21701
+ reserveSource = "none";
21702
+ } else {
21703
+ softReserve = output ?? 0;
21704
+ reserveSource = output === undefined ? "none" : "output_catalog";
21705
+ const cap = softContext * OUTPUT_RESERVE_CAP_RATIO;
21706
+ softReserve = Math.min(softReserve, options.harness === "pi" || options.overlay === undefined ? cap : Math.min(cap, OPENCODE_OUTPUT_CAP));
21707
+ }
21708
+ const floor = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, softContext * 0.5);
21709
+ const flooredReserve = Math.min(softReserve, Math.max(0, softContext - floor));
21710
+ if (flooredReserve < softReserve) {
21711
+ logGeometryClampOnce(`soft-floor|${providerID}/${modelID}|${softReserve}|${flooredReserve}`, `output reserve clamped by the half-window floor for ${providerID}/${modelID}: reserve ${softReserve} → ${flooredReserve} (catalog context/output pair is contradictory)`, options.log);
21712
+ }
21713
+ softReserve = flooredReserve;
21714
+ usableSoft = Math.floor(softContext - softReserve);
21715
+ } else {
21716
+ usableSoft = input;
21717
+ }
21718
+ const hardWindow = hardContext ?? softContext ?? input;
21719
+ if (!isFinitePositive(hardWindow))
21720
+ return;
21721
+ let usableHard;
21722
+ if (geometry === "separate") {
21723
+ usableHard = hardWindow;
21724
+ } else if (geometry === "shared_truncating") {
21725
+ usableHard = hardWindow - PROMPT_WALL_MARGIN;
21726
+ } else if (options.harness === "pi" && providerID !== "openai-codex") {
21727
+ usableHard = hardWindow - PI_OUTPUT_FLOOR;
21728
+ } else if (options.harness === "pi") {
21729
+ usableHard = hardWindow - (output ?? OPENCODE_OUTPUT_CAP);
21730
+ } else {
21731
+ const requestedOutput = Math.min(output ?? OPENCODE_OUTPUT_CAP, OPENCODE_OUTPUT_CAP);
21732
+ usableHard = hardWindow - requestedOutput;
21733
+ }
21734
+ usableHard = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, Math.floor(usableHard));
21735
+ if (usableHard < usableSoft) {
21736
+ logGeometryClampOnce(`${providerID}/${modelID}|${usableSoft}|${usableHard}`, `usable hard limit clamped for ${providerID}/${modelID}: ${usableHard} → ${usableSoft} (overlay/provider inversion)`, options.log);
21737
+ usableHard = usableSoft;
21738
+ }
21739
+ const resolvedWindow = derivationWindow ?? usableSoft;
21740
+ return {
21741
+ usableSoft,
21742
+ usableHard,
21743
+ geometry,
21744
+ derivation: {
21745
+ window: Math.floor(resolvedWindow),
21746
+ reserve: Math.floor(Math.max(0, resolvedWindow - usableSoft)),
21747
+ reserveSource,
21748
+ geometry
21749
+ }
21750
+ };
21751
+ }
21752
+ function formatWindowDerivationLine(inputTokens, result) {
21753
+ const percentage = result.usableSoft > 0 ? inputTokens / result.usableSoft * 100 : 0;
21754
+ const reserveLabel = result.derivation.reserveSource === "wall_margin" ? "wall margin" : result.derivation.reserveSource === "none" ? "reserve" : "output reserve";
21755
+ return `Context: ${formatCompactTokens(inputTokens)} / ${formatCompactTokens(result.usableSoft)} usable (${percentage.toFixed(1)}%) — window ${formatCompactTokens(result.derivation.window)} − ${formatCompactTokens(result.derivation.reserve)} ${reserveLabel} [${result.geometry}]`;
21756
+ }
21757
+ function formatCompactTokens(value) {
21758
+ if (Math.abs(value) >= 1e6) {
21759
+ return `${(value / 1e6).toFixed(1).replace(/\.0$/, "")}m`;
21760
+ }
21761
+ if (Math.abs(value) >= 1000) {
21762
+ return `${(value / 1000).toFixed(1).replace(/\.0$/, "")}k`;
21763
+ }
21764
+ return Math.round(value).toLocaleString();
21765
+ }
21766
+
20809
21767
  // ../plugin/src/shared/prompt-surface-runtime.ts
20810
- import { existsSync as existsSync8, readFileSync as readFileSync7, statSync as statSync5 } from "node:fs";
21768
+ import { existsSync as existsSync8, readFileSync as readFileSync8, statSync as statSync5 } from "node:fs";
20811
21769
  import { dirname as dirname4, isAbsolute as isAbsolute2, resolve as resolve3 } from "node:path";
20812
21770
 
20813
21771
  // ../plugin/src/tools/light-descriptions.ts
@@ -20818,7 +21776,7 @@ var CTX_MEMORY_LIGHT_DESCRIPTION = `For ctx_memory users, write one standalone d
20818
21776
  var CTX_SEARCH_LIGHT_DESCRIPTION = `For ctx_search users, retrieve only hidden recall: memories not already in <project-memory>, compacted messages outside the live tail, commits, and notes. Omit sources for broad search; select memory, message, git_commit, or note to target a source, or pass memory IDs to bypass text search. Message hits continue through ctx_expand.`;
20819
21777
 
20820
21778
  // ../plugin/src/shared/jsonc-parser.ts
20821
- import { existsSync as existsSync7, readFileSync as readFileSync6 } from "node:fs";
21779
+ import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
20822
21780
  function stripJsonComments(content) {
20823
21781
  let result = "";
20824
21782
  let inString = false;
@@ -21089,7 +22047,7 @@ function createPromptSurfaceRuntime(options) {
21089
22047
  warnOnce(`guidance-not-file:${path3}`, `prompt_surface.guidance_override_path (${path3}) is not a file; using built-in guidance.`);
21090
22048
  return;
21091
22049
  }
21092
- content = readFileSync7(path3, "utf8");
22050
+ content = readFileSync8(path3, "utf8");
21093
22051
  } catch (error) {
21094
22052
  const reason = error instanceof Error ? error.message : String(error);
21095
22053
  warnOnce(`guidance-unreadable:${path3}:${reason}`, `prompt_surface.guidance_override_path (${path3}) could not be read (${reason}); using built-in guidance.`);
@@ -37301,13 +38259,13 @@ import {
37301
38259
  existsSync as existsSync9,
37302
38260
  linkSync,
37303
38261
  openSync as openSync2,
37304
- readFileSync as readFileSync8,
38262
+ readFileSync as readFileSync9,
37305
38263
  renameSync as renameSync2,
37306
38264
  statSync as statSync6,
37307
38265
  unlinkSync as unlinkSync3,
37308
38266
  writeFileSync as writeFileSync2
37309
38267
  } from "node:fs";
37310
- import { basename as basename3, dirname as dirname5, join as join6 } from "node:path";
38268
+ import { basename as basename3, dirname as dirname5, join as join7 } from "node:path";
37311
38269
 
37312
38270
  // ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
37313
38271
  function createScanner(text, ignoreTrivia = false) {
@@ -38708,13 +39666,13 @@ var QUALIFIER_FIELDS = ["variant", "thinking_level"];
38708
39666
  var TASK_MODEL_FIELDS = [...MODEL_FIELDS, ...QUALIFIER_FIELDS, "timeout_minutes"];
38709
39667
  var PRE_PER_HARNESS_BACKUP_SUFFIX = ".pre-per-harness.bak";
38710
39668
  var temporaryFileSequence = 0;
38711
- function isRecord2(value) {
39669
+ function isRecord3(value) {
38712
39670
  return typeof value === "object" && value !== null && !Array.isArray(value);
38713
39671
  }
38714
39672
  function asDocument(text) {
38715
39673
  try {
38716
39674
  const document = parseJsonc(text.startsWith("\uFEFF") ? text.slice(1) : text);
38717
- return isRecord2(document) ? document : null;
39675
+ return isRecord3(document) ? document : null;
38718
39676
  } catch {
38719
39677
  return null;
38720
39678
  }
@@ -38722,7 +39680,7 @@ function asDocument(text) {
38722
39680
  function getAtPath(document, path3) {
38723
39681
  let current = document;
38724
39682
  for (const part of path3) {
38725
- if (!isRecord2(current) || !Object.hasOwn(current, part))
39683
+ if (!isRecord3(current) || !Object.hasOwn(current, part))
38726
39684
  return;
38727
39685
  current = current[part];
38728
39686
  }
@@ -38731,7 +39689,7 @@ function getAtPath(document, path3) {
38731
39689
  function stableJson(value) {
38732
39690
  if (Array.isArray(value))
38733
39691
  return `[${value.map(stableJson).join(",")}]`;
38734
- if (!isRecord2(value))
39692
+ if (!isRecord3(value))
38735
39693
  return JSON.stringify(value);
38736
39694
  return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(",")}}`;
38737
39695
  }
@@ -38744,7 +39702,7 @@ function valueForDiagnostic(value) {
38744
39702
  function migrateEntryForHarness(value, harness) {
38745
39703
  if (Array.isArray(value))
38746
39704
  return value.map((entry2) => migrateEntryForHarness(entry2, harness));
38747
- if (!isRecord2(value) || !Object.hasOwn(value, "model"))
39705
+ if (!isRecord3(value) || !Object.hasOwn(value, "model"))
38748
39706
  return value;
38749
39707
  const entry = { model: value.model };
38750
39708
  if (harness === "opencode" && Object.hasOwn(value, "variant")) {
@@ -38765,11 +39723,11 @@ function canCreateAtPath(document, path3) {
38765
39723
  for (const part of path3) {
38766
39724
  if (current === undefined)
38767
39725
  return true;
38768
- if (!isRecord2(current))
39726
+ if (!isRecord3(current))
38769
39727
  return false;
38770
39728
  current = current[part];
38771
39729
  }
38772
- return current === undefined || isRecord2(current);
39730
+ return current === undefined || isRecord3(current);
38773
39731
  }
38774
39732
  function flatFieldPath(parts) {
38775
39733
  return parts.join(".");
@@ -38810,7 +39768,7 @@ function updateDocumentForFlatFields(text) {
38810
39768
  };
38811
39769
  const migrateAgentFields = (agentName) => {
38812
39770
  const agent = document[agentName];
38813
- if (!isRecord2(agent))
39771
+ if (!isRecord3(agent))
38814
39772
  return;
38815
39773
  for (const field of MODEL_FIELDS) {
38816
39774
  if (!Object.hasOwn(agent, field))
@@ -38841,11 +39799,11 @@ function updateDocumentForFlatFields(text) {
38841
39799
  migrateAgentFields("historian");
38842
39800
  migrateAgentFields("dreamer");
38843
39801
  const dreamer = document.dreamer;
38844
- const tasks = isRecord2(dreamer) ? dreamer.tasks : undefined;
38845
- if (isRecord2(tasks)) {
39802
+ const tasks = isRecord3(dreamer) ? dreamer.tasks : undefined;
39803
+ if (isRecord3(tasks)) {
38846
39804
  for (const taskName of Object.keys(tasks).sort()) {
38847
39805
  const task = tasks[taskName];
38848
- if (!isRecord2(task))
39806
+ if (!isRecord3(task))
38849
39807
  continue;
38850
39808
  for (const field of TASK_MODEL_FIELDS) {
38851
39809
  if (!Object.hasOwn(task, field))
@@ -38880,646 +39838,265 @@ function updateDocumentForFlatFields(text) {
38880
39838
  }
38881
39839
  function hasFlatKeys(input) {
38882
39840
  const text = typeof input === "string" ? input : input.toString("utf-8");
38883
- return updateDocumentForFlatFields(text).hasFlatKeys;
38884
- }
38885
- function migrateFlatDetailed(input) {
38886
- const bytes = typeof input === "string" ? Buffer.from(input, "utf-8") : input;
38887
- const result = updateDocumentForFlatFields(bytes.toString("utf-8"));
38888
- return {
38889
- bytes: Buffer.from(result.text, "utf-8"),
38890
- hasFlatKeys: result.hasFlatKeys,
38891
- diagnostics: result.diagnostics
38892
- };
38893
- }
38894
- function writeExclusiveBackup(backupPath, bytes, mode) {
38895
- const temporaryPath = writeTemporaryCandidate(backupPath, bytes, mode);
38896
- try {
38897
- try {
38898
- linkSync(temporaryPath, backupPath);
38899
- return;
38900
- } catch (error51) {
38901
- if (error51.code !== "EEXIST")
38902
- throw error51;
38903
- }
38904
- const existingBytes = readFileSync8(backupPath);
38905
- if (existingBytes.equals(bytes))
38906
- return;
38907
- if (bytes.subarray(0, existingBytes.length).equals(existingBytes)) {
38908
- renameSync2(temporaryPath, backupPath);
38909
- return;
38910
- }
38911
- } finally {
38912
- try {
38913
- unlinkSync3(temporaryPath);
38914
- } catch {}
38915
- }
38916
- }
38917
- function writeTemporaryCandidate(configPath, bytes, mode) {
38918
- const directory = dirname5(configPath);
38919
- const stem = basename3(configPath);
38920
- for (let attempt = 0;attempt < 32; attempt++) {
38921
- temporaryFileSequence += 1;
38922
- const path3 = join6(directory, `.${stem}.per-harness-${process.pid}-${temporaryFileSequence}.tmp`);
38923
- let descriptor;
38924
- try {
38925
- descriptor = openSync2(path3, "wx", mode);
38926
- writeFileSync2(descriptor, bytes);
38927
- closeSync2(descriptor);
38928
- return path3;
38929
- } catch (error51) {
38930
- if (descriptor !== undefined) {
38931
- try {
38932
- closeSync2(descriptor);
38933
- } catch {}
38934
- }
38935
- try {
38936
- unlinkSync3(path3);
38937
- } catch {}
38938
- if (error51.code !== "EEXIST")
38939
- throw error51;
38940
- }
38941
- }
38942
- throw new Error(`Could not allocate a temporary config file beside ${configPath}`);
38943
- }
38944
- function migrationWarning(diagnostic) {
38945
- return diagnostic.message;
38946
- }
38947
- function loadRawConfigFile(options) {
38948
- if (!existsSync9(options.configPath))
38949
- return null;
38950
- let observedBytes;
38951
- try {
38952
- observedBytes = readFileSync8(options.configPath);
38953
- } catch (error51) {
38954
- throw new Error(`failed to read config: ${error51 instanceof Error ? error51.message : String(error51)}`);
38955
- }
38956
- const initialMigration = migrateFlatDetailed(observedBytes);
38957
- if (!initialMigration.hasFlatKeys) {
38958
- return {
38959
- configPath: options.configPath,
38960
- bytes: observedBytes,
38961
- text: observedBytes.toString("utf-8"),
38962
- warnings: [],
38963
- migrated: false
38964
- };
38965
- }
38966
- if (options.tier === "project") {
38967
- return {
38968
- configPath: options.configPath,
38969
- bytes: initialMigration.bytes,
38970
- text: initialMigration.bytes.toString("utf-8"),
38971
- warnings: [
38972
- "Adapted flat model config in memory; use historian.opencode/historian.pi and dreamer.opencode/dreamer.pi instead. Project config files are never rewritten.",
38973
- ...initialMigration.diagnostics.map(migrationWarning)
38974
- ],
38975
- migrated: false
38976
- };
38977
- }
38978
- const backupPath = `${options.configPath}${PRE_PER_HARNESS_BACKUP_SUFFIX}`;
38979
- for (;; ) {
38980
- const migration = migrateFlatDetailed(observedBytes);
38981
- if (!migration.hasFlatKeys) {
38982
- return {
38983
- configPath: options.configPath,
38984
- bytes: observedBytes,
38985
- text: observedBytes.toString("utf-8"),
38986
- warnings: [],
38987
- migrated: false
38988
- };
38989
- }
38990
- let temporaryPath;
38991
- try {
38992
- const mode = statSync6(options.configPath).mode & 511;
38993
- writeExclusiveBackup(backupPath, observedBytes, mode);
38994
- temporaryPath = writeTemporaryCandidate(options.configPath, migration.bytes, mode);
38995
- options.afterTemporaryWrite?.();
38996
- const currentBytes = readFileSync8(options.configPath);
38997
- if (!hasFlatKeys(currentBytes)) {
38998
- unlinkSync3(temporaryPath);
38999
- return {
39000
- configPath: options.configPath,
39001
- bytes: currentBytes,
39002
- text: currentBytes.toString("utf-8"),
39003
- warnings: [],
39004
- migrated: false
39005
- };
39006
- }
39007
- if (!currentBytes.equals(observedBytes)) {
39008
- unlinkSync3(temporaryPath);
39009
- observedBytes = currentBytes;
39010
- continue;
39011
- }
39012
- renameSync2(temporaryPath, options.configPath);
39013
- return {
39014
- configPath: options.configPath,
39015
- bytes: migration.bytes,
39016
- text: migration.bytes.toString("utf-8"),
39017
- warnings: [
39018
- "Migrated flat historian/dreamer model config to per-harness blocks.",
39019
- ...migration.diagnostics.map(migrationWarning)
39020
- ],
39021
- migrated: true
39022
- };
39023
- } catch (error51) {
39024
- if (temporaryPath) {
39025
- try {
39026
- unlinkSync3(temporaryPath);
39027
- } catch {}
39028
- }
39029
- return {
39030
- configPath: options.configPath,
39031
- bytes: observedBytes,
39032
- text: observedBytes.toString("utf-8"),
39033
- warnings: [
39034
- `Could not migrate flat model config: ${error51 instanceof Error ? error51.message : String(error51)}. Flat fields were not applied.`,
39035
- ...migration.diagnostics.map(migrationWarning)
39036
- ],
39037
- migrated: false
39038
- };
39039
- }
39040
- }
39041
- }
39042
-
39043
- // ../plugin/src/config/variable.ts
39044
- import { existsSync as existsSync10, readFileSync as readFileSync9 } from "node:fs";
39045
- import { homedir as homedir5 } from "node:os";
39046
- import { dirname as dirname6, isAbsolute as isAbsolute3, resolve as resolve4 } from "node:path";
39047
- var ENV_PATTERN = /\{env:([^}]+)\}/g;
39048
- var FILE_PATTERN = /\{file:([^}]+)\}/g;
39049
- function sensitiveFilePathReason(resolvedPath) {
39050
- const home = homedir5();
39051
- const sensitiveDirs = [
39052
- { dir: resolve4(home, ".ssh"), label: "SSH keys" },
39053
- { dir: resolve4(home, ".aws"), label: "AWS credentials" },
39054
- { dir: resolve4(home, ".gnupg"), label: "GnuPG keyring" },
39055
- { dir: resolve4(home, ".config", "gh"), label: "GitHub CLI auth" }
39056
- ];
39057
- for (const { dir, label } of sensitiveDirs) {
39058
- if (resolvedPath === dir || resolvedPath.startsWith(`${dir}/`)) {
39059
- return label;
39060
- }
39061
- }
39062
- return null;
39063
- }
39064
- function substituteConfigVariables(input) {
39065
- const warnings = [];
39066
- let text = input.text;
39067
- if (input.isProjectConfig) {
39068
- const hasEnvTokens = ENV_PATTERN.test(text);
39069
- const hasFileTokens = FILE_PATTERN.test(text);
39070
- ENV_PATTERN.lastIndex = 0;
39071
- FILE_PATTERN.lastIndex = 0;
39072
- if (hasEnvTokens || hasFileTokens) {
39073
- const tokenTypes = [
39074
- hasEnvTokens ? "{env:}" : undefined,
39075
- hasFileTokens ? "{file:}" : undefined
39076
- ].filter(Boolean).join(" and ");
39077
- warnings.push(`Project-level config no longer supports ${tokenTypes} tokens for security reasons; leaving tokens literal. Move secret expansion to user-level config.`);
39078
- }
39079
- return { text, warnings };
39080
- }
39081
- text = stripJsonComments(text);
39082
- text = text.replace(ENV_PATTERN, (_, rawName) => {
39083
- const varName = rawName.trim();
39084
- const value = varName ? process.env[varName] : undefined;
39085
- if (value === undefined || value === "") {
39086
- warnings.push(`Environment variable ${varName} is not set (referenced via {env:${varName}}); using empty string`);
39087
- return "";
39088
- }
39089
- return JSON.stringify(value).slice(1, -1);
39090
- });
39091
- const fileMatches = Array.from(text.matchAll(FILE_PATTERN));
39092
- if (fileMatches.length === 0) {
39093
- return { text, warnings };
39094
- }
39095
- const configDir = input.configPath ? dirname6(input.configPath) : process.cwd();
39096
- let output = "";
39097
- let cursor = 0;
39098
- for (const match of fileMatches) {
39099
- const token = match[0];
39100
- const rawPath = match[1] ?? "";
39101
- const index = match.index ?? 0;
39102
- output += text.slice(cursor, index);
39103
- cursor = index + token.length;
39104
- const lineStart = text.lastIndexOf(`
39105
- `, index - 1) + 1;
39106
- const prefix = text.slice(lineStart, index).trimStart();
39107
- if (prefix.startsWith("//")) {
39108
- output += token;
39109
- continue;
39110
- }
39111
- let filePath = rawPath.trim();
39112
- if (filePath.startsWith("~/")) {
39113
- filePath = resolve4(homedir5(), filePath.slice(2));
39114
- } else if (!isAbsolute3(filePath)) {
39115
- filePath = resolve4(configDir, filePath);
39116
- }
39117
- const sensitiveReason = sensitiveFilePathReason(filePath);
39118
- if (sensitiveReason) {
39119
- warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
39120
- }
39121
- if (!existsSync10(filePath)) {
39122
- warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
39123
- continue;
39124
- }
39125
- let contents;
39126
- try {
39127
- contents = readFileSync9(filePath, "utf-8").trim();
39128
- } catch (error51) {
39129
- const message = error51 instanceof Error ? error51.message : String(error51);
39130
- warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
39131
- continue;
39132
- }
39133
- output += JSON.stringify(contents).slice(1, -1);
39134
- }
39135
- output += text.slice(cursor);
39136
- return { text: output, warnings };
39137
- }
39138
-
39139
- // ../plugin/src/shared/models-dev-cache.ts
39140
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync11, renameSync as renameSync3, writeFileSync as writeFileSync3 } from "node:fs";
39141
- import { join as join8 } from "node:path";
39142
-
39143
- // ../plugin/src/shared/window-geometry.ts
39144
- import { readFileSync as readFileSync10 } from "node:fs";
39145
- import { join as join7 } from "node:path";
39146
- var WINDOW_OVERLAY_SCHEMA = "fusiform-window-overlay/v1";
39147
- var PROMPT_WALL_MARGIN = 4096;
39148
- var PI_OUTPUT_FLOOR = 4096;
39149
- var OPENCODE_OUTPUT_CAP = 32000;
39150
- var MIN_PLAUSIBLE_CONTEXT_LIMIT = 1024;
39151
- var OUTPUT_RESERVE_CAP_RATIO = 0.25;
39152
- var PROVIDER_GEOMETRY = {
39153
- anthropic: "shared_truncating",
39154
- xai: "shared_truncating",
39155
- google: "separate",
39156
- "google-antigravity": "separate"
39157
- };
39158
- var GRADES = new Set([
39159
- "provider_asserted_runtime",
39160
- "measured",
39161
- "provider_asserted_doc",
39162
- "catalog",
39163
- "unknown"
39164
- ]);
39165
- var UNITS = new Set(["provider", "estimate"]);
39166
- var BOUNDARIES = new Set(["Observed", "Asserted", "Corrected"]);
39167
- var UNKNOWN_REASONS = new Set([
39168
- "placeholder_output_equals_context",
39169
- "placeholder_zero",
39170
- "never_measured",
39171
- "not_single_valued_at_key",
39172
- "retracted"
39173
- ]);
39174
- var NUMERIC_FACT_KEYS = new Set([
39175
- "window.advertised",
39176
- "window.enforced",
39177
- "output.advertised",
39178
- "output.enforced",
39179
- "output.default"
39180
- ]);
39181
- var configuredOverlayPath;
39182
- var loadedOverlayPath;
39183
- var loadedOverlay;
39184
- var geometryClampLogSeen = new Set;
39185
- function isRecord3(value) {
39186
- return typeof value === "object" && value !== null && !Array.isArray(value);
39187
- }
39188
- function isFinitePositive(value) {
39189
- return typeof value === "number" && Number.isFinite(value) && value > 0;
39190
- }
39191
- function scalarizeFact(value) {
39192
- if (value.kind === "stated")
39193
- return isFinitePositive(value.value) ? value.value : undefined;
39194
- if (value.kind === "bracket") {
39195
- return isFinitePositive(value.at_least) ? value.at_least : undefined;
39196
- }
39197
- return;
39198
- }
39199
- function parseFactValue(value) {
39200
- if (!isRecord3(value) || typeof value.kind !== "string")
39201
- return;
39202
- if (value.kind === "stated") {
39203
- if ((typeof value.value !== "number" || !Number.isFinite(value.value)) && typeof value.value !== "string") {
39204
- return;
39205
- }
39206
- return { kind: "stated", value: value.value };
39207
- }
39208
- if (value.kind === "bracket") {
39209
- const atLeast = value.at_least;
39210
- const below = value.below;
39211
- if (atLeast === undefined && below === undefined)
39212
- return { kind: "bracket" };
39213
- if (atLeast !== undefined && !isFinitePositive(atLeast))
39214
- return;
39215
- if (below !== undefined && !isFinitePositive(below))
39216
- return;
39217
- if (isFinitePositive(atLeast) && isFinitePositive(below) && below <= atLeast) {
39218
- return;
39219
- }
39220
- return {
39221
- kind: "bracket",
39222
- ...isFinitePositive(atLeast) ? { at_least: atLeast } : {},
39223
- ...isFinitePositive(below) ? { below } : {}
39224
- };
39225
- }
39226
- if (value.kind === "unknown" && UNKNOWN_REASONS.has(value.why)) {
39227
- return { kind: "unknown", why: value.why };
39228
- }
39229
- return;
39230
- }
39231
- function parseFact(key, value) {
39232
- if (!isRecord3(value))
39233
- return;
39234
- const parsedValue = parseFactValue(value.value);
39235
- if (!parsedValue || !GRADES.has(value.grade) || !UNITS.has(value.units) || !BOUNDARIES.has(value.boundary) || typeof value.source_ref !== "string" || value.source_ref.length === 0 || typeof value.observed_at !== "string" || value.observed_at.length === 0) {
39236
- return;
39237
- }
39238
- if (NUMERIC_FACT_KEYS.has(key) && parsedValue.kind === "stated" && !isFinitePositive(parsedValue.value)) {
39239
- return;
39240
- }
39241
- if (key === "geometry" && parsedValue.kind === "stated" && !["shared_upfront", "shared_truncating", "separate"].includes(String(parsedValue.value))) {
39242
- return;
39243
- }
39244
- return {
39245
- ...value,
39246
- value: parsedValue,
39247
- grade: value.grade,
39248
- units: value.units,
39249
- boundary: value.boundary,
39250
- source_ref: value.source_ref,
39251
- observed_at: value.observed_at
39252
- };
39253
- }
39254
- function parseWindowOverlay(value) {
39255
- if (!isRecord3(value)) {
39256
- return { badCells: 0, refusal: "overlay root is not an object" };
39257
- }
39258
- if (value.schema !== WINDOW_OVERLAY_SCHEMA) {
39259
- return {
39260
- badCells: 0,
39261
- refusal: `unrecognized schema ${JSON.stringify(value.schema)}`
39262
- };
39263
- }
39264
- if (typeof value.generated_at !== "string" || !Array.isArray(value.minted_provider_ids) || !value.minted_provider_ids.every((id) => typeof id === "string" && id.length > 0) || !Array.isArray(value.cells)) {
39265
- return { badCells: 0, refusal: "invalid v1 envelope" };
39266
- }
39267
- const cells = [];
39268
- let badCells = 0;
39269
- for (const rawCell of value.cells) {
39270
- if (!isRecord3(rawCell) || typeof rawCell.provider_id !== "string" || rawCell.provider_id.length === 0 || typeof rawCell.model_id !== "string" || rawCell.model_id.length === 0 || !isRecord3(rawCell.facts)) {
39271
- badCells++;
39272
- continue;
39273
- }
39274
- const facts = {};
39275
- let valid = true;
39276
- for (const [key, rawFact] of Object.entries(rawCell.facts)) {
39277
- const fact = parseFact(key, rawFact);
39278
- if (!fact) {
39279
- valid = false;
39280
- break;
39281
- }
39282
- facts[key] = fact;
39283
- }
39284
- if (!valid) {
39285
- badCells++;
39286
- continue;
39287
- }
39288
- cells.push({
39289
- provider_id: rawCell.provider_id,
39290
- model_id: rawCell.model_id,
39291
- facts
39292
- });
39293
- }
39294
- return {
39295
- overlay: {
39296
- schema: WINDOW_OVERLAY_SCHEMA,
39297
- generated_at: value.generated_at,
39298
- minted_provider_ids: [...value.minted_provider_ids],
39299
- cells
39300
- },
39301
- badCells
39302
- };
39303
- }
39304
- function defaultWindowOverlayPath() {
39305
- return join7(getDataDir(), "fusiform", "window-overlay.json");
39306
- }
39307
- function readWindowOverlayFile(path3, log2 = (message) => sessionLog("global", message)) {
39308
- let raw;
39309
- try {
39310
- raw = readFileSync10(path3, "utf8");
39311
- } catch (error51) {
39312
- if (error51.code === "ENOENT")
39313
- return;
39314
- log2(`window-overlay: unable to read ${path3}; overlay ignored`);
39315
- return;
39316
- }
39317
- let decoded;
39318
- try {
39319
- decoded = JSON.parse(raw);
39320
- } catch {
39321
- log2(`window-overlay: invalid JSON in ${path3}; overlay ignored`);
39322
- return;
39323
- }
39324
- const parsed = parseWindowOverlay(decoded);
39325
- if (parsed.refusal) {
39326
- log2(`window-overlay: ${parsed.refusal} in ${path3}; entire overlay ignored`);
39327
- return;
39328
- }
39329
- if (parsed.badCells > 0) {
39330
- log2(`window-overlay: skipped ${parsed.badCells} invalid cell(s) from ${path3}`);
39331
- }
39332
- return parsed.overlay;
39333
- }
39334
- function setWindowOverlayPath(path3) {
39335
- configuredOverlayPath = path3;
39336
- loadedOverlayPath = undefined;
39337
- loadedOverlay = undefined;
39338
- }
39339
- function getWindowOverlay() {
39340
- const path3 = configuredOverlayPath ?? defaultWindowOverlayPath();
39341
- if (loadedOverlayPath === path3 && loadedOverlay !== undefined) {
39342
- return loadedOverlay ?? undefined;
39343
- }
39344
- loadedOverlayPath = path3;
39345
- loadedOverlay = readWindowOverlayFile(path3) ?? null;
39346
- return loadedOverlay ?? undefined;
39347
- }
39348
- function resolveWindowOverlayFacts(providerID, modelID, overlay = getWindowOverlay()) {
39349
- if (!overlay)
39350
- return;
39351
- const modelRefs = modelRefLookupOrder(`${providerID}/${modelID}`);
39352
- const providerCandidates = new Set(modelRefs.map((ref) => ref.slice(0, ref.indexOf("/"))));
39353
- const modelCandidates = new Set([
39354
- modelID,
39355
- ...modelRefs.map((ref) => ref.slice(ref.indexOf("/") + 1))
39356
- ]);
39357
- const colon = modelID.lastIndexOf(":");
39358
- if (colon > 0)
39359
- modelCandidates.add(modelID.slice(0, colon));
39360
- const wildcardFacts = {};
39361
- const specificFacts = {};
39362
- for (const cell of overlay.cells) {
39363
- if (!providerCandidates.has(cell.provider_id))
39364
- continue;
39365
- if (cell.model_id === "*")
39366
- Object.assign(wildcardFacts, cell.facts);
39367
- else if (modelCandidates.has(cell.model_id))
39368
- Object.assign(specificFacts, cell.facts);
39369
- }
39370
- const facts = { ...wildcardFacts, ...specificFacts };
39371
- return Object.keys(facts).length > 0 ? { facts } : undefined;
39372
- }
39373
- function numericOverlayFact(overlay, key) {
39374
- const fact = overlay?.facts[key];
39375
- return fact ? scalarizeFact(fact.value) : undefined;
39376
- }
39377
- function overlayGeometry(overlay) {
39378
- const fact = overlay?.facts.geometry;
39379
- if (fact === undefined)
39380
- return;
39381
- if (fact.value.kind === "unknown")
39382
- return { kind: "unknown" };
39383
- if (fact.value.kind !== "stated")
39384
- return;
39385
- const value = fact.value.value;
39386
- return value === "shared_upfront" || value === "shared_truncating" || value === "separate" ? { kind: "stated", value } : undefined;
39387
- }
39388
- function placeholderFilteredOutput(output, context) {
39389
- if (!isFinitePositive(output))
39390
- return;
39391
- if (isFinitePositive(context) && output >= context)
39392
- return;
39393
- return output;
39394
- }
39395
- function mergePositive(overlayValue, providerValue) {
39396
- return isFinitePositive(providerValue) ? providerValue : overlayValue;
39841
+ return updateDocumentForFlatFields(text).hasFlatKeys;
39397
39842
  }
39398
- function logGeometryClampOnce(key, message, log2) {
39399
- if (geometryClampLogSeen.has(key))
39400
- return;
39401
- geometryClampLogSeen.add(key);
39402
- (log2 ?? ((entry) => sessionLog("global", `window-geometry: ${entry}`)))(message);
39843
+ function migrateFlatDetailed(input) {
39844
+ const bytes = typeof input === "string" ? Buffer.from(input, "utf-8") : input;
39845
+ const result = updateDocumentForFlatFields(bytes.toString("utf-8"));
39846
+ return {
39847
+ bytes: Buffer.from(result.text, "utf-8"),
39848
+ hasFlatKeys: result.hasFlatKeys,
39849
+ diagnostics: result.diagnostics
39850
+ };
39403
39851
  }
39404
- function deriveWindowGeometry(providerID, modelID, catalogLimit, options = {}) {
39405
- if (!catalogLimit && !options.providerLimit)
39406
- return;
39407
- const providerLimit = options.providerLimit;
39408
- const catalogContext = isFinitePositive(catalogLimit?.context) ? catalogLimit.context : undefined;
39409
- const advertised = numericOverlayFact(options.overlay, "window.advertised");
39410
- const enforced = numericOverlayFact(options.overlay, "window.enforced");
39411
- let softContext = mergePositive(enforced ?? advertised ?? catalogContext, providerLimit?.context);
39412
- let hardContext = mergePositive(enforced ?? softContext, providerLimit?.context);
39413
- if (isFinitePositive(options.contextCap)) {
39414
- softContext = isFinitePositive(softContext) ? Math.min(softContext, options.contextCap) : options.contextCap;
39415
- hardContext = isFinitePositive(hardContext) ? Math.min(hardContext, options.contextCap) : options.contextCap;
39416
- }
39417
- const input = mergePositive(isFinitePositive(catalogLimit?.input) ? catalogLimit.input : undefined, providerLimit?.input);
39418
- if (!isFinitePositive(softContext) && !isFinitePositive(input))
39419
- return;
39420
- const catalogOutput = options.overlay === undefined && options.providerLimit === undefined ? isFinitePositive(catalogLimit?.output) ? catalogLimit.output : undefined : placeholderFilteredOutput(catalogLimit?.output, softContext);
39421
- const overlayOutput = placeholderFilteredOutput(numericOverlayFact(options.overlay, "output.enforced") ?? numericOverlayFact(options.overlay, "output.default") ?? numericOverlayFact(options.overlay, "output.advertised"), softContext);
39422
- const providerOutput = placeholderFilteredOutput(providerLimit?.output, softContext);
39423
- const output = providerOutput ?? overlayOutput ?? catalogOutput;
39424
- const geometryFact = overlayGeometry(options.overlay);
39425
- const geometry = geometryFact?.kind === "stated" ? geometryFact.value : geometryFact?.kind === "unknown" ? "shared_upfront" : PROVIDER_GEOMETRY[providerID] ?? "shared_upfront";
39426
- const geometryOverride = geometryFact?.kind === "stated" ? geometryFact.value : undefined;
39427
- const preCarvedInput = isFinitePositive(input) && (!isFinitePositive(softContext) || input < softContext);
39428
- const outputReserveOverride = typeof options.outputReserveOverride === "number" && Number.isFinite(options.outputReserveOverride) && options.outputReserveOverride >= 0 ? options.outputReserveOverride : undefined;
39429
- let derivationWindow = softContext ?? input;
39430
- let usableSoft;
39431
- let softReserve = 0;
39432
- let reserveSource = "none";
39433
- if (outputReserveOverride !== undefined) {
39434
- const reserveWindow = preCarvedInput ? input : softContext ?? input;
39435
- if (!isFinitePositive(reserveWindow))
39852
+ function writeExclusiveBackup(backupPath, bytes, mode) {
39853
+ const temporaryPath = writeTemporaryCandidate(backupPath, bytes, mode);
39854
+ try {
39855
+ try {
39856
+ linkSync(temporaryPath, backupPath);
39436
39857
  return;
39437
- derivationWindow = reserveWindow;
39438
- softReserve = outputReserveOverride;
39439
- reserveSource = "output_config";
39440
- const floor = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, reserveWindow * 0.5);
39441
- const flooredReserve = Math.min(softReserve, Math.max(0, reserveWindow - floor));
39442
- if (flooredReserve < softReserve) {
39443
- logGeometryClampOnce(`soft-floor|${providerID}/${modelID}|${softReserve}|${flooredReserve}`, `output reserve clamped by the half-window floor for ${providerID}/${modelID}: reserve ${softReserve} → ${flooredReserve}`, options.log);
39444
- }
39445
- softReserve = flooredReserve;
39446
- usableSoft = Math.floor(reserveWindow - softReserve);
39447
- } else if (preCarvedInput) {
39448
- usableSoft = input;
39449
- if (isFinitePositive(softContext)) {
39450
- softReserve = Math.max(0, softContext - input);
39451
- reserveSource = "output_catalog";
39858
+ } catch (error51) {
39859
+ if (error51.code !== "EEXIST")
39860
+ throw error51;
39452
39861
  }
39453
- } else if (isFinitePositive(softContext)) {
39454
- if (geometry === "separate" && (options.overlay === undefined || options.harness === "pi" || geometryOverride !== undefined)) {
39455
- softReserve = 0;
39456
- reserveSource = "none";
39457
- } else {
39458
- softReserve = output ?? 0;
39459
- reserveSource = output === undefined ? "none" : "output_catalog";
39460
- const cap = softContext * OUTPUT_RESERVE_CAP_RATIO;
39461
- softReserve = Math.min(softReserve, options.harness === "pi" || options.overlay === undefined ? cap : Math.min(cap, OPENCODE_OUTPUT_CAP));
39862
+ const existingBytes = readFileSync9(backupPath);
39863
+ if (existingBytes.equals(bytes))
39864
+ return;
39865
+ if (bytes.subarray(0, existingBytes.length).equals(existingBytes)) {
39866
+ renameSync2(temporaryPath, backupPath);
39867
+ return;
39462
39868
  }
39463
- const floor = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, softContext * 0.5);
39464
- const flooredReserve = Math.min(softReserve, Math.max(0, softContext - floor));
39465
- if (flooredReserve < softReserve) {
39466
- logGeometryClampOnce(`soft-floor|${providerID}/${modelID}|${softReserve}|${flooredReserve}`, `output reserve clamped by the half-window floor for ${providerID}/${modelID}: reserve ${softReserve} → ${flooredReserve} (catalog context/output pair is contradictory)`, options.log);
39869
+ } finally {
39870
+ try {
39871
+ unlinkSync3(temporaryPath);
39872
+ } catch {}
39873
+ }
39874
+ }
39875
+ function writeTemporaryCandidate(configPath, bytes, mode) {
39876
+ const directory = dirname5(configPath);
39877
+ const stem = basename3(configPath);
39878
+ for (let attempt = 0;attempt < 32; attempt++) {
39879
+ temporaryFileSequence += 1;
39880
+ const path3 = join7(directory, `.${stem}.per-harness-${process.pid}-${temporaryFileSequence}.tmp`);
39881
+ let descriptor;
39882
+ try {
39883
+ descriptor = openSync2(path3, "wx", mode);
39884
+ writeFileSync2(descriptor, bytes);
39885
+ closeSync2(descriptor);
39886
+ return path3;
39887
+ } catch (error51) {
39888
+ if (descriptor !== undefined) {
39889
+ try {
39890
+ closeSync2(descriptor);
39891
+ } catch {}
39892
+ }
39893
+ try {
39894
+ unlinkSync3(path3);
39895
+ } catch {}
39896
+ if (error51.code !== "EEXIST")
39897
+ throw error51;
39467
39898
  }
39468
- softReserve = flooredReserve;
39469
- usableSoft = Math.floor(softContext - softReserve);
39470
- } else {
39471
- usableSoft = input;
39472
39899
  }
39473
- const hardWindow = hardContext ?? softContext ?? input;
39474
- if (!isFinitePositive(hardWindow))
39475
- return;
39476
- let usableHard;
39477
- if (geometry === "separate") {
39478
- usableHard = hardWindow;
39479
- } else if (geometry === "shared_truncating") {
39480
- usableHard = hardWindow - PROMPT_WALL_MARGIN;
39481
- } else if (options.harness === "pi" && providerID !== "openai-codex") {
39482
- usableHard = hardWindow - PI_OUTPUT_FLOOR;
39483
- } else if (options.harness === "pi") {
39484
- usableHard = hardWindow - (output ?? OPENCODE_OUTPUT_CAP);
39485
- } else {
39486
- const requestedOutput = Math.min(output ?? OPENCODE_OUTPUT_CAP, OPENCODE_OUTPUT_CAP);
39487
- usableHard = hardWindow - requestedOutput;
39900
+ throw new Error(`Could not allocate a temporary config file beside ${configPath}`);
39901
+ }
39902
+ function migrationWarning(diagnostic) {
39903
+ return diagnostic.message;
39904
+ }
39905
+ function loadRawConfigFile(options) {
39906
+ if (!existsSync9(options.configPath))
39907
+ return null;
39908
+ let observedBytes;
39909
+ try {
39910
+ observedBytes = readFileSync9(options.configPath);
39911
+ } catch (error51) {
39912
+ throw new Error(`failed to read config: ${error51 instanceof Error ? error51.message : String(error51)}`);
39488
39913
  }
39489
- usableHard = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, Math.floor(usableHard));
39490
- if (usableHard < usableSoft) {
39491
- logGeometryClampOnce(`${providerID}/${modelID}|${usableSoft}|${usableHard}`, `usable hard limit clamped for ${providerID}/${modelID}: ${usableHard} → ${usableSoft} (overlay/provider inversion)`, options.log);
39492
- usableHard = usableSoft;
39914
+ const initialMigration = migrateFlatDetailed(observedBytes);
39915
+ if (!initialMigration.hasFlatKeys) {
39916
+ return {
39917
+ configPath: options.configPath,
39918
+ bytes: observedBytes,
39919
+ text: observedBytes.toString("utf-8"),
39920
+ warnings: [],
39921
+ migrated: false
39922
+ };
39493
39923
  }
39494
- const resolvedWindow = derivationWindow ?? usableSoft;
39495
- return {
39496
- usableSoft,
39497
- usableHard,
39498
- geometry,
39499
- derivation: {
39500
- window: Math.floor(resolvedWindow),
39501
- reserve: Math.floor(Math.max(0, resolvedWindow - usableSoft)),
39502
- reserveSource,
39503
- geometry
39924
+ if (options.tier === "project") {
39925
+ return {
39926
+ configPath: options.configPath,
39927
+ bytes: initialMigration.bytes,
39928
+ text: initialMigration.bytes.toString("utf-8"),
39929
+ warnings: [
39930
+ "Adapted flat model config in memory; use historian.opencode/historian.pi and dreamer.opencode/dreamer.pi instead. Project config files are never rewritten.",
39931
+ ...initialMigration.diagnostics.map(migrationWarning)
39932
+ ],
39933
+ migrated: false
39934
+ };
39935
+ }
39936
+ const backupPath = `${options.configPath}${PRE_PER_HARNESS_BACKUP_SUFFIX}`;
39937
+ for (;; ) {
39938
+ const migration = migrateFlatDetailed(observedBytes);
39939
+ if (!migration.hasFlatKeys) {
39940
+ return {
39941
+ configPath: options.configPath,
39942
+ bytes: observedBytes,
39943
+ text: observedBytes.toString("utf-8"),
39944
+ warnings: [],
39945
+ migrated: false
39946
+ };
39504
39947
  }
39505
- };
39948
+ let temporaryPath;
39949
+ try {
39950
+ const mode = statSync6(options.configPath).mode & 511;
39951
+ writeExclusiveBackup(backupPath, observedBytes, mode);
39952
+ temporaryPath = writeTemporaryCandidate(options.configPath, migration.bytes, mode);
39953
+ options.afterTemporaryWrite?.();
39954
+ const currentBytes = readFileSync9(options.configPath);
39955
+ if (!hasFlatKeys(currentBytes)) {
39956
+ unlinkSync3(temporaryPath);
39957
+ return {
39958
+ configPath: options.configPath,
39959
+ bytes: currentBytes,
39960
+ text: currentBytes.toString("utf-8"),
39961
+ warnings: [],
39962
+ migrated: false
39963
+ };
39964
+ }
39965
+ if (!currentBytes.equals(observedBytes)) {
39966
+ unlinkSync3(temporaryPath);
39967
+ observedBytes = currentBytes;
39968
+ continue;
39969
+ }
39970
+ renameSync2(temporaryPath, options.configPath);
39971
+ return {
39972
+ configPath: options.configPath,
39973
+ bytes: migration.bytes,
39974
+ text: migration.bytes.toString("utf-8"),
39975
+ warnings: [
39976
+ "Migrated flat historian/dreamer model config to per-harness blocks.",
39977
+ ...migration.diagnostics.map(migrationWarning)
39978
+ ],
39979
+ migrated: true
39980
+ };
39981
+ } catch (error51) {
39982
+ if (temporaryPath) {
39983
+ try {
39984
+ unlinkSync3(temporaryPath);
39985
+ } catch {}
39986
+ }
39987
+ return {
39988
+ configPath: options.configPath,
39989
+ bytes: observedBytes,
39990
+ text: observedBytes.toString("utf-8"),
39991
+ warnings: [
39992
+ `Could not migrate flat model config: ${error51 instanceof Error ? error51.message : String(error51)}. Flat fields were not applied.`,
39993
+ ...migration.diagnostics.map(migrationWarning)
39994
+ ],
39995
+ migrated: false
39996
+ };
39997
+ }
39998
+ }
39506
39999
  }
39507
- function formatWindowDerivationLine(inputTokens, result) {
39508
- const percentage = result.usableSoft > 0 ? inputTokens / result.usableSoft * 100 : 0;
39509
- const reserveLabel = result.derivation.reserveSource === "wall_margin" ? "wall margin" : result.derivation.reserveSource === "none" ? "reserve" : "output reserve";
39510
- return `Context: ${formatCompactTokens(inputTokens)} / ${formatCompactTokens(result.usableSoft)} usable (${percentage.toFixed(1)}%) — window ${formatCompactTokens(result.derivation.window)} − ${formatCompactTokens(result.derivation.reserve)} ${reserveLabel} [${result.geometry}]`;
40000
+
40001
+ // ../plugin/src/config/variable.ts
40002
+ import { existsSync as existsSync10, readFileSync as readFileSync10 } from "node:fs";
40003
+ import { homedir as homedir5 } from "node:os";
40004
+ import { dirname as dirname6, isAbsolute as isAbsolute3, resolve as resolve4 } from "node:path";
40005
+ var ENV_PATTERN = /\{env:([^}]+)\}/g;
40006
+ var FILE_PATTERN = /\{file:([^}]+)\}/g;
40007
+ function sensitiveFilePathReason(resolvedPath) {
40008
+ const home = homedir5();
40009
+ const sensitiveDirs = [
40010
+ { dir: resolve4(home, ".ssh"), label: "SSH keys" },
40011
+ { dir: resolve4(home, ".aws"), label: "AWS credentials" },
40012
+ { dir: resolve4(home, ".gnupg"), label: "GnuPG keyring" },
40013
+ { dir: resolve4(home, ".config", "gh"), label: "GitHub CLI auth" }
40014
+ ];
40015
+ for (const { dir, label } of sensitiveDirs) {
40016
+ if (resolvedPath === dir || resolvedPath.startsWith(`${dir}/`)) {
40017
+ return label;
40018
+ }
40019
+ }
40020
+ return null;
39511
40021
  }
39512
- function formatCompactTokens(value) {
39513
- if (Math.abs(value) >= 1e6) {
39514
- return `${(value / 1e6).toFixed(1).replace(/\.0$/, "")}m`;
40022
+ function substituteConfigVariables(input) {
40023
+ const warnings = [];
40024
+ let text = input.text;
40025
+ if (input.isProjectConfig) {
40026
+ const hasEnvTokens = ENV_PATTERN.test(text);
40027
+ const hasFileTokens = FILE_PATTERN.test(text);
40028
+ ENV_PATTERN.lastIndex = 0;
40029
+ FILE_PATTERN.lastIndex = 0;
40030
+ if (hasEnvTokens || hasFileTokens) {
40031
+ const tokenTypes = [
40032
+ hasEnvTokens ? "{env:}" : undefined,
40033
+ hasFileTokens ? "{file:}" : undefined
40034
+ ].filter(Boolean).join(" and ");
40035
+ warnings.push(`Project-level config no longer supports ${tokenTypes} tokens for security reasons; leaving tokens literal. Move secret expansion to user-level config.`);
40036
+ }
40037
+ return { text, warnings };
39515
40038
  }
39516
- if (Math.abs(value) >= 1000) {
39517
- return `${(value / 1000).toFixed(1).replace(/\.0$/, "")}k`;
40039
+ text = stripJsonComments(text);
40040
+ text = text.replace(ENV_PATTERN, (_, rawName) => {
40041
+ const varName = rawName.trim();
40042
+ const value = varName ? process.env[varName] : undefined;
40043
+ if (value === undefined || value === "") {
40044
+ warnings.push(`Environment variable ${varName} is not set (referenced via {env:${varName}}); using empty string`);
40045
+ return "";
40046
+ }
40047
+ return JSON.stringify(value).slice(1, -1);
40048
+ });
40049
+ const fileMatches = Array.from(text.matchAll(FILE_PATTERN));
40050
+ if (fileMatches.length === 0) {
40051
+ return { text, warnings };
39518
40052
  }
39519
- return Math.round(value).toLocaleString();
40053
+ const configDir = input.configPath ? dirname6(input.configPath) : process.cwd();
40054
+ let output = "";
40055
+ let cursor = 0;
40056
+ for (const match of fileMatches) {
40057
+ const token = match[0];
40058
+ const rawPath = match[1] ?? "";
40059
+ const index = match.index ?? 0;
40060
+ output += text.slice(cursor, index);
40061
+ cursor = index + token.length;
40062
+ const lineStart = text.lastIndexOf(`
40063
+ `, index - 1) + 1;
40064
+ const prefix = text.slice(lineStart, index).trimStart();
40065
+ if (prefix.startsWith("//")) {
40066
+ output += token;
40067
+ continue;
40068
+ }
40069
+ let filePath = rawPath.trim();
40070
+ if (filePath.startsWith("~/")) {
40071
+ filePath = resolve4(homedir5(), filePath.slice(2));
40072
+ } else if (!isAbsolute3(filePath)) {
40073
+ filePath = resolve4(configDir, filePath);
40074
+ }
40075
+ const sensitiveReason = sensitiveFilePathReason(filePath);
40076
+ if (sensitiveReason) {
40077
+ warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
40078
+ }
40079
+ if (!existsSync10(filePath)) {
40080
+ warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
40081
+ continue;
40082
+ }
40083
+ let contents;
40084
+ try {
40085
+ contents = readFileSync10(filePath, "utf-8").trim();
40086
+ } catch (error51) {
40087
+ const message = error51 instanceof Error ? error51.message : String(error51);
40088
+ warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
40089
+ continue;
40090
+ }
40091
+ output += JSON.stringify(contents).slice(1, -1);
40092
+ }
40093
+ output += text.slice(cursor);
40094
+ return { text: output, warnings };
39520
40095
  }
39521
40096
 
39522
40097
  // ../plugin/src/shared/models-dev-cache.ts
40098
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync11, renameSync as renameSync3, writeFileSync as writeFileSync3 } from "node:fs";
40099
+ import { join as join8 } from "node:path";
39523
40100
  var MIN_SANE_LIMIT = 20000;
39524
40101
  var MAX_SANE_LIMIT = 3000000;
39525
40102
  function isSaneLimit(limit) {
@@ -40102,7 +40679,7 @@ function loadPiConfigDetailed(opts = {}) {
40102
40679
  import { statSync as statSync7 } from "node:fs";
40103
40680
 
40104
40681
  // ../plugin/src/features/magic-context/compartment-chunk-embedding.ts
40105
- import { createHash as createHash8 } from "node:crypto";
40682
+ import { createHash as createHash9 } from "node:crypto";
40106
40683
 
40107
40684
  // ../plugin/src/features/magic-context/recursive-text-splitter.ts
40108
40685
  var DEFAULT_SEPARATORS = [`
@@ -40192,6 +40769,14 @@ function recursiveCharacterSplit(text, options) {
40192
40769
  // ../plugin/src/features/magic-context/compartment-chunk-embedding.ts
40193
40770
  var DEFAULT_COMPARTMENT_CHUNK_MAX_INPUT_TOKENS = 512;
40194
40771
  var CHUNK_WINDOW_SAFETY_RATIO = 0.9;
40772
+ var MESSAGE_FTS_CHUNK_LOAD_SQL = `SELECT map.message_ordinal AS messageOrdinal, fts.role, fts.content
40773
+ FROM message_fts_rowid_map AS map
40774
+ CROSS JOIN message_history_fts AS fts
40775
+ ON fts.rowid = map.fts_rowid
40776
+ WHERE map.session_id = ?
40777
+ AND map.message_ordinal BETWEEN ? AND ?
40778
+ AND fts.role IN ('user', 'assistant')
40779
+ ORDER BY map.message_ordinal ASC`;
40195
40780
  var loadFtsRowsStatements = new WeakMap;
40196
40781
  var existingHashStatements = new WeakMap;
40197
40782
  var existingHashByProjectStatements = new WeakMap;
@@ -40208,13 +40793,7 @@ var decodedSearchPoolBytes = 0;
40208
40793
  function getLoadFtsRowsStatement(db) {
40209
40794
  let stmt = loadFtsRowsStatements.get(db);
40210
40795
  if (!stmt) {
40211
- stmt = db.prepare(`SELECT message_ordinal AS messageOrdinal, role, content
40212
- FROM message_history_fts
40213
- WHERE session_id = ?
40214
- AND message_ordinal >= ?
40215
- AND message_ordinal <= ?
40216
- AND role IN ('user', 'assistant')
40217
- ORDER BY message_ordinal ASC`);
40796
+ stmt = db.prepare(MESSAGE_FTS_CHUNK_LOAD_SQL);
40218
40797
  loadFtsRowsStatements.set(db, stmt);
40219
40798
  }
40220
40799
  return stmt;
@@ -40387,7 +40966,7 @@ function parseCanonicalLineRange(line) {
40387
40966
  return { start, end };
40388
40967
  }
40389
40968
  function hashChunkText(text) {
40390
- return createHash8("sha256").update(text).digest("hex");
40969
+ return createHash9("sha256").update(text).digest("hex");
40391
40970
  }
40392
40971
  function vectorBlob2(vector) {
40393
40972
  return new Uint8Array(vector.buffer, vector.byteOffset, vector.byteLength);
@@ -40402,6 +40981,8 @@ function toFloat32Array(blob) {
40402
40981
  function buildCanonicalChunkTextFromFts(db, sessionId, startOrdinal, endOrdinal) {
40403
40982
  if (endOrdinal < startOrdinal)
40404
40983
  return "";
40984
+ if (!messageFtsOrdinalRangeIsMapped(db, sessionId, startOrdinal, endOrdinal))
40985
+ return null;
40405
40986
  const rows = getLoadFtsRowsStatement(db).all(sessionId, startOrdinal, endOrdinal).map((row) => row);
40406
40987
  const lines = [];
40407
40988
  let current = null;
@@ -40677,7 +41258,10 @@ function mapBackfillCandidateRows(rows) {
40677
41258
  }));
40678
41259
  }
40679
41260
  function classifyChunkCoverageDefect(db, projectPath, modelId, candidate, maxInputTokens) {
40680
- const canonicalText = buildCanonicalChunkTextFromFts(db, candidate.sessionId, candidate.startMessage, candidate.endMessage) || buildCompartmentSummaryFallbackText(db, candidate.id);
41261
+ const mappedText = buildCanonicalChunkTextFromFts(db, candidate.sessionId, candidate.startMessage, candidate.endMessage);
41262
+ if (mappedText === null)
41263
+ return "deferred";
41264
+ const canonicalText = mappedText || buildCompartmentSummaryFallbackText(db, candidate.id);
40681
41265
  const windows = chunkCanonicalText(canonicalText, candidate.startMessage, candidate.endMessage, maxInputTokens);
40682
41266
  const existing = getExistingChunkHashes(db, candidate.id, modelId, projectPath);
40683
41267
  if (windows.some((window) => !existing.has(window.windowIndex)))
@@ -40787,7 +41371,7 @@ function cosineSimilarity(a, b) {
40787
41371
  }
40788
41372
 
40789
41373
  // ../plugin/src/features/magic-context/memory/embedding-synapse.ts
40790
- import { createHash as createHash9 } from "node:crypto";
41374
+ import { createHash as createHash10 } from "node:crypto";
40791
41375
 
40792
41376
  // ../../node_modules/.bun/@cortexkit+subc-client@0.4.1/node_modules/@cortexkit/subc-client/dist/client.js
40793
41377
  import { promises as fs2 } from "node:fs";
@@ -42268,7 +42852,7 @@ function wait(ms) {
42268
42852
  return new Promise((resolve5) => setTimeout(resolve5, ms));
42269
42853
  }
42270
42854
  function sha256(value) {
42271
- return createHash9("sha256").update(value).digest("hex");
42855
+ return createHash10("sha256").update(value).digest("hex");
42272
42856
  }
42273
42857
  function stableJson2(value) {
42274
42858
  if (Array.isArray(value))
@@ -42711,13 +43295,13 @@ class SynapseEmbeddingProvider {
42711
43295
  }
42712
43296
 
42713
43297
  // ../plugin/src/features/magic-context/memory/normalize-hash.ts
42714
- import { createHash as createHash10 } from "node:crypto";
43298
+ import { createHash as createHash11 } from "node:crypto";
42715
43299
  function normalizeMemoryContent(content) {
42716
43300
  return content.toLowerCase().replace(/\s+/g, " ").trim();
42717
43301
  }
42718
43302
  function computeNormalizedHash(content) {
42719
43303
  const normalized = normalizeMemoryContent(content);
42720
- return createHash10("md5").update(normalized).digest("hex");
43304
+ return createHash11("md5").update(normalized).digest("hex");
42721
43305
  }
42722
43306
 
42723
43307
  // ../plugin/src/features/magic-context/memory/embedding-identity.ts
@@ -42761,14 +43345,113 @@ import { chmodSync as chmodSync2, mkdirSync as mkdirSync4 } from "node:fs";
42761
43345
  import { open, stat, unlink, writeFile } from "node:fs/promises";
42762
43346
  import { dirname as dirname7, join as join9 } from "node:path";
42763
43347
  import { pathToFileURL as pathToFileURL2 } from "node:url";
43348
+
43349
+ // ../plugin/src/features/magic-context/memory/embedding-failure.ts
43350
+ function errorMessage(error51) {
43351
+ return error51 instanceof Error ? error51.message : String(error51 ?? "unknown error");
43352
+ }
43353
+ function nestedMessages(error51) {
43354
+ const messages = [errorMessage(error51)];
43355
+ if (error51 && typeof error51 === "object" && "cause" in error51) {
43356
+ const cause = error51.cause;
43357
+ if (cause !== undefined)
43358
+ messages.push(...nestedMessages(cause));
43359
+ }
43360
+ return messages;
43361
+ }
43362
+ function safeErrorDetail(message) {
43363
+ return message.replace(/https?:\/\/[^\s"']+/gi, "<remote URL>").replace(/\/(?:Users|home)\/[^/\s]+/g, "~").replace(/\s+/g, " ").trim().slice(0, 240);
43364
+ }
43365
+ function hasAny(messages, patterns) {
43366
+ return messages.some((message) => {
43367
+ const lower = message.toLowerCase();
43368
+ return patterns.some((pattern) => lower.includes(pattern));
43369
+ });
43370
+ }
43371
+ function classifyLocalEmbeddingFailure(error51, context = {}) {
43372
+ const primaryMessages = nestedMessages(error51);
43373
+ const nativeMessages = context.nativeError === undefined ? [] : nestedMessages(context.nativeError);
43374
+ if (hasAny(primaryMessages, [
43375
+ "mc_embedding_fs_unavailable",
43376
+ "file system cache is not available"
43377
+ ]) || context.usesWasm && hasAny(primaryMessages, ["unable to get model file path or buffer"])) {
43378
+ return {
43379
+ class: "local_fs_unavailable",
43380
+ reason: "the WASM model cache cannot access the Node filesystem",
43381
+ retryable: false
43382
+ };
43383
+ }
43384
+ if (hasAny(primaryMessages, [
43385
+ "failed to fetch",
43386
+ "fetch failed",
43387
+ "network error",
43388
+ "enotfound",
43389
+ "econnreset",
43390
+ "econnrefused",
43391
+ "certificate",
43392
+ "unable to load file",
43393
+ "unauthorized access to file",
43394
+ "forbidden access to file",
43395
+ "not found at"
43396
+ ]) || primaryMessages.some((message) => /\bHTTP\s+[45]\d\d\b/i.test(message))) {
43397
+ return {
43398
+ class: "local_download_failure",
43399
+ reason: `the embedding model download failed: ${safeErrorDetail(primaryMessages[0])}`,
43400
+ retryable: true
43401
+ };
43402
+ }
43403
+ const bindingMessages = [...primaryMessages, ...nativeMessages];
43404
+ if (hasAny(bindingMessages, [
43405
+ "onnxruntime_binding.node",
43406
+ "cannot find package 'onnxruntime-node'",
43407
+ 'cannot find package "onnxruntime-node"',
43408
+ "cannot find module 'onnxruntime-node'",
43409
+ 'cannot find module "onnxruntime-node"',
43410
+ "could not resolve: onnxruntime-node"
43411
+ ])) {
43412
+ const platform = context.platform ?? process.platform;
43413
+ const arch = context.arch ?? process.arch;
43414
+ return {
43415
+ class: "local_binding_missing",
43416
+ reason: platform === "darwin" && arch === "x64" ? "onnxruntime-node has no darwin/x64 native binding and the WASM fallback could not complete" : `onnxruntime-node has no usable native binding for ${platform}/${arch} and the WASM fallback could not complete`,
43417
+ retryable: false
43418
+ };
43419
+ }
43420
+ return {
43421
+ class: "local_runtime_error",
43422
+ reason: `the local embedding runtime failed: ${safeErrorDetail(primaryMessages[0])}`,
43423
+ retryable: false
43424
+ };
43425
+ }
43426
+ function dominantEmbeddingFailure(failures) {
43427
+ const counts = new Map;
43428
+ for (const failure of failures) {
43429
+ const key = `${failure.class}\x00${failure.reason}`;
43430
+ const current = counts.get(key);
43431
+ if (current)
43432
+ current.count += 1;
43433
+ else
43434
+ counts.set(key, { failure, count: 1 });
43435
+ }
43436
+ let dominant;
43437
+ for (const candidate of counts.values()) {
43438
+ if (!dominant || candidate.count > dominant.count)
43439
+ dominant = candidate;
43440
+ }
43441
+ return dominant?.failure;
43442
+ }
43443
+
43444
+ // ../plugin/src/features/magic-context/memory/embedding-local.ts
42764
43445
  var BUN_NAPI_TEARDOWN_FIX_VERSION = [1, 4, 0];
42765
43446
  function currentLocalEmbeddingHost() {
42766
43447
  const bun = globalThis.Bun;
42767
- const bunVersion = typeof process !== "undefined" && typeof process.versions?.bun === "string" ? process.versions.bun : undefined;
43448
+ const hasProcess = typeof process !== "undefined";
43449
+ const bunVersion = hasProcess && typeof process.versions?.bun === "string" ? process.versions.bun : undefined;
42768
43450
  return {
42769
- isElectron: typeof process !== "undefined" && Boolean(process.versions?.electron),
43451
+ isElectron: hasProcess && Boolean(process.versions?.electron),
42770
43452
  isBun: Boolean(bun) || Boolean(bunVersion),
42771
- bunVersion
43453
+ bunVersion,
43454
+ hasNodeFilesystem: hasProcess && (typeof process.versions?.node === "string" || typeof bunVersion === "string")
42772
43455
  };
42773
43456
  }
42774
43457
  function bunHasNapiTeardownFix(version2) {
@@ -42839,6 +43522,7 @@ function startLockHeartbeat(lockPath) {
42839
43522
  return () => clearInterval(timer);
42840
43523
  }
42841
43524
  var localEmbeddingRuntimeMode = "native";
43525
+ var localEmbeddingProcessFailure = null;
42842
43526
  var wasmRuntimeInjected = false;
42843
43527
  var localEmbeddingHostForRuntime = currentLocalEmbeddingHost;
42844
43528
  var importWasmOrtForRuntime = async () => {
@@ -42857,6 +43541,10 @@ var importTransformersWasmFallbackForRuntime = async () => {
42857
43541
  const webEntry = new URL("./transformers-web.js", import.meta.url).href;
42858
43542
  return await import(webEntry);
42859
43543
  };
43544
+ var importTransformersNodeWasmFallbackForRuntime = async () => {
43545
+ const nodeWasmEntry = new URL("./transformers-node-wasm.js", import.meta.url).href;
43546
+ return await import(nodeWasmEntry);
43547
+ };
42860
43548
  var modelCacheDirForRuntime = () => join9(getMagicContextStorageDir(), "models");
42861
43549
  var logForRuntime = log;
42862
43550
  var injectWasmOrtForRuntime = injectWasmOrt;
@@ -42897,9 +43585,35 @@ function likelyMuslHint() {
42897
43585
  function localEmbeddingRuntimeIsDisabled() {
42898
43586
  return localEmbeddingRuntimeMode === "disabled";
42899
43587
  }
43588
+
43589
+ class LocalEmbeddingFallbackError extends Error {
43590
+ nativeError;
43591
+ constructor(nativeError, wasmError) {
43592
+ super("the native local embedding runtime and its WASM fallback both failed", {
43593
+ cause: wasmError
43594
+ });
43595
+ this.name = "LocalEmbeddingFallbackError";
43596
+ this.nativeError = nativeError;
43597
+ }
43598
+ }
43599
+
43600
+ class LocalEmbeddingFsUnavailableError extends Error {
43601
+ code = "MC_EMBEDDING_FS_UNAVAILABLE";
43602
+ constructor() {
43603
+ super("MC_EMBEDDING_FS_UNAVAILABLE: Node WASM bundle has no filesystem cache");
43604
+ this.name = "LocalEmbeddingFsUnavailableError";
43605
+ }
43606
+ }
43607
+ async function importWasmTransformersForHost() {
43608
+ const host = localEmbeddingHostForRuntime();
43609
+ if (host.isElectron) {
43610
+ return importTransformersForRuntime();
43611
+ }
43612
+ return host.hasNodeFilesystem ? importTransformersNodeWasmFallbackForRuntime() : importTransformersWasmFallbackForRuntime();
43613
+ }
42900
43614
  function disableLocalEmbeddingsAfterRuntimeFailure(detail) {
42901
43615
  localEmbeddingRuntimeMode = "disabled";
42902
- logForRuntime(`[magic-context] local embeddings are disabled because both the onnxruntime-node native binding and the onnxruntime-web (WASM) fallback failed to load. Native failure: ${detail}. Run \`npx @cortexkit/magic-context@latest doctor\` for repair guidance (use \`doctor --force\` to reinstall cached plugin packages), or configure an \`openai-compatible\` embedding HTTP endpoint. Existing memories are unaffected.`);
43616
+ logForRuntime(`[magic-context] local embeddings are disabled because both the onnxruntime-node native binding and the onnxruntime-web (WASM) fallback failed to load. Native failure: ${detail}. Run \`npx @cortexkit/magic-context@latest doctor\` for diagnostics; reinstalling repairs missing package files but cannot add a native binding that upstream does not ship. Alternatively, configure an \`openai-compatible\` embedding HTTP endpoint. Existing memories are unaffected.`);
42903
43617
  }
42904
43618
  async function loadTransformersForLocalEmbedding(runtimePreference) {
42905
43619
  if (localEmbeddingRuntimeMode === "disabled") {
@@ -42911,7 +43625,7 @@ async function loadTransformersForLocalEmbedding(runtimePreference) {
42911
43625
  disableLocalEmbeddingsAfterRuntimeFailure("the selected WASM runtime is unavailable");
42912
43626
  throw new Error("onnxruntime-web failed to load");
42913
43627
  }
42914
- return { module: await importTransformersForRuntime(), usesWasm: true };
43628
+ return { module: await importWasmTransformersForHost(), usesWasm: true };
42915
43629
  }
42916
43630
  if (localEmbeddingRuntimeMode === "wasm") {
42917
43631
  if (!await ensureWasmOrtInjected()) {
@@ -42919,7 +43633,7 @@ async function loadTransformersForLocalEmbedding(runtimePreference) {
42919
43633
  throw new Error("onnxruntime-web failed to load");
42920
43634
  }
42921
43635
  try {
42922
- return { module: await importTransformersWasmFallbackForRuntime(), usesWasm: true };
43636
+ return { module: await importWasmTransformersForHost(), usesWasm: true };
42923
43637
  } catch (wasmError) {
42924
43638
  disableLocalEmbeddingsAfterRuntimeFailure("the previously selected WASM runtime failed to load");
42925
43639
  throw wasmError;
@@ -42947,12 +43661,12 @@ async function loadTransformersForLocalEmbedding(runtimePreference) {
42947
43661
  }
42948
43662
  localEmbeddingRuntimeMode = "wasm";
42949
43663
  try {
42950
- const module = await importTransformersWasmFallbackForRuntime();
43664
+ const module = await importWasmTransformersForHost();
42951
43665
  logForRuntime("[magic-context] onnxruntime-node failed to load; using onnxruntime-web (WASM) for local embeddings. WASM inference is slower than native; a remote `openai-compatible` provider may be faster." + likelyMuslHint());
42952
43666
  return { module, usesWasm: true };
42953
43667
  } catch (wasmError) {
42954
43668
  disableLocalEmbeddingsAfterRuntimeFailure(nativeError instanceof Error ? nativeError.message : String(nativeError));
42955
- throw wasmError;
43669
+ throw new LocalEmbeddingFallbackError(nativeError, wasmError);
42956
43670
  }
42957
43671
  }
42958
43672
  }
@@ -43038,6 +43752,8 @@ class LocalEmbeddingProvider {
43038
43752
  runtimePreference;
43039
43753
  pipeline = null;
43040
43754
  initPromise = null;
43755
+ lastFailureReason = null;
43756
+ usesWasm = false;
43041
43757
  inFlight = 0;
43042
43758
  disposing = false;
43043
43759
  disposePromise = null;
@@ -43062,6 +43778,7 @@ class LocalEmbeddingProvider {
43062
43778
  return true;
43063
43779
  }
43064
43780
  if (localEmbeddingRuntimeMode === "disabled") {
43781
+ this.lastFailureReason = localEmbeddingProcessFailure ?? classifyLocalEmbeddingFailure(new Error("local embedding runtime is disabled"));
43065
43782
  return false;
43066
43783
  }
43067
43784
  if (this.initPromise) {
@@ -43074,11 +43791,16 @@ class LocalEmbeddingProvider {
43074
43791
  return;
43075
43792
  }
43076
43793
  const { module: transformersModule, usesWasm } = await loadTransformersForLocalEmbedding(this.runtimePreference);
43794
+ this.usesWasm = usesWasm;
43077
43795
  const env = transformersModule.env;
43078
43796
  const LogLevel = transformersModule.LogLevel;
43079
43797
  if (LogLevel && "ERROR" in LogLevel) {
43080
43798
  env.logLevel = LogLevel.ERROR;
43081
43799
  }
43800
+ const host = localEmbeddingHostForRuntime();
43801
+ if (usesWasm && host.hasNodeFilesystem && !host.isElectron && (env.useFS !== true || env.useFSCache !== true)) {
43802
+ throw new LocalEmbeddingFsUnavailableError;
43803
+ }
43082
43804
  const modelCacheDir = modelCacheDirForRuntime();
43083
43805
  try {
43084
43806
  if (shouldEnforcePrivateStoragePermissions()) {
@@ -43127,6 +43849,8 @@ class LocalEmbeddingProvider {
43127
43849
  }
43128
43850
  }
43129
43851
  if (this.pipeline) {
43852
+ this.lastFailureReason = null;
43853
+ localEmbeddingProcessFailure = null;
43130
43854
  log(`[magic-context] embedding model loaded: ${this.model}`);
43131
43855
  } else if (this.disposing) {
43132
43856
  return;
@@ -43138,11 +43862,19 @@ class LocalEmbeddingProvider {
43138
43862
  await releaseLock();
43139
43863
  }
43140
43864
  } catch (error51) {
43865
+ const nativeError = error51 instanceof LocalEmbeddingFallbackError ? error51.nativeError : undefined;
43866
+ const failure = classifyLocalEmbeddingFailure(error51, {
43867
+ platform: process.platform,
43868
+ arch: process.arch,
43869
+ usesWasm: this.usesWasm,
43870
+ nativeError
43871
+ });
43872
+ this.lastFailureReason = failure;
43873
+ localEmbeddingProcessFailure = failure;
43141
43874
  if (!localEmbeddingRuntimeIsDisabled() && isNativeRuntimeMissingError(error51)) {
43142
43875
  disableLocalEmbeddingsAfterRuntimeFailure(error51 instanceof Error ? error51.message : String(error51));
43143
- } else if (!localEmbeddingRuntimeIsDisabled()) {
43144
- logForRuntime("[magic-context] embedding model failed to load:", error51);
43145
43876
  }
43877
+ logForRuntime(`[magic-context] embedding model failed to load (${failure.class}: ${failure.reason}):`, error51);
43146
43878
  this.pipeline = null;
43147
43879
  } finally {
43148
43880
  this.initPromise = null;
@@ -43186,9 +43918,17 @@ class LocalEmbeddingProvider {
43186
43918
  pooling: "mean",
43187
43919
  normalize: true
43188
43920
  }));
43189
- return extractBatchEmbeddings(result, 1)[0] ?? null;
43921
+ const embedding = extractBatchEmbeddings(result, 1)[0] ?? null;
43922
+ if (!embedding) {
43923
+ this.lastFailureReason = classifyLocalEmbeddingFailure(new Error("local embedding pipeline returned no vector"), { usesWasm: this.usesWasm });
43924
+ } else {
43925
+ this.lastFailureReason = null;
43926
+ }
43927
+ return embedding;
43190
43928
  } catch (error51) {
43191
- log("[magic-context] embedding failed:", error51);
43929
+ const failure = classifyLocalEmbeddingFailure(error51, { usesWasm: this.usesWasm });
43930
+ this.lastFailureReason = failure;
43931
+ logForRuntime(`[magic-context] embedding failed (${failure.class}: ${failure.reason}):`, error51);
43192
43932
  return null;
43193
43933
  } finally {
43194
43934
  this.finishInFlight();
@@ -43217,9 +43957,17 @@ class LocalEmbeddingProvider {
43217
43957
  pooling: "mean",
43218
43958
  normalize: true
43219
43959
  }));
43220
- return extractBatchEmbeddings(result, texts.length);
43960
+ const embeddings = extractBatchEmbeddings(result, texts.length);
43961
+ if (embeddings.every((embedding) => embedding === null)) {
43962
+ this.lastFailureReason = classifyLocalEmbeddingFailure(new Error("local embedding pipeline returned no vectors"), { usesWasm: this.usesWasm });
43963
+ } else {
43964
+ this.lastFailureReason = null;
43965
+ }
43966
+ return embeddings;
43221
43967
  } catch (error51) {
43222
- log("[magic-context] embedding batch failed:", error51);
43968
+ const failure = classifyLocalEmbeddingFailure(error51, { usesWasm: this.usesWasm });
43969
+ this.lastFailureReason = failure;
43970
+ logForRuntime(`[magic-context] embedding batch failed (${failure.class}: ${failure.reason}):`, error51);
43223
43971
  return Array.from({ length: texts.length }, () => null);
43224
43972
  } finally {
43225
43973
  this.finishInFlight();
@@ -43252,6 +44000,9 @@ class LocalEmbeddingProvider {
43252
44000
  isLoaded() {
43253
44001
  return this.pipeline !== null;
43254
44002
  }
44003
+ getLastFailureReason() {
44004
+ return this.lastFailureReason;
44005
+ }
43255
44006
  }
43256
44007
 
43257
44008
  // ../plugin/src/features/magic-context/memory/embedding-ssrf.ts
@@ -43620,7 +44371,7 @@ class OpenAICompatibleEmbeddingProvider {
43620
44371
  }
43621
44372
 
43622
44373
  // ../plugin/src/features/magic-context/project-embedding-registry.ts
43623
- import { createHash as createHash11, randomUUID as randomUUID2 } from "node:crypto";
44374
+ import { createHash as createHash12, randomUUID as randomUUID2 } from "node:crypto";
43624
44375
 
43625
44376
  // ../plugin/src/features/magic-context/git-commits/storage-git-commit-embeddings.ts
43626
44377
  var saveStatements = new WeakMap;
@@ -44072,25 +44823,6 @@ function invalidateMemory(projectPath, memoryId) {
44072
44823
  }
44073
44824
  }
44074
44825
 
44075
- // ../plugin/src/features/magic-context/memory/embedding-failure.ts
44076
- function dominantEmbeddingFailure(failures) {
44077
- const counts = new Map;
44078
- for (const failure of failures) {
44079
- const key = `${failure.class}\x00${failure.reason}`;
44080
- const current = counts.get(key);
44081
- if (current)
44082
- current.count += 1;
44083
- else
44084
- counts.set(key, { failure, count: 1 });
44085
- }
44086
- let dominant;
44087
- for (const candidate of counts.values()) {
44088
- if (!dominant || candidate.count > dominant.count)
44089
- dominant = candidate;
44090
- }
44091
- return dominant?.failure;
44092
- }
44093
-
44094
44826
  // ../plugin/src/features/magic-context/session-project-storage.ts
44095
44827
  var SESSION_CHUNK_REPAIR_BATCH_SIZE = 100;
44096
44828
  var upsertSessionProjectStatements = new WeakMap;
@@ -44341,10 +45073,10 @@ function stableStringify2(value) {
44341
45073
  return JSON.stringify(value);
44342
45074
  }
44343
45075
  function sha256Prefix(value, length = 16) {
44344
- return createHash11("sha256").update(value).digest("hex").slice(0, length);
45076
+ return createHash12("sha256").update(value).digest("hex").slice(0, length);
44345
45077
  }
44346
45078
  function contentSha256(value) {
44347
- return createHash11("sha256").update(value).digest("hex");
45079
+ return createHash12("sha256").update(value).digest("hex");
44348
45080
  }
44349
45081
  function getRuntimeFingerprint(config2) {
44350
45082
  if (config2.provider === "off") {
@@ -44885,13 +45617,17 @@ async function processShadowQueueItem(item) {
44885
45617
  const placeholders3 = boundedIds.map(() => "?").join(",");
44886
45618
  const candidates = db.prepare(`SELECT id, session_id, start_message, end_message
44887
45619
  FROM compartments WHERE id IN (${placeholders3})`).all(...boundedIds.map((id) => Number(id)));
44888
- const prepared = candidates.flatMap((candidate) => {
44889
- const text = buildCanonicalChunkTextFromFts(db, candidate.session_id, candidate.start_message, candidate.end_message) || buildCompartmentSummaryFallbackText(db, candidate.id);
44890
- if (!text)
44891
- return [];
44892
- const windows = chunkCanonicalText(text, candidate.start_message, candidate.end_message, SYNAPSE_MAX_INPUT_TOKENS);
44893
- return windows.length > 0 ? [{ candidate, windows }] : [];
44894
- });
45620
+ const prepared = [];
45621
+ for (const candidate of candidates) {
45622
+ const mappedText = buildCanonicalChunkTextFromFts(db, candidate.session_id, candidate.start_message, candidate.end_message);
45623
+ if (mappedText !== null) {
45624
+ const text = mappedText || buildCompartmentSummaryFallbackText(db, candidate.id);
45625
+ const windows = chunkCanonicalText(text, candidate.start_message, candidate.end_message, SYNAPSE_MAX_INPUT_TOKENS);
45626
+ if (windows.length > 0)
45627
+ prepared.push({ candidate, windows });
45628
+ }
45629
+ await new Promise((resolve5) => setTimeout(resolve5, 0));
45630
+ }
44895
45631
  const items = prepared.flatMap((item2) => item2.windows.map((window) => ({
44896
45632
  id: `chunk:${item2.candidate.id}:${window.windowIndex}`,
44897
45633
  text: window.text,
@@ -45236,7 +45972,11 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
45236
45972
  const maxInputTokens = getProjectEmbeddingMaxInputTokens(projectIdentity);
45237
45973
  const prepared = [];
45238
45974
  for (const candidate of candidates) {
45239
- const canonicalText = buildCanonicalChunkTextFromFts(db, candidate.sessionId, candidate.startMessage, candidate.endMessage) || buildCompartmentSummaryFallbackText(db, candidate.id);
45975
+ await new Promise((resolve5) => setTimeout(resolve5, 0));
45976
+ const mappedText = buildCanonicalChunkTextFromFts(db, candidate.sessionId, candidate.startMessage, candidate.endMessage);
45977
+ if (mappedText === null)
45978
+ continue;
45979
+ const canonicalText = mappedText || buildCompartmentSummaryFallbackText(db, candidate.id);
45240
45980
  if (canonicalText.length === 0) {
45241
45981
  noWork.push(candidate.id);
45242
45982
  continue;
@@ -45527,7 +46267,7 @@ async function embedText(text, signal) {
45527
46267
  }
45528
46268
 
45529
46269
  // ../plugin/src/plugin/embedding-bootstrap-helpers.ts
45530
- import { createHash as createHash12 } from "node:crypto";
46270
+ import { createHash as createHash13 } from "node:crypto";
45531
46271
  var EMBEDDING_AFFECTING_KEYS = new Set([
45532
46272
  "embedding.api_key",
45533
46273
  "embedding.endpoint",
@@ -45573,7 +46313,7 @@ var EMBEDDING_WARNING_TERMS = [
45573
46313
  ];
45574
46314
  var loggedFailureSignatures = new Map;
45575
46315
  function sha256Prefix2(value, length = 16) {
45576
- return createHash12("sha256").update(value).digest("hex").slice(0, length);
46316
+ return createHash13("sha256").update(value).digest("hex").slice(0, length);
45577
46317
  }
45578
46318
  function warningLooksEmbeddingRelated(message) {
45579
46319
  const lower = message.toLowerCase();
@@ -50702,6 +51442,87 @@ function createCtxExpandTool(deps) {
50702
51442
  }
50703
51443
  };
50704
51444
  }
51445
+
51446
+ // ../plugin/src/features/magic-context/dreamer/memory-claim-safety.ts
51447
+ var POLICY_SENTENCE_START = /(?:^|[.!?]\s+|\n\s*)(?:[-*]\s+|\d+[.)]\s+)?(?:you\s+|we\s+)?(?:must(?:\s+not)?|never|always|do\s+not|don't|shall\s+not)\b/i;
51448
+ var ACTOR_POLICY = /\b(?:you|we|agents?|masons?|workers?|operators?|users?|maintainers?)\s+(?:must(?:\s+not)?|should(?:\s+not)?|need\s+to|shall(?:\s+not)?|cannot|can't|may\s+not)\b/i;
51449
+ var BEHAVIORAL_WHEN_CLAUSE = /\bwhen\s+(?:you(?:'re|\s+are)?|we(?:'re|\s+are)?|told|asked|requested|working|debugging|reviewing|checking|verifying|investigating|using|running|editing|changing)\b/i;
51450
+ var WORKFLOW_IMPERATIVE = /(?:^|[.!?]\s+|\n\s*)(?:[-*]\s+|\d+[.)]\s+)?(?:please\s+)?(?:run|use|check|ask|avoid|prefer|ensure|keep|follow|brief|report|inspect|search|open|read|review|validate|confirm|delegate|stop|start|remember)\b/i;
51451
+ var DECISION_AUTHORITY = /\b(?:the\s+)?(?:user|operator|maintainer|owner)\s+(?:decides|chooses|approves|has\s+(?:the\s+)?final\s+say)\b/i;
51452
+ function isDirectiveShapedProjectRule(category, content) {
51453
+ if (category !== "PROJECT_RULES")
51454
+ return false;
51455
+ const text = content.trim();
51456
+ if (!text)
51457
+ return false;
51458
+ return POLICY_SENTENCE_START.test(text) || ACTOR_POLICY.test(text) || BEHAVIORAL_WHEN_CLAUSE.test(text) || WORKFLOW_IMPERATIVE.test(text) || DECISION_AUTHORITY.test(text);
51459
+ }
51460
+
51461
+ // ../plugin/src/features/magic-context/dreamer/curate-memory-safety.ts
51462
+ var PROJECT_SCOPED_CATEGORIES = new Set([
51463
+ "PROJECT_RULES",
51464
+ "ARCHITECTURE",
51465
+ "CONSTRAINTS",
51466
+ "CONFIG_VALUES",
51467
+ "NAMING"
51468
+ ]);
51469
+ var USER_PROFILE_REFERENCE = /\buser(?:[\s_-]+)(?:profile|preferences?)\b|\bU\d+\b/i;
51470
+ var refusalCountsBySession = new Map;
51471
+ function isSurvivingConsolidationTarget(memory2, successor, projectIdentity) {
51472
+ return successor !== null && successor.id !== memory2.id && successor.status === "active" && successor.supersededByMemoryId === null && (successor.expiresAt === null || successor.expiresAt > Date.now()) && projectIdentity(successor) === projectIdentity(memory2) && successor.category === memory2.category;
51473
+ }
51474
+ function assessCurateMutationSafety(args) {
51475
+ const { memory: memory2, successor, verdict } = args;
51476
+ if (verdict === "archive") {
51477
+ if (!isSurvivingConsolidationTarget(memory2, successor, args.projectIdentity)) {
51478
+ return {
51479
+ memoryId: memory2.id,
51480
+ verdict,
51481
+ reason: "missing-active-same-category-successor"
51482
+ };
51483
+ }
51484
+ if (PROJECT_SCOPED_CATEGORIES.has(memory2.category) && USER_PROFILE_REFERENCE.test(args.reason ?? "")) {
51485
+ return {
51486
+ memoryId: memory2.id,
51487
+ verdict,
51488
+ reason: "user-profile-is-not-project-memory"
51489
+ };
51490
+ }
51491
+ }
51492
+ if (isDirectiveShapedProjectRule(memory2.category, memory2.content)) {
51493
+ return {
51494
+ memoryId: memory2.id,
51495
+ verdict,
51496
+ reason: "directive-shaped-project-rule"
51497
+ };
51498
+ }
51499
+ if (verdict === "update") {
51500
+ const originalChars = memory2.content.trim().length;
51501
+ const replacementChars = args.replacementContent?.trim().length ?? 0;
51502
+ if (replacementChars * 2 < originalChars && !isSurvivingConsolidationTarget(memory2, successor, args.projectIdentity)) {
51503
+ return {
51504
+ memoryId: memory2.id,
51505
+ verdict,
51506
+ reason: "content-loss",
51507
+ originalChars,
51508
+ replacementChars
51509
+ };
51510
+ }
51511
+ }
51512
+ return null;
51513
+ }
51514
+ function recordCurateSafetyRefusal(sessionId, refusal) {
51515
+ const count = (refusalCountsBySession.get(sessionId) ?? 0) + 1;
51516
+ refusalCountsBySession.set(sessionId, count);
51517
+ const lengths = refusal.originalChars === undefined ? "" : ` original_chars=${refusal.originalChars} replacement_chars=${refusal.replacementChars ?? 0}`;
51518
+ log(`[dreamer] curate safety refusal: session_id=${sessionId} memory_id=${refusal.memoryId} verdict=${refusal.verdict} reason=${refusal.reason}${lengths} refused=${count}`);
51519
+ return count;
51520
+ }
51521
+ function takeCurateSafetyRefusalCount(sessionId) {
51522
+ const count = refusalCountsBySession.get(sessionId) ?? 0;
51523
+ refusalCountsBySession.delete(sessionId);
51524
+ return count;
51525
+ }
50705
51526
  // ../plugin/src/features/magic-context/memory/embedding-backfill.ts
50706
51527
  async function ensureMemoryEmbeddings(args) {
50707
51528
  const snapshot = getProjectEmbeddingSnapshot(args.projectIdentity);
@@ -50743,9 +51564,9 @@ async function ensureMemoryEmbeddings(args) {
50743
51564
  return args.existingEmbeddings;
50744
51565
  }
50745
51566
  // ../plugin/src/features/magic-context/mural/storage-mural-cues.ts
50746
- import { createHash as createHash13 } from "node:crypto";
51567
+ import { createHash as createHash14 } from "node:crypto";
50747
51568
  function computeCueContentHash(content) {
50748
- return createHash13("sha256").update(content).digest("hex");
51569
+ return createHash14("sha256").update(content).digest("hex");
50749
51570
  }
50750
51571
  var muralCueColumnCache = new WeakMap;
50751
51572
  var muralCueRejectionColumnCache = new WeakMap;
@@ -52014,7 +52835,7 @@ var ALL_ACTIONS = [
52014
52835
  ];
52015
52836
  var DREAMER_ONLY_ACTIONS = new Set(["list"]);
52016
52837
  var GET_MAX_IDS = 20;
52017
- var ParamsSchema2 = exports_typebox.Object({
52838
+ var ParamsShape = {
52018
52839
  action: exports_typebox.Optional(exports_typebox.Union(ALL_ACTIONS.map((a) => exports_typebox.Literal(a)), {
52019
52840
  description: "What to do: write, update, archive, merge, get, or list"
52020
52841
  })),
@@ -52033,6 +52854,15 @@ var ParamsSchema2 = exports_typebox.Object({
52033
52854
  reason: exports_typebox.Optional(exports_typebox.String({
52034
52855
  description: "Why the memory is being archived (optional, recommended)"
52035
52856
  }))
52857
+ };
52858
+ var PrimaryParamsSchema = exports_typebox.Object(ParamsShape, {
52859
+ additionalProperties: true
52860
+ });
52861
+ var DreamerParamsSchema = exports_typebox.Object({
52862
+ ...ParamsShape,
52863
+ superseded_by: exports_typebox.Optional(exports_typebox.Number({
52864
+ description: "Active same-project/category memory that survives a curate consolidation"
52865
+ }))
52036
52866
  }, { additionalProperties: true });
52037
52867
  function ok2(text) {
52038
52868
  return { content: [{ type: "text", text }], details: undefined };
@@ -52158,7 +52988,7 @@ function createCtxMemoryTool(deps) {
52158
52988
  name: "ctx_memory",
52159
52989
  label: "Magic Context: Memory",
52160
52990
  description,
52161
- parameters: ParamsSchema2,
52991
+ parameters: dreamerAllowed ? DreamerParamsSchema : PrimaryParamsSchema,
52162
52992
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
52163
52993
  params = unwrapImitatedReducedArgs(params, ["action"], {
52164
52994
  action: { type: "enum", values: ALL_ACTIONS },
@@ -52166,7 +52996,8 @@ function createCtxMemoryTool(deps) {
52166
52996
  category: { type: "enum", values: V2_MEMORY_CATEGORIES },
52167
52997
  ids: { type: "array", items: "number", maxItems: 100 },
52168
52998
  limit: "number",
52169
- reason: "string"
52999
+ reason: "string",
53000
+ superseded_by: "number"
52170
53001
  });
52171
53002
  if (params.action === undefined) {
52172
53003
  return err2("Error: Action 'undefined' is not allowed in this context.");
@@ -52202,6 +53033,44 @@ function createCtxMemoryTool(deps) {
52202
53033
  return err2("Cross-session memory is disabled for this project.");
52203
53034
  }
52204
53035
  const sessionId = ctx.sessionManager.getSessionId();
53036
+ let curateSuccessor = null;
53037
+ if (dreamerAllowed && (params.action === "archive" || params.action === "update")) {
53038
+ const verdict = params.action;
53039
+ const ids = params.ids;
53040
+ const content = params.content?.trim();
53041
+ const validShape = ids && ids.length > 0 && ids.every(Number.isInteger) && (verdict !== "update" || ids.length === 1 && Boolean(content));
53042
+ if (validShape) {
53043
+ const uniqueIds = [...new Set(ids)];
53044
+ const memories = uniqueIds.map((id) => getMemoryById(deps.db, id));
53045
+ if (memories.every((memory2) => memory2 && memoryVisibleToTool(memory2))) {
53046
+ curateSuccessor = Number.isInteger(params.superseded_by) ? getMemoryById(deps.db, params.superseded_by) : null;
53047
+ const refusals = memories.flatMap((memory2) => {
53048
+ if (!memory2)
53049
+ return [];
53050
+ const refusal = assessCurateMutationSafety({
53051
+ memory: memory2,
53052
+ verdict,
53053
+ reason: params.reason,
53054
+ replacementContent: content,
53055
+ successor: curateSuccessor,
53056
+ projectIdentity: (candidate) => targetIdentityForStoredPath(candidate.projectPath)
53057
+ });
53058
+ return refusal ? [refusal] : [];
53059
+ });
53060
+ if (refusals.length > 0) {
53061
+ let refused = 0;
53062
+ for (const refusal of refusals) {
53063
+ refused = recordCurateSafetyRefusal(sessionId, refusal);
53064
+ }
53065
+ const memoryIds = refusals.map((refusal) => refusal.memoryId).join(", ");
53066
+ const reasons = [
53067
+ ...new Set(refusals.map((refusal) => refusal.reason))
53068
+ ].join(",");
53069
+ return ok2(`Skipped ${verdict} for memory [ID: ${memoryIds}]: curate safety refusal (${reasons}); refused=${refused}.`);
53070
+ }
53071
+ }
53072
+ }
53073
+ }
52205
53074
  if (params.action === "write") {
52206
53075
  const content = params.content?.trim();
52207
53076
  if (!content)
@@ -52429,11 +53298,21 @@ function createCtxMemoryTool(deps) {
52429
53298
  runImmediateTransaction(deps.db, () => {
52430
53299
  for (const target2 of targets) {
52431
53300
  archiveMemory(deps.db, target2.memoryId, params.reason);
52432
- queueMemoryMutation(deps.db, {
52433
- projectPath: target2.projectIdentity,
52434
- mutationType: "archive",
52435
- targetMemoryId: target2.memoryId
52436
- });
53301
+ if (dreamerAllowed && curateSuccessor) {
53302
+ supersededMemory(deps.db, target2.memoryId, curateSuccessor.id);
53303
+ queueMemoryMutation(deps.db, {
53304
+ projectPath: target2.projectIdentity,
53305
+ mutationType: "superseded",
53306
+ targetMemoryId: target2.memoryId,
53307
+ supersededById: curateSuccessor.id
53308
+ });
53309
+ } else {
53310
+ queueMemoryMutation(deps.db, {
53311
+ projectPath: target2.projectIdentity,
53312
+ mutationType: "archive",
53313
+ targetMemoryId: target2.memoryId
53314
+ });
53315
+ }
52437
53316
  }
52438
53317
  });
52439
53318
  const reasonSuffix = params.reason ? ` (${params.reason})` : "";
@@ -53018,7 +53897,7 @@ var FILTER_VALUES = [
53018
53897
  "dismissed",
53019
53898
  "all"
53020
53899
  ];
53021
- var ParamsSchema3 = exports_typebox.Object({
53900
+ var ParamsSchema2 = exports_typebox.Object({
53022
53901
  action: exports_typebox.Optional(exports_typebox.Union([
53023
53902
  exports_typebox.Literal("write"),
53024
53903
  exports_typebox.Literal("read"),
@@ -53095,7 +53974,7 @@ function createCtxNoteTool(deps) {
53095
53974
  name: "ctx_note",
53096
53975
  label: "Magic Context: Notes",
53097
53976
  description: CTX_NOTE_DESCRIPTION,
53098
- parameters: ParamsSchema3,
53977
+ parameters: ParamsSchema2,
53099
53978
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
53100
53979
  params = unwrapImitatedReducedArgs(params, ["action", "content"], {
53101
53980
  action: {
@@ -53375,7 +54254,7 @@ Keep: user messages, unresolved errors, raw evidence you haven't extracted yet,
53375
54254
  Never blanket-mark large ranges (e.g. "1-50") — review what each tag holds first.`;
53376
54255
 
53377
54256
  // src/tools/ctx-reduce.ts
53378
- var ParamsSchema4 = exports_typebox.Object({
54257
+ var ParamsSchema3 = exports_typebox.Object({
53379
54258
  drop: exports_typebox.Optional(exports_typebox.String({
53380
54259
  description: "Tag IDs to drop entirely. Ranges: '3-5', '1,2,9'"
53381
54260
  }))
@@ -53398,7 +54277,7 @@ function createCtxReduceTool(deps) {
53398
54277
  name: "ctx_reduce",
53399
54278
  label: "Magic Context: Reduce",
53400
54279
  description: CTX_REDUCE_DESCRIPTION,
53401
- parameters: ParamsSchema4,
54280
+ parameters: ParamsSchema3,
53402
54281
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
53403
54282
  params = unwrapImitatedReducedArgs(params, ["drop"], { drop: "string" });
53404
54283
  const sessionId = ctx.sessionManager.getSessionId();
@@ -53423,11 +54302,16 @@ function createCtxReduceTool(deps) {
53423
54302
  const protectedTagIds = activeTags.map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, protectedTags);
53424
54303
  const protectedSet = new Set(protectedTagIds);
53425
54304
  const tagStatusMap = new Map(allTags.map((tag) => [tag.tagNumber, tag.status]));
54305
+ const inertWhitespaceTagNumbers = new Set(getInertWhitespaceAssistantTags(deps.db, sessionId).map((tag) => tag.tagNumber));
54306
+ const inertDropIds = [
54307
+ ...new Set(dropIds.filter((id) => inertWhitespaceTagNumbers.has(id)))
54308
+ ];
54309
+ const inertNote = inertDropIds.length > 0 ? `Skipped: ${inertDropIds.map((id) => `§${id}§ is provider framing, nothing to reclaim`).join("; ")}.` : "";
53426
54310
  const pendingOps = getPendingOps(deps.db, sessionId);
53427
54311
  const pendingMap = new Map(pendingOps.map((op) => [op.tagId, op.operation]));
53428
54312
  const conflicts = [];
53429
54313
  for (const id of dropIds) {
53430
- if (tagStatusMap.get(id) === "compacted") {
54314
+ if (tagStatusMap.get(id) === "compacted" && !inertWhitespaceTagNumbers.has(id)) {
53431
54315
  conflicts.push(`§${id}§ is from before compaction`);
53432
54316
  }
53433
54317
  }
@@ -53435,10 +54319,13 @@ function createCtxReduceTool(deps) {
53435
54319
  return err4(`Error: Conflicting operations — ${conflicts.join("; ")}.`);
53436
54320
  }
53437
54321
  const preFilterDropCount = dropIds.length;
53438
- dropIds = dropIds.filter((id) => tagStatusMap.get(id) !== "dropped" && pendingMap.get(id) !== "drop");
54322
+ dropIds = dropIds.filter((id) => !inertWhitespaceTagNumbers.has(id) && tagStatusMap.get(id) !== "dropped" && pendingMap.get(id) !== "drop");
53439
54323
  const skippedCount = preFilterDropCount - dropIds.length;
53440
54324
  if (dropIds.length === 0) {
53441
- return ok4("All requested tags were already queued or processed. No new action is needed.");
54325
+ return ok4([
54326
+ inertNote,
54327
+ "All requested tags were already queued or processed. No new action is needed."
54328
+ ].filter(Boolean).join(" "));
53442
54329
  }
53443
54330
  try {
53444
54331
  deps.db.transaction(() => {
@@ -53464,7 +54351,7 @@ function createCtxReduceTool(deps) {
53464
54351
  parts.push(`drop ${formatIds(immediateDropIds)}`);
53465
54352
  if (deferredDropIds.length > 0)
53466
54353
  parts.push(`deferred drop ${formatIds(deferredDropIds)}`);
53467
- return ok4(`Queued: ${parts.join(", ")}.${skippedNote}`);
54354
+ return ok4(`Queued: ${parts.join(", ")}.${skippedNote}${inertNote ? ` ${inertNote}` : ""}`);
53468
54355
  }
53469
54356
  };
53470
54357
  }
@@ -53865,7 +54752,7 @@ function containsProbeVerbatim(text, probes) {
53865
54752
  }
53866
54753
 
53867
54754
  // ../plugin/src/features/magic-context/search-measurement.ts
53868
- import { createHash as createHash14 } from "node:crypto";
54755
+ import { createHash as createHash15 } from "node:crypto";
53869
54756
  function resultId(result) {
53870
54757
  switch (result.source) {
53871
54758
  case "memory":
@@ -53952,7 +54839,7 @@ async function recordShadowMeasurement(args) {
53952
54839
  }
53953
54840
  }
53954
54841
  function sha2562(value) {
53955
- return createHash14("sha256").update(value).digest("hex");
54842
+ return createHash15("sha256").update(value).digest("hex");
53956
54843
  }
53957
54844
 
53958
54845
  // ../plugin/src/features/magic-context/search.ts
@@ -55210,7 +56097,7 @@ ${bodyParts.join(`
55210
56097
  }
55211
56098
 
55212
56099
  // ../plugin/src/features/magic-context/mural/render-trigger.ts
55213
- import { createHash as createHash15 } from "node:crypto";
56100
+ import { createHash as createHash16 } from "node:crypto";
55214
56101
 
55215
56102
  // ../plugin/src/features/magic-context/mural/mural-selection.ts
55216
56103
  var DEFAULT_MURAL_MEMORY_BUDGET = 8000;
@@ -55836,7 +56723,7 @@ function ensureMuralRendered(db, projectIdentity, budgetTokens = DEFAULT_MURAL_M
55836
56723
  return { hasMural: false, rerendered: false };
55837
56724
  }
55838
56725
  const rendered = renderMural(entries);
55839
- const textHash = createHash15("sha256").update(rendered.sha256Input).digest("hex");
56726
+ const textHash = createHash16("sha256").update(rendered.sha256Input).digest("hex");
55840
56727
  const existing = getMural(db, projectIdentity);
55841
56728
  if (existing && existing.contentHash === textHash && existing.width === rendered.width && existing.height === rendered.height) {
55842
56729
  return {
@@ -56066,7 +56953,7 @@ class BoundedSessionMap {
56066
56953
  }
56067
56954
 
56068
56955
  // ../plugin/src/features/magic-context/compaction-marker.ts
56069
- import { createHash as createHash16 } from "node:crypto";
56956
+ import { createHash as createHash17 } from "node:crypto";
56070
56957
  import { existsSync as existsSync14 } from "node:fs";
56071
56958
  import { join as join12 } from "node:path";
56072
56959
  var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -56074,7 +56961,7 @@ var ID_PREFIX_HEX_LENGTH = 12;
56074
56961
  var ID_SUFFIX_LENGTH = 14;
56075
56962
  var ID_PREFIX_MASK = (1n << BigInt(ID_PREFIX_HEX_LENGTH * 4)) - 1n;
56076
56963
  function deterministicBase62(seed, length) {
56077
- let value = BigInt(`0x${createHash16("sha256").update(seed).digest("hex")}`);
56964
+ let value = BigInt(`0x${createHash17("sha256").update(seed).digest("hex")}`);
56078
56965
  const chars = Array(length);
56079
56966
  for (let index = length - 1;index >= 0; index -= 1) {
56080
56967
  chars[index] = BASE62_CHARS[Number(value % 62n)];
@@ -56972,7 +57859,7 @@ Picking sources:
56972
57859
 
56973
57860
  // src/tools/ctx-search.ts
56974
57861
  var DEFAULT_LIMIT = 10;
56975
- var ParamsSchema5 = exports_typebox.Object({
57862
+ var ParamsSchema4 = exports_typebox.Object({
56976
57863
  query: exports_typebox.Optional(exports_typebox.String({
56977
57864
  description: "Search query. Matches against memory content, Primers, git commit messages, and raw user/assistant message text."
56978
57865
  })),
@@ -57000,7 +57887,7 @@ function createCtxSearchTool(deps) {
57000
57887
  name: "ctx_search",
57001
57888
  label: "Magic Context: Search",
57002
57889
  description: CTX_SEARCH_DESCRIPTION,
57003
- parameters: ParamsSchema5,
57890
+ parameters: ParamsSchema4,
57004
57891
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
57005
57892
  params = unwrapImitatedReducedArgs(params, ["query"], {
57006
57893
  query: "string",
@@ -57149,6 +58036,14 @@ function createTodowriteTool() {
57149
58036
  }
57150
58037
 
57151
58038
  // src/tools/index.ts
58039
+ var CTX_MEMORY_TOOL_NAME = "ctx_memory";
58040
+ function syncCtxMemoryToolEnabled(pi, memoryEnabled) {
58041
+ const activeTools = pi.getActiveTools();
58042
+ const isActive = activeTools.includes(CTX_MEMORY_TOOL_NAME);
58043
+ if (memoryEnabled === isActive)
58044
+ return;
58045
+ pi.setActiveTools(memoryEnabled ? [...activeTools, CTX_MEMORY_TOOL_NAME] : activeTools.filter((toolName) => toolName !== CTX_MEMORY_TOOL_NAME));
58046
+ }
57152
58047
  function registerMagicContextTools(pi, opts) {
57153
58048
  const resolveProjectIdentity2 = opts.resolveProjectIdentity ? (directory) => opts.resolveProjectIdentity?.({ cwd: directory }) : undefined;
57154
58049
  const promptSurfaceRuntime = opts.promptSurfaceRuntime ?? createPromptSurfaceRuntime({
@@ -57202,4 +58097,4 @@ function registerMagicContextTools(pi, opts) {
57202
58097
  }
57203
58098
  }
57204
58099
 
57205
- export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, migrateMagicContextConfigLocations, FAIL_CLOSED_DOCTOR_COMMAND, formatFailClosedBlockingMessage, createFailClosedBlockingError, isFailClosedBlockingError, shouldBypassFailClosedBlock, createFailClosedController, ProjectIdentityError, resolveProjectIdentityStrict, resolveProjectIdentity, resolveProjectIdentityForSession, beginBootQuietPeriod, scheduleAfterBootQuiet, Database, closeQuietly, isMidTurn, textMentionsRecentCommit, hasMeaningfulUserText, extractTexts, extractToolCallSummaries, preloadTokenizer, estimateTokens, normalizeText, isRecord, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForCompletedToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isEditTool, applyEditMarkerToInput, setRawMessageProvider, withRawMessageProvider, cleanUserText, withRawSessionMessageCache, readRawSessionMessages, primeTailRawMessageCache, getCachedAbsoluteMessageCount, primeInMemoryTailRawMessageCache, getRawSessionMessageCount, getRawSessionTagKeysThrough, getLegacyProtectedTailStartOrdinal, readSessionChunk, clearCompressionDepth, clearCompressionDepthRange, getMessageIndexSourceIdentity, isMessageIndexSourceCurrent, getLastIndexedOrdinal, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, indexSingleMessage, indexMessagesAfterOrdinal, sweepOrphanedOpenCodeMessageIndexes, recordSessionProjectIdentity, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, isCompartmentLeaseHeld, piModelRefToCanonical, resolveModelRefForPi, modelRefLookupOrder, ompModelRefToCanonical, resolveModelRefForOmp, persistCachedM0, clearCachedM0M1, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getCompartmentsByEndMessageId, appendCompartments, saveRecompStagingPass, getRecompStaging, clearRecompStaging, getRecompPartialRange, setRecompPartialRange, escapeXmlAttr, escapeXmlContent, getModuleNoteEvaluationBridge, getContextStoreUuid, parseCompartmentOutput, logSlowWriteTransaction, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, sourceNameForMemory, computeWorkspaceEpochFingerprint, bumpEpochsForWorkspaceMembers, readProjectDocsCanonical, copySessionStateForClone, getErrorMessage, describeError, setStoragePrivatePermissionEnforcement, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, applySqliteTuningPragmas, runSqliteOptimize, openDatabase, openDatabaseAsync, queueM0Mutation, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRender, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationId, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, describeProtectedTailDrainBudgetSkip, loadProtectedTailMeta, markProtectedTailPolicyV3Seeded, recordProtectedTailPublicationFloor, recordProtectedTailNoEligibleHead, getWrapupInProgressState, isWrapupInProgress, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, reserveProtectedTailDrainTokens, clearEmergencyDrainLatch, recordHistorianDrainFailure, clearHistorianDrainFailure, rollbackProtectedTailDrainReservation, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getChannel1NudgeState, setChannel1NudgeState, markChannel1PostReduceGracePending, captureChannel1PostReduceGraceBaseline, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, setPersistedNoteNudgeTrigger, setPersistedNoteNudgeTriggerMessageId, getNoteNudgeAnchors, getAutoSearchHintDecisions, deliverNoteNudgeAtomic, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, getNoteLastReadAt, getHistorianFailureState, incrementHistorianFailure, clearHistorianFailureState, getOverflowState, recordOverflowDetected, clearEmergencyRecovery, clearDetectedContextLimit, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, getPendingPiCompactionMarkerState, setPendingPiCompactionMarkerState, clearPendingPiCompactionMarkerStateIf, getSessionsWithPendingPiMarker, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, setSessionWorkMetrics, getSessionWorkMetrics, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, retryPendingSessionCleanups, getNotes, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, getPendingOpsCount, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, insertPrimerCandidates, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, recordSubagentInvocation, getLatestHistorianInvocationId, CTX_REDUCE_KEEP, estimateImageTokensFromDataUrl, normalizeTodoStateJson, buildSyntheticTodoPart, stripChannel1ReminderSpans, effectiveTailHygiene, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, decideChannel1, evaluateChannel2, reclaimableToolOutputCount, buildChannel2Reminder, buildChannel1Reminder, planEmergencyDrop, updateTagByteSize, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, updateTagInputByteSize, updateTagTokenCount, getPersistedToolTagAccounting, getAllStatusTagTokenTotalsFlat, updateTagInputTokenCount, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, hasPiFallbackMessageTags, findAdoptableFallbackTags, hasPiFallbackToolOwnerTags, findPiFallbackToolOwnerTags, adoptPiFallbackToolOwnerTag, adoptPiFallbackMessageTag, getMaxTagNumberBySession, getTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getTagsForPendingOperations, getTagsByNumbers, getDroppedTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, BoundedSessionMap, getWindowOverlay, resolveWindowOverlayFacts, deriveWindowGeometry, formatWindowDerivationLine, isSaneLimit, resolveOutputReserve, getSdkContextLimit, resolveModelConfigOrDefault, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, SYNTH_USER_ID_PREFIX, resolvePiStableId, isMidTurnPi, readPiSessionSnapshot, readPiSessionMessages, findLastModelKeyFromBranch, convertEntriesToRawMessages, withContentLanguageDirective, withMigrationLanguageDirective, buildPrimaryLanguageDirective, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, invalidateMemory, computeNormalizedHash, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, insertMemory, getMemoryByHash, getMemoriesByProject, getMemoriesByProjects, getMaxMemoryIdForProjects, getAllActiveMemoriesForMigration, getMemoryById, setMemoryClassification, archiveMemory, deleteMemory, getMemoryCount, getMemoryCountsByStatus, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, getOpenCodeDbPath2 as getOpenCodeDbPath, parseCron, nextOccurrence, nextDueAtMs, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, buildCanonicalChunkTextFromFts, buildCompartmentSummaryFallbackText, canonicalizeInMemoryChunkTextForEmbedding, chunkCanonicalText, chunkEmbeddingWindowsAreCurrent, replaceCompartmentChunkEmbeddings, cosineSimilarity, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, contentSha256, sweepStaleEmbeddingIdentitiesForProject, enqueueShadowEmbeddingItems, getProjectEmbeddingSnapshot, getProjectChunkEmbeddingModelId, getProjectEmbeddingMaxInputTokens, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, promoteSessionFactsDurable, embedPromotedFacts, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, wakePlaneStatus, indexCommitsForProject, embedUnembeddedCommits, loadPiConfig, ensureProjectRegisteredFromPiDirectory, resolveMuralWire, updateCompactionMarkerAfterPublication, COMPARTMENT_RENDER_EPOCH, encodeCachedM0UpgradeIdentity, decodeCachedM0UpgradeIdentity, DEFAULT_HISTORY_BUDGET_TOKENS, renderCompartmentAtTier, renderDecayedCompartments, extractM0Block, TEMPORAL_MARKER_PATTERN, temporalMarkerPrefix, clearInjectionCache, getVisibleMemoryIds, renderMemoryBlock, DEFAULT_MEMORY_BUDGET_TOKENS, DEFAULT_USER_PROFILE_BUDGET_TOKENS, trimMemoriesToBudgetV2, trimWorkspaceMemoriesToBudgetV2, trimUserMemoriesToBudget, renderMemoryBlockV2, stripMemoryMuralBlock, unifiedSearch, rememberTodowriteToolCallTodos, parseTodos, setTodoSnapshot, registerTodoOverlay, registerTodoStateLifecycle, registerMagicContextTools };
58100
+ export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, migrateMagicContextConfigLocations, FAIL_CLOSED_DOCTOR_COMMAND, formatFailClosedBlockingMessage, createFailClosedBlockingError, isFailClosedBlockingError, shouldBypassFailClosedBlock, createFailClosedController, ProjectIdentityError, resolveProjectIdentityStrict, resolveProjectIdentity, resolveProjectIdentityForSession, beginBootQuietPeriod, scheduleAfterBootQuiet, Database, closeQuietly, isMidTurn, textMentionsRecentCommit, hasMeaningfulUserText, extractTexts, extractToolCallSummaries, preloadTokenizer, estimateTokens, normalizeText, isRecord, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForCompletedToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isEditTool, applyEditMarkerToInput, setRawMessageProvider, withRawMessageProvider, cleanUserText, withRawSessionMessageCache, readRawSessionMessages, primeTailRawMessageCache, getCachedAbsoluteMessageCount, primeInMemoryTailRawMessageCache, getRawSessionMessageCount, getRawSessionTagKeysThrough, getLegacyProtectedTailStartOrdinal, readSessionChunk, clearCompressionDepth, clearCompressionDepthRange, getMessageIndexSourceIdentity, isMessageIndexSourceCurrent, getLastIndexedOrdinal, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, indexSingleMessage, indexMessagesAfterOrdinal, sweepOrphanedOpenCodeMessageIndexes, recordSessionProjectIdentity, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, isCompartmentLeaseHeld, piModelRefToCanonical, resolveModelRefForPi, modelRefLookupOrder, ompModelRefToCanonical, resolveModelRefForOmp, persistCachedM0, clearCachedM0M1, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getCompartmentsByEndMessageId, appendCompartments, saveRecompStagingPass, getRecompStaging, clearRecompStaging, getRecompPartialRange, setRecompPartialRange, escapeXmlAttr, escapeXmlContent, getModuleNoteEvaluationBridge, getContextStoreUuid, parseCompartmentOutput, logSlowWriteTransaction, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, sourceNameForMemory, computeWorkspaceEpochFingerprint, bumpEpochsForWorkspaceMembers, readProjectDocsCanonical, copySessionStateForClone, getErrorMessage, describeError, setStoragePrivatePermissionEnforcement, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, applySqliteTuningPragmas, runSqliteOptimize, openDatabase, openDatabaseAsync, queueM0Mutation, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRender, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationId, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, describeProtectedTailDrainBudgetSkip, loadProtectedTailMeta, markProtectedTailPolicyV3Seeded, recordProtectedTailPublicationFloor, recordProtectedTailNoEligibleHead, getWrapupInProgressState, isWrapupInProgress, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, reserveProtectedTailDrainTokens, clearEmergencyDrainLatch, recordHistorianDrainFailure, clearHistorianDrainFailure, rollbackProtectedTailDrainReservation, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getChannel1NudgeState, setChannel1NudgeState, markChannel1PostReduceGracePending, captureChannel1PostReduceGraceBaseline, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, setPersistedNoteNudgeTrigger, setPersistedNoteNudgeTriggerMessageId, getNoteNudgeAnchors, getAutoSearchHintDecisions, deliverNoteNudgeAtomic, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, getNoteLastReadAt, getHistorianFailureState, incrementHistorianFailure, clearHistorianFailureState, getOverflowState, recordOverflowDetected, clearEmergencyRecovery, clearDetectedContextLimit, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, getPendingPiCompactionMarkerState, setPendingPiCompactionMarkerState, clearPendingPiCompactionMarkerStateIf, getSessionsWithPendingPiMarker, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, setSessionWorkMetrics, getSessionWorkMetrics, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, retryPendingSessionCleanups, retryPendingRustSessionCleanupsForProject, getNotes, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, getPendingOpsCount, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, insertPrimerCandidates, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, recordSubagentInvocation, getLatestHistorianInvocationId, CTX_REDUCE_KEEP, estimateImageTokensFromDataUrl, normalizeTodoStateJson, buildSyntheticTodoPart, stripChannel1ReminderSpans, effectiveTailHygiene, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, decideChannel1, evaluateChannel2, reclaimableToolOutputCount, buildChannel2Reminder, buildChannel1Reminder, planEmergencyDrop, updateTagByteSize, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, updateTagInputByteSize, updateTagTokenCount, getPersistedToolTagAccounting, getAllStatusTagTokenTotalsFlat, updateTagInputTokenCount, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, hasPiFallbackMessageTags, findAdoptableFallbackTags, hasPiFallbackToolOwnerTags, findPiFallbackToolOwnerTags, adoptPiFallbackToolOwnerTag, adoptPiFallbackMessageTag, getMaxTagNumberBySession, getAssignableTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getTagsForPendingOperations, getTagsByNumbers, getDroppedTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, BoundedSessionMap, reloadWindowOverlay, getWindowOverlay, resolveWindowOverlayFacts, deriveWindowGeometry, formatWindowDerivationLine, isSaneLimit, resolveOutputReserve, getSdkContextLimit, resolveModelConfigOrDefault, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, SYNTH_USER_ID_PREFIX, resolvePiStableId, isMidTurnPi, readPiSessionSnapshot, readPiSessionMessages, findLastModelKeyFromBranch, convertEntriesToRawMessages, withContentLanguageDirective, withMigrationLanguageDirective, buildPrimaryLanguageDirective, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, invalidateMemory, computeNormalizedHash, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, insertMemory, getMemoryByHash, getMemoriesByProject, getMemoriesByProjects, getMaxMemoryIdForProjects, getAllActiveMemoriesForMigration, getMemoryById, setMemoryClassification, archiveMemory, deleteMemory, getMemoryCount, getMemoryCountsByStatus, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, getOpenCodeDbPath2 as getOpenCodeDbPath, parseCron, nextOccurrence, nextDueAtMs, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, buildCanonicalChunkTextFromFts, buildCompartmentSummaryFallbackText, canonicalizeInMemoryChunkTextForEmbedding, chunkCanonicalText, chunkEmbeddingWindowsAreCurrent, replaceCompartmentChunkEmbeddings, cosineSimilarity, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, contentSha256, sweepStaleEmbeddingIdentitiesForProject, enqueueShadowEmbeddingItems, getProjectEmbeddingSnapshot, getProjectChunkEmbeddingModelId, getProjectEmbeddingMaxInputTokens, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, promoteSessionFactsDurable, embedPromotedFacts, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, isDirectiveShapedProjectRule, takeCurateSafetyRefusalCount, wakePlaneStatus, indexCommitsForProject, embedUnembeddedCommits, loadPiConfig, ensureProjectRegisteredFromPiDirectory, resolveMuralWire, updateCompactionMarkerAfterPublication, COMPARTMENT_RENDER_EPOCH, encodeCachedM0UpgradeIdentity, decodeCachedM0UpgradeIdentity, DEFAULT_HISTORY_BUDGET_TOKENS, renderCompartmentAtTier, renderDecayedCompartments, extractM0Block, TEMPORAL_MARKER_PATTERN, temporalMarkerPrefix, clearInjectionCache, getVisibleMemoryIds, renderMemoryBlock, DEFAULT_MEMORY_BUDGET_TOKENS, DEFAULT_USER_PROFILE_BUDGET_TOKENS, trimMemoriesToBudgetV2, trimWorkspaceMemoriesToBudgetV2, trimUserMemoriesToBudget, renderMemoryBlockV2, stripMemoryMuralBlock, unifiedSearch, rememberTodowriteToolCallTodos, parseTodos, setTodoSnapshot, registerTodoOverlay, registerTodoStateLifecycle, syncCtxMemoryToolEnabled, registerMagicContextTools };