@cortexkit/opencode-magic-context 0.36.0 → 0.37.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 (192) hide show
  1. package/dist/config/index.d.ts.map +1 -1
  2. package/dist/config/project-security.d.ts +2 -1
  3. package/dist/config/project-security.d.ts.map +1 -1
  4. package/dist/config/schema/magic-context.d.ts +10 -0
  5. package/dist/config/schema/magic-context.d.ts.map +1 -1
  6. package/dist/{conflict-warning-hook-dw9fs934.js → conflict-warning-hook-an4fxhwf.js} +4 -4
  7. package/dist/{derive-budgets-88mxk2w1.js → derive-budgets-0f8xpyw2.js} +3 -2
  8. package/dist/features/magic-context/context-authority.d.ts +12 -0
  9. package/dist/features/magic-context/context-authority.d.ts.map +1 -1
  10. package/dist/features/magic-context/dreamer/classify.d.ts +2 -0
  11. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  12. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +2 -0
  13. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  14. package/dist/features/magic-context/dreamer/lease.d.ts +10 -3
  15. package/dist/features/magic-context/dreamer/lease.d.ts.map +1 -1
  16. package/dist/features/magic-context/dreamer/map-memories.d.ts +2 -0
  17. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  18. package/dist/features/magic-context/dreamer/module-apply.d.ts +5 -0
  19. package/dist/features/magic-context/dreamer/module-apply.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/promote-primers.d.ts +2 -0
  21. package/dist/features/magic-context/dreamer/promote-primers.d.ts.map +1 -1
  22. package/dist/features/magic-context/dreamer/refresh-primers.d.ts +2 -0
  23. package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -1
  24. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  25. package/dist/features/magic-context/dreamer/task-scheduler.d.ts +5 -2
  26. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  27. package/dist/features/magic-context/dreamer/verify.d.ts +2 -0
  28. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  29. package/dist/features/magic-context/memory/embedding-openai.d.ts +3 -1
  30. package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
  31. package/dist/features/magic-context/memory/project-identity.d.ts +6 -0
  32. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
  33. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  34. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  35. package/dist/features/magic-context/mural/compress-cues.d.ts +2 -0
  36. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  37. package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
  38. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  39. package/dist/features/magic-context/schema-fence-probe.d.ts +1 -0
  40. package/dist/features/magic-context/schema-fence-probe.d.ts.map +1 -1
  41. package/dist/features/magic-context/smart-notes/condition-compiler.d.ts +1 -0
  42. package/dist/features/magic-context/smart-notes/condition-compiler.d.ts.map +1 -1
  43. package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
  44. package/dist/features/magic-context/smart-notes/wake-plane.d.ts +21 -0
  45. package/dist/features/magic-context/smart-notes/wake-plane.d.ts.map +1 -0
  46. package/dist/features/magic-context/storage-clone.d.ts +6 -0
  47. package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
  48. package/dist/features/magic-context/storage-db.d.ts +14 -3
  49. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  50. package/dist/features/magic-context/storage-identity-merge.d.ts.map +1 -1
  51. package/dist/features/magic-context/storage-meta-persisted.d.ts +22 -0
  52. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  53. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
  54. package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
  55. package/dist/features/magic-context/storage-primers.d.ts +11 -0
  56. package/dist/features/magic-context/storage-primers.d.ts.map +1 -1
  57. package/dist/features/magic-context/storage-schema-helpers.d.ts.map +1 -1
  58. package/dist/features/magic-context/storage-tags.d.ts +2 -0
  59. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  60. package/dist/features/magic-context/storage.d.ts +1 -1
  61. package/dist/features/magic-context/storage.d.ts.map +1 -1
  62. package/dist/features/magic-context/user-memory/review-user-memories.d.ts +2 -0
  63. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  64. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts +7 -0
  65. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
  66. package/dist/features/magic-context/window-report-ledger.d.ts +70 -0
  67. package/dist/features/magic-context/window-report-ledger.d.ts.map +1 -0
  68. package/dist/hooks/magic-context/child-session-spawn.d.ts +1 -0
  69. package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -1
  70. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  71. package/dist/hooks/magic-context/compaction-off-transition.d.ts.map +1 -1
  72. package/dist/hooks/magic-context/compartment-render-epoch.d.ts +5 -3
  73. package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
  74. package/dist/hooks/magic-context/embed-session-state.d.ts +1 -1
  75. package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -1
  76. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  77. package/dist/hooks/magic-context/event-resolvers.d.ts +4 -0
  78. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  79. package/dist/hooks/magic-context/execute-status.d.ts +2 -1
  80. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  81. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  82. package/dist/hooks/magic-context/inject-compartments.d.ts +8 -0
  83. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  84. package/dist/hooks/magic-context/lkg-replay.d.ts +5 -2
  85. package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
  86. package/dist/hooks/magic-context/lkg-slot.d.ts +20 -0
  87. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  88. package/dist/hooks/magic-context/module-state-sync.d.ts +9 -0
  89. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  90. package/dist/hooks/magic-context/module-transport.d.ts +20 -3
  91. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  92. package/dist/hooks/magic-context/module-wire.d.ts +6 -1
  93. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  94. package/dist/hooks/magic-context/read-session-formatting.d.ts +1 -0
  95. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  96. package/dist/hooks/magic-context/rust-mode-transform.d.ts +20 -0
  97. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  98. package/dist/hooks/magic-context/strip-content.d.ts +31 -1
  99. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  100. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  101. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +12 -3
  102. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  103. package/dist/hooks/magic-context/transform.d.ts +10 -0
  104. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  105. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  106. package/dist/{index-3nfgbsp4.js → index-0ze9p983.js} +897 -114
  107. package/dist/{index-nsx2n9eg.js → index-4cz5nfxf.js} +3 -3
  108. package/dist/{index-0c9dmw9m.js → index-8mtsfhyg.js} +33 -3
  109. package/dist/{index-f1tnb3vm.js → index-8pqfcghm.js} +21 -9
  110. package/dist/{index-37rt2bka.js → index-cae89eas.js} +26 -7
  111. package/dist/index-cgyfn1s2.js +53 -0
  112. package/dist/{index-z8v31d85.js → index-crke4z5j.js} +144 -14
  113. package/dist/{index-tsgs7td8.js → index-pck9vadr.js} +1 -1
  114. package/dist/index-q0t189ay.js +741 -0
  115. package/dist/{index-3tnkymva.js → index-sw8gnq34.js} +1 -1
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +1952 -795
  118. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -0
  119. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  120. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  121. package/dist/plugin/rust-tool-backends.d.ts +4 -0
  122. package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
  123. package/dist/{recomp-orchestrator-7wbbvf87.js → recomp-orchestrator-c3ff16k7.js} +8 -7
  124. package/dist/{safe-notification-target-c11fdda2.js → safe-notification-target-b693f9x3.js} +2 -2
  125. package/dist/{send-session-notification-bgtf4853.js → send-session-notification-dxske5zm.js} +3 -3
  126. package/dist/shared/conflict-detector.d.ts +63 -0
  127. package/dist/shared/conflict-detector.d.ts.map +1 -1
  128. package/dist/shared/conflict-fixer.d.ts.map +1 -1
  129. package/dist/shared/harness-provider-map.d.ts +8 -0
  130. package/dist/shared/harness-provider-map.d.ts.map +1 -1
  131. package/dist/shared/jsonc-edit.d.ts +18 -0
  132. package/dist/shared/jsonc-edit.d.ts.map +1 -0
  133. package/dist/shared/jsonc-parser.d.ts +11 -1
  134. package/dist/shared/jsonc-parser.d.ts.map +1 -1
  135. package/dist/shared/logger.d.ts +8 -0
  136. package/dist/shared/logger.d.ts.map +1 -1
  137. package/dist/shared/models-dev-cache.d.ts +5 -0
  138. package/dist/shared/models-dev-cache.d.ts.map +1 -1
  139. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
  140. package/dist/shared/prompt-surface.d.ts +7 -3
  141. package/dist/shared/prompt-surface.d.ts.map +1 -1
  142. package/dist/shared/rpc-client.d.ts.map +1 -1
  143. package/dist/shared/rpc-types.d.ts +14 -0
  144. package/dist/shared/rpc-types.d.ts.map +1 -1
  145. package/dist/shared/rpc-utils.d.ts +32 -6
  146. package/dist/shared/rpc-utils.d.ts.map +1 -1
  147. package/dist/shared/tui-preferences.d.ts +9 -0
  148. package/dist/shared/tui-preferences.d.ts.map +1 -1
  149. package/dist/shared/window-geometry.d.ts +89 -0
  150. package/dist/shared/window-geometry.d.ts.map +1 -0
  151. package/dist/{storage-meta-session-kh5egr11.js → storage-meta-session-mk4gsnke.js} +4 -3
  152. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  153. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  154. package/dist/tui/data/context-db.d.ts.map +1 -1
  155. package/dist/tui-compiled/data/context-db.d.ts.map +1 -1
  156. package/package.json +2 -1
  157. package/src/config/index.test.ts +23 -0
  158. package/src/config/index.ts +43 -9
  159. package/src/config/latch-permanence-guard.test.ts +218 -0
  160. package/src/config/project-security.ts +10 -1
  161. package/src/config/schema/magic-context.test.ts +2 -1
  162. package/src/config/schema/magic-context.ts +13 -3
  163. package/src/shared/__fixtures__/window-overlay.v1.json +337 -0
  164. package/src/shared/conflict-detector.test.ts +176 -1
  165. package/src/shared/conflict-detector.ts +126 -3
  166. package/src/shared/conflict-fixer.test.ts +174 -0
  167. package/src/shared/conflict-fixer.ts +66 -70
  168. package/src/shared/harness-provider-map.test.ts +20 -0
  169. package/src/shared/harness-provider-map.ts +19 -0
  170. package/src/shared/jsonc-edit.ts +295 -0
  171. package/src/shared/jsonc-parser.test.ts +33 -0
  172. package/src/shared/jsonc-parser.ts +54 -2
  173. package/src/shared/logger.test.ts +119 -0
  174. package/src/shared/logger.ts +33 -15
  175. package/src/shared/models-dev-cache.test.ts +17 -0
  176. package/src/shared/models-dev-cache.ts +58 -6
  177. package/src/shared/prompt-surface-runtime.ts +5 -3
  178. package/src/shared/prompt-surface.test.ts +91 -2
  179. package/src/shared/prompt-surface.ts +35 -11
  180. package/src/shared/rpc-client.ts +4 -2
  181. package/src/shared/rpc-types.ts +14 -0
  182. package/src/shared/rpc-utils.test.ts +173 -13
  183. package/src/shared/rpc-utils.ts +202 -18
  184. package/src/shared/tui-preferences.test.ts +52 -2
  185. package/src/shared/tui-preferences.ts +42 -17
  186. package/src/shared/window-geometry.test.ts +309 -0
  187. package/src/shared/window-geometry.ts +629 -0
  188. package/src/tui/data/context-db.ts +5 -0
  189. package/src/tui/index.tsx +22 -0
  190. package/src/tui-compiled/data/context-db.ts +5 -0
  191. package/src/tui-compiled/index.tsx +319 -255
  192. package/dist/index-wgvxkqpx.js +0 -342
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  isMidTurn
3
- } from "./index-3tnkymva.js";
3
+ } from "./index-sw8gnq34.js";
4
4
  import {
5
5
  sessionLog
6
- } from "./index-f1tnb3vm.js";
6
+ } from "./index-8pqfcghm.js";
7
7
  import {
8
8
  __require
9
9
  } from "./index-wckvcay0.js";
