@cortexkit/pi-magic-context 0.36.1 → 0.38.0

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.
@@ -5,7 +5,7 @@ import {
5
5
  getMagicContextStorageDir,
6
6
  log,
7
7
  sessionLog
8
- } from "./index-npnqc564.js";
8
+ } from "./index-hk6sj7dn.js";
9
9
  import {
10
10
  __commonJS,
11
11
  __export,
@@ -7696,10 +7696,10 @@ var require_stringify = __commonJS((exports, module) => {
7696
7696
  replacer = null;
7697
7697
  indent = EMPTY;
7698
7698
  };
7699
- var join7 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two)), gap) : EMPTY;
7699
+ var join8 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two)), gap) : EMPTY;
7700
7700
  var join_content = (inside, value, gap) => {
7701
7701
  const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
7702
- return join7(comment, inside, gap);
7702
+ return join8(comment, inside, gap);
7703
7703
  };
7704
7704
  var stringify_string = (holder, key, value) => {
7705
7705
  const raw = get_raw_string_literal(holder, key);
@@ -7721,13 +7721,13 @@ var require_stringify = __commonJS((exports, module) => {
7721
7721
  if (i !== 0) {
7722
7722
  inside += COMMA;
7723
7723
  }
7724
- const before = join7(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
7724
+ const before = join8(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
7725
7725
  inside += before || LF + deeper_gap;
7726
7726
  inside += stringify(i, value, deeper_gap) || STR_NULL;
7727
7727
  inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
7728
7728
  after_comma = process_comments(value, AFTER(i), deeper_gap);
7729
7729
  }
7730
- inside += join7(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
7730
+ inside += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
7731
7731
  return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
7732
7732
  };
7733
7733
  var object_stringify = (value, gap) => {
@@ -7748,13 +7748,13 @@ var require_stringify = __commonJS((exports, module) => {
7748
7748
  inside += COMMA;
7749
7749
  }
7750
7750
  first = false;
7751
- const before = join7(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
7751
+ const before = join8(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
7752
7752
  inside += before || LF + deeper_gap;
7753
7753
  inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
7754
7754
  after_comma = process_comments(value, AFTER(key), deeper_gap);
7755
7755
  };
7756
7756
  keys.forEach(iteratee);
7757
- inside += join7(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
7757
+ inside += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
7758
7758
  return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
7759
7759
  };
7760
7760
  function stringify(key, holder, gap) {
@@ -8292,6 +8292,7 @@ import path from "node:path";
8292
8292
  var GIT_TIMEOUT_MS = 5000;
8293
8293
  var TRANSIENT_FAILURE_COOLDOWN_MS = 5 * 60 * 1000;
8294
8294
  var identityCache = new Map;
8295
+ var linkedGitWorktreeCache = new Map;
8295
8296
  var lastKnownGitIdentityCache = new Map;
8296
8297
  var directoryFallbackCache = new Map;
8297
8298
  var transientFailureCooldown = new Map;
@@ -8497,7 +8498,12 @@ function recordDubiousOwnershipFallback(canonical) {
8497
8498
  log(`[magic-context] ${formatDubiousOwnershipWarning(canonical)}`);
8498
8499
  }
8499
8500
  function canonicalUserHomeDirectory() {
8500
- return realpathSync.native(userHomeDirectoryForIdentity());
8501
+ const homeDirectory = userHomeDirectoryForIdentity();
8502
+ try {
8503
+ return realpathSync.native(homeDirectory);
8504
+ } catch {
8505
+ return homeDirectory;
8506
+ }
8501
8507
  }
8502
8508
  function isUserHomeDirectory(directory) {
8503
8509
  try {
@@ -8953,6 +8959,58 @@ function mergeCommitHashes(existing, next) {
8953
8959
  return merged;
8954
8960
  }
8955
8961
 
8962
+ // ../plugin/src/shared/harness-provider-map.ts
8963
+ var CANONICAL_TO_PI_PROVIDER = {
8964
+ openai: "openai-codex",
8965
+ google: "google-antigravity"
8966
+ };
8967
+ var PI_TO_CANONICAL_PROVIDER = {
8968
+ "openai-codex": "openai",
8969
+ "google-antigravity": "google"
8970
+ };
8971
+ var CANONICAL_TO_OMP_PROVIDER = {
8972
+ openai: "openai-codex",
8973
+ google: "google-antigravity"
8974
+ };
8975
+ var OMP_TO_CANONICAL_PROVIDER = {
8976
+ "openai-codex": "openai",
8977
+ "google-antigravity": "google"
8978
+ };
8979
+ function remapProviderPrefix(ref, map) {
8980
+ if (typeof ref !== "string")
8981
+ return ref;
8982
+ const slash = ref.indexOf("/");
8983
+ if (slash <= 0)
8984
+ return ref;
8985
+ const provider = ref.slice(0, slash);
8986
+ if (!Object.hasOwn(map, provider))
8987
+ return ref;
8988
+ return `${map[provider]}${ref.slice(slash)}`;
8989
+ }
8990
+ function piModelRefToCanonical(ref) {
8991
+ return remapProviderPrefix(ref, PI_TO_CANONICAL_PROVIDER);
8992
+ }
8993
+ function resolveModelRefForPi(ref) {
8994
+ return remapProviderPrefix(piModelRefToCanonical(ref), CANONICAL_TO_PI_PROVIDER);
8995
+ }
8996
+ function modelRefLookupOrder(ref) {
8997
+ const canonical = piModelRefToCanonical(ompModelRefToCanonical(ref));
8998
+ return [
8999
+ ...new Set([
9000
+ canonical,
9001
+ ref,
9002
+ resolveModelRefForPi(canonical),
9003
+ resolveModelRefForOmp(canonical)
9004
+ ])
9005
+ ];
9006
+ }
9007
+ function ompModelRefToCanonical(ref) {
9008
+ return remapProviderPrefix(ref, OMP_TO_CANONICAL_PROVIDER);
9009
+ }
9010
+ function resolveModelRefForOmp(ref) {
9011
+ return remapProviderPrefix(ompModelRefToCanonical(ref), CANONICAL_TO_OMP_PROVIDER);
9012
+ }
9013
+
8956
9014
  // ../plugin/src/shared/storage-permissions.ts
8957
9015
  var enforcePrivateStoragePermissions = true;
8958
9016
  function setStoragePrivatePermissionEnforcement(enforce) {
@@ -8974,7 +9032,7 @@ import {
8974
9032
  statSync as statSync3,
8975
9033
  unlinkSync as unlinkSync2
8976
9034
  } from "node:fs";
8977
- import { basename as basename2, dirname as dirname3, join as join4 } from "node:path";
9035
+ import { basename as basename2, dirname as dirname3, join as join4, resolve as resolve2 } from "node:path";
8978
9036
 
8979
9037
  // ../plugin/src/shared/error-message.ts
8980
9038
  function getErrorMessage(error) {
@@ -9057,20 +9115,24 @@ import { execFileSync as execFileSync2 } from "node:child_process";
9057
9115
  import { readFileSync as readFileSync3 } from "node:fs";
9058
9116
  function isPidAlive(pid) {
9059
9117
  if (!Number.isInteger(pid) || pid <= 0)
9060
- return false;
9118
+ return "dead";
9119
+ if (rpcIdentityPlatform === "win32")
9120
+ return readWindowsProcess(pid).state;
9061
9121
  try {
9062
- process.kill(pid, 0);
9063
- return true;
9064
- } catch (err) {
9065
- return err.code === "EPERM";
9122
+ rpcIdentityProcessKill(pid, 0);
9123
+ return "alive";
9124
+ } catch (error) {
9125
+ return error.code === "ESRCH" ? "dead" : "inconclusive";
9066
9126
  }
9067
9127
  }
9068
9128
  var RPC_IDENTITY_SKEW_TOLERANCE_MS = 120000;
9069
9129
  var LINUX_CLOCK_TICKS_PER_SECOND = 100;
9070
9130
  var PS_PROBE_TIMEOUT_MS = 1000;
9071
9131
  var OPEN_CODE_COMMAND_MARKERS = ["opencode", "node", "bun", "electron"];
9132
+ var TASKLIST_NO_TASKS_PATTERN = /^INFO:\s+No tasks are running which match the specified criteria\.?$/im;
9072
9133
  var rpcIdentityReadFileSync = readFileSync3;
9073
9134
  var rpcIdentityExecFileSync = execFileSync2;
9135
+ var rpcIdentityProcessKill = process.kill;
9074
9136
  var rpcProcessListExecFileSync = execFileSync2;
9075
9137
  var rpcIdentityPlatform = process.platform;
9076
9138
  var rpcIdentityNowMs = () => Date.now();
@@ -9100,7 +9162,8 @@ function readPsProcessStartTime(pid) {
9100
9162
  try {
9101
9163
  const output = rpcIdentityExecFileSync("ps", ["-p", String(pid), "-o", "lstart="], {
9102
9164
  encoding: "utf8",
9103
- timeout: PS_PROBE_TIMEOUT_MS
9165
+ timeout: PS_PROBE_TIMEOUT_MS,
9166
+ stdio: ["ignore", "pipe", "pipe"]
9104
9167
  });
9105
9168
  const processStartTime = Date.parse(String(output).trim());
9106
9169
  return Number.isFinite(processStartTime) ? processStartTime : null;
@@ -9108,6 +9171,70 @@ function readPsProcessStartTime(pid) {
9108
9171
  return null;
9109
9172
  }
9110
9173
  }
9174
+ function parseCsvLine(line) {
9175
+ const fields = [];
9176
+ let field = "";
9177
+ let quoted = false;
9178
+ for (let index = 0;index < line.length; index += 1) {
9179
+ const character = line[index];
9180
+ if (character === '"') {
9181
+ if (quoted && line[index + 1] === '"') {
9182
+ field += '"';
9183
+ index += 1;
9184
+ } else {
9185
+ quoted = !quoted;
9186
+ }
9187
+ } else if (character === "," && !quoted) {
9188
+ fields.push(field);
9189
+ field = "";
9190
+ } else {
9191
+ field += character;
9192
+ }
9193
+ }
9194
+ if (quoted)
9195
+ return null;
9196
+ fields.push(field);
9197
+ return fields;
9198
+ }
9199
+ function parseTasklistOutput(output) {
9200
+ const entries = [];
9201
+ let sawHeader = false;
9202
+ for (const rawLine of output.split(/\r?\n/)) {
9203
+ const line = rawLine.trim();
9204
+ if (!line)
9205
+ continue;
9206
+ if (TASKLIST_NO_TASKS_PATTERN.test(line))
9207
+ return [];
9208
+ const fields = parseCsvLine(line);
9209
+ if (!fields)
9210
+ continue;
9211
+ if (fields[1]?.trim().toLowerCase() === "pid") {
9212
+ sawHeader = true;
9213
+ continue;
9214
+ }
9215
+ const pid = Number(fields[1]);
9216
+ if (!Number.isInteger(pid) || pid <= 0 || !fields[0])
9217
+ continue;
9218
+ entries.push({ pid, command: fields[0] });
9219
+ }
9220
+ return entries.length > 0 || sawHeader ? entries : null;
9221
+ }
9222
+ function readWindowsProcess(pid) {
9223
+ try {
9224
+ const output = rpcIdentityExecFileSync("tasklist", ["/FO", "CSV", "/FI", `PID eq ${pid}`], {
9225
+ encoding: "utf8",
9226
+ timeout: PS_PROBE_TIMEOUT_MS,
9227
+ stdio: ["ignore", "pipe", "pipe"]
9228
+ });
9229
+ const entries = parseTasklistOutput(String(output));
9230
+ if (entries === null)
9231
+ return { state: "inconclusive" };
9232
+ const process2 = entries.find((entry) => entry.pid === pid);
9233
+ return process2 ? { state: "alive", command: process2.command } : { state: "dead" };
9234
+ } catch {
9235
+ return { state: "inconclusive" };
9236
+ }
9237
+ }
9111
9238
  function readLinuxProcessCommand(pid) {
9112
9239
  try {
9113
9240
  return String(rpcIdentityReadFileSync(`/proc/${pid}/cmdline`, "utf8"));
@@ -9119,40 +9246,86 @@ function readPsProcessCommand(pid) {
9119
9246
  try {
9120
9247
  const output = rpcIdentityExecFileSync("ps", ["-p", String(pid), "-o", "command="], {
9121
9248
  encoding: "utf8",
9122
- timeout: PS_PROBE_TIMEOUT_MS
9249
+ timeout: PS_PROBE_TIMEOUT_MS,
9250
+ stdio: ["ignore", "pipe", "pipe"]
9123
9251
  });
9124
9252
  return String(output);
9125
9253
  } catch {
9126
9254
  return null;
9127
9255
  }
9128
9256
  }
9257
+ function readProcessCommand(pid) {
9258
+ if (!Number.isInteger(pid) || pid <= 0)
9259
+ return null;
9260
+ return rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(pid) : rpcIdentityPlatform === "win32" ? readWindowsProcess(pid).command ?? null : readPsProcessCommand(pid);
9261
+ }
9262
+ function executableName(token) {
9263
+ return (token ?? "").replace(/^['"]|['"]$/g, "").split("/").at(-1) ?? "";
9264
+ }
9265
+ function commandTokens(command) {
9266
+ return command.toLowerCase().replaceAll("\\", "/").replaceAll("\x00", " ").split(/\s+/).map((token) => token.replace(/^['"]|['"]$/g, "")).filter(Boolean);
9267
+ }
9268
+ function commandHasOpenCodeExecutable(tokens) {
9269
+ return tokens.findIndex((token) => {
9270
+ const executable = executableName(token).replace(/\.(?:exe|cmd)$/, "");
9271
+ return executable === "opencode" || executable.endsWith("/opencode");
9272
+ });
9273
+ }
9274
+ function commandHasPiExecutable(tokens) {
9275
+ for (let index = 0;index < tokens.length; index += 1) {
9276
+ const executable = executableName(tokens[index]).replace(/\.(?:exe|cmd)$/, "");
9277
+ if (["pi", "omp", "oh-my-pi"].includes(executable))
9278
+ return true;
9279
+ if (["node", "bun", "deno"].includes(executable)) {
9280
+ const script = executableName(tokens[index + 1]).replace(/\.(?:exe|cmd)$/, "");
9281
+ if (["pi", "pi.js", "pi.mjs", "pi.cjs"].includes(script) || tokens[index + 1]?.includes("pi-coding-agent")) {
9282
+ return true;
9283
+ }
9284
+ }
9285
+ }
9286
+ return false;
9287
+ }
9288
+ function classifyProcessKind(command) {
9289
+ if (!command)
9290
+ return "process";
9291
+ const tokens = commandTokens(command);
9292
+ const openCodeIndex = commandHasOpenCodeExecutable(tokens);
9293
+ if (openCodeIndex >= 0) {
9294
+ const args = tokens.slice(openCodeIndex + 1);
9295
+ if (args.some((token) => token === "serve" || token === "--serve" || token.startsWith("--serve="))) {
9296
+ return "OpenCode server";
9297
+ }
9298
+ return "OpenCode instance (TUI/CLI)";
9299
+ }
9300
+ return commandHasPiExecutable(tokens) ? "Pi" : "process";
9301
+ }
9129
9302
  function commandLooksLikeOpenCode(command) {
9130
9303
  const normalized = command.toLowerCase();
9131
9304
  return OPEN_CODE_COMMAND_MARKERS.some((marker) => normalized.includes(marker));
9132
9305
  }
9133
9306
  function isPidIdentityPlausible(record) {
9134
9307
  if (!Number.isInteger(record.pid) || record.pid <= 0)
9135
- return false;
9308
+ return "implausible";
9136
9309
  if (Number.isFinite(record.started_at) && record.started_at > 0) {
9137
- const processStartTime = rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(record.pid) : readPsProcessStartTime(record.pid);
9310
+ const processStartTime = rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(record.pid) : rpcIdentityPlatform === "win32" ? null : readPsProcessStartTime(record.pid);
9138
9311
  if (processStartTime === null)
9139
- return true;
9140
- return processStartTime <= record.started_at + RPC_IDENTITY_SKEW_TOLERANCE_MS;
9312
+ return "inconclusive";
9313
+ return processStartTime <= record.started_at + RPC_IDENTITY_SKEW_TOLERANCE_MS ? "plausible" : "implausible";
9141
9314
  }
9142
- const command = rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(record.pid) : readPsProcessCommand(record.pid);
9315
+ const command = rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(record.pid) : rpcIdentityPlatform === "win32" ? readWindowsProcess(record.pid).command ?? null : readPsProcessCommand(record.pid);
9143
9316
  if (command === null)
9144
- return true;
9145
- return commandLooksLikeOpenCode(command);
9317
+ return "inconclusive";
9318
+ return commandLooksLikeOpenCode(command) ? "plausible" : "implausible";
9146
9319
  }
9147
9320
  function commandLooksLikePi(command) {
9148
9321
  const normalized = command.trim().toLowerCase().replaceAll("\\", "/");
9149
9322
  const tokens = normalized.split(/\s+/).filter(Boolean);
9150
- const executableName = (token) => (token ?? "").split("/").at(-1) ?? "";
9151
- const first = executableName(tokens[0]).replace(/\.exe$/, "");
9323
+ const executableName2 = (token) => (token ?? "").split("/").at(-1) ?? "";
9324
+ const first = executableName2(tokens[0]).replace(/\.exe$/, "");
9152
9325
  if (["pi", "pi.cmd", "omp", "oh-my-pi"].includes(first))
9153
9326
  return true;
9154
9327
  if (["node", "bun", "deno"].includes(first)) {
9155
- const script = executableName(tokens[1]);
9328
+ const script = executableName2(tokens[1]);
9156
9329
  return ["pi", "pi.js", "pi.mjs", "pi.cjs"].includes(script) || normalized.includes("pi-coding-agent");
9157
9330
  }
9158
9331
  return false;
@@ -9160,20 +9333,39 @@ function commandLooksLikePi(command) {
9160
9333
  function inspectLivePiProcesses() {
9161
9334
  if (false) {}
9162
9335
  try {
9163
- const output = String(rpcProcessListExecFileSync("ps", ["-axo", "pid=,command="], {
9336
+ const isWindows = rpcIdentityPlatform === "win32";
9337
+ const output = String(rpcProcessListExecFileSync(isWindows ? "tasklist" : "ps", isWindows ? ["/FO", "CSV"] : ["-axo", "pid=,command="], {
9164
9338
  encoding: "utf8",
9165
- timeout: PS_PROBE_TIMEOUT_MS
9339
+ timeout: PS_PROBE_TIMEOUT_MS,
9340
+ stdio: ["ignore", "pipe", "pipe"]
9166
9341
  }));
9167
9342
  const pids = new Set;
9168
- for (const line of output.split(/\r?\n/)) {
9169
- const match = /^\s*(\d+)\s+(.+)$/.exec(line);
9170
- if (!match)
9171
- continue;
9172
- const pid = Number(match[1]);
9173
- if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid)
9174
- continue;
9175
- if (commandLooksLikePi(match[2]))
9176
- pids.add(pid);
9343
+ if (isWindows) {
9344
+ const entries = parseTasklistOutput(output);
9345
+ if (entries === null) {
9346
+ return {
9347
+ state: "unreadable",
9348
+ processIds: [],
9349
+ error: "tasklist output unavailable"
9350
+ };
9351
+ }
9352
+ for (const entry of entries) {
9353
+ if (entry.pid === process.pid)
9354
+ continue;
9355
+ if (commandLooksLikePi(entry.command))
9356
+ pids.add(entry.pid);
9357
+ }
9358
+ } else {
9359
+ for (const line of output.split(/\r?\n/)) {
9360
+ const match = /^\s*(\d+)\s+(.+)$/.exec(line);
9361
+ if (!match)
9362
+ continue;
9363
+ const pid = Number(match[1]);
9364
+ if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid)
9365
+ continue;
9366
+ if (commandLooksLikePi(match[2]))
9367
+ pids.add(pid);
9368
+ }
9177
9369
  }
9178
9370
  return { state: "known", processIds: [...pids].sort((left, right) => left - right) };
9179
9371
  } catch (error) {
@@ -9184,9 +9376,6 @@ function inspectLivePiProcesses() {
9184
9376
  };
9185
9377
  }
9186
9378
  }
9187
- function discoverLivePiProcessIds() {
9188
- return inspectLivePiProcesses().processIds;
9189
- }
9190
9379
  function parseRpcPortFile(content, fallbackPid = 0) {
9191
9380
  const trimmed = content.trim();
9192
9381
  if (!trimmed)
@@ -9203,6 +9392,8 @@ function parseRpcPortFile(content, fallbackPid = 0) {
9203
9392
  port: port2,
9204
9393
  pid,
9205
9394
  started_at: Number.isFinite(startedAt) ? startedAt : 0,
9395
+ kind: typeof parsed.kind === "string" ? parsed.kind : undefined,
9396
+ harness: typeof parsed.harness === "string" ? parsed.harness : undefined,
9206
9397
  token: typeof parsed.token === "string" ? parsed.token : undefined,
9207
9398
  instance_id: typeof parsed.instance_id === "string" ? parsed.instance_id : undefined
9208
9399
  };
@@ -9631,6 +9822,8 @@ function healAllNullColumns(db) {
9631
9822
  ["stripped_placeholder_ids", ""],
9632
9823
  ["stale_reduce_stripped_ids", ""],
9633
9824
  ["processed_image_stripped_ids", ""],
9825
+ ["merged_reasoning_stripped_ids", ""],
9826
+ ["trailing_blank_decisions", ""],
9634
9827
  ["memory_block_cache", ""],
9635
9828
  ["memory_block_ids", ""],
9636
9829
  ["compaction_marker_state", ""],
@@ -10223,6 +10416,7 @@ var MIGRATIONS = [
10223
10416
  status TEXT NOT NULL DEFAULT 'active',
10224
10417
  promoted_at INTEGER NOT NULL,
10225
10418
  source_candidate_ids TEXT DEFAULT '[]',
10419
+ source_candidate_provenance TEXT,
10226
10420
  created_at INTEGER NOT NULL,
10227
10421
  updated_at INTEGER NOT NULL
10228
10422
  );
@@ -11249,6 +11443,7 @@ var MIGRATIONS = [
11249
11443
  last_observed_at INTEGER,
11250
11444
  answer_refreshed_at INTEGER,
11251
11445
  source_candidate_ids TEXT NOT NULL DEFAULT '[]',
11446
+ source_candidate_provenance TEXT,
11252
11447
  created_at INTEGER NOT NULL,
11253
11448
  updated_at INTEGER NOT NULL
11254
11449
  );
@@ -12058,6 +12253,37 @@ var MIGRATIONS = [
12058
12253
  ensureColumn(db, "notes", "compiled_at", "INTEGER");
12059
12254
  ensureColumn(db, "notes", "compile_status", "TEXT CHECK(compile_status IN ('compiled', 'plain', 'refused'))");
12060
12255
  }
12256
+ },
12257
+ {
12258
+ version: 77,
12259
+ description: "persist scoped provenance for promoted user memories and primers",
12260
+ up(db) {
12261
+ if (tableExists2(db, "user_memories")) {
12262
+ ensureColumn(db, "user_memories", "source_candidate_provenance", "TEXT");
12263
+ }
12264
+ if (tableExists2(db, "primers")) {
12265
+ ensureColumn(db, "primers", "source_candidate_provenance", "TEXT");
12266
+ }
12267
+ }
12268
+ },
12269
+ {
12270
+ version: 78,
12271
+ description: "add migration_pending journal for crash-safe cross-harness session migration",
12272
+ up(db) {
12273
+ db.exec(`
12274
+ CREATE TABLE IF NOT EXISTS migration_pending (
12275
+ migration_key TEXT PRIMARY KEY,
12276
+ source_session_id TEXT NOT NULL,
12277
+ target_harness TEXT NOT NULL,
12278
+ pi_session_id TEXT NOT NULL,
12279
+ final_path TEXT NOT NULL,
12280
+ stage_path TEXT NOT NULL,
12281
+ content_sha256 TEXT NOT NULL,
12282
+ phase TEXT NOT NULL CHECK (phase IN ('staged', 'db_committed')),
12283
+ created_at INTEGER NOT NULL
12284
+ );
12285
+ `);
12286
+ }
12061
12287
  }
12062
12288
  ];
12063
12289
  var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
@@ -12492,7 +12718,7 @@ function getSchemaFenceRejection() {
12492
12718
  function getMigrationOnOpenRefusal() {
12493
12719
  return lastMigrationOnOpenRefusal;
12494
12720
  }
12495
- var LATEST_SUPPORTED_VERSION = 76;
12721
+ var LATEST_SUPPORTED_VERSION = 78;
12496
12722
  var PERMISSIONS_ENFORCEABLE = process.platform !== "win32";
12497
12723
  var defaultStoragePermissionFs = { chmodSync, mkdirSync: mkdirSync2 };
12498
12724
  var storagePermissionFs = defaultStoragePermissionFs;
@@ -12639,6 +12865,28 @@ function invalidDiscoveryReason(raw) {
12639
12865
  }
12640
12866
  return "parse-invalid";
12641
12867
  }
12868
+ function classifyDiscoveryRecordKind(record) {
12869
+ for (const value of [record.kind, record.harness]) {
12870
+ const normalized = value?.trim().toLowerCase();
12871
+ if (!normalized)
12872
+ continue;
12873
+ if (normalized === "process")
12874
+ return "process";
12875
+ if (normalized === "opencode server" || normalized === "server") {
12876
+ return "OpenCode server";
12877
+ }
12878
+ if (normalized === "opencode instance" || normalized === "opencode instance (tui/cli)" || normalized === "opencode" || normalized === "tui" || normalized === "cli") {
12879
+ return "OpenCode instance (TUI/CLI)";
12880
+ }
12881
+ if (normalized === "pi" || normalized === "pi harness" || normalized === "omp" || normalized === "oh-my-pi") {
12882
+ return "Pi";
12883
+ }
12884
+ }
12885
+ return null;
12886
+ }
12887
+ function classifyRpcProcess(record) {
12888
+ return classifyDiscoveryRecordKind(record) ?? classifyProcessKind(readProcessCommand(record.pid));
12889
+ }
12642
12890
  function classifyJunkDiscovery(portFile, raw, staleFiles) {
12643
12891
  let mtimeMs;
12644
12892
  try {
@@ -12691,7 +12939,9 @@ function inspectRpcServerDiscovery(storageDir) {
12691
12939
  return { state: "absent", serverPids: [], staleFiles: [] };
12692
12940
  }
12693
12941
  const pids = new Set;
12942
+ const processByPid = new Map;
12694
12943
  const staleFiles = [];
12944
+ const inconclusivePids = new Set;
12695
12945
  for (const portFile of portFiles) {
12696
12946
  let raw;
12697
12947
  try {
@@ -12711,10 +12961,23 @@ function inspectRpcServerDiscovery(storageDir) {
12711
12961
  return junk;
12712
12962
  continue;
12713
12963
  }
12714
- if (isPidAlive(record.pid) && isPidIdentityPlausible(record))
12964
+ const liveness = isPidAlive(record.pid);
12965
+ const identity = liveness === "dead" ? "implausible" : isPidIdentityPlausible(record);
12966
+ if (liveness === "alive" && identity === "plausible") {
12715
12967
  pids.add(record.pid);
12716
- else
12968
+ const detected = {
12969
+ kind: classifyRpcProcess(record),
12970
+ pid: record.pid
12971
+ };
12972
+ const previous = processByPid.get(record.pid);
12973
+ if (!previous || previous.kind === "process" && detected.kind !== "process") {
12974
+ processByPid.set(record.pid, detected);
12975
+ }
12976
+ } else if (liveness === "dead" || identity === "implausible") {
12717
12977
  staleFiles.push(portFile);
12978
+ } else {
12979
+ inconclusivePids.add(record.pid);
12980
+ }
12718
12981
  }
12719
12982
  for (const staleFile of staleFiles) {
12720
12983
  try {
@@ -12725,10 +12988,55 @@ function inspectRpcServerDiscovery(storageDir) {
12725
12988
  }
12726
12989
  const serverPids = [...pids].sort((a, b) => a - b);
12727
12990
  if (serverPids.length > 0) {
12728
- return { state: "live", serverPids, staleFiles };
12991
+ return {
12992
+ state: "live",
12993
+ serverPids,
12994
+ serverProcesses: serverPids.map((pid) => processByPid.get(pid) ?? { kind: "process", pid }),
12995
+ staleFiles
12996
+ };
12997
+ }
12998
+ const uncertainPids = [...inconclusivePids].sort((a, b) => a - b);
12999
+ if (uncertainPids.length > 0) {
13000
+ return {
13001
+ state: "inconclusive",
13002
+ serverPids: [],
13003
+ staleFiles,
13004
+ inconclusivePids: uncertainPids
13005
+ };
12729
13006
  }
12730
13007
  return { state: "stale", serverPids: [], staleFiles };
12731
13008
  }
13009
+ function formatInconclusiveOpenCodeMigrationWarning(dbPath, pids) {
13010
+ 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.`;
13011
+ }
13012
+ function logInconclusiveMigrationProbes(dbPath, discovery, piProbeState) {
13013
+ const uncertainPids = discovery.inconclusivePids ?? [];
13014
+ if (uncertainPids.length > 0) {
13015
+ log(formatInconclusiveOpenCodeMigrationWarning(dbPath, uncertainPids));
13016
+ }
13017
+ if (piProbeState === "unreadable") {
13018
+ 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.`);
13019
+ }
13020
+ }
13021
+ function isDefaultSharedDatabasePath(dbPath) {
13022
+ if (!process.env.XDG_DATA_HOME && (process.env.MAGIC_CONTEXT_TEST_DATA_DIR || false)) {
13023
+ return false;
13024
+ }
13025
+ return resolve2(dbPath) === resolve2(join4(getMagicContextStorageDir(), "context.db"));
13026
+ }
13027
+ function migrationBlockingPiPids(dbPath, discovery, discoveredPiPids) {
13028
+ if (isDefaultSharedDatabasePath(dbPath))
13029
+ return [...discoveredPiPids];
13030
+ const sameDataDirPids = new Set(discovery.serverPids);
13031
+ return discoveredPiPids.filter((pid) => sameDataDirPids.has(pid));
13032
+ }
13033
+ function formatLiveProcessMigrationRefusal(dbPath, persistedVersion, latestSupportedVersion, serverPids, piPids) {
13034
+ const blockers = [
13035
+ ...serverPids.map((pid) => `confirmed OpenCode server PID ${pid}`),
13036
+ ...piPids.map((pid) => `confirmed Pi harness PID ${pid}`)
13037
+ ];
13038
+ return `[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} while ${blockers.join(", ")} still use the old plugin build. Restart the blocking harness, then retry this process.`;
13039
+ }
12732
13040
  function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion) {
12733
13041
  const persistedVersion = getPersistedSchemaVersion(db);
12734
13042
  if (persistedVersion >= latestSupportedVersion) {
@@ -12736,9 +13044,16 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
12736
13044
  return true;
12737
13045
  }
12738
13046
  const discovery = inspectRpcServerDiscovery(dbDir);
12739
- const piPids = discoverLivePiProcessIds();
12740
- if ((discovery.state === "absent" || discovery.state === "stale") && piPids.length === 0) {
13047
+ const piDiscovery = inspectLivePiProcesses();
13048
+ const piPids = migrationBlockingPiPids(dbPath, discovery, piDiscovery.processIds);
13049
+ const serverProcesses = discovery.serverProcesses ?? (discovery.state === "live" ? discovery.serverPids.map((pid) => ({ kind: "process", pid })) : []);
13050
+ const blockingProcesses = [
13051
+ ...serverProcesses,
13052
+ ...piPids.map((pid) => ({ kind: "Pi", pid }))
13053
+ ];
13054
+ if ((discovery.state === "absent" || discovery.state === "stale" || discovery.state === "inconclusive") && piPids.length === 0) {
12741
13055
  lastMigrationOnOpenRefusal = null;
13056
+ logInconclusiveMigrationProbes(dbPath, discovery, piDiscovery.state);
12742
13057
  return true;
12743
13058
  }
12744
13059
  const blockingPids = [...new Set([...discovery.serverPids, ...piPids])].sort((left, right) => left - right);
@@ -12746,6 +13061,7 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
12746
13061
  persistedVersion,
12747
13062
  supportedVersion: latestSupportedVersion,
12748
13063
  serverPids: blockingPids,
13064
+ blockingProcesses,
12749
13065
  ...discovery.unreadableFile ? { unreadableFile: discovery.unreadableFile } : {},
12750
13066
  ...discovery.unreadableArm ? { unreadableArm: discovery.unreadableArm } : {}
12751
13067
  };
@@ -12755,11 +13071,7 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
12755
13071
  const recovery = arm === "io" ? `If no OpenCode server is running, it is safe to delete ${unreadableFile} and retry.` : `Retry after the file is older than the ten-minute grace window, or stop OpenCode before deleting it.`;
12756
13072
  log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} because RPC discovery file ${unreadableFile} is uncertain (${arm} arm), so the absence of a live OpenCode server cannot be proven. ${recovery}`);
12757
13073
  } else {
12758
- const blockers = [
12759
- ...discovery.serverPids.map((pid) => `OpenCode server PID ${pid}`),
12760
- ...piPids.map((pid) => `Pi harness PID ${pid}`)
12761
- ];
12762
- log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} while ${blockers.join(", ")} may still use the old plugin build. Restart the blocking harness, then retry this process.`);
13074
+ log(formatLiveProcessMigrationRefusal(dbPath, persistedVersion, latestSupportedVersion, discovery.serverPids, piPids));
12763
13075
  }
12764
13076
  return false;
12765
13077
  }
@@ -12983,6 +13295,7 @@ function initializeDatabase(db) {
12983
13295
  last_observed_at INTEGER,
12984
13296
  answer_refreshed_at INTEGER,
12985
13297
  source_candidate_ids TEXT NOT NULL DEFAULT '[]',
13298
+ source_candidate_provenance TEXT,
12986
13299
  created_at INTEGER NOT NULL,
12987
13300
  updated_at INTEGER NOT NULL
12988
13301
  );
@@ -13618,6 +13931,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
13618
13931
  ensureColumn(db, "primer_candidates", "question_embedding", "BLOB");
13619
13932
  ensureColumn(db, "primer_candidates", "question_embedding_model_id", "TEXT");
13620
13933
  ensureColumn(db, "primers", "question_embedding_model_id", "TEXT");
13934
+ ensureColumn(db, "primers", "source_candidate_provenance", "TEXT");
13935
+ const hasUserMemoriesTable = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'user_memories'").get();
13936
+ if (hasUserMemoriesTable) {
13937
+ ensureColumn(db, "user_memories", "source_candidate_provenance", "TEXT");
13938
+ }
13621
13939
  db.exec(`
13622
13940
  CREATE UNIQUE INDEX IF NOT EXISTS idx_primer_candidates_occurrence
13623
13941
  ON primer_candidates(project_path, harness, session_id, source_start_message_id, source_end_message_id);
@@ -13691,6 +14009,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
13691
14009
  ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
13692
14010
  ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
13693
14011
  ensureColumn(db, "session_meta", "processed_image_stripped_ids", "TEXT DEFAULT ''");
14012
+ ensureColumn(db, "session_meta", "merged_reasoning_stripped_ids", "TEXT DEFAULT ''");
14013
+ ensureColumn(db, "session_meta", "trailing_blank_decisions", "TEXT DEFAULT ''");
13694
14014
  ensureColumn(db, "compartments", "start_message_id", "TEXT DEFAULT ''");
13695
14015
  ensureColumn(db, "compartments", "end_message_id", "TEXT DEFAULT ''");
13696
14016
  ensureColumn(db, "memory_embeddings", "model_id", "TEXT");
@@ -13909,11 +14229,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
13909
14229
  ensureColumn(db, "message_history_index", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
13910
14230
  ensureColumn(db, "workspaces", "share_categories", `TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'`);
13911
14231
  }
13912
- var CHANNEL2_CLAIM_TTL_MS = 120000;
14232
+ var CHANNEL2_CLAIM_TTL_MS = 10 * 60000;
13913
14233
  function healWedgedChannel2Claims(db) {
13914
14234
  try {
13915
14235
  const staleBefore = Date.now() - CHANNEL2_CLAIM_TTL_MS;
13916
- db.prepare("UPDATE session_meta SET channel2_nudge_state = 'pending', channel2_nudge_claimed_at = 0, channel2_nudge_claim_token = '' WHERE channel2_nudge_state = 'claimed' AND (channel2_nudge_claimed_at IS NULL OR channel2_nudge_claimed_at = 0 OR channel2_nudge_claimed_at <= ?)").run(staleBefore);
14236
+ db.prepare("UPDATE session_meta SET channel2_nudge_state = '', channel2_nudge_claimed_at = 0, channel2_nudge_claim_token = '' WHERE channel2_nudge_state = 'claimed' AND (channel2_nudge_claimed_at IS NULL OR channel2_nudge_claimed_at = 0 OR channel2_nudge_claimed_at <= ?)").run(staleBefore);
13917
14237
  } catch {}
13918
14238
  }
13919
14239
  function openDatabase(dbPathOrOptions) {
@@ -14338,7 +14658,7 @@ function persistCachedM0(db, sessionId, payload) {
14338
14658
  cached_m0_system_hash = ?,
14339
14659
  cached_m0_model_key = ?,
14340
14660
  cached_m0_project_identity = ?
14341
- WHERE session_id = ?`).run(Buffer2.from(payload.m0Bytes), payload.muralDataUrl ?? null, payload.muralHash ?? null, payload.projectMemoryEpoch, payload.workspaceFingerprint ?? null, payload.projectUserProfileVersion, payload.maxCompartmentSeq, payload.maxMemoryId, payload.maxMutationId, payload.maxMemoryMutationId ?? null, payload.m1Bytes ? Buffer2.from(payload.m1Bytes) : null, payload.projectDocsHash, payload.materializedAt, payload.sessionFactsVersion, payload.upgradeState, payload.systemHash ?? "", payload.modelKey ?? "", payload.projectIdentity ?? null, sessionId);
14661
+ WHERE session_id = ?`).run(Buffer2.from(payload.m0Bytes), payload.muralDataUrl ?? null, payload.muralHash ?? null, payload.projectMemoryEpoch, payload.workspaceFingerprint ?? null, payload.projectUserProfileVersion, payload.maxCompartmentSeq, payload.maxMemoryId, payload.maxMutationId, payload.maxMemoryMutationId ?? null, payload.m1Bytes ? Buffer2.from(payload.m1Bytes) : null, payload.projectDocsHash, payload.materializedAt, payload.sessionFactsVersion, payload.upgradeState, payload.systemHash ?? "", payload.modelKey ? piModelRefToCanonical(payload.modelKey) : "", payload.projectIdentity ?? null, sessionId);
14342
14662
  }
14343
14663
  function clearCachedM0M1(db, sessionId) {
14344
14664
  ensureSessionMetaRow(db, sessionId);
@@ -14897,6 +15217,16 @@ function getChannel2NudgeState(db, sessionId) {
14897
15217
  const raw = result.channel2_nudge_state;
14898
15218
  return raw === "pending" || raw === "claimed" || raw === "delivered" ? raw : "";
14899
15219
  }
15220
+ function getChannel2NudgeClaim(db, sessionId) {
15221
+ const result = db.prepare("SELECT channel2_nudge_state, channel2_nudge_claimed_at, channel2_nudge_claim_token FROM session_meta WHERE session_id = ?").get(sessionId);
15222
+ const rawState = typeof result?.channel2_nudge_state === "string" ? result.channel2_nudge_state : "";
15223
+ const state = rawState === "pending" || rawState === "claimed" || rawState === "delivered" ? rawState : "";
15224
+ return {
15225
+ state,
15226
+ claimedAt: typeof result?.channel2_nudge_claimed_at === "number" ? result.channel2_nudge_claimed_at : 0,
15227
+ claimToken: typeof result?.channel2_nudge_claim_token === "string" ? result.channel2_nudge_claim_token : ""
15228
+ };
15229
+ }
14900
15230
  function setChannel2NudgeState(db, sessionId, state) {
14901
15231
  db.transaction(() => {
14902
15232
  ensureSessionMetaRow(db, sessionId);
@@ -14914,6 +15244,26 @@ function casChannel2NudgeState(db, sessionId, from, to) {
14914
15244
  })();
14915
15245
  return changed;
14916
15246
  }
15247
+ function claimChannel2NudgeState(db, sessionId, claimToken) {
15248
+ let changed = false;
15249
+ db.transaction(() => {
15250
+ ensureSessionMetaRow(db, sessionId);
15251
+ const result = db.prepare("UPDATE session_meta SET channel2_nudge_state = 'claimed', channel2_nudge_claimed_at = ?, channel2_nudge_claim_token = ? WHERE session_id = ? AND channel2_nudge_state = 'pending'").run(Date.now(), claimToken, sessionId);
15252
+ changed = (result.changes ?? 0) > 0;
15253
+ })();
15254
+ return changed;
15255
+ }
15256
+ function casChannel2NudgeClaim(db, sessionId, to, claimToken) {
15257
+ let changed = false;
15258
+ db.transaction(() => {
15259
+ ensureSessionMetaRow(db, sessionId);
15260
+ const claimedAt = to === "claimed" ? Date.now() : 0;
15261
+ const nextClaimToken = to === "claimed" ? claimToken : "";
15262
+ const result = db.prepare("UPDATE session_meta SET channel2_nudge_state = ?, channel2_nudge_claimed_at = ?, channel2_nudge_claim_token = ? WHERE session_id = ? AND channel2_nudge_state = 'claimed' AND channel2_nudge_claim_token = ?").run(to, claimedAt, nextClaimToken, sessionId, claimToken);
15263
+ changed = (result.changes ?? 0) > 0;
15264
+ })();
15265
+ return changed;
15266
+ }
14917
15267
  function getPersistedNoteNudge(db, sessionId) {
14918
15268
  const result = db.prepare("SELECT note_nudge_trigger_pending, note_nudge_trigger_message_id, note_nudge_sticky_text, note_nudge_sticky_message_id FROM session_meta WHERE session_id = ?").get(sessionId);
14919
15269
  if (!isPersistedNoteNudgeRow(result)) {
@@ -15115,7 +15465,7 @@ function clearHistorianFailureState(db, sessionId) {
15115
15465
  })();
15116
15466
  }
15117
15467
  function normalizeDetectedLimitModelKey(modelKey) {
15118
- return typeof modelKey === "string" && modelKey.length > 0 ? modelKey : null;
15468
+ return typeof modelKey === "string" && modelKey.length > 0 ? piModelRefToCanonical(modelKey) : null;
15119
15469
  }
15120
15470
  function normalizeEmergencyRecoveryOrigin(value) {
15121
15471
  return value === "provider_overflow" || value === "proactive_model_shrink" ? value : null;
@@ -17225,7 +17575,7 @@ function updateSessionMeta(db, sessionId, updates) {
17225
17575
  values.push(value ? 1 : 0);
17226
17576
  } else if (typeof value === "string" || typeof value === "number") {
17227
17577
  setClauses.push(`${column} = ?`);
17228
- values.push(value);
17578
+ values.push(key === "lastObservedModelKey" && typeof value === "string" ? piModelRefToCanonical(value) : value);
17229
17579
  }
17230
17580
  }
17231
17581
  if (setClauses.length === 0) {
@@ -17289,6 +17639,113 @@ function clearSession(db, sessionId) {
17289
17639
  clearIndexedMessages(db, sessionId);
17290
17640
  })();
17291
17641
  }
17642
+ // ../plugin/src/hooks/magic-context/todo-view.ts
17643
+ import { createHash as createHash5 } from "node:crypto";
17644
+ var TODO_STATUS_PENDING = "pending";
17645
+ var TODO_STATUS_IN_PROGRESS = "in_progress";
17646
+ var TODO_STATUS_COMPLETED = "completed";
17647
+ var TODO_STATUS_CANCELLED = "cancelled";
17648
+ var TODO_PRIORITY_HIGH = "high";
17649
+ var TODO_PRIORITY_MEDIUM = "medium";
17650
+ var TODO_PRIORITY_LOW = "low";
17651
+ var TODO_STATUSES = [
17652
+ TODO_STATUS_PENDING,
17653
+ TODO_STATUS_IN_PROGRESS,
17654
+ TODO_STATUS_COMPLETED,
17655
+ TODO_STATUS_CANCELLED
17656
+ ];
17657
+ var TODO_PRIORITIES = [
17658
+ TODO_PRIORITY_HIGH,
17659
+ TODO_PRIORITY_MEDIUM,
17660
+ TODO_PRIORITY_LOW
17661
+ ];
17662
+ var TODO_STATUS_SET = new Set(TODO_STATUSES);
17663
+ var TODO_PRIORITY_SET = new Set(TODO_PRIORITIES);
17664
+ var TERMINAL_STATUSES = new Set([
17665
+ TODO_STATUS_COMPLETED,
17666
+ TODO_STATUS_CANCELLED
17667
+ ]);
17668
+ var TITLE_DONE_STATUSES = new Set([TODO_STATUS_COMPLETED]);
17669
+ var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
17670
+ function normalizeTodoStateJson(todos) {
17671
+ if (!Array.isArray(todos))
17672
+ return null;
17673
+ const normalized = [];
17674
+ for (const todo of todos) {
17675
+ if (!isTodoItem(todo))
17676
+ return null;
17677
+ normalized.push({
17678
+ content: todo.content,
17679
+ status: todo.status,
17680
+ priority: todo.priority ?? TODO_PRIORITY_MEDIUM
17681
+ });
17682
+ }
17683
+ return JSON.stringify(normalized);
17684
+ }
17685
+ function buildSyntheticTodoPart(stateJson) {
17686
+ const todos = parseTodoState(stateJson);
17687
+ if (todos === null || todos.length === 0)
17688
+ return null;
17689
+ if (todos.every((t) => TERMINAL_STATUSES.has(t.status)))
17690
+ return null;
17691
+ const callID = computeSyntheticCallId(stateJson);
17692
+ const activeCount = todos.filter((t) => !TITLE_DONE_STATUSES.has(t.status)).length;
17693
+ const output = JSON.stringify(todos, null, 2);
17694
+ const ts = 0;
17695
+ return {
17696
+ type: "tool",
17697
+ callID,
17698
+ tool: "todowrite",
17699
+ state: {
17700
+ status: "completed",
17701
+ input: { todos },
17702
+ output,
17703
+ title: `${activeCount} todos`,
17704
+ metadata: { todos, truncated: false },
17705
+ time: { start: ts, end: ts }
17706
+ },
17707
+ syntheticTodoMarker: true
17708
+ };
17709
+ }
17710
+ function computeSyntheticCallId(stateJson) {
17711
+ const hash = createHash5("sha256").update(stateJson).digest("hex").slice(0, 16);
17712
+ return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
17713
+ }
17714
+ function parseTodoState(stateJson) {
17715
+ if (stateJson.length === 0)
17716
+ return null;
17717
+ try {
17718
+ const parsed = JSON.parse(stateJson);
17719
+ if (!Array.isArray(parsed))
17720
+ return null;
17721
+ const result = [];
17722
+ for (const item of parsed) {
17723
+ if (!isTodoItem(item))
17724
+ return null;
17725
+ result.push({
17726
+ content: item.content,
17727
+ status: item.status,
17728
+ priority: item.priority ?? TODO_PRIORITY_MEDIUM
17729
+ });
17730
+ }
17731
+ return result;
17732
+ } catch {
17733
+ return null;
17734
+ }
17735
+ }
17736
+ function isTodoStatus(value) {
17737
+ return typeof value === "string" && TODO_STATUS_SET.has(value);
17738
+ }
17739
+ function isTodoPriority(value) {
17740
+ return typeof value === "string" && TODO_PRIORITY_SET.has(value);
17741
+ }
17742
+ function isTodoItem(value) {
17743
+ if (value === null || typeof value !== "object")
17744
+ return false;
17745
+ const todo = value;
17746
+ return typeof todo.content === "string" && isTodoStatus(todo.status) && (todo.priority === undefined || isTodoPriority(todo.priority));
17747
+ }
17748
+
17292
17749
  // ../plugin/src/features/magic-context/compartment-lease.ts
17293
17750
  var COMPARTMENT_LEASE_TTL_MS = 5 * 60 * 1000;
17294
17751
  var COMPARTMENT_LEASE_RENEWAL_MS = 60 * 1000;
@@ -17489,7 +17946,7 @@ function escapeXmlContent(s) {
17489
17946
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
17490
17947
  }
17491
17948
  // ../plugin/src/features/magic-context/project-docs-hash.ts
17492
- import { createHash as createHash5 } from "node:crypto";
17949
+ import { createHash as createHash6 } from "node:crypto";
17493
17950
  import { lstatSync, readFileSync as readFileSync5, statSync as statSync4 } from "node:fs";
17494
17951
  import path2 from "node:path";
17495
17952
  var PROJECT_DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
@@ -17587,7 +18044,7 @@ function hashCanonicalPieces(hashPieces) {
17587
18044
  if (hashPieces.length === 0) {
17588
18045
  return "";
17589
18046
  }
17590
- return createHash5("sha256").update(hashPieces.join(PROJECT_DOCS_DELIMITER), "utf8").digest("hex");
18047
+ return createHash6("sha256").update(hashPieces.join(PROJECT_DOCS_DELIMITER), "utf8").digest("hex");
17591
18048
  }
17592
18049
  function readProjectDocsCanonical(projectDirectory) {
17593
18050
  const canonicalDirectory = path2.resolve(projectDirectory);
@@ -17858,10 +18315,10 @@ function copySessionStateForClone(db, sourceSessionId, destinationSessionId, fil
17858
18315
  });
17859
18316
  }
17860
18317
  // ../plugin/src/features/magic-context/storage-embedding-measurements.ts
17861
- import { createHash as createHash6 } from "node:crypto";
18318
+ import { createHash as createHash7 } from "node:crypto";
17862
18319
  function normalizedQueryHash(query) {
17863
18320
  const normalized = query.trim().replace(/\s+/g, " ").toLowerCase();
17864
- return createHash6("sha256").update(normalized).digest("hex");
18321
+ return createHash7("sha256").update(normalized).digest("hex");
17865
18322
  }
17866
18323
  var MEASUREMENT_CORPUS_SESSION_ROW_CAP = 2000;
17867
18324
  function recordEmbeddingMeasurement(db, input) {
@@ -18435,6 +18892,76 @@ function parseCandidateIds(raw) {
18435
18892
  return [];
18436
18893
  }
18437
18894
  }
18895
+ function parsePrimerSourceProvenance(raw) {
18896
+ if (raw === null)
18897
+ return null;
18898
+ try {
18899
+ const parsed = JSON.parse(raw);
18900
+ if (!Array.isArray(parsed))
18901
+ return null;
18902
+ const provenance = [];
18903
+ for (const value of parsed) {
18904
+ if (!value || typeof value !== "object")
18905
+ return null;
18906
+ const source = value;
18907
+ if (typeof source.candidate_id !== "number" || !Number.isFinite(source.candidate_id) || typeof source.project_path !== "string" || typeof source.harness !== "string" || typeof source.session_id !== "string" || source.source_compartment_start !== null && typeof source.source_compartment_start !== "number" || source.source_compartment_end !== null && typeof source.source_compartment_end !== "number" || typeof source.source_start_message_id !== "string" || typeof source.source_end_message_id !== "string") {
18908
+ return null;
18909
+ }
18910
+ provenance.push({
18911
+ candidateId: source.candidate_id,
18912
+ projectPath: source.project_path,
18913
+ harness: source.harness,
18914
+ sessionId: source.session_id,
18915
+ sourceCompartmentStart: source.source_compartment_start,
18916
+ sourceCompartmentEnd: source.source_compartment_end,
18917
+ sourceStartMessageId: source.source_start_message_id,
18918
+ sourceEndMessageId: source.source_end_message_id
18919
+ });
18920
+ }
18921
+ return provenance;
18922
+ } catch {
18923
+ return null;
18924
+ }
18925
+ }
18926
+ function loadPrimerSourceProvenance(db, candidateIds) {
18927
+ const ids = [...new Set(candidateIds)].sort((a, b) => a - b);
18928
+ if (ids.length === 0)
18929
+ return [];
18930
+ const placeholders3 = ids.map(() => "?").join(",");
18931
+ const rows = db.prepare(`SELECT id, project_path, harness, session_id,
18932
+ source_compartment_start, source_compartment_end,
18933
+ source_start_message_id, source_end_message_id
18934
+ FROM primer_candidates
18935
+ WHERE id IN (${placeholders3})
18936
+ ORDER BY id ASC`).all(...ids);
18937
+ return rows.map((row) => ({
18938
+ candidateId: row.id,
18939
+ projectPath: row.project_path,
18940
+ harness: row.harness,
18941
+ sessionId: row.session_id,
18942
+ sourceCompartmentStart: row.source_compartment_start,
18943
+ sourceCompartmentEnd: row.source_compartment_end,
18944
+ sourceStartMessageId: row.source_start_message_id,
18945
+ sourceEndMessageId: row.source_end_message_id
18946
+ }));
18947
+ }
18948
+ function serializePrimerSourceProvenance(provenance, sourceCandidateIds) {
18949
+ if (provenance.length === 0 && sourceCandidateIds.length > 0)
18950
+ return null;
18951
+ return JSON.stringify(provenance.map((source) => ({
18952
+ candidate_id: source.candidateId,
18953
+ project_path: source.projectPath,
18954
+ harness: source.harness,
18955
+ session_id: source.sessionId,
18956
+ source_compartment_start: source.sourceCompartmentStart,
18957
+ source_compartment_end: source.sourceCompartmentEnd,
18958
+ source_start_message_id: source.sourceStartMessageId,
18959
+ source_end_message_id: source.sourceEndMessageId
18960
+ })));
18961
+ }
18962
+ function normalizedCandidateIds(candidateIds) {
18963
+ return [...new Set(candidateIds)].sort((a, b) => a - b);
18964
+ }
18438
18965
  function toCandidate(row) {
18439
18966
  return {
18440
18967
  id: row.id,
@@ -18467,6 +18994,7 @@ function toPrimer(row) {
18467
18994
  lastObservedAt: row.last_observed_at,
18468
18995
  answerRefreshedAt: row.answer_refreshed_at,
18469
18996
  sourceCandidateIds: parseCandidateIds(row.source_candidate_ids),
18997
+ sourceProvenance: parsePrimerSourceProvenance(row.source_candidate_provenance),
18470
18998
  createdAt: row.created_at,
18471
18999
  updatedAt: row.updated_at
18472
19000
  };
@@ -18538,23 +19066,43 @@ function getActivePrimers(db, projectPath) {
18538
19066
  return rows.map(toPrimer);
18539
19067
  }
18540
19068
  function createPrimer(db, input) {
18541
- const now = input.now ?? Date.now();
18542
- const info = db.prepare(`INSERT INTO primers (
18543
- project_path, question, question_embedding, question_embedding_model_id, answer,
18544
- status, total_support, last_observed_at, answer_refreshed_at,
18545
- source_candidate_ids, created_at, updated_at
18546
- ) VALUES (?, ?, ?, ?, ?, 'active', ?, ?, NULL, ?, ?, ?)`).run(input.projectPath, input.question, vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.answer ?? "", input.totalSupport, input.lastObservedAt, JSON.stringify([...new Set(input.sourceCandidateIds)].sort((a, b) => a - b)), now, now);
18547
- return Number(info.lastInsertRowid);
19069
+ return db.transaction(() => {
19070
+ const now = input.now ?? Date.now();
19071
+ const sourceCandidateIds = normalizedCandidateIds(input.sourceCandidateIds);
19072
+ const sourceProvenance = loadPrimerSourceProvenance(db, sourceCandidateIds);
19073
+ const info = db.prepare(`INSERT INTO primers (
19074
+ project_path, question, question_embedding, question_embedding_model_id, answer,
19075
+ status, total_support, last_observed_at, answer_refreshed_at,
19076
+ source_candidate_ids, source_candidate_provenance, created_at, updated_at
19077
+ ) VALUES (?, ?, ?, ?, ?, 'active', ?, ?, NULL, ?, ?, ?, ?)`).run(input.projectPath, input.question, vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.answer ?? "", input.totalSupport, input.lastObservedAt, JSON.stringify(sourceCandidateIds), serializePrimerSourceProvenance(sourceProvenance, sourceCandidateIds), now, now);
19078
+ return Number(info.lastInsertRowid);
19079
+ })();
18548
19080
  }
18549
19081
  function updatePrimerSupport(db, input) {
18550
- db.prepare(`UPDATE primers
18551
- SET question_embedding = COALESCE(?, question_embedding),
18552
- question_embedding_model_id = COALESCE(?, question_embedding_model_id),
18553
- total_support = ?,
18554
- last_observed_at = ?,
18555
- source_candidate_ids = ?,
18556
- updated_at = ?
18557
- WHERE id = ?`).run(vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.totalSupport, input.lastObservedAt, JSON.stringify([...new Set(input.sourceCandidateIds)].sort((a, b) => a - b)), input.now ?? Date.now(), input.primerId);
19082
+ db.transaction(() => {
19083
+ const sourceCandidateIds = normalizedCandidateIds(input.sourceCandidateIds);
19084
+ const allowedIds = new Set(sourceCandidateIds);
19085
+ const existingRow = db.prepare("SELECT source_candidate_provenance FROM primers WHERE id = ?").get(input.primerId);
19086
+ const provenanceByCandidateId = new Map;
19087
+ for (const source of parsePrimerSourceProvenance(existingRow?.source_candidate_provenance ?? null) ?? []) {
19088
+ if (allowedIds.has(source.candidateId)) {
19089
+ provenanceByCandidateId.set(source.candidateId, source);
19090
+ }
19091
+ }
19092
+ for (const source of loadPrimerSourceProvenance(db, sourceCandidateIds)) {
19093
+ provenanceByCandidateId.set(source.candidateId, source);
19094
+ }
19095
+ const sourceProvenance = [...provenanceByCandidateId.values()].sort((a, b) => a.candidateId - b.candidateId);
19096
+ db.prepare(`UPDATE primers
19097
+ SET question_embedding = COALESCE(?, question_embedding),
19098
+ question_embedding_model_id = COALESCE(?, question_embedding_model_id),
19099
+ total_support = ?,
19100
+ last_observed_at = ?,
19101
+ source_candidate_ids = ?,
19102
+ source_candidate_provenance = ?,
19103
+ updated_at = ?
19104
+ WHERE id = ?`).run(vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.totalSupport, input.lastObservedAt, JSON.stringify(sourceCandidateIds), serializePrimerSourceProvenance(sourceProvenance, sourceCandidateIds), input.now ?? Date.now(), input.primerId);
19105
+ })();
18558
19106
  }
18559
19107
  function updatePrimerAnswer(db, primerId, answer, refreshedAt = Date.now()) {
18560
19108
  db.prepare("UPDATE primers SET answer = ?, answer_refreshed_at = ?, updated_at = ? WHERE id = ?").run(answer, refreshedAt, refreshedAt, primerId);
@@ -18645,6 +19193,436 @@ function getLatestHistorianInvocationId(db, sessionId) {
18645
19193
  return null;
18646
19194
  }
18647
19195
  }
19196
+ // ../plugin/src/features/magic-context/reclaim-protection.ts
19197
+ var CTX_REDUCE_KEEP = 3;
19198
+ function newestCtxReduceTagNumbers(tags) {
19199
+ return new Set(tags.filter((tag) => tag.toolName === "ctx_reduce").sort((left, right) => right.tagNumber - left.tagNumber).slice(0, CTX_REDUCE_KEEP).map((tag) => tag.tagNumber));
19200
+ }
19201
+
19202
+ // ../plugin/src/hooks/magic-context/image-token-estimate.ts
19203
+ var IMAGE_TOKEN_DIVISOR = 750;
19204
+ var IMAGE_FALLBACK_TOKENS = 1200;
19205
+ var IMAGE_TOKEN_CAP = 4500;
19206
+ function estimateImageTokensFromDataUrl(url) {
19207
+ const comma = url.indexOf(",");
19208
+ if (comma < 0)
19209
+ return IMAGE_FALLBACK_TOKENS;
19210
+ const header = url.slice(0, comma);
19211
+ const payload = url.slice(comma + 1);
19212
+ const sliceLen = Math.min(512, payload.length);
19213
+ const preview = payload.slice(0, sliceLen);
19214
+ let bytes;
19215
+ try {
19216
+ bytes = base64Decode(preview);
19217
+ } catch {
19218
+ return IMAGE_FALLBACK_TOKENS;
19219
+ }
19220
+ if (header.includes("image/png")) {
19221
+ const dims = parsePngDimensions(bytes);
19222
+ if (dims)
19223
+ return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
19224
+ } else if (header.includes("image/jpeg") || header.includes("image/jpg")) {
19225
+ const dims = parseJpegDimensions(bytes);
19226
+ if (dims)
19227
+ return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
19228
+ } else if (header.includes("image/webp")) {
19229
+ const dims = parseWebpDimensions(bytes);
19230
+ if (dims)
19231
+ return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
19232
+ } else if (header.includes("image/gif")) {
19233
+ const dims = parseGifDimensions(bytes);
19234
+ if (dims)
19235
+ return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
19236
+ }
19237
+ return IMAGE_FALLBACK_TOKENS;
19238
+ }
19239
+ function clampImageTokens(n) {
19240
+ if (n < 1)
19241
+ return 1;
19242
+ if (n > IMAGE_TOKEN_CAP)
19243
+ return IMAGE_TOKEN_CAP;
19244
+ return n;
19245
+ }
19246
+ function base64Decode(b64) {
19247
+ const pad = b64.length % 4;
19248
+ const padded = pad === 0 ? b64 : b64 + "=".repeat(4 - pad);
19249
+ const binary = atob(padded);
19250
+ const out = new Uint8Array(binary.length);
19251
+ for (let i = 0;i < binary.length; i++)
19252
+ out[i] = binary.charCodeAt(i);
19253
+ return out;
19254
+ }
19255
+ function parsePngDimensions(b) {
19256
+ if (b.length < 24)
19257
+ return null;
19258
+ if (b[0] !== 137 || b[1] !== 80 || b[2] !== 78 || b[3] !== 71 || b[4] !== 13 || b[5] !== 10 || b[6] !== 26 || b[7] !== 10)
19259
+ return null;
19260
+ const w = readUint32BE(b, 16);
19261
+ const h = readUint32BE(b, 20);
19262
+ if (!w || !h)
19263
+ return null;
19264
+ return { w, h };
19265
+ }
19266
+ function parseJpegDimensions(b) {
19267
+ if (b.length < 4 || b[0] !== 255 || b[1] !== 216)
19268
+ return null;
19269
+ let i = 2;
19270
+ while (i < b.length - 8) {
19271
+ if (b[i] !== 255) {
19272
+ i++;
19273
+ continue;
19274
+ }
19275
+ const marker = b[i + 1];
19276
+ if (marker === undefined)
19277
+ break;
19278
+ if (isSofMarker(marker)) {
19279
+ const h = b[i + 5] << 8 | b[i + 6];
19280
+ const w = b[i + 7] << 8 | b[i + 8];
19281
+ if (w && h)
19282
+ return { w, h };
19283
+ return null;
19284
+ }
19285
+ if (marker === 216 || marker === 217 || marker === 1) {
19286
+ i += 2;
19287
+ continue;
19288
+ }
19289
+ const segLen = b[i + 2] << 8 | b[i + 3];
19290
+ if (segLen < 2)
19291
+ return null;
19292
+ i += 2 + segLen;
19293
+ }
19294
+ return null;
19295
+ }
19296
+ function isSofMarker(m) {
19297
+ if (m >= 192 && m <= 195)
19298
+ return true;
19299
+ if (m >= 197 && m <= 199)
19300
+ return true;
19301
+ if (m >= 201 && m <= 203)
19302
+ return true;
19303
+ if (m >= 205 && m <= 207)
19304
+ return true;
19305
+ return false;
19306
+ }
19307
+ function parseWebpDimensions(b) {
19308
+ if (b.length < 30)
19309
+ return null;
19310
+ if (b[0] !== 82 || b[1] !== 73 || b[2] !== 70 || b[3] !== 70)
19311
+ return null;
19312
+ if (b[8] !== 87 || b[9] !== 69 || b[10] !== 66 || b[11] !== 80)
19313
+ return null;
19314
+ const variant = String.fromCharCode(b[12], b[13], b[14], b[15]);
19315
+ if (variant === "VP8 ") {
19316
+ const w = (b[26] | b[27] << 8) & 16383;
19317
+ const h = (b[28] | b[29] << 8) & 16383;
19318
+ if (w && h)
19319
+ return { w, h };
19320
+ } else if (variant === "VP8L") {
19321
+ const b0 = b[21];
19322
+ const b1 = b[22];
19323
+ const b2 = b[23];
19324
+ const b3 = b[24];
19325
+ const w = 1 + ((b0 | b1 << 8) & 16383);
19326
+ const h = 1 + ((b1 >> 6 | b2 << 2 | b3 << 10) & 16383);
19327
+ if (w && h)
19328
+ return { w, h };
19329
+ } else if (variant === "VP8X") {
19330
+ const w = 1 + (b[24] | b[25] << 8 | b[26] << 16);
19331
+ const h = 1 + (b[27] | b[28] << 8 | b[29] << 16);
19332
+ if (w && h)
19333
+ return { w, h };
19334
+ }
19335
+ return null;
19336
+ }
19337
+ function parseGifDimensions(b) {
19338
+ if (b.length < 10)
19339
+ return null;
19340
+ if (b[0] !== 71 || b[1] !== 73 || b[2] !== 70)
19341
+ return null;
19342
+ const w = b[6] | b[7] << 8;
19343
+ const h = b[8] | b[9] << 8;
19344
+ if (!w || !h)
19345
+ return null;
19346
+ return { w, h };
19347
+ }
19348
+ function readUint32BE(b, offset) {
19349
+ return (b[offset] << 24 | b[offset + 1] << 16 | b[offset + 2] << 8 | b[offset + 3]) >>> 0;
19350
+ }
19351
+
19352
+ // ../plugin/src/hooks/magic-context/tail-hygiene-walk.ts
19353
+ var MAX_CONTENT_MEMO_BYTES = 64 * 1024 * 1024;
19354
+ var contentMemo = new Map;
19355
+ var CHANNEL1_REMINDER_OPEN = `
19356
+
19357
+ <system-reminder>
19358
+ `;
19359
+ var CHANNEL1_REMINDER_CLOSE = `
19360
+ </system-reminder>`;
19361
+ function stripChannel1ReminderSpans(output) {
19362
+ let stripped = output;
19363
+ while (stripped.endsWith(CHANNEL1_REMINDER_CLOSE)) {
19364
+ const opener = stripped.lastIndexOf(CHANNEL1_REMINDER_OPEN);
19365
+ if (opener < 0)
19366
+ break;
19367
+ stripped = stripped.slice(0, opener);
19368
+ }
19369
+ return stripped;
19370
+ }
19371
+ function effectiveTailHygiene(baseline) {
19372
+ const t = Math.max(0, baseline.baselineT + baseline.turnDeltaT);
19373
+ const u = Math.min(t, Math.max(0, baseline.baselineU + baseline.turnDeltaU));
19374
+ return { u, t };
19375
+ }
19376
+
19377
+ // ../plugin/src/hooks/magic-context/ctx-reduce-nudge.ts
19378
+ var CHANNEL1_SENTINEL = "<system-reminder>";
19379
+ var TOKENS_PER_BYTE = 0.25;
19380
+ var CHANNEL1_MIN_TOKENS = 60000;
19381
+ var CHANNEL1_FLOOR_TOKENS = 25000;
19382
+ var CHANNEL1_REFIRE_FLOOR_TOKENS = 25000;
19383
+ var S_GENTLE = 0.2;
19384
+ var S_FIRM = 0.4;
19385
+ var S_URGENT = 0.6;
19386
+ var LEVEL_RANK = { gentle: 1, firm: 2, urgent: 3 };
19387
+ function channel1RefireTokens(tailTokens) {
19388
+ const scaled = Math.round(0.08 * Math.max(0, tailTokens));
19389
+ return Math.max(CHANNEL1_REFIRE_FLOOR_TOKENS, scaled);
19390
+ }
19391
+ function decideChannel1(input) {
19392
+ const tailTokens = Math.max(0, input.baselineT + input.turnDeltaT);
19393
+ const undroppedTokens = Math.min(tailTokens, Math.max(0, input.baselineU + input.turnDeltaU));
19394
+ const severity = Math.min(1, Math.max(0, undroppedTokens / Math.max(tailTokens, 1)));
19395
+ const resetCycle = input.hasRecentReduce || undroppedTokens < input.lastNudgeUndropped;
19396
+ const lastNudge = resetCycle ? 0 : input.lastNudgeUndropped;
19397
+ const lastLevel = resetCycle ? "" : input.lastNudgeLevel;
19398
+ const quiet = () => ({
19399
+ fire: false,
19400
+ level: "gentle",
19401
+ undroppedTokens,
19402
+ tailTokens,
19403
+ severity,
19404
+ nextLastNudge: lastNudge,
19405
+ nextLastNudgeLevel: lastLevel
19406
+ });
19407
+ if (input.evaluable === false || input.generationInvalidated === true)
19408
+ return quiet();
19409
+ if (input.hasRecentReduce)
19410
+ return quiet();
19411
+ if (tailTokens < CHANNEL1_MIN_TOKENS)
19412
+ return quiet();
19413
+ if (undroppedTokens < CHANNEL1_FLOOR_TOKENS || undroppedTokens === 0)
19414
+ return quiet();
19415
+ if (severity < S_GENTLE)
19416
+ return quiet();
19417
+ let level;
19418
+ if (severity >= S_URGENT)
19419
+ level = "urgent";
19420
+ else if (severity >= S_FIRM)
19421
+ level = "firm";
19422
+ else
19423
+ level = "gentle";
19424
+ const escalated = lastLevel === "" || LEVEL_RANK[level] > LEVEL_RANK[lastLevel];
19425
+ const cadenceReached = lastLevel !== "" && undroppedTokens - lastNudge >= channel1RefireTokens(tailTokens);
19426
+ if (!escalated && !cadenceReached)
19427
+ return quiet();
19428
+ return {
19429
+ fire: true,
19430
+ level,
19431
+ undroppedTokens,
19432
+ tailTokens,
19433
+ severity,
19434
+ nextLastNudge: undroppedTokens,
19435
+ nextLastNudgeLevel: level
19436
+ };
19437
+ }
19438
+ var CHANNEL2_SEVERITY_THRESHOLD = 0.75;
19439
+ var CHANNEL2_FLOOR_TOKENS = 50000;
19440
+ function evaluateChannel2(input) {
19441
+ const values = input ? [input.baselineU, input.baselineT, input.turnDeltaU, input.turnDeltaT] : [];
19442
+ if (input?.evaluable !== true || input.generationInvalidated === true || values.some((value) => !Number.isFinite(value))) {
19443
+ return {
19444
+ evaluable: false,
19445
+ shouldTrigger: false,
19446
+ reclaimableTokens: 0,
19447
+ tailTokens: 0,
19448
+ severity: 0
19449
+ };
19450
+ }
19451
+ const tailTokens = Math.max(0, input.baselineT + input.turnDeltaT);
19452
+ const reclaimableTokens = Math.min(tailTokens, Math.max(0, input.baselineU + input.turnDeltaU));
19453
+ const severity = Math.min(1, Math.max(0, reclaimableTokens / Math.max(tailTokens, 1)));
19454
+ return {
19455
+ evaluable: true,
19456
+ shouldTrigger: tailTokens >= CHANNEL1_MIN_TOKENS && reclaimableTokens >= CHANNEL2_FLOOR_TOKENS && severity >= CHANNEL2_SEVERITY_THRESHOLD,
19457
+ reclaimableTokens,
19458
+ tailTokens,
19459
+ severity
19460
+ };
19461
+ }
19462
+ function approxThousands(tokens) {
19463
+ return `${Math.round(tokens / 1000)}k`;
19464
+ }
19465
+ function formatOldestReclaimableHint(hint) {
19466
+ if (!hint || hint.length === 0)
19467
+ return "";
19468
+ const rendered = hint.slice(0, 4).map((tag) => `§${tag.tagNumber}§ ${tag.toolName ?? "tool"}`).join(" · ");
19469
+ return rendered.length > 0 ? `
19470
+ oldest reclaimable: ${rendered}.` : "";
19471
+ }
19472
+ function buildChannel2Reminder(undroppedTokens, hint) {
19473
+ const amount = approxThousands(undroppedTokens);
19474
+ const hintText = formatOldestReclaimableHint(hint);
19475
+ return `<system-reminder>
19476
+ ` + `Routine context housekeeping is near: a large span of this session will be comparted soon, ` + `and ~${amount} tokens of tool output remain unreduced. Drop spent outputs with ctx_reduce ` + `first so the archived span is the part that matters.${hintText}
19477
+ ` + `</system-reminder>`;
19478
+ }
19479
+ function buildChannel1Reminder(level, undroppedTokens, hint) {
19480
+ const amount = approxThousands(undroppedTokens);
19481
+ const hintText = formatOldestReclaimableHint(hint);
19482
+ let body;
19483
+ switch (level) {
19484
+ case "gentle":
19485
+ body = `You have ~${amount} tokens of content you have not reduced. ` + `When you are done with earlier outputs, dropping them with ctx_reduce keeps context lean.`;
19486
+ break;
19487
+ case "firm":
19488
+ body = `~${amount} tokens of unreduced content has built up. ` + `At your next natural stopping point, consider dropping what you have already processed with ctx_reduce.`;
19489
+ break;
19490
+ case "urgent":
19491
+ body = `~${amount} tokens of unreduced content remain across most of the live tail. ` + `Consider dropping spent outputs with ctx_reduce so the archived span is the part that matters.`;
19492
+ break;
19493
+ }
19494
+ return `
19495
+
19496
+ <system-reminder>
19497
+ ${body}${hintText}
19498
+ </system-reminder>`;
19499
+ }
19500
+
19501
+ // ../plugin/src/hooks/magic-context/emergency-drop.ts
19502
+ var TARGET_FRACTION = 0.3;
19503
+ var TIER_RECENCY_RESERVE = 0.2;
19504
+ var EMERGENCY_REARM_MIN_TOKENS = 2000;
19505
+ var T1_TOOLS = new Set(["read", "todowrite", "task", "aft_outline", "aft_zoom"]);
19506
+ var T2_TOOLS = new Set(["edit", "write", "apply_patch", "grep", "glob", "aft_search"]);
19507
+ function normalizeToolName(toolName) {
19508
+ if (!toolName)
19509
+ return "";
19510
+ let name = toolName.toLowerCase();
19511
+ if (name.startsWith("mcp_"))
19512
+ name = name.slice(4);
19513
+ return name;
19514
+ }
19515
+ function resolveToolTier(toolName) {
19516
+ const name = normalizeToolName(toolName);
19517
+ if (T1_TOOLS.has(name))
19518
+ return 1;
19519
+ if (T2_TOOLS.has(name))
19520
+ return 2;
19521
+ return 3;
19522
+ }
19523
+ function tagReclaimBytes(tag) {
19524
+ return tag.byteSize + tag.inputByteSize + tag.reasoningByteSize;
19525
+ }
19526
+ function estimateEmergencyDropReclaimTokens(tag) {
19527
+ return Math.round(tagReclaimBytes(tag) * TOKENS_PER_BYTE);
19528
+ }
19529
+ function planEmergencyDrop(input) {
19530
+ const {
19531
+ tags,
19532
+ floorTags,
19533
+ maxTag,
19534
+ protectedTags,
19535
+ currentTotalInputTokens,
19536
+ ceilingTokens,
19537
+ priorInputSample,
19538
+ hasPriorDrop
19539
+ } = input;
19540
+ const noop = (reason) => ({
19541
+ shouldDrop: false,
19542
+ tagNumbers: [],
19543
+ reclaimTokens: 0,
19544
+ reason
19545
+ });
19546
+ if (!Number.isFinite(ceilingTokens) || ceilingTokens <= 0) {
19547
+ return noop("unknown-ceiling");
19548
+ }
19549
+ if (!Number.isFinite(currentTotalInputTokens) || currentTotalInputTokens <= 0) {
19550
+ return noop("unknown-usage");
19551
+ }
19552
+ if (hasPriorDrop && currentTotalInputTokens === priorInputSample) {
19553
+ return noop("same-input-sample (awaiting fresh usage after prior drop)");
19554
+ }
19555
+ let tailTokens = 0;
19556
+ for (const tag of floorTags) {
19557
+ if (tag.status !== "active")
19558
+ continue;
19559
+ tailTokens += estimateEmergencyDropReclaimTokens(tag);
19560
+ }
19561
+ const fixedFloor = Math.max(currentTotalInputTokens - tailTokens, 0);
19562
+ const workingSpan = Math.max(ceilingTokens - fixedFloor, 0);
19563
+ const target = fixedFloor + TARGET_FRACTION * workingSpan;
19564
+ const reclaimTokens = Math.round(currentTotalInputTokens - target);
19565
+ if (reclaimTokens <= EMERGENCY_REARM_MIN_TOKENS) {
19566
+ return noop(`reclaim<=min (${reclaimTokens} <= ${EMERGENCY_REARM_MIN_TOKENS})`);
19567
+ }
19568
+ const protectedCutoff = maxTag - protectedTags;
19569
+ const tierActive = { 1: [], 2: [] };
19570
+ for (const tag of tags) {
19571
+ if (tag.status !== "active" || tag.type !== "tool")
19572
+ continue;
19573
+ const tier = resolveToolTier(tag.toolName);
19574
+ if (tier === 1 || tier === 2)
19575
+ tierActive[tier].push(tag.tagNumber);
19576
+ }
19577
+ const reserved = new Set;
19578
+ for (const tier of [1, 2]) {
19579
+ const nums = tierActive[tier];
19580
+ if (nums.length === 0)
19581
+ continue;
19582
+ nums.sort((a, b) => b - a);
19583
+ const reserveCount = Math.ceil(TIER_RECENCY_RESERVE * nums.length);
19584
+ for (let i = 0;i < reserveCount && i < nums.length; i++) {
19585
+ reserved.add(nums[i]);
19586
+ }
19587
+ }
19588
+ const protectedCtxReduceTags = newestCtxReduceTagNumbers(floorTags.filter((tag) => tag.status === "active" && tag.type === "tool"));
19589
+ const byTier = { 1: [], 2: [], 3: [] };
19590
+ for (const tag of tags) {
19591
+ if (tag.status !== "active" || tag.type !== "tool")
19592
+ continue;
19593
+ if (tag.tagNumber > protectedCutoff)
19594
+ continue;
19595
+ if (protectedCtxReduceTags.has(tag.tagNumber))
19596
+ continue;
19597
+ const tier = resolveToolTier(tag.toolName);
19598
+ if ((tier === 1 || tier === 2) && reserved.has(tag.tagNumber))
19599
+ continue;
19600
+ byTier[tier].push(tag);
19601
+ }
19602
+ const selected = [];
19603
+ let reclaimed = 0;
19604
+ outer:
19605
+ for (const tier of [3, 2, 1]) {
19606
+ const group = byTier[tier];
19607
+ group.sort((a, b) => a.tagNumber - b.tagNumber);
19608
+ for (const tag of group) {
19609
+ selected.push(tag.tagNumber);
19610
+ reclaimed += estimateEmergencyDropReclaimTokens(tag);
19611
+ if (reclaimed >= reclaimTokens)
19612
+ break outer;
19613
+ }
19614
+ }
19615
+ if (selected.length === 0) {
19616
+ return noop("no-candidates");
19617
+ }
19618
+ return {
19619
+ shouldDrop: true,
19620
+ tagNumbers: selected,
19621
+ reclaimTokens,
19622
+ reason: `tiered drop: ${selected.length} tags, reclaim≈${reclaimed}/${reclaimTokens} tokens (floor≈${fixedFloor}, ceiling=${Math.round(ceilingTokens)})`
19623
+ };
19624
+ }
19625
+
18648
19626
  // ../plugin/src/features/magic-context/storage-tags.ts
18649
19627
  var insertTagStatements = new WeakMap;
18650
19628
  var updateTagStatusStatements = new WeakMap;
@@ -18707,32 +19685,23 @@ function ownerMessageIdForTagRow(row) {
18707
19685
  }
18708
19686
  return row.message_id.replace(CONTENT_ID_SUFFIX, "");
18709
19687
  }
18710
- function getActiveTagTokenAggregate(db, sessionId, protectedTags = 0) {
18711
- const toolOutputExpr = protectedTags > 0 ? `COALESCE(SUM(CASE WHEN type = 'tool' AND tag_number < (
18712
- SELECT tag_number FROM tags
18713
- WHERE session_id = ? AND status = 'active'
18714
- ORDER BY tag_number DESC LIMIT 1 OFFSET ?
18715
- ) THEN COALESCE(token_count, 0) ELSE 0 END), 0)` : `COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0)`;
18716
- const sql = `SELECT
18717
- COALESCE(SUM(CASE WHEN type != 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0)
18718
- + COALESCE(SUM(COALESCE(reasoning_token_count, 0)), 0) AS conversation,
18719
- COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) + COALESCE(input_token_count, 0) ELSE 0 END), 0) AS tool_call,
18720
- ${toolOutputExpr} AS tool_output,
18721
- COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
18722
- FROM tags
18723
- WHERE session_id = ? AND status = 'active'`;
18724
- const params = protectedTags > 0 ? [sessionId, protectedTags - 1, sessionId] : [sessionId];
18725
- const row = db.prepare(sql).get(...params);
18726
- return {
18727
- conversation: row?.conversation ?? 0,
18728
- toolCall: row?.tool_call ?? 0,
18729
- toolOutput: row?.tool_output ?? 0,
18730
- nullCount: row?.null_count ?? 0
18731
- };
18732
- }
18733
- var RECLAIM_HINT_EXCLUDED_TOOLS = ["todowrite"];
19688
+ var RECLAIM_HINT_EXCLUDED_TOOLS = new Set([
19689
+ "ask",
19690
+ "bash_kill",
19691
+ "bash_status",
19692
+ "board",
19693
+ "task",
19694
+ "todoread",
19695
+ "todowrite",
19696
+ "work"
19697
+ ]);
18734
19698
  var AGE_RECLAIM_MIN_TOKENS = 250;
18735
- var RECLAIM_HINT_EXCLUDED_LIST = RECLAIM_HINT_EXCLUDED_TOOLS.map((name) => `'${name.replace(/'/g, "''")}'`).join(", ");
19699
+ function isReclaimHintExcludedTool(toolName) {
19700
+ if (!toolName)
19701
+ return false;
19702
+ const normalized = toolName.toLowerCase().replace(/^mcp_/, "");
19703
+ return normalized.startsWith("ctx_") || RECLAIM_HINT_EXCLUDED_TOOLS.has(normalized);
19704
+ }
18736
19705
  function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, limit = 4) {
18737
19706
  if (limit <= 0)
18738
19707
  return [];
@@ -18742,24 +19711,21 @@ function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, li
18742
19711
  WHERE session_id = ? AND status = 'active'
18743
19712
  ORDER BY tag_number DESC LIMIT 1 OFFSET ?
18744
19713
  )` : "";
18745
- const excludeStateTools = RECLAIM_HINT_EXCLUDED_LIST ? `AND (tool_name IS NULL OR tool_name NOT IN (${RECLAIM_HINT_EXCLUDED_LIST}))` : "";
18746
19714
  const valueFloor = `AND (
18747
19715
  (token_count IS NULL AND input_token_count IS NULL)
18748
19716
  OR (COALESCE(token_count, 0) + COALESCE(input_token_count, 0)) >= ?
18749
19717
  )`;
18750
- const params = protectedTags > 0 ? [sessionId, AGE_RECLAIM_MIN_TOKENS, sessionId, protectedTags - 1, boundedLimit] : [sessionId, AGE_RECLAIM_MIN_TOKENS, boundedLimit];
19718
+ const params = protectedTags > 0 ? [sessionId, AGE_RECLAIM_MIN_TOKENS, sessionId, protectedTags - 1] : [sessionId, AGE_RECLAIM_MIN_TOKENS];
18751
19719
  const rows = db.prepare(`SELECT tag_number, tool_name
18752
19720
  FROM tags
18753
19721
  WHERE session_id = ? AND status = 'active' AND type = 'tool'
18754
- ${excludeStateTools}
18755
19722
  ${valueFloor}
18756
19723
  ${whereProtected}
18757
- ORDER BY tag_number ASC, id ASC
18758
- LIMIT ?`).all(...params);
19724
+ ORDER BY tag_number ASC, id ASC`).all(...params);
18759
19725
  return rows.filter((row) => typeof row.tag_number === "number").map((row) => ({
18760
19726
  tagNumber: row.tag_number,
18761
19727
  toolName: typeof row.tool_name === "string" ? row.tool_name : null
18762
- }));
19728
+ })).filter((tag) => !isReclaimHintExcludedTool(tag.toolName)).sort((left, right) => resolveToolTier(right.toolName) - resolveToolTier(left.toolName) || left.tagNumber - right.tagNumber).slice(0, boundedLimit);
18763
19729
  }
18764
19730
  var getActiveToolTagsForAgeReclaimStatements = new WeakMap;
18765
19731
  function getActiveToolTagsForAgeReclaim(db, sessionId) {
@@ -18772,7 +19738,7 @@ function getActiveToolTagsForAgeReclaim(db, sessionId) {
18772
19738
  getActiveToolTagsForAgeReclaimStatements.set(db, stmt);
18773
19739
  }
18774
19740
  const rows = stmt.all(sessionId);
18775
- return rows.filter((row) => typeof row.tag_number === "number").map((row) => {
19741
+ const tags = rows.filter((row) => typeof row.tag_number === "number").map((row) => {
18776
19742
  const outputTokens = typeof row.token_count === "number" ? row.token_count : null;
18777
19743
  const inputTokens = typeof row.input_token_count === "number" ? row.input_token_count : null;
18778
19744
  return {
@@ -18781,6 +19747,8 @@ function getActiveToolTagsForAgeReclaim(db, sessionId) {
18781
19747
  reclaimableTokens: outputTokens === null && inputTokens === null ? null : (outputTokens ?? 0) + (inputTokens ?? 0)
18782
19748
  };
18783
19749
  });
19750
+ const protectedCtxReduceTags = newestCtxReduceTagNumbers(tags);
19751
+ return tags.filter((tag) => !protectedCtxReduceTags.has(tag.tagNumber));
18784
19752
  }
18785
19753
  function getTriggerTagTokenUpperBound(db, sessionId, floor = 0) {
18786
19754
  const sql = floor > 0 ? `SELECT
@@ -19225,6 +20193,7 @@ function getTagsBySession(db, sessionId) {
19225
20193
  return rows.map(toTagEntry);
19226
20194
  }
19227
20195
  var getActiveTagsBySessionStatements = new WeakMap;
20196
+ var getNullOwnerToolTagsBySessionStatements = new WeakMap;
19228
20197
  var getDroppedTagsBySessionStatements = new WeakMap;
19229
20198
  var getMaxDroppedTagNumberStatements = new WeakMap;
19230
20199
  function getActiveTagsBySessionStatement(db) {
@@ -19366,157 +20335,9 @@ var ERROR_CLASSES = new Set([
19366
20335
  "permission_denied",
19367
20336
  "unknown"
19368
20337
  ]);
19369
- // ../plugin/src/shared/harness-provider-map.ts
19370
- var CANONICAL_TO_PI_PROVIDER = {
19371
- openai: "openai-codex",
19372
- google: "google-antigravity"
19373
- };
19374
- var PI_TO_CANONICAL_PROVIDER = {
19375
- "openai-codex": "openai",
19376
- "google-antigravity": "google"
19377
- };
19378
- var CANONICAL_TO_OMP_PROVIDER = {
19379
- openai: "openai-codex",
19380
- google: "google-antigravity"
19381
- };
19382
- var OMP_TO_CANONICAL_PROVIDER = {
19383
- "openai-codex": "openai",
19384
- "google-antigravity": "google"
19385
- };
19386
- function remapProviderPrefix(ref, map) {
19387
- if (typeof ref !== "string")
19388
- return ref;
19389
- const slash = ref.indexOf("/");
19390
- if (slash <= 0)
19391
- return ref;
19392
- const provider = ref.slice(0, slash);
19393
- if (!Object.hasOwn(map, provider))
19394
- return ref;
19395
- return `${map[provider]}${ref.slice(slash)}`;
19396
- }
19397
- function piModelRefToCanonical(ref) {
19398
- return remapProviderPrefix(ref, PI_TO_CANONICAL_PROVIDER);
19399
- }
19400
- function resolveModelRefForPi(ref) {
19401
- return remapProviderPrefix(piModelRefToCanonical(ref), CANONICAL_TO_PI_PROVIDER);
19402
- }
19403
- function ompModelRefToCanonical(ref) {
19404
- return remapProviderPrefix(ref, OMP_TO_CANONICAL_PROVIDER);
19405
- }
19406
- function resolveModelRefForOmp(ref) {
19407
- return remapProviderPrefix(ompModelRefToCanonical(ref), CANONICAL_TO_OMP_PROVIDER);
19408
- }
19409
-
19410
- // ../plugin/src/hooks/magic-context/todo-view.ts
19411
- import { createHash as createHash7 } from "node:crypto";
19412
- var TODO_STATUS_PENDING = "pending";
19413
- var TODO_STATUS_IN_PROGRESS = "in_progress";
19414
- var TODO_STATUS_COMPLETED = "completed";
19415
- var TODO_STATUS_CANCELLED = "cancelled";
19416
- var TODO_PRIORITY_HIGH = "high";
19417
- var TODO_PRIORITY_MEDIUM = "medium";
19418
- var TODO_PRIORITY_LOW = "low";
19419
- var TODO_STATUSES = [
19420
- TODO_STATUS_PENDING,
19421
- TODO_STATUS_IN_PROGRESS,
19422
- TODO_STATUS_COMPLETED,
19423
- TODO_STATUS_CANCELLED
19424
- ];
19425
- var TODO_PRIORITIES = [
19426
- TODO_PRIORITY_HIGH,
19427
- TODO_PRIORITY_MEDIUM,
19428
- TODO_PRIORITY_LOW
19429
- ];
19430
- var TODO_STATUS_SET = new Set(TODO_STATUSES);
19431
- var TODO_PRIORITY_SET = new Set(TODO_PRIORITIES);
19432
- var TERMINAL_STATUSES = new Set([
19433
- TODO_STATUS_COMPLETED,
19434
- TODO_STATUS_CANCELLED
19435
- ]);
19436
- var TITLE_DONE_STATUSES = new Set([TODO_STATUS_COMPLETED]);
19437
- var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
19438
- function normalizeTodoStateJson(todos) {
19439
- if (!Array.isArray(todos))
19440
- return null;
19441
- const normalized = [];
19442
- for (const todo of todos) {
19443
- if (!isTodoItem(todo))
19444
- return null;
19445
- normalized.push({
19446
- content: todo.content,
19447
- status: todo.status,
19448
- priority: todo.priority ?? TODO_PRIORITY_MEDIUM
19449
- });
19450
- }
19451
- return JSON.stringify(normalized);
19452
- }
19453
- function buildSyntheticTodoPart(stateJson) {
19454
- const todos = parseTodoState(stateJson);
19455
- if (todos === null || todos.length === 0)
19456
- return null;
19457
- if (todos.every((t) => TERMINAL_STATUSES.has(t.status)))
19458
- return null;
19459
- const callID = computeSyntheticCallId(stateJson);
19460
- const activeCount = todos.filter((t) => !TITLE_DONE_STATUSES.has(t.status)).length;
19461
- const output = JSON.stringify(todos, null, 2);
19462
- const ts = 0;
19463
- return {
19464
- type: "tool",
19465
- callID,
19466
- tool: "todowrite",
19467
- state: {
19468
- status: "completed",
19469
- input: { todos },
19470
- output,
19471
- title: `${activeCount} todos`,
19472
- metadata: { todos, truncated: false },
19473
- time: { start: ts, end: ts }
19474
- },
19475
- syntheticTodoMarker: true
19476
- };
19477
- }
19478
- function computeSyntheticCallId(stateJson) {
19479
- const hash = createHash7("sha256").update(stateJson).digest("hex").slice(0, 16);
19480
- return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
19481
- }
19482
- function parseTodoState(stateJson) {
19483
- if (stateJson.length === 0)
19484
- return null;
19485
- try {
19486
- const parsed = JSON.parse(stateJson);
19487
- if (!Array.isArray(parsed))
19488
- return null;
19489
- const result = [];
19490
- for (const item of parsed) {
19491
- if (!isTodoItem(item))
19492
- return null;
19493
- result.push({
19494
- content: item.content,
19495
- status: item.status,
19496
- priority: item.priority ?? TODO_PRIORITY_MEDIUM
19497
- });
19498
- }
19499
- return result;
19500
- } catch {
19501
- return null;
19502
- }
19503
- }
19504
- function isTodoStatus(value) {
19505
- return typeof value === "string" && TODO_STATUS_SET.has(value);
19506
- }
19507
- function isTodoPriority(value) {
19508
- return typeof value === "string" && TODO_PRIORITY_SET.has(value);
19509
- }
19510
- function isTodoItem(value) {
19511
- if (value === null || typeof value !== "object")
19512
- return false;
19513
- const todo = value;
19514
- return typeof todo.content === "string" && isTodoStatus(todo.status) && (todo.priority === undefined || isTodoPriority(todo.priority));
19515
- }
19516
-
19517
20338
  // ../plugin/src/shared/prompt-surface-runtime.ts
19518
20339
  import { existsSync as existsSync8, readFileSync as readFileSync7, statSync as statSync5 } from "node:fs";
19519
- import { dirname as dirname4, isAbsolute as isAbsolute2, resolve as resolve2 } from "node:path";
20340
+ import { dirname as dirname4, isAbsolute as isAbsolute2, resolve as resolve3 } from "node:path";
19520
20341
 
19521
20342
  // ../plugin/src/tools/light-descriptions.ts
19522
20343
  var CTX_REDUCE_LIGHT_DESCRIPTION = `For ctx_reduce users, mark spent §N§ outputs discardable; release is QUEUED, not immediate, so content stays visible until space is needed. Newest tags stay protected until they age out. Released content becomes a placeholder; recover it only by rerunning the source or recovery tool, so mark only genuinely finished material. Mark analyzed, redundant, persisted, or merely confirmatory outputs; keep user messages, unresolved errors, unextracted evidence, and exact wording. NEVER blanket-mark a large range: review every tag first.`;
@@ -19649,16 +20470,25 @@ function modelKeyLookupOrder(modelKey) {
19649
20470
  return [];
19650
20471
  const provider = modelKey.slice(0, slash);
19651
20472
  let modelID = modelKey.slice(slash + 1);
20473
+ const providerRefs = modelRefLookupOrder(`${provider}/${modelID}`);
19652
20474
  const candidates = [];
19653
20475
  while (modelID.length > 0) {
19654
- candidates.push({ key: `${provider}/${modelID}`, source: "exact" });
20476
+ for (const providerRef of providerRefs) {
20477
+ const providerSlash = providerRef.indexOf("/");
20478
+ const providerPrefix = providerRef.slice(0, providerSlash);
20479
+ candidates.push({ key: `${providerPrefix}/${modelID}`, source: "exact" });
20480
+ }
19655
20481
  candidates.push({ key: modelID, source: "bare" });
19656
20482
  const lastDash = modelID.lastIndexOf("-");
19657
20483
  if (lastDash <= 0)
19658
20484
  break;
19659
20485
  modelID = modelID.slice(0, lastDash);
19660
20486
  }
19661
- candidates.push({ key: `${provider}/*`, source: "wildcard" });
20487
+ for (const providerRef of providerRefs) {
20488
+ const providerSlash = providerRef.indexOf("/");
20489
+ const providerPrefix = providerRef.slice(0, providerSlash);
20490
+ candidates.push({ key: `${providerPrefix}/*`, source: "wildcard" });
20491
+ }
19662
20492
  const seen = new Set;
19663
20493
  return candidates.filter((candidate) => {
19664
20494
  if (seen.has(candidate.key))
@@ -19714,7 +20544,7 @@ function promptSurfaceHashMaterial(systemContent, preset = "full") {
19714
20544
  var PROMPT_SURFACE_TOOL_ID_SET = new Set(ACTIVE_TOOL_IDS);
19715
20545
  function resolveUserConfigDirectory(options) {
19716
20546
  if (options.userConfigDirectory)
19717
- return resolve2(options.userConfigDirectory);
20547
+ return resolve3(options.userConfigDirectory);
19718
20548
  const sharedBase = cortexKitUserConfigBasePath();
19719
20549
  const shared = detectConfigFile(sharedBase);
19720
20550
  if (shared.format !== "none")
@@ -19741,7 +20571,7 @@ function createPromptSurfaceRuntime(options) {
19741
20571
  const readGuidanceOverride = (configuredPath) => {
19742
20572
  if (!configuredPath)
19743
20573
  return;
19744
- const path3 = isAbsolute2(configuredPath) ? configuredPath : resolve2(userConfigDirectory, configuredPath);
20574
+ const path3 = isAbsolute2(configuredPath) ? configuredPath : resolve3(userConfigDirectory, configuredPath);
19745
20575
  let content;
19746
20576
  try {
19747
20577
  if (!statSync5(path3).isFile()) {
@@ -19801,12 +20631,13 @@ function createPromptSurfaceGuidanceEpochCache(runtime) {
19801
20631
  const epochs = new Map;
19802
20632
  return {
19803
20633
  resolve(sessionId, config, modelKey) {
20634
+ const canonicalModelKey = modelKey ? piModelRefToCanonical(modelKey) : undefined;
19804
20635
  const cached = epochs.get(sessionId);
19805
- if (cached && cached.config === config && cached.modelKey === modelKey) {
20636
+ if (cached && cached.config === config && cached.modelKey === canonicalModelKey) {
19806
20637
  return cached.selection;
19807
20638
  }
19808
- const selection = runtime.resolveGuidance(config, modelKey);
19809
- epochs.set(sessionId, { config, modelKey, selection });
20639
+ const selection = runtime.resolveGuidance(config, canonicalModelKey);
20640
+ epochs.set(sessionId, { config, modelKey: canonicalModelKey, selection });
19810
20641
  return selection;
19811
20642
  },
19812
20643
  clear(sessionId) {
@@ -20165,7 +20996,7 @@ function pruneNestedConfigLeaf(block, relativePath) {
20165
20996
  }
20166
20997
 
20167
20998
  // src/config/index.ts
20168
- import { existsSync as existsSync10, readFileSync as readFileSync10 } from "node:fs";
20999
+ import { existsSync as existsSync10, readFileSync as readFileSync11 } from "node:fs";
20169
21000
 
20170
21001
  // ../plugin/src/config/migrate-dreamer-v2.ts
20171
21002
  var OLD_VERIFY_TASK = "verify";
@@ -35228,7 +36059,10 @@ var MagicContextConfigSchema = exports_external.object({
35228
36059
  output_reserve: exports_external.union([
35229
36060
  exports_external.number().min(0),
35230
36061
  exports_external.object({ default: exports_external.number().min(0) }).catchall(exports_external.number().min(0))
35231
- ]).optional().describe('User-only output-token reservation override. Number or per-model object ({ default: 16384, "provider/model": 8192 }); 0 disables reservation. When unset, Magic Context reserves the catalog output limit (capped at 25% of context) for shared-window providers and keeps proven separate-quota Google/Gemini windows unchanged.'),
36062
+ ]).optional().describe('User-only output-token reservation override. Number or per-model object ({ default: 16384, "provider/model": 8192 }); 0 disables reservation. Takes precedence over every derived source: an explicit value here always wins against catalog output limits, provider window-geometry facts, and the 25%-of-context fallback (usable window = context window minus this reserve). When unset, Magic Context reserves the catalog output limit (capped at 25% of context) for shared-window providers and keeps proven separate-quota Google/Gemini windows unchanged.'),
36063
+ models: exports_external.object({
36064
+ window_overlay_path: exports_external.string().trim().min(1).optional()
36065
+ }).optional().describe("User-only Fusiform window-overlay settings. The path defaults to <dataDir>/fusiform/window-overlay.json."),
35232
36066
  toast_duration_ms: exports_external.number().min(0).max(60000).default(5000).describe("TUI toast lifetime in milliseconds for Magic Context notifications. Set to 0 to disable Magic Context toasts entirely (min: 0, max: 60000, default: 5000)"),
35233
36067
  execute_threshold_percentage: exports_external.union([
35234
36068
  exports_external.number().min(20).max(90, EXECUTE_THRESHOLD_CAP_MESSAGE),
@@ -35280,7 +36114,7 @@ var MagicContextConfigSchema = exports_external.object({
35280
36114
  overlay: exports_external.boolean().default(true).describe("Pi only: show the persistent todo overlay above the editor while tasks are active.")
35281
36115
  }).default({ enabled: true, overlay: true }).describe("Pi-only todowrite tool and overlay controls. Pi registers tools and widgets at extension boot, so changing this after /cd requires /reload or restart."),
35282
36116
  pi: PiConfigSchema.describe("Pi-only child-process extension controls. This setting is user-level only; project configuration cannot choose which extensions a user's subagent children load."),
35283
- smart_drops: exports_external.boolean().default(false).describe("Content-aware reclaim of provably-superseded tool output, layered on the existing execute-pass auto-drop. When on: superseded todowrite (keep newest 1), spent ctx_reduce (keep newest 5), and zero-value meta (bash_status, bash_kill, ctx_note read/dismiss) outputs are dropped; older edits to a file are compressed to a filePath-preserving marker while the newest edit per file stays full. Only acts on passes already busting the cache, so it never originates a cache bust. Honors the protected-tag reserve. Experimental: opt-in, default off until cache stability is proven; when off the wire is byte-identical to the positional-only reclaim. Requires a restart."),
36117
+ smart_drops: exports_external.boolean().default(false).describe("Content-aware reclaim of provably-superseded tool output, layered on the existing execute-pass auto-drop. When on: superseded todowrite (keep newest 1), spent ctx_reduce (keep newest 3), and zero-value meta (bash_status, bash_kill, ctx_note read/dismiss) outputs are dropped; older edits to a file are compressed to a filePath-preserving marker while the newest edit per file stays full. Only acts on passes already busting the cache, so it never originates a cache bust. Honors the protected-tag reserve. Experimental: opt-in, default off until cache stability is proven; when off the wire is byte-identical to the positional-only reclaim. Requires a restart."),
35284
36118
  caveman_text_compression: exports_external.object({
35285
36119
  enabled: exports_external.boolean().default(false).describe("Apply deterministic caveman-style text compression to old conversation text. Active for primary sessions when enabled; never for subagents. Compresses user/assistant text in oldest-first tiers: ultra (oldest 20%), full, lite, untouched (newest 40%)."),
35286
36120
  min_chars: exports_external.number().min(100).max(1e4).default(500).describe("Text parts shorter than this (characters) stay untouched. Min 100, max 10000. Default: 500.")
@@ -35442,6 +36276,11 @@ function stripUnsafeProjectConfigFields(projectRaw) {
35442
36276
  delete projectRaw.output_reserve;
35443
36277
  warnings.push("Ignoring output_reserve from project config (security: output-token reservation only honors user-level config).");
35444
36278
  }
36279
+ const models = projectRaw.models;
36280
+ if (isPlainObject3(models) && "window_overlay_path" in models) {
36281
+ delete models.window_overlay_path;
36282
+ warnings.push("Ignoring models.window_overlay_path from project config (security: only user-level config may select model geometry metadata).");
36283
+ }
35445
36284
  if ("language" in projectRaw) {
35446
36285
  delete projectRaw.language;
35447
36286
  warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
@@ -35666,16 +36505,16 @@ function dropInheritedEmbeddingKeyOnRedirect(projectRaw, mergedRaw, userRaw) {
35666
36505
  // ../plugin/src/config/variable.ts
35667
36506
  import { existsSync as existsSync9, readFileSync as readFileSync8 } from "node:fs";
35668
36507
  import { homedir as homedir5 } from "node:os";
35669
- import { dirname as dirname5, isAbsolute as isAbsolute3, resolve as resolve3 } from "node:path";
36508
+ import { dirname as dirname5, isAbsolute as isAbsolute3, resolve as resolve4 } from "node:path";
35670
36509
  var ENV_PATTERN = /\{env:([^}]+)\}/g;
35671
36510
  var FILE_PATTERN = /\{file:([^}]+)\}/g;
35672
36511
  function sensitiveFilePathReason(resolvedPath) {
35673
36512
  const home = homedir5();
35674
36513
  const sensitiveDirs = [
35675
- { dir: resolve3(home, ".ssh"), label: "SSH keys" },
35676
- { dir: resolve3(home, ".aws"), label: "AWS credentials" },
35677
- { dir: resolve3(home, ".gnupg"), label: "GnuPG keyring" },
35678
- { dir: resolve3(home, ".config", "gh"), label: "GitHub CLI auth" }
36514
+ { dir: resolve4(home, ".ssh"), label: "SSH keys" },
36515
+ { dir: resolve4(home, ".aws"), label: "AWS credentials" },
36516
+ { dir: resolve4(home, ".gnupg"), label: "GnuPG keyring" },
36517
+ { dir: resolve4(home, ".config", "gh"), label: "GitHub CLI auth" }
35679
36518
  ];
35680
36519
  for (const { dir, label } of sensitiveDirs) {
35681
36520
  if (resolvedPath === dir || resolvedPath.startsWith(`${dir}/`)) {
@@ -35733,9 +36572,9 @@ function substituteConfigVariables(input) {
35733
36572
  }
35734
36573
  let filePath = rawPath.trim();
35735
36574
  if (filePath.startsWith("~/")) {
35736
- filePath = resolve3(homedir5(), filePath.slice(2));
36575
+ filePath = resolve4(homedir5(), filePath.slice(2));
35737
36576
  } else if (!isAbsolute3(filePath)) {
35738
- filePath = resolve3(configDir, filePath);
36577
+ filePath = resolve4(configDir, filePath);
35739
36578
  }
35740
36579
  const sensitiveReason = sensitiveFilePathReason(filePath);
35741
36580
  if (sensitiveReason) {
@@ -35760,29 +36599,410 @@ function substituteConfigVariables(input) {
35760
36599
  }
35761
36600
 
35762
36601
  // ../plugin/src/shared/models-dev-cache.ts
35763
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync9, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
36602
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync10, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
36603
+ import { join as join7 } from "node:path";
36604
+
36605
+ // ../plugin/src/shared/window-geometry.ts
36606
+ import { readFileSync as readFileSync9 } from "node:fs";
35764
36607
  import { join as join6 } from "node:path";
36608
+ var WINDOW_OVERLAY_SCHEMA = "fusiform-window-overlay/v1";
36609
+ var PROMPT_WALL_MARGIN = 4096;
36610
+ var PI_OUTPUT_FLOOR = 4096;
36611
+ var OPENCODE_OUTPUT_CAP = 32000;
36612
+ var MIN_PLAUSIBLE_CONTEXT_LIMIT = 1024;
36613
+ var OUTPUT_RESERVE_CAP_RATIO = 0.25;
36614
+ var PROVIDER_GEOMETRY = {
36615
+ anthropic: "shared_truncating",
36616
+ xai: "shared_truncating",
36617
+ google: "separate",
36618
+ "google-antigravity": "separate"
36619
+ };
36620
+ var GRADES = new Set([
36621
+ "provider_asserted_runtime",
36622
+ "measured",
36623
+ "provider_asserted_doc",
36624
+ "catalog",
36625
+ "unknown"
36626
+ ]);
36627
+ var UNITS = new Set(["provider", "estimate"]);
36628
+ var BOUNDARIES = new Set(["Observed", "Asserted", "Corrected"]);
36629
+ var UNKNOWN_REASONS = new Set([
36630
+ "placeholder_output_equals_context",
36631
+ "placeholder_zero",
36632
+ "never_measured",
36633
+ "not_single_valued_at_key",
36634
+ "retracted"
36635
+ ]);
36636
+ var NUMERIC_FACT_KEYS = new Set([
36637
+ "window.advertised",
36638
+ "window.enforced",
36639
+ "output.advertised",
36640
+ "output.enforced",
36641
+ "output.default"
36642
+ ]);
36643
+ var configuredOverlayPath;
36644
+ var loadedOverlayPath;
36645
+ var loadedOverlay;
36646
+ var geometryClampLogSeen = new Set;
36647
+ function isRecord2(value) {
36648
+ return typeof value === "object" && value !== null && !Array.isArray(value);
36649
+ }
36650
+ function isFinitePositive(value) {
36651
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
36652
+ }
36653
+ function scalarizeFact(value) {
36654
+ if (value.kind === "stated")
36655
+ return isFinitePositive(value.value) ? value.value : undefined;
36656
+ if (value.kind === "bracket") {
36657
+ return isFinitePositive(value.at_least) ? value.at_least : undefined;
36658
+ }
36659
+ return;
36660
+ }
36661
+ function parseFactValue(value) {
36662
+ if (!isRecord2(value) || typeof value.kind !== "string")
36663
+ return;
36664
+ if (value.kind === "stated") {
36665
+ if ((typeof value.value !== "number" || !Number.isFinite(value.value)) && typeof value.value !== "string") {
36666
+ return;
36667
+ }
36668
+ return { kind: "stated", value: value.value };
36669
+ }
36670
+ if (value.kind === "bracket") {
36671
+ const atLeast = value.at_least;
36672
+ const below = value.below;
36673
+ if (atLeast === undefined && below === undefined)
36674
+ return { kind: "bracket" };
36675
+ if (atLeast !== undefined && !isFinitePositive(atLeast))
36676
+ return;
36677
+ if (below !== undefined && !isFinitePositive(below))
36678
+ return;
36679
+ if (isFinitePositive(atLeast) && isFinitePositive(below) && below <= atLeast) {
36680
+ return;
36681
+ }
36682
+ return {
36683
+ kind: "bracket",
36684
+ ...isFinitePositive(atLeast) ? { at_least: atLeast } : {},
36685
+ ...isFinitePositive(below) ? { below } : {}
36686
+ };
36687
+ }
36688
+ if (value.kind === "unknown" && UNKNOWN_REASONS.has(value.why)) {
36689
+ return { kind: "unknown", why: value.why };
36690
+ }
36691
+ return;
36692
+ }
36693
+ function parseFact(key, value) {
36694
+ if (!isRecord2(value))
36695
+ return;
36696
+ const parsedValue = parseFactValue(value.value);
36697
+ 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) {
36698
+ return;
36699
+ }
36700
+ if (NUMERIC_FACT_KEYS.has(key) && parsedValue.kind === "stated" && !isFinitePositive(parsedValue.value)) {
36701
+ return;
36702
+ }
36703
+ if (key === "geometry" && parsedValue.kind === "stated" && !["shared_upfront", "shared_truncating", "separate"].includes(String(parsedValue.value))) {
36704
+ return;
36705
+ }
36706
+ return {
36707
+ ...value,
36708
+ value: parsedValue,
36709
+ grade: value.grade,
36710
+ units: value.units,
36711
+ boundary: value.boundary,
36712
+ source_ref: value.source_ref,
36713
+ observed_at: value.observed_at
36714
+ };
36715
+ }
36716
+ function parseWindowOverlay(value) {
36717
+ if (!isRecord2(value)) {
36718
+ return { badCells: 0, refusal: "overlay root is not an object" };
36719
+ }
36720
+ if (value.schema !== WINDOW_OVERLAY_SCHEMA) {
36721
+ return {
36722
+ badCells: 0,
36723
+ refusal: `unrecognized schema ${JSON.stringify(value.schema)}`
36724
+ };
36725
+ }
36726
+ 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)) {
36727
+ return { badCells: 0, refusal: "invalid v1 envelope" };
36728
+ }
36729
+ const cells = [];
36730
+ let badCells = 0;
36731
+ for (const rawCell of value.cells) {
36732
+ 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)) {
36733
+ badCells++;
36734
+ continue;
36735
+ }
36736
+ const facts = {};
36737
+ let valid = true;
36738
+ for (const [key, rawFact] of Object.entries(rawCell.facts)) {
36739
+ const fact = parseFact(key, rawFact);
36740
+ if (!fact) {
36741
+ valid = false;
36742
+ break;
36743
+ }
36744
+ facts[key] = fact;
36745
+ }
36746
+ if (!valid) {
36747
+ badCells++;
36748
+ continue;
36749
+ }
36750
+ cells.push({
36751
+ provider_id: rawCell.provider_id,
36752
+ model_id: rawCell.model_id,
36753
+ facts
36754
+ });
36755
+ }
36756
+ return {
36757
+ overlay: {
36758
+ schema: WINDOW_OVERLAY_SCHEMA,
36759
+ generated_at: value.generated_at,
36760
+ minted_provider_ids: [...value.minted_provider_ids],
36761
+ cells
36762
+ },
36763
+ badCells
36764
+ };
36765
+ }
36766
+ function defaultWindowOverlayPath() {
36767
+ return join6(getDataDir(), "fusiform", "window-overlay.json");
36768
+ }
36769
+ function readWindowOverlayFile(path3, log2 = (message) => sessionLog("global", message)) {
36770
+ let raw;
36771
+ try {
36772
+ raw = readFileSync9(path3, "utf8");
36773
+ } catch (error51) {
36774
+ if (error51.code === "ENOENT")
36775
+ return;
36776
+ log2(`window-overlay: unable to read ${path3}; overlay ignored`);
36777
+ return;
36778
+ }
36779
+ let decoded;
36780
+ try {
36781
+ decoded = JSON.parse(raw);
36782
+ } catch {
36783
+ log2(`window-overlay: invalid JSON in ${path3}; overlay ignored`);
36784
+ return;
36785
+ }
36786
+ const parsed = parseWindowOverlay(decoded);
36787
+ if (parsed.refusal) {
36788
+ log2(`window-overlay: ${parsed.refusal} in ${path3}; entire overlay ignored`);
36789
+ return;
36790
+ }
36791
+ if (parsed.badCells > 0) {
36792
+ log2(`window-overlay: skipped ${parsed.badCells} invalid cell(s) from ${path3}`);
36793
+ }
36794
+ return parsed.overlay;
36795
+ }
36796
+ function setWindowOverlayPath(path3) {
36797
+ configuredOverlayPath = path3;
36798
+ loadedOverlayPath = undefined;
36799
+ loadedOverlay = undefined;
36800
+ }
36801
+ function getWindowOverlay() {
36802
+ const path3 = configuredOverlayPath ?? defaultWindowOverlayPath();
36803
+ if (loadedOverlayPath === path3 && loadedOverlay !== undefined) {
36804
+ return loadedOverlay ?? undefined;
36805
+ }
36806
+ loadedOverlayPath = path3;
36807
+ loadedOverlay = readWindowOverlayFile(path3) ?? null;
36808
+ return loadedOverlay ?? undefined;
36809
+ }
36810
+ function resolveWindowOverlayFacts(providerID, modelID, overlay = getWindowOverlay()) {
36811
+ if (!overlay)
36812
+ return;
36813
+ const modelRefs = modelRefLookupOrder(`${providerID}/${modelID}`);
36814
+ const providerCandidates = new Set(modelRefs.map((ref) => ref.slice(0, ref.indexOf("/"))));
36815
+ const modelCandidates = new Set([
36816
+ modelID,
36817
+ ...modelRefs.map((ref) => ref.slice(ref.indexOf("/") + 1))
36818
+ ]);
36819
+ const colon = modelID.lastIndexOf(":");
36820
+ if (colon > 0)
36821
+ modelCandidates.add(modelID.slice(0, colon));
36822
+ const wildcardFacts = {};
36823
+ const specificFacts = {};
36824
+ for (const cell of overlay.cells) {
36825
+ if (!providerCandidates.has(cell.provider_id))
36826
+ continue;
36827
+ if (cell.model_id === "*")
36828
+ Object.assign(wildcardFacts, cell.facts);
36829
+ else if (modelCandidates.has(cell.model_id))
36830
+ Object.assign(specificFacts, cell.facts);
36831
+ }
36832
+ const facts = { ...wildcardFacts, ...specificFacts };
36833
+ return Object.keys(facts).length > 0 ? { facts } : undefined;
36834
+ }
36835
+ function numericOverlayFact(overlay, key) {
36836
+ const fact = overlay?.facts[key];
36837
+ return fact ? scalarizeFact(fact.value) : undefined;
36838
+ }
36839
+ function overlayGeometry(overlay) {
36840
+ const fact = overlay?.facts.geometry;
36841
+ if (fact === undefined)
36842
+ return;
36843
+ if (fact.value.kind === "unknown")
36844
+ return { kind: "unknown" };
36845
+ if (fact.value.kind !== "stated")
36846
+ return;
36847
+ const value = fact.value.value;
36848
+ return value === "shared_upfront" || value === "shared_truncating" || value === "separate" ? { kind: "stated", value } : undefined;
36849
+ }
36850
+ function placeholderFilteredOutput(output, context) {
36851
+ if (!isFinitePositive(output))
36852
+ return;
36853
+ if (isFinitePositive(context) && output >= context)
36854
+ return;
36855
+ return output;
36856
+ }
36857
+ function mergePositive(overlayValue, providerValue) {
36858
+ return isFinitePositive(providerValue) ? providerValue : overlayValue;
36859
+ }
36860
+ function logGeometryClampOnce(key, message, log2) {
36861
+ if (geometryClampLogSeen.has(key))
36862
+ return;
36863
+ geometryClampLogSeen.add(key);
36864
+ (log2 ?? ((entry) => sessionLog("global", `window-geometry: ${entry}`)))(message);
36865
+ }
36866
+ function deriveWindowGeometry(providerID, modelID, catalogLimit, options = {}) {
36867
+ if (!catalogLimit && !options.providerLimit)
36868
+ return;
36869
+ const providerLimit = options.providerLimit;
36870
+ const catalogContext = isFinitePositive(catalogLimit?.context) ? catalogLimit.context : undefined;
36871
+ const advertised = numericOverlayFact(options.overlay, "window.advertised");
36872
+ const enforced = numericOverlayFact(options.overlay, "window.enforced");
36873
+ let softContext = mergePositive(enforced ?? advertised ?? catalogContext, providerLimit?.context);
36874
+ let hardContext = mergePositive(enforced ?? softContext, providerLimit?.context);
36875
+ if (isFinitePositive(options.contextCap)) {
36876
+ softContext = isFinitePositive(softContext) ? Math.min(softContext, options.contextCap) : options.contextCap;
36877
+ hardContext = isFinitePositive(hardContext) ? Math.min(hardContext, options.contextCap) : options.contextCap;
36878
+ }
36879
+ const input = mergePositive(isFinitePositive(catalogLimit?.input) ? catalogLimit.input : undefined, providerLimit?.input);
36880
+ if (!isFinitePositive(softContext) && !isFinitePositive(input))
36881
+ return;
36882
+ const catalogOutput = options.overlay === undefined && options.providerLimit === undefined ? isFinitePositive(catalogLimit?.output) ? catalogLimit.output : undefined : placeholderFilteredOutput(catalogLimit?.output, softContext);
36883
+ const overlayOutput = placeholderFilteredOutput(numericOverlayFact(options.overlay, "output.enforced") ?? numericOverlayFact(options.overlay, "output.default") ?? numericOverlayFact(options.overlay, "output.advertised"), softContext);
36884
+ const providerOutput = placeholderFilteredOutput(providerLimit?.output, softContext);
36885
+ const output = providerOutput ?? overlayOutput ?? catalogOutput;
36886
+ const geometryFact = overlayGeometry(options.overlay);
36887
+ const geometry = geometryFact?.kind === "stated" ? geometryFact.value : geometryFact?.kind === "unknown" ? "shared_upfront" : PROVIDER_GEOMETRY[providerID] ?? "shared_upfront";
36888
+ const geometryOverride = geometryFact?.kind === "stated" ? geometryFact.value : undefined;
36889
+ const preCarvedInput = isFinitePositive(input) && (!isFinitePositive(softContext) || input < softContext);
36890
+ const outputReserveOverride = typeof options.outputReserveOverride === "number" && Number.isFinite(options.outputReserveOverride) && options.outputReserveOverride >= 0 ? options.outputReserveOverride : undefined;
36891
+ let derivationWindow = softContext ?? input;
36892
+ let usableSoft;
36893
+ let softReserve = 0;
36894
+ let reserveSource = "none";
36895
+ if (outputReserveOverride !== undefined) {
36896
+ const reserveWindow = preCarvedInput ? input : softContext ?? input;
36897
+ if (!isFinitePositive(reserveWindow))
36898
+ return;
36899
+ derivationWindow = reserveWindow;
36900
+ softReserve = outputReserveOverride;
36901
+ reserveSource = "output_config";
36902
+ const floor = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, reserveWindow * 0.5);
36903
+ const flooredReserve = Math.min(softReserve, Math.max(0, reserveWindow - floor));
36904
+ if (flooredReserve < softReserve) {
36905
+ logGeometryClampOnce(`soft-floor|${providerID}/${modelID}|${softReserve}|${flooredReserve}`, `output reserve clamped by the half-window floor for ${providerID}/${modelID}: reserve ${softReserve} → ${flooredReserve}`, options.log);
36906
+ }
36907
+ softReserve = flooredReserve;
36908
+ usableSoft = Math.floor(reserveWindow - softReserve);
36909
+ } else if (preCarvedInput) {
36910
+ usableSoft = input;
36911
+ if (isFinitePositive(softContext)) {
36912
+ softReserve = Math.max(0, softContext - input);
36913
+ reserveSource = "output_catalog";
36914
+ }
36915
+ } else if (isFinitePositive(softContext)) {
36916
+ if (geometry === "separate" && (options.overlay === undefined || options.harness === "pi" || geometryOverride !== undefined)) {
36917
+ softReserve = 0;
36918
+ reserveSource = "none";
36919
+ } else {
36920
+ softReserve = output ?? 0;
36921
+ reserveSource = output === undefined ? "none" : "output_catalog";
36922
+ const cap = softContext * OUTPUT_RESERVE_CAP_RATIO;
36923
+ softReserve = Math.min(softReserve, options.harness === "pi" || options.overlay === undefined ? cap : Math.min(cap, OPENCODE_OUTPUT_CAP));
36924
+ }
36925
+ const floor = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, softContext * 0.5);
36926
+ const flooredReserve = Math.min(softReserve, Math.max(0, softContext - floor));
36927
+ if (flooredReserve < softReserve) {
36928
+ 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);
36929
+ }
36930
+ softReserve = flooredReserve;
36931
+ usableSoft = Math.floor(softContext - softReserve);
36932
+ } else {
36933
+ usableSoft = input;
36934
+ }
36935
+ const hardWindow = hardContext ?? softContext ?? input;
36936
+ if (!isFinitePositive(hardWindow))
36937
+ return;
36938
+ let usableHard;
36939
+ if (geometry === "separate") {
36940
+ usableHard = hardWindow;
36941
+ } else if (geometry === "shared_truncating") {
36942
+ usableHard = hardWindow - PROMPT_WALL_MARGIN;
36943
+ } else if (options.harness === "pi" && providerID !== "openai-codex") {
36944
+ usableHard = hardWindow - PI_OUTPUT_FLOOR;
36945
+ } else if (options.harness === "pi") {
36946
+ usableHard = hardWindow - (output ?? OPENCODE_OUTPUT_CAP);
36947
+ } else {
36948
+ const requestedOutput = Math.min(output ?? OPENCODE_OUTPUT_CAP, OPENCODE_OUTPUT_CAP);
36949
+ usableHard = hardWindow - requestedOutput;
36950
+ }
36951
+ usableHard = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, Math.floor(usableHard));
36952
+ if (usableHard < usableSoft) {
36953
+ logGeometryClampOnce(`${providerID}/${modelID}|${usableSoft}|${usableHard}`, `usable hard limit clamped for ${providerID}/${modelID}: ${usableHard} → ${usableSoft} (overlay/provider inversion)`, options.log);
36954
+ usableHard = usableSoft;
36955
+ }
36956
+ const resolvedWindow = derivationWindow ?? usableSoft;
36957
+ return {
36958
+ usableSoft,
36959
+ usableHard,
36960
+ geometry,
36961
+ derivation: {
36962
+ window: Math.floor(resolvedWindow),
36963
+ reserve: Math.floor(Math.max(0, resolvedWindow - usableSoft)),
36964
+ reserveSource,
36965
+ geometry
36966
+ }
36967
+ };
36968
+ }
36969
+ function formatWindowDerivationLine(inputTokens, result) {
36970
+ const percentage = result.usableSoft > 0 ? inputTokens / result.usableSoft * 100 : 0;
36971
+ const reserveLabel = result.derivation.reserveSource === "wall_margin" ? "wall margin" : result.derivation.reserveSource === "none" ? "reserve" : "output reserve";
36972
+ return `Context: ${formatCompactTokens(inputTokens)} / ${formatCompactTokens(result.usableSoft)} usable (${percentage.toFixed(1)}%) — window ${formatCompactTokens(result.derivation.window)} − ${formatCompactTokens(result.derivation.reserve)} ${reserveLabel} [${result.geometry}]`;
36973
+ }
36974
+ function formatCompactTokens(value) {
36975
+ if (Math.abs(value) >= 1e6) {
36976
+ return `${(value / 1e6).toFixed(1).replace(/\.0$/, "")}m`;
36977
+ }
36978
+ if (Math.abs(value) >= 1000) {
36979
+ return `${(value / 1000).toFixed(1).replace(/\.0$/, "")}k`;
36980
+ }
36981
+ return Math.round(value).toLocaleString();
36982
+ }
36983
+
36984
+ // ../plugin/src/shared/models-dev-cache.ts
35765
36985
  var MIN_SANE_LIMIT = 20000;
35766
36986
  var MAX_SANE_LIMIT = 3000000;
35767
36987
  function isSaneLimit(limit) {
35768
36988
  return typeof limit === "number" && limit >= MIN_SANE_LIMIT && limit <= MAX_SANE_LIMIT;
35769
36989
  }
35770
36990
  var SEPARATE_OUTPUT_QUOTA_PROVIDERS = new Set(["google", "google-antigravity"]);
35771
- var MIN_PLAUSIBLE_CONTEXT_LIMIT = 1024;
35772
- var OUTPUT_RESERVE_CAP_RATIO = 0.25;
36991
+ var MIN_PLAUSIBLE_CONTEXT_LIMIT2 = 1024;
36992
+ var OUTPUT_RESERVE_CAP_RATIO2 = 0.25;
35773
36993
  var outputReserveConfig;
35774
36994
  var reserveClampLogSeen = new Set;
35775
36995
  var apiCache = null;
35776
36996
  var persistSeedLoaded = false;
35777
36997
  function persistFilePath() {
35778
- return join6(getMagicContextStorageDir(), `model-context-limits-${getHarness()}.json`);
36998
+ return join7(getMagicContextStorageDir(), `model-context-limits-${getHarness()}.json`);
35779
36999
  }
35780
37000
  function loadPersistedApiCacheOnce() {
35781
37001
  if (persistSeedLoaded || apiCache !== null)
35782
37002
  return;
35783
37003
  persistSeedLoaded = true;
35784
37004
  try {
35785
- const raw = readFileSync9(persistFilePath(), "utf-8");
37005
+ const raw = readFileSync10(persistFilePath(), "utf-8");
35786
37006
  const obj = JSON.parse(raw);
35787
37007
  const map2 = new Map;
35788
37008
  for (const [key, persisted] of Object.entries(obj)) {
@@ -35796,7 +37016,7 @@ function loadPersistedApiCacheOnce() {
35796
37016
  limit: isSaneLimit(limit) ? limit : undefined,
35797
37017
  contextLimit: isSaneLimit(contextLimit) ? contextLimit : undefined,
35798
37018
  inputLimit: isSaneLimit(inputLimit) ? inputLimit : undefined,
35799
- outputLimit: isFinitePositive(outputLimit) ? outputLimit : undefined,
37019
+ outputLimit: isFinitePositive2(outputLimit) ? outputLimit : undefined,
35800
37020
  vision
35801
37021
  });
35802
37022
  }
@@ -35807,22 +37027,19 @@ function loadPersistedApiCacheOnce() {
35807
37027
  }
35808
37028
  } catch {}
35809
37029
  }
35810
- function isFinitePositive(value) {
37030
+ function isFinitePositive2(value) {
35811
37031
  return typeof value === "number" && Number.isFinite(value) && value > 0;
35812
37032
  }
35813
37033
  function modelKeyLookupOrder2(providerID, modelID) {
35814
- const full = `${providerID}/${modelID}`;
35815
- const canonicalFull = piModelRefToCanonical(full);
35816
- const candidates = [full, canonicalFull, modelID];
37034
+ const candidates = [...modelRefLookupOrder(`${providerID}/${modelID}`), modelID];
35817
37035
  const colon = modelID.lastIndexOf(":");
35818
37036
  if (colon > 0) {
35819
37037
  const bareModel = modelID.slice(0, colon);
35820
- const providerBare = `${providerID}/${bareModel}`;
35821
- candidates.push(providerBare, piModelRefToCanonical(providerBare), bareModel);
37038
+ candidates.push(...modelRefLookupOrder(`${providerID}/${bareModel}`), bareModel);
35822
37039
  }
35823
37040
  return [...new Set(candidates)];
35824
37041
  }
35825
- function configuredOutputReserve(config2, providerID, modelID) {
37042
+ function resolveOutputReserve(providerID, modelID, config2 = outputReserveConfig) {
35826
37043
  if (typeof config2 === "number")
35827
37044
  return Number.isFinite(config2) && config2 >= 0 ? config2 : undefined;
35828
37045
  if (!config2)
@@ -35846,27 +37063,27 @@ function setOutputReserveConfig(config2) {
35846
37063
  function resolveLimit(limit, providerID, modelID, reserveConfig = outputReserveConfig) {
35847
37064
  if (!limit)
35848
37065
  return;
35849
- const context = isFinitePositive(limit.context) ? limit.context : undefined;
35850
- const input = isFinitePositive(limit.input) ? limit.input : undefined;
37066
+ const context = isFinitePositive2(limit.context) ? limit.context : undefined;
37067
+ const input = isFinitePositive2(limit.input) ? limit.input : undefined;
35851
37068
  if (input !== undefined && (context === undefined || input < context))
35852
37069
  return input;
35853
37070
  if (context === undefined)
35854
37071
  return;
35855
- const configuredReserve = configuredOutputReserve(reserveConfig, providerID, modelID);
37072
+ const configuredReserve = resolveOutputReserve(providerID, modelID, reserveConfig);
35856
37073
  let reserve;
35857
37074
  if (configuredReserve !== undefined) {
35858
37075
  reserve = configuredReserve;
35859
37076
  } else if (SEPARATE_OUTPUT_QUOTA_PROVIDERS.has(providerID)) {
35860
37077
  reserve = 0;
35861
37078
  } else {
35862
- const output = isFinitePositive(limit.output) ? limit.output : 0;
35863
- const cap = context * OUTPUT_RESERVE_CAP_RATIO;
37079
+ const output = isFinitePositive2(limit.output) ? limit.output : 0;
37080
+ const cap = context * OUTPUT_RESERVE_CAP_RATIO2;
35864
37081
  reserve = Math.min(output, cap);
35865
37082
  if (output > cap) {
35866
37083
  logReserveClampOnce(`cap|${providerID}/${modelID}|${context}|${output}`, `output reserve capped at 25% for ${providerID}/${modelID}: ${output} → ${cap}`);
35867
37084
  }
35868
37085
  }
35869
- const floor = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, context * 0.5);
37086
+ const floor = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT2, context * 0.5);
35870
37087
  const maxReserve = Math.max(0, context - floor);
35871
37088
  if (reserve > maxReserve) {
35872
37089
  logReserveClampOnce(`floor|${providerID}/${modelID}|${context}|${reserve}`, `output reserve clamped for ${providerID}/${modelID}: ${reserve} → ${maxReserve} (usable floor ${floor})`);
@@ -35874,15 +37091,46 @@ function resolveLimit(limit, providerID, modelID, reserveConfig = outputReserveC
35874
37091
  }
35875
37092
  return Math.floor(context - reserve);
35876
37093
  }
37094
+ function getSdkWindowGeometry(providerID, modelID, detectedContextLimit, options) {
37095
+ loadPersistedApiCacheOnce();
37096
+ const metadata = lookupMetadataWithTagFallback(apiCache, providerID, modelID);
37097
+ if (!metadata)
37098
+ return;
37099
+ const rawContext = metadata.contextLimit ?? metadata.limit;
37100
+ const promptOnlyDetected = options?.detectedLimitProvenance === "prompt_only" && isFinitePositive2(detectedContextLimit) ? detectedContextLimit : undefined;
37101
+ const result = deriveWindowGeometry(providerID, modelID, {
37102
+ context: rawContext,
37103
+ input: metadata.inputLimit,
37104
+ output: metadata.outputLimit
37105
+ }, {
37106
+ overlay: resolveWindowOverlayFacts(providerID, modelID, getWindowOverlay()),
37107
+ outputReserveOverride: resolveOutputReserve(providerID, modelID),
37108
+ harness: options?.harness ?? "opencode",
37109
+ contextCap: promptOnlyDetected === undefined && isFinitePositive2(detectedContextLimit) ? detectedContextLimit : undefined
37110
+ });
37111
+ if (!result || promptOnlyDetected === undefined)
37112
+ return result;
37113
+ const usableSoft = promptOnlyDetected;
37114
+ return {
37115
+ ...result,
37116
+ usableSoft,
37117
+ usableHard: Math.max(usableSoft, Math.min(result.usableHard, promptOnlyDetected))
37118
+ };
37119
+ }
35877
37120
  function getSdkContextLimit(providerID, modelID, detectedContextLimit, options) {
37121
+ if (options?.reservation !== "none") {
37122
+ return getSdkWindowGeometry(providerID, modelID, detectedContextLimit, {
37123
+ detectedLimitProvenance: options?.detectedLimitProvenance
37124
+ })?.usableSoft;
37125
+ }
35878
37126
  loadPersistedApiCacheOnce();
35879
37127
  const metadata = lookupMetadataWithTagFallback(apiCache, providerID, modelID);
35880
37128
  if (!metadata)
35881
37129
  return;
35882
37130
  const rawContext = metadata.contextLimit ?? metadata.limit;
35883
- const promptOnlyDetected = options?.detectedLimitProvenance === "prompt_only" && isFinitePositive(detectedContextLimit) ? detectedContextLimit : undefined;
35884
- const context = promptOnlyDetected === undefined && isFinitePositive(detectedContextLimit) && isFinitePositive(rawContext) ? Math.min(rawContext, detectedContextLimit) : promptOnlyDetected === undefined && isFinitePositive(detectedContextLimit) ? detectedContextLimit : rawContext;
35885
- const inputCandidates = [metadata.inputLimit, promptOnlyDetected].filter(isFinitePositive);
37131
+ const promptOnlyDetected = options?.detectedLimitProvenance === "prompt_only" && isFinitePositive2(detectedContextLimit) ? detectedContextLimit : undefined;
37132
+ const context = promptOnlyDetected === undefined && isFinitePositive2(detectedContextLimit) && isFinitePositive2(rawContext) ? Math.min(rawContext, detectedContextLimit) : promptOnlyDetected === undefined && isFinitePositive2(detectedContextLimit) ? detectedContextLimit : rawContext;
37133
+ const inputCandidates = [metadata.inputLimit, promptOnlyDetected].filter(isFinitePositive2);
35886
37134
  const input = inputCandidates.length > 0 ? Math.min(...inputCandidates) : undefined;
35887
37135
  return resolveLimit({
35888
37136
  context,
@@ -35931,7 +37179,7 @@ function resolvePiLegacyFallback(sources) {
35931
37179
  }
35932
37180
  function loadConfigFile(path3, scope) {
35933
37181
  try {
35934
- const rawText = readFileSync10(path3, "utf-8");
37182
+ const rawText = readFileSync11(path3, "utf-8");
35935
37183
  const substituted = substituteConfigVariables({
35936
37184
  text: rawText,
35937
37185
  configPath: path3,
@@ -36137,6 +37385,7 @@ function loadPiConfig(opts = {}) {
36137
37385
  }
36138
37386
  const parsed = parsePiConfig(rawConfig);
36139
37387
  setOutputReserveConfig(parsed.config.output_reserve);
37388
+ setWindowOverlayPath(parsed.config.models?.window_overlay_path);
36140
37389
  warnings.push(...parsed.warnings.map((warning) => `[merged config] ${warning}`));
36141
37390
  return {
36142
37391
  config: parsed.config,
@@ -36258,6 +37507,7 @@ function loadPiConfigDetailed(opts = {}) {
36258
37507
  const recoveredTopLevelKeys = [];
36259
37508
  const parsed = parsePiConfig(rawConfig, recoveredTopLevelKeys);
36260
37509
  setOutputReserveConfig(parsed.config.output_reserve);
37510
+ setWindowOverlayPath(parsed.config.models?.window_overlay_path);
36261
37511
  warnings.push(...parsed.warnings.map((warning) => `[merged config] ${warning}`));
36262
37512
  const substitutionFailures = loadedFiles.flatMap(bindSubstitutionFailures);
36263
37513
  const userLoaded = loadedFiles.find((loaded) => loaded.scope === "user");
@@ -37353,7 +38603,7 @@ class SubcSocket {
37353
38603
  return this.sock.localPort ?? null;
37354
38604
  }
37355
38605
  static connect(host, port, deadlineMs) {
37356
- return new Promise((resolve4, reject) => {
38606
+ return new Promise((resolve5, reject) => {
37357
38607
  const sock = net.connect({ host, port });
37358
38608
  sock.setNoDelay(true);
37359
38609
  const timer = setTimeout(() => {
@@ -37362,7 +38612,7 @@ class SubcSocket {
37362
38612
  }, Math.max(0, deadlineMs - Date.now()));
37363
38613
  sock.once("connect", () => {
37364
38614
  clearTimeout(timer);
37365
- resolve4(new SubcSocket(sock));
38615
+ resolve5(new SubcSocket(sock));
37366
38616
  });
37367
38617
  sock.once("error", (err) => {
37368
38618
  clearTimeout(timer);
@@ -37394,7 +38644,7 @@ class SubcSocket {
37394
38644
  }
37395
38645
  if (n === 0)
37396
38646
  return Promise.resolve(new Uint8Array(0));
37397
- return new Promise((resolve4, reject) => {
38647
+ return new Promise((resolve5, reject) => {
37398
38648
  let timer = null;
37399
38649
  if (Number.isFinite(deadlineMs)) {
37400
38650
  const remaining = deadlineMs - Date.now();
@@ -37407,7 +38657,7 @@ class SubcSocket {
37407
38657
  reject(new SocketTimeoutError(`timed out waiting for ${n} bytes`));
37408
38658
  }, remaining);
37409
38659
  }
37410
- this.waiter = { need: n, resolve: resolve4, reject, timer };
38660
+ this.waiter = { need: n, resolve: resolve5, reject, timer };
37411
38661
  this.tryServe();
37412
38662
  });
37413
38663
  }
@@ -37431,7 +38681,7 @@ class SubcSocket {
37431
38681
  let queued = false;
37432
38682
  let settled = false;
37433
38683
  let timer = null;
37434
- const completed = new Promise((resolve4, reject) => {
38684
+ const completed = new Promise((resolve5, reject) => {
37435
38685
  const settle = (run) => {
37436
38686
  if (settled)
37437
38687
  return;
@@ -37455,7 +38705,7 @@ class SubcSocket {
37455
38705
  if (err) {
37456
38706
  reject(new SocketWriteQueuedError("subc socket reported a write error after bytes were handed to the socket", err instanceof Error ? err : new Error(String(err))));
37457
38707
  } else {
37458
- resolve4();
38708
+ resolve5();
37459
38709
  }
37460
38710
  });
37461
38711
  });
@@ -37671,14 +38921,14 @@ class SubcClient {
37671
38921
  const admission = opts.admissionClass ?? AdmissionClass.Normal;
37672
38922
  const corr = this.allocateCorr();
37673
38923
  const key = pendingKey(handle, corr);
37674
- const closed = new Promise((resolve4, reject) => {
38924
+ const closed = new Promise((resolve5, reject) => {
37675
38925
  if (this.closedErr) {
37676
38926
  reject(this.closedErr);
37677
38927
  return;
37678
38928
  }
37679
38929
  this.pending.set(key, {
37680
38930
  handle,
37681
- resolve: () => resolve4(),
38931
+ resolve: () => resolve5(),
37682
38932
  reject,
37683
38933
  onProgress: onEvent,
37684
38934
  timer: null,
@@ -37763,11 +39013,11 @@ class SubcClient {
37763
39013
  const waiters = [];
37764
39014
  for (const pending of this.pending.values()) {
37765
39015
  if (pending.handle === handle && !pending.subscription) {
37766
- waiters.push(new Promise((resolve4) => {
39016
+ waiters.push(new Promise((resolve5) => {
37767
39017
  const previous = pending.onSettle;
37768
39018
  pending.onSettle = () => {
37769
39019
  previous?.();
37770
- resolve4();
39020
+ resolve5();
37771
39021
  };
37772
39022
  }));
37773
39023
  }
@@ -37823,11 +39073,11 @@ class SubcClient {
37823
39073
  const channel = handle?.channel ?? 0;
37824
39074
  const epoch = handle?.epoch ?? 0;
37825
39075
  const frame = buildFrame(FrameType.Request, buildFlags(false, priority, false, admission), channel, epoch, corr, body);
37826
- return new Promise((resolve4, reject) => {
39076
+ return new Promise((resolve5, reject) => {
37827
39077
  const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
37828
39078
  const pending = {
37829
39079
  handle,
37830
- resolve: resolve4,
39080
+ resolve: resolve5,
37831
39081
  reject,
37832
39082
  onProgress,
37833
39083
  timer: null,
@@ -37901,11 +39151,11 @@ class SubcClient {
37901
39151
  }
37902
39152
  return this.outcomeUnknownCallError("connection dropped before the managed call returned a response", error51);
37903
39153
  };
37904
- return new Promise((resolve4, reject) => {
39154
+ return new Promise((resolve5, reject) => {
37905
39155
  const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
37906
39156
  const pending = {
37907
39157
  handle,
37908
- resolve: resolve4,
39158
+ resolve: resolve5,
37909
39159
  reject,
37910
39160
  onProgress,
37911
39161
  timer: null,
@@ -38293,7 +39543,7 @@ function normalizeConnectOptions(opts) {
38293
39543
  identity: opts.identity,
38294
39544
  targetKind: opts.targetKind ?? DEFAULT_MANAGED_TARGET_KIND,
38295
39545
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
38296
- sleep: opts.sleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms))),
39546
+ sleep: opts.sleep ?? ((ms) => new Promise((resolve5) => setTimeout(resolve5, ms))),
38297
39547
  timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS
38298
39548
  };
38299
39549
  }
@@ -38350,8 +39600,8 @@ class AsyncPermitPool {
38350
39600
  this.available -= 1;
38351
39601
  return this.releaseOnce();
38352
39602
  }
38353
- await new Promise((resolve4) => {
38354
- this.waiters.push(resolve4);
39603
+ await new Promise((resolve5) => {
39604
+ this.waiters.push(resolve5);
38355
39605
  });
38356
39606
  return this.releaseOnce();
38357
39607
  }
@@ -38407,8 +39657,8 @@ class SubcProvider {
38407
39657
  this.currentConn = currentConn;
38408
39658
  this.opts = opts;
38409
39659
  this.storage = storage;
38410
- this.closed = new Promise((resolve4) => {
38411
- this.resolveClosed = resolve4;
39660
+ this.closed = new Promise((resolve5) => {
39661
+ this.resolveClosed = resolve5;
38412
39662
  });
38413
39663
  this.readLoop(sock, this.generation);
38414
39664
  this.enqueueConnectionState({ state: "connected", epoch: this.connectionEpoch });
@@ -38428,13 +39678,13 @@ class SubcProvider {
38428
39678
  const key = routeKey(handle, corr);
38429
39679
  const timeoutMs = opts.timeoutMs ?? WRITE_TIMEOUT_MS;
38430
39680
  const frame = buildFrame(FrameType.Request, buildFlags(false, opts.priority ?? Priority.Interactive, false, opts.admissionClass ?? AdmissionClass.Normal), handle.channel, handle.epoch, corr, body);
38431
- return await new Promise((resolve4, reject) => {
39681
+ return await new Promise((resolve5, reject) => {
38432
39682
  const timer = setTimeout(() => {
38433
39683
  if (this.pending.delete(key))
38434
39684
  reject(new SubcProviderError("reverse request timed out", "request_timeout"));
38435
39685
  }, timeoutMs);
38436
39686
  this.pending.set(key, {
38437
- resolve: (response) => resolve4(response.body),
39687
+ resolve: (response) => resolve5(response.body),
38438
39688
  reject,
38439
39689
  timer
38440
39690
  });
@@ -38906,7 +40156,7 @@ function normalizeProviderConnectOptions(opts) {
38906
40156
  onBound: opts.onBound,
38907
40157
  onRouteGone: opts.onRouteGone,
38908
40158
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
38909
- sleep: opts.sleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms))),
40159
+ sleep: opts.sleep ?? ((ms) => new Promise((resolve5) => setTimeout(resolve5, ms))),
38910
40160
  restoredDebounceMs: opts.restoredDebounceMs ?? DEFAULT_RESTORED_DEBOUNCE_MS,
38911
40161
  onConnectionState: opts.onConnectionState,
38912
40162
  launchNonce: opts.launchNonce
@@ -38951,7 +40201,7 @@ function errorCode2(err) {
38951
40201
  return;
38952
40202
  }
38953
40203
  async function pauseBeforeStateRetry() {
38954
- await new Promise((resolve4) => setTimeout(resolve4, 0));
40204
+ await new Promise((resolve5) => setTimeout(resolve5, 0));
38955
40205
  }
38956
40206
  function controlFlags() {
38957
40207
  return buildFlags(false, Priority.Passive, false);
@@ -39189,7 +40439,7 @@ function classifyError(value) {
39189
40439
  });
39190
40440
  }
39191
40441
  function wait(ms) {
39192
- return new Promise((resolve4) => setTimeout(resolve4, ms));
40442
+ return new Promise((resolve5) => setTimeout(resolve5, ms));
39193
40443
  }
39194
40444
  function sha256(value) {
39195
40445
  return createHash9("sha256").update(value).digest("hex");
@@ -39668,7 +40918,7 @@ function getEmbeddingProviderIdentity(config2) {
39668
40918
  // ../plugin/src/features/magic-context/memory/embedding-local.ts
39669
40919
  import { chmodSync as chmodSync2, mkdirSync as mkdirSync4 } from "node:fs";
39670
40920
  import { open, stat, unlink, writeFile } from "node:fs/promises";
39671
- import { dirname as dirname6, join as join7 } from "node:path";
40921
+ import { dirname as dirname6, join as join8 } from "node:path";
39672
40922
  import { pathToFileURL as pathToFileURL2 } from "node:url";
39673
40923
  var LOCK_POLL_MS = 150;
39674
40924
  var STALE_LOCK_MS = 3 * 60000;
@@ -39708,7 +40958,7 @@ async function acquireModelLoadLock(lockPath) {
39708
40958
  if (Date.now() - waitStart > MAX_LOCK_WAIT_MS) {
39709
40959
  throw new Error(`[magic-context] embedding-load lock wait exceeded ${MAX_LOCK_WAIT_MS}ms; another process is still loading the model. Skipping this init attempt to avoid an unsynchronized native load.`);
39710
40960
  }
39711
- await new Promise((resolve4) => setTimeout(resolve4, LOCK_POLL_MS));
40961
+ await new Promise((resolve5) => setTimeout(resolve5, LOCK_POLL_MS));
39712
40962
  }
39713
40963
  }
39714
40964
  }
@@ -39869,7 +41119,7 @@ class LocalEmbeddingProvider {
39869
41119
  if (LogLevel && "ERROR" in LogLevel) {
39870
41120
  env.logLevel = LogLevel.ERROR;
39871
41121
  }
39872
- const modelCacheDir = join7(getMagicContextStorageDir(), "models");
41122
+ const modelCacheDir = join8(getMagicContextStorageDir(), "models");
39873
41123
  try {
39874
41124
  if (shouldEnforcePrivateStoragePermissions()) {
39875
41125
  mkdirSync4(modelCacheDir, { recursive: true, mode: 448 });
@@ -39886,7 +41136,7 @@ class LocalEmbeddingProvider {
39886
41136
  log("[magic-context] could not create model cache dir, using library default");
39887
41137
  }
39888
41138
  const createPipeline = transformersModule.pipeline;
39889
- const lockPath = join7(modelCacheDir, ".load.lock");
41139
+ const lockPath = join8(modelCacheDir, ".load.lock");
39890
41140
  const releaseLock = await acquireModelLoadLock(lockPath);
39891
41141
  const stopHeartbeat = startLockHeartbeat(lockPath);
39892
41142
  try {
@@ -39913,7 +41163,7 @@ class LocalEmbeddingProvider {
39913
41163
  }
39914
41164
  const delayMs = 300 * attempt + Math.floor(Math.random() * 200);
39915
41165
  log(`[magic-context] embedding model load attempt ${attempt}/${MAX_ATTEMPTS} failed transiently, retrying in ${delayMs}ms`);
39916
- await new Promise((resolve4) => setTimeout(resolve4, delayMs));
41166
+ await new Promise((resolve5) => setTimeout(resolve5, delayMs));
39917
41167
  }
39918
41168
  }
39919
41169
  if (this.pipeline) {
@@ -39946,8 +41196,8 @@ class LocalEmbeddingProvider {
39946
41196
  if (this.inFlight === 0) {
39947
41197
  return Promise.resolve();
39948
41198
  }
39949
- return new Promise((resolve4) => {
39950
- this.inFlightWaiters.push(resolve4);
41199
+ return new Promise((resolve5) => {
41200
+ this.inFlightWaiters.push(resolve5);
39951
41201
  });
39952
41202
  }
39953
41203
  finishInFlight() {
@@ -40102,9 +41352,14 @@ function blockedEmbeddingEndpointReason(endpoint) {
40102
41352
  function normalizeEndpoint3(endpoint) {
40103
41353
  return endpoint?.trim().replace(/\/+$/, "") ?? "";
40104
41354
  }
40105
- function embeddingModelsMatch(served, requested) {
40106
- const a = served.trim().toLowerCase();
40107
- const b = requested.trim().toLowerCase();
41355
+ function parseEmbeddingModel(model) {
41356
+ const lastColon = model.lastIndexOf(":");
41357
+ if (lastColon > model.lastIndexOf("/")) {
41358
+ return { base: model.slice(0, lastColon), tag: model.slice(lastColon + 1) };
41359
+ }
41360
+ return { base: model };
41361
+ }
41362
+ function matchNormalizedEmbeddingModels(a, b) {
40108
41363
  if (a.length === 0 || b.length === 0)
40109
41364
  return true;
40110
41365
  if (a === b)
@@ -40118,6 +41373,16 @@ function embeddingModelsMatch(served, requested) {
40118
41373
  return true;
40119
41374
  return false;
40120
41375
  }
41376
+ function embeddingModelsMatch(served, requested) {
41377
+ const a = served.trim().toLowerCase();
41378
+ const b = requested.trim().toLowerCase();
41379
+ const servedModel = parseEmbeddingModel(a);
41380
+ const requestedModel = parseEmbeddingModel(b);
41381
+ if (servedModel.tag !== undefined && requestedModel.tag !== undefined && servedModel.tag !== requestedModel.tag) {
41382
+ return false;
41383
+ }
41384
+ return matchNormalizedEmbeddingModels(servedModel.base, requestedModel.base);
41385
+ }
40121
41386
  var FAILURE_THRESHOLD = 3;
40122
41387
  var FAILURE_WINDOW_MS = 60000;
40123
41388
  var OPEN_DURATION_MS = 5 * 60000;
@@ -40248,7 +41513,7 @@ class OpenAICompatibleEmbeddingProvider {
40248
41513
  const servedModel = typeof body.model === "string" ? body.model : "";
40249
41514
  if (this.model && servedModel && !embeddingModelsMatch(servedModel, this.model)) {
40250
41515
  if (!this.modelMismatchLogged) {
40251
- log(`[magic-context] embedding endpoint served a DIFFERENT model than requested — refusing the substituted vectors (they have the wrong dimensions/space). requested="${this.model}" served="${servedModel}". The endpoint likely substituted a loaded model; load/select "${this.model}" on the endpoint, or set embedding.model to the served model.`);
41516
+ log(`[magic-context] embedding endpoint served a DIFFERENT model than requested — refusing the substituted vectors (they have the wrong dimensions/space). requested="${this.model}" served="${servedModel}". Check that the endpoint serves the requested model; variant suffixes and vendor prefixes are matched automatically.`);
40252
41517
  this.modelMismatchLogged = true;
40253
41518
  }
40254
41519
  this.recordFailure(isProbe);
@@ -41645,7 +42910,7 @@ async function runShadowWorker() {
41645
42910
  }
41646
42911
  processed += item.ids.length;
41647
42912
  processedBytes += itemBytes;
41648
- await new Promise((resolve4) => setTimeout(resolve4, 0));
42913
+ await new Promise((resolve5) => setTimeout(resolve5, 0));
41649
42914
  }
41650
42915
  }
41651
42916
  function registerProjectInObservationMode(db, projectIdentity, sourceDirectory, failedConfig, failureSummary) {
@@ -42006,7 +43271,7 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
42006
43271
  if (Date.now() - attemptStart >= EMBED_SLOW_FAILURE_NO_RETRY_MS)
42007
43272
  break;
42008
43273
  if (attempt < EMBED_SLICE_RETRY_ATTEMPTS - 1) {
42009
- await new Promise((resolve4) => setTimeout(resolve4, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
43274
+ await new Promise((resolve5) => setTimeout(resolve5, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
42010
43275
  }
42011
43276
  }
42012
43277
  embedded += persistedIds.size;
@@ -42091,7 +43356,7 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
42091
43356
  }
42092
43357
  embedded += n;
42093
43358
  options?.onProgress?.({ embedded: Math.min(embedded, total), total });
42094
- await new Promise((resolve4) => setTimeout(resolve4, 0));
43359
+ await new Promise((resolve5) => setTimeout(resolve5, 0));
42095
43360
  }
42096
43361
  } finally {
42097
43362
  clearInterval(renewal);
@@ -42833,7 +44098,7 @@ Two recovery modes for finer detail:
42833
44098
  var CTX_EXPAND_TOKEN_BUDGET = 15000;
42834
44099
 
42835
44100
  // ../plugin/src/tools/ctx-expand/render.ts
42836
- function isRecord2(value) {
44101
+ function isRecord3(value) {
42837
44102
  return value !== null && typeof value === "object" && !Array.isArray(value);
42838
44103
  }
42839
44104
  function roleLabel(role) {
@@ -42862,15 +44127,15 @@ function keyArg(input) {
42862
44127
  function asToolPart(part) {
42863
44128
  const type = typeof part.type === "string" ? part.type : "";
42864
44129
  if (type === "tool") {
42865
- const state = isRecord2(part.state) ? part.state : null;
44130
+ const state = isRecord3(part.state) ? part.state : null;
42866
44131
  const output = state && typeof state.output === "string" ? state.output : state && state.output != null ? JSON.stringify(state.output) : null;
42867
- const metadata = state && isRecord2(state.metadata) ? state.metadata : null;
44132
+ const metadata = state && isRecord3(state.metadata) ? state.metadata : null;
42868
44133
  const title = state && typeof state.title === "string" && state.title || metadata && typeof metadata.title === "string" && metadata.title || null;
42869
44134
  return {
42870
44135
  name: typeof part.tool === "string" ? part.tool : "tool",
42871
44136
  callId: typeof part.callID === "string" ? part.callID : "",
42872
44137
  title,
42873
- input: state && isRecord2(state.input) ? state.input : null,
44138
+ input: state && isRecord3(state.input) ? state.input : null,
42874
44139
  output
42875
44140
  };
42876
44141
  }
@@ -42879,7 +44144,7 @@ function asToolPart(part) {
42879
44144
  name: typeof part.name === "string" ? part.name : "tool",
42880
44145
  callId: typeof part.id === "string" ? part.id : "",
42881
44146
  title: null,
42882
- input: isRecord2(part.input) ? part.input : null,
44147
+ input: isRecord3(part.input) ? part.input : null,
42883
44148
  output: null
42884
44149
  };
42885
44150
  }
@@ -42908,7 +44173,7 @@ function reasoningOf(part) {
42908
44173
  return null;
42909
44174
  }
42910
44175
  function renderPartPreview(part) {
42911
- if (!isRecord2(part))
44176
+ if (!isRecord3(part))
42912
44177
  return null;
42913
44178
  const text = textOf(part);
42914
44179
  if (text !== null) {
@@ -42932,7 +44197,7 @@ function renderPartPreview(part) {
42932
44197
  return ` • [${type}]`;
42933
44198
  }
42934
44199
  function renderPartFull(part) {
42935
- if (!isRecord2(part))
44200
+ if (!isRecord3(part))
42936
44201
  return null;
42937
44202
  const text = textOf(part);
42938
44203
  if (text !== null) {
@@ -48039,25 +49304,6 @@ function getMaxMemoryIdForProjects(db, projectPaths, ownIdentities, shareCategor
48039
49304
  AND (expires_at IS NULL OR expires_at > ?)${sharingFilter.clause}`).get(...identities, expiryCutoff, ...sharingFilter.params);
48040
49305
  return typeof row?.max_id === "number" ? row.max_id : 0;
48041
49306
  }
48042
- function readNewMemoriesForM1Union(db, projectPaths, afterId, expiryCutoff, ownIdentities, shareCategories) {
48043
- const identities = uniqueValues(projectPaths);
48044
- if (identities.length === 0)
48045
- return [];
48046
- const sharingFilter = buildWorkspaceMemorySqlFilter({
48047
- identities,
48048
- ownIdentities,
48049
- shareCategories,
48050
- includeClassificationFields: hasMemoryShareableColumn(db) && hasMemoryScopeColumn(db)
48051
- });
48052
- const rows = db.prepare(`SELECT ${getMemorySelectColumns(db)}
48053
- FROM memories
48054
- WHERE project_path IN (${sqlPlaceholders(identities)})
48055
- AND id > ?
48056
- AND status IN ('active', 'permanent')
48057
- AND (expires_at IS NULL OR expires_at > ?)${sharingFilter.clause}
48058
- ORDER BY ${MEMORY_CATEGORY_ORDER_SQL}, id ASC`).all(...identities, afterId, expiryCutoff, ...sharingFilter.params).filter(isMemoryRow);
48059
- return rows.map(toMemory);
48060
- }
48061
49307
  function getAllActiveMemoriesForMigration(db, projectPath) {
48062
49308
  const rows = getActiveMemoriesNoExpiryStatement(db).all(projectPath).filter(isMemoryRow);
48063
49309
  return rows.map(toMemory);
@@ -49119,7 +50365,7 @@ import { isAbsolute as isAbsolute5 } from "node:path";
49119
50365
  // ../retina-local-fs/src/path-fence.ts
49120
50366
  import { lstat, readlink, realpath } from "node:fs/promises";
49121
50367
  import { homedir as homedir6 } from "node:os";
49122
- import { basename as basename3, dirname as dirname7, isAbsolute as isAbsolute4, join as join8, relative, resolve as resolve4, sep } from "node:path";
50368
+ import { basename as basename3, dirname as dirname7, isAbsolute as isAbsolute4, join as join9, relative, resolve as resolve5, sep } from "node:path";
49123
50369
 
49124
50370
  // ../retina-local-fs/src/errors.ts
49125
50371
  class ProviderError extends Error {
@@ -49134,8 +50380,8 @@ class ProviderError extends Error {
49134
50380
  // ../retina-local-fs/src/path-fence.ts
49135
50381
  async function resolveAndFenceProviderPath(configuredPath, options) {
49136
50382
  const { home, dataDirectory } = await resolveFenceRoots(options);
49137
- const expanded = configuredPath.startsWith("~/") ? join8(home, configuredPath.slice(2)) : configuredPath === "~" ? home : configuredPath;
49138
- const absolute = isAbsolute4(expanded) ? resolve4(expanded) : resolve4(options.cwd ?? process.cwd(), expanded);
50383
+ const expanded = configuredPath.startsWith("~/") ? join9(home, configuredPath.slice(2)) : configuredPath === "~" ? home : configuredPath;
50384
+ const absolute = isAbsolute4(expanded) ? resolve5(expanded) : resolve5(options.cwd ?? process.cwd(), expanded);
49139
50385
  const canonical = await canonicalPath(absolute, options.allowMissing);
49140
50386
  if (isFencedPath(canonical, home, dataDirectory)) {
49141
50387
  throw new ProviderError("fenced_path", `Refusing fenced path: ${canonical}`);
@@ -49143,14 +50389,14 @@ async function resolveAndFenceProviderPath(configuredPath, options) {
49143
50389
  return canonical;
49144
50390
  }
49145
50391
  async function resolveFenceRoots(options) {
49146
- const configuredHomePath = resolve4(options.homeDirectory ?? process.env.HOME ?? homedir6());
50392
+ const configuredHomePath = resolve5(options.homeDirectory ?? process.env.HOME ?? homedir6());
49147
50393
  let home;
49148
50394
  try {
49149
50395
  home = await realpath(configuredHomePath);
49150
50396
  } catch (error51) {
49151
50397
  throw fsError(configuredHomePath, error51);
49152
50398
  }
49153
- const configuredDataDirectory = resolve4(options.dataDirectory ?? process.env.XDG_DATA_HOME ?? join8(home, ".local", "share"));
50399
+ const configuredDataDirectory = resolve5(options.dataDirectory ?? process.env.XDG_DATA_HOME ?? join9(home, ".local", "share"));
49154
50400
  const dataDirectory = await canonicalPath(configuredDataDirectory, true);
49155
50401
  return { home, dataDirectory };
49156
50402
  }
@@ -49168,8 +50414,8 @@ async function canonicalPath(path4, allowMissing) {
49168
50414
  const metadata = await lstat(candidate);
49169
50415
  if (metadata.isSymbolicLink()) {
49170
50416
  const target2 = await readlink(candidate);
49171
- const resolvedTarget = resolve4(dirname7(candidate), target2);
49172
- return canonicalPath(join8(resolvedTarget, ...suffix), true);
50417
+ const resolvedTarget = resolve5(dirname7(candidate), target2);
50418
+ return canonicalPath(join9(resolvedTarget, ...suffix), true);
49173
50419
  }
49174
50420
  } catch (candidateError) {
49175
50421
  if (!isMissingError(candidateError)) {
@@ -49183,7 +50429,7 @@ async function canonicalPath(path4, allowMissing) {
49183
50429
  suffix.unshift(basename3(candidate));
49184
50430
  candidate = parent;
49185
50431
  try {
49186
- return join8(await realpath(candidate), ...suffix);
50432
+ return join9(await realpath(candidate), ...suffix);
49187
50433
  } catch (parentError) {
49188
50434
  if (!isMissingError(parentError)) {
49189
50435
  throw fsError(path4, parentError);
@@ -49192,8 +50438,8 @@ async function canonicalPath(path4, allowMissing) {
49192
50438
  }
49193
50439
  }
49194
50440
  }
49195
- function isFencedPath(canonicalPath2, homeDirectory, dataDirectory = process.env.XDG_DATA_HOME ?? join8(resolve4(homeDirectory), ".local", "share")) {
49196
- const cortexkitRoot = join8(resolve4(dataDirectory), "cortexkit");
50441
+ function isFencedPath(canonicalPath2, homeDirectory, dataDirectory = process.env.XDG_DATA_HOME ?? join9(resolve5(homeDirectory), ".local", "share")) {
50442
+ const cortexkitRoot = join9(resolve5(dataDirectory), "cortexkit");
49197
50443
  const relativeToCortexkit = relative(cortexkitRoot, canonicalPath2);
49198
50444
  const insideCortexkit = relativeToCortexkit !== "" && relativeToCortexkit !== ".." && !relativeToCortexkit.startsWith(`..${sep}`) && !isAbsolute4(relativeToCortexkit);
49199
50445
  const parts = insideCortexkit ? relativeToCortexkit.split(sep) : [];
@@ -49600,6 +50846,63 @@ function singleLine(value) {
49600
50846
  return value.replace(/\s+/g, " ").trim();
49601
50847
  }
49602
50848
 
50849
+ // ../plugin/src/features/magic-context/smart-notes/wake-plane.ts
50850
+ import { join as join10 } from "node:path";
50851
+ var WAKE_PLANE_CAPABILITY = "wake.create";
50852
+ var WAKE_PLANE_STATUS_TTL_MS = 5 * 60 * 1000;
50853
+ var WAKE_PLANE_HANDSHAKE_TIMEOUT_MS = 2000;
50854
+ var cachedStatus = null;
50855
+ var inFlightProbe = null;
50856
+ var catalogProbe = probeWakePlaneCatalog;
50857
+ var now = () => Date.now();
50858
+ function connectionFile() {
50859
+ return join10(getDataDir(), "cortexkit", "run", "subc-connection.json");
50860
+ }
50861
+ async function probeWakePlaneCatalog() {
50862
+ const file2 = connectionFile();
50863
+ if (!await connectionFileExists(file2)) {
50864
+ throw new Error("subc connection is not configured");
50865
+ }
50866
+ const client = await SubcClient.connect({
50867
+ connectionFile: file2,
50868
+ handshakeTimeoutMs: WAKE_PLANE_HANDSHAKE_TIMEOUT_MS
50869
+ });
50870
+ try {
50871
+ return await client.catalogList();
50872
+ } finally {
50873
+ client.close();
50874
+ }
50875
+ }
50876
+ function catalogHasWakePlane(entries) {
50877
+ return entries.some((entry) => Array.isArray(entry.control_ops) && entry.control_ops.includes(WAKE_PLANE_CAPABILITY));
50878
+ }
50879
+ async function probeStatus() {
50880
+ try {
50881
+ return catalogHasWakePlane(await catalogProbe()) ? "present" : "absent";
50882
+ } catch {
50883
+ return "unknown";
50884
+ }
50885
+ }
50886
+ async function wakePlaneStatus() {
50887
+ const cached2 = cachedStatus;
50888
+ if (cached2 && now() < cached2.expiresAt)
50889
+ return cached2.status;
50890
+ if (inFlightProbe)
50891
+ return await inFlightProbe;
50892
+ const startedAt = now();
50893
+ const probe = probeStatus().then((status) => {
50894
+ cachedStatus = { status, expiresAt: startedAt + WAKE_PLANE_STATUS_TTL_MS };
50895
+ return status;
50896
+ });
50897
+ inFlightProbe = probe;
50898
+ try {
50899
+ return await probe;
50900
+ } finally {
50901
+ if (inFlightProbe === probe)
50902
+ inFlightProbe = null;
50903
+ }
50904
+ }
50905
+
49603
50906
  // ../plugin/src/tools/ctx-note/constants.ts
49604
50907
  var CTX_NOTE_DESCRIPTION = `Working notes for this session's future — reminders, follow-ups, and things to revisit later.
49605
50908
 
@@ -49727,6 +51030,15 @@ function createCtxNoteTool(deps) {
49727
51030
  const anchorOrdinal = captureAnchorOrdinal(deps.db, sessionId);
49728
51031
  const surfaceCondition = params.surface_condition?.trim();
49729
51032
  if (surfaceCondition) {
51033
+ if (await wakePlaneStatus() === "present") {
51034
+ const note3 = addNote(deps.db, "session", {
51035
+ sessionId,
51036
+ content,
51037
+ anchorOrdinal
51038
+ });
51039
+ return ok3(`Saved session note #${note3.id}.
51040
+ wake plane active — create a scheduled wake instead; stored as a plain note.`);
51041
+ }
49730
51042
  if (dreamerEnabled !== true) {
49731
51043
  return err3("Error: Smart notes require dreamer to be enabled. Enable dreamer in magic-context.jsonc to use surface_condition.");
49732
51044
  }
@@ -50041,9 +51353,9 @@ function createCtxReduceTool(deps) {
50041
51353
  }
50042
51354
  try {
50043
51355
  deps.db.transaction(() => {
50044
- const now = Date.now();
51356
+ const now2 = Date.now();
50045
51357
  for (const id of dropIds) {
50046
- queuePendingOp(deps.db, sessionId, id, "drop", now);
51358
+ queuePendingOp(deps.db, sessionId, id, "drop", now2);
50047
51359
  }
50048
51360
  })();
50049
51361
  } catch (error51) {
@@ -52256,11 +53568,11 @@ var USER_MEMORY_CANDIDATE_TTL_MS = 30 * 24 * 60 * 60 * 1000;
52256
53568
  function insertUserMemoryCandidates(db, candidates2) {
52257
53569
  if (candidates2.length === 0)
52258
53570
  return;
52259
- const now = Date.now();
53571
+ const now2 = Date.now();
52260
53572
  const stmt = db.prepare("INSERT INTO user_memory_candidates (content, session_id, source_compartment_start, source_compartment_end, created_at) VALUES (?, ?, ?, ?, ?)");
52261
53573
  db.transaction(() => {
52262
53574
  for (const c of candidates2) {
52263
- stmt.run(c.content, c.sessionId, c.sourceCompartmentStart ?? null, c.sourceCompartmentEnd ?? null, now);
53575
+ stmt.run(c.content, c.sessionId, c.sourceCompartmentStart ?? null, c.sourceCompartmentEnd ?? null, now2);
52264
53576
  }
52265
53577
  })();
52266
53578
  }
@@ -52281,18 +53593,49 @@ function deleteUserMemoryCandidates(db, ids) {
52281
53593
  const placeholders4 = ids.map(() => "?").join(",");
52282
53594
  db.prepare(`DELETE FROM user_memory_candidates WHERE id IN (${placeholders4})`).run(...ids);
52283
53595
  }
52284
- function pruneExpiredUserMemoryCandidates(db, ttlMs, now = Date.now()) {
52285
- const cutoff = now - ttlMs;
53596
+ function pruneExpiredUserMemoryCandidates(db, ttlMs, now2 = Date.now()) {
53597
+ const cutoff = now2 - ttlMs;
52286
53598
  const result = db.prepare("DELETE FROM user_memory_candidates WHERE created_at < ?").run(cutoff);
52287
53599
  return Number(result.changes ?? 0);
52288
53600
  }
53601
+ function loadUserMemorySourceProvenance(db, candidateIds) {
53602
+ const ids = [...new Set(candidateIds)].sort((a, b) => a - b);
53603
+ if (ids.length === 0)
53604
+ return [];
53605
+ const placeholders4 = ids.map(() => "?").join(",");
53606
+ const rows = db.prepare(`SELECT id, session_id, source_compartment_start, source_compartment_end
53607
+ FROM user_memory_candidates
53608
+ WHERE id IN (${placeholders4})
53609
+ ORDER BY id ASC`).all(...ids);
53610
+ return rows.map((row) => ({
53611
+ candidateId: row.id,
53612
+ sessionId: row.session_id,
53613
+ sourceCompartmentStart: row.source_compartment_start,
53614
+ sourceCompartmentEnd: row.source_compartment_end
53615
+ }));
53616
+ }
53617
+ function serializeUserMemorySourceProvenance(provenance, sourceCandidateIds) {
53618
+ if (provenance.length === 0 && sourceCandidateIds.length > 0)
53619
+ return null;
53620
+ return JSON.stringify(provenance.map((source) => ({
53621
+ candidate_id: source.candidateId,
53622
+ session_id: source.sessionId,
53623
+ source_compartment_start: source.sourceCompartmentStart,
53624
+ source_compartment_end: source.sourceCompartmentEnd
53625
+ })));
53626
+ }
52289
53627
  function insertUserMemory(db, content, sourceCandidateIds) {
52290
- const now = Date.now();
52291
- const result = db.prepare("INSERT INTO user_memories (content, status, promoted_at, source_candidate_ids, created_at, updated_at) VALUES (?, 'active', ?, ?, ?, ?)").run(content, now, JSON.stringify(sourceCandidateIds), now, now);
52292
- return Number(result.lastInsertRowid);
53628
+ return db.transaction(() => {
53629
+ const now2 = Date.now();
53630
+ const sourceProvenance = loadUserMemorySourceProvenance(db, sourceCandidateIds);
53631
+ const result = db.prepare(`INSERT INTO user_memories
53632
+ (content, status, promoted_at, source_candidate_ids, source_candidate_provenance, created_at, updated_at)
53633
+ VALUES (?, 'active', ?, ?, ?, ?, ?)`).run(content, now2, JSON.stringify(sourceCandidateIds), serializeUserMemorySourceProvenance(sourceProvenance, sourceCandidateIds), now2, now2);
53634
+ return Number(result.lastInsertRowid);
53635
+ })();
52293
53636
  }
52294
53637
  function getActiveUserMemories(db) {
52295
- const rows = db.prepare("SELECT id, content, status, promoted_at, source_candidate_ids, created_at, updated_at FROM user_memories WHERE status = 'active' ORDER BY promoted_at ASC, id ASC").all();
53638
+ const rows = db.prepare("SELECT id, content, status, promoted_at, source_candidate_ids, source_candidate_provenance, created_at, updated_at FROM user_memories WHERE status = 'active' ORDER BY promoted_at ASC, id ASC").all();
52296
53639
  return rows.map(parseUserMemoryRow);
52297
53640
  }
52298
53641
  function updateUserMemoryContent(db, id, content) {
@@ -52301,17 +53644,49 @@ function updateUserMemoryContent(db, id, content) {
52301
53644
  function dismissUserMemory(db, id) {
52302
53645
  db.prepare("UPDATE user_memories SET status = 'dismissed', updated_at = ? WHERE id = ?").run(Date.now(), id);
52303
53646
  }
52304
- function parseUserMemoryRow(row) {
52305
- let candidateIds = [];
53647
+ function parseCandidateIds2(raw) {
52306
53648
  try {
52307
- candidateIds = JSON.parse(row.source_candidate_ids);
52308
- } catch {}
53649
+ const parsed = JSON.parse(raw);
53650
+ return Array.isArray(parsed) ? parsed.filter((id) => typeof id === "number" && Number.isFinite(id)) : [];
53651
+ } catch {
53652
+ return [];
53653
+ }
53654
+ }
53655
+ function parseUserMemorySourceProvenance(raw) {
53656
+ if (raw === null)
53657
+ return null;
53658
+ try {
53659
+ const parsed = JSON.parse(raw);
53660
+ if (!Array.isArray(parsed))
53661
+ return null;
53662
+ const provenance = [];
53663
+ for (const value of parsed) {
53664
+ if (!value || typeof value !== "object")
53665
+ return null;
53666
+ const source = value;
53667
+ if (typeof source.candidate_id !== "number" || !Number.isFinite(source.candidate_id) || typeof source.session_id !== "string" || source.source_compartment_start !== null && typeof source.source_compartment_start !== "number" || source.source_compartment_end !== null && typeof source.source_compartment_end !== "number") {
53668
+ return null;
53669
+ }
53670
+ provenance.push({
53671
+ candidateId: source.candidate_id,
53672
+ sessionId: source.session_id,
53673
+ sourceCompartmentStart: source.source_compartment_start,
53674
+ sourceCompartmentEnd: source.source_compartment_end
53675
+ });
53676
+ }
53677
+ return provenance;
53678
+ } catch {
53679
+ return null;
53680
+ }
53681
+ }
53682
+ function parseUserMemoryRow(row) {
52309
53683
  return {
52310
53684
  id: row.id,
52311
53685
  content: row.content,
52312
53686
  status: row.status === "dismissed" ? "dismissed" : "active",
52313
53687
  promotedAt: row.promoted_at,
52314
- sourceCandidateIds: candidateIds,
53688
+ sourceCandidateIds: parseCandidateIds2(row.source_candidate_ids),
53689
+ sourceProvenance: parseUserMemorySourceProvenance(row.source_candidate_provenance),
52315
53690
  createdAt: row.created_at,
52316
53691
  updatedAt: row.updated_at
52317
53692
  };
@@ -52365,7 +53740,7 @@ class BoundedSessionMap {
52365
53740
  // ../plugin/src/features/magic-context/compaction-marker.ts
52366
53741
  import { createHash as createHash16 } from "node:crypto";
52367
53742
  import { existsSync as existsSync13 } from "node:fs";
52368
- import { join as join9 } from "node:path";
53743
+ import { join as join11 } from "node:path";
52369
53744
  var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
52370
53745
  var ID_PREFIX_HEX_LENGTH = 12;
52371
53746
  var ID_SUFFIX_LENGTH = 14;
@@ -52391,7 +53766,7 @@ function generatePartId(timestampMs, counter = 0n, identity = "") {
52391
53766
  return generateId("prt", timestampMs, counter, identity);
52392
53767
  }
52393
53768
  function getOpenCodeDbPath2() {
52394
- return join9(getDataDir(), "opencode", "opencode.db");
53769
+ return join11(getDataDir(), "opencode", "opencode.db");
52395
53770
  }
52396
53771
  var cachedWriteDb = null;
52397
53772
  var REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
@@ -53577,4 +54952,4 @@ function registerMagicContextTools(pi, opts) {
53577
54952
  }
53578
54953
  }
53579
54954
 
53580
- export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, migrateMagicContextConfigLocations, ProjectIdentityError, resolveProjectIdentityStrict, resolveProjectIdentity, resolveProjectIdentityForSession, beginBootQuietPeriod, scheduleAfterBootQuiet, Database, closeQuietly, isMidTurn, textMentionsRecentCommit, hasMeaningfulUserText, extractTexts, extractToolCallSummaries, preloadTokenizer, estimateTokens, normalizeText, isRecord, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, 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, persistCachedM0, clearCachedM0M1, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getCompartmentsByEndMessageId, appendCompartments, saveRecompStagingPass, getRecompStaging, clearRecompStaging, getRecompPartialRange, setRecompPartialRange, escapeXmlAttr, escapeXmlContent, getModuleNoteEvaluationBridge, getContextStoreUuid, parseCompartmentOutput, 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, loadProtectedTailMeta, markProtectedTailPolicyV3Seeded, recordProtectedTailPublicationFloor, recordProtectedTailNoEligibleHead, getWrapupInProgressState, isWrapupInProgress, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, reserveProtectedTailDrainTokens, clearEmergencyDrainLatch, recordHistorianDrainFailure, clearHistorianDrainFailure, rollbackProtectedTailDrainReservation, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, getChannel2NudgeState, setChannel2NudgeState, casChannel2NudgeState, 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, 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, updateTagByteSize, getActiveTagTokenAggregate, 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, piModelRefToCanonical, resolveModelRefForPi, ompModelRefToCanonical, resolveModelRefForOmp, isSaneLimit, resolveLimit, getSdkContextLimit, resolveModelConfigOrDefault, normalizeTodoStateJson, buildSyntheticTodoPart, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, SYNTH_USER_ID_PREFIX, resolvePiStableId, isMidTurnPi, readPiSessionMessages, findLastModelKeyFromBranch, convertEntriesToRawMessages, withContentLanguageDirective, withMigrationLanguageDirective, buildPrimaryLanguageDirective, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, invalidateMemory, computeNormalizedHash, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, insertMemory, getMemoryByHash, getMemoriesByProject, getMemoriesByProjects, getMaxMemoryIdForProjects, readNewMemoriesForM1Union, 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, 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 };
54955
+ export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, migrateMagicContextConfigLocations, ProjectIdentityError, resolveProjectIdentityStrict, resolveProjectIdentity, resolveProjectIdentityForSession, beginBootQuietPeriod, scheduleAfterBootQuiet, Database, closeQuietly, isMidTurn, textMentionsRecentCommit, hasMeaningfulUserText, extractTexts, extractToolCallSummaries, preloadTokenizer, estimateTokens, normalizeText, isRecord, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, 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, 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, loadProtectedTailMeta, markProtectedTailPolicyV3Seeded, recordProtectedTailPublicationFloor, recordProtectedTailNoEligibleHead, getWrapupInProgressState, isWrapupInProgress, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, reserveProtectedTailDrainTokens, clearEmergencyDrainLatch, recordHistorianDrainFailure, clearHistorianDrainFailure, rollbackProtectedTailDrainReservation, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, 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, 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, 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, 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 };