@cortexkit/opencode-magic-context 0.35.1 → 0.36.1

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 (155) hide show
  1. package/README.md +9 -5
  2. package/dist/agents/permissions.d.ts +17 -0
  3. package/dist/agents/permissions.d.ts.map +1 -1
  4. package/dist/{announcement-gms2nhya.js → announcement-6c1g4es4.js} +2 -2
  5. package/dist/config/index.d.ts.map +1 -1
  6. package/dist/config/schema/magic-context.d.ts +10 -0
  7. package/dist/config/schema/magic-context.d.ts.map +1 -1
  8. package/dist/{conflict-warning-hook-p2pmhvn7.js → conflict-warning-hook-mt0ttc4x.js} +5 -5
  9. package/dist/{derive-budgets-9crp0cvd.js → derive-budgets-88mxk2w1.js} +3 -3
  10. package/dist/features/magic-context/context-authority.d.ts +12 -0
  11. package/dist/features/magic-context/context-authority.d.ts.map +1 -1
  12. package/dist/features/magic-context/dreamer/classify.d.ts +2 -0
  13. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  14. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +4 -0
  15. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  16. package/dist/features/magic-context/dreamer/lease.d.ts +10 -3
  17. package/dist/features/magic-context/dreamer/lease.d.ts.map +1 -1
  18. package/dist/features/magic-context/dreamer/map-memories.d.ts +2 -0
  19. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/module-apply.d.ts +5 -0
  21. package/dist/features/magic-context/dreamer/module-apply.d.ts.map +1 -1
  22. package/dist/features/magic-context/dreamer/promote-primers.d.ts +2 -0
  23. package/dist/features/magic-context/dreamer/promote-primers.d.ts.map +1 -1
  24. package/dist/features/magic-context/dreamer/refresh-primers.d.ts +2 -0
  25. package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -1
  26. package/dist/features/magic-context/dreamer/task-executor.d.ts +1 -0
  27. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  28. package/dist/features/magic-context/dreamer/task-scheduler.d.ts +5 -2
  29. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  30. package/dist/features/magic-context/dreamer/verify.d.ts +2 -0
  31. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  32. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  33. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  34. package/dist/features/magic-context/mural/compress-cues.d.ts +2 -0
  35. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  36. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  37. package/dist/features/magic-context/schema-fence-probe.d.ts +1 -0
  38. package/dist/features/magic-context/schema-fence-probe.d.ts.map +1 -1
  39. package/dist/features/magic-context/smart-notes/condition-compiler.d.ts +38 -0
  40. package/dist/features/magic-context/smart-notes/condition-compiler.d.ts.map +1 -0
  41. package/dist/features/magic-context/smart-notes/runner.d.ts +1 -0
  42. package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
  43. package/dist/features/magic-context/smart-notes/storage.d.ts +3 -3
  44. package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
  45. package/dist/features/magic-context/storage-clone.d.ts +6 -0
  46. package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
  47. package/dist/features/magic-context/storage-db.d.ts +2 -2
  48. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  49. package/dist/features/magic-context/storage-identity-merge.d.ts.map +1 -1
  50. package/dist/features/magic-context/storage-notes.d.ts +13 -0
  51. package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
  52. package/dist/features/magic-context/storage-tags.d.ts +2 -0
  53. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  54. package/dist/features/magic-context/storage.d.ts +2 -2
  55. package/dist/features/magic-context/storage.d.ts.map +1 -1
  56. package/dist/features/magic-context/user-memory/review-user-memories.d.ts +2 -0
  57. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  58. package/dist/hooks/magic-context/child-session-spawn.d.ts +1 -0
  59. package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -1
  60. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  61. package/dist/hooks/magic-context/compaction-off-transition.d.ts.map +1 -1
  62. package/dist/hooks/magic-context/compartment-render-epoch.d.ts +5 -3
  63. package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
  64. package/dist/hooks/magic-context/embed-session-state.d.ts +1 -1
  65. package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -1
  66. package/dist/hooks/magic-context/hook.d.ts +3 -0
  67. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  68. package/dist/hooks/magic-context/inject-compartments.d.ts +8 -0
  69. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  70. package/dist/hooks/magic-context/lkg-replay.d.ts +5 -2
  71. package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
  72. package/dist/hooks/magic-context/lkg-slot.d.ts +15 -1
  73. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  74. package/dist/hooks/magic-context/module-state-sync.d.ts +7 -0
  75. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  76. package/dist/hooks/magic-context/module-transport.d.ts +29 -3
  77. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  78. package/dist/hooks/magic-context/raw-fallback-context-limit.d.ts +10 -0
  79. package/dist/hooks/magic-context/raw-fallback-context-limit.d.ts.map +1 -0
  80. package/dist/hooks/magic-context/read-session-formatting.d.ts +1 -0
  81. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  82. package/dist/hooks/magic-context/rust-mode-transform.d.ts +10 -2
  83. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  84. package/dist/hooks/magic-context/strip-content.d.ts +6 -1
  85. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  86. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  87. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +1 -0
  88. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  89. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  90. package/dist/{index-fkyamz2w.js → index-1skzp4dc.js} +444 -98
  91. package/dist/{index-w0nygb4p.js → index-3tnkymva.js} +2 -2
  92. package/dist/{index-dpdnjawy.js → index-3zqcdwqr.js} +140 -13
  93. package/dist/{index-0c9dmw9m.js → index-8mtsfhyg.js} +33 -3
  94. package/dist/{index-k1esqfwk.js → index-f1tnb3vm.js} +1 -1
  95. package/dist/{index-kvrcg31b.js → index-mmrhhk9a.js} +8 -1
  96. package/dist/{index-h5zjfesc.js → index-nsx2n9eg.js} +3 -3
  97. package/dist/{index-dmr999a2.js → index-qf20mv7e.js} +1 -1
  98. package/dist/{index-73xz0247.js → index-tsgs7td8.js} +1 -1
  99. package/dist/{index-ry8rh8cv.js → index-wgvxkqpx.js} +5 -4
  100. package/dist/{index-8aaadh98.js → index-zp6x6s6a.js} +3 -3
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +1556 -619
  103. package/dist/plugin/dream-timer.d.ts +1 -0
  104. package/dist/plugin/dream-timer.d.ts.map +1 -1
  105. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -0
  106. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  107. package/dist/plugin/messages-transform.d.ts +5 -5
  108. package/dist/plugin/messages-transform.d.ts.map +1 -1
  109. package/dist/plugin/rust-tool-backends.d.ts +4 -0
  110. package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
  111. package/dist/{recomp-orchestrator-29f4rqax.js → recomp-orchestrator-a0g9b52q.js} +8 -8
  112. package/dist/{safe-notification-target-q9jk5n44.js → safe-notification-target-c11fdda2.js} +3 -3
  113. package/dist/{send-session-notification-sr5g06hz.js → send-session-notification-bgtf4853.js} +4 -4
  114. package/dist/shared/conflict-fixer.d.ts.map +1 -1
  115. package/dist/shared/data-path.d.ts +27 -0
  116. package/dist/shared/data-path.d.ts.map +1 -1
  117. package/dist/shared/harness-provider-map.d.ts +23 -20
  118. package/dist/shared/harness-provider-map.d.ts.map +1 -1
  119. package/dist/shared/jsonc-edit.d.ts +18 -0
  120. package/dist/shared/jsonc-edit.d.ts.map +1 -0
  121. package/dist/shared/jsonc-parser.d.ts +11 -1
  122. package/dist/shared/jsonc-parser.d.ts.map +1 -1
  123. package/dist/shared/prompt-surface-runtime.d.ts +15 -2
  124. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
  125. package/dist/shared/prompt-surface.d.ts +5 -3
  126. package/dist/shared/prompt-surface.d.ts.map +1 -1
  127. package/dist/shared/rpc-utils.d.ts +16 -0
  128. package/dist/shared/rpc-utils.d.ts.map +1 -1
  129. package/dist/shared/tui-preferences.d.ts +9 -0
  130. package/dist/shared/tui-preferences.d.ts.map +1 -1
  131. package/dist/{storage-meta-session-ev8b55a9.js → storage-meta-session-df9tstzr.js} +4 -4
  132. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  133. package/package.json +4 -3
  134. package/src/agents/permissions.ts +87 -0
  135. package/src/config/compaction-accessor-guard.test.ts +9 -4
  136. package/src/config/index.test.ts +23 -0
  137. package/src/config/index.ts +41 -9
  138. package/src/config/schema/magic-context.test.ts +4 -1
  139. package/src/config/schema/magic-context.ts +18 -3
  140. package/src/shared/conflict-fixer.test.ts +174 -0
  141. package/src/shared/conflict-fixer.ts +66 -70
  142. package/src/shared/data-path.test.ts +65 -9
  143. package/src/shared/data-path.ts +66 -1
  144. package/src/shared/harness-provider-map.test.ts +42 -1
  145. package/src/shared/harness-provider-map.ts +48 -26
  146. package/src/shared/jsonc-edit.ts +295 -0
  147. package/src/shared/jsonc-parser.test.ts +33 -0
  148. package/src/shared/jsonc-parser.ts +54 -2
  149. package/src/shared/prompt-surface-runtime.ts +13 -5
  150. package/src/shared/prompt-surface.test.ts +53 -2
  151. package/src/shared/prompt-surface.ts +20 -9
  152. package/src/shared/rpc-utils.test.ts +36 -0
  153. package/src/shared/rpc-utils.ts +71 -0
  154. package/src/shared/tui-preferences.test.ts +52 -2
  155. package/src/shared/tui-preferences.ts +42 -17
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  log
3
- } from "./index-k1esqfwk.js";
3
+ } from "./index-f1tnb3vm.js";
4
4
  import {
5
5
  getDataDir
6
- } from "./index-kvrcg31b.js";
6
+ } from "./index-mmrhhk9a.js";
7
7
 
