@cortexkit/opencode-magic-context 0.37.0 → 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.
Files changed (94) hide show
  1. package/README.md +2 -0
  2. package/dist/{derive-budgets-0f8xpyw2.js → derive-budgets-da4yg3tz.js} +1 -1
  3. package/dist/features/magic-context/dreamer/classify-prompt.d.ts +5 -1
  4. package/dist/features/magic-context/dreamer/classify-prompt.d.ts.map +1 -1
  5. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  6. package/dist/features/magic-context/dreamer/manifest-parser.d.ts +8 -0
  7. package/dist/features/magic-context/dreamer/manifest-parser.d.ts.map +1 -1
  8. package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts +7 -1
  9. package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts.map +1 -1
  10. package/dist/features/magic-context/dreamer/map-memories.d.ts +18 -0
  11. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  12. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +5 -0
  13. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  14. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  15. package/dist/features/magic-context/dreamer/verify-prompt.d.ts +5 -1
  16. package/dist/features/magic-context/dreamer/verify-prompt.d.ts.map +1 -1
  17. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  18. package/dist/features/magic-context/fail-closed-block.d.ts +6 -1
  19. package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
  20. package/dist/features/magic-context/reclaim-protection.d.ts +13 -0
  21. package/dist/features/magic-context/reclaim-protection.d.ts.map +1 -0
  22. package/dist/features/magic-context/storage-db.d.ts +6 -1
  23. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  24. package/dist/features/magic-context/storage-meta-persisted.d.ts +7 -6
  25. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  26. package/dist/features/magic-context/storage-tags.d.ts +13 -5
  27. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  28. package/dist/hooks/auto-update-checker/checker.d.ts +8 -1
  29. package/dist/hooks/auto-update-checker/checker.d.ts.map +1 -1
  30. package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
  31. package/dist/hooks/magic-context/channel2-cycle.d.ts +16 -0
  32. package/dist/hooks/magic-context/channel2-cycle.d.ts.map +1 -0
  33. package/dist/hooks/magic-context/channel2-delivery.d.ts +3 -9
  34. package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
  35. package/dist/hooks/magic-context/command-handler.d.ts +2 -0
  36. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  37. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +33 -103
  38. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
  39. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
  40. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  41. package/dist/hooks/magic-context/execute-status.d.ts +2 -1
  42. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/fold-execution-gate.d.ts +2 -0
  44. package/dist/hooks/magic-context/fold-execution-gate.d.ts.map +1 -0
  45. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  47. package/dist/hooks/magic-context/live-session-state.d.ts +3 -0
  48. package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -1
  49. package/dist/hooks/magic-context/rust-mode-transform.d.ts +4 -2
  50. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  51. package/dist/hooks/magic-context/strip-content.d.ts +10 -8
  52. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  53. package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
  54. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  55. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +78 -0
  56. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -0
  57. package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -1
  58. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +3 -0
  59. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  60. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  61. package/dist/{index-q0t189ay.js → index-9zhhvr4w.js} +27 -35
  62. package/dist/{index-0ze9p983.js → index-mmvhrqqb.js} +1428 -191
  63. package/dist/index.js +604 -763
  64. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  65. package/dist/plugin/messages-transform.d.ts.map +1 -1
  66. package/dist/plugin/rpc-handlers.d.ts +2 -0
  67. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  68. package/dist/{recomp-orchestrator-c3ff16k7.js → recomp-orchestrator-jsde4ygw.js} +2 -2
  69. package/dist/shared/models-dev-cache.d.ts +2 -0
  70. package/dist/shared/models-dev-cache.d.ts.map +1 -1
  71. package/dist/shared/rpc-server.d.ts.map +1 -1
  72. package/dist/shared/rpc-types.d.ts +15 -0
  73. package/dist/shared/rpc-types.d.ts.map +1 -1
  74. package/dist/shared/rpc-utils.d.ts +9 -0
  75. package/dist/shared/rpc-utils.d.ts.map +1 -1
  76. package/dist/shared/tail-hygiene-status.d.ts +15 -0
  77. package/dist/shared/tail-hygiene-status.d.ts.map +1 -0
  78. package/dist/shared/window-geometry.d.ts +3 -2
  79. package/dist/shared/window-geometry.d.ts.map +1 -1
  80. package/package.json +3 -1
  81. package/src/config/schema/magic-context.ts +2 -2
  82. package/src/shared/models-dev-cache.test.ts +25 -0
  83. package/src/shared/models-dev-cache.ts +5 -4
  84. package/src/shared/rpc-server.ts +1 -0
  85. package/src/shared/rpc-types.ts +16 -0
  86. package/src/shared/rpc-utils.test.ts +25 -0
  87. package/src/shared/rpc-utils.ts +80 -0
  88. package/src/shared/tail-hygiene-status.ts +57 -0
  89. package/src/shared/window-geometry.test.ts +34 -1
  90. package/src/shared/window-geometry.ts +37 -40
  91. package/src/tui/index.tsx +11 -1
  92. package/src/tui/slots/sidebar-content.tsx +17 -5
  93. package/src/tui-compiled/index.tsx +311 -289
  94. package/src/tui-compiled/slots/sidebar-content.tsx +316 -287
@@ -2,7 +2,7 @@ import {
2
2
  deriveTriggerBudget,
3
3
  modelSupportsVision,
4
4
  shouldEnforcePrivateStoragePermissions
5
- } from "./index-q0t189ay.js";
5
+ } from "./index-9zhhvr4w.js";
6
6
  import {
7
7
  parseProviderModel
8
8
  } from "./index-td9depx5.js";