@@ -171,7 +171,7 @@ async function sendIgnoredMessageNow(client, sessionId, text, params, forcePersi
171
171
  queueIgnoredNotification({ client, sessionId, text, params, forcePersist });
172
172
  return "queued";
173
173
  }
174
- const { waitForSafeNotificationTarget } = await import("./safe-notification-target-c11fdda2.js");
174
+ const { waitForSafeNotificationTarget } = await import("./safe-notification-target-b693f9x3.js");
175
175
  if (await waitForSafeNotificationTarget(client, sessionId) === "skip") {
176
176
  sessionLog(sessionId, "notification skipped (session not titled yet)");
177
177
  return "skipped";
@@ -90,9 +90,39 @@ function stripTrailingCommas(content) {
90
90
  }
91
91
  return result;
92
92
  }
93
- function parseJsonc(content) {
93
+ var PROTOTYPE_POLLUTION_KEYS = new Set(["__proto__", "constructor", "prototype"]);
94
+ function isPrototypePollutionKey(key) {
95
+ return PROTOTYPE_POLLUTION_KEYS.has(key);
96
+ }
97
+ function sanitizeParsedJson(value, options = {}, path = []) {
98
+ if (Array.isArray(value)) {
99
+ return value.map((entry, index) => sanitizeParsedJson(entry, options, [...path, index]));
100
+ }
101
+ if (value === null || typeof value !== "object")
102
+ return value;
103
+ const source = value;
104
+ const sourcePrototype = Object.getPrototypeOf(source);
105
+ if (sourcePrototype !== null && sourcePrototype !== Object.prototype) {
106
+ options.onRejectedKey?.([...path, "__proto__"]);
107
+ }
108
+ const sanitized = {};
109
+ for (const key of Object.keys(source)) {
110
+ if (isPrototypePollutionKey(key)) {
111
+ options.onRejectedKey?.([...path, key]);
112
+ continue;
113
+ }
114
+ Object.defineProperty(sanitized, key, {
115
+ value: sanitizeParsedJson(source[key], options, [...path, key]),
116
+ enumerable: true,
117
+ configurable: true,
118
+ writable: true
119
+ });
120
+ }
121
+ return sanitized;
122
+ }
123
+ function parseJsonc(content, options = {}) {
94
124
  const normalized = stripTrailingCommas(stripJsonComments(content));
95
- return JSON.parse(normalized);
125
+ return sanitizeParsedJson(JSON.parse(normalized), options);
96
126
  }
97
127
  function readJsoncFile(filePath) {
98
128
  try {
@@ -113,4 +143,4 @@ function detectConfigFile(basePath) {
113
143
  return { format: "none", path: jsoncPath };
114
144
  }
115
145
 
116
- export { stripJsonComments, parseJsonc, readJsoncFile, detectConfigFile };
146
+ export { stripJsonComments, isPrototypePollutionKey, parseJsonc, readJsoncFile, detectConfigFile };
@@ -10,16 +10,19 @@ var buffer = [];
10
10
  var flushTimer = null;
11
11
  var FLUSH_INTERVAL_MS = 500;
12
12
  var BUFFER_SIZE_LIMIT = 50;
13
- var lastEnsuredDir = null;
14
- function ensureDir(filePath) {
15
- const dir = path.dirname(filePath);
16
- if (dir === lastEnsuredDir)
17
- return;
13
+ var swallowedWriteCount = 0;
14
+ var lastErrorMessage = null;
15
+ var lastErrorTime = null;
16
+ function recordSwallowedWrite(error) {
18
17
  try {
19
- fs.mkdirSync(dir, { recursive: true });
20
- lastEnsuredDir = dir;
18
+ swallowedWriteCount++;
19
+ lastErrorMessage = error instanceof Error ? error.message : String(error);
20
+ lastErrorTime = new Date().toISOString();
21
21
  } catch {}
22
22
  }
23
+ function ensureDir(filePath) {
24
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
25
+ }
23
26
  function flush() {
24
27
  if (flushTimer) {
25
28
  clearTimeout(flushTimer);
@@ -33,7 +36,9 @@ function flush() {
33
36
  const logFile = getMagicContextLogPath();
34
37
  ensureDir(logFile);
35
38
  fs.appendFileSync(logFile, data);
36
- } catch {}
39
+ } catch (error) {
40
+ recordSwallowedWrite(error);
41
+ }
37
42
  }
38
43
  function scheduleFlush() {
39
44
  if (flushTimer)
@@ -62,8 +67,15 @@ ${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
62
67
  function sessionLog(sessionId, message, data) {
63
68
  log(`[magic-context][${sessionId}] ${message}`, data);
64
69
  }
70
+ function getLoggerDiagnostics() {
71
+ return {
72
+ swallowedWriteCount,
73
+ lastErrorMessage,
74
+ lastErrorTime
75
+ };
76
+ }
65
77
  if (!isTestEnv) {
66
78
  process.on("exit", flush);
67
79
  }
68
80
 
69
- export { log, sessionLog };
81
+ export { log, sessionLog, getLoggerDiagnostics };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  readJsoncFile
3
- } from "./index-0c9dmw9m.js";
3
+ } from "./index-8mtsfhyg.js";
4
4
  import {
5
5
  waitForSafeNotificationTarget
6
- } from "./index-tsgs7td8.js";
6
+ } from "./index-pck9vadr.js";
7
7
  import {
8
8
  log
9
- } from "./index-f1tnb3vm.js";
9
+ } from "./index-8pqfcghm.js";
10
10
  import {
11
11
  __require
12
12
  } from "./index-wckvcay0.js";
@@ -59,14 +59,17 @@ function detectConflicts(directory, options) {
59
59
  omoAnthropicRecovery: false
60
60
  };
61
61
  const reasons = [];
62
- const compactionResult = checkCompaction(directory);
62
+ let compactionResult = options?.resolvedCompaction ?? checkCompaction(directory);
63
+ if (process.env.OPENCODE_DISABLE_AUTOCOMPACT) {
64
+ compactionResult = { auto: false, prune: false };
65
+ }
63
66
  if (compactionEnabled && compactionResult.auto) {
64
67
  conflicts.compactionAuto = true;
65
- reasons.push("OpenCode auto-compaction is enabled (compaction.auto=true)");
68
+ reasons.push(options?.resolvedCompaction ? "OpenCode auto-compaction is enabled (compaction.auto=true) (resolved config)" : "OpenCode auto-compaction is enabled (compaction.auto=true)");
66
69
  }
67
70
  if (compactionEnabled && compactionResult.prune) {
68
71
  conflicts.compactionPrune = true;
69
- reasons.push("OpenCode prune is enabled (compaction.prune=true)");
72
+ reasons.push(options?.resolvedCompaction ? "OpenCode prune is enabled (compaction.prune=true) (resolved config)" : "OpenCode prune is enabled (compaction.prune=true)");
70
73
  }
71
74
  const dcpFound = checkDcpPlugin(directory);
72
75
  if (dcpFound) {
@@ -93,6 +96,22 @@ function detectConflicts(directory, options) {
93
96
  nativeCompaction: { auto: compactionResult.auto, prune: compactionResult.prune }
94
97
  };
95
98
  }
99
+ async function resolveCompactionForBoot(client, timeoutMs = 2000) {
100
+ try {
101
+ const result = await Promise.race([
102
+ client.config.get(),
103
+ new Promise((_, reject) => setTimeout(() => reject(new Error("config.get() timed out")), timeoutMs))
104
+ ]);
105
+ const compaction = result?.data?.compaction;
106
+ if (typeof compaction?.auto !== "boolean" || typeof compaction?.prune !== "boolean") {
107
+ log(`[magic-context] conflict-detector: resolved config carried no explicit compaction block (${JSON.stringify(compaction) ?? "absent"}); falling back to file-based detection`);
108
+ return null;
109
+ }
110
+ return { auto: compaction.auto, prune: compaction.prune };
111
+ } catch {
112
+ return null;
113
+ }
114
+ }
96
115
  function checkCompaction(directory) {
97
116
  if (process.env.OPENCODE_DISABLE_AUTOCOMPACT) {
98
117
  return { auto: false, prune: false };
@@ -586,4 +605,4 @@ async function sendStartupAnnouncement(client, directory, version, features, foo
586
605
  markSeen(version);
587
606
  }
588
607
 
589
- export { detectConflicts, sendConflictWarning, cleanupConflictWarnings, sendSchemaFenceWarning, sendStartupAnnouncement };
608
+ export { detectConflicts, resolveCompactionForBoot, sendConflictWarning, cleanupConflictWarnings, sendSchemaFenceWarning, sendStartupAnnouncement };
@@ -0,0 +1,53 @@
1
+ // src/shared/harness-provider-map.ts
2
+ var CANONICAL_TO_PI_PROVIDER = {
3
+ openai: "openai-codex",
4
+ google: "google-antigravity"
5
+ };
6
+ var PI_TO_CANONICAL_PROVIDER = {
7
+ "openai-codex": "openai",
8
+ "google-antigravity": "google"
9
+ };
10
+ var CANONICAL_TO_OMP_PROVIDER = {
11
+ openai: "openai-codex",
12
+ google: "google-antigravity"
13
+ };
14
+ var OMP_TO_CANONICAL_PROVIDER = {
15
+ "openai-codex": "openai",
16
+ "google-antigravity": "google"
17
+ };
18
+ function remapProviderPrefix(ref, map) {
19
+ if (typeof ref !== "string")
20
+ return ref;
21
+ const slash = ref.indexOf("/");
22
+ if (slash <= 0)
23
+ return ref;
24
+ const provider = ref.slice(0, slash);
25
+ if (!Object.hasOwn(map, provider))
26
+ return ref;
27
+ return `${map[provider]}${ref.slice(slash)}`;
28
+ }
29
+ function piModelRefToCanonical(ref) {
30
+ return remapProviderPrefix(ref, PI_TO_CANONICAL_PROVIDER);
31
+ }
32
+ function resolveModelRefForPi(ref) {
33
+ return remapProviderPrefix(piModelRefToCanonical(ref), CANONICAL_TO_PI_PROVIDER);
34
+ }
35
+ function modelRefLookupOrder(ref) {
36
+ const canonical = piModelRefToCanonical(ompModelRefToCanonical(ref));
37
+ return [
38
+ ...new Set([
39
+ canonical,
40
+ ref,
41
+ resolveModelRefForPi(canonical),
42
+ resolveModelRefForOmp(canonical)
43
+ ])
44
+ ];
45
+ }
46
+ function ompModelRefToCanonical(ref) {
47
+ return remapProviderPrefix(ref, OMP_TO_CANONICAL_PROVIDER);
48
+ }
49
+ function resolveModelRefForOmp(ref) {
50
+ return remapProviderPrefix(ompModelRefToCanonical(ref), CANONICAL_TO_OMP_PROVIDER);
51
+ }
52
+
53
+ export { piModelRefToCanonical, modelRefLookupOrder };
@@ -1,12 +1,15 @@
1
+ import {
2
+ piModelRefToCanonical
3
+ } from "./index-cgyfn1s2.js";
1
4
  import {
2
5
  closeQuietly,
3
6
  getRawSessionMessageCountFromDb,
4
7
  openCodeDbExists,
5
8
  withReadOnlySessionDb
6
- } from "./index-3tnkymva.js";
9
+ } from "./index-sw8gnq34.js";
7
10
  import {
8
11
  log
9
- } from "./index-f1tnb3vm.js";
12
+ } from "./index-8pqfcghm.js";
10
13
  import {
11
14
  getHarness
12
15
  } from "./index-mmrhhk9a.js";
@@ -53,7 +56,11 @@ function removeSystemReminders(text) {
53
56
  }
54
57
 
55
58
  // src/hooks/magic-context/read-session-formatting.ts
59
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
56
60
  import { createRequire } from "node:module";
61
+ import { homedir } from "node:os";
62
+ import { dirname, join, resolve } from "node:path";
63
+ import { pathToFileURL } from "node:url";
57
64
 
58
65
  // src/shared/commit-detection.ts
59
66
  var HASH_HEX = "[0-9a-f]{7,12}";
@@ -146,23 +153,146 @@ function truncateArg(value, maxLen = 60) {
146
153
  return value;
147
154
  return `${value.slice(0, maxLen)}…`;
148
155
  }
149
- var requireFromThisModule = createRequire(import.meta.url);
156
+ var TOKENIZER_PACKAGE_DIRS = [
157
+ ["@cortexkit", "opencode-magic-context"],
158
+ ["@cortexkit", "pi-magic-context"]
159
+ ];
150
160
  var tokenizer;
151
- function getTokenizer() {
161
+ var tokenizerLoadAttempted = false;
162
+ var tokenizerLoadPromise;
163
+ var tokenizerWarningSent = false;
164
+ function tokenizerPackageRoots() {
165
+ const cwd = process.cwd();
166
+ const openCodeCache = join(process.env.XDG_CACHE_HOME ?? join(homedir(), ".cache"), "opencode");
167
+ const roots = [cwd, openCodeCache];
168
+ const candidates = [];
169
+ for (const root of roots) {
170
+ for (const packageDir of TOKENIZER_PACKAGE_DIRS) {
171
+ candidates.push(join(root, "node_modules", ...packageDir, "node_modules", "ai-tokenizer"));
172
+ }
173
+ candidates.push(join(root, "node_modules", "ai-tokenizer"));
174
+ }
175
+ let ancestor = process.argv[1] ? dirname(resolve(process.argv[1])) : cwd;
176
+ while (true) {
177
+ candidates.push(join(ancestor, "node_modules", "ai-tokenizer"));
178
+ const parent = dirname(ancestor);
179
+ if (parent === ancestor)
180
+ break;
181
+ ancestor = parent;
182
+ }
183
+ return [...new Set(candidates)];
184
+ }
185
+ function packageImportTarget(value) {
186
+ if (typeof value === "string")
187
+ return value;
188
+ if (!value || typeof value !== "object")
189
+ return;
190
+ const conditions = value;
191
+ return packageImportTarget(conditions.import) ?? packageImportTarget(conditions.default);
192
+ }
193
+ function findTokenizerImportPaths() {
194
+ for (const packageRoot of tokenizerPackageRoots()) {
195
+ const packageJsonPath = join(packageRoot, "package.json");
196
+ if (!existsSync(packageJsonPath))
197
+ continue;
198
+ try {
199
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
200
+ const tokenizerTarget = packageImportTarget(packageJson.exports?.["."]) ?? (typeof packageJson.module === "string" ? packageJson.module : undefined) ?? (typeof packageJson.main === "string" ? packageJson.main : undefined);
201
+ const encodingTarget = packageImportTarget(packageJson.exports?.["./encoding/claude"]);
202
+ if (!tokenizerTarget || !encodingTarget)
203
+ continue;
204
+ return {
205
+ tokenizerPath: realpathSync(join(packageRoot, tokenizerTarget)),
206
+ encodingPath: realpathSync(join(packageRoot, encodingTarget))
207
+ };
208
+ } catch {}
209
+ }
210
+ return;
211
+ }
212
+ function constructTokenizer(tokenizerModule, claudeEncoding) {
213
+ const typedModule = tokenizerModule;
214
+ const Tokenizer = typedModule.default ?? typedModule.Tokenizer;
215
+ if (!Tokenizer) {
216
+ throw new Error("ai-tokenizer does not expose a Tokenizer constructor");
217
+ }
218
+ return new Tokenizer(claudeEncoding);
219
+ }
220
+ function loadTokenizer() {
221
+ const requireFromThisModule = createRequire(import.meta.url);
222
+ return constructTokenizer(requireFromThisModule("ai-" + "tokenizer"), requireFromThisModule("ai-tokenizer/encoding/" + "claude"));
223
+ }
224
+ async function loadTokenizerFromInstalledPackage() {
225
+ const installedPaths = findTokenizerImportPaths();
226
+ if (!installedPaths) {
227
+ throw new Error("ai-tokenizer was not found under the project, runtime, or OpenCode cache node_modules roots");
228
+ }
229
+ const [tokenizerModule, claudeEncoding] = await Promise.all([
230
+ import(pathToFileURL(installedPaths.tokenizerPath).href),
231
+ import(pathToFileURL(installedPaths.encodingPath).href)
232
+ ]);
233
+ return constructTokenizer(tokenizerModule, claudeEncoding);
234
+ }
235
+ function warnTokenizerFallback(error) {
236
+ if (tokenizerWarningSent)
237
+ return;
238
+ tokenizerWarningSent = true;
239
+ const reason = error instanceof Error ? error.message : String(error);
240
+ console.warn("[magic-context] ai-tokenizer is unavailable; using approximate character-based token counts for this process. Token budgets, persisted per-message counts, and protected-tail/compartment boundaries may be less accurate until restart:", reason);
241
+ }
242
+ async function preloadTokenizer() {
152
243
  if (tokenizer)
244
+ return true;
245
+ if (tokenizerLoadAttempted)
246
+ return false;
247
+ if (tokenizerLoadPromise)
248
+ return tokenizerLoadPromise;
249
+ tokenizerLoadPromise = (async () => {
250
+ try {
251
+ try {
252
+ tokenizer = loadTokenizer();
253
+ } catch {
254
+ tokenizer = await loadTokenizerFromInstalledPackage();
255
+ }
256
+ tokenizerLoadAttempted = true;
257
+ return true;
258
+ } catch (error) {
259
+ tokenizerLoadAttempted = true;
260
+ warnTokenizerFallback(error);
261
+ return false;
262
+ } finally {
263
+ tokenizerLoadPromise = undefined;
264
+ }
265
+ })();
266
+ return tokenizerLoadPromise;
267
+ }
268
+ function getTokenizer() {
269
+ if (tokenizer || tokenizerLoadAttempted)
153
270
  return tokenizer;
154
- const tokenizerModule = requireFromThisModule("ai-" + "tokenizer");
155
- const Tokenizer = tokenizerModule.default ?? tokenizerModule.Tokenizer;
156
- if (!Tokenizer)
157
- throw new Error("ai-tokenizer does not expose a Tokenizer constructor");
158
- const claudeEncoding = requireFromThisModule("ai-tokenizer/encoding/" + "claude");
159
- tokenizer = new Tokenizer(claudeEncoding);
271
+ tokenizerLoadAttempted = true;
272
+ try {
273
+ tokenizer = loadTokenizer();
274
+ } catch (error) {
275
+ warnTokenizerFallback(error);
276
+ }
160
277
  return tokenizer;
161
278
  }
279
+ function estimateTokensHeuristically(text) {
280
+ return Math.ceil(text.length / 3.5);
281
+ }
162
282
  function estimateTokens(text) {
163
283
  if (!text)
164
284
  return 0;
165
- return getTokenizer().encode(text, "all").length;
285
+ const activeTokenizer = getTokenizer();
286
+ if (!activeTokenizer)
287
+ return estimateTokensHeuristically(text);
288
+ try {
289
+ return activeTokenizer.encode(text, "all").length;
290
+ } catch (error) {
291
+ tokenizer = undefined;
292
+ tokenizerLoadAttempted = true;
293
+ warnTokenizerFallback(error);
294
+ return estimateTokensHeuristically(text);
295
+ }
166
296
  }
167
297
  function normalizeText(text) {
168
298
  return text.replace(/\s+/g, " ").trim();
@@ -2695,7 +2825,7 @@ function persistCachedM0(db, sessionId, payload) {
2695
2825
  cached_m0_system_hash = ?,
2696
2826
  cached_m0_model_key = ?,
2697
2827
  cached_m0_project_identity = ?
2698
- WHERE session_id = ?`).run(Buffer.from(payload.m0Bytes), payload.muralDataUrl ?? null, payload.muralHash ?? null, payload.projectMemoryEpoch, payload.workspaceFingerprint ?? null, payload.projectUserProfileVersion, payload.maxCompartmentSeq, payload.maxMemoryId, payload.maxMutationId, payload.maxMemoryMutationId ?? null, payload.m1Bytes ? Buffer.from(payload.m1Bytes) : null, payload.projectDocsHash, payload.materializedAt, payload.sessionFactsVersion, payload.upgradeState, payload.systemHash ?? "", payload.modelKey ?? "", payload.projectIdentity ?? null, sessionId);
2828
+ WHERE session_id = ?`).run(Buffer.from(payload.m0Bytes), payload.muralDataUrl ?? null, payload.muralHash ?? null, payload.projectMemoryEpoch, payload.workspaceFingerprint ?? null, payload.projectUserProfileVersion, payload.maxCompartmentSeq, payload.maxMemoryId, payload.maxMutationId, payload.maxMemoryMutationId ?? null, payload.m1Bytes ? Buffer.from(payload.m1Bytes) : null, payload.projectDocsHash, payload.materializedAt, payload.sessionFactsVersion, payload.upgradeState, payload.systemHash ?? "", payload.modelKey ? piModelRefToCanonical(payload.modelKey) : "", payload.projectIdentity ?? null, sessionId);
2699
2829
  }
2700
2830
  function clearCachedM0M1(db, sessionId) {
2701
2831
  ensureSessionMetaRow(db, sessionId);
@@ -2817,7 +2947,7 @@ function updateSessionMeta(db, sessionId, updates) {
2817
2947
  values.push(value ? 1 : 0);
2818
2948
  } else if (typeof value === "string" || typeof value === "number") {
2819
2949
  setClauses.push(`${column} = ?`);
2820
- values.push(value);
2950
+ values.push(key === "lastObservedModelKey" && typeof value === "string" ? piModelRefToCanonical(value) : value);
2821
2951
  }
2822
2952
  }
2823
2953
  if (setClauses.length === 0) {
@@ -2889,4 +3019,4 @@ function clearSession(db, sessionId) {
2889
3019
  })();
2890
3020
  }
2891
3021
 
2892
- export { textMentionsRecentCommit, hasMeaningfulUserText, extractTexts, extractToolCallSummaries, estimateTokens, normalizeText, stableStringify, clearCompressionDepth, clearCompressionDepthRange, ensureSessionMetaRow, persistCachedM0, clearCachedM0M1, isRawCompactionSummaryInfo, extractInMemoryMessageViews, buildInMemoryTailRawMessages, isRecord, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isThinkingPart, isTextPart, isToolPartWithOutput, isFilePart, buildFileSourceContent, isEditTool, partHasCompletedResult, extractToolCallObservation, ToolMutationBatch, createToolDropTarget, setRawMessageProvider, cleanUserText, withRawSessionMessageCache, readRawSessionMessages, primeTailRawMessageCache, getCachedAbsoluteMessageCount, primeInMemoryTailRawMessageCache, readRawSessionMessageOrdinalPage, getRawSessionStoredMessageCount, readRawSessionMessagePartsById, readRawSessionMessageOrdinalById, readRawSessionMessageById, getRawSessionMessageCount, getRawSessionTagKeysThrough, getLegacyProtectedTailStartOrdinal, readSessionChunk, getMessageIndexSourceIdentity, isMessageIndexSourceCurrent, getLastIndexedOrdinal, getIndexedMessageCorpusSize, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, deleteIndexedMessage, clearIndexedMessages, indexSingleMessage, indexMessagesAfterOrdinal, sweepOrphanedOpenCodeMessageIndexes, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, markSessionCleanupPending, retryPendingSessionCleanups, clearSession };
3022
+ export { textMentionsRecentCommit, hasMeaningfulUserText, extractTexts, extractToolCallSummaries, preloadTokenizer, estimateTokens, normalizeText, stableStringify, clearCompressionDepth, clearCompressionDepthRange, ensureSessionMetaRow, persistCachedM0, clearCachedM0M1, isRawCompactionSummaryInfo, extractInMemoryMessageViews, buildInMemoryTailRawMessages, isRecord, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isThinkingPart, isTextPart, isToolPartWithOutput, isFilePart, buildFileSourceContent, isEditTool, partHasCompletedResult, extractToolCallObservation, ToolMutationBatch, createToolDropTarget, setRawMessageProvider, cleanUserText, withRawSessionMessageCache, readRawSessionMessages, primeTailRawMessageCache, getCachedAbsoluteMessageCount, primeInMemoryTailRawMessageCache, readRawSessionMessageOrdinalPage, getRawSessionStoredMessageCount, readRawSessionMessagePartsById, readRawSessionMessageOrdinalById, readRawSessionMessageById, getRawSessionMessageCount, getRawSessionTagKeysThrough, getLegacyProtectedTailStartOrdinal, readSessionChunk, getMessageIndexSourceIdentity, isMessageIndexSourceCurrent, getLastIndexedOrdinal, getIndexedMessageCorpusSize, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, deleteIndexedMessage, clearIndexedMessages, indexSingleMessage, indexMessagesAfterOrdinal, sweepOrphanedOpenCodeMessageIndexes, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, markSessionCleanupPending, retryPendingSessionCleanups, clearSession };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  log
3
- } from "./index-f1tnb3vm.js";
3
+ } from "./index-8pqfcghm.js";
4
4
 
5
5
  // src/shared/safe-notification-target.ts
6
6
  var DEFAULT_TITLE_RE = /^(New session - |Child session - )\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;