8
8
  // src/shared/sqlite-helpers.ts
9
9
  function closeQuietly(db) {
@@ -3,13 +3,13 @@ import {
3
3
  getRawSessionMessageCountFromDb,
4
4
  openCodeDbExists,
5
5
  withReadOnlySessionDb
6
- } from "./index-w0nygb4p.js";
6
+ } from "./index-3tnkymva.js";
7
7
  import {
8
8
  log
9
- } from "./index-k1esqfwk.js";
9
+ } from "./index-f1tnb3vm.js";
10
10
  import {
11
11
  getHarness
12
- } from "./index-kvrcg31b.js";
12
+ } from "./index-mmrhhk9a.js";
13
13
 
14
14
  // src/features/magic-context/storage-meta-session.ts
15
15
  import { Buffer as Buffer2 } from "node:buffer";
@@ -53,7 +53,11 @@ function removeSystemReminders(text) {
53
53
  }
54
54
 
55
55
  // src/hooks/magic-context/read-session-formatting.ts
56
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
56
57
  import { createRequire } from "node:module";
58
+ import { homedir } from "node:os";
59
+ import { dirname, join, resolve } from "node:path";
60
+ import { pathToFileURL } from "node:url";
57
61
 
58
62
  // src/shared/commit-detection.ts
59
63
  var HASH_HEX = "[0-9a-f]{7,12}";