@@ -14,6 +14,7 @@ import {
14
14
  import {
15
15
  buildToolArcs,
16
16
  buildTrueRawTokenIndex,
17
+ byteSize,
17
18
  clearCachedM0M1,
18
19
  clearCompressionDepth,
19
20
  clearCompressionDepthRange,
@@ -417,24 +418,44 @@ function isMagicContextHiddenAgentName(agent) {
417
418
  return false;
418
419
  }
419
420
  var MAX_FORMATTED_BLOCKING_PROCESSES = 8;
421
+ function normalizeFailClosedProcessKind(process2) {
422
+ switch (process2.kind) {
423
+ case "OpenCode server":
424
+ case "OpenCode instance (TUI/CLI)":
425
+ case "Pi":
426
+ case "process":
427
+ return process2.kind;
428
+ }
429
+ switch (process2.harness?.trim().toLowerCase()) {
430
+ case "opencode server":
431
+ return "OpenCode server";
432
+ case "opencode instance (tui/cli)":
433
+ case "opencode instance":
434
+ return "OpenCode instance (TUI/CLI)";
435
+ case "pi":
436
+ case "pi harness":
437
+ case "omp":
438
+ return "Pi";
439
+ default:
440
+ return "process";
441
+ }
442
+ }
420
443
  function formatFailClosedBlockingProcesses(processes) {
421
444
  const uniqueProcesses = new Map;
422
445
  for (const process2 of processes) {
423
- if (!process2.harness.trim() || !Number.isInteger(process2.pid) || process2.pid <= 0)
446
+ if (!Number.isInteger(process2.pid) || process2.pid <= 0)
424
447
  continue;
425
- uniqueProcesses.set(`${process2.harness}\x00${process2.pid}`, {
426
- harness: process2.harness.trim(),
427
- pid: process2.pid
428
- });
448
+ const kind = normalizeFailClosedProcessKind(process2);
449
+ uniqueProcesses.set(`${kind}\x00${process2.pid}`, { kind, pid: process2.pid });
429
450
  }
430
451
  const entries = [...uniqueProcesses.values()];
431
452
  const visible = entries.slice(0, MAX_FORMATTED_BLOCKING_PROCESSES);
432
- const rendered = visible.map(({ harness, pid }) => `${harness} (PID ${pid})`);
453
+ const rendered = visible.map(({ kind, pid }) => `${kind} (PID ${pid})`);
433
454
  const omitted = entries.length - visible.length;
434
455
  if (omitted > 0)
435
456
  rendered.push(`${omitted} more blocking process(es)`);
436
457
  if (rendered.length === 0)
437
- return "a live harness process";
458
+ return "a live process";
438
459
  if (rendered.length === 1)
439
460
  return rendered[0];
440
461
  const last = rendered.pop();
@@ -444,9 +465,9 @@ function formatFailClosedBlockingMessage(reason) {
444
465
  if (reason.kind === "migration_guard") {
445
466
  if (reason.unreadableFile) {
446
467
  const arm = reason.unreadableArm ?? "io";
447
- const recovery = arm === "io" ? `If no OpenCode server is running, it is safe to delete ${reason.unreadableFile} and retry.` : `The file may be a recent incomplete write; retry after the file is older than the ten-minute grace window, or stop OpenCode before deleting it.`;
468
+ const recovery = arm === "io" ? `If none of these processes are running, it is safe to delete ${reason.unreadableFile} and retry.` : `The file may be a recent incomplete write; retry after the file is older than the ten-minute grace window, or stop the relevant process before deleting it.`;
448
469
  return [
449
- `Magic Context cannot migrate the shared database because RPC discovery file ${reason.unreadableFile} is uncertain (${arm} arm), so the absence of a live OpenCode server cannot be proven.`,
470
+ `Magic Context cannot migrate the shared database because RPC discovery file ${reason.unreadableFile} is uncertain (${arm} arm), so the absence of a live process cannot be proven.`,
450
471
  recovery,
451
472
  `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
452
473
  ].join(" ");
@@ -569,7 +590,7 @@ import {
569
590
  statSync as statSync2,
570
591
  unlinkSync
571
592
  } from "node:fs";
572
- import { basename, dirname, join as join3 } from "node:path";
593
+ import { basename, dirname, join as join3, resolve } from "node:path";
573
594
 
574
595
  // src/plugin/boot-quiet.ts
575
596
  var BOOT_QUIET_MS = 120000;
@@ -744,6 +765,51 @@ function readPsProcessCommand(pid) {
744
765
  return null;
745
766
  }
746
767
  }
768
+ function readProcessCommand(pid) {
769
+ if (!Number.isInteger(pid) || pid <= 0)
770
+ return null;
771
+ return rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(pid) : rpcIdentityPlatform === "win32" ? readWindowsProcess(pid).command ?? null : readPsProcessCommand(pid);
772
+ }
773
+ function executableName(token) {
774
+ return (token ?? "").replace(/^['"]|['"]$/g, "").split("/").at(-1) ?? "";
775
+ }
776
+ function commandTokens(command) {
777
+ return command.toLowerCase().replaceAll("\\", "/").replaceAll("\x00", " ").split(/\s+/).map((token) => token.replace(/^['"]|['"]$/g, "")).filter(Boolean);
778
+ }
779
+ function commandHasOpenCodeExecutable(tokens) {
780
+ return tokens.findIndex((token) => {
781
+ const executable = executableName(token).replace(/\.(?:exe|cmd)$/, "");
782
+ return executable === "opencode" || executable.endsWith("/opencode");
783
+ });
784
+ }
785
+ function commandHasPiExecutable(tokens) {
786
+ for (let index = 0;index < tokens.length; index += 1) {
787
+ const executable = executableName(tokens[index]).replace(/\.(?:exe|cmd)$/, "");
788
+ if (["pi", "omp", "oh-my-pi"].includes(executable))
789
+ return true;
790
+ if (["node", "bun", "deno"].includes(executable)) {
791
+ const script = executableName(tokens[index + 1]).replace(/\.(?:exe|cmd)$/, "");
792
+ if (["pi", "pi.js", "pi.mjs", "pi.cjs"].includes(script) || tokens[index + 1]?.includes("pi-coding-agent")) {
793
+ return true;
794
+ }
795
+ }
796
+ }
797
+ return false;
798
+ }
799
+ function classifyProcessKind(command) {
800
+ if (!command)
801
+ return "process";
802
+ const tokens = commandTokens(command);
803
+ const openCodeIndex = commandHasOpenCodeExecutable(tokens);
804
+ if (openCodeIndex >= 0) {
805
+ const args = tokens.slice(openCodeIndex + 1);
806
+ if (args.some((token) => token === "serve" || token === "--serve" || token.startsWith("--serve="))) {
807
+ return "OpenCode server";
808
+ }
809
+ return "OpenCode instance (TUI/CLI)";
810
+ }
811
+ return commandHasPiExecutable(tokens) ? "Pi" : "process";
812
+ }
747
813
  function commandLooksLikeOpenCode(command) {
748
814
  const normalized = command.toLowerCase();
749
815
  return OPEN_CODE_COMMAND_MARKERS.some((marker) => normalized.includes(marker));
@@ -765,12 +831,12 @@ function isPidIdentityPlausible(record) {
765
831
  function commandLooksLikePi(command) {
766
832
  const normalized = command.trim().toLowerCase().replaceAll("\\", "/");
767
833
  const tokens = normalized.split(/\s+/).filter(Boolean);
768
- const executableName = (token) => (token ?? "").split("/").at(-1) ?? "";
769
- const first = executableName(tokens[0]).replace(/\.exe$/, "");
834
+ const executableName2 = (token) => (token ?? "").split("/").at(-1) ?? "";
835
+ const first = executableName2(tokens[0]).replace(/\.exe$/, "");
770
836
  if (["pi", "pi.cmd", "omp", "oh-my-pi"].includes(first))
771
837
  return true;
772
838
  if (["node", "bun", "deno"].includes(first)) {
773
- const script = executableName(tokens[1]);
839
+ const script = executableName2(tokens[1]);
774
840
  return ["pi", "pi.js", "pi.mjs", "pi.cjs"].includes(script) || normalized.includes("pi-coding-agent");
775
841
  }
776
842
  return false;
@@ -837,6 +903,8 @@ function parseRpcPortFile(content, fallbackPid = 0) {
837
903
  port: port2,
838
904
  pid,
839
905
  started_at: Number.isFinite(startedAt) ? startedAt : 0,
906
+ kind: typeof parsed.kind === "string" ? parsed.kind : undefined,
907
+ harness: typeof parsed.harness === "string" ? parsed.harness : undefined,
840
908
  token: typeof parsed.token === "string" ? parsed.token : undefined,
841
909
  instance_id: typeof parsed.instance_id === "string" ? parsed.instance_id : undefined
842
910
  };
@@ -5687,6 +5755,28 @@ function invalidDiscoveryReason(raw) {
5687
5755
  }
5688
5756
  return "parse-invalid";
5689
5757
  }
5758
+ function classifyDiscoveryRecordKind(record) {
5759
+ for (const value of [record.kind, record.harness]) {
5760
+ const normalized = value?.trim().toLowerCase();
5761
+ if (!normalized)
5762
+ continue;
5763
+ if (normalized === "process")
5764
+ return "process";
5765
+ if (normalized === "opencode server" || normalized === "server") {
5766
+ return "OpenCode server";
5767
+ }
5768
+ if (normalized === "opencode instance" || normalized === "opencode instance (tui/cli)" || normalized === "opencode" || normalized === "tui" || normalized === "cli") {
5769
+ return "OpenCode instance (TUI/CLI)";
5770
+ }
5771
+ if (normalized === "pi" || normalized === "pi harness" || normalized === "omp" || normalized === "oh-my-pi") {
5772
+ return "Pi";
5773
+ }
5774
+ }
5775
+ return null;
5776
+ }
5777
+ function classifyRpcProcess(record) {
5778
+ return classifyDiscoveryRecordKind(record) ?? classifyProcessKind(readProcessCommand(record.pid));
5779
+ }
5690
5780
  function classifyJunkDiscovery(portFile, raw, staleFiles) {
5691
5781
  let mtimeMs;
5692
5782
  try {
@@ -5739,6 +5829,7 @@ function inspectRpcServerDiscovery(storageDir) {
5739
5829
  return { state: "absent", serverPids: [], staleFiles: [] };
5740
5830
  }
5741
5831
  const pids = new Set;
5832
+ const processByPid = new Map;
5742
5833
  const staleFiles = [];
5743
5834
  const inconclusivePids = new Set;
5744
5835
  for (const portFile of portFiles) {
@@ -5764,6 +5855,14 @@ function inspectRpcServerDiscovery(storageDir) {
5764
5855
  const identity = liveness === "dead" ? "implausible" : isPidIdentityPlausible(record);
5765
5856
  if (liveness === "alive" && identity === "plausible") {
5766
5857
  pids.add(record.pid);
5858
+ const detected = {
5859
+ kind: classifyRpcProcess(record),
5860
+ pid: record.pid
5861
+ };
5862
+ const previous = processByPid.get(record.pid);
5863
+ if (!previous || previous.kind === "process" && detected.kind !== "process") {
5864
+ processByPid.set(record.pid, detected);
5865
+ }
5767
5866
  } else if (liveness === "dead" || identity === "implausible") {
5768
5867
  staleFiles.push(portFile);
5769
5868
  } else {
@@ -5779,7 +5878,12 @@ function inspectRpcServerDiscovery(storageDir) {
5779
5878
  }
5780
5879
  const serverPids = [...pids].sort((a, b) => a - b);
5781
5880
  if (serverPids.length > 0) {
5782
- return { state: "live", serverPids, staleFiles };
5881
+ return {
5882
+ state: "live",
5883
+ serverPids,
5884
+ serverProcesses: serverPids.map((pid) => processByPid.get(pid) ?? { kind: "process", pid }),
5885
+ staleFiles
5886
+ };
5783
5887
  }
5784
5888
  const uncertainPids = [...inconclusivePids].sort((a, b) => a - b);
5785
5889
  if (uncertainPids.length > 0) {
@@ -5804,6 +5908,25 @@ function logInconclusiveMigrationProbes(dbPath, discovery, piProbeState) {
5804
5908
  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.`);
5805
5909
  }
5806
5910
  }
5911
+ function isDefaultSharedDatabasePath(dbPath) {
5912
+ if (!process.env.XDG_DATA_HOME && (process.env.MAGIC_CONTEXT_TEST_DATA_DIR || false)) {
5913
+ return false;
5914
+ }
5915
+ return resolve(dbPath) === resolve(join3(getMagicContextStorageDir(), "context.db"));
5916
+ }
5917
+ function migrationBlockingPiPids(dbPath, discovery, discoveredPiPids) {
5918
+ if (isDefaultSharedDatabasePath(dbPath))
5919
+ return [...discoveredPiPids];
5920
+ const sameDataDirPids = new Set(discovery.serverPids);
5921
+ return discoveredPiPids.filter((pid) => sameDataDirPids.has(pid));
5922
+ }
5923
+ function formatLiveProcessMigrationRefusal(dbPath, persistedVersion, latestSupportedVersion, serverPids, piPids) {
5924
+ const blockers = [
5925
+ ...serverPids.map((pid) => `confirmed OpenCode server PID ${pid}`),
5926
+ ...piPids.map((pid) => `confirmed Pi harness PID ${pid}`)
5927
+ ];
5928
+ 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.`;
5929
+ }
5807
5930
  function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion) {
5808
5931
  const persistedVersion = getPersistedSchemaVersion(db);
5809
5932
  if (persistedVersion >= latestSupportedVersion) {
@@ -5812,7 +5935,12 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
5812
5935
  }
5813
5936
  const discovery = inspectRpcServerDiscovery(dbDir);
5814
5937
  const piDiscovery = inspectLivePiProcesses();
5815
- const piPids = piDiscovery.processIds;
5938
+ const piPids = migrationBlockingPiPids(dbPath, discovery, piDiscovery.processIds);
5939
+ const serverProcesses = discovery.serverProcesses ?? (discovery.state === "live" ? discovery.serverPids.map((pid) => ({ kind: "process", pid })) : []);
5940
+ const blockingProcesses = [
5941
+ ...serverProcesses,
5942
+ ...piPids.map((pid) => ({ kind: "Pi", pid }))
5943
+ ];
5816
5944
  if ((discovery.state === "absent" || discovery.state === "stale" || discovery.state === "inconclusive") && piPids.length === 0) {
5817
5945
  lastMigrationOnOpenRefusal = null;
5818
5946
  logInconclusiveMigrationProbes(dbPath, discovery, piDiscovery.state);
@@ -5823,6 +5951,7 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
5823
5951
  persistedVersion,
5824
5952
  supportedVersion: latestSupportedVersion,
5825
5953
  serverPids: blockingPids,
5954
+ blockingProcesses,
5826
5955
  ...discovery.unreadableFile ? { unreadableFile: discovery.unreadableFile } : {},
5827
5956
  ...discovery.unreadableArm ? { unreadableArm: discovery.unreadableArm } : {}
5828
5957
  };
@@ -5832,11 +5961,7 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
5832
5961
  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.`;
5833
5962
  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}`);
5834
5963
  } else {
5835
- const blockers = [
5836
- ...discovery.serverPids.map((pid) => `confirmed OpenCode server PID ${pid}`),
5837
- ...piPids.map((pid) => `confirmed Pi harness PID ${pid}`)
5838
- ];
5839
- log(`[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.`);
5964
+ log(formatLiveProcessMigrationRefusal(dbPath, persistedVersion, latestSupportedVersion, discovery.serverPids, piPids));
5840
5965
  }
5841
5966
  return false;
5842
5967
  }
@@ -6994,11 +7119,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
6994
7119
  ensureColumn(db, "message_history_index", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
6995
7120
  ensureColumn(db, "workspaces", "share_categories", `TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'`);
6996
7121
  }
6997
- var CHANNEL2_CLAIM_TTL_MS = 120000;
7122
+ var CHANNEL2_CLAIM_TTL_MS = 10 * 60000;
6998
7123
  function healWedgedChannel2Claims(db) {
6999
7124
  try {
7000
7125
  const staleBefore = Date.now() - CHANNEL2_CLAIM_TTL_MS;
7001
- 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);
7126
+ 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);
7002
7127
  } catch {}
7003
7128
  }
7004
7129
  function openDatabase(dbPathOrOptions) {
@@ -8578,6 +8703,17 @@ function addMergedReasoningStrippedIds(db, sessionId, ids) {
8578
8703
  sessionLog(sessionId, `merged_reasoning_stripped_ids CAS: ${CAS_RETRY_LIMIT} retries exhausted`);
8579
8704
  return false;
8580
8705
  }
8706
+ function isPersistedTrailingBlankDecision(value) {
8707
+ if (value === "keep" || value === "strip")
8708
+ return true;
8709
+ if (typeof value !== "string" || !value.startsWith("keep:"))
8710
+ return false;
8711
+ const countText = value.slice("keep:".length);
8712
+ if (!/^[1-9]\d*$/.test(countText))
8713
+ return false;
8714
+ const count = Number(countText);
8715
+ return Number.isSafeInteger(count) && count > 1 && count <= 1e4;
8716
+ }
8581
8717
  function parseTrailingBlankDecisions(raw) {
8582
8718
  if (!raw)
8583
8719
  return new Map;
@@ -8587,7 +8723,7 @@ function parseTrailingBlankDecisions(raw) {
8587
8723
  return new Map;
8588
8724
  const decisions = new Map;
8589
8725
  for (const [id, decision] of Object.entries(parsed)) {
8590
- if (id.length > 0 && (decision === "keep" || decision === "strip")) {
8726
+ if (id.length > 0 && isPersistedTrailingBlankDecision(decision)) {
8591
8727
  decisions.set(id, decision);
8592
8728
  }
8593
8729
  }
@@ -8600,7 +8736,7 @@ function getTrailingBlankDecisions(db, sessionId) {
8600
8736
  const row = db.prepare("SELECT trailing_blank_decisions FROM session_meta WHERE session_id = ?").get(sessionId);
8601
8737
  return parseTrailingBlankDecisions(row?.trailing_blank_decisions);
8602
8738
  }
8603
- function addTrailingBlankDecisions(db, sessionId, additions) {
8739
+ function addTrailingBlankDecisions(db, sessionId, additions, options) {
8604
8740
  const add = [...additions];
8605
8741
  if (add.length === 0)
8606
8742
  return true;
@@ -8611,7 +8747,8 @@ function addTrailingBlankDecisions(db, sessionId, additions) {
8611
8747
  const current = parseTrailingBlankDecisions(rawStored);
8612
8748
  let changed = false;
8613
8749
  for (const [id, decision] of add) {
8614
- if (!current.has(id)) {
8750
+ const currentDecision = current.get(id);
8751
+ if (currentDecision === undefined || id === options?.overwriteMessageId && currentDecision !== decision) {
8615
8752
  current.set(id, decision);
8616
8753
  changed = true;
8617
8754
  }
@@ -9387,6 +9524,1097 @@ function getLatestHistorianInvocationId(db, sessionId) {
9387
9524
  return null;
9388
9525
  }
9389
9526
  }
9527
+ // src/features/magic-context/reclaim-protection.ts
9528
+ var CTX_REDUCE_KEEP = 3;
9529
+ function newestCtxReduceTagNumbers(tags) {
9530
+ 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));
9531
+ }
9532
+
9533
+ // src/hooks/magic-context/image-token-estimate.ts
9534
+ var IMAGE_TOKEN_DIVISOR = 750;
9535
+ var IMAGE_FALLBACK_TOKENS = 1200;
9536
+ var IMAGE_TOKEN_CAP = 4500;
9537
+ function estimateImageTokensFromDataUrl(url) {
9538
+ const comma = url.indexOf(",");
9539
+ if (comma < 0)
9540
+ return IMAGE_FALLBACK_TOKENS;
9541
+ const header = url.slice(0, comma);
9542
+ const payload = url.slice(comma + 1);
9543
+ const sliceLen = Math.min(512, payload.length);
9544
+ const preview = payload.slice(0, sliceLen);
9545
+ let bytes;
9546
+ try {
9547
+ bytes = base64Decode(preview);
9548
+ } catch {
9549
+ return IMAGE_FALLBACK_TOKENS;
9550
+ }
9551
+ if (header.includes("image/png")) {
9552
+ const dims = parsePngDimensions(bytes);
9553
+ if (dims)
9554
+ return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
9555
+ } else if (header.includes("image/jpeg") || header.includes("image/jpg")) {
9556
+ const dims = parseJpegDimensions(bytes);
9557
+ if (dims)
9558
+ return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
9559
+ } else if (header.includes("image/webp")) {
9560
+ const dims = parseWebpDimensions(bytes);
9561
+ if (dims)
9562
+ return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
9563
+ } else if (header.includes("image/gif")) {
9564
+ const dims = parseGifDimensions(bytes);
9565
+ if (dims)
9566
+ return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
9567
+ }
9568
+ return IMAGE_FALLBACK_TOKENS;
9569
+ }
9570
+ function clampImageTokens(n) {
9571
+ if (n < 1)
9572
+ return 1;
9573
+ if (n > IMAGE_TOKEN_CAP)
9574
+ return IMAGE_TOKEN_CAP;
9575
+ return n;
9576
+ }
9577
+ function base64Decode(b64) {
9578
+ const pad = b64.length % 4;
9579
+ const padded = pad === 0 ? b64 : b64 + "=".repeat(4 - pad);
9580
+ const binary = atob(padded);
9581
+ const out = new Uint8Array(binary.length);
9582
+ for (let i = 0;i < binary.length; i++)
9583
+ out[i] = binary.charCodeAt(i);
9584
+ return out;
9585
+ }
9586
+ function parsePngDimensions(b) {
9587
+ if (b.length < 24)
9588
+ return null;
9589
+ 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)
9590
+ return null;
9591
+ const w = readUint32BE(b, 16);
9592
+ const h = readUint32BE(b, 20);
9593
+ if (!w || !h)
9594
+ return null;
9595
+ return { w, h };
9596
+ }
9597
+ function parseJpegDimensions(b) {
9598
+ if (b.length < 4 || b[0] !== 255 || b[1] !== 216)
9599
+ return null;
9600
+ let i = 2;
9601
+ while (i < b.length - 8) {
9602
+ if (b[i] !== 255) {
9603
+ i++;
9604
+ continue;
9605
+ }
9606
+ const marker = b[i + 1];
9607
+ if (marker === undefined)
9608
+ break;
9609
+ if (isSofMarker(marker)) {
9610
+ const h = b[i + 5] << 8 | b[i + 6];
9611
+ const w = b[i + 7] << 8 | b[i + 8];
9612
+ if (w && h)
9613
+ return { w, h };
9614
+ return null;
9615
+ }
9616
+ if (marker === 216 || marker === 217 || marker === 1) {
9617
+ i += 2;
9618
+ continue;
9619
+ }
9620
+ const segLen = b[i + 2] << 8 | b[i + 3];
9621
+ if (segLen < 2)
9622
+ return null;
9623
+ i += 2 + segLen;
9624
+ }
9625
+ return null;
9626
+ }
9627
+ function isSofMarker(m) {
9628
+ if (m >= 192 && m <= 195)
9629
+ return true;
9630
+ if (m >= 197 && m <= 199)
9631
+ return true;
9632
+ if (m >= 201 && m <= 203)
9633
+ return true;
9634
+ if (m >= 205 && m <= 207)
9635
+ return true;
9636
+ return false;
9637
+ }
9638
+ function parseWebpDimensions(b) {
9639
+ if (b.length < 30)
9640
+ return null;
9641
+ if (b[0] !== 82 || b[1] !== 73 || b[2] !== 70 || b[3] !== 70)
9642
+ return null;
9643
+ if (b[8] !== 87 || b[9] !== 69 || b[10] !== 66 || b[11] !== 80)
9644
+ return null;
9645
+ const variant = String.fromCharCode(b[12], b[13], b[14], b[15]);
9646
+ if (variant === "VP8 ") {
9647
+ const w = (b[26] | b[27] << 8) & 16383;
9648
+ const h = (b[28] | b[29] << 8) & 16383;
9649
+ if (w && h)
9650
+ return { w, h };
9651
+ } else if (variant === "VP8L") {
9652
+ const b0 = b[21];
9653
+ const b1 = b[22];
9654
+ const b2 = b[23];
9655
+ const b3 = b[24];
9656
+ const w = 1 + ((b0 | b1 << 8) & 16383);
9657
+ const h = 1 + ((b1 >> 6 | b2 << 2 | b3 << 10) & 16383);
9658
+ if (w && h)
9659
+ return { w, h };
9660
+ } else if (variant === "VP8X") {
9661
+ const w = 1 + (b[24] | b[25] << 8 | b[26] << 16);
9662
+ const h = 1 + (b[27] | b[28] << 8 | b[29] << 16);
9663
+ if (w && h)
9664
+ return { w, h };
9665
+ }
9666
+ return null;
9667
+ }
9668
+ function parseGifDimensions(b) {
9669
+ if (b.length < 10)
9670
+ return null;
9671
+ if (b[0] !== 71 || b[1] !== 73 || b[2] !== 70)
9672
+ return null;
9673
+ const w = b[6] | b[7] << 8;
9674
+ const h = b[8] | b[9] << 8;
9675
+ if (!w || !h)
9676
+ return null;
9677
+ return { w, h };
9678
+ }
9679
+ function readUint32BE(b, offset) {
9680
+ return (b[offset] << 24 | b[offset + 1] << 16 | b[offset + 2] << 8 | b[offset + 3]) >>> 0;
9681
+ }
9682
+
9683
+ // src/hooks/magic-context/todo-view.ts
9684
+ import { createHash as createHash8 } from "node:crypto";
9685
+ var TODO_STATUS_PENDING = "pending";
9686
+ var TODO_STATUS_IN_PROGRESS = "in_progress";
9687
+ var TODO_STATUS_COMPLETED = "completed";
9688
+ var TODO_STATUS_CANCELLED = "cancelled";
9689
+ var TODO_PRIORITY_HIGH = "high";
9690
+ var TODO_PRIORITY_MEDIUM = "medium";
9691
+ var TODO_PRIORITY_LOW = "low";
9692
+ var TODO_STATUSES = [
9693
+ TODO_STATUS_PENDING,
9694
+ TODO_STATUS_IN_PROGRESS,
9695
+ TODO_STATUS_COMPLETED,
9696
+ TODO_STATUS_CANCELLED
9697
+ ];
9698
+ var TODO_PRIORITIES = [
9699
+ TODO_PRIORITY_HIGH,
9700
+ TODO_PRIORITY_MEDIUM,
9701
+ TODO_PRIORITY_LOW
9702
+ ];
9703
+ var TODO_STATUS_SET = new Set(TODO_STATUSES);
9704
+ var TODO_PRIORITY_SET = new Set(TODO_PRIORITIES);
9705
+ var TERMINAL_STATUSES = new Set([
9706
+ TODO_STATUS_COMPLETED,
9707
+ TODO_STATUS_CANCELLED
9708
+ ]);
9709
+ var TITLE_DONE_STATUSES = new Set([TODO_STATUS_COMPLETED]);
9710
+ var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
9711
+ function normalizeTodoStateJson(todos) {
9712
+ if (!Array.isArray(todos))
9713
+ return null;
9714
+ const normalized = [];
9715
+ for (const todo of todos) {
9716
+ if (!isTodoItem(todo))
9717
+ return null;
9718
+ normalized.push({
9719
+ content: todo.content,
9720
+ status: todo.status,
9721
+ priority: todo.priority ?? TODO_PRIORITY_MEDIUM
9722
+ });
9723
+ }
9724
+ return JSON.stringify(normalized);
9725
+ }
9726
+ function buildSyntheticTodoPart(stateJson) {
9727
+ const todos = parseTodoState(stateJson);
9728
+ if (todos === null || todos.length === 0)
9729
+ return null;
9730
+ if (todos.every((t) => TERMINAL_STATUSES.has(t.status)))
9731
+ return null;
9732
+ const callID = computeSyntheticCallId(stateJson);
9733
+ const activeCount = todos.filter((t) => !TITLE_DONE_STATUSES.has(t.status)).length;
9734
+ const output = JSON.stringify(todos, null, 2);
9735
+ const ts = 0;
9736
+ return {
9737
+ type: "tool",
9738
+ callID,
9739
+ tool: "todowrite",
9740
+ state: {
9741
+ status: "completed",
9742
+ input: { todos },
9743
+ output,
9744
+ title: `${activeCount} todos`,
9745
+ metadata: { todos, truncated: false },
9746
+ time: { start: ts, end: ts }
9747
+ },
9748
+ syntheticTodoMarker: true
9749
+ };
9750
+ }
9751
+ function computeSyntheticCallId(stateJson) {
9752
+ const hash = createHash8("sha256").update(stateJson).digest("hex").slice(0, 16);
9753
+ return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
9754
+ }
9755
+ function isSyntheticTodoPart(part) {
9756
+ if (part === null || typeof part !== "object")
9757
+ return false;
9758
+ const p = part;
9759
+ if (p.syntheticTodoMarker === true)
9760
+ return true;
9761
+ return p.type === "tool" && p.tool === "todowrite" && typeof p.callID === "string" && p.callID.startsWith(SYNTHETIC_CALL_ID_PREFIX);
9762
+ }
9763
+ function parseTodoState(stateJson) {
9764
+ if (stateJson.length === 0)
9765
+ return null;
9766
+ try {
9767
+ const parsed = JSON.parse(stateJson);
9768
+ if (!Array.isArray(parsed))
9769
+ return null;
9770
+ const result = [];
9771
+ for (const item of parsed) {
9772
+ if (!isTodoItem(item))
9773
+ return null;
9774
+ result.push({
9775
+ content: item.content,
9776
+ status: item.status,
9777
+ priority: item.priority ?? TODO_PRIORITY_MEDIUM
9778
+ });
9779
+ }
9780
+ return result;
9781
+ } catch {
9782
+ return null;
9783
+ }
9784
+ }
9785
+ function isTodoStatus(value) {
9786
+ return typeof value === "string" && TODO_STATUS_SET.has(value);
9787
+ }
9788
+ function isTodoPriority(value) {
9789
+ return typeof value === "string" && TODO_PRIORITY_SET.has(value);
9790
+ }
9791
+ function isTodoItem(value) {
9792
+ if (value === null || typeof value !== "object")
9793
+ return false;
9794
+ const todo = value;
9795
+ return typeof todo.content === "string" && isTodoStatus(todo.status) && (todo.priority === undefined || isTodoPriority(todo.priority));
9796
+ }
9797
+
9798
+ // src/hooks/magic-context/tail-hygiene-walk.ts
9799
+ var MAX_CONTENT_MEMO_ENTRIES = 1e5;
9800
+ var MAX_CONTENT_MEMO_BYTES = 64 * 1024 * 1024;
9801
+ var contentMemo = new Map;
9802
+ var contentMemoBytes = 0;
9803
+ var FNV1A_32_OFFSET = 2166136261;
9804
+ var FNV1A_32_PRIME = 16777619;
9805
+ var TAG_PREFIX = /^§\d+§\s*/;
9806
+ var DROP_PREFIXES = ["[dropped", "[truncated"];
9807
+ var CHANNEL1_REMINDER_OPEN = `
9808
+
9809
+ <system-reminder>
9810
+ `;
9811
+ var CHANNEL1_REMINDER_CLOSE = `
9812
+ </system-reminder>`;
9813
+ var TODO_HEAD_ANCHOR_ID = "__magic_context_todo_head__";
9814
+ function fnv1a32(value) {
9815
+ let hash = FNV1A_32_OFFSET;
9816
+ for (let index = 0;index < value.length; index += 1) {
9817
+ hash ^= value.charCodeAt(index);
9818
+ hash = Math.imul(hash, FNV1A_32_PRIME) >>> 0;
9819
+ }
9820
+ return hash.toString(16).padStart(8, "0");
9821
+ }
9822
+ function memoizedContent(kind, content) {
9823
+ const key = `${kind}\x00${content}`;
9824
+ const cached = contentMemo.get(key);
9825
+ if (cached)
9826
+ return cached;
9827
+ const measured = {
9828
+ hash: fnv1a32(key),
9829
+ tokens: kind === "excluded" ? 0 : estimateTokens(content),
9830
+ keyBytes: key.length * 2 + 32
9831
+ };
9832
+ contentMemo.set(key, measured);
9833
+ contentMemoBytes += measured.keyBytes;
9834
+ while (contentMemo.size > MAX_CONTENT_MEMO_ENTRIES || contentMemoBytes > MAX_CONTENT_MEMO_BYTES) {
9835
+ const oldest = contentMemo.keys().next().value;
9836
+ if (typeof oldest !== "string")
9837
+ break;
9838
+ const removed = contentMemo.get(oldest);
9839
+ if (removed)
9840
+ contentMemoBytes -= removed.keyBytes;
9841
+ contentMemo.delete(oldest);
9842
+ }
9843
+ return measured;
9844
+ }
9845
+ function safeStableStringify(value) {
9846
+ if (value === undefined || value === null)
9847
+ return "";
9848
+ if (typeof value === "string")
9849
+ return value;
9850
+ try {
9851
+ return stableStringify(value);
9852
+ } catch {
9853
+ return String(value);
9854
+ }
9855
+ }
9856
+ function firstString(record, fields) {
9857
+ for (const field of fields) {
9858
+ const value = record[field];
9859
+ if (typeof value === "string")
9860
+ return value;
9861
+ }
9862
+ return "";
9863
+ }
9864
+ function callIdFromPart(part) {
9865
+ const direct = firstString(part, ["callID", "callId", "toolCallId", "tool_call_id", "id"]);
9866
+ if (direct)
9867
+ return direct;
9868
+ const state2 = isRecord(part.state) ? part.state : null;
9869
+ return state2 ? firstString(state2, ["callID", "callId", "toolCallId", "tool_call_id", "id"]) : "";
9870
+ }
9871
+ function toolResultCallId(part) {
9872
+ return firstString(part, ["tool_use_id", "toolUseId", "callID", "callId"]);
9873
+ }
9874
+ function messageIdentity(message, messageIndex) {
9875
+ return typeof message.info.id === "string" ? message.info.id : `ordinal:${messageIndex}:${message.info.role ?? "unknown"}`;
9876
+ }
9877
+ function collectToolPartIdentities(messages) {
9878
+ const identities = new Map;
9879
+ const pendingOwners = new Map;
9880
+ for (let messageIndex = 0;messageIndex < messages.length; messageIndex += 1) {
9881
+ const message = messages[messageIndex];
9882
+ const currentOwner = messageIdentity(message, messageIndex);
9883
+ for (const part of message.parts) {
9884
+ if (!isRecord(part))
9885
+ continue;
9886
+ if (part.type === "tool-invocation" || part.type === "tool_use") {
9887
+ const callId = callIdFromPart(part);
9888
+ if (!callId)
9889
+ continue;
9890
+ const owners = pendingOwners.get(callId) ?? [];
9891
+ owners.push(currentOwner);
9892
+ pendingOwners.set(callId, owners);
9893
+ identities.set(part, {
9894
+ callId,
9895
+ ownerMessageId: currentOwner,
9896
+ messageIndex,
9897
+ kind: "invocation"
9898
+ });
9899
+ continue;
9900
+ }
9901
+ if (part.type === "tool_result") {
9902
+ const callId = toolResultCallId(part);
9903
+ if (!callId)
9904
+ continue;
9905
+ const owners = pendingOwners.get(callId);
9906
+ const ownerMessageId = owners?.shift() ?? currentOwner;
9907
+ identities.set(part, {
9908
+ callId,
9909
+ ownerMessageId,
9910
+ messageIndex,
9911
+ kind: "result"
9912
+ });
9913
+ continue;
9914
+ }
9915
+ if (part.type === "tool") {
9916
+ const callId = callIdFromPart(part);
9917
+ if (!callId)
9918
+ continue;
9919
+ identities.set(part, {
9920
+ callId,
9921
+ ownerMessageId: currentOwner,
9922
+ messageIndex,
9923
+ kind: "native"
9924
+ });
9925
+ }
9926
+ }
9927
+ }
9928
+ return identities;
9929
+ }
9930
+ function isSyntheticMessage(message) {
9931
+ const structuralHead = message.info.id === undefined && message.info.role === "user" && message.parts.length > 0 && message.parts.every((part) => isRecord(part) && part.synthetic === true);
9932
+ return structuralHead || message.info.summary === true || message.info.id === TODO_HEAD_ANCHOR_ID;
9933
+ }
9934
+ function isSyntheticPart(part) {
9935
+ return isRecord(part) && part.synthetic === true || isSyntheticTodoPart(part);
9936
+ }
9937
+ function stripChannel1ReminderSpans(output) {
9938
+ let stripped = output;
9939
+ while (stripped.endsWith(CHANNEL1_REMINDER_CLOSE)) {
9940
+ const opener = stripped.lastIndexOf(CHANNEL1_REMINDER_OPEN);
9941
+ if (opener < 0)
9942
+ break;
9943
+ stripped = stripped.slice(0, opener);
9944
+ }
9945
+ return stripped;
9946
+ }
9947
+ function isDropSentinel(content) {
9948
+ const stripped = content.trimStart().replace(TAG_PREFIX, "").trimStart().toLowerCase();
9949
+ return DROP_PREFIXES.some((prefix) => stripped.startsWith(prefix));
9950
+ }
9951
+ function toolOutputText(part) {
9952
+ if (part.type === "tool") {
9953
+ const state2 = isRecord(part.state) ? part.state : null;
9954
+ if (!state2)
9955
+ return null;
9956
+ if (state2.output !== undefined)
9957
+ return safeStableStringify(state2.output);
9958
+ if (state2.error !== undefined)
9959
+ return safeStableStringify(state2.error);
9960
+ if (state2.result !== undefined)
9961
+ return safeStableStringify(state2.result);
9962
+ return null;
9963
+ }
9964
+ if (part.type === "tool_result") {
9965
+ const value = part.content ?? part.output ?? part.result;
9966
+ return value === undefined ? null : safeStableStringify(value);
9967
+ }
9968
+ return null;
9969
+ }
9970
+ function toolInputText(part) {
9971
+ if (part.type === "tool") {
9972
+ const state2 = isRecord(part.state) ? part.state : null;
9973
+ if (!state2 || state2.input === undefined)
9974
+ return null;
9975
+ return safeStableStringify(state2.input);
9976
+ }
9977
+ if (part.type === "tool-invocation") {
9978
+ const value = part.args ?? part.input;
9979
+ return value === undefined ? null : safeStableStringify(value);
9980
+ }
9981
+ if (part.type === "tool_use") {
9982
+ return part.input === undefined ? null : safeStableStringify(part.input);
9983
+ }
9984
+ return null;
9985
+ }
9986
+ function messageIdForTag(tag) {
9987
+ if (tag.type === "tool")
9988
+ return tag.toolOwnerMessageId;
9989
+ return tag.messageId.replace(/:(?:p|file)\d+$/, "");
9990
+ }
9991
+ function protectedTagNumbers(tags, protectedTags) {
9992
+ const active = Array.from(new Set(tags.filter((tag) => tag.status === "active").map((tag) => tag.tagNumber))).sort((left, right) => right - left).slice(0, Math.max(0, protectedTags));
9993
+ const protectedNumbers = new Set(active);
9994
+ const protectedCtxReduceTags = newestCtxReduceTagNumbers(tags.filter((tag) => tag.status === "active" && tag.type === "tool"));
9995
+ for (const tagNumber of protectedCtxReduceTags)
9996
+ protectedNumbers.add(tagNumber);
9997
+ return protectedNumbers;
9998
+ }
9999
+ function neighborhoodConsistent(args) {
10000
+ let previousMax = null;
10001
+ for (let index = 0;index <= args.messageIndex; index += 1) {
10002
+ const bound = args.boundsByMessageIndex.get(index);
10003
+ if (bound)
10004
+ previousMax = previousMax === null ? bound.max : Math.max(previousMax, bound.max);
10005
+ }
10006
+ let nextMin = null;
10007
+ for (let index = args.messageIndex + 1;index < args.messageCount; index += 1) {
10008
+ const bound = args.boundsByMessageIndex.get(index);
10009
+ if (bound)
10010
+ nextMin = nextMin === null ? bound.min : Math.min(nextMin, bound.min);
10011
+ }
10012
+ if (previousMax === null || nextMin === null)
10013
+ return false;
10014
+ return args.orphanTagNumber >= previousMax && args.orphanTagNumber <= nextMin;
10015
+ }
10016
+ function buildTagAttribution(args) {
10017
+ const protectedNumbers = protectedTagNumbers(args.tags, args.protectedTags);
10018
+ const messageTags = new Map;
10019
+ const exactToolTags = new Map;
10020
+ const orphanTagsByCall = new Map;
10021
+ const messageIndexById = new Map;
10022
+ for (let index = 0;index < args.messages.length; index += 1) {
10023
+ const id = args.messages[index].info.id;
10024
+ if (typeof id === "string")
10025
+ messageIndexById.set(id, index);
10026
+ }
10027
+ const boundsByMessageIndex = new Map;
10028
+ for (const tag of args.tags) {
10029
+ if (tag.type === "tool") {
10030
+ if (tag.toolOwnerMessageId === null) {
10031
+ const rows = orphanTagsByCall.get(tag.messageId) ?? [];
10032
+ rows.push(tag);
10033
+ orphanTagsByCall.set(tag.messageId, rows);
10034
+ } else {
10035
+ exactToolTags.set(`${tag.toolOwnerMessageId}\x00${tag.messageId}`, tag);
10036
+ }
10037
+ } else {
10038
+ messageTags.set(tag.messageId, tag);
10039
+ }
10040
+ const ownerId = messageIdForTag(tag);
10041
+ const index = ownerId === null ? undefined : messageIndexById.get(ownerId);
10042
+ if (index === undefined)
10043
+ continue;
10044
+ const existing = boundsByMessageIndex.get(index);
10045
+ boundsByMessageIndex.set(index, {
10046
+ min: existing ? Math.min(existing.min, tag.tagNumber) : tag.tagNumber,
10047
+ max: existing ? Math.max(existing.max, tag.tagNumber) : tag.tagNumber
10048
+ });
10049
+ }
10050
+ const toolTagsByPart = new Map;
10051
+ const orphanCandidateOwners = new Map;
10052
+ for (const [part, identity] of args.toolIdentities) {
10053
+ const exact = exactToolTags.get(`${identity.ownerMessageId}\x00${identity.callId}`);
10054
+ if (exact) {
10055
+ toolTagsByPart.set(part, exact);
10056
+ continue;
10057
+ }
10058
+ const orphans = orphanTagsByCall.get(identity.callId);
10059
+ if (orphans?.length !== 1)
10060
+ continue;
10061
+ if (!neighborhoodConsistent({
10062
+ orphanTagNumber: orphans[0].tagNumber,
10063
+ messageIndex: identity.messageIndex,
10064
+ boundsByMessageIndex,
10065
+ messageCount: args.messages.length
10066
+ })) {
10067
+ continue;
10068
+ }
10069
+ const byOwner = orphanCandidateOwners.get(identity.callId) ?? new Map;
10070
+ const ownerParts = byOwner.get(identity.ownerMessageId) ?? [];
10071
+ ownerParts.push(identity);
10072
+ byOwner.set(identity.ownerMessageId, ownerParts);
10073
+ orphanCandidateOwners.set(identity.callId, byOwner);
10074
+ }
10075
+ for (const [callId, byOwner] of orphanCandidateOwners) {
10076
+ if (byOwner.size !== 1)
10077
+ continue;
10078
+ const orphan = orphanTagsByCall.get(callId)?.[0];
10079
+ if (!orphan)
10080
+ continue;
10081
+ const ownerId = byOwner.keys().next().value;
10082
+ if (typeof ownerId !== "string")
10083
+ continue;
10084
+ for (const [part, identity] of args.toolIdentities) {
10085
+ if (identity.callId === callId && identity.ownerMessageId === ownerId) {
10086
+ toolTagsByPart.set(part, orphan);
10087
+ }
10088
+ }
10089
+ }
10090
+ return { protectedNumbers, messageTags, toolTagsByPart };
10091
+ }
10092
+ function snapshot(args) {
10093
+ const memo = memoizedContent(args.kind, args.content);
10094
+ const tag = args.tag;
10095
+ const isProtected = tag ? args.protectedNumbers.has(tag.tagNumber) : false;
10096
+ const uTokens = tag?.status === "active" && !isProtected && args.kind !== "excluded" ? args.tokens : 0;
10097
+ return {
10098
+ key: args.key,
10099
+ contentHash: memo.hash,
10100
+ kind: args.kind,
10101
+ tokens: args.tokens,
10102
+ uTokens,
10103
+ tagNumber: tag?.tagNumber ?? null,
10104
+ tagStatus: tag?.status ?? null,
10105
+ protected: isProtected
10106
+ };
10107
+ }
10108
+ function excludedSnapshot(key, part) {
10109
+ const content = safeStableStringify(part);
10110
+ return snapshot({
10111
+ key,
10112
+ kind: "excluded",
10113
+ content,
10114
+ tokens: 0,
10115
+ tag: undefined,
10116
+ protectedNumbers: new Set
10117
+ });
10118
+ }
10119
+ function fileContentAndTokens(part) {
10120
+ const mime = typeof part.mime === "string" ? part.mime : "";
10121
+ const type = typeof part.type === "string" ? part.type.toLowerCase() : "";
10122
+ const url = typeof part.url === "string" ? part.url : "";
10123
+ if (mime.startsWith("image/") || type.includes("image")) {
10124
+ return {
10125
+ content: url,
10126
+ tokens: url.startsWith("data:") ? estimateImageTokensFromDataUrl(url) : 1200
10127
+ };
10128
+ }
10129
+ const content = firstString(part, ["content", "text", "source", "url"]);
10130
+ const memo = memoizedContent("file", content);
10131
+ return { content, tokens: memo.tokens };
10132
+ }
10133
+ function contentSignature(parts) {
10134
+ return fnv1a32(parts.map((part) => `${part.key}:${part.contentHash}`).join("\x00"));
10135
+ }
10136
+ function tailHygieneStructuralSignature(messages) {
10137
+ const partCounts = [];
10138
+ let totalBytes = 0;
10139
+ for (const message of messages) {
10140
+ partCounts.push(message.parts.length);
10141
+ totalBytes += byteSize(JSON.stringify(message) ?? "");
10142
+ }
10143
+ return { messageCount: messages.length, partCounts, totalBytes };
10144
+ }
10145
+ function sameTailHygieneStructuralSignature(expected, actual) {
10146
+ if (expected.messageCount !== actual.messageCount || expected.totalBytes !== actual.totalBytes || expected.partCounts.length !== actual.partCounts.length) {
10147
+ return false;
10148
+ }
10149
+ return expected.partCounts.every((count, index) => count === actual.partCounts[index]);
10150
+ }
10151
+ function measureTailHygiene(input) {
10152
+ const toolIdentities = collectToolPartIdentities(input.messages);
10153
+ const attribution = buildTagAttribution({
10154
+ messages: input.messages,
10155
+ tags: input.tags,
10156
+ toolIdentities,
10157
+ protectedTags: input.protectedTags
10158
+ });
10159
+ const droppedToolOwners = new Set;
10160
+ for (const [part, identity] of toolIdentities) {
10161
+ if (!isRecord(part))
10162
+ continue;
10163
+ const output = toolOutputText(part);
10164
+ if (output !== null && isDropSentinel(output)) {
10165
+ droppedToolOwners.add(`${identity.ownerMessageId}\x00${identity.callId}`);
10166
+ }
10167
+ }
10168
+ const parts = [];
10169
+ let t = 0;
10170
+ let u = 0;
10171
+ for (let messageIndex = 0;messageIndex < input.messages.length; messageIndex += 1) {
10172
+ const message = input.messages[messageIndex];
10173
+ const messageKey = messageIdentity(message, messageIndex);
10174
+ const messageSynthetic = isSyntheticMessage(message);
10175
+ for (let partIndex = 0;partIndex < message.parts.length; partIndex += 1) {
10176
+ const part = message.parts[partIndex];
10177
+ const key = `${messageKey}\x00${partIndex}`;
10178
+ if (messageSynthetic || isSyntheticPart(part) || !isRecord(part)) {
10179
+ parts.push(excludedSnapshot(`${key}\x00excluded`, part));
10180
+ continue;
10181
+ }
10182
+ const type = typeof part.type === "string" ? part.type : "";
10183
+ if (type === "reasoning" || type === "thinking" || type === "redacted_thinking" || type === "signature") {
10184
+ parts.push(excludedSnapshot(`${key}\x00excluded`, part));
10185
+ continue;
10186
+ }
10187
+ if (type === "text") {
10188
+ const content = firstString(part, ["text", "content"]);
10189
+ if (!content || isDropSentinel(content)) {
10190
+ parts.push(excludedSnapshot(`${key}\x00excluded`, part));
10191
+ continue;
10192
+ }
10193
+ const memo = memoizedContent("text", content);
10194
+ const tag = attribution.messageTags.get(`${message.info.id}:p${partIndex}`);
10195
+ const measured = snapshot({
10196
+ key: `${key}\x00text`,
10197
+ kind: "text",
10198
+ content,
10199
+ tokens: memo.tokens,
10200
+ tag,
10201
+ protectedNumbers: attribution.protectedNumbers
10202
+ });
10203
+ parts.push(measured);
10204
+ t += measured.tokens;
10205
+ u += measured.uTokens;
10206
+ continue;
10207
+ }
10208
+ if (type === "file" || type.includes("image") || type === "source") {
10209
+ const file = fileContentAndTokens(part);
10210
+ if (!file.content || isDropSentinel(file.content)) {
10211
+ parts.push(excludedSnapshot(`${key}\x00excluded`, part));
10212
+ continue;
10213
+ }
10214
+ const tag = attribution.messageTags.get(`${message.info.id}:file${partIndex}`);
10215
+ const measured = snapshot({
10216
+ key: `${key}\x00file`,
10217
+ kind: "file",
10218
+ content: file.content,
10219
+ tokens: file.tokens,
10220
+ tag,
10221
+ protectedNumbers: attribution.protectedNumbers
10222
+ });
10223
+ parts.push(measured);
10224
+ t += measured.tokens;
10225
+ u += measured.uTokens;
10226
+ continue;
10227
+ }
10228
+ const toolIdentity = toolIdentities.get(part);
10229
+ if (toolIdentity) {
10230
+ const ownerKey = `${toolIdentity.ownerMessageId}\x00${toolIdentity.callId}`;
10231
+ if (droppedToolOwners.has(ownerKey)) {
10232
+ parts.push(excludedSnapshot(`${key}\x00excluded`, part));
10233
+ continue;
10234
+ }
10235
+ const tag = attribution.toolTagsByPart.get(part);
10236
+ const inputText = toolInputText(part);
10237
+ if (inputText !== null) {
10238
+ const memo = memoizedContent("toolInput", inputText);
10239
+ const measured = snapshot({
10240
+ key: `${key}\x00toolInput`,
10241
+ kind: "toolInput",
10242
+ content: inputText,
10243
+ tokens: memo.tokens,
10244
+ tag,
10245
+ protectedNumbers: attribution.protectedNumbers
10246
+ });
10247
+ parts.push(measured);
10248
+ t += measured.tokens;
10249
+ u += measured.uTokens;
10250
+ }
10251
+ const rawOutput = toolOutputText(part);
10252
+ if (rawOutput !== null) {
10253
+ const output = stripChannel1ReminderSpans(rawOutput);
10254
+ if (isDropSentinel(output)) {
10255
+ parts.push(excludedSnapshot(`${key}\x00excludedOutput`, output));
10256
+ } else {
10257
+ const memo = memoizedContent("toolOutput", output);
10258
+ const measured = snapshot({
10259
+ key: `${key}\x00toolOutput`,
10260
+ kind: "toolOutput",
10261
+ content: output,
10262
+ tokens: memo.tokens,
10263
+ tag,
10264
+ protectedNumbers: attribution.protectedNumbers
10265
+ });
10266
+ parts.push(measured);
10267
+ t += measured.tokens;
10268
+ u += measured.uTokens;
10269
+ }
10270
+ }
10271
+ if (inputText === null && rawOutput === null) {
10272
+ parts.push(excludedSnapshot(`${key}\x00excluded`, part));
10273
+ }
10274
+ continue;
10275
+ }
10276
+ parts.push(excludedSnapshot(`${key}\x00excluded`, part));
10277
+ }
10278
+ }
10279
+ return {
10280
+ u: Math.min(Math.max(0, u), Math.max(0, t)),
10281
+ t: Math.max(0, t),
10282
+ contentSignature: contentSignature(parts),
10283
+ parts
10284
+ };
10285
+ }
10286
+ function sameMeasuredPrefix(baseline, current) {
10287
+ if (current.length < baseline.length)
10288
+ return { valid: false, boundaryAdvanceU: 0 };
10289
+ let boundaryAdvanceU = 0;
10290
+ for (let index = 0;index < baseline.length; index += 1) {
10291
+ const before = baseline[index];
10292
+ const after = current[index];
10293
+ if (before.key !== after.key || before.contentHash !== after.contentHash || before.kind !== after.kind || before.tokens !== after.tokens || before.tagNumber !== after.tagNumber || before.tagStatus !== after.tagStatus) {
10294
+ return { valid: false, boundaryAdvanceU: 0 };
10295
+ }
10296
+ if (!before.protected && after.protected)
10297
+ return { valid: false, boundaryAdvanceU: 0 };
10298
+ if (before.protected && !after.protected) {
10299
+ if (after.tagStatus !== "active")
10300
+ return { valid: false, boundaryAdvanceU: 0 };
10301
+ boundaryAdvanceU += after.tokens;
10302
+ } else if (before.uTokens !== after.uTokens) {
10303
+ return { valid: false, boundaryAdvanceU: 0 };
10304
+ }
10305
+ }
10306
+ return { valid: true, boundaryAdvanceU };
10307
+ }
10308
+ function refreshTailHygieneBaseline(input) {
10309
+ const measured = measureTailHygiene(input);
10310
+ const now = input.now ?? Date.now();
10311
+ if (!input.cacheBusting && input.previous?.generationInvalidated) {
10312
+ return { ...input.previous, contentSignature: measured.contentSignature };
10313
+ }
10314
+ if (input.cacheBusting || !input.previous) {
10315
+ return {
10316
+ baselineU: measured.u,
10317
+ baselineT: measured.t,
10318
+ turnDeltaU: 0,
10319
+ turnDeltaT: 0,
10320
+ baselineGeneration: (input.previous?.baselineGeneration ?? 0) + 1,
10321
+ computedAt: now,
10322
+ evaluable: true,
10323
+ generationInvalidated: false,
10324
+ baselineParts: measured.parts,
10325
+ contentSignature: measured.contentSignature
10326
+ };
10327
+ }
10328
+ const prefix = sameMeasuredPrefix(input.previous.baselineParts, measured.parts);
10329
+ if (!prefix.valid) {
10330
+ return {
10331
+ ...input.previous,
10332
+ evaluable: false,
10333
+ generationInvalidated: true,
10334
+ contentSignature: measured.contentSignature
10335
+ };
10336
+ }
10337
+ let turnDeltaT = 0;
10338
+ let turnDeltaU = prefix.boundaryAdvanceU;
10339
+ for (let index = input.previous.baselineParts.length;index < measured.parts.length; index += 1) {
10340
+ const part = measured.parts[index];
10341
+ turnDeltaT += part.tokens;
10342
+ if (part.kind !== "toolOutput")
10343
+ turnDeltaU += part.uTokens;
10344
+ }
10345
+ return {
10346
+ ...input.previous,
10347
+ turnDeltaU,
10348
+ turnDeltaT,
10349
+ evaluable: true,
10350
+ generationInvalidated: false,
10351
+ contentSignature: measured.contentSignature
10352
+ };
10353
+ }
10354
+ function effectiveTailHygiene(baseline) {
10355
+ const t = Math.max(0, baseline.baselineT + baseline.turnDeltaT);
10356
+ const u = Math.min(t, Math.max(0, baseline.baselineU + baseline.turnDeltaU));
10357
+ return { u, t };
10358
+ }
10359
+ function assertTailHygieneContentUnchanged(input) {
10360
+ const actual = measureTailHygiene(input).contentSignature;
10361
+ if (actual !== input.expectedSignature) {
10362
+ throw new Error(`tail hygiene walk was not the last byte-affecting operation: expected ${input.expectedSignature}, got ${actual}`);
10363
+ }
10364
+ }
10365
+
10366
+ // src/hooks/magic-context/ctx-reduce-nudge.ts
10367
+ var CHANNEL1_SENTINEL = "<system-reminder>";
10368
+ var TOKENS_PER_BYTE = 0.25;
10369
+ var CHANNEL1_MIN_TOKENS = 60000;
10370
+ var CHANNEL1_FLOOR_TOKENS = 25000;
10371
+ var CHANNEL1_REFIRE_FLOOR_TOKENS = 25000;
10372
+ var S_GENTLE = 0.2;
10373
+ var S_FIRM = 0.4;
10374
+ var S_URGENT = 0.6;
10375
+ var LEVEL_RANK = { gentle: 1, firm: 2, urgent: 3 };
10376
+ function channel1RefireTokens(tailTokens) {
10377
+ const scaled = Math.round(0.08 * Math.max(0, tailTokens));
10378
+ return Math.max(CHANNEL1_REFIRE_FLOOR_TOKENS, scaled);
10379
+ }
10380
+ function toolOutputTokens(output) {
10381
+ return estimateTokens(stripChannel1ReminderSpans(output));
10382
+ }
10383
+ function decideChannel1(input) {
10384
+ const tailTokens = Math.max(0, input.baselineT + input.turnDeltaT);
10385
+ const undroppedTokens = Math.min(tailTokens, Math.max(0, input.baselineU + input.turnDeltaU));
10386
+ const severity = Math.min(1, Math.max(0, undroppedTokens / Math.max(tailTokens, 1)));
10387
+ const resetCycle = input.hasRecentReduce || undroppedTokens < input.lastNudgeUndropped;
10388
+ const lastNudge = resetCycle ? 0 : input.lastNudgeUndropped;
10389
+ const lastLevel = resetCycle ? "" : input.lastNudgeLevel;
10390
+ const quiet = () => ({
10391
+ fire: false,
10392
+ level: "gentle",
10393
+ undroppedTokens,
10394
+ tailTokens,
10395
+ severity,
10396
+ nextLastNudge: lastNudge,
10397
+ nextLastNudgeLevel: lastLevel
10398
+ });
10399
+ if (input.evaluable === false || input.generationInvalidated === true)
10400
+ return quiet();
10401
+ if (input.hasRecentReduce)
10402
+ return quiet();
10403
+ if (tailTokens < CHANNEL1_MIN_TOKENS)
10404
+ return quiet();
10405
+ if (undroppedTokens < CHANNEL1_FLOOR_TOKENS || undroppedTokens === 0)
10406
+ return quiet();
10407
+ if (severity < S_GENTLE)
10408
+ return quiet();
10409
+ let level;
10410
+ if (severity >= S_URGENT)
10411
+ level = "urgent";
10412
+ else if (severity >= S_FIRM)
10413
+ level = "firm";
10414
+ else
10415
+ level = "gentle";
10416
+ const escalated = lastLevel === "" || LEVEL_RANK[level] > LEVEL_RANK[lastLevel];
10417
+ const cadenceReached = lastLevel !== "" && undroppedTokens - lastNudge >= channel1RefireTokens(tailTokens);
10418
+ if (!escalated && !cadenceReached)
10419
+ return quiet();
10420
+ return {
10421
+ fire: true,
10422
+ level,
10423
+ undroppedTokens,
10424
+ tailTokens,
10425
+ severity,
10426
+ nextLastNudge: undroppedTokens,
10427
+ nextLastNudgeLevel: level
10428
+ };
10429
+ }
10430
+ var CHANNEL2_SEVERITY_THRESHOLD = 0.75;
10431
+ var CHANNEL2_FLOOR_TOKENS = 50000;
10432
+ function evaluateChannel2(input) {
10433
+ const values = input ? [input.baselineU, input.baselineT, input.turnDeltaU, input.turnDeltaT] : [];
10434
+ if (input?.evaluable !== true || input.generationInvalidated === true || values.some((value) => !Number.isFinite(value))) {
10435
+ return {
10436
+ evaluable: false,
10437
+ shouldTrigger: false,
10438
+ reclaimableTokens: 0,
10439
+ tailTokens: 0,
10440
+ severity: 0
10441
+ };
10442
+ }
10443
+ const tailTokens = Math.max(0, input.baselineT + input.turnDeltaT);
10444
+ const reclaimableTokens = Math.min(tailTokens, Math.max(0, input.baselineU + input.turnDeltaU));
10445
+ const severity = Math.min(1, Math.max(0, reclaimableTokens / Math.max(tailTokens, 1)));
10446
+ return {
10447
+ evaluable: true,
10448
+ shouldTrigger: tailTokens >= CHANNEL1_MIN_TOKENS && reclaimableTokens >= CHANNEL2_FLOOR_TOKENS && severity >= CHANNEL2_SEVERITY_THRESHOLD,
10449
+ reclaimableTokens,
10450
+ tailTokens,
10451
+ severity
10452
+ };
10453
+ }
10454
+ function approxThousands(tokens) {
10455
+ return `${Math.round(tokens / 1000)}k`;
10456
+ }
10457
+ function formatOldestReclaimableHint(hint) {
10458
+ if (!hint || hint.length === 0)
10459
+ return "";
10460
+ const rendered = hint.slice(0, 4).map((tag) => `§${tag.tagNumber}§ ${tag.toolName ?? "tool"}`).join(" · ");
10461
+ return rendered.length > 0 ? `
10462
+ oldest reclaimable: ${rendered}.` : "";
10463
+ }
10464
+ function buildChannel2Reminder(undroppedTokens, hint) {
10465
+ const amount = approxThousands(undroppedTokens);
10466
+ const hintText = formatOldestReclaimableHint(hint);
10467
+ return `<system-reminder>
10468
+ ` + `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}
10469
+ ` + `</system-reminder>`;
10470
+ }
10471
+ function buildChannel1Reminder(level, undroppedTokens, hint) {
10472
+ const amount = approxThousands(undroppedTokens);
10473
+ const hintText = formatOldestReclaimableHint(hint);
10474
+ let body;
10475
+ switch (level) {
10476
+ case "gentle":
10477
+ 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.`;
10478
+ break;
10479
+ case "firm":
10480
+ 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.`;
10481
+ break;
10482
+ case "urgent":
10483
+ 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.`;
10484
+ break;
10485
+ }
10486
+ return `
10487
+
10488
+ <system-reminder>
10489
+ ${body}${hintText}
10490
+ </system-reminder>`;
10491
+ }
10492
+
10493
+ // src/hooks/magic-context/emergency-drop.ts
10494
+ var TARGET_FRACTION = 0.3;
10495
+ var TIER_RECENCY_RESERVE = 0.2;
10496
+ var EMERGENCY_REARM_MIN_TOKENS = 2000;
10497
+ var T1_TOOLS = new Set(["read", "todowrite", "task", "aft_outline", "aft_zoom"]);
10498
+ var T2_TOOLS = new Set(["edit", "write", "apply_patch", "grep", "glob", "aft_search"]);
10499
+ function normalizeToolName(toolName) {
10500
+ if (!toolName)
10501
+ return "";
10502
+ let name = toolName.toLowerCase();
10503
+ if (name.startsWith("mcp_"))
10504
+ name = name.slice(4);
10505
+ return name;
10506
+ }
10507
+ function resolveToolTier(toolName) {
10508
+ const name = normalizeToolName(toolName);
10509
+ if (T1_TOOLS.has(name))
10510
+ return 1;
10511
+ if (T2_TOOLS.has(name))
10512
+ return 2;
10513
+ return 3;
10514
+ }
10515
+ function tagReclaimBytes(tag) {
10516
+ return tag.byteSize + tag.inputByteSize + tag.reasoningByteSize;
10517
+ }
10518
+ function estimateEmergencyDropReclaimTokens(tag) {
10519
+ return Math.round(tagReclaimBytes(tag) * TOKENS_PER_BYTE);
10520
+ }
10521
+ function planEmergencyDrop(input) {
10522
+ const {
10523
+ tags,
10524
+ floorTags,
10525
+ maxTag,
10526
+ protectedTags,
10527
+ currentTotalInputTokens,
10528
+ ceilingTokens,
10529
+ priorInputSample,
10530
+ hasPriorDrop
10531
+ } = input;
10532
+ const noop = (reason) => ({
10533
+ shouldDrop: false,
10534
+ tagNumbers: [],
10535
+ reclaimTokens: 0,
10536
+ reason
10537
+ });
10538
+ if (!Number.isFinite(ceilingTokens) || ceilingTokens <= 0) {
10539
+ return noop("unknown-ceiling");
10540
+ }
10541
+ if (!Number.isFinite(currentTotalInputTokens) || currentTotalInputTokens <= 0) {
10542
+ return noop("unknown-usage");
10543
+ }
10544
+ if (hasPriorDrop && currentTotalInputTokens === priorInputSample) {
10545
+ return noop("same-input-sample (awaiting fresh usage after prior drop)");
10546
+ }
10547
+ let tailTokens = 0;
10548
+ for (const tag of floorTags) {
10549
+ if (tag.status !== "active")
10550
+ continue;
10551
+ tailTokens += estimateEmergencyDropReclaimTokens(tag);
10552
+ }
10553
+ const fixedFloor = Math.max(currentTotalInputTokens - tailTokens, 0);
10554
+ const workingSpan = Math.max(ceilingTokens - fixedFloor, 0);
10555
+ const target = fixedFloor + TARGET_FRACTION * workingSpan;
10556
+ const reclaimTokens = Math.round(currentTotalInputTokens - target);
10557
+ if (reclaimTokens <= EMERGENCY_REARM_MIN_TOKENS) {
10558
+ return noop(`reclaim<=min (${reclaimTokens} <= ${EMERGENCY_REARM_MIN_TOKENS})`);
10559
+ }
10560
+ const protectedCutoff = maxTag - protectedTags;
10561
+ const tierActive = { 1: [], 2: [] };
10562
+ for (const tag of tags) {
10563
+ if (tag.status !== "active" || tag.type !== "tool")
10564
+ continue;
10565
+ const tier = resolveToolTier(tag.toolName);
10566
+ if (tier === 1 || tier === 2)
10567
+ tierActive[tier].push(tag.tagNumber);
10568
+ }
10569
+ const reserved = new Set;
10570
+ for (const tier of [1, 2]) {
10571
+ const nums = tierActive[tier];
10572
+ if (nums.length === 0)
10573
+ continue;
10574
+ nums.sort((a, b) => b - a);
10575
+ const reserveCount = Math.ceil(TIER_RECENCY_RESERVE * nums.length);
10576
+ for (let i = 0;i < reserveCount && i < nums.length; i++) {
10577
+ reserved.add(nums[i]);
10578
+ }
10579
+ }
10580
+ const protectedCtxReduceTags = newestCtxReduceTagNumbers(floorTags.filter((tag) => tag.status === "active" && tag.type === "tool"));
10581
+ const byTier = { 1: [], 2: [], 3: [] };
10582
+ for (const tag of tags) {
10583
+ if (tag.status !== "active" || tag.type !== "tool")
10584
+ continue;
10585
+ if (tag.tagNumber > protectedCutoff)
10586
+ continue;
10587
+ if (protectedCtxReduceTags.has(tag.tagNumber))
10588
+ continue;
10589
+ const tier = resolveToolTier(tag.toolName);
10590
+ if ((tier === 1 || tier === 2) && reserved.has(tag.tagNumber))
10591
+ continue;
10592
+ byTier[tier].push(tag);
10593
+ }
10594
+ const selected = [];
10595
+ let reclaimed = 0;
10596
+ outer:
10597
+ for (const tier of [3, 2, 1]) {
10598
+ const group = byTier[tier];
10599
+ group.sort((a, b) => a.tagNumber - b.tagNumber);
10600
+ for (const tag of group) {
10601
+ selected.push(tag.tagNumber);
10602
+ reclaimed += estimateEmergencyDropReclaimTokens(tag);
10603
+ if (reclaimed >= reclaimTokens)
10604
+ break outer;
10605
+ }
10606
+ }
10607
+ if (selected.length === 0) {
10608
+ return noop("no-candidates");
10609
+ }
10610
+ return {
10611
+ shouldDrop: true,
10612
+ tagNumbers: selected,
10613
+ reclaimTokens,
10614
+ reason: `tiered drop: ${selected.length} tags, reclaim≈${reclaimed}/${reclaimTokens} tokens (floor≈${fixedFloor}, ceiling=${Math.round(ceilingTokens)})`
10615
+ };
10616
+ }
10617
+
9390
10618
  // src/features/magic-context/storage-tags.ts
9391
10619
  var insertTagStatements = new WeakMap;
9392
10620
  var updateTagStatusStatements = new WeakMap;
@@ -9430,32 +10658,23 @@ function ownerMessageIdForTagRow(row) {
9430
10658
  }
9431
10659
  return row.message_id.replace(CONTENT_ID_SUFFIX, "");
9432
10660
  }
9433
- function getActiveTagTokenAggregate(db, sessionId, protectedTags = 0) {
9434
- const toolOutputExpr = protectedTags > 0 ? `COALESCE(SUM(CASE WHEN type = 'tool' AND tag_number < (
9435
- SELECT tag_number FROM tags
9436
- WHERE session_id = ? AND status = 'active'
9437
- ORDER BY tag_number DESC LIMIT 1 OFFSET ?
9438
- ) THEN COALESCE(token_count, 0) ELSE 0 END), 0)` : `COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0)`;
9439
- const sql = `SELECT
9440
- COALESCE(SUM(CASE WHEN type != 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0)
9441
- + COALESCE(SUM(COALESCE(reasoning_token_count, 0)), 0) AS conversation,
9442
- COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) + COALESCE(input_token_count, 0) ELSE 0 END), 0) AS tool_call,
9443
- ${toolOutputExpr} AS tool_output,
9444
- COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
9445
- FROM tags
9446
- WHERE session_id = ? AND status = 'active'`;
9447
- const params = protectedTags > 0 ? [sessionId, protectedTags - 1, sessionId] : [sessionId];
9448
- const row = db.prepare(sql).get(...params);
9449
- return {
9450
- conversation: row?.conversation ?? 0,
9451
- toolCall: row?.tool_call ?? 0,
9452
- toolOutput: row?.tool_output ?? 0,
9453
- nullCount: row?.null_count ?? 0
9454
- };
9455
- }
9456
- var RECLAIM_HINT_EXCLUDED_TOOLS = ["todowrite"];
10661
+ var RECLAIM_HINT_EXCLUDED_TOOLS = new Set([
10662
+ "ask",
10663
+ "bash_kill",
10664
+ "bash_status",
10665
+ "board",
10666
+ "task",
10667
+ "todoread",
10668
+ "todowrite",
10669
+ "work"
10670
+ ]);
9457
10671
  var AGE_RECLAIM_MIN_TOKENS = 250;
9458
- var RECLAIM_HINT_EXCLUDED_LIST = RECLAIM_HINT_EXCLUDED_TOOLS.map((name) => `'${name.replace(/'/g, "''")}'`).join(", ");
10672
+ function isReclaimHintExcludedTool(toolName) {
10673
+ if (!toolName)
10674
+ return false;
10675
+ const normalized = toolName.toLowerCase().replace(/^mcp_/, "");
10676
+ return normalized.startsWith("ctx_") || RECLAIM_HINT_EXCLUDED_TOOLS.has(normalized);
10677
+ }
9459
10678
  function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, limit = 4) {
9460
10679
  if (limit <= 0)
9461
10680
  return [];
@@ -9465,24 +10684,21 @@ function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, li
9465
10684
  WHERE session_id = ? AND status = 'active'
9466
10685
  ORDER BY tag_number DESC LIMIT 1 OFFSET ?
9467
10686
  )` : "";
9468
- const excludeStateTools = RECLAIM_HINT_EXCLUDED_LIST ? `AND (tool_name IS NULL OR tool_name NOT IN (${RECLAIM_HINT_EXCLUDED_LIST}))` : "";
9469
10687
  const valueFloor = `AND (
9470
10688
  (token_count IS NULL AND input_token_count IS NULL)
9471
10689
  OR (COALESCE(token_count, 0) + COALESCE(input_token_count, 0)) >= ?
9472
10690
  )`;
9473
- const params = protectedTags > 0 ? [sessionId, AGE_RECLAIM_MIN_TOKENS, sessionId, protectedTags - 1, boundedLimit] : [sessionId, AGE_RECLAIM_MIN_TOKENS, boundedLimit];
10691
+ const params = protectedTags > 0 ? [sessionId, AGE_RECLAIM_MIN_TOKENS, sessionId, protectedTags - 1] : [sessionId, AGE_RECLAIM_MIN_TOKENS];
9474
10692
  const rows = db.prepare(`SELECT tag_number, tool_name
9475
10693
  FROM tags
9476
10694
  WHERE session_id = ? AND status = 'active' AND type = 'tool'
9477
- ${excludeStateTools}
9478
10695
  ${valueFloor}
9479
10696
  ${whereProtected}
9480
- ORDER BY tag_number ASC, id ASC
9481
- LIMIT ?`).all(...params);
10697
+ ORDER BY tag_number ASC, id ASC`).all(...params);
9482
10698
  return rows.filter((row) => typeof row.tag_number === "number").map((row) => ({
9483
10699
  tagNumber: row.tag_number,
9484
10700
  toolName: typeof row.tool_name === "string" ? row.tool_name : null
9485
- }));
10701
+ })).filter((tag) => !isReclaimHintExcludedTool(tag.toolName)).sort((left, right) => resolveToolTier(right.toolName) - resolveToolTier(left.toolName) || left.tagNumber - right.tagNumber).slice(0, boundedLimit);
9486
10702
  }