@@ -146,23 +150,146 @@ function truncateArg(value, maxLen = 60) {
146
150
  return value;
147
151
  return `${value.slice(0, maxLen)}…`;
148
152
  }
149
- var requireFromThisModule = createRequire(import.meta.url);
153
+ var TOKENIZER_PACKAGE_DIRS = [
154
+ ["@cortexkit", "opencode-magic-context"],
155
+ ["@cortexkit", "pi-magic-context"]
156
+ ];
150
157
  var tokenizer;
151
- function getTokenizer() {
158
+ var tokenizerLoadAttempted = false;
159
+ var tokenizerLoadPromise;
160
+ var tokenizerWarningSent = false;
161
+ function tokenizerPackageRoots() {
162
+ const cwd = process.cwd();
163
+ const openCodeCache = join(process.env.XDG_CACHE_HOME ?? join(homedir(), ".cache"), "opencode");
164
+ const roots = [cwd, openCodeCache];
165
+ const candidates = [];
166
+ for (const root of roots) {
167
+ for (const packageDir of TOKENIZER_PACKAGE_DIRS) {
168
+ candidates.push(join(root, "node_modules", ...packageDir, "node_modules", "ai-tokenizer"));
169
+ }
170
+ candidates.push(join(root, "node_modules", "ai-tokenizer"));
171
+ }
172
+ let ancestor = process.argv[1] ? dirname(resolve(process.argv[1])) : cwd;
173
+ while (true) {
174
+ candidates.push(join(ancestor, "node_modules", "ai-tokenizer"));
175
+ const parent = dirname(ancestor);
176
+ if (parent === ancestor)
177
+ break;
178
+ ancestor = parent;
179
+ }
180
+ return [...new Set(candidates)];
181
+ }
182
+ function packageImportTarget(value) {
183
+ if (typeof value === "string")
184
+ return value;
185
+ if (!value || typeof value !== "object")
186
+ return;
187
+ const conditions = value;
188
+ return packageImportTarget(conditions.import) ?? packageImportTarget(conditions.default);
189
+ }
190
+ function findTokenizerImportPaths() {
191
+ for (const packageRoot of tokenizerPackageRoots()) {
192
+ const packageJsonPath = join(packageRoot, "package.json");
193
+ if (!existsSync(packageJsonPath))
194
+ continue;
195
+ try {
196
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
197
+ const tokenizerTarget = packageImportTarget(packageJson.exports?.["."]) ?? (typeof packageJson.module === "string" ? packageJson.module : undefined) ?? (typeof packageJson.main === "string" ? packageJson.main : undefined);
198
+ const encodingTarget = packageImportTarget(packageJson.exports?.["./encoding/claude"]);
199
+ if (!tokenizerTarget || !encodingTarget)
200
+ continue;
201
+ return {
202
+ tokenizerPath: realpathSync(join(packageRoot, tokenizerTarget)),
203
+ encodingPath: realpathSync(join(packageRoot, encodingTarget))
204
+ };
205
+ } catch {}
206
+ }
207
+ return;
208
+ }
209
+ function constructTokenizer(tokenizerModule, claudeEncoding) {
210
+ const typedModule = tokenizerModule;
211
+ const Tokenizer = typedModule.default ?? typedModule.Tokenizer;
212
+ if (!Tokenizer) {
213
+ throw new Error("ai-tokenizer does not expose a Tokenizer constructor");
214
+ }
215
+ return new Tokenizer(claudeEncoding);
216
+ }
217
+ function loadTokenizer() {
218
+ const requireFromThisModule = createRequire(import.meta.url);
219
+ return constructTokenizer(requireFromThisModule("ai-" + "tokenizer"), requireFromThisModule("ai-tokenizer/encoding/" + "claude"));
220
+ }
221
+ async function loadTokenizerFromInstalledPackage() {
222
+ const installedPaths = findTokenizerImportPaths();
223
+ if (!installedPaths) {
224
+ throw new Error("ai-tokenizer was not found under the project, runtime, or OpenCode cache node_modules roots");
225
+ }
226
+ const [tokenizerModule, claudeEncoding] = await Promise.all([
227
+ import(pathToFileURL(installedPaths.tokenizerPath).href),
228
+ import(pathToFileURL(installedPaths.encodingPath).href)
229
+ ]);
230
+ return constructTokenizer(tokenizerModule, claudeEncoding);
231
+ }
232
+ function warnTokenizerFallback(error) {
233
+ if (tokenizerWarningSent)
234
+ return;
235
+ tokenizerWarningSent = true;
236
+ const reason = error instanceof Error ? error.message : String(error);
237
+ 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);
238
+ }
239
+ async function preloadTokenizer() {
152
240
  if (tokenizer)
241
+ return true;
242
+ if (tokenizerLoadAttempted)
243
+ return false;
244
+ if (tokenizerLoadPromise)
245
+ return tokenizerLoadPromise;
246
+ tokenizerLoadPromise = (async () => {
247
+ try {
248
+ try {
249
+ tokenizer = loadTokenizer();
250
+ } catch {
251
+ tokenizer = await loadTokenizerFromInstalledPackage();
252
+ }
253
+ tokenizerLoadAttempted = true;
254
+ return true;
255
+ } catch (error) {
256
+ tokenizerLoadAttempted = true;
257
+ warnTokenizerFallback(error);
258
+ return false;
259
+ } finally {
260
+ tokenizerLoadPromise = undefined;
261
+ }
262
+ })();
263
+ return tokenizerLoadPromise;
264
+ }
265
+ function getTokenizer() {
266
+ if (tokenizer || tokenizerLoadAttempted)
153
267
  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);