9487
10703
  var getActiveToolTagsForAgeReclaimStatements = new WeakMap;
9488
10704
  function getActiveToolTagsForAgeReclaim(db, sessionId) {
@@ -9495,7 +10711,7 @@ function getActiveToolTagsForAgeReclaim(db, sessionId) {
9495
10711
  getActiveToolTagsForAgeReclaimStatements.set(db, stmt);
9496
10712
  }
9497
10713
  const rows = stmt.all(sessionId);
9498
- return rows.filter((row) => typeof row.tag_number === "number").map((row) => {
10714
+ const tags = rows.filter((row) => typeof row.tag_number === "number").map((row) => {
9499
10715
  const outputTokens = typeof row.token_count === "number" ? row.token_count : null;
9500
10716
  const inputTokens = typeof row.input_token_count === "number" ? row.input_token_count : null;
9501
10717
  return {
@@ -9504,6 +10720,8 @@ function getActiveToolTagsForAgeReclaim(db, sessionId) {
9504
10720
  reclaimableTokens: outputTokens === null && inputTokens === null ? null : (outputTokens ?? 0) + (inputTokens ?? 0)
9505
10721
  };
9506
10722
  });
10723
+ const protectedCtxReduceTags = newestCtxReduceTagNumbers(tags);
10724
+ return tags.filter((tag) => !protectedCtxReduceTags.has(tag.tagNumber));
9507
10725
  }
9508
10726
  function getTriggerTagTokenUpperBound(db, sessionId, floor = 0) {
9509
10727
  const sql = floor > 0 ? `SELECT
@@ -9658,8 +10876,8 @@ function isMaxTagNumberRow(row) {
9658
10876
  function escapeLikePattern(value) {
9659
10877
  return value.replaceAll("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_");
9660
10878
  }
9661
- function insertTag(db, sessionId, messageId, type, byteSize, tagNumber, reasoningByteSize = 0, toolName = null, inputByteSize = 0, toolOwnerMessageId = null, entryFingerprint = null, tokenCounts = null) {
9662
- getInsertTagStatement(db).run(sessionId, messageId, type, byteSize, reasoningByteSize, tagNumber, toolName, inputByteSize, getHarness(), toolOwnerMessageId, entryFingerprint, tokenCounts?.tokenCount ?? null, tokenCounts?.inputTokenCount ?? null, tokenCounts?.reasoningTokenCount ?? null);
10879
+ function insertTag(db, sessionId, messageId, type, byteSize2, tagNumber, reasoningByteSize = 0, toolName = null, inputByteSize = 0, toolOwnerMessageId = null, entryFingerprint = null, tokenCounts = null) {
10880
+ getInsertTagStatement(db).run(sessionId, messageId, type, byteSize2, reasoningByteSize, tagNumber, toolName, inputByteSize, getHarness(), toolOwnerMessageId, entryFingerprint, tokenCounts?.tokenCount ?? null, tokenCounts?.inputTokenCount ?? null, tokenCounts?.reasoningTokenCount ?? null);
9663
10881
  return tagNumber;
9664
10882
  }
9665
10883
  function updateTagStatus(db, sessionId, tagId, status) {
@@ -9764,6 +10982,7 @@ function getTagsBySession(db, sessionId) {
9764
10982
  return rows.map(toTagEntry);
9765
10983
  }
9766
10984
  var getActiveTagsBySessionStatements = new WeakMap;
10985
+ var getNullOwnerToolTagsBySessionStatements = new WeakMap;
9767
10986
  var getDroppedTagsBySessionStatements = new WeakMap;
9768
10987
  var getMaxDroppedTagNumberStatements = new WeakMap;
9769
10988
  function getActiveTagsBySessionStatement(db) {
@@ -9794,6 +11013,24 @@ function getActiveTagsBySession(db, sessionId) {
9794
11013
  const rows = getActiveTagsBySessionStatement(db).all(sessionId).filter(isTagRow);
9795
11014
  return rows.map(toTagEntry);
9796
11015
  }
11016
+ function getTailHygieneTags(db, sessionId) {
11017
+ const active = getActiveTagsBySession(db, sessionId);
11018
+ let orphanStatement = getNullOwnerToolTagsBySessionStatements.get(db);
11019
+ if (!orphanStatement) {
11020
+ orphanStatement = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags
11021
+ WHERE session_id = ? AND type = 'tool' AND tool_owner_message_id IS NULL
11022
+ ORDER BY tag_number ASC, id ASC`);
11023
+ getNullOwnerToolTagsBySessionStatements.set(db, orphanStatement);
11024
+ }
11025
+ const seen = new Set(active.map((tag) => `${tag.tagNumber}\x00${tag.messageId}\x00${tag.type}`));
11026
+ for (const row of orphanStatement.all(sessionId).filter(isTagRow)) {
11027
+ const orphan = toTagEntry(row);
11028
+ const key = `${orphan.tagNumber}\x00${orphan.messageId}\x00${orphan.type}`;
11029
+ if (!seen.has(key))
11030
+ active.push(orphan);
11031
+ }
11032
+ return active;
11033
+ }
9797
11034
  function getDroppedTagsBySession(db, sessionId) {
9798
11035
  const rows = getDroppedTagsBySessionStatement(db).all(sessionId).filter(isTagRow);
9799
11036
  return rows.map(toTagEntry);
@@ -10184,7 +11421,7 @@ async function abortChildRun(client, sessionId) {
10184
11421
  try {
10185
11422
  await Promise.race([
10186
11423
  client.session.abort({ path: { id: sessionId } }),
10187
- new Promise((resolve) => setTimeout(resolve, ABORT_CALL_TIMEOUT_MS))
11424
+ new Promise((resolve2) => setTimeout(resolve2, ABORT_CALL_TIMEOUT_MS))
10188
11425
  ]);
10189
11426
  } catch (error) {
10190
11427
  log(`[model-retry] child session abort failed for ${sessionId}: ${String(error)}`);
@@ -10464,7 +11701,7 @@ function resolveModelConfigOrDefault(values, modelKey, fallback) {
10464
11701
  }
10465
11702
  // src/shared/prompt-surface-runtime.ts
10466
11703
  import { existsSync as existsSync5, readFileSync as readFileSync5, statSync as statSync5 } from "node:fs";
10467
- import { dirname as dirname3, isAbsolute as isAbsolute2, resolve } from "node:path";
11704
+ import { dirname as dirname3, isAbsolute as isAbsolute2, resolve as resolve2 } from "node:path";
10468
11705
 
10469
11706
  // src/config/migrate-config-location.ts
10470
11707
  import {
@@ -10875,7 +12112,7 @@ function promptSurfaceHashMaterial(systemContent, preset = "full") {
10875
12112
  var PROMPT_SURFACE_TOOL_ID_SET = new Set(ACTIVE_TOOL_IDS);
10876
12113
  function resolveUserConfigDirectory(options) {
10877
12114
  if (options.userConfigDirectory)
10878
- return resolve(options.userConfigDirectory);
12115
+ return resolve2(options.userConfigDirectory);
10879
12116
  const sharedBase = cortexKitUserConfigBasePath();
10880
12117
  const shared = detectConfigFile(sharedBase);
10881
12118
  if (shared.format !== "none")
@@ -10902,7 +12139,7 @@ function createPromptSurfaceRuntime(options) {
10902
12139
  const readGuidanceOverride = (configuredPath) => {
10903
12140
  if (!configuredPath)
10904
12141
  return;
10905
- const path3 = isAbsolute2(configuredPath) ? configuredPath : resolve(userConfigDirectory, configuredPath);
12142
+ const path3 = isAbsolute2(configuredPath) ? configuredPath : resolve2(userConfigDirectory, configuredPath);
10906
12143
  let content;
10907
12144
  try {
10908
12145
  if (!statSync5(path3).isFile()) {
@@ -11169,9 +12406,9 @@ function parseUserMemoryRow(row) {
11169
12406
  }
11170
12407
 
11171
12408
  // src/features/magic-context/mural/storage-mural-cues.ts
11172
- import { createHash as createHash8 } from "node:crypto";
12409
+ import { createHash as createHash9 } from "node:crypto";
11173
12410
  function computeCueContentHash(content) {
11174
- return createHash8("sha256").update(content).digest("hex");
12411
+ return createHash9("sha256").update(content).digest("hex");
11175
12412
  }
11176
12413
  var muralCueColumnCache = new WeakMap;
11177
12414
  var muralCueRejectionColumnCache = new WeakMap;
@@ -11369,13 +12606,13 @@ function invalidateMemory(projectPath, memoryId) {
11369
12606
  }
11370
12607
 
11371
12608
  // src/features/magic-context/memory/normalize-hash.ts
11372
- import { createHash as createHash9 } from "node:crypto";
12609
+ import { createHash as createHash10 } from "node:crypto";
11373
12610
  function normalizeMemoryContent(content) {
11374
12611
  return content.toLowerCase().replace(/\s+/g, " ").trim();
11375
12612
  }
11376
12613
  function computeNormalizedHash(content) {
11377
12614
  const normalized = normalizeMemoryContent(content);
11378
- return createHash9("md5").update(normalized).digest("hex");
12615
+ return createHash10("md5").update(normalized).digest("hex");
11379
12616
  }
11380
12617
 
11381
12618
  // src/features/magic-context/memory/visibility.ts
@@ -12344,7 +13581,7 @@ async function runMemoryMigration(deps) {
12344
13581
  }
12345
13582
 
12346
13583
  // src/features/magic-context/compartment-chunk-embedding.ts
12347
- import { createHash as createHash10 } from "node:crypto";
13584
+ import { createHash as createHash11 } from "node:crypto";
12348
13585
 
12349
13586
  // src/features/magic-context/recursive-text-splitter.ts
12350
13587
  var DEFAULT_SEPARATORS = [`
@@ -12629,7 +13866,7 @@ function parseCanonicalLineRange(line) {
12629
13866
  return { start, end };
12630
13867
  }
12631
13868
  function hashChunkText(text) {
12632
- return createHash10("sha256").update(text).digest("hex");
13869
+ return createHash11("sha256").update(text).digest("hex");
12633
13870
  }
12634
13871
  function vectorBlob2(vector) {
12635
13872
  return new Uint8Array(vector.buffer, vector.byteOffset, vector.byteLength);
@@ -13020,7 +14257,7 @@ function countSessionCompartmentEmbedCoverage(db, projectPath, sessionId, modelI
13020
14257
  }
13021
14258
 
13022
14259
  // src/features/magic-context/project-embedding-registry.ts
13023
- import { createHash as createHash12, randomUUID as randomUUID2 } from "node:crypto";
14260
+ import { createHash as createHash13, randomUUID as randomUUID2 } from "node:crypto";
13024
14261
 
13025
14262
  // src/config/schema/magic-context.ts
13026
14263
  import { homedir as homedir3 } from "node:os";
@@ -27686,7 +28923,7 @@ var MagicContextConfigSchema = exports_external.object({
27686
28923
  output_reserve: exports_external.union([
27687
28924
  exports_external.number().min(0),
27688
28925
  exports_external.object({ default: exports_external.number().min(0) }).catchall(exports_external.number().min(0))
27689
- ]).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.'),
28926
+ ]).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.'),
27690
28927
  models: exports_external.object({
27691
28928
  window_overlay_path: exports_external.string().trim().min(1).optional()
27692
28929
  }).optional().describe("User-only Fusiform window-overlay settings. The path defaults to <dataDir>/fusiform/window-overlay.json."),
@@ -27741,7 +28978,7 @@ var MagicContextConfigSchema = exports_external.object({
27741
28978
  overlay: exports_external.boolean().default(true).describe("Pi only: show the persistent todo overlay above the editor while tasks are active.")
27742
28979
  }).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."),
27743
28980
  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."),
27744
- 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."),
28981
+ 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."),
27745
28982
  caveman_text_compression: exports_external.object({
27746
28983
  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%)."),
27747
28984
  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.")
@@ -28093,7 +29330,7 @@ function releaseGitSweepLease(db, projectPath, holderId) {
28093
29330
  }
28094
29331
 
28095
29332
  // src/features/magic-context/memory/embedding-synapse.ts
28096
- import { createHash as createHash11 } from "node:crypto";
29333
+ import { createHash as createHash12 } from "node:crypto";
28097
29334
 
28098
29335
  // ../../node_modules/.bun/@cortexkit+subc-client@0.4.1/node_modules/@cortexkit/subc-client/dist/client.js
28099
29336
  import { promises as fs2 } from "node:fs";
@@ -28467,7 +29704,7 @@ class SubcSocket {
28467
29704
  return this.sock.localPort ?? null;
28468
29705
  }
28469
29706
  static connect(host, port, deadlineMs) {
28470
- return new Promise((resolve2, reject) => {
29707
+ return new Promise((resolve3, reject) => {
28471
29708
  const sock = net.connect({ host, port });
28472
29709
  sock.setNoDelay(true);
28473
29710
  const timer = setTimeout(() => {
@@ -28476,7 +29713,7 @@ class SubcSocket {
28476
29713
  }, Math.max(0, deadlineMs - Date.now()));
28477
29714
  sock.once("connect", () => {
28478
29715
  clearTimeout(timer);
28479
- resolve2(new SubcSocket(sock));
29716
+ resolve3(new SubcSocket(sock));
28480
29717
  });
28481
29718
  sock.once("error", (err) => {
28482
29719
  clearTimeout(timer);
@@ -28508,7 +29745,7 @@ class SubcSocket {
28508
29745
  }
28509
29746
  if (n === 0)
28510
29747
  return Promise.resolve(new Uint8Array(0));
28511
- return new Promise((resolve2, reject) => {
29748
+ return new Promise((resolve3, reject) => {
28512
29749
  let timer = null;
28513
29750
  if (Number.isFinite(deadlineMs)) {
28514
29751
  const remaining = deadlineMs - Date.now();
@@ -28521,7 +29758,7 @@ class SubcSocket {
28521
29758
  reject(new SocketTimeoutError(`timed out waiting for ${n} bytes`));
28522
29759
  }, remaining);
28523
29760
  }
28524
- this.waiter = { need: n, resolve: resolve2, reject, timer };
29761
+ this.waiter = { need: n, resolve: resolve3, reject, timer };
28525
29762
  this.tryServe();
28526
29763
  });
28527
29764
  }
@@ -28545,7 +29782,7 @@ class SubcSocket {
28545
29782
  let queued = false;
28546
29783
  let settled = false;
28547
29784
  let timer = null;
28548
- const completed = new Promise((resolve2, reject) => {
29785
+ const completed = new Promise((resolve3, reject) => {
28549
29786
  const settle = (run) => {
28550
29787
  if (settled)
28551
29788
  return;
@@ -28569,7 +29806,7 @@ class SubcSocket {
28569
29806
  if (err) {
28570
29807
  reject(new SocketWriteQueuedError("subc socket reported a write error after bytes were handed to the socket", err instanceof Error ? err : new Error(String(err))));
28571
29808
  } else {
28572
- resolve2();
29809
+ resolve3();
28573
29810
  }
28574
29811
  });
28575
29812
  });
@@ -28785,14 +30022,14 @@ class SubcClient {
28785
30022
  const admission = opts.admissionClass ?? AdmissionClass.Normal;
28786
30023
  const corr = this.allocateCorr();
28787
30024
  const key = pendingKey(handle, corr);
28788
- const closed = new Promise((resolve2, reject) => {
30025
+ const closed = new Promise((resolve3, reject) => {
28789
30026
  if (this.closedErr) {
28790
30027
  reject(this.closedErr);
28791
30028
  return;
28792
30029
  }
28793
30030
  this.pending.set(key, {
28794
30031
  handle,
28795
- resolve: () => resolve2(),
30032
+ resolve: () => resolve3(),
28796
30033
  reject,
28797
30034
  onProgress: onEvent,
28798
30035
  timer: null,
@@ -28877,11 +30114,11 @@ class SubcClient {
28877
30114
  const waiters = [];
28878
30115
  for (const pending of this.pending.values()) {
28879
30116
  if (pending.handle === handle && !pending.subscription) {
28880
- waiters.push(new Promise((resolve2) => {
30117
+ waiters.push(new Promise((resolve3) => {
28881
30118
  const previous = pending.onSettle;
28882
30119
  pending.onSettle = () => {
28883
30120
  previous?.();
28884
- resolve2();
30121
+ resolve3();
28885
30122
  };
28886
30123
  }));
28887
30124
  }
@@ -28937,11 +30174,11 @@ class SubcClient {
28937
30174
  const channel = handle?.channel ?? 0;
28938
30175
  const epoch = handle?.epoch ?? 0;
28939
30176
  const frame = buildFrame(FrameType.Request, buildFlags(false, priority, false, admission), channel, epoch, corr, body);
28940
- return new Promise((resolve2, reject) => {
30177
+ return new Promise((resolve3, reject) => {
28941
30178
  const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
28942
30179
  const pending = {
28943
30180
  handle,
28944
- resolve: resolve2,
30181
+ resolve: resolve3,
28945
30182
  reject,
28946
30183
  onProgress,
28947
30184
  timer: null,
@@ -29015,11 +30252,11 @@ class SubcClient {
29015
30252
  }
29016
30253
  return this.outcomeUnknownCallError("connection dropped before the managed call returned a response", error51);
29017
30254
  };
29018
- return new Promise((resolve2, reject) => {
30255
+ return new Promise((resolve3, reject) => {
29019
30256
  const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
29020
30257
  const pending = {
29021
30258
  handle,
29022
- resolve: resolve2,
30259
+ resolve: resolve3,
29023
30260
  reject,
29024
30261
  onProgress,
29025
30262
  timer: null,
@@ -29407,7 +30644,7 @@ function normalizeConnectOptions(opts) {
29407
30644
  identity: opts.identity,
29408
30645
  targetKind: opts.targetKind ?? DEFAULT_MANAGED_TARGET_KIND,
29409
30646
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
29410
- sleep: opts.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms))),
30647
+ sleep: opts.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms))),
29411
30648
  timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS
29412
30649
  };
29413
30650
  }
@@ -29464,8 +30701,8 @@ class AsyncPermitPool {
29464
30701
  this.available -= 1;
29465
30702
  return this.releaseOnce();
29466
30703
  }
29467
- await new Promise((resolve2) => {
29468
- this.waiters.push(resolve2);
30704
+ await new Promise((resolve3) => {
30705
+ this.waiters.push(resolve3);
29469
30706
  });
29470
30707
  return this.releaseOnce();
29471
30708
  }
@@ -29521,8 +30758,8 @@ class SubcProvider {
29521
30758
  this.currentConn = currentConn;
29522
30759
  this.opts = opts;
29523
30760
  this.storage = storage;
29524
- this.closed = new Promise((resolve2) => {
29525
- this.resolveClosed = resolve2;
30761
+ this.closed = new Promise((resolve3) => {
30762
+ this.resolveClosed = resolve3;
29526
30763
  });
29527
30764
  this.readLoop(sock, this.generation);
29528
30765
  this.enqueueConnectionState({ state: "connected", epoch: this.connectionEpoch });
@@ -29542,13 +30779,13 @@ class SubcProvider {
29542
30779
  const key = routeKey(handle, corr);
29543
30780
  const timeoutMs = opts.timeoutMs ?? WRITE_TIMEOUT_MS;
29544
30781
  const frame = buildFrame(FrameType.Request, buildFlags(false, opts.priority ?? Priority.Interactive, false, opts.admissionClass ?? AdmissionClass.Normal), handle.channel, handle.epoch, corr, body);
29545
- return await new Promise((resolve2, reject) => {
30782
+ return await new Promise((resolve3, reject) => {
29546
30783
  const timer = setTimeout(() => {
29547
30784
  if (this.pending.delete(key))
29548
30785
  reject(new SubcProviderError("reverse request timed out", "request_timeout"));
29549
30786
  }, timeoutMs);
29550
30787
  this.pending.set(key, {
29551
- resolve: (response) => resolve2(response.body),
30788
+ resolve: (response) => resolve3(response.body),
29552
30789
  reject,
29553
30790
  timer
29554
30791
  });
@@ -30020,7 +31257,7 @@ function normalizeProviderConnectOptions(opts) {
30020
31257
  onBound: opts.onBound,
30021
31258
  onRouteGone: opts.onRouteGone,
30022
31259
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
30023
- sleep: opts.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms))),
31260
+ sleep: opts.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms))),
30024
31261
  restoredDebounceMs: opts.restoredDebounceMs ?? DEFAULT_RESTORED_DEBOUNCE_MS,
30025
31262
  onConnectionState: opts.onConnectionState,
30026
31263
  launchNonce: opts.launchNonce
@@ -30065,7 +31302,7 @@ function errorCode2(err) {
30065
31302
  return;
30066
31303
  }
30067
31304
  async function pauseBeforeStateRetry() {
30068
- await new Promise((resolve2) => setTimeout(resolve2, 0));
31305
+ await new Promise((resolve3) => setTimeout(resolve3, 0));
30069
31306
  }
30070
31307
  function controlFlags() {
30071
31308
  return buildFlags(false, Priority.Passive, false);
@@ -30303,10 +31540,10 @@ function classifyError(value) {
30303
31540
  });
30304
31541
  }
30305
31542
  function wait(ms) {
30306
- return new Promise((resolve2) => setTimeout(resolve2, ms));
31543
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
30307
31544
  }
30308
31545
  function sha256(value) {
30309
- return createHash11("sha256").update(value).digest("hex");
31546
+ return createHash12("sha256").update(value).digest("hex");
30310
31547
  }
30311
31548
  function stableJson(value) {
30312
31549
  if (Array.isArray(value))
@@ -30812,7 +32049,7 @@ async function acquireModelLoadLock(lockPath) {
30812
32049
  if (Date.now() - waitStart > MAX_LOCK_WAIT_MS) {
30813
32050
  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.`);
30814
32051
  }
30815
- await new Promise((resolve2) => setTimeout(resolve2, LOCK_POLL_MS));
32052
+ await new Promise((resolve3) => setTimeout(resolve3, LOCK_POLL_MS));
30816
32053
  }
30817
32054
  }
30818
32055
  }
@@ -31017,7 +32254,7 @@ class LocalEmbeddingProvider {
31017
32254
  }
31018
32255
  const delayMs = 300 * attempt + Math.floor(Math.random() * 200);
31019
32256
  log(`[magic-context] embedding model load attempt ${attempt}/${MAX_ATTEMPTS} failed transiently, retrying in ${delayMs}ms`);
31020
- await new Promise((resolve2) => setTimeout(resolve2, delayMs));
32257
+ await new Promise((resolve3) => setTimeout(resolve3, delayMs));
31021
32258
  }
31022
32259
  }
31023
32260
  if (this.pipeline) {
@@ -31050,8 +32287,8 @@ class LocalEmbeddingProvider {
31050
32287
  if (this.inFlight === 0) {
31051
32288
  return Promise.resolve();
31052
32289
  }
31053
- return new Promise((resolve2) => {
31054
- this.inFlightWaiters.push(resolve2);
32290
+ return new Promise((resolve3) => {
32291
+ this.inFlightWaiters.push(resolve3);
31055
32292
  });
31056
32293
  }
31057
32294
  finishInFlight() {
@@ -31754,10 +32991,10 @@ function stableStringify2(value) {
31754
32991
  return JSON.stringify(value);
31755
32992
  }
31756
32993
  function sha256Prefix(value, length = 16) {
31757
- return createHash12("sha256").update(value).digest("hex").slice(0, length);
32994
+ return createHash13("sha256").update(value).digest("hex").slice(0, length);
31758
32995
  }
31759
32996
  function contentSha256(value) {
31760
- return createHash12("sha256").update(value).digest("hex");
32997
+ return createHash13("sha256").update(value).digest("hex");
31761
32998
  }
31762
32999
  function getRuntimeFingerprint(config2) {
31763
33000
  if (config2.provider === "off") {
@@ -31957,14 +33194,14 @@ function hasStaleEmbeddingRows(db, scope, projectIdentity, modelId) {
31957
33194
  LIMIT 1`).get(projectIdentity, modelId));
31958
33195
  }
31959
33196
  function sweepStaleEmbeddingIdentitiesForProject(db, projectIdentity, now = Date.now()) {
31960
- const snapshot = getProjectEmbeddingSnapshot(projectIdentity);
33197
+ const snapshot2 = getProjectEmbeddingSnapshot(projectIdentity);
31961
33198
  const result = {
31962
33199
  memoryRowsDeleted: 0,
31963
33200
  commitRowsDeleted: 0,
31964
33201
  chunkRowsDeleted: 0,
31965
33202
  trackingRowsDeleted: 0
31966
33203
  };
31967
- if (!snapshot)
33204
+ if (!snapshot2)
31968
33205
  return result;
31969
33206
  if (untrustedLoadProjects.has(projectIdentity))
31970
33207
  return result;
@@ -31972,25 +33209,25 @@ function sweepStaleEmbeddingIdentitiesForProject(db, projectIdentity, now = Date
31972
33209
  const deleteTracking = getDeleteActiveIdentityStatement(db);
31973
33210
  const shadow = shadowRegistrations.get(projectIdentity);
31974
33211
  const protectedModels = {
31975
- memory: new Set([snapshot.modelId, ...shadow ? [shadow.modelId] : []]),
31976
- commit: new Set([snapshot.modelId, ...shadow ? [shadow.modelId] : []]),
31977
- chunk: new Set([snapshot.chunkModelId, ...shadow ? [shadow.chunkModelId] : []])
33212
+ memory: new Set([snapshot2.modelId, ...shadow ? [shadow.modelId] : []]),
33213
+ commit: new Set([snapshot2.modelId, ...shadow ? [shadow.modelId] : []]),
33214
+ chunk: new Set([snapshot2.chunkModelId, ...shadow ? [shadow.chunkModelId] : []])
31978
33215
  };
31979
33216
  const scopes = [
31980
33217
  {
31981
33218
  scope: "memory",
31982
- enabled: snapshot.enabled && snapshot.modelId !== "off",
31983
- currentModelId: snapshot.modelId
33219
+ enabled: snapshot2.enabled && snapshot2.modelId !== "off",
33220
+ currentModelId: snapshot2.modelId
31984
33221
  },
31985
33222
  {
31986
33223
  scope: "commit",
31987
- enabled: snapshot.gitCommitEnabled && snapshot.modelId !== "off",
31988
- currentModelId: snapshot.modelId
33224
+ enabled: snapshot2.gitCommitEnabled && snapshot2.modelId !== "off",
33225
+ currentModelId: snapshot2.modelId
31989
33226
  },
31990
33227
  {
31991
33228
  scope: "chunk",
31992
- enabled: snapshot.enabled && snapshot.chunkModelId !== "off",
31993
- currentModelId: snapshot.chunkModelId
33229
+ enabled: snapshot2.enabled && snapshot2.chunkModelId !== "off",
33230
+ currentModelId: snapshot2.chunkModelId
31994
33231
  }
31995
33232
  ];
31996
33233
  let remainingBudget = STALE_EMBEDDING_GC_BATCH_SIZE;
@@ -32446,7 +33683,7 @@ async function runShadowWorker() {
32446
33683
  }
32447
33684
  processed += item.ids.length;
32448
33685
  processedBytes += itemBytes;
32449
- await new Promise((resolve2) => setTimeout(resolve2, 0));
33686
+ await new Promise((resolve3) => setTimeout(resolve3, 0));
32450
33687
  }
32451
33688
  }
32452
33689
  function registerProjectInObservationMode(db, projectIdentity, sourceDirectory, failedConfig, failureSummary) {
@@ -32629,11 +33866,11 @@ function getLoadUnembeddedMemoriesStatement(db) {
32629
33866
  return stmt;
32630
33867
  }
32631
33868
  async function embedUnembeddedMemoriesForProject(db, projectIdentity, batchSize = 10) {
32632
- const snapshot = getProjectEmbeddingSnapshot(projectIdentity);
32633
- if (!snapshot?.enabled)
33869
+ const snapshot2 = getProjectEmbeddingSnapshot(projectIdentity);
33870
+ if (!snapshot2?.enabled)
32634
33871
  return 0;
32635
33872
  const normalizedBatchSize = Math.max(1, Math.floor(batchSize));
32636
- const memories = getLoadUnembeddedMemoriesStatement(db).all(snapshot.modelId, projectIdentity, normalizedBatchSize).filter(isUnembeddedMemoryRow);
33873
+ const memories = getLoadUnembeddedMemoriesStatement(db).all(snapshot2.modelId, projectIdentity, normalizedBatchSize).filter(isUnembeddedMemoryRow);
32637
33874
  if (memories.length === 0)
32638
33875
  return 0;
32639
33876
  try {
@@ -32663,10 +33900,10 @@ async function embedUnembeddedMemoriesForProject(db, projectIdentity, batchSize
32663
33900
  }
32664
33901
  }
32665
33902
  async function embedCommitBatch(db, projectIdentity, batchSize) {
32666
- const snapshot = getProjectEmbeddingSnapshot(projectIdentity);
32667
- if (!snapshot?.gitCommitEnabled)
33903
+ const snapshot2 = getProjectEmbeddingSnapshot(projectIdentity);
33904
+ if (!snapshot2?.gitCommitEnabled)
32668
33905
  return 0;
32669
- const commits = loadUnembeddedCommits(db, projectIdentity, snapshot.modelId, Math.max(1, Math.floor(batchSize)));
33906
+ const commits = loadUnembeddedCommits(db, projectIdentity, snapshot2.modelId, Math.max(1, Math.floor(batchSize)));
32670
33907
  if (commits.length === 0)
32671
33908
  return 0;
32672
33909
  const result = await embedItemsForProject(projectIdentity, commits.map((commit) => ({
@@ -32690,8 +33927,8 @@ async function embedCommitBatch(db, projectIdentity, batchSize) {
32690
33927
  return embeddedCount;
32691
33928
  }
32692
33929
  async function drainCommitBacklogForProject(db, projectIdentity, deadline) {
32693
- const snapshot = getProjectEmbeddingSnapshot(projectIdentity);
32694
- if (!snapshot?.gitCommitEnabled)
33930
+ const snapshot2 = getProjectEmbeddingSnapshot(projectIdentity);
33931
+ if (!snapshot2?.gitCommitEnabled)
32695
33932
  return 0;
32696
33933
  const holderId = `embed-sweep-${randomUUID2()}`;
32697
33934
  const lease = acquireGitSweepLease(db, projectIdentity, holderId, { ignoreCooldown: true });
@@ -32807,7 +34044,7 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
32807
34044
  if (Date.now() - attemptStart >= EMBED_SLOW_FAILURE_NO_RETRY_MS)
32808
34045
  break;
32809
34046
  if (attempt < EMBED_SLICE_RETRY_ATTEMPTS - 1) {
32810
- await new Promise((resolve2) => setTimeout(resolve2, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
34047
+ await new Promise((resolve3) => setTimeout(resolve3, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
32811
34048
  }
32812
34049
  }
32813
34050
  embedded += persistedIds.size;
@@ -32821,12 +34058,12 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
32821
34058
  return { embedded, noWork, failed };
32822
34059
  }
32823
34060
  async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, options) {
32824
- const snapshot = getProjectEmbeddingSnapshot(projectIdentity);
32825
- if (!snapshot?.enabled || snapshot.chunkModelId === "off") {
34061
+ const snapshot2 = getProjectEmbeddingSnapshot(projectIdentity);
34062
+ if (!snapshot2?.enabled || snapshot2.chunkModelId === "off") {
32826
34063
  return { status: "disabled", embedded: 0, total: 0 };
32827
34064
  }
32828
34065
  recordSessionProjectIdentity(db, sessionId, projectIdentity);
32829
- const total = countUnembeddedSessionCompartments(db, projectIdentity, sessionId, snapshot.chunkModelId);
34066
+ const total = countUnembeddedSessionCompartments(db, projectIdentity, sessionId, snapshot2.chunkModelId);
32830
34067
  if (total === 0)
32831
34068
  return { status: "nothing", embedded: 0, total: 0 };
32832
34069
  const holderId = `session-embed-${randomUUID2()}`;
@@ -32863,14 +34100,14 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
32863
34100
  aborted2 = true;
32864
34101
  break;
32865
34102
  }
32866
- const candidates = loadUnembeddedSessionChunkCandidates(db, projectIdentity, sessionId, snapshot.chunkModelId, batchSize, [...skipIds, ...failedIds]);
34103
+ const candidates = loadUnembeddedSessionChunkCandidates(db, projectIdentity, sessionId, snapshot2.chunkModelId, batchSize, [...skipIds, ...failedIds]);
32867
34104
  if (candidates.length === 0)
32868
34105
  break;
32869
34106
  const {
32870
34107
  embedded: n,
32871
34108
  noWork,
32872
34109
  failed
32873
- } = await embedCandidateChunkBatch(db, projectIdentity, snapshot.chunkModelId, candidates, drainAbort.signal);
34110
+ } = await embedCandidateChunkBatch(db, projectIdentity, snapshot2.chunkModelId, candidates, drainAbort.signal);
32874
34111
  if (leaseLost || !renewGitSweepLease(db, projectIdentity, holderId)) {
32875
34112
  leaseLost = true;
32876
34113
  drainAbort.abort();
@@ -32892,7 +34129,7 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
32892
34129
  }
32893
34130
  embedded += n;
32894
34131
  options?.onProgress?.({ embedded: Math.min(embedded, total), total });
32895
- await new Promise((resolve2) => setTimeout(resolve2, 0));
34132
+ await new Promise((resolve3) => setTimeout(resolve3, 0));
32896
34133
  }
32897
34134
  } finally {
32898
34135
  clearInterval(renewal);
@@ -32906,7 +34143,7 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
32906
34143
  if (aborted2)
32907
34144
  return { status: "aborted", embedded, total, failed: failedIds.length };
32908
34145
  if (providerDown || failedIds.length > 0) {
32909
- const remaining = Math.max(0, countUnembeddedSessionCompartments(db, projectIdentity, sessionId, snapshot.chunkModelId) - skipIds.length);
34146
+ const remaining = Math.max(0, countUnembeddedSessionCompartments(db, projectIdentity, sessionId, snapshot2.chunkModelId) - skipIds.length);
32910
34147
  if (remaining > 0) {
32911
34148
  return { status: "stalled", embedded, total, remaining, failed: failedIds.length };
32912
34149
  }
@@ -32914,29 +34151,29 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
32914
34151
  return { status: "done", embedded, total, failed: failedIds.length };
32915
34152
  }
32916
34153
  function getEmbeddingCoverageStatus(db, projectIdentity, sessionId) {
32917
- const snapshot = getProjectEmbeddingSnapshot(projectIdentity);
32918
- if (!snapshot?.enabled || snapshot.chunkModelId === "off") {
34154
+ const snapshot2 = getProjectEmbeddingSnapshot(projectIdentity);
34155
+ if (!snapshot2?.enabled || snapshot2.chunkModelId === "off") {
32919
34156
  return {
32920
34157
  enabled: false,
32921
- model: snapshot?.model ?? "off",
32922
- provider: snapshot?.provider ?? "off",
34158
+ model: snapshot2?.model ?? "off",
34159
+ provider: snapshot2?.provider ?? "off",
32923
34160
  session: { embedded: 0, total: 0 },
32924
34161
  memories: { embedded: 0, total: 0 },
32925
34162
  commits: { embedded: 0, total: 0, gitEnabled: false }
32926
34163
  };
32927
34164
  }
32928
- const session = countSessionCompartmentEmbedCoverage(db, projectIdentity, sessionId, snapshot.chunkModelId);
32929
- const memories = getMemoryEmbedCoverage(db, projectIdentity, snapshot.modelId);
32930
- const gitEnabled = snapshot.gitCommitEnabled;
34165
+ const session = countSessionCompartmentEmbedCoverage(db, projectIdentity, sessionId, snapshot2.chunkModelId);
34166
+ const memories = getMemoryEmbedCoverage(db, projectIdentity, snapshot2.modelId);
34167
+ const gitEnabled = snapshot2.gitCommitEnabled;
32931
34168
  const commits = gitEnabled ? {
32932
- embedded: countEmbeddedCommits(db, projectIdentity, snapshot.modelId),
34169
+ embedded: countEmbeddedCommits(db, projectIdentity, snapshot2.modelId),
32933
34170
  total: getCommitCount(db, projectIdentity),
32934
34171
  gitEnabled: true
32935
34172
  } : { embedded: 0, total: 0, gitEnabled: false };
32936
34173
  return {
32937
34174
  enabled: true,
32938
- model: snapshot.model,
32939
- provider: snapshot.provider,
34175
+ model: snapshot2.model,
34176
+ provider: snapshot2.provider,
32940
34177
  session,
32941
34178
  memories,
32942
34179
  commits
@@ -33124,8 +34361,8 @@ async function embedText(text, signal) {
33124
34361
  }
33125
34362
  // src/features/magic-context/memory/embedding-backfill.ts
33126
34363
  async function ensureMemoryEmbeddings(args) {
33127
- const snapshot = getProjectEmbeddingSnapshot(args.projectIdentity);
33128
- if (!snapshot?.enabled) {
34364
+ const snapshot2 = getProjectEmbeddingSnapshot(args.projectIdentity);
34365
+ if (!snapshot2?.enabled) {
33129
34366
  return args.existingEmbeddings;
33130
34367
  }
33131
34368
  const missingMemories = args.memories.filter((memory) => !args.existingEmbeddings.has(memory.id));
@@ -33597,7 +34834,7 @@ function tallyFactsByCategory(facts) {
33597
34834
  import { join as join7 } from "node:path";
33598
34835
 
33599
34836
  // src/features/magic-context/compaction-marker.ts
33600
- import { createHash as createHash13 } from "node:crypto";
34837
+ import { createHash as createHash14 } from "node:crypto";
33601
34838
  import { existsSync as existsSync7 } from "node:fs";
33602
34839
  import { join as join6 } from "node:path";
33603
34840
  var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -33605,7 +34842,7 @@ var ID_PREFIX_HEX_LENGTH = 12;
33605
34842
  var ID_SUFFIX_LENGTH = 14;
33606
34843
  var ID_PREFIX_MASK = (1n << BigInt(ID_PREFIX_HEX_LENGTH * 4)) - 1n;
33607
34844
  function deterministicBase62(seed, length) {
33608
- let value = BigInt(`0x${createHash13("sha256").update(seed).digest("hex")}`);
34845
+ let value = BigInt(`0x${createHash14("sha256").update(seed).digest("hex")}`);
33609
34846
  const chars = Array(length);
33610
34847
  for (let index = length - 1;index >= 0; index -= 1) {
33611
34848
  chars[index] = BASE62_CHARS[Number(value % 62n)];
@@ -35925,8 +37162,8 @@ function isTransientHistorianPromptError(message) {
35925
37162
  ].some((token) => normalized.includes(token));
35926
37163
  }
35927
37164
  function sleep(ms) {
35928
- return new Promise((resolve2) => {
35929
- setTimeout(resolve2, ms);
37165
+ return new Promise((resolve3) => {
37166
+ setTimeout(resolve3, ms);
35930
37167
  });
35931
37168
  }
35932
37169
  function cleanupHistorianDump(sessionId, dumpPath) {
@@ -35971,7 +37208,7 @@ function sanitizeDumpName(value) {
35971
37208
  import { Buffer as Buffer3 } from "node:buffer";
35972
37209
 
35973
37210
  // src/features/magic-context/mural/render-trigger.ts
35974
- import { createHash as createHash14 } from "node:crypto";
37211
+ import { createHash as createHash15 } from "node:crypto";
35975
37212
 
35976
37213
  // src/features/magic-context/mural/mural-selection.ts
35977
37214
  var DEFAULT_MURAL_MEMORY_BUDGET = 8000;
@@ -36597,7 +37834,7 @@ function ensureMuralRendered(db, projectIdentity, budgetTokens = DEFAULT_MURAL_M
36597
37834
  return { hasMural: false, rerendered: false };
36598
37835
  }
36599
37836
  const rendered = renderMural(entries);
36600
- const textHash = createHash14("sha256").update(rendered.sha256Input).digest("hex");
37837
+ const textHash = createHash15("sha256").update(rendered.sha256Input).digest("hex");
36601
37838
  const existing = getMural(db, projectIdentity);
36602
37839
  if (existing && existing.contentHash === textHash && existing.width === rendered.width && existing.height === rendered.height) {
36603
37840
  return {
@@ -39018,13 +40255,13 @@ function force80PerRunCap(usable, N) {
39018
40255
  function force95PerRunCap(usable, N) {
39019
40256
  return Math.min(FORCE95_MAX_CAP, Math.max(4 * N, Math.min(Math.round(0.5 * usable), 250000)));
39020
40257
  }
39021
- function selectPerRunCap(snapshot) {
39022
- const usable = Math.max(1, Math.round(snapshot.contextLimit * snapshot.executeThresholdPercentage / 100));
39023
- if (snapshot.usagePercentage >= 95)
39024
- return force95PerRunCap(usable, snapshot.N);
39025
- if (snapshot.usagePercentage >= 80)
39026
- return force80PerRunCap(usable, snapshot.N);
39027
- return nonEmergencyPerRunCap(usable, snapshot.N);
40258
+ function selectPerRunCap(snapshot2) {
40259
+ const usable = Math.max(1, Math.round(snapshot2.contextLimit * snapshot2.executeThresholdPercentage / 100));
40260
+ if (snapshot2.usagePercentage >= 95)
40261
+ return force95PerRunCap(usable, snapshot2.N);
40262
+ if (snapshot2.usagePercentage >= 80)
40263
+ return force80PerRunCap(usable, snapshot2.N);
40264
+ return nonEmergencyPerRunCap(usable, snapshot2.N);
39028
40265
  }
39029
40266
  function boundaryMessageId(index, ordinal) {
39030
40267
  if (ordinal < 1 || ordinal > index.rawMessageCount)
@@ -39436,7 +40673,7 @@ function resolveWrapupProtectedTailBoundary(args) {
39436
40673
  });
39437
40674
  const eligibleEndOrdinal = Math.min(head.eligibleEndOrdinal, targetProtectedTailStart);
39438
40675
  const rawRangeFingerprint = computeRawRangeFingerprint(messages, offset, eligibleEndOrdinal);
39439
- const snapshot = {
40676
+ const snapshot2 = {
39440
40677
  sessionId: ctx.sessionId,
39441
40678
  mode: "manual-wrapup",
39442
40679
  offset,
@@ -39466,7 +40703,7 @@ function resolveWrapupProtectedTailBoundary(args) {
39466
40703
  boundaryReason
39467
40704
  };
39468
40705
  return {
39469
- snapshot,
40706
+ snapshot: snapshot2,
39470
40707
  rawMessagesAboveLastCompartment,
39471
40708
  anchorRawMessageCount,
39472
40709
  targetProtectedTailStart,
@@ -39485,46 +40722,46 @@ function getRawHistoryEligibility(db, sessionId) {
39485
40722
  hasRawBeyondLastCompartment: rawMessageCount >= offset
39486
40723
  };
39487
40724
  }
39488
- function hasRunnableCompartmentWindow(snapshot) {
39489
- if (snapshot.offset >= snapshot.protectedTailStart)
40725
+ function hasRunnableCompartmentWindow(snapshot2) {
40726
+ if (snapshot2.offset >= snapshot2.protectedTailStart)
39490
40727
  return false;
39491
- const forceMaterializationPercentage = escalationBands(snapshot.executeThresholdPercentage).forceMaterializationPercentage;
39492
- if (snapshot.usagePercentage >= forceMaterializationPercentage || snapshot.emergencyTailScale) {
39493
- return snapshot.trueRawEligibleTokens >= deriveMinForceEligibleTokens(snapshot.N) || snapshot.eligibleEndOrdinal > snapshot.offset;
40728
+ const forceMaterializationPercentage = escalationBands(snapshot2.executeThresholdPercentage).forceMaterializationPercentage;
40729
+ if (snapshot2.usagePercentage >= forceMaterializationPercentage || snapshot2.emergencyTailScale) {
40730
+ return snapshot2.trueRawEligibleTokens >= deriveMinForceEligibleTokens(snapshot2.N) || snapshot2.eligibleEndOrdinal > snapshot2.offset;
39494
40731
  }
39495
- return snapshot.eligibleEndOrdinal > snapshot.offset;
40732
+ return snapshot2.eligibleEndOrdinal > snapshot2.offset;
39496
40733
  }
39497
40734
  function validateBoundarySnapshot(args) {
39498
- const { snapshot } = args;
39499
- if (args.currentContextLimit && args.currentContextLimit !== snapshot.contextLimit) {
40735
+ const { snapshot: snapshot2 } = args;
40736
+ if (args.currentContextLimit && args.currentContextLimit !== snapshot2.contextLimit) {
39500
40737
  return {
39501
40738
  ok: false,
39502
40739
  reason: "model_or_limit_changed",
39503
- detail: `context limit changed from ${snapshot.contextLimit} to ${args.currentContextLimit}`
40740
+ detail: `context limit changed from ${snapshot2.contextLimit} to ${args.currentContextLimit}`
39504
40741
  };
39505
40742
  }
39506
- const messages = readRawSessionMessages(snapshot.sessionId);
40743
+ const messages = readRawSessionMessages(snapshot2.sessionId);
39507
40744
  const currentRawMessageCount = messages.reduce((max, message) => Math.max(max, message.ordinal), messages.length);
39508
- if (snapshot.rawMessageCountAtTrigger > currentRawMessageCount) {
40745
+ if (snapshot2.rawMessageCountAtTrigger > currentRawMessageCount) {
39509
40746
  return { ok: false, reason: "stale_snapshot", detail: "raw message count shrank" };
39510
40747
  }
39511
40748
  const idsByOrdinal = new Map(messages.map((message) => [message.ordinal, message.id]));
39512
40749
  const idAt = (ordinal) => idsByOrdinal.get(ordinal) ?? null;
39513
40750
  const checks3 = [
39514
- [snapshot.offset, snapshot.offsetMessageId, "offset"],
39515
- [snapshot.rawMessageCountAtTrigger, snapshot.rawLastMessageIdAtTrigger, "last"]
40751
+ [snapshot2.offset, snapshot2.offsetMessageId, "offset"],
40752
+ [snapshot2.rawMessageCountAtTrigger, snapshot2.rawLastMessageIdAtTrigger, "last"]
39516
40753
  ];
39517
- if (snapshot.protectedTailStart <= snapshot.rawMessageCountAtTrigger) {
40754
+ if (snapshot2.protectedTailStart <= snapshot2.rawMessageCountAtTrigger) {
39518
40755
  checks3.push([
39519
- snapshot.protectedTailStart,
39520
- snapshot.protectedTailStartMessageId,
40756
+ snapshot2.protectedTailStart,
40757
+ snapshot2.protectedTailStartMessageId,
39521
40758
  "protectedTailStart"
39522
40759
  ]);
39523
40760
  }
39524
- if (snapshot.eligibleEndOrdinal > snapshot.offset) {
40761
+ if (snapshot2.eligibleEndOrdinal > snapshot2.offset) {
39525
40762
  checks3.push([
39526
- snapshot.eligibleEndOrdinal - 1,
39527
- snapshot.eligibleEndMessageId,
40763
+ snapshot2.eligibleEndOrdinal - 1,
40764
+ snapshot2.eligibleEndMessageId,
39528
40765
  "eligibleEnd"
39529
40766
  ]);
39530
40767
  }
@@ -39537,26 +40774,26 @@ function validateBoundarySnapshot(args) {
39537
40774
  };
39538
40775
  }
39539
40776
  }
39540
- const expectedOffset = Math.max(1, getLastCompartmentEndMessage(args.db, snapshot.sessionId) + 1);
39541
- if (expectedOffset !== snapshot.offset) {
40777
+ const expectedOffset = Math.max(1, getLastCompartmentEndMessage(args.db, snapshot2.sessionId) + 1);
40778
+ if (expectedOffset !== snapshot2.offset) {
39542
40779
  return {
39543
40780
  ok: false,
39544
40781
  reason: "stale_snapshot",
39545
- detail: `last compartment moved: offset ${snapshot.offset} -> ${expectedOffset}`
40782
+ detail: `last compartment moved: offset ${snapshot2.offset} -> ${expectedOffset}`
39546
40783
  };
39547
40784
  }
39548
- const fingerprint = computeRawRangeFingerprint(messages, snapshot.offset, snapshot.eligibleEndOrdinal);
39549
- if (fingerprint !== snapshot.rawRangeFingerprint) {
40785
+ const fingerprint = computeRawRangeFingerprint(messages, snapshot2.offset, snapshot2.eligibleEndOrdinal);
40786
+ if (fingerprint !== snapshot2.rawRangeFingerprint) {
39550
40787
  return { ok: false, reason: "stale_snapshot", detail: "raw range fingerprint changed" };
39551
40788
  }
39552
40789
  return { ok: true };
39553
40790
  }
39554
- function recordHighPressureNoEligibleHead(db, snapshot) {
39555
- const forceMaterializationPercentage = escalationBands(snapshot.executeThresholdPercentage).forceMaterializationPercentage;
39556
- if (snapshot.usagePercentage < forceMaterializationPercentage && !snapshot.emergencyTailScale) {
40791
+ function recordHighPressureNoEligibleHead(db, snapshot2) {
40792
+ const forceMaterializationPercentage = escalationBands(snapshot2.executeThresholdPercentage).forceMaterializationPercentage;
40793
+ if (snapshot2.usagePercentage < forceMaterializationPercentage && !snapshot2.emergencyTailScale) {
39557
40794
  return 0;
39558
40795
  }
39559
- return recordProtectedTailNoEligibleHead(db, snapshot.sessionId);
40796
+ return recordProtectedTailNoEligibleHead(db, snapshot2.sessionId);
39560
40797
  }
39561
40798
 
39562
40799
  // src/hooks/magic-context/reference-seeds.generated.ts
@@ -42716,7 +43953,7 @@ async function executeContextRecomp(deps, options = {}) {
42716
43953
  }
42717
43954
 
42718
43955
  // src/hooks/magic-context/lkg-slot.ts
42719
- import { createHash as createHash15 } from "node:crypto";
43956
+ import { createHash as createHash16 } from "node:crypto";
42720
43957
  var LKG_TOTAL_BYTES = 64 * 1024 * 1024;
42721
43958
  var LKG_SINGLE_SLOT_BYTES = 24 * 1024 * 1024;
42722
43959
  var LKG_METADATA_BYTES = 256;
@@ -42778,7 +44015,7 @@ function lkgContentFields(value) {
42778
44015
  }
42779
44016
  }
42780
44017
  function lkgContentDigestFromFields(fields) {
42781
- const hash2 = createHash15("sha256");
44018
+ const hash2 = createHash16("sha256");
42782
44019
  for (const field of fields) {
42783
44020
  const value = typeof field === "symbol" ? field.description ?? "" : String(field);
42784
44021
  hash2.update(`${typeof field}:${value.length}:`).update(value).update("\x00");
@@ -43134,4 +44371,4 @@ async function runUpgradeMemoryMigration(ctx, sessionId, migrationDirectory) {
43134
44371
  }
43135
44372
  }
43136
44373
 
43137
- export { withContentLanguageDirective, buildPrimaryLanguageDirective, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, resolveLegacyConfigSources, resolveLegacyConfigSourcesForHarness, migrateMagicContextConfigLocations, exports_external, DEFAULT_PROTECTED_TAGS, parseCron, nextOccurrence, nextDueAtMs, promptSurfaceConfigIdentity, resolvePromptSurface, resolveModelConfigOrDefault, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, DEFAULT_LOCAL_EMBEDDING_MODEL, MagicContextConfigSchema, getOpenCodeDbPath, removeMcOwnedCompactionMarkers, isFailClosedBlockingError, shouldBypassFailClosedBlock, resolveAgentNameFromMessages, createFailClosedController, recordHookInitFailure, clearHookInitFailure, getLastHookInitFailure, ProjectIdentityError, resolveProjectIdentityStrict, takeDubiousOwnershipProjectIdentityWarning, resolveProjectIdentity, resolveProjectIdentityForSession, normalizeStoredProjectPath, storedPathBelongsToIdentity, isLinkedGitWorktree, recordSessionProjectIdentity, beginBootQuietPeriod, bootQuietRemainingMs, scheduleAfterBootQuiet, rpcPortDir, rpcPortFilePath, isPidAlive, parseRpcPortFile, registerModuleNoteEvaluationBridge, getModuleNoteEvaluationBridge, getContextStoreUuid, ensureContextStoreUuid, getAuthorityManagedMarker, reconcileAuthorityProject, checksumAuthoritySeedRows, prepareAuthority, drainAuthority, getMirrorCursor, applyMirroredNoteCompileFields, applyMirrorPage, pullMemoryMirrorOnce, V2_MEMORY_CATEGORIES, CATEGORY_PRIORITY, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, resolveStoredPathWorkspaceIdentity, storedPathBelongsToWorkspace, sourceNameForMemory, computeWorkspaceEpochFingerprint, recordToolDefinition, getMeasuredToolDefinitionTokens, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, runSqliteOptimize, openDatabase, openDatabaseAsync, isDatabasePersisted, getDatabasePersistenceError, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, clearRecompStaging, recordEmbeddingMeasurement, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, isEmergencyRecoveryArmed, isProviderOverflowReconfirmed, getEmergencyRecoveryArmedAt, loadPersistedUsage, loadProtectedTailMeta, resetProtectedTailNoEligibleHead, getWrapupInProgressState, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, getPersistedReasoningWatermark, setPersistedReasoningWatermark, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, getNoteNudgeAnchors, getAutoSearchHintDecisions, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, removeNoteNudgeAnchorByMessageId, removeAutoSearchHintDecisionByMessageId, getPersistedTodoPermissionDenied, setPersistedTodoPermissionDenied, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, setNoteLastReadAt, getHistorianFailureState, clearHistorianFailureState, getOverflowState, recordOverflowDetected, recordDetectedContextLimit, clearEmergencyRecovery, clearDetectedContextLimit, getPersistedCompactionMarkerState, setPersistedCompactionMarkerState, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, removeStrippedPlaceholderId, getMergedReasoningStrippedIds, addMergedReasoningStrippedIds, getTrailingBlankDecisions, addTrailingBlankDecisions, getStaleReduceStrippedIds, addStaleReduceStrippedIds, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, getSessionsWithPendingMarker, setSessionWorkMetrics, getNotes, addNote, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, updateNote, dismissNote, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectMemoryEpoch, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, getActiveTagTokenAggregate, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, getActiveTagTokenTotalsByMessage, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, updateTagMessageId, deleteTagsByMessageId, getMaxTagNumberBySession, getTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getDroppedTagsBySession, getTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, getCandidateToolOwners, pickNearestPriorOwner, createChildSessionWithFence, detectOverflow, promptSyncWithValidatedOutputRetry, normalizeSDKResponse, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, extractLatestAssistantText, hasLengthCappedOutput, setKeepSubagents, shouldKeepSubagents, recordChildInvocation, COMPARTMENT_AGENT_SYSTEM_PROMPT, HISTORIAN_EDITOR_SYSTEM_PROMPT, COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, Priority, AdmissionClass, StaleRouteHandleError, SocketClosedError, SocketTimeoutError, SubcClient, isConsumerReconnectTransient, connectionFileExists, getCompartmentEvents, loadCompartmentChunkEmbeddingsForSearch, cosineSimilarity, SYNAPSE_DEFAULT_MODEL, SynapseEmbeddingProvider, computeNormalizedHash, saveCommitEmbedding, loadProjectCommitEmbeddings, loadUnembeddedCommits, countEmbeddedCommits, upsertCommits, getLatestIndexedCommitTimeMs, enforceProjectCap, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, saveEmbeddingIfHashMatches, getProjectEmbeddings, peekProjectEmbeddings, invalidateProject, invalidateMemory, markProjectLoadUntrusted, contentSha256, sweepStaleEmbeddingIdentitiesForProject, registerProjectEmbedding, registerProjectShadowEmbedding, getShadowEmbeddingMeasurementCohort, getPrimaryEmbeddingMeasurementCohort, embedShadowTextForProject, enqueueShadowEmbeddingItems, registerProjectInObservationMode, getProjectEmbeddingSnapshot, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, isEmbeddingEnabled, embedText, ensureMemoryEmbeddings, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, ModuleMemoryAuthorityError, insertMemory, insertMemoryIdempotent, getMemoryByHash, getMemoriesByProject, buildWorkspaceMemorySqlFilter, getMemoriesByProjects, getMaxMemoryIdForProjects, readNewMemoriesForM1Union, getMemoryById, getMemoriesByIds, updateMemorySeenCount, updateMemoryRetrievalCount, setMemoryClassification, supersededMemory, mergeMemoryStats, archiveMemory, getMemoryCountsByStatus, sanitizeFtsQuery, searchMemoriesFTS, searchMemoriesFTSUnion, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, MARKER_SUMMARY_TEXT, applyDeferredCompactionMarker, removeCompactionMarkerForSession, checkCompactionMarkerConsistency, getMural, resolveMuralWire, BoundedSessionMap, extractM0Block, formatDate, injectTemporalMarkers, clearInjectionCache, getVisibleMemoryIds, prepareCompartmentInjection, renderCompartmentInjection, mustMaterialize, trimMemoriesToBudgetV2, renderMemoryBlockV2, injectM0M1, onNoteTrigger, peekNoteNudgeText, markNoteNudgeDelivered, clearNoteNudgeTriggerAndCooldown, resetNoteNudgeCooldownOnly, clearNoteNudgeTriggerOnly, RECOVERY_NO_HEAD_LIMIT, resolveOpenCodeProtectedTailBoundary, resolveWrapupProtectedTailBoundary, getRawHistoryEligibility, hasRunnableCompartmentWindow, recordHighPressureNoEligibleHead, runCompartmentAgent, snapRangeToCompartments, LKG_SNAPSHOT_ARRAY, LKG_SNAPSHOT_OBJECT, LKG_SNAPSHOT_KEY, LKG_SNAPSHOT_STRING, LKG_SNAPSHOT_NUMBER, LKG_SNAPSHOT_BOOLEAN, LKG_SNAPSHOT_NULL, LKG_SNAPSHOT_UNDEFINED, incrementalLkgContentDigests, lkgContentDigest, captureSlot, getSlot, dropSlot, noteEntry, getActiveCompartmentRun, markActiveCompartmentRunPublished, registerActiveCompartmentRun, startCompartmentAgent, isRecompFailure, isRecompSkip, isRecompComplete, extractRecompReason, contextualizeUpgradeReason, setRecompStarting, setRecompNote, setRecompTerminal, runManagedRecomp, runManagedUpgrade };
44374
+ export { withContentLanguageDirective, buildPrimaryLanguageDirective, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, resolveLegacyConfigSources, resolveLegacyConfigSourcesForHarness, migrateMagicContextConfigLocations, exports_external, DEFAULT_PROTECTED_TAGS, parseCron, nextOccurrence, nextDueAtMs, promptSurfaceConfigIdentity, resolvePromptSurface, resolveModelConfigOrDefault, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, DEFAULT_LOCAL_EMBEDDING_MODEL, MagicContextConfigSchema, getOpenCodeDbPath, removeMcOwnedCompactionMarkers, isFailClosedBlockingError, shouldBypassFailClosedBlock, resolveAgentNameFromMessages, createFailClosedController, recordHookInitFailure, clearHookInitFailure, getLastHookInitFailure, ProjectIdentityError, resolveProjectIdentityStrict, takeDubiousOwnershipProjectIdentityWarning, resolveProjectIdentity, resolveProjectIdentityForSession, normalizeStoredProjectPath, storedPathBelongsToIdentity, isLinkedGitWorktree, recordSessionProjectIdentity, beginBootQuietPeriod, bootQuietRemainingMs, scheduleAfterBootQuiet, rpcPortDir, rpcPortFilePath, isPidAlive, parseRpcPortFile, registerModuleNoteEvaluationBridge, getModuleNoteEvaluationBridge, getContextStoreUuid, ensureContextStoreUuid, getAuthorityManagedMarker, reconcileAuthorityProject, checksumAuthoritySeedRows, prepareAuthority, drainAuthority, getMirrorCursor, applyMirroredNoteCompileFields, applyMirrorPage, pullMemoryMirrorOnce, V2_MEMORY_CATEGORIES, CATEGORY_PRIORITY, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, resolveStoredPathWorkspaceIdentity, storedPathBelongsToWorkspace, sourceNameForMemory, computeWorkspaceEpochFingerprint, recordToolDefinition, getMeasuredToolDefinitionTokens, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, runSqliteOptimize, openDatabase, openDatabaseAsync, isDatabasePersisted, getDatabasePersistenceError, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, clearRecompStaging, recordEmbeddingMeasurement, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, isEmergencyRecoveryArmed, isProviderOverflowReconfirmed, getEmergencyRecoveryArmedAt, loadPersistedUsage, loadProtectedTailMeta, resetProtectedTailNoEligibleHead, getWrapupInProgressState, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, getPersistedReasoningWatermark, setPersistedReasoningWatermark, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, getNoteNudgeAnchors, getAutoSearchHintDecisions, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, removeNoteNudgeAnchorByMessageId, removeAutoSearchHintDecisionByMessageId, getPersistedTodoPermissionDenied, setPersistedTodoPermissionDenied, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, setNoteLastReadAt, getHistorianFailureState, clearHistorianFailureState, getOverflowState, recordOverflowDetected, recordDetectedContextLimit, clearEmergencyRecovery, clearDetectedContextLimit, getPersistedCompactionMarkerState, setPersistedCompactionMarkerState, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, removeStrippedPlaceholderId, getMergedReasoningStrippedIds, addMergedReasoningStrippedIds, getTrailingBlankDecisions, addTrailingBlankDecisions, getStaleReduceStrippedIds, addStaleReduceStrippedIds, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, getSessionsWithPendingMarker, setSessionWorkMetrics, getNotes, addNote, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, updateNote, dismissNote, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectMemoryEpoch, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, CTX_REDUCE_KEEP, estimateImageTokensFromDataUrl, normalizeTodoStateJson, buildSyntheticTodoPart, computeSyntheticCallId, isSyntheticTodoPart, tailHygieneStructuralSignature, sameTailHygieneStructuralSignature, refreshTailHygieneBaseline, effectiveTailHygiene, assertTailHygieneContentUnchanged, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, toolOutputTokens, decideChannel1, evaluateChannel2, buildChannel2Reminder, buildChannel1Reminder, estimateEmergencyDropReclaimTokens, planEmergencyDrop, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, getActiveTagTokenTotalsByMessage, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, updateTagMessageId, deleteTagsByMessageId, getMaxTagNumberBySession, getTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getTailHygieneTags, getDroppedTagsBySession, getTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, getCandidateToolOwners, pickNearestPriorOwner, createChildSessionWithFence, detectOverflow, promptSyncWithValidatedOutputRetry, normalizeSDKResponse, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, extractLatestAssistantText, hasLengthCappedOutput, setKeepSubagents, shouldKeepSubagents, recordChildInvocation, COMPARTMENT_AGENT_SYSTEM_PROMPT, HISTORIAN_EDITOR_SYSTEM_PROMPT, COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, Priority, AdmissionClass, StaleRouteHandleError, SocketClosedError, SocketTimeoutError, SubcClient, isConsumerReconnectTransient, connectionFileExists, getCompartmentEvents, loadCompartmentChunkEmbeddingsForSearch, cosineSimilarity, SYNAPSE_DEFAULT_MODEL, SynapseEmbeddingProvider, computeNormalizedHash, saveCommitEmbedding, loadProjectCommitEmbeddings, loadUnembeddedCommits, countEmbeddedCommits, upsertCommits, getLatestIndexedCommitTimeMs, enforceProjectCap, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, saveEmbeddingIfHashMatches, getProjectEmbeddings, peekProjectEmbeddings, invalidateProject, invalidateMemory, markProjectLoadUntrusted, contentSha256, sweepStaleEmbeddingIdentitiesForProject, registerProjectEmbedding, registerProjectShadowEmbedding, getShadowEmbeddingMeasurementCohort, getPrimaryEmbeddingMeasurementCohort, embedShadowTextForProject, enqueueShadowEmbeddingItems, registerProjectInObservationMode, getProjectEmbeddingSnapshot, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, isEmbeddingEnabled, embedText, ensureMemoryEmbeddings, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, ModuleMemoryAuthorityError, insertMemory, insertMemoryIdempotent, getMemoryByHash, getMemoriesByProject, buildWorkspaceMemorySqlFilter, getMemoriesByProjects, getMaxMemoryIdForProjects, readNewMemoriesForM1Union, getMemoryById, getMemoriesByIds, updateMemorySeenCount, updateMemoryRetrievalCount, setMemoryClassification, supersededMemory, mergeMemoryStats, archiveMemory, getMemoryCountsByStatus, sanitizeFtsQuery, searchMemoriesFTS, searchMemoriesFTSUnion, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, MARKER_SUMMARY_TEXT, applyDeferredCompactionMarker, removeCompactionMarkerForSession, checkCompactionMarkerConsistency, getMural, resolveMuralWire, BoundedSessionMap, extractM0Block, formatDate, injectTemporalMarkers, clearInjectionCache, getVisibleMemoryIds, prepareCompartmentInjection, renderCompartmentInjection, mustMaterialize, trimMemoriesToBudgetV2, renderMemoryBlockV2, injectM0M1, onNoteTrigger, peekNoteNudgeText, markNoteNudgeDelivered, clearNoteNudgeTriggerAndCooldown, resetNoteNudgeCooldownOnly, clearNoteNudgeTriggerOnly, RECOVERY_NO_HEAD_LIMIT, resolveOpenCodeProtectedTailBoundary, resolveWrapupProtectedTailBoundary, getRawHistoryEligibility, hasRunnableCompartmentWindow, recordHighPressureNoEligibleHead, runCompartmentAgent, snapRangeToCompartments, LKG_SNAPSHOT_ARRAY, LKG_SNAPSHOT_OBJECT, LKG_SNAPSHOT_KEY, LKG_SNAPSHOT_STRING, LKG_SNAPSHOT_NUMBER, LKG_SNAPSHOT_BOOLEAN, LKG_SNAPSHOT_NULL, LKG_SNAPSHOT_UNDEFINED, incrementalLkgContentDigests, lkgContentDigest, captureSlot, getSlot, dropSlot, noteEntry, getActiveCompartmentRun, markActiveCompartmentRunPublished, registerActiveCompartmentRun, startCompartmentAgent, isRecompFailure, isRecompSkip, isRecompComplete, extractRecompReason, contextualizeUpgradeReason, setRecompStarting, setRecompNote, setRecompTerminal, runManagedRecomp, runManagedUpgrade };