268
+ tokenizerLoadAttempted = true;
269
+ try {
270
+ tokenizer = loadTokenizer();
271
+ } catch (error) {
272
+ warnTokenizerFallback(error);
273
+ }
160
274
  return tokenizer;
161
275
  }
276
+ function estimateTokensHeuristically(text) {
277
+ return Math.ceil(text.length / 3.5);
278
+ }
162
279
  function estimateTokens(text) {
163
280
  if (!text)
164
281
  return 0;
165
- return getTokenizer().encode(text, "all").length;
282
+ const activeTokenizer = getTokenizer();
283
+ if (!activeTokenizer)
284
+ return estimateTokensHeuristically(text);
285
+ try {
286
+ return activeTokenizer.encode(text, "all").length;
287
+ } catch (error) {
288
+ tokenizer = undefined;
289
+ tokenizerLoadAttempted = true;
290
+ warnTokenizerFallback(error);
291
+ return estimateTokensHeuristically(text);
292
+ }
166
293
  }
167
294
  function normalizeText(text) {
168
295
  return text.replace(/\s+/g, " ").trim();
@@ -2889,4 +3016,4 @@ function clearSession(db, sessionId) {
2889
3016
  })();
2890
3017
  }
2891
3018
 
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 };
3019
+ 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 };
@@ -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 };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getMagicContextLogPath
3
- } from "./index-kvrcg31b.js";
3
+ } from "./index-mmrhhk9a.js";
4
4
 
5
5
  // src/shared/logger.ts
6
6
  import * as fs from "node:fs";
@@ -5,7 +5,7 @@ function getHarness() {
5
5
  }
6
6
 
7
7
  // src/shared/data-path.ts
8
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
8
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
9
9
  import * as os from "node:os";
10
10
  import * as path from "node:path";
11
11
  function getDataDir() {
@@ -54,6 +54,13 @@ function getOpenCodeStorageDir() {
54
54
  return path.join(getDataDir(), "opencode", "storage");
55
55
  }
56
56
  function getMagicContextStorageDir() {
57
+ if (!process.env.XDG_DATA_HOME) {
58
+ const testDataDir = process.env.MAGIC_CONTEXT_TEST_DATA_DIR;
59
+ if (testDataDir) {
60
+ return path.join(testDataDir, "cortexkit", "magic-context");
61
+ }
62
+ if (false) {}
63
+ }
57
64
  return path.join(getDataDir(), "cortexkit", "magic-context");
58
65
  }
59
66
  function getLegacyOpenCodeMagicContextStorageDir() {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  isMidTurn
3
- } from "./index-w0nygb4p.js";
3
+ } from "./index-3tnkymva.js";
4
4
  import {
5
5
  sessionLog
6
- } from "./index-k1esqfwk.js";
6
+ } from "./index-f1tnb3vm.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-q9jk5n44.js");
174
+ const { waitForSafeNotificationTarget } = await import("./safe-notification-target-c11fdda2.js");
175
175
  if (await waitForSafeNotificationTarget(client, sessionId) === "skip") {
176
176
  sessionLog(sessionId, "notification skipped (session not titled yet)");
177
177
  return "skipped";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getMagicContextStorageDir
3
- } from "./index-kvrcg31b.js";
3
+ } from "./index-mmrhhk9a.js";
4
4
 
5
5
  // src/shared/announcement.ts
6
6
  import * as fs from "node:fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  log
3
- } from "./index-k1esqfwk.js";
3
+ } from "./index-f1tnb3vm.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$/;
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  sessionLog
3
- } from "./index-k1esqfwk.js";
3
+ } from "./index-f1tnb3vm.js";
4
4
  import {
5
5
  getHarness,
6
6
  getMagicContextStorageDir
7
- } from "./index-kvrcg31b.js";
7
+ } from "./index-mmrhhk9a.js";
8
8
 
9
9
  // src/shared/models-dev-cache.ts
10
10
  import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
@@ -22,8 +22,9 @@ function remapProviderPrefix(ref, map) {
22
22
  if (slash <= 0)
23
23
  return ref;
24
24
  const provider = ref.slice(0, slash);
25
- const mapped = map[provider];
26
- return mapped ? `${mapped}${ref.slice(slash)}` : ref;
25
+ if (!Object.hasOwn(map, provider))
26
+ return ref;
27
+ return `${map[provider]}${ref.slice(slash)}`;
27
28
  }
28
29
  function piModelRefToCanonical(ref) {
29
30
  return remapProviderPrefix(ref, PI_TO_CANONICAL_PROVIDER);
@@ -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-73xz0247.js";
6
+ } from "./index-tsgs7td8.js";
7
7
  import {
8
8
  log
9
- } from "./index-k1esqfwk.js";
9
+ } from "./index-f1tnb3vm.js";
10
10
  import {
11
11
  __require
12
12
  } from "./index-wckvcay0.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA0xBvE,QAAA,MAAM,MAAM,EAAE,YAGb,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAuyBvE,QAAA,MAAM,MAAM,EAAE,YAGb,CAAC;AAEF,eAAe,MAAM,CAAC"}