@cortexkit/opencode-magic-context 0.34.1 → 0.35.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 (109) hide show
  1. package/README.md +3 -1
  2. package/dist/agents/magic-context-prompt.d.ts +2 -1
  3. package/dist/agents/magic-context-prompt.d.ts.map +1 -1
  4. package/dist/config/index.d.ts +3 -0
  5. package/dist/config/index.d.ts.map +1 -1
  6. package/dist/config/project-security.d.ts +3 -0
  7. package/dist/config/project-security.d.ts.map +1 -1
  8. package/dist/config/schema/magic-context.d.ts +42 -1
  9. package/dist/config/schema/magic-context.d.ts.map +1 -1
  10. package/dist/{conflict-warning-hook-fvpfvt0w.js → conflict-warning-hook-p2pmhvn7.js} +2 -1
  11. package/dist/features/magic-context/context-authority.d.ts.map +1 -1
  12. package/dist/features/magic-context/dreamer/provider-output-failure.d.ts +15 -0
  13. package/dist/features/magic-context/dreamer/provider-output-failure.d.ts.map +1 -0
  14. package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts +9 -5
  15. package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts.map +1 -1
  16. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  17. package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
  18. package/dist/features/magic-context/dreamer/verify-gate.d.ts +8 -2
  19. package/dist/features/magic-context/dreamer/verify-gate.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/verify.d.ts +2 -0
  21. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  22. package/dist/features/magic-context/fail-closed-block.d.ts +2 -0
  23. package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
  24. package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -1
  25. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  26. package/dist/features/magic-context/mural/compress-cues.d.ts +13 -5
  27. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  28. package/dist/features/magic-context/mural/cue-validation.d.ts +7 -7
  29. package/dist/features/magic-context/mural/cue-validation.d.ts.map +1 -1
  30. package/dist/features/magic-context/mural/storage-mural-cues.d.ts +17 -7
  31. package/dist/features/magic-context/mural/storage-mural-cues.d.ts.map +1 -1
  32. package/dist/features/magic-context/storage-db.d.ts +21 -3
  33. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  34. package/dist/features/magic-context/storage-meta-persisted.d.ts +1 -0
  35. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  36. package/dist/hooks/magic-context/compartment-runner-historian.d.ts +2 -14
  37. package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
  38. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  39. package/dist/hooks/magic-context/compartment-runner-validation.d.ts +16 -2
  40. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
  41. package/dist/hooks/magic-context/event-handler.d.ts +1 -0
  42. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  44. package/dist/hooks/magic-context/hook.d.ts +10 -3
  45. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/module-state-sync.d.ts +1 -1
  47. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  48. package/dist/hooks/magic-context/module-transport.d.ts +2 -1
  49. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  50. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  51. package/dist/hooks/magic-context/read-session-chunk.d.ts +5 -0
  52. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  53. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +2 -0
  54. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
  55. package/dist/hooks/magic-context/rust-mode-transform.d.ts +22 -0
  56. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  57. package/dist/hooks/magic-context/system-prompt-hash.d.ts +19 -5
  58. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  59. package/dist/hooks/magic-context/transform-context-state.d.ts +1 -0
  60. package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -1
  61. package/dist/hooks/magic-context/transform.d.ts +4 -0
  62. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  63. package/dist/index-0c9dmw9m.js +116 -0
  64. package/dist/{index-x8spt5wy.js → index-4anesz49.js} +849 -633
  65. package/dist/{index-dtas91s5.js → index-8aaadh98.js} +7 -119
  66. package/dist/{index-b563sga5.js → index-h8mk7vpa.js} +541 -7
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +1010 -840
  69. package/dist/plugin/hooks/create-session-hooks.d.ts +12 -0
  70. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  71. package/dist/plugin/rpc-handlers.d.ts +1 -0
  72. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  73. package/dist/plugin/tool-registry.d.ts +4 -0
  74. package/dist/plugin/tool-registry.d.ts.map +1 -1
  75. package/dist/{recomp-orchestrator-k72ejkkh.js → recomp-orchestrator-zc915ceq.js} +3 -2
  76. package/dist/shared/index.d.ts +2 -0
  77. package/dist/shared/index.d.ts.map +1 -1
  78. package/dist/shared/prompt-surface-runtime.d.ts +43 -0
  79. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -0
  80. package/dist/shared/prompt-surface.d.ts +49 -0
  81. package/dist/shared/prompt-surface.d.ts.map +1 -0
  82. package/dist/{storage-meta-session-xt41zbw4.js → storage-meta-session-53cjs6mr.js} +1 -1
  83. package/dist/tools/ctx-expand/tools.d.ts +1 -0
  84. package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
  85. package/dist/tools/ctx-memory/tools.d.ts +1 -0
  86. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  87. package/dist/tools/ctx-note/tools.d.ts +1 -0
  88. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  89. package/dist/tools/ctx-reduce/tools.d.ts +1 -0
  90. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  91. package/dist/tools/ctx-search/tools.d.ts +1 -0
  92. package/dist/tools/ctx-search/tools.d.ts.map +1 -1
  93. package/dist/tools/light-descriptions.d.ts +6 -0
  94. package/dist/tools/light-descriptions.d.ts.map +1 -0
  95. package/package.json +1 -1
  96. package/src/agents/magic-context-prompt.test.ts +144 -0
  97. package/src/agents/magic-context-prompt.ts +53 -2
  98. package/src/config/index.test.ts +53 -0
  99. package/src/config/index.ts +4 -0
  100. package/src/config/project-security.test.ts +20 -0
  101. package/src/config/project-security.ts +23 -0
  102. package/src/config/schema/magic-context.test.ts +58 -0
  103. package/src/config/schema/magic-context.ts +61 -1
  104. package/src/shared/index.ts +2 -0
  105. package/src/shared/prompt-surface-a1-golden.md +458 -0
  106. package/src/shared/prompt-surface-runtime.test.ts +141 -0
  107. package/src/shared/prompt-surface-runtime.ts +250 -0
  108. package/src/shared/prompt-surface.test.ts +109 -0
  109. package/src/shared/prompt-surface.ts +138 -0
package/dist/index.js CHANGED
@@ -85,11 +85,15 @@ import {
85
85
  computeNormalizedHash,
86
86
  computeWorkspaceEpochFingerprint,
87
87
  contentSha256,
88
+ cortexKitProjectConfigBasePath,
89
+ cortexKitUserConfigBasePath,
88
90
  cosineSimilarity,
89
91
  countEmbeddedCommits,
90
92
  countPrimerCandidatesForProject,
91
93
  createChildSessionWithFence,
92
94
  createPrimer,
95
+ createPromptSurfaceGuidanceEpochCache,
96
+ createPromptSurfaceRuntime,
93
97
  deleteTagsByMessageId,
94
98
  deleteUserMemoryCandidates,
95
99
  deriveTagLoadFloor,
@@ -111,7 +115,6 @@ import {
111
115
  ensureContextStoreUuid,
112
116
  ensureMemoryEmbeddings,
113
117
  escalationBands,
114
- estimateTrueRawMessageTokens,
115
118
  expandWorkspaceIdentitySetWithAliases,
116
119
  exports_external,
117
120
  extractLatestAssistantText,
@@ -138,6 +141,7 @@ import {
138
141
  getDroppedTagsBySession,
139
142
  getEmbeddingCoverageStatus,
140
143
  getEmergencyInputSample,
144
+ getEmergencyRecoveryArmedAt,
141
145
  getHistorianFailureState,
142
146
  getLastCompartmentEndMessage,
143
147
  getLastCompartmentEndMessageId,
@@ -219,7 +223,6 @@ import {
219
223
  insertUserMemoryCandidates,
220
224
  invalidateMemory,
221
225
  invalidateProject,
222
- invalidateTrueRawTokenCache,
223
226
  isConsumerReconnectTransient,
224
227
  isDatabasePersisted,
225
228
  isEmbeddingEnabled,
@@ -240,6 +243,7 @@ import {
240
243
  markProjectLoadUntrusted,
241
244
  memoryNeedsCue,
242
245
  mergeMemoryStats,
246
+ migrateMagicContextConfigLocations,
243
247
  mustMaterialize,
244
248
  nextDueAtMs,
245
249
  nextOccurrence,
@@ -261,6 +265,7 @@ import {
261
265
  prepareCompartmentInjection,
262
266
  primerOccurrenceKey,
263
267
  primerOccurrenceUtcDay,
268
+ promptSurfaceHashMaterial,
264
269
  promptSyncWithValidatedOutputRetry,
265
270
  pruneAutoSearchHintDecisions,
266
271
  pruneExpiredUserMemoryCandidates,
@@ -279,6 +284,7 @@ import {
279
284
  recordHighPressureNoEligibleHead,
280
285
  recordMemoryMapping,
281
286
  recordMemoryVerifications,
287
+ recordMuralCueRejection,
282
288
  recordOverflowDetected,
283
289
  recordSessionProjectIdentity,
284
290
  recordToolDefinition,
@@ -307,10 +313,14 @@ import {
307
313
  resetProtectedTailNoEligibleHead,
308
314
  resolveCompactionModeRecord,
309
315
  resolveGitTopLevel,
316
+ resolveLegacyConfigSources,
317
+ resolveLegacyConfigSourcesForHarness,
318
+ resolveModelConfigOrDefault,
310
319
  resolveOpenCodeProtectedTailBoundary,
311
320
  resolveProjectIdentity,
312
321
  resolveProjectIdentityForSession,
313
322
  resolveProjectIdentityStrict,
323
+ resolvePromptSurface,
314
324
  resolveStoredPathWorkspaceIdentity,
315
325
  resolveWorkspaceIdentitySet,
316
326
  resolveWorkspaceShareCategories,
@@ -372,7 +382,7 @@ import {
372
382
  upsertCommits,
373
383
  verificationFileExists,
374
384
  withContentLanguageDirective
375
- } from "./index-x8spt5wy.js";
385
+ } from "./index-4anesz49.js";
376
386
  import {
377
387
  deriveHistorianChunkTokens,
378
388
  deriveTriggerBudget,
@@ -409,6 +419,7 @@ import {
409
419
  createToolDropTarget,
410
420
  deleteIndexedMessage,
411
421
  estimateTokens,
422
+ estimateTrueRawMessageTokens,
412
423
  extractInMemoryMessageViews,
413
424
  extractTexts,
414
425
  extractToolCallObservation,
@@ -422,6 +433,7 @@ import {
422
433
  hasMeaningfulUserText,
423
434
  indexMessagesAfterOrdinal,
424
435
  indexSingleMessage,
436
+ invalidateTrueRawTokenCache,
425
437
  isEditTool,
426
438
  isFilePart,
427
439
  isMessageIndexReconciledThrough,
@@ -451,7 +463,7 @@ import {
451
463
  textMentionsRecentCommit,
452
464
  updateSessionMeta,
453
465
  withRawSessionMessageCache
454
- } from "./index-b563sga5.js";
466
+ } from "./index-h8mk7vpa.js";
455
467
  import {
456
468
  Database,
457
469
  closeQuietly,
@@ -463,12 +475,14 @@ import {
463
475
  } from "./index-fcyvznch.js";
464
476
  import {
465
477
  cleanupConflictWarnings,
466
- detectConfigFile,
467
478
  detectConflicts,
479
+ sendConflictWarning
480
+ } from "./index-8aaadh98.js";
481
+ import {
482
+ detectConfigFile,
468
483
  parseJsonc,
469
- sendConflictWarning,
470
484
  stripJsonComments
471
- } from "./index-dtas91s5.js";
485
+ } from "./index-0c9dmw9m.js";
472
486
  import {
473
487
  ANNOUNCEMENT_FEATURES,
474
488
  ANNOUNCEMENT_FOOTER,
@@ -8188,10 +8202,10 @@ var require_stringify = __commonJS((exports, module) => {
8188
8202
  replacer = null;
8189
8203
  indent = EMPTY;
8190
8204
  };
8191
- var join2 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two)), gap) : EMPTY;
8205
+ var join = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two)), gap) : EMPTY;
8192
8206
  var join_content = (inside, value, gap) => {
8193
8207
  const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
8194
- return join2(comment, inside, gap);
8208
+ return join(comment, inside, gap);
8195
8209
  };
8196
8210
  var stringify_string = (holder, key, value) => {
8197
8211
  const raw = get_raw_string_literal(holder, key);
@@ -8213,13 +8227,13 @@ var require_stringify = __commonJS((exports, module) => {
8213
8227
  if (i !== 0) {
8214
8228
  inside += COMMA;
8215
8229
  }
8216
- const before = join2(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
8230
+ const before = join(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
8217
8231
  inside += before || LF + deeper_gap;
8218
8232
  inside += stringify(i, value, deeper_gap) || STR_NULL;
8219
8233
  inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
8220
8234
  after_comma = process_comments(value, AFTER(i), deeper_gap);
8221
8235
  }
8222
- inside += join2(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
8236
+ inside += join(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
8223
8237
  return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
8224
8238
  };
8225
8239
  var object_stringify = (value, gap) => {
@@ -8240,13 +8254,13 @@ var require_stringify = __commonJS((exports, module) => {
8240
8254
  inside += COMMA;
8241
8255
  }
8242
8256
  first = false;
8243
- const before = join2(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
8257
+ const before = join(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
8244
8258
  inside += before || LF + deeper_gap;
8245
8259
  inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
8246
8260
  after_comma = process_comments(value, AFTER(key), deeper_gap);
8247
8261
  };
8248
8262
  keys.forEach(iteratee);
8249
- inside += join2(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
8263
+ inside += join(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
8250
8264
  return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
8251
8265
  };
8252
8266
  function stringify(key, holder, gap) {
@@ -8514,7 +8528,7 @@ function buildHiddenAgentConfig(prompt, allowedTools, maxSteps, overrides, agent
8514
8528
  }
8515
8529
 
8516
8530
  // src/config/index.ts
8517
- import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
8531
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
8518
8532
 
8519
8533
  // src/config/agent-disable.ts
8520
8534
  var COMPACTION_ENABLED_PATH = `compaction${"."}enabled`;
@@ -8576,384 +8590,6 @@ function migrateLegacyAgentEnabledInMemory(rawConfig, warnings) {
8576
8590
  return patched;
8577
8591
  }
8578
8592
 
8579
- // src/config/migrate-config-location.ts
8580
- import {
8581
- closeSync,
8582
- existsSync,
8583
- mkdirSync,
8584
- openSync,
8585
- readFileSync,
8586
- renameSync,
8587
- rmSync,
8588
- statSync,
8589
- unlinkSync,
8590
- writeFileSync
8591
- } from "node:fs";
8592
- import { homedir } from "node:os";
8593
- import { basename, dirname, isAbsolute, join } from "node:path";
8594
- var CONFIG_FILE_BASENAME = "magic-context";
8595
- var MOVED_MARKER_SUFFIX = ".MOVED_READPLEASE";
8596
- function homeDir() {
8597
- if (process.platform === "win32") {
8598
- return process.env.USERPROFILE || process.env.HOME || homedir();
8599
- }
8600
- return process.env.HOME || homedir();
8601
- }
8602
- function configHome() {
8603
- const xdg = process.env.XDG_CONFIG_HOME;
8604
- if (xdg && isAbsolute(xdg))
8605
- return xdg;
8606
- return join(homeDir(), ".config");
8607
- }
8608
- function cortexKitUserConfigBasePath() {
8609
- return join(configHome(), "cortexkit", CONFIG_FILE_BASENAME);
8610
- }
8611
- function cortexKitProjectConfigBasePath(directory) {
8612
- return join(directory, ".cortexkit", CONFIG_FILE_BASENAME);
8613
- }
8614
- function resolveCortexKitUserConfigPath() {
8615
- return `${cortexKitUserConfigBasePath()}.jsonc`;
8616
- }
8617
- function resolveCortexKitProjectConfigPath(directory) {
8618
- return `${cortexKitProjectConfigBasePath(directory)}.jsonc`;
8619
- }
8620
- function legacySourcesForBase(basePath, label) {
8621
- return [
8622
- { path: `${basePath}.jsonc`, label: `${label} magic-context.jsonc` },
8623
- { path: `${basePath}.json`, label: `${label} magic-context.json` }
8624
- ];
8625
- }
8626
- function userScopeConfigPaths() {
8627
- return new Set([
8628
- `${cortexKitUserConfigBasePath()}.jsonc`,
8629
- `${cortexKitUserConfigBasePath()}.json`,
8630
- join(configHome(), "opencode", `${CONFIG_FILE_BASENAME}.jsonc`),
8631
- join(configHome(), "opencode", `${CONFIG_FILE_BASENAME}.json`),
8632
- join(homeDir(), ".pi", "agent", `${CONFIG_FILE_BASENAME}.jsonc`),
8633
- join(homeDir(), ".pi", "agent", `${CONFIG_FILE_BASENAME}.json`)
8634
- ]);
8635
- }
8636
- function resolveLegacyConfigSources(directory) {
8637
- const userPaths = userScopeConfigPaths();
8638
- return {
8639
- user: [
8640
- ...legacySourcesForBase(join(configHome(), "opencode", CONFIG_FILE_BASENAME), "OpenCode user"),
8641
- ...legacySourcesForBase(join(homeDir(), ".pi", "agent", CONFIG_FILE_BASENAME), "Pi user")
8642
- ],
8643
- project: [
8644
- ...legacySourcesForBase(join(directory, CONFIG_FILE_BASENAME), "project root"),
8645
- ...legacySourcesForBase(join(directory, ".opencode", CONFIG_FILE_BASENAME), "OpenCode project"),
8646
- ...legacySourcesForBase(join(directory, ".pi", CONFIG_FILE_BASENAME), "Pi project")
8647
- ].filter((source) => !userPaths.has(source.path))
8648
- };
8649
- }
8650
- function resolveLegacyConfigSourcesForHarness(directory, harness) {
8651
- if (harness === "pi") {
8652
- return {
8653
- user: legacySourcesForBase(join(homeDir(), ".pi", "agent", CONFIG_FILE_BASENAME), "Pi user"),
8654
- project: legacySourcesForBase(join(directory, ".pi", CONFIG_FILE_BASENAME), "Pi project")
8655
- };
8656
- }
8657
- return {
8658
- user: legacySourcesForBase(join(configHome(), "opencode", CONFIG_FILE_BASENAME), "OpenCode user"),
8659
- project: [
8660
- ...legacySourcesForBase(join(directory, CONFIG_FILE_BASENAME), "project root"),
8661
- ...legacySourcesForBase(join(directory, ".opencode", CONFIG_FILE_BASENAME), "OpenCode project")
8662
- ]
8663
- };
8664
- }
8665
- function stripJsoncForParse(input) {
8666
- let out = "";
8667
- let inString = false;
8668
- let escaped = false;
8669
- for (let i = 0;i < input.length; i++) {
8670
- const ch = input[i];
8671
- const next = input[i + 1];
8672
- if (inString) {
8673
- out += ch;
8674
- if (escaped)
8675
- escaped = false;
8676
- else if (ch === "\\")
8677
- escaped = true;
8678
- else if (ch === '"')
8679
- inString = false;
8680
- continue;
8681
- }
8682
- if (ch === '"') {
8683
- inString = true;
8684
- out += ch;
8685
- continue;
8686
- }
8687
- if (ch === "/" && next === "/") {
8688
- while (i < input.length && input[i] !== `
8689
- `)
8690
- i++;
8691
- out += `
8692
- `;
8693
- continue;
8694
- }
8695
- if (ch === "/" && next === "*") {
8696
- i += 2;
8697
- while (i < input.length && !(input[i] === "*" && input[i + 1] === "/"))
8698
- i++;
8699
- i++;
8700
- out += " ";
8701
- continue;
8702
- }
8703
- out += ch;
8704
- }
8705
- let withoutTrailingCommas = "";
8706
- inString = false;
8707
- escaped = false;
8708
- for (let i = 0;i < out.length; i++) {
8709
- const ch = out[i];
8710
- if (inString) {
8711
- withoutTrailingCommas += ch;
8712
- if (escaped)
8713
- escaped = false;
8714
- else if (ch === "\\")
8715
- escaped = true;
8716
- else if (ch === '"')
8717
- inString = false;
8718
- continue;
8719
- }
8720
- if (ch === '"') {
8721
- inString = true;
8722
- withoutTrailingCommas += ch;
8723
- continue;
8724
- }
8725
- if (ch === ",") {
8726
- let j = i + 1;
8727
- while (j < out.length && /\s/.test(out[j]))
8728
- j++;
8729
- if (out[j] === "}" || out[j] === "]")
8730
- continue;
8731
- }
8732
- withoutTrailingCommas += ch;
8733
- }
8734
- return withoutTrailingCommas;
8735
- }
8736
- function sortJson(value) {
8737
- if (Array.isArray(value))
8738
- return value.map(sortJson);
8739
- if (value && typeof value === "object") {
8740
- const sorted = {};
8741
- for (const key of Object.keys(value).sort()) {
8742
- sorted[key] = sortJson(value[key]);
8743
- }
8744
- return sorted;
8745
- }
8746
- return value;
8747
- }
8748
- function normalizedJsoncSemantics(content) {
8749
- return JSON.stringify(sortJson(JSON.parse(stripJsoncForParse(content))));
8750
- }
8751
- function fileSemanticsMatch(a, b) {
8752
- try {
8753
- return normalizedJsoncSemantics(a) === normalizedJsoncSemantics(b);
8754
- } catch {
8755
- return a === b;
8756
- }
8757
- }
8758
- var CONFIG_LOCK_STALE_MS = 4000;
8759
- function acquireConfigMigrationLock(lockDir) {
8760
- for (let attempt = 0;attempt < 2; attempt++) {
8761
- try {
8762
- mkdirSync(lockDir, { recursive: false });
8763
- return () => {
8764
- try {
8765
- rmSync(lockDir, { recursive: true, force: true });
8766
- } catch {}
8767
- };
8768
- } catch (err) {
8769
- const code = err?.code;
8770
- if (code !== "EEXIST")
8771
- throw err;
8772
- try {
8773
- const ageMs = Date.now() - statSync(lockDir).mtimeMs;
8774
- if (ageMs > CONFIG_LOCK_STALE_MS) {
8775
- rmSync(lockDir, { recursive: true, force: true });
8776
- continue;
8777
- }
8778
- } catch {
8779
- continue;
8780
- }
8781
- return null;
8782
- }
8783
- }
8784
- return null;
8785
- }
8786
- function atomicCopyConfigFile(sourcePath, targetPath) {
8787
- mkdirSync(dirname(targetPath), { recursive: true });
8788
- const tmpPath = join(dirname(targetPath), `.${basename(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
8789
- let fd = null;
8790
- try {
8791
- fd = openSync(tmpPath, "wx", 384);
8792
- writeFileSync(fd, readFileSync(sourcePath));
8793
- closeSync(fd);
8794
- fd = null;
8795
- renameSync(tmpPath, targetPath);
8796
- } catch (err) {
8797
- if (fd !== null) {
8798
- try {
8799
- closeSync(fd);
8800
- } catch {}
8801
- }
8802
- try {
8803
- unlinkSync(tmpPath);
8804
- } catch {}
8805
- throw err;
8806
- }
8807
- }
8808
- function atomicWriteConfigFile(targetPath, content) {
8809
- mkdirSync(dirname(targetPath), { recursive: true });
8810
- const tmpPath = join(dirname(targetPath), `.${basename(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
8811
- let fd = null;
8812
- try {
8813
- fd = openSync(tmpPath, "wx", 384);
8814
- writeFileSync(fd, content);
8815
- closeSync(fd);
8816
- fd = null;
8817
- renameSync(tmpPath, targetPath);
8818
- } catch (err) {
8819
- if (fd !== null) {
8820
- try {
8821
- closeSync(fd);
8822
- } catch {}
8823
- }
8824
- try {
8825
- unlinkSync(tmpPath);
8826
- } catch {}
8827
- throw err;
8828
- }
8829
- }
8830
- function movedMarkerContent(targetPath, originalName, originalContent) {
8831
- const header = [
8832
- "// Magic Context configuration moved.",
8833
- "//",
8834
- "// Magic Context now reads its configuration from one shared CortexKit",
8835
- "// location instead of a per-agent path. The settings that were in this",
8836
- "// file have been moved to:",
8837
- "//",
8838
- `// ${targetPath}`,
8839
- "//",
8840
- "// Edit that file to change Magic Context settings. This location is no",
8841
- "// longer read by Magic Context.",
8842
- "//",
8843
- `// To undo, rename this file back to "${originalName}" (and remove the`,
8844
- "// CortexKit copy above if you want this location to take precedence).",
8845
- "//",
8846
- "// Your original settings are preserved below for reference.",
8847
- "",
8848
- ""
8849
- ].join(`
8850
- `);
8851
- return `${header}${originalContent}`;
8852
- }
8853
- function markLegacySourcesMovedAside(sources, targetPath, logger) {
8854
- const warnings = [];
8855
- const info = logger?.info ?? logger?.log;
8856
- for (const source of sources) {
8857
- const markerPath = `${source.path}${MOVED_MARKER_SUFFIX}`;
8858
- try {
8859
- const original = readFileSync(source.path, "utf-8");
8860
- atomicWriteConfigFile(markerPath, movedMarkerContent(targetPath, basename(source.path), original));
8861
- unlinkSync(source.path);
8862
- info?.(`Moved legacy Magic Context config ${source.path} aside to ${markerPath}; now reading ${targetPath}`);
8863
- } catch (err) {
8864
- const msg = err instanceof Error ? err.message : String(err);
8865
- warnings.push(`Magic Context could not move legacy config ${source.path} aside (${msg}); it is now stale and ignored. Delete it manually — config is read from ${targetPath}.`);
8866
- logger?.warn?.(`Could not move legacy Magic Context config ${source.path} aside (${msg}); reading ${targetPath}`);
8867
- }
8868
- }
8869
- return warnings;
8870
- }
8871
- function visibleConfigMigrationWarning(scope, targetPath, paths, reason) {
8872
- const uniquePaths = [...new Set([targetPath, ...paths])];
8873
- return `Magic Context ${scope} config migration refused: ${reason}. ` + `Legacy and CortexKit config paths collapse to one file, but Magic Context will not overwrite or merge them automatically. ` + `Please consolidate manually into ${targetPath}. Paths: ${uniquePaths.join(" ; ")}`;
8874
- }
8875
- function migrateConfigFile(opts) {
8876
- const warnings = [];
8877
- const existingSources = opts.legacySources.filter((source) => existsSync(source.path));
8878
- const info = opts.logger?.info ?? opts.logger?.log;
8879
- if (existingSources.length === 0) {
8880
- return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
8881
- }
8882
- mkdirSync(dirname(opts.targetPath), { recursive: true });
8883
- const release = acquireConfigMigrationLock(`${opts.targetPath}.lock`);
8884
- if (!release) {
8885
- warnings.push(`Config migration for ${opts.scope} skipped this run (another instance is migrating); will retry on next start.`);
8886
- return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
8887
- }
8888
- try {
8889
- const sources = existingSources.map((source) => ({
8890
- ...source,
8891
- content: readFileSync(source.path, "utf-8")
8892
- }));
8893
- if (existsSync(opts.targetPath)) {
8894
- const targetContent = readFileSync(opts.targetPath, "utf-8");
8895
- const differing2 = sources.filter((source) => !fileSemanticsMatch(source.content, targetContent));
8896
- if (differing2.length > 0) {
8897
- const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, differing2.map((source) => source.path), "the CortexKit target already exists with different settings");
8898
- warnings.push(message);
8899
- opts.logger?.warn?.(message);
8900
- return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
8901
- }
8902
- info?.(`Magic Context ${opts.scope} config already present at ${opts.targetPath}; legacy copies match`);
8903
- warnings.push(...markLegacySourcesMovedAside(sources, opts.targetPath, opts.logger));
8904
- return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
8905
- }
8906
- const first = sources[0];
8907
- const differing = sources.filter((source) => !fileSemanticsMatch(source.content, first.content));
8908
- if (differing.length > 0) {
8909
- const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, sources.map((source) => source.path), "multiple legacy sources have different settings");
8910
- warnings.push(message);
8911
- opts.logger?.warn?.(message);
8912
- return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
8913
- }
8914
- atomicCopyConfigFile(first.path, opts.targetPath);
8915
- info?.(`Migrated Magic Context ${opts.scope} config from ${first.path} to ${opts.targetPath}`);
8916
- warnings.push(...markLegacySourcesMovedAside(sources, opts.targetPath, opts.logger));
8917
- return {
8918
- migrated: true,
8919
- conflict: false,
8920
- sourcePath: first.path,
8921
- targetPath: opts.targetPath,
8922
- warnings
8923
- };
8924
- } catch (err) {
8925
- const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, existingSources.map((source) => source.path), `migration failed (${err instanceof Error ? err.message : String(err)})`);
8926
- warnings.push(message);
8927
- opts.logger?.warn?.(message);
8928
- return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
8929
- } finally {
8930
- release();
8931
- }
8932
- }
8933
- function migrateMagicContextConfigLocations(directory, logger) {
8934
- const warnings = [];
8935
- const legacy = resolveLegacyConfigSources(directory);
8936
- try {
8937
- warnings.push(...migrateConfigFile({
8938
- scope: "user",
8939
- targetPath: resolveCortexKitUserConfigPath(),
8940
- legacySources: legacy.user,
8941
- logger
8942
- }).warnings);
8943
- warnings.push(...migrateConfigFile({
8944
- scope: "project",
8945
- targetPath: resolveCortexKitProjectConfigPath(directory),
8946
- legacySources: legacy.project,
8947
- logger
8948
- }).warnings);
8949
- } catch (err) {
8950
- const msg = err instanceof Error ? err.message : String(err);
8951
- logger?.warn?.(`Magic Context config-location migration error (continuing): ${msg}`);
8952
- warnings.push(`Magic Context config-location migration error: ${msg}`);
8953
- }
8954
- return warnings;
8955
- }
8956
-
8957
8593
  // src/config/migrate-dreamer-v2.ts
8958
8594
  var OLD_VERIFY_TASK = "verify";
8959
8595
  var OLD_CURATE_TASKS = ["consolidate", "archive-stale", "improve"];
@@ -9265,6 +8901,7 @@ function migrateLegacyExperimental(rawConfig, warnings) {
9265
8901
  // src/config/project-security.ts
9266
8902
  var HIDDEN_AGENT_KEYS = ["historian", "dreamer", "sidekick"];
9267
8903
  var HISTORIAN_USER_ONLY_FIELDS = ["model", "fallback_models"];
8904
+ var PROMPT_SURFACE_USER_ONLY_FIELDS = ["guidance_override_path", "tool_descriptions"];
9268
8905
  var AGENT_ESCALATION_FIELDS = ["prompt", "permission", "tools", "system_prompt"];
9269
8906
  var EMBEDDING_DESTINATION_FIELDS = ["endpoint", "provider", "fallback_provider"];
9270
8907
  var PERCENTAGE_THRESHOLD_REASON = "security: a repository may only raise compaction thresholds above the user's effective value; it cannot force earlier historian work or cloned-repo cost escalation.";
@@ -9400,6 +9037,19 @@ function stripUnsafeProjectConfigFields(projectRaw) {
9400
9037
  delete storage.enforce_private_permissions;
9401
9038
  warnings.push("Ignoring storage.enforce_private_permissions from project config (security: only user-level config may opt into externally managed shared storage permissions).");
9402
9039
  }
9040
+ const promptSurface = projectRaw.prompt_surface;
9041
+ if (isPlainObject(promptSurface)) {
9042
+ const removed = [];
9043
+ for (const field of PROMPT_SURFACE_USER_ONLY_FIELDS) {
9044
+ if (field in promptSurface) {
9045
+ delete promptSurface[field];
9046
+ removed.push(field);
9047
+ }
9048
+ }
9049
+ if (removed.length > 0) {
9050
+ warnings.push(`Ignoring prompt_surface.${removed.join("/")} from project config (security: repositories may select prompt presets but only user config may provide guidance or tool-description text).`);
9051
+ }
9052
+ }
9403
9053
  const pi = projectRaw.pi;
9404
9054
  if (isPlainObject(pi) && "subagent_extensions" in pi) {
9405
9055
  delete pi.subagent_extensions;
@@ -9647,13 +9297,13 @@ function resolveTransformMode(args) {
9647
9297
  }
9648
9298
 
9649
9299
  // src/config/variable.ts
9650
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
9651
- import { homedir as homedir2 } from "node:os";
9652
- import { dirname as dirname2, isAbsolute as isAbsolute2, resolve } from "node:path";
9300
+ import { existsSync, readFileSync } from "node:fs";
9301
+ import { homedir } from "node:os";
9302
+ import { dirname, isAbsolute, resolve } from "node:path";
9653
9303
  var ENV_PATTERN = /\{env:([^}]+)\}/g;
9654
9304
  var FILE_PATTERN = /\{file:([^}]+)\}/g;
9655
9305
  function sensitiveFilePathReason(resolvedPath) {
9656
- const home = homedir2();
9306
+ const home = homedir();
9657
9307
  const sensitiveDirs = [
9658
9308
  { dir: resolve(home, ".ssh"), label: "SSH keys" },
9659
9309
  { dir: resolve(home, ".aws"), label: "AWS credentials" },
@@ -9698,7 +9348,7 @@ function substituteConfigVariables(input) {
9698
9348
  if (fileMatches.length === 0) {
9699
9349
  return { text, warnings };
9700
9350
  }
9701
- const configDir = input.configPath ? dirname2(input.configPath) : process.cwd();
9351
+ const configDir = input.configPath ? dirname(input.configPath) : process.cwd();
9702
9352
  let output = "";
9703
9353
  let cursor = 0;
9704
9354
  for (const match of fileMatches) {
@@ -9716,21 +9366,21 @@ function substituteConfigVariables(input) {
9716
9366
  }
9717
9367
  let filePath = rawPath.trim();
9718
9368
  if (filePath.startsWith("~/")) {
9719
- filePath = resolve(homedir2(), filePath.slice(2));
9720
- } else if (!isAbsolute2(filePath)) {
9369
+ filePath = resolve(homedir(), filePath.slice(2));
9370
+ } else if (!isAbsolute(filePath)) {
9721
9371
  filePath = resolve(configDir, filePath);
9722
9372
  }
9723
9373
  const sensitiveReason = sensitiveFilePathReason(filePath);
9724
9374
  if (sensitiveReason) {
9725
9375
  warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
9726
9376
  }
9727
- if (!existsSync2(filePath)) {
9377
+ if (!existsSync(filePath)) {
9728
9378
  warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
9729
9379
  continue;
9730
9380
  }
9731
9381
  let contents;
9732
9382
  try {
9733
- contents = readFileSync2(filePath, "utf-8").trim();
9383
+ contents = readFileSync(filePath, "utf-8").trim();
9734
9384
  } catch (error) {
9735
9385
  const message = error instanceof Error ? error.message : String(error);
9736
9386
  warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
@@ -9750,15 +9400,15 @@ function getProjectConfigBasePath(directory) {
9750
9400
  return cortexKitProjectConfigBasePath(directory);
9751
9401
  }
9752
9402
  function resolveLegacyReadFallback(sources) {
9753
- return { source: sources.find((s) => existsSync3(s.path)) ?? null };
9403
+ return { source: sources.find((s) => existsSync2(s.path)) ?? null };
9754
9404
  }
9755
9405
  function loadConfigFileDetailed(configPath, source) {
9756
- if (!existsSync3(configPath)) {
9406
+ if (!existsSync2(configPath)) {
9757
9407
  return null;
9758
9408
  }
9759
9409
  let rawText;
9760
9410
  try {
9761
- rawText = readFileSync3(configPath, "utf-8");
9411
+ rawText = readFileSync2(configPath, "utf-8");
9762
9412
  } catch (error) {
9763
9413
  return {
9764
9414
  config: {},
@@ -9917,9 +9567,6 @@ function parsePluginConfig(rawConfig, recoveredTopLevelKeys = []) {
9917
9567
  configWarnings: [...preMigrationWarnings, ...warnings]
9918
9568
  };
9919
9569
  }
9920
- function loadPluginConfig(directory) {
9921
- return loadPluginConfigDetailed(directory).config;
9922
- }
9923
9570
  function hasUserTierSubcConfig(config) {
9924
9571
  const subc = config?.subc;
9925
9572
  if (typeof subc !== "object" || subc === null || Array.isArray(subc))
@@ -9975,8 +9622,8 @@ function loadPluginConfigDetailed(directory) {
9975
9622
  const harnessLegacy = resolveLegacyConfigSourcesForHarness(directory, "opencode");
9976
9623
  const userLegacyFallback = userDetected.format === "none" ? resolveLegacyReadFallback(harnessLegacy.user) : { source: null };
9977
9624
  const projectLegacyFallback = projectDetected.format === "none" ? resolveLegacyReadFallback(harnessLegacy.project) : { source: null };
9978
- const legacyUserUnmigrated = userDetected.format === "none" && !userLegacyFallback.source && legacySources.user.some((source) => existsSync3(source.path));
9979
- const legacyProjectUnmigrated = projectDetected.format === "none" && !projectLegacyFallback.source && legacySources.project.some((source) => existsSync3(source.path));
9625
+ const legacyUserUnmigrated = userDetected.format === "none" && !userLegacyFallback.source && legacySources.user.some((source) => existsSync2(source.path));
9626
+ const legacyProjectUnmigrated = projectDetected.format === "none" && !projectLegacyFallback.source && legacySources.project.some((source) => existsSync2(source.path));
9980
9627
  const userLoaded = userDetected.format !== "none" ? loadConfigFileDetailed(userDetected.path, "user") : userLegacyFallback.source ? loadConfigFileDetailed(userLegacyFallback.source.path, "user") : null;
9981
9628
  const projectLoaded = projectDetected.format !== "none" ? loadConfigFileDetailed(projectDetected.path, "project") : projectLegacyFallback.source ? loadConfigFileDetailed(projectLegacyFallback.source.path, "project") : null;
9982
9629
  const allWarnings = [];
@@ -10048,6 +9695,7 @@ function loadPluginConfigDetailed(directory) {
10048
9695
  };
10049
9696
  return {
10050
9697
  config,
9698
+ registrationPromptSurface: trustedBaseConfig.prompt_surface,
10051
9699
  loadOutcome: combinedOutcome({ sources, substitutionFailures, recoveredTopLevelKeys }),
10052
9700
  sources,
10053
9701
  substitutionFailures,
@@ -10096,10 +9744,10 @@ function getMagicContextBuiltinCommands(compactionEnabled = true) {
10096
9744
  }
10097
9745
 
10098
9746
  // src/features/magic-context/dreamer/open-opencode-db.ts
10099
- import { existsSync as existsSync4 } from "node:fs";
9747
+ import { existsSync as existsSync3 } from "node:fs";
10100
9748
  function openOpenCodeDb() {
10101
9749
  const dbPath = getOpenCodeDbPath();
10102
- if (!existsSync4(dbPath)) {
9750
+ if (!existsSync3(dbPath)) {
10103
9751
  log(`[dreamer] OpenCode DB not found at ${dbPath} — skipping OpenCode history scan`);
10104
9752
  return null;
10105
9753
  }
@@ -10469,6 +10117,15 @@ function formatFailClosedBlockingProcesses(processes) {
10469
10117
  }
10470
10118
  function formatFailClosedBlockingMessage(reason) {
10471
10119
  if (reason.kind === "migration_guard") {
10120
+ if (reason.unreadableFile) {
10121
+ const arm = reason.unreadableArm ?? "io";
10122
+ 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.`;
10123
+ return [
10124
+ `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.`,
10125
+ recovery,
10126
+ `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
10127
+ ].join(" ");
10128
+ }
10472
10129
  return [
10473
10130
  `Magic Context cannot migrate the shared database because ${formatFailClosedBlockingProcesses(reason.blockingProcesses)} may be running an older Magic Context build that would fail against the migrated database.`,
10474
10131
  "Restart the blocking process (it will pick up the new build and migrate on start), or shut it down and retry.",
@@ -10577,7 +10234,7 @@ function getLastHookInitFailure() {
10577
10234
 
10578
10235
  // src/features/magic-context/session-project-backfill.ts
10579
10236
  import { randomUUID } from "node:crypto";
10580
- import { existsSync as existsSync5 } from "node:fs";
10237
+ import { existsSync as existsSync4 } from "node:fs";
10581
10238
  var LEASE_TTL_MS = 10 * 60 * 1000;
10582
10239
  var SESSION_PAGE_SIZE = 100;
10583
10240
  var SESSION_QUERY_CHUNK_SIZE = 250;
@@ -10773,7 +10430,7 @@ async function runSessionProjectBackfill(db, source, options = {}) {
10773
10430
  if (!session.directory) {
10774
10431
  result.skippedEmptyDirectories += 1;
10775
10432
  } else {
10776
- const stillExists = existenceCache.get(session.directory) ?? existsSync5(session.directory);
10433
+ const stillExists = existenceCache.get(session.directory) ?? existsSync4(session.directory);
10777
10434
  existenceCache.set(session.directory, stillExists);
10778
10435
  if (!stillExists) {
10779
10436
  result.skippedDeadDirectories += 1;
@@ -11198,45 +10855,45 @@ async function runDeferredV22Backfill(db, options = {}) {
11198
10855
  }
11199
10856
 
11200
10857
  // src/hooks/auto-update-checker/index.ts
11201
- import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as readFileSync5, renameSync as renameSync3, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "node:fs";
11202
- import { dirname as dirname4, join as join4 } from "node:path";
10858
+ import { existsSync as existsSync6, mkdirSync, readFileSync as readFileSync4, renameSync as renameSync2, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
10859
+ import { dirname as dirname3, join as join3 } from "node:path";
11203
10860
 
11204
10861
  // src/hooks/auto-update-checker/checker.ts
11205
10862
  var import_comment_json = __toESM(require_src2(), 1);
11206
10863
  import { spawn } from "node:child_process";
11207
10864
  import {
11208
10865
  accessSync,
11209
- existsSync as existsSync6,
10866
+ existsSync as existsSync5,
11210
10867
  constants as fsConstants,
11211
- readFileSync as readFileSync4,
11212
- renameSync as renameSync2,
11213
- statSync as statSync2,
11214
- writeFileSync as writeFileSync2
10868
+ readFileSync as readFileSync3,
10869
+ renameSync,
10870
+ statSync,
10871
+ writeFileSync
11215
10872
  } from "node:fs";
11216
- import { dirname as dirname3, isAbsolute as isAbsolute3, join as join3, resolve as resolve2 } from "node:path";
10873
+ import { dirname as dirname2, isAbsolute as isAbsolute2, join as join2, resolve as resolve2 } from "node:path";
11217
10874
  import { fileURLToPath } from "node:url";
11218
10875
 
11219
10876
  // src/hooks/auto-update-checker/constants.ts
11220
- import { homedir as homedir3, platform } from "node:os";
11221
- import { join as join2 } from "node:path";
10877
+ import { homedir as homedir2, platform } from "node:os";
10878
+ import { join } from "node:path";
11222
10879
  var PACKAGE_NAME = "@cortexkit/opencode-magic-context";
11223
10880
  var NPM_REGISTRY_URL = "https://registry.npmjs.org";
11224
10881
  var NPM_FETCH_TIMEOUT = 1e4;
11225
10882
  function getOpenCodeCacheRoot() {
11226
10883
  if (platform() === "win32") {
11227
- return join2(process.env.LOCALAPPDATA ?? homedir3(), "opencode");
10884
+ return join(process.env.LOCALAPPDATA ?? homedir2(), "opencode");
11228
10885
  }
11229
- return join2(homedir3(), ".cache", "opencode");
10886
+ return join(homedir2(), ".cache", "opencode");
11230
10887
  }
11231
10888
  function getOpenCodeConfigRoot() {
11232
10889
  if (platform() === "win32") {
11233
- return join2(process.env.APPDATA ?? join2(homedir3(), "AppData", "Roaming"), "opencode");
10890
+ return join(process.env.APPDATA ?? join(homedir2(), "AppData", "Roaming"), "opencode");
11234
10891
  }
11235
- return join2(process.env.XDG_CONFIG_HOME ?? join2(homedir3(), ".config"), "opencode");
10892
+ return join(process.env.XDG_CONFIG_HOME ?? join(homedir2(), ".config"), "opencode");
11236
10893
  }
11237
- var CACHE_DIR = join2(getOpenCodeCacheRoot(), "packages");
11238
- var USER_OPENCODE_CONFIG = join2(getOpenCodeConfigRoot(), "opencode.json");
11239
- var USER_OPENCODE_CONFIG_JSONC = join2(getOpenCodeConfigRoot(), "opencode.jsonc");
10894
+ var CACHE_DIR = join(getOpenCodeCacheRoot(), "packages");
10895
+ var USER_OPENCODE_CONFIG = join(getOpenCodeConfigRoot(), "opencode.json");
10896
+ var USER_OPENCODE_CONFIG_JSONC = join(getOpenCodeConfigRoot(), "opencode.jsonc");
11240
10897
 
11241
10898
  // src/hooks/auto-update-checker/types.ts
11242
10899
  var NpmPackageEnvelopeSchema = exports_external.object({
@@ -11297,17 +10954,17 @@ function extractChannel(version) {
11297
10954
  }
11298
10955
  function getSurfaceConfigPaths(directory, surface) {
11299
10956
  const name = surface === "server" ? "opencode" : "tui";
11300
- const globalDir = dirname3(USER_OPENCODE_CONFIG);
10957
+ const globalDir = dirname2(USER_OPENCODE_CONFIG);
11301
10958
  const dirs = [
11302
10959
  globalDir,
11303
10960
  directory,
11304
- join3(directory, ".opencode"),
10961
+ join2(directory, ".opencode"),
11305
10962
  process.env.OPENCODE_CONFIG_DIR
11306
10963
  ].filter((value) => Boolean(value));
11307
10964
  const paths = [];
11308
10965
  for (const dir of dirs) {
11309
10966
  for (const extension of ["json", "jsonc"]) {
11310
- const path2 = join3(dir, `${name}.${extension}`);
10967
+ const path2 = join2(dir, `${name}.${extension}`);
11311
10968
  if (!paths.includes(path2))
11312
10969
  paths.push(path2);
11313
10970
  }
@@ -11318,9 +10975,9 @@ function getWinningConfig(directory, surface) {
11318
10975
  let winner = null;
11319
10976
  for (const path2 of getSurfaceConfigPaths(directory, surface)) {
11320
10977
  try {
11321
- if (!existsSync6(path2))
10978
+ if (!existsSync5(path2))
11322
10979
  continue;
11323
- const parsed = parseJsonConfig(readFileSync4(path2, "utf-8"));
10980
+ const parsed = parseJsonConfig(readFileSync3(path2, "utf-8"));
11324
10981
  const entries = getPluginEntries(parsed);
11325
10982
  if (entries.some((entry) => entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`))) {
11326
10983
  if (winner) {
@@ -11343,24 +11000,24 @@ function resolvePathPluginSpec(spec, configPath) {
11343
11000
  return spec.replace(/^file:\/\//, "");
11344
11001
  }
11345
11002
  }
11346
- if (isAbsolute3(spec) || /^[A-Za-z]:[\\/]/.test(spec))
11003
+ if (isAbsolute2(spec) || /^[A-Za-z]:[\\/]/.test(spec))
11347
11004
  return spec;
11348
- return resolve2(dirname3(configPath), spec);
11005
+ return resolve2(dirname2(configPath), spec);
11349
11006
  }
11350
11007
  function findPackageJsonUp(startPath) {
11351
11008
  try {
11352
- const stat = statSync2(startPath);
11353
- let dir = stat.isDirectory() ? startPath : dirname3(startPath);
11009
+ const stat = statSync(startPath);
11010
+ let dir = stat.isDirectory() ? startPath : dirname2(startPath);
11354
11011
  for (let i = 0;i < 10; i++) {
11355
- const pkgPath = join3(dir, "package.json");
11356
- if (existsSync6(pkgPath)) {
11012
+ const pkgPath = join2(dir, "package.json");
11013
+ if (existsSync5(pkgPath)) {
11357
11014
  try {
11358
- const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync4(pkgPath, "utf-8")));
11015
+ const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync3(pkgPath, "utf-8")));
11359
11016
  if (pkg.success && pkg.data.name === PACKAGE_NAME)
11360
11017
  return pkgPath;
11361
11018
  } catch {}
11362
11019
  }
11363
- const parent = dirname3(dir);
11020
+ const parent = dirname2(dir);
11364
11021
  if (parent === dir)
11365
11022
  break;
11366
11023
  dir = parent;
@@ -11371,19 +11028,19 @@ function findPackageJsonUp(startPath) {
11371
11028
  function getLocalDevPath(directory) {
11372
11029
  for (const configPath of getConfigPaths(directory)) {
11373
11030
  try {
11374
- if (!existsSync6(configPath))
11031
+ if (!existsSync5(configPath))
11375
11032
  continue;
11376
- const rawConfig = parseJsonConfig(readFileSync4(configPath, "utf-8"));
11033
+ const rawConfig = parseJsonConfig(readFileSync3(configPath, "utf-8"));
11377
11034
  const plugins = getPluginEntries(rawConfig);
11378
11035
  for (const entry of plugins) {
11379
11036
  if (entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`))
11380
11037
  continue;
11381
- if (entry.startsWith("file://") || entry.startsWith(".") || isAbsolute3(entry)) {
11038
+ if (entry.startsWith("file://") || entry.startsWith(".") || isAbsolute2(entry)) {
11382
11039
  const localPath = resolvePathPluginSpec(entry, configPath);
11383
11040
  const pkgPath = findPackageJsonUp(localPath);
11384
11041
  if (!pkgPath)
11385
11042
  continue;
11386
- const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync4(pkgPath, "utf-8")));
11043
+ const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync3(pkgPath, "utf-8")));
11387
11044
  if (pkg.success && pkg.data.name === PACKAGE_NAME)
11388
11045
  return localPath;
11389
11046
  }
@@ -11400,7 +11057,7 @@ function getLocalDevVersion(directory) {
11400
11057
  const pkgPath = findPackageJsonUp(localPath);
11401
11058
  if (!pkgPath)
11402
11059
  return null;
11403
- const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync4(pkgPath, "utf-8")));
11060
+ const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync3(pkgPath, "utf-8")));
11404
11061
  return pkg.success ? pkg.data.version ?? null : null;
11405
11062
  } catch {
11406
11063
  return null;
@@ -11408,7 +11065,7 @@ function getLocalDevVersion(directory) {
11408
11065
  }
11409
11066
  function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
11410
11067
  try {
11411
- return findPackageJsonUp(dirname3(fileURLToPath(currentModuleUrl)));
11068
+ return findPackageJsonUp(dirname2(fileURLToPath(currentModuleUrl)));
11412
11069
  } catch (err) {
11413
11070
  warn(`[auto-update-checker] Failed to resolve runtime package path: ${String(err)}`);
11414
11071
  return null;
@@ -11449,7 +11106,7 @@ function preflightConfigUpdates(paths, version) {
11449
11106
  for (const path2 of paths) {
11450
11107
  try {
11451
11108
  accessSync(path2, fsConstants.W_OK);
11452
- const original = readFileSync4(path2, "utf-8");
11109
+ const original = readFileSync3(path2, "utf-8");
11453
11110
  const updated = configUpdateContent(original, version);
11454
11111
  if (!updated)
11455
11112
  return null;
@@ -11463,8 +11120,8 @@ function preflightConfigUpdates(paths, version) {
11463
11120
  }
11464
11121
  function writeConfig(path2, content) {
11465
11122
  const tmp = `${path2}.mc-tmp-${process.pid}`;
11466
- writeFileSync2(tmp, content, "utf-8");
11467
- renameSync2(tmp, path2);
11123
+ writeFileSync(tmp, content, "utf-8");
11124
+ renameSync(tmp, path2);
11468
11125
  }
11469
11126
  function restoreConfigs(snapshots) {
11470
11127
  for (const snapshot of snapshots) {
@@ -11478,7 +11135,7 @@ function restoreConfigs(snapshots) {
11478
11135
  function configsHaveSpec(paths, spec) {
11479
11136
  return paths.every((path2) => {
11480
11137
  try {
11481
- const parsed = parseJsonConfig(readFileSync4(path2, "utf-8"));
11138
+ const parsed = parseJsonConfig(readFileSync3(path2, "utf-8"));
11482
11139
  return getPluginEntries(parsed).includes(spec);
11483
11140
  } catch {
11484
11141
  return false;
@@ -11534,8 +11191,8 @@ async function preparePluginUpdate(directory, _pluginInfo, version, options = {}
11534
11191
  return null;
11535
11192
  const spec = `${PACKAGE_NAME}@${version}`;
11536
11193
  const globalServerPaths = [USER_OPENCODE_CONFIG, USER_OPENCODE_CONFIG_JSONC];
11537
- const globalTuiPaths = globalServerPaths.map((path2) => join3(dirname3(path2), "tui.json"));
11538
- globalTuiPaths.push(...globalServerPaths.map((path2) => join3(dirname3(path2), "tui.jsonc")));
11194
+ const globalTuiPaths = globalServerPaths.map((path2) => join2(dirname2(path2), "tui.json"));
11195
+ globalTuiPaths.push(...globalServerPaths.map((path2) => join2(dirname2(path2), "tui.jsonc")));
11539
11196
  const isGlobal = globalServerPaths.includes(paths[0]) && globalTuiPaths.includes(paths[1]);
11540
11197
  if (isGlobal) {
11541
11198
  const hostResult = await runHostPluginInstall(spec, options.signal, options.timeoutMs);
@@ -11568,9 +11225,9 @@ function getCachedVersion(_spec) {
11568
11225
  const candidates = [getCurrentRuntimePackageJsonPath()].filter(isString);
11569
11226
  for (const packageJsonPath of candidates) {
11570
11227
  try {
11571
- if (!existsSync6(packageJsonPath))
11228
+ if (!existsSync5(packageJsonPath))
11572
11229
  continue;
11573
- const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync4(packageJsonPath, "utf-8")));
11230
+ const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync3(packageJsonPath, "utf-8")));
11574
11231
  if (pkg.success && pkg.data.version) {
11575
11232
  if (!_spec)
11576
11233
  cachedPackageVersion = pkg.data.version;
@@ -11668,20 +11325,20 @@ function claimCheckSlot(storageDir, intervalMs) {
11668
11325
  if (!storageDir)
11669
11326
  return true;
11670
11327
  try {
11671
- const file = join4(storageDir, TIMESTAMP_FILENAME);
11672
- if (existsSync7(file)) {
11328
+ const file = join3(storageDir, TIMESTAMP_FILENAME);
11329
+ if (existsSync6(file)) {
11673
11330
  try {
11674
- const raw = JSON.parse(readFileSync5(file, "utf-8"));
11331
+ const raw = JSON.parse(readFileSync4(file, "utf-8"));
11675
11332
  const last = typeof raw.lastCheckedMs === "number" ? raw.lastCheckedMs : 0;
11676
11333
  if (Number.isFinite(last) && Date.now() - last < intervalMs) {
11677
11334
  return false;
11678
11335
  }
11679
11336
  } catch {}
11680
11337
  }
11681
- mkdirSync2(dirname4(file), { recursive: true });
11338
+ mkdirSync(dirname3(file), { recursive: true });
11682
11339
  const tmp = `${file}.tmp.${process.pid}`;
11683
- writeFileSync3(tmp, JSON.stringify({ lastCheckedMs: Date.now() }), "utf-8");
11684
- renameSync3(tmp, file);
11340
+ writeFileSync2(tmp, JSON.stringify({ lastCheckedMs: Date.now() }), "utf-8");
11341
+ renameSync2(tmp, file);
11685
11342
  return true;
11686
11343
  } catch (err) {
11687
11344
  warn2(`[auto-update-checker] Could not coordinate via timestamp file: ${String(err)}`);
@@ -11689,39 +11346,39 @@ function claimCheckSlot(storageDir, intervalMs) {
11689
11346
  }
11690
11347
  }
11691
11348
  function pendingMarkerPath(storageDir) {
11692
- return join4(storageDir ?? getOpenCodeStorageDir(), PENDING_UPDATE_FILENAME);
11349
+ return join3(storageDir ?? getOpenCodeStorageDir(), PENDING_UPDATE_FILENAME);
11693
11350
  }
11694
11351
  function writePendingUpdateMarker(storageDir, update, version) {
11695
11352
  try {
11696
- const dir = storageDir ?? dirname4(pendingMarkerPath(storageDir));
11697
- mkdirSync2(dir, { recursive: true });
11353
+ const dir = storageDir ?? dirname3(pendingMarkerPath(storageDir));
11354
+ mkdirSync(dir, { recursive: true });
11698
11355
  const path2 = pendingMarkerPath(storageDir);
11699
11356
  const temp = `${path2}.tmp.${process.pid}`;
11700
- writeFileSync3(temp, `${JSON.stringify({ spec: update.spec, version, configPaths: update.configPaths, writtenAt: Date.now() }, null, 2)}
11357
+ writeFileSync2(temp, `${JSON.stringify({ spec: update.spec, version, configPaths: update.configPaths, writtenAt: Date.now() }, null, 2)}
11701
11358
  `, "utf-8");
11702
- renameSync3(temp, path2);
11359
+ renameSync2(temp, path2);
11703
11360
  } catch (err) {
11704
11361
  warn2(`[auto-update-checker] Could not write pending update marker: ${String(err)}`);
11705
11362
  }
11706
11363
  }
11707
11364
  function consumePendingUpdateMarker(storageDir, loadedVersion) {
11708
11365
  const path2 = pendingMarkerPath(storageDir);
11709
- if (!existsSync7(path2))
11366
+ if (!existsSync6(path2))
11710
11367
  return;
11711
11368
  try {
11712
- const marker = JSON.parse(readFileSync5(path2, "utf-8"));
11369
+ const marker = JSON.parse(readFileSync4(path2, "utf-8"));
11713
11370
  const age = Date.now() - (marker.writtenAt ?? 0);
11714
11371
  const olderThanLoaded = typeof marker.version === "string" && typeof loadedVersion === "string" && (compareSemverCore(marker.version, loadedVersion) ?? 0) < 0;
11715
11372
  if (marker.version === loadedVersion && marker.spec === `${PACKAGE_NAME}@${loadedVersion}` && Array.isArray(marker.configPaths) && marker.configPaths.length === 2) {
11716
- rmSync2(path2, { force: true });
11373
+ rmSync(path2, { force: true });
11717
11374
  log(`[auto-update-checker] Pending update applied: ${marker.spec}`);
11718
11375
  } else if (age > PENDING_UPDATE_MAX_AGE_MS || olderThanLoaded) {
11719
- rmSync2(path2, { force: true });
11376
+ rmSync(path2, { force: true });
11720
11377
  warn2("[auto-update-checker] Discarded stale or mismatched pending update marker");
11721
11378
  }
11722
11379
  } catch (err) {
11723
11380
  try {
11724
- rmSync2(path2, { force: true });
11381
+ rmSync(path2, { force: true });
11725
11382
  } catch {}
11726
11383
  warn2(`[auto-update-checker] Discarded corrupt pending update marker: ${String(err)}`);
11727
11384
  }
@@ -11822,7 +11479,7 @@ function createLiveSessionState() {
11822
11479
 
11823
11480
  // src/hooks/magic-context/module-transport.ts
11824
11481
  import { realpathSync as realpathSync2 } from "node:fs";
11825
- import { join as join5 } from "node:path";
11482
+ import { join as join4 } from "node:path";
11826
11483
  var DEFAULT_MODULE_ID = "magic-context";
11827
11484
  var CONNECT_BACKOFF_INITIAL_MS = 1000;
11828
11485
  var CONNECT_BACKOFF_MAX_MS = 30000;
@@ -11832,7 +11489,7 @@ var SERIAL_LANE_MAX_WAITERS = 16;
11832
11489
  var SERIAL_LANE_MIN_REMAINING_MS = 25;
11833
11490
  var CANONICAL_ROOT_CACHE_MAX_ENTRIES = 256;
11834
11491
  function getDefaultConnectionFile() {
11835
- return join5(getDataDir(), "cortexkit", "run", "subc-connection.json");
11492
+ return join4(getDataDir(), "cortexkit", "run", "subc-connection.json");
11836
11493
  }
11837
11494
  function errorChainSome(error, predicate) {
11838
11495
  let current = error;
@@ -12100,6 +11757,14 @@ class SubcModuleTransport {
12100
11757
  throw new Error("mirror.pull omitted page");
12101
11758
  return { page: response.page };
12102
11759
  }
11760
+ async deleteSession(sessionId, projectRoot) {
11761
+ await this.call({
11762
+ sessionId,
11763
+ projectRoot,
11764
+ method: "session.delete",
11765
+ body: { method: "session.delete", v: 1, session_id: sessionId }
11766
+ });
11767
+ }
12103
11768
  closeSession(sessionId) {
12104
11769
  const client = this.client;
12105
11770
  const prefix = `${sessionId}\x00`;
@@ -12219,7 +11884,7 @@ class SubcModuleTransport {
12219
11884
  }
12220
11885
 
12221
11886
  // src/plugin/dream-timer.ts
12222
- import { statSync as statSync4 } from "node:fs";
11887
+ import { statSync as statSync3 } from "node:fs";
12223
11888
 
12224
11889
  // src/features/magic-context/dreamer/storage-dream-state.ts
12225
11890
  var getDreamStateStatements = new WeakMap;
@@ -12847,6 +12512,7 @@ function seedTaskScheduleState(db, projectPath, task, nextDueAt, lastRunAt, sche
12847
12512
  db.prepare("INSERT INTO task_schedule_state (project_path, task, last_run_at, next_due_at, schedule, last_status, last_error, retry_count) VALUES (?, ?, ?, ?, ?, NULL, NULL, 0) ON CONFLICT(project_path, task) DO NOTHING").run(projectPath, task, lastRunAt, nextDueAt, schedule);
12848
12513
  }
12849
12514
  function writeTaskScheduleState(db, row) {
12515
+ const broadCycleUpdate = row.lastBroadRunAt === undefined ? "last_broad_run_at = task_schedule_state.last_broad_run_at" : "last_broad_run_at = excluded.last_broad_run_at";
12850
12516
  db.prepare(`INSERT INTO task_schedule_state
12851
12517
  (project_path, task, last_run_at, next_due_at, schedule, last_status, last_error, retry_count, last_checked_commit, last_broad_run_at, retrospective_watermark_ms)
12852
12518
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
@@ -12858,7 +12524,7 @@ function writeTaskScheduleState(db, row) {
12858
12524
  last_error = excluded.last_error,
12859
12525
  retry_count = excluded.retry_count,
12860
12526
  last_checked_commit = COALESCE(excluded.last_checked_commit, task_schedule_state.last_checked_commit),
12861
- last_broad_run_at = COALESCE(excluded.last_broad_run_at, task_schedule_state.last_broad_run_at),
12527
+ ${broadCycleUpdate},
12862
12528
  retrospective_watermark_ms = COALESCE(excluded.retrospective_watermark_ms, task_schedule_state.retrospective_watermark_ms)`).run(row.projectPath, row.task, row.lastRunAt, row.nextDueAt, row.schedule, row.lastStatus, row.lastError, row.retryCount, row.lastCheckedCommit ?? null, row.lastBroadRunAt ?? null, row.retrospectiveWatermarkMs ?? null);
12863
12529
  }
12864
12530
  function isRetrospectiveWindowProcessed(db, projectPath, windowKey) {
@@ -12870,8 +12536,8 @@ function recordRetrospectiveWindowProcessed(db, projectPath, windowKey) {
12870
12536
  }
12871
12537
 
12872
12538
  // src/features/magic-context/dreamer/task-executor.ts
12873
- import { createHash as createHash6 } from "node:crypto";
12874
- import { existsSync as existsSync10 } from "node:fs";
12539
+ import { createHash as createHash8 } from "node:crypto";
12540
+ import { existsSync as existsSync9 } from "node:fs";
12875
12541
 
12876
12542
  // src/agents/dreamer.ts
12877
12543
  var DREAMER_AGENT = "dreamer";
@@ -12882,6 +12548,9 @@ var DREAMER_CLASSIFIER_AGENT = "dreamer-classifier";
12882
12548
  var DREAMER_DOCS_AGENT = "dreamer-docs";
12883
12549
  var DREAMER_REVIEWER_AGENT = "dreamer-reviewer";
12884
12550
 
12551
+ // src/features/magic-context/mural/compress-cues.ts
12552
+ import { createHash as createHash2 } from "node:crypto";
12553
+
12885
12554
  // src/features/magic-context/dreamer/manifest-parser.ts
12886
12555
  function extractCompleteManifestBody(text, rootName) {
12887
12556
  const escapedRoot = rootName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -12915,6 +12584,64 @@ function assertManifestCoversExactly(ids, expectedIds, rootName) {
12915
12584
  }
12916
12585
  }
12917
12586
 
12587
+ // src/features/magic-context/dreamer/module-apply.ts
12588
+ class DreamerModuleFailureError extends Error {
12589
+ transient = true;
12590
+ constructor(operation, cause) {
12591
+ super(`Rust dreamer ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`);
12592
+ this.name = "DreamerModuleFailureError";
12593
+ this.cause = cause;
12594
+ }
12595
+ }
12596
+ async function resolveDreamerModuleRoute(args) {
12597
+ const transport = args.transformMode === "ts" ? undefined : args.moduleClient;
12598
+ if (!transport?.authorityStatus)
12599
+ return;
12600
+ const contextStoreUuid = getContextStoreUuid(args.db);
12601
+ if (!contextStoreUuid)
12602
+ throw new Error("Rust dreamer requires a context store identity");
12603
+ const result = await transport.authorityStatus({
12604
+ context_store_uuid: contextStoreUuid,
12605
+ project: args.projectIdentity,
12606
+ projectRoot: args.projectRoot,
12607
+ domain: "memories"
12608
+ });
12609
+ if (result.authority?.state !== "MODULE")
12610
+ return;
12611
+ const generation = result.authority.generation;
12612
+ if (typeof generation !== "number")
12613
+ throw new Error("Rust authority status omitted generation");
12614
+ return {
12615
+ moduleClient: transport,
12616
+ moduleSessionId: args.projectIdentity,
12617
+ moduleProjectRoot: args.projectRoot,
12618
+ moduleContextStoreUuid: contextStoreUuid,
12619
+ moduleAuthorityGeneration: generation,
12620
+ moduleCommandId: args.commandId
12621
+ };
12622
+ }
12623
+ function getModuleMemoryIdentities(db, projectIdentity, contextIds) {
12624
+ if (contextIds.length === 0)
12625
+ return new Map;
12626
+ const placeholders = contextIds.map(() => "?").join(", ");
12627
+ const rows = db.prepare(`SELECT identity.context_row_id, identity.module_row_id, live.normalized_hash
12628
+ FROM mirror_identity identity
12629
+ LEFT JOIN mirror_live_memory_rows live
12630
+ ON live.module_project = identity.module_project
12631
+ AND live.module_row_id = identity.module_row_id
12632
+ WHERE identity.domain = 'memories' AND identity.module_project = ?
12633
+ AND identity.context_row_id IN (${placeholders})`).all(projectIdentity, ...contextIds);
12634
+ return new Map(rows.flatMap((row) => Number.isInteger(row.context_row_id) && Number.isInteger(row.module_row_id) && typeof row.normalized_hash === "string" ? [
12635
+ [
12636
+ row.context_row_id,
12637
+ {
12638
+ moduleId: row.module_row_id,
12639
+ normalizedHash: row.normalized_hash
12640
+ }
12641
+ ]
12642
+ ] : []));
12643
+ }
12644
+
12918
12645
  // src/features/magic-context/mural/compress-cues-prompt.ts
12919
12646
  var CUE_BUDGET_HIGH = 90;
12920
12647
  var CUE_BUDGET_LOW = 50;
@@ -12986,7 +12713,7 @@ function hasBalancedParentheses(cue) {
12986
12713
  }
12987
12714
  return depth === 0;
12988
12715
  }
12989
- function validateCue(cue, importance) {
12716
+ function validateCue(cue, importance, ownId) {
12990
12717
  const trimmed = cue.trim();
12991
12718
  if (trimmed.length === 0)
12992
12719
  return { reason: "empty" };
@@ -12994,8 +12721,9 @@ function validateCue(cue, importance) {
12994
12721
  const length = [...trimmed].length;
12995
12722
  if (length > budget)
12996
12723
  return { reason: `over-budget ${length}>${budget}` };
12997
- if (/#\d+/.test(trimmed))
12724
+ if (ownId !== undefined && new RegExp(`#${ownId}\\b`).test(trimmed)) {
12998
12725
  return { reason: "leaked-id" };
12726
+ }
12999
12727
  if (!hasBalancedParentheses(trimmed))
13000
12728
  return { reason: "unbalanced-parens" };
13001
12729
  const markers = trimmed.split("⊘").length - 1;
@@ -13011,6 +12739,7 @@ function validateCue(cue, importance) {
13011
12739
  // src/features/magic-context/mural/compress-cues.ts
13012
12740
  var COMPRESS_CUES_CHUNK_SIZE = 40;
13013
12741
  var CHUNK_TIMEOUT_FLOOR_MS = 240000;
12742
+ var CUE_REJECTION_LATCH_THRESHOLD = 3;
13014
12743
  var CONSECUTIVE_TIMEOUT_LIMIT = 2;
13015
12744
  function toPromptMemory(candidate) {
13016
12745
  const memory = candidate.memory;
@@ -13021,6 +12750,38 @@ function toPromptMemory(candidate) {
13021
12750
  content: memory.content
13022
12751
  };
13023
12752
  }
12753
+ function stripOwnIdToken(value, ownId) {
12754
+ return value.replace(new RegExp(`#${ownId}\\b`, "g"), "");
12755
+ }
12756
+ function truncateCue(value, budget) {
12757
+ const trimmed = value.trim();
12758
+ const codepoints = [...trimmed];
12759
+ if (codepoints.length <= budget)
12760
+ return trimmed;
12761
+ const prefix = codepoints.slice(0, budget).join("");
12762
+ const boundary = prefix.search(/\s+\S*$/);
12763
+ return (boundary > 0 ? prefix.slice(0, boundary) : prefix).trim();
12764
+ }
12765
+ function sanitizeCue(value, candidate) {
12766
+ return truncateCue(stripOwnIdToken(value, candidate.memory.id), cueBudgetFor(candidate.memory.importance ?? 50));
12767
+ }
12768
+ function deterministicFallbackCue(candidate, lastCandidate) {
12769
+ const importance = candidate.memory.importance ?? 50;
12770
+ const budget = cueBudgetFor(importance);
12771
+ const sanitizedCandidate = sanitizeCue(lastCandidate, candidate);
12772
+ if (validateCue(sanitizedCandidate, importance, candidate.memory.id) === null) {
12773
+ return sanitizedCandidate;
12774
+ }
12775
+ const sourceSlice = sanitizeCue(candidate.memory.content, candidate);
12776
+ if (validateCue(sourceSlice, importance, candidate.memory.id) === null) {
12777
+ return sourceSlice;
12778
+ }
12779
+ const grammarSafe = truncateCue(sourceSlice.replaceAll("⊘", "").replace(/[()]/g, "").replace(/\b(?:must not|never|without|instead of|exclude|excludes)\b/gi, "").replace(/\s+/g, " "), budget);
12780
+ if (validateCue(grammarSafe, importance, candidate.memory.id) === null) {
12781
+ return grammarSafe;
12782
+ }
12783
+ return "memory";
12784
+ }
13024
12785
  function selectCandidates(db, projectIdentity) {
13025
12786
  const memories = getMemoriesByProject(db, projectIdentity, ["active", "permanent"]);
13026
12787
  const cueState = getMuralCueState(db, memories.map((memory) => memory.id));
@@ -13152,7 +12913,7 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
13152
12913
  return text;
13153
12914
  }
13154
12915
  });
13155
- return applyCues(args, chunk, run.validated);
12916
+ return args.moduleRoute ? await applyCuesThroughModule(args, chunk, run.validated, signal) : applyCues(args, chunk, run.validated);
13156
12917
  } catch (error) {
13157
12918
  const desc = describeError(error);
13158
12919
  log(`[dreamer] compress-cues chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
@@ -13189,10 +12950,19 @@ function applyCues(args, chunk, manifestText) {
13189
12950
  const candidate = byId.get(entry.id);
13190
12951
  if (!candidate)
13191
12952
  throw new Error(`cues manifest contains unknown id ${entry.id}`);
13192
- const failure = validateCue(entry.cue, candidate.memory.importance ?? 50);
12953
+ const importance = candidate.memory.importance ?? 50;
12954
+ const failure = validateCue(entry.cue, importance, candidate.memory.id);
13193
12955
  if (failure) {
12956
+ const rejectionCount = recordMuralCueRejection(args.db, args.projectIdentity, entry.id, candidate.contentHash);
12957
+ if (rejectionCount >= CUE_REJECTION_LATCH_THRESHOLD) {
12958
+ const fallback = deterministicFallbackCue(candidate, entry.cue);
12959
+ setMuralCue(args.db, args.projectIdentity, entry.id, fallback, candidate.contentHash);
12960
+ compressed += 1;
12961
+ log(`[dreamer] compress-cues: fallback cue for memory ${entry.id} (${failure.reason}; ${rejectionCount} rejections; fallback)`);
12962
+ continue;
12963
+ }
13194
12964
  skipped += 1;
13195
- log(`[dreamer] compress-cues: skipped cue for memory ${entry.id} (${failure.reason})`);
12965
+ log(`[dreamer] compress-cues: skipped cue for memory ${entry.id} (${failure.reason}; rejection ${rejectionCount}/${CUE_REJECTION_LATCH_THRESHOLD})`);
13196
12966
  continue;
13197
12967
  }
13198
12968
  setMuralCue(args.db, args.projectIdentity, entry.id, entry.cue.trim(), candidate.contentHash);
@@ -13201,6 +12971,111 @@ function applyCues(args, chunk, manifestText) {
13201
12971
  });
13202
12972
  return { compressed, skipped };
13203
12973
  }
12974
+ async function applyCuesThroughModule(args, chunk, manifestText, signal) {
12975
+ const route = args.moduleRoute;
12976
+ if (!route)
12977
+ throw new Error("module cue apply called without a module route");
12978
+ const byId = new Map(chunk.map((candidate) => [candidate.memory.id, candidate]));
12979
+ const parsed = parseCuesManifest(manifestText);
12980
+ assertManifestCoversExactly(parsed.map((entry) => entry.id), new Set(byId.keys()), "cues");
12981
+ const state = getMuralCueState(args.db, chunk.map((candidate) => candidate.memory.id));
12982
+ const identities = getModuleMemoryIdentities(args.db, args.projectIdentity, chunk.map((candidate) => candidate.memory.id));
12983
+ const updates = [];
12984
+ for (const entry of parsed) {
12985
+ const candidate = byId.get(entry.id);
12986
+ if (!candidate)
12987
+ throw new Error(`cues manifest contains unknown id ${entry.id}`);
12988
+ const identity = identities.get(candidate.memory.id);
12989
+ if (!identity) {
12990
+ throw new Error(`module mirror identity missing for memory ${candidate.memory.id}`);
12991
+ }
12992
+ const failure = validateCue(entry.cue, candidate.memory.importance ?? 50, candidate.memory.id);
12993
+ if (!failure) {
12994
+ updates.push({
12995
+ contextId: candidate.memory.id,
12996
+ moduleId: identity.moduleId,
12997
+ contentHash: candidate.contentHash,
12998
+ cue: entry.cue.trim(),
12999
+ rejectionCount: 0,
13000
+ kind: "compressed"
13001
+ });
13002
+ continue;
13003
+ }
13004
+ const previous = state.get(candidate.memory.id);
13005
+ const rejectionCount = previous?.hash === candidate.contentHash ? (previous.rejectionCount ?? 0) + 1 : 1;
13006
+ if (rejectionCount >= CUE_REJECTION_LATCH_THRESHOLD) {
13007
+ updates.push({
13008
+ contextId: candidate.memory.id,
13009
+ moduleId: identity.moduleId,
13010
+ contentHash: candidate.contentHash,
13011
+ cue: deterministicFallbackCue(candidate, entry.cue),
13012
+ rejectionCount: 0,
13013
+ kind: "compressed"
13014
+ });
13015
+ log(`[dreamer] compress-cues: fallback cue for memory ${entry.id} (${failure.reason}; ${rejectionCount} rejections; fallback)`);
13016
+ } else {
13017
+ updates.push({
13018
+ contextId: candidate.memory.id,
13019
+ moduleId: identity.moduleId,
13020
+ contentHash: candidate.contentHash,
13021
+ cue: null,
13022
+ rejectionCount,
13023
+ kind: "skipped"
13024
+ });
13025
+ log(`[dreamer] compress-cues: skipped cue for memory ${entry.id} (${failure.reason}; rejection ${rejectionCount}/${CUE_REJECTION_LATCH_THRESHOLD})`);
13026
+ }
13027
+ }
13028
+ const commandId = `mural-cues:${route.moduleCommandId}:${createHash2("sha256").update(chunk.map((candidate) => candidate.memory.id).join(",")).digest("hex").slice(0, 24)}`;
13029
+ let response;
13030
+ try {
13031
+ response = await route.moduleClient.call({
13032
+ sessionId: route.moduleSessionId,
13033
+ projectRoot: route.moduleProjectRoot,
13034
+ method: "memory.set_mural_cue",
13035
+ body: {
13036
+ name: "memory.set_mural_cue",
13037
+ arguments: {
13038
+ memory_project: args.projectIdentity,
13039
+ context_store_uuid: route.moduleContextStoreUuid,
13040
+ authority_generation: route.moduleAuthorityGeneration,
13041
+ command_id: commandId,
13042
+ rows: updates.map((update) => ({
13043
+ memory_id: update.moduleId,
13044
+ content_hash_at_prompt: update.contentHash,
13045
+ cue: update.cue,
13046
+ rejection_count: update.rejectionCount
13047
+ }))
13048
+ }
13049
+ },
13050
+ signal
13051
+ });
13052
+ } catch (error) {
13053
+ throw new DreamerModuleFailureError("mural cue apply", error);
13054
+ }
13055
+ const result = response?.result ?? response;
13056
+ if (!result || typeof result !== "object") {
13057
+ throw new Error("module returned invalid mural cue apply result");
13058
+ }
13059
+ const accepted = result.accepted;
13060
+ if (!Array.isArray(accepted) || !accepted.every((id) => Number.isInteger(id))) {
13061
+ throw new Error("module returned no mural cue acceptance list");
13062
+ }
13063
+ const acceptedIds = new Set(accepted);
13064
+ const rejected = result.rejected;
13065
+ const rejectedReasons = new Map;
13066
+ for (const row of Array.isArray(rejected) ? rejected : []) {
13067
+ const reason = row && typeof row === "object" && typeof row.reason === "string" ? row.reason : "unknown";
13068
+ rejectedReasons.set(reason, (rejectedReasons.get(reason) ?? 0) + 1);
13069
+ }
13070
+ if ([...rejectedReasons].some(([reason]) => reason !== "stale")) {
13071
+ throw new Error(`module rejected mural cues (${[...rejectedReasons].map(([reason, count]) => `${reason}=${count}`).join(", ")})`);
13072
+ }
13073
+ return updates.reduce((counts, update) => {
13074
+ if (acceptedIds.has(update.moduleId))
13075
+ counts[update.kind] += 1;
13076
+ return counts;
13077
+ }, { compressed: 0, skipped: 0 });
13078
+ }
13204
13079
 
13205
13080
  // src/features/magic-context/user-memory/review-user-memories.ts
13206
13081
  async function reviewUserMemories(args) {
@@ -13410,7 +13285,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
13410
13285
  }
13411
13286
 
13412
13287
  // src/features/magic-context/dreamer/classify.ts
13413
- import { createHash as createHash2 } from "node:crypto";
13288
+ import { createHash as createHash3 } from "node:crypto";
13414
13289
 
13415
13290
  // src/plugin/rust-tool-backends.ts
13416
13291
  function toolCallIdFromContext(context) {
@@ -13445,7 +13320,7 @@ function isRustAuthorityDrainingError(error) {
13445
13320
  }
13446
13321
 
13447
13322
  // src/shared/redaction.ts
13448
- import { homedir as homedir4, userInfo } from "node:os";
13323
+ import { homedir as homedir3, userInfo } from "node:os";
13449
13324
  function escapeRegex(value) {
13450
13325
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
13451
13326
  }
@@ -13494,7 +13369,7 @@ var SECRET_QUALIFIERS = new Set([
13494
13369
  "azure"
13495
13370
  ]);
13496
13371
  function sanitizePathString(value) {
13497
- const home = homedir4();
13372
+ const home = homedir3();
13498
13373
  const username = userInfo().username;
13499
13374
  let sanitized = value;
13500
13375
  if (home) {
@@ -13696,64 +13571,6 @@ function parseClassifyManifest(text) {
13696
13571
  return out;
13697
13572
  }
13698
13573
 
13699
- // src/features/magic-context/dreamer/module-apply.ts
13700
- class DreamerModuleFailureError extends Error {
13701
- transient = true;
13702
- constructor(operation, cause) {
13703
- super(`Rust dreamer ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`);
13704
- this.name = "DreamerModuleFailureError";
13705
- this.cause = cause;
13706
- }
13707
- }
13708
- async function resolveDreamerModuleRoute(args) {
13709
- const transport = args.transformMode === "ts" ? undefined : args.moduleClient;
13710
- if (!transport?.authorityStatus)
13711
- return;
13712
- const contextStoreUuid = getContextStoreUuid(args.db);
13713
- if (!contextStoreUuid)
13714
- throw new Error("Rust dreamer requires a context store identity");
13715
- const result = await transport.authorityStatus({
13716
- context_store_uuid: contextStoreUuid,
13717
- project: args.projectIdentity,
13718
- projectRoot: args.projectRoot,
13719
- domain: "memories"
13720
- });
13721
- if (result.authority?.state !== "MODULE")
13722
- return;
13723
- const generation = result.authority.generation;
13724
- if (typeof generation !== "number")
13725
- throw new Error("Rust authority status omitted generation");
13726
- return {
13727
- moduleClient: transport,
13728
- moduleSessionId: args.projectIdentity,
13729
- moduleProjectRoot: args.projectRoot,
13730
- moduleContextStoreUuid: contextStoreUuid,
13731
- moduleAuthorityGeneration: generation,
13732
- moduleCommandId: args.commandId
13733
- };
13734
- }
13735
- function getModuleMemoryIdentities(db, projectIdentity, contextIds) {
13736
- if (contextIds.length === 0)
13737
- return new Map;
13738
- const placeholders = contextIds.map(() => "?").join(", ");
13739
- const rows = db.prepare(`SELECT identity.context_row_id, identity.module_row_id, live.normalized_hash
13740
- FROM mirror_identity identity
13741
- LEFT JOIN mirror_live_memory_rows live
13742
- ON live.module_project = identity.module_project
13743
- AND live.module_row_id = identity.module_row_id
13744
- WHERE identity.domain = 'memories' AND identity.module_project = ?
13745
- AND identity.context_row_id IN (${placeholders})`).all(projectIdentity, ...contextIds);
13746
- return new Map(rows.flatMap((row) => Number.isInteger(row.context_row_id) && Number.isInteger(row.module_row_id) && typeof row.normalized_hash === "string" ? [
13747
- [
13748
- row.context_row_id,
13749
- {
13750
- moduleId: row.module_row_id,
13751
- normalizedHash: row.normalized_hash
13752
- }
13753
- ]
13754
- ] : []));
13755
- }
13756
-
13757
13574
  // src/features/magic-context/dreamer/classify.ts
13758
13575
  var MIN_POOL_TO_CLASSIFY = 10;
13759
13576
  var FULL_POOL_CEILING = 100;
@@ -13990,7 +13807,7 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
13990
13807
  v: 1,
13991
13808
  session_id: args.moduleSessionId,
13992
13809
  task: "classify",
13993
- command_id: `classify:${args.moduleCommandId ?? Date.now()}:${createHash2("sha256").update(chunk.map((candidate) => candidate.id).join(",")).digest("hex").slice(0, 24)}`,
13810
+ command_id: `classify:${args.moduleCommandId ?? Date.now()}:${createHash3("sha256").update(chunk.map((candidate) => candidate.id).join(",")).digest("hex").slice(0, 24)}`,
13994
13811
  authority_generation: args.moduleAuthorityGeneration,
13995
13812
  payload: {
13996
13813
  prompt_body: prompt,
@@ -14522,21 +14339,21 @@ function isSecretDeniedPath(repoRelativePath) {
14522
14339
  const segments = normalized.split("/");
14523
14340
  if (segments.includes(".git") || segments.includes("secrets"))
14524
14341
  return true;
14525
- const basename2 = segments.at(-1) ?? "";
14526
- if (basename2 === ".npmrc" || basename2.startsWith(".env"))
14342
+ const basename = segments.at(-1) ?? "";
14343
+ if (basename === ".npmrc" || basename.startsWith(".env"))
14527
14344
  return true;
14528
- if (basename2 === ".pgpass" || basename2 === ".netrc")
14345
+ if (basename === ".pgpass" || basename === ".netrc")
14529
14346
  return true;
14530
- if (SECRET_KEY_EXTENSIONS.some((extension) => basename2.endsWith(extension)))
14347
+ if (SECRET_KEY_EXTENSIONS.some((extension) => basename.endsWith(extension)))
14531
14348
  return true;
14532
- if (basename2 === "id_rsa" || basename2 === "id_dsa" || basename2 === "id_ecdsa" || basename2 === "id_ed25519" || basename2.startsWith("id_")) {
14349
+ if (basename === "id_rsa" || basename === "id_dsa" || basename === "id_ecdsa" || basename === "id_ed25519" || basename.startsWith("id_")) {
14533
14350
  return true;
14534
14351
  }
14535
- if (segments.includes(".aws") && basename2 === "credentials")
14352
+ if (segments.includes(".aws") && basename === "credentials")
14536
14353
  return true;
14537
- if (basename2.endsWith(".json")) {
14538
- const serviceAccountJson = basename2.includes("service-account") || basename2.includes("service_account");
14539
- const gcloudCredentialJson = segments.includes("gcloud") && (basename2 === "application_default_credentials.json" || basename2.includes("credential") || segments.includes("legacy_credentials"));
14354
+ if (basename.endsWith(".json")) {
14355
+ const serviceAccountJson = basename.includes("service-account") || basename.includes("service_account");
14356
+ const gcloudCredentialJson = segments.includes("gcloud") && (basename === "application_default_credentials.json" || basename.includes("credential") || segments.includes("legacy_credentials"));
14540
14357
  if (serviceAccountJson || gcloudCredentialJson)
14541
14358
  return true;
14542
14359
  }
@@ -14686,7 +14503,7 @@ function throwIfAborted2(signal) {
14686
14503
  }
14687
14504
 
14688
14505
  // src/features/magic-context/smart-notes/compiler.ts
14689
- import { createHash as createHash3 } from "node:crypto";
14506
+ import { createHash as createHash4 } from "node:crypto";
14690
14507
 
14691
14508
  // src/features/magic-context/smart-notes/sandbox-runner.ts
14692
14509
  var asyncModulePromise = null;
@@ -15080,7 +14897,7 @@ function manifestAdvisoryWarnings(code, manifest) {
15080
14897
  return warnings;
15081
14898
  }
15082
14899
  function hashCheck(surfaceCondition, compiledCheck, manifest, checkCron) {
15083
- return createHash3("sha256").update(surfaceCondition ?? "").update("\x00").update(compiledCheck).update("\x00").update(JSON.stringify(manifest)).update("\x00").update(checkCron).digest("hex");
14900
+ return createHash4("sha256").update(surfaceCondition ?? "").update("\x00").update(compiledCheck).update("\x00").update(JSON.stringify(manifest)).update("\x00").update(checkCron).digest("hex");
15084
14901
  }
15085
14902
  function extractJsonObject(output) {
15086
14903
  const fenced = output.match(/```(?:json)?\s*([\s\S]*?)```/i);
@@ -15778,8 +15595,8 @@ Output exactly JSON: {"met": false}`;
15778
15595
  }
15779
15596
 
15780
15597
  // src/features/magic-context/dreamer/maintain-docs-protected-enforcement.ts
15781
- import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "node:fs";
15782
- import { join as join6 } from "node:path";
15598
+ import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "node:fs";
15599
+ import { join as join5 } from "node:path";
15783
15600
 
15784
15601
  // src/features/magic-context/dreamer/protected-regions.ts
15785
15602
  var PROTECTED_START_TOKEN = "mc:protected START";
@@ -15880,10 +15697,10 @@ var MAINTAIN_DOCS_SNAPSHOT_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
15880
15697
  function snapshotMaintainDocsFiles(docsDir) {
15881
15698
  const snapshot = new Map;
15882
15699
  for (const name of MAINTAIN_DOCS_SNAPSHOT_FILES) {
15883
- const path3 = join6(docsDir, name);
15700
+ const path3 = join5(docsDir, name);
15884
15701
  try {
15885
- if (existsSync8(path3)) {
15886
- snapshot.set(name, readFileSync6(path3, "utf8"));
15702
+ if (existsSync7(path3)) {
15703
+ snapshot.set(name, readFileSync5(path3, "utf8"));
15887
15704
  }
15888
15705
  } catch {}
15889
15706
  }
@@ -15891,14 +15708,14 @@ function snapshotMaintainDocsFiles(docsDir) {
15891
15708
  }
15892
15709
  function enforceMaintainDocsProtectedRegions(args) {
15893
15710
  for (const [fileName, original] of args.snapshot) {
15894
- const path3 = join6(args.docsDir, fileName);
15711
+ const path3 = join5(args.docsDir, fileName);
15895
15712
  try {
15896
- const current = readFileSync6(path3, "utf8");
15713
+ const current = readFileSync5(path3, "utf8");
15897
15714
  const { text, violated } = enforceProtectedRegions(original, current);
15898
15715
  if (!violated) {
15899
15716
  continue;
15900
15717
  }
15901
- writeFileSync4(path3, text, "utf8");
15718
+ writeFileSync3(path3, text, "utf8");
15902
15719
  log(`[dreamer] maintain-docs altered a protected region in ${fileName} — restored from pre-task snapshot`);
15903
15720
  } catch (error) {
15904
15721
  log(`[dreamer] maintain-docs protected-region enforcement failed for ${fileName}: ${error}`);
@@ -15907,10 +15724,10 @@ function enforceMaintainDocsProtectedRegions(args) {
15907
15724
  }
15908
15725
 
15909
15726
  // src/features/magic-context/dreamer/map-memories.ts
15910
- import { createHash as createHash4 } from "node:crypto";
15727
+ import { createHash as createHash5 } from "node:crypto";
15911
15728
 
15912
15729
  // src/features/magic-context/dreamer/map-memories-prompt.ts
15913
- import { existsSync as existsSync9, statSync as statSync3 } from "node:fs";
15730
+ import { existsSync as existsSync8, statSync as statSync2 } from "node:fs";
15914
15731
  import path3 from "node:path";
15915
15732
  var MAP_MEMORIES_SYSTEM_PROMPT = `You are a memory mapper for the magic-context system. You map project memories to the repository files that back them.
15916
15733
 
@@ -15948,7 +15765,7 @@ function extractMemoryCandidatePaths(content, repoDir) {
15948
15765
  if (!abs.startsWith(`${root}/`))
15949
15766
  continue;
15950
15767
  try {
15951
- if (existsSync9(abs) && statSync3(abs).isFile())
15768
+ if (existsSync8(abs) && statSync2(abs).isFile())
15952
15769
  found.add(rel);
15953
15770
  } catch {}
15954
15771
  if (found.size >= MAX_SEED_PATHS_PER_MEMORY)
@@ -16168,7 +15985,7 @@ async function applyBatchMappings(args, batch, manifestText) {
16168
15985
  memory_project: args.projectIdentity,
16169
15986
  context_store_uuid: args.moduleRoute.moduleContextStoreUuid,
16170
15987
  authority_generation: args.moduleRoute.moduleAuthorityGeneration,
16171
- command_id: `${args.moduleRoute.moduleCommandId}:${createHash4("sha256").update(rows.map((row) => row.memory_id).join(",")).digest("hex").slice(0, 16)}`,
15988
+ command_id: `${args.moduleRoute.moduleCommandId}:${createHash5("sha256").update(rows.map((row) => row.memory_id).join(",")).digest("hex").slice(0, 16)}`,
16172
15989
  rows
16173
15990
  }
16174
15991
  }
@@ -16954,6 +16771,19 @@ function countUnverifiedMappedMemories(db, projectPath) {
16954
16771
  AND v.verified_at = 0`).get(projectPath);
16955
16772
  return row?.cnt ?? 0;
16956
16773
  }
16774
+ function countBroadCycleCandidates(db, projectPath, cycleStartAt) {
16775
+ const row = db.prepare(`SELECT COUNT(*) AS cnt
16776
+ FROM memories m
16777
+ WHERE m.project_path = ?
16778
+ AND m.status IN ('active','permanent')
16779
+ AND (
16780
+ SELECT MAX(v.verified_at)
16781
+ FROM memory_verifications v
16782
+ WHERE v.memory_id = m.id
16783
+ AND v.file_path <> ''
16784
+ ) < ?`).get(projectPath, cycleStartAt);
16785
+ return row?.cnt ?? 0;
16786
+ }
16957
16787
  function countCueCandidates(db, projectPath) {
16958
16788
  if (!hasMuralCueColumns(db))
16959
16789
  return countActiveMemories(db, projectPath);
@@ -17009,7 +16839,9 @@ function getDreamTaskBacklog(db, projectPath, task, options = {}) {
17009
16839
  }
17010
16840
  case "verify-broad": {
17011
16841
  const total = countMappedMemories(db, projectPath);
17012
- return { pending: total, total };
16842
+ const cycleStartAt = getTaskScheduleState(db, projectPath, "verify-broad")?.lastBroadRunAt;
16843
+ const pending = cycleStartAt == null ? total : countBroadCycleCandidates(db, projectPath, cycleStartAt);
16844
+ return { pending, total };
17013
16845
  }
17014
16846
  case "curate": {
17015
16847
  const total = countActiveMemories(db, projectPath);
@@ -17068,7 +16900,7 @@ function evaluateTaskGate(task, ctx) {
17068
16900
  case "verify":
17069
16901
  return countActiveMemories(db, project) > 0;
17070
16902
  case "verify-broad":
17071
- return countActiveMemories(db, project) > 0;
16903
+ return getTaskScheduleState(db, project, "verify-broad")?.lastBroadRunAt != null || countActiveMemories(db, project) > 0;
17072
16904
  case "curate":
17073
16905
  return countActiveMemories(db, project) > 0;
17074
16906
  case "compress-cues":
@@ -17095,13 +16927,99 @@ function evaluateTaskGate(task, ctx) {
17095
16927
  }
17096
16928
 
17097
16929
  // src/features/magic-context/dreamer/verify.ts
17098
- import { createHash as createHash5 } from "node:crypto";
16930
+ import { createHash as createHash7 } from "node:crypto";
16931
+
16932
+ // src/features/magic-context/dreamer/provider-output-failure.ts
16933
+ import { createHash as createHash6 } from "node:crypto";
16934
+ var MAX_NEAR_ZERO_OUTPUT_TOKENS = 32;
16935
+
16936
+ class DreamerProviderOutputFailureError extends Error {
16937
+ fingerprint;
16938
+ outputTokens;
16939
+ reasoningTokens;
16940
+ transient = true;
16941
+ constructor(fingerprint, outputTokens, reasoningTokens, responseText) {
16942
+ const preview = responseText.trim().replace(/\s+/g, " ").slice(0, 160);
16943
+ super(`verify provider-outage completion (output_tokens=${outputTokens}, reasoning_tokens=${reasoningTokens}): ${JSON.stringify(preview)}`);
16944
+ this.fingerprint = fingerprint;
16945
+ this.outputTokens = outputTokens;
16946
+ this.reasoningTokens = reasoningTokens;
16947
+ this.name = "DreamerProviderOutputFailureError";
16948
+ }
16949
+ }
16950
+ function finiteTokenCount(value) {
16951
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
16952
+ }
16953
+ function completionShape(value) {
16954
+ if (!isRecord(value))
16955
+ return null;
16956
+ const info = isRecord(value.info) ? value.info : value;
16957
+ if (info.role !== "assistant")
16958
+ return null;
16959
+ const time = isRecord(info.time) ? info.time : null;
16960
+ const tokens = isRecord(info.tokens) ? info.tokens : null;
16961
+ return {
16962
+ createdAt: typeof time?.created === "number" ? time.created : 0,
16963
+ finish: typeof info.finish === "string" ? info.finish : typeof info.finish_reason === "string" ? info.finish_reason : typeof info.finishReason === "string" ? info.finishReason : null,
16964
+ error: info.error,
16965
+ outputTokens: finiteTokenCount(tokens?.output),
16966
+ reasoningTokens: finiteTokenCount(tokens?.reasoning)
16967
+ };
16968
+ }
16969
+ function latestAssistantCompletion(messages) {
16970
+ if (!Array.isArray(messages))
16971
+ return null;
16972
+ let latest = null;
16973
+ for (const message of messages) {
16974
+ const completion = completionShape(message);
16975
+ if (completion && (!latest || completion.createdAt >= latest.createdAt))
16976
+ latest = completion;
16977
+ }
16978
+ return latest;
16979
+ }
16980
+ function providerOutputFailureFromInvalidManifest(messages, responseText) {
16981
+ const completion = latestAssistantCompletion(messages);
16982
+ if (completion?.finish?.toLowerCase() !== "stop")
16983
+ return null;
16984
+ if (completion.error != null || completion.outputTokens === null || completion.outputTokens > MAX_NEAR_ZERO_OUTPUT_TOKENS || completion.reasoningTokens !== 0) {
16985
+ return null;
16986
+ }
16987
+ const normalized = responseText.trim().replace(/\s+/g, " ").toLowerCase();
16988
+ if (!normalized)
16989
+ return null;
16990
+ const fingerprint = createHash6("sha256").update(normalized).digest("hex").slice(0, 16);
16991
+ return new DreamerProviderOutputFailureError(fingerprint, completion.outputTokens, completion.reasoningTokens, responseText);
16992
+ }
17099
16993
 
17100
16994
  // src/features/magic-context/dreamer/verify-gate.ts
17101
16995
  import path4 from "node:path";
17102
16996
  function minOf(values) {
17103
16997
  return values.reduce((acc, v) => v < acc ? v : acc, Number.POSITIVE_INFINITY);
17104
16998
  }
16999
+ function ensureBroadCycleStart(args) {
17000
+ const current = getTaskScheduleState(args.db, args.projectIdentity, "verify-broad");
17001
+ if (current?.lastBroadRunAt != null && current.lastBroadRunAt > 0) {
17002
+ return current.lastBroadRunAt;
17003
+ }
17004
+ if (!current)
17005
+ return args.runStartedAt;
17006
+ if (!args.holderId || !args.leaseKey) {
17007
+ throw new Error("verify-broad cycle opening requires the task lease");
17008
+ }
17009
+ return runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
17010
+ const latest = getTaskScheduleState(args.db, args.projectIdentity, "verify-broad");
17011
+ if (!latest)
17012
+ return args.runStartedAt;
17013
+ if (latest.lastBroadRunAt != null && latest.lastBroadRunAt > 0) {
17014
+ return latest.lastBroadRunAt;
17015
+ }
17016
+ writeTaskScheduleState(args.db, {
17017
+ ...latest,
17018
+ lastBroadRunAt: args.runStartedAt
17019
+ });
17020
+ return args.runStartedAt;
17021
+ });
17022
+ }
17105
17023
  async function partitionVerifyScope(args) {
17106
17024
  const runStartedAt = args.now ?? Date.now();
17107
17025
  const active = getMemoriesByProject(args.db, args.projectIdentity);
@@ -17113,6 +17031,29 @@ async function partitionVerifyScope(args) {
17113
17031
  content: m.content,
17114
17032
  mappedFiles: verById.get(m.id)?.files ?? []
17115
17033
  });
17034
+ if (args.forceBroad) {
17035
+ const broadCycleStartAt = ensureBroadCycleStart({
17036
+ db: args.db,
17037
+ projectIdentity: args.projectIdentity,
17038
+ holderId: args.holderId,
17039
+ leaseKey: args.leaseKey,
17040
+ runStartedAt
17041
+ });
17042
+ const broadCandidates = candidates.filter((m) => (verById.get(m.id)?.verifiedAt ?? 0) < broadCycleStartAt).sort((a, b) => {
17043
+ const verifiedAtA = verById.get(a.id)?.verifiedAt ?? 0;
17044
+ const verifiedAtB = verById.get(b.id)?.verifiedAt ?? 0;
17045
+ return verifiedAtA - verifiedAtB || a.id - b.id;
17046
+ });
17047
+ return {
17048
+ runStartedAt,
17049
+ mode: "broad",
17050
+ inScope: broadCandidates.map(toPrompt),
17051
+ inScopeIds: broadCandidates.map((m) => m.id),
17052
+ skippedIds: candidates.filter((m) => !broadCandidates.some((candidate) => candidate.id === m.id)).map((m) => m.id),
17053
+ broadCycleStartAt,
17054
+ reason: `broad cycle (${broadCandidates.length} remain; started ${broadCycleStartAt})`
17055
+ };
17056
+ }
17116
17057
  if (candidates.length === 0) {
17117
17058
  return {
17118
17059
  runStartedAt,
@@ -17123,16 +17064,6 @@ async function partitionVerifyScope(args) {
17123
17064
  reason: "no file-mapped memories in scope"
17124
17065
  };
17125
17066
  }
17126
- if (args.forceBroad) {
17127
- return {
17128
- runStartedAt,
17129
- mode: "broad",
17130
- inScope: candidates.map(toPrompt),
17131
- inScopeIds: candidates.map((m) => m.id),
17132
- skippedIds: [],
17133
- reason: "broad full-pool verification of file-mapped memories"
17134
- };
17135
- }
17136
17067
  const allInScope = (mode, reason) => ({
17137
17068
  runStartedAt,
17138
17069
  mode,
@@ -17251,7 +17182,26 @@ function parseVerifyManifest(text) {
17251
17182
 
17252
17183
  // src/features/magic-context/dreamer/verify.ts
17253
17184
  var VERIFY_BATCH_SIZE = 50;
17185
+ var IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT = 2;
17186
+ function closeBroadCycle(args, cycleStartAt) {
17187
+ if (!args.forceBroad || cycleStartAt === undefined)
17188
+ return;
17189
+ if (!getTaskScheduleState(args.db, args.projectIdentity, "verify-broad"))
17190
+ return;
17191
+ runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
17192
+ const current = getTaskScheduleState(args.db, args.projectIdentity, "verify-broad");
17193
+ if (current?.lastBroadRunAt !== cycleStartAt)
17194
+ return;
17195
+ if (!current)
17196
+ return;
17197
+ writeTaskScheduleState(args.db, {
17198
+ ...current,
17199
+ lastBroadRunAt: null
17200
+ });
17201
+ });
17202
+ }
17254
17203
  async function runVerify(args) {
17204
+ const runStartedAt = Date.now();
17255
17205
  const result = {
17256
17206
  verified: 0,
17257
17207
  updated: 0,
@@ -17266,20 +17216,29 @@ async function runVerify(args) {
17266
17216
  db: args.db,
17267
17217
  projectIdentity: args.projectIdentity,
17268
17218
  projectDirectory: args.sessionDirectory,
17269
- forceBroad: args.forceBroad
17219
+ forceBroad: args.forceBroad,
17220
+ now: runStartedAt,
17221
+ holderId: args.holderId,
17222
+ leaseKey: args.leaseKey
17270
17223
  });
17271
17224
  result.mode = gate.mode;
17225
+ result.broadCycleStartAt = gate.broadCycleStartAt;
17272
17226
  result.inScope = gate.inScope.length;
17273
17227
  result.remaining = gate.inScope.length;
17274
17228
  log(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"} gate: mode=${gate.mode} in_scope=${gate.inScope.length} skipped=${gate.skippedIds.length} reason=${gate.reason}`);
17275
- if (gate.inScope.length === 0)
17229
+ if (gate.inScope.length === 0) {
17230
+ closeBroadCycle(args, gate.broadCycleStartAt);
17276
17231
  return result;
17232
+ }
17277
17233
  const batches = [];
17278
17234
  for (let i = 0;i < gate.inScope.length; i += VERIFY_BATCH_SIZE) {
17279
17235
  batches.push(gate.inScope.slice(i, i + VERIFY_BATCH_SIZE));
17280
17236
  }
17281
17237
  const abortController = new AbortController;
17282
17238
  const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
17239
+ let consecutiveProviderFailures = 0;
17240
+ let priorProviderFailureFingerprint = null;
17241
+ let lastProviderFailure = null;
17283
17242
  try {
17284
17243
  for (let i = 0;i < batches.length; i += 1) {
17285
17244
  const remainingMs = Math.max(0, args.deadline - Date.now());
@@ -17294,8 +17253,28 @@ async function runVerify(args) {
17294
17253
  result.remaining -= counts.verified + counts.updated + counts.archived;
17295
17254
  result.batches += 1;
17296
17255
  args.onProgress?.(result.verified + result.updated + result.archived);
17256
+ if (counts.providerFailure) {
17257
+ lastProviderFailure = counts.providerFailure;
17258
+ if (counts.providerFailure.fingerprint === priorProviderFailureFingerprint) {
17259
+ consecutiveProviderFailures += 1;
17260
+ } else {
17261
+ priorProviderFailureFingerprint = counts.providerFailure.fingerprint;
17262
+ consecutiveProviderFailures = 1;
17263
+ }
17264
+ if (consecutiveProviderFailures >= IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT) {
17265
+ log(`[dreamer] verify run aborting after ${consecutiveProviderFailures} identical provider-failure batches`);
17266
+ throw counts.providerFailure;
17267
+ }
17268
+ } else {
17269
+ priorProviderFailureFingerprint = null;
17270
+ consecutiveProviderFailures = 0;
17271
+ }
17297
17272
  }
17273
+ if (lastProviderFailure)
17274
+ throw lastProviderFailure;
17298
17275
  result.complete = result.remaining === 0;
17276
+ if (result.complete)
17277
+ closeBroadCycle(args, gate.broadCycleStartAt);
17299
17278
  log(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: verified=${result.verified} updated=${result.updated} archived=${result.archived} batches=${result.batches} remaining=${result.remaining} complete=${result.complete}`);
17300
17279
  return result;
17301
17280
  } finally {
@@ -17350,7 +17329,14 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
17350
17329
  const text = extractLatestAssistantText(messages);
17351
17330
  if (!text)
17352
17331
  throw new Error("verify returned no output");
17353
- parseVerifyManifest(text);
17332
+ try {
17333
+ parseVerifyManifest(text);
17334
+ } catch (error) {
17335
+ const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
17336
+ if (providerFailure)
17337
+ throw providerFailure;
17338
+ throw error;
17339
+ }
17354
17340
  return text;
17355
17341
  }
17356
17342
  });
@@ -17358,11 +17344,12 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
17358
17344
  return await applyVerifyManifest(args, batch, run.validated);
17359
17345
  } catch (error) {
17360
17346
  const desc = describeError(error);
17361
- log(`[dreamer] verify batch failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
17347
+ const providerFailure = error instanceof DreamerProviderOutputFailureError ? error : undefined;
17348
+ log(`[dreamer] verify batch ${providerFailure ? "provider failure" : "failed"}: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
17362
17349
  recordInvocation4(args, startedAt, { status: "failed", error });
17363
17350
  if (error instanceof DreamerModuleFailureError || signal.aborted)
17364
17351
  throw error;
17365
- return { verified: 0, updated: 0, archived: 0 };
17352
+ return { verified: 0, updated: 0, archived: 0, providerFailure };
17366
17353
  } finally {
17367
17354
  if (agentSessionId && !shouldKeepSubagents()) {
17368
17355
  await args.client.session.delete({
@@ -17434,7 +17421,7 @@ async function applyVerifyManifest(args, batch, manifestText) {
17434
17421
  memory_project: args.projectIdentity,
17435
17422
  context_store_uuid: args.moduleRoute.moduleContextStoreUuid,
17436
17423
  authority_generation: args.moduleRoute.moduleAuthorityGeneration,
17437
- command_id: `${args.moduleRoute.moduleCommandId}:${createHash5("sha256").update(rows.map((row) => row.memory_id).join(",")).digest("hex").slice(0, 16)}`,
17424
+ command_id: `${args.moduleRoute.moduleCommandId}:${createHash7("sha256").update(rows.map((row) => row.memory_id).join(",")).digest("hex").slice(0, 16)}`,
17438
17425
  rows
17439
17426
  }
17440
17427
  }
@@ -17629,7 +17616,7 @@ function createDreamTaskExecutor(deps) {
17629
17616
  resultChars: 0,
17630
17617
  ...error ? { error } : {},
17631
17618
  backlog: (() => {
17632
- const end = getDreamTaskBacklog(db, projectIdentity, config.task);
17619
+ const end = extra?.backlogAfter ?? getDreamTaskBacklog(db, projectIdentity, config.task);
17633
17620
  const processed = processedDreamTaskItems(backlogAtStart.pending, end.pending);
17634
17621
  const value = {
17635
17622
  pendingAtStart: backlogAtStart.pending,
@@ -17678,12 +17665,6 @@ function createDreamTaskExecutor(deps) {
17678
17665
  recordRun("completed", null);
17679
17666
  return { status: "completed" };
17680
17667
  }
17681
- if (moduleRoute) {
17682
- const reason = "compress-cues parked: MODULE memory authority has no cue write facade";
17683
- log(`[dreamer] compress-cues: skipped (${reason})`);
17684
- recordRun("failed", reason);
17685
- return { status: "failed", transient: true, error: reason };
17686
- }
17687
17668
  const result = await runCompressCues({
17688
17669
  db,
17689
17670
  client: deps.client,
@@ -17695,6 +17676,7 @@ function createDreamTaskExecutor(deps) {
17695
17676
  deadline,
17696
17677
  model: config.model ?? deps.mural.model ?? deps.dreamerModel,
17697
17678
  fallbackModels: config.fallbackModels,
17679
+ moduleRoute,
17698
17680
  onProgress: (processed) => reportProgress(processed)
17699
17681
  });
17700
17682
  log(`[dreamer] compress-cues: compressed=${result.compressed} skipped=${result.skipped} chunks=${result.chunks} remaining=${result.remaining}`);
@@ -17764,19 +17746,31 @@ function createDreamTaskExecutor(deps) {
17764
17746
  fallbackModels: config.fallbackModels,
17765
17747
  language: config.language ?? deps.language,
17766
17748
  moduleRoute,
17767
- onProgress: (processed) => reportProgress(processed)
17749
+ onProgress: (processed2) => reportProgress(processed2)
17768
17750
  });
17751
+ const processed = result.verified + result.updated + result.archived;
17752
+ const broadProgress = config.task === "verify-broad" ? `verify-broad cycle ${result.broadCycleStartAt ?? "open"}: verified ${processed}, ${result.remaining} remain` : null;
17753
+ const backlogAfter = config.task === "verify-broad" ? { pending: result.remaining, total: backlogAtStart.total } : undefined;
17769
17754
  if (!result.complete) {
17755
+ if (broadProgress && processed > 0) {
17756
+ recordRun("completed", broadProgress, {
17757
+ memoryChanges: computeMemoryDelta(memoryBefore),
17758
+ backlogAfter
17759
+ });
17760
+ return { status: "completed", error: broadProgress };
17761
+ }
17770
17762
  const error = incompleteMessage(result.remaining);
17771
17763
  recordRun("failed", error, {
17772
- memoryChanges: computeMemoryDelta(memoryBefore)
17764
+ memoryChanges: computeMemoryDelta(memoryBefore),
17765
+ backlogAfter
17773
17766
  });
17774
17767
  return { status: "failed", transient: true, error };
17775
17768
  }
17776
- recordRun("completed", null, {
17777
- memoryChanges: computeMemoryDelta(memoryBefore)
17769
+ recordRun("completed", broadProgress, {
17770
+ memoryChanges: computeMemoryDelta(memoryBefore),
17771
+ backlogAfter
17778
17772
  });
17779
- return { status: "completed" };
17773
+ return broadProgress ? { status: "completed", error: broadProgress } : { status: "completed" };
17780
17774
  }
17781
17775
  if (config.task === "classify-memories") {
17782
17776
  let moduleArgs;
@@ -17964,7 +17958,7 @@ function parseFrictionGateVerdict(verdict) {
17964
17958
  }
17965
17959
  function computeRetrospectiveWindowKey(flagged) {
17966
17960
  const anchors = flagged.map((message) => `${message.sessionId}:${message.ts}`).sort().join("|");
17967
- return createHash6("sha256").update(anchors).digest("hex").slice(0, 32);
17961
+ return createHash8("sha256").update(anchors).digest("hex").slice(0, 32);
17968
17962
  }
17969
17963
  function renderFrictionWindow(messages, flaggedOrdinals, radius = 2) {
17970
17964
  const flagged = new Set(flaggedOrdinals);
@@ -18197,8 +18191,8 @@ async function runAgenticTask(config, ctx, helpers) {
18197
18191
  const lastRunAt = getTaskScheduleState(db, projectIdentity, config.task)?.lastRunAt ?? null;
18198
18192
  const maintainDocsSnapshot = task === "maintain-docs" ? snapshotMaintainDocsFiles(docsDir) : undefined;
18199
18193
  const existingDocs = task === "maintain-docs" ? {
18200
- architecture: existsSync10(`${docsDir}/ARCHITECTURE.md`),
18201
- structure: existsSync10(`${docsDir}/STRUCTURE.md`)
18194
+ architecture: existsSync9(`${docsDir}/ARCHITECTURE.md`),
18195
+ structure: existsSync9(`${docsDir}/STRUCTURE.md`)
18202
18196
  } : undefined;
18203
18197
  const userMemories = task === "curate" ? getActiveUserMemories(db).map((um) => ({ id: um.id, content: um.content })) : undefined;
18204
18198
  let curateMemories;
@@ -18911,7 +18905,7 @@ var startupJitters = new Map;
18911
18905
  var nextStartupJitterSlot = 0;
18912
18906
  function directoryStillExists(directory) {
18913
18907
  try {
18914
- return statSync4(directory).isDirectory();
18908
+ return statSync3(directory).isDirectory();
18915
18909
  } catch {
18916
18910
  return false;
18917
18911
  }
@@ -19234,7 +19228,7 @@ function createDreamTimerModuleClient(moduleClient) {
19234
19228
  }
19235
19229
 
19236
19230
  // src/plugin/embedding-bootstrap-helpers.ts
19237
- import { createHash as createHash7 } from "node:crypto";
19231
+ import { createHash as createHash9 } from "node:crypto";
19238
19232
  var EMBEDDING_AFFECTING_KEYS = new Set([
19239
19233
  "embedding.api_key",
19240
19234
  "embedding.endpoint",
@@ -19280,7 +19274,7 @@ var EMBEDDING_WARNING_TERMS = [
19280
19274
  ];
19281
19275
  var loggedFailureSignatures = new Map;
19282
19276
  function sha256Prefix(value, length = 16) {
19283
- return createHash7("sha256").update(value).digest("hex").slice(0, length);
19277
+ return createHash9("sha256").update(value).digest("hex").slice(0, length);
19284
19278
  }
19285
19279
  function warningLooksEmbeddingRelated(message) {
19286
19280
  const lower = message.toLowerCase();
@@ -19584,16 +19578,7 @@ function resolveCacheTtl(cacheTtl, modelKey) {
19584
19578
  if (typeof cacheTtl === "string") {
19585
19579
  return cacheTtl;
19586
19580
  }
19587
- if (modelKey && typeof cacheTtl[modelKey] === "string") {
19588
- return cacheTtl[modelKey];
19589
- }
19590
- if (modelKey) {
19591
- const bareModelId = modelKey.split("/").slice(1).join("/");
19592
- if (bareModelId && typeof cacheTtl[bareModelId] === "string") {
19593
- return cacheTtl[bareModelId];
19594
- }
19595
- }
19596
- return cacheTtl.default ?? "5m";
19581
+ return resolveModelConfigOrDefault(cacheTtl, modelKey, cacheTtl.default ?? "5m");
19597
19582
  }
19598
19583
  var clampWarnSeen = new Set;
19599
19584
  function isFinitePositive(v) {
@@ -22620,7 +22605,7 @@ function replayCavemanCompression(sessionId, db, targets, tags) {
22620
22605
  }
22621
22606
 
22622
22607
  // src/hooks/magic-context/compaction-off-transition.ts
22623
- import { existsSync as existsSync11 } from "node:fs";
22608
+ import { existsSync as existsSync10 } from "node:fs";
22624
22609
  var loggedUnverifiedMarkerCleanupRetry = false;
22625
22610
  var COMPACTION_OFF_FLIP_NOTICE = [
22626
22611
  "## Magic Context — compaction-off mode is now active",
@@ -22655,7 +22640,7 @@ function clearCachedM0Baseline(db, sessionId) {
22655
22640
  return (result.changes ?? 0) > 0;
22656
22641
  }
22657
22642
  function cleanupOffMarkers(sessionId) {
22658
- if (!existsSync11(getOpenCodeDbPath())) {
22643
+ if (!existsSync10(getOpenCodeDbPath())) {
22659
22644
  return { verified: true, removedLineages: 0, removedRows: 0, retainedLineages: 0 };
22660
22645
  }
22661
22646
  return removeMcOwnedCompactionMarkers(sessionId, MARKER_SUMMARY_TEXT);
@@ -23749,7 +23734,7 @@ function createPassOutcome() {
23749
23734
  }
23750
23735
 
23751
23736
  // src/hooks/magic-context/rust-mode-transform.ts
23752
- import { createHash as createHash11 } from "node:crypto";
23737
+ import { createHash as createHash13 } from "node:crypto";
23753
23738
 
23754
23739
  // src/hooks/magic-context/module-state-sync.ts
23755
23740
  import { createHmac, randomUUID as randomUUID5 } from "node:crypto";
@@ -25087,6 +25072,121 @@ async function syncModuleState(args) {
25087
25072
  }
25088
25073
  }
25089
25074
 
25075
+ // src/hooks/magic-context/todo-view.ts
25076
+ import { createHash as createHash11 } from "node:crypto";
25077
+ var TODO_STATUS_PENDING = "pending";
25078
+ var TODO_STATUS_IN_PROGRESS = "in_progress";
25079
+ var TODO_STATUS_COMPLETED = "completed";
25080
+ var TODO_STATUS_CANCELLED = "cancelled";
25081
+ var TODO_PRIORITY_HIGH = "high";
25082
+ var TODO_PRIORITY_MEDIUM = "medium";
25083
+ var TODO_PRIORITY_LOW = "low";
25084
+ var TODO_STATUSES = [
25085
+ TODO_STATUS_PENDING,
25086
+ TODO_STATUS_IN_PROGRESS,
25087
+ TODO_STATUS_COMPLETED,
25088
+ TODO_STATUS_CANCELLED
25089
+ ];
25090
+ var TODO_PRIORITIES = [
25091
+ TODO_PRIORITY_HIGH,
25092
+ TODO_PRIORITY_MEDIUM,
25093
+ TODO_PRIORITY_LOW
25094
+ ];
25095
+ var TODO_STATUS_SET = new Set(TODO_STATUSES);
25096
+ var TODO_PRIORITY_SET = new Set(TODO_PRIORITIES);
25097
+ var TERMINAL_STATUSES = new Set([
25098
+ TODO_STATUS_COMPLETED,
25099
+ TODO_STATUS_CANCELLED
25100
+ ]);
25101
+ var TITLE_DONE_STATUSES = new Set([TODO_STATUS_COMPLETED]);
25102
+ var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
25103
+ function normalizeTodoStateJson(todos) {
25104
+ if (!Array.isArray(todos))
25105
+ return null;
25106
+ const normalized = [];
25107
+ for (const todo of todos) {
25108
+ if (!isTodoItem(todo))
25109
+ return null;
25110
+ normalized.push({
25111
+ content: todo.content,
25112
+ status: todo.status,
25113
+ priority: todo.priority ?? TODO_PRIORITY_MEDIUM
25114
+ });
25115
+ }
25116
+ return JSON.stringify(normalized);
25117
+ }
25118
+ function buildSyntheticTodoPart(stateJson) {
25119
+ const todos = parseTodoState(stateJson);
25120
+ if (todos === null || todos.length === 0)
25121
+ return null;
25122
+ if (todos.every((t) => TERMINAL_STATUSES.has(t.status)))
25123
+ return null;
25124
+ const callID = computeSyntheticCallId(stateJson);
25125
+ const activeCount = todos.filter((t) => !TITLE_DONE_STATUSES.has(t.status)).length;
25126
+ const output = JSON.stringify(todos, null, 2);
25127
+ const ts = 0;
25128
+ return {
25129
+ type: "tool",
25130
+ callID,
25131
+ tool: "todowrite",
25132
+ state: {
25133
+ status: "completed",
25134
+ input: { todos },
25135
+ output,
25136
+ title: `${activeCount} todos`,
25137
+ metadata: { todos, truncated: false },
25138
+ time: { start: ts, end: ts }
25139
+ },
25140
+ syntheticTodoMarker: true
25141
+ };
25142
+ }
25143
+ function computeSyntheticCallId(stateJson) {
25144
+ const hash = createHash11("sha256").update(stateJson).digest("hex").slice(0, 16);
25145
+ return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
25146
+ }
25147
+ function isSyntheticTodoPart(part) {
25148
+ if (part === null || typeof part !== "object")
25149
+ return false;
25150
+ const p = part;
25151
+ if (p.syntheticTodoMarker === true)
25152
+ return true;
25153
+ return p.type === "tool" && p.tool === "todowrite" && typeof p.callID === "string" && p.callID.startsWith(SYNTHETIC_CALL_ID_PREFIX);
25154
+ }
25155
+ function parseTodoState(stateJson) {
25156
+ if (stateJson.length === 0)
25157
+ return null;
25158
+ try {
25159
+ const parsed = JSON.parse(stateJson);
25160
+ if (!Array.isArray(parsed))
25161
+ return null;
25162
+ const result = [];
25163
+ for (const item of parsed) {
25164
+ if (!isTodoItem(item))
25165
+ return null;
25166
+ result.push({
25167
+ content: item.content,
25168
+ status: item.status,
25169
+ priority: item.priority ?? TODO_PRIORITY_MEDIUM
25170
+ });
25171
+ }
25172
+ return result;
25173
+ } catch {
25174
+ return null;
25175
+ }
25176
+ }
25177
+ function isTodoStatus(value) {
25178
+ return typeof value === "string" && TODO_STATUS_SET.has(value);
25179
+ }
25180
+ function isTodoPriority(value) {
25181
+ return typeof value === "string" && TODO_PRIORITY_SET.has(value);
25182
+ }
25183
+ function isTodoItem(value) {
25184
+ if (value === null || typeof value !== "object")
25185
+ return false;
25186
+ const todo = value;
25187
+ return typeof todo.content === "string" && isTodoStatus(todo.status) && (todo.priority === undefined || isTodoPriority(todo.priority));
25188
+ }
25189
+
25090
25190
  // src/hooks/magic-context/transform-context-state.ts
25091
25191
  function loadPersistedUsageWatermark(db, sessionId) {
25092
25192
  const result = db.prepare("SELECT last_response_time FROM session_meta WHERE session_id = ?").get(sessionId);
@@ -25110,7 +25210,8 @@ function loadContextUsage(contextUsageMap, db, sessionId) {
25110
25210
  if (persisted) {
25111
25211
  contextUsageMap.set(sessionId, {
25112
25212
  ...persisted,
25113
- lastResponseTime: persistedLastResponseTime ?? persisted.updatedAt
25213
+ lastResponseTime: persistedLastResponseTime ?? persisted.updatedAt,
25214
+ hasUsageTokens: false
25114
25215
  });
25115
25216
  return persisted.usage;
25116
25217
  }
@@ -25189,7 +25290,7 @@ function containsProbeVerbatim(text, probes) {
25189
25290
  }
25190
25291
 
25191
25292
  // src/features/magic-context/search-measurement.ts
25192
- import { createHash as createHash9 } from "node:crypto";
25293
+ import { createHash as createHash12 } from "node:crypto";
25193
25294
  function resultId(result) {
25194
25295
  switch (result.source) {
25195
25296
  case "memory":
@@ -25276,7 +25377,7 @@ async function recordShadowMeasurement(args) {
25276
25377
  }
25277
25378
  }
25278
25379
  function sha256(value) {
25279
- return createHash9("sha256").update(value).digest("hex");
25380
+ return createHash12("sha256").update(value).digest("hex");
25280
25381
  }
25281
25382
 
25282
25383
  // src/features/magic-context/search.ts
@@ -27637,121 +27738,6 @@ function readFilePath(target) {
27637
27738
  return null;
27638
27739
  }
27639
27740
 
27640
- // src/hooks/magic-context/todo-view.ts
27641
- import { createHash as createHash10 } from "node:crypto";
27642
- var TODO_STATUS_PENDING = "pending";
27643
- var TODO_STATUS_IN_PROGRESS = "in_progress";
27644
- var TODO_STATUS_COMPLETED = "completed";
27645
- var TODO_STATUS_CANCELLED = "cancelled";
27646
- var TODO_PRIORITY_HIGH = "high";
27647
- var TODO_PRIORITY_MEDIUM = "medium";
27648
- var TODO_PRIORITY_LOW = "low";
27649
- var TODO_STATUSES = [
27650
- TODO_STATUS_PENDING,
27651
- TODO_STATUS_IN_PROGRESS,
27652
- TODO_STATUS_COMPLETED,
27653
- TODO_STATUS_CANCELLED
27654
- ];
27655
- var TODO_PRIORITIES = [
27656
- TODO_PRIORITY_HIGH,
27657
- TODO_PRIORITY_MEDIUM,
27658
- TODO_PRIORITY_LOW
27659
- ];
27660
- var TODO_STATUS_SET = new Set(TODO_STATUSES);
27661
- var TODO_PRIORITY_SET = new Set(TODO_PRIORITIES);
27662
- var TERMINAL_STATUSES = new Set([
27663
- TODO_STATUS_COMPLETED,
27664
- TODO_STATUS_CANCELLED
27665
- ]);
27666
- var TITLE_DONE_STATUSES = new Set([TODO_STATUS_COMPLETED]);
27667
- var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
27668
- function normalizeTodoStateJson(todos) {
27669
- if (!Array.isArray(todos))
27670
- return null;
27671
- const normalized = [];
27672
- for (const todo of todos) {
27673
- if (!isTodoItem(todo))
27674
- return null;
27675
- normalized.push({
27676
- content: todo.content,
27677
- status: todo.status,
27678
- priority: todo.priority ?? TODO_PRIORITY_MEDIUM
27679
- });
27680
- }
27681
- return JSON.stringify(normalized);
27682
- }
27683
- function buildSyntheticTodoPart(stateJson) {
27684
- const todos = parseTodoState(stateJson);
27685
- if (todos === null || todos.length === 0)
27686
- return null;
27687
- if (todos.every((t) => TERMINAL_STATUSES.has(t.status)))
27688
- return null;
27689
- const callID = computeSyntheticCallId(stateJson);
27690
- const activeCount = todos.filter((t) => !TITLE_DONE_STATUSES.has(t.status)).length;
27691
- const output = JSON.stringify(todos, null, 2);
27692
- const ts = 0;
27693
- return {
27694
- type: "tool",
27695
- callID,
27696
- tool: "todowrite",
27697
- state: {
27698
- status: "completed",
27699
- input: { todos },
27700
- output,
27701
- title: `${activeCount} todos`,
27702
- metadata: { todos, truncated: false },
27703
- time: { start: ts, end: ts }
27704
- },
27705
- syntheticTodoMarker: true
27706
- };
27707
- }
27708
- function computeSyntheticCallId(stateJson) {
27709
- const hash = createHash10("sha256").update(stateJson).digest("hex").slice(0, 16);
27710
- return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
27711
- }
27712
- function isSyntheticTodoPart(part) {
27713
- if (part === null || typeof part !== "object")
27714
- return false;
27715
- const p = part;
27716
- if (p.syntheticTodoMarker === true)
27717
- return true;
27718
- return p.type === "tool" && p.tool === "todowrite" && typeof p.callID === "string" && p.callID.startsWith(SYNTHETIC_CALL_ID_PREFIX);
27719
- }
27720
- function parseTodoState(stateJson) {
27721
- if (stateJson.length === 0)
27722
- return null;
27723
- try {
27724
- const parsed = JSON.parse(stateJson);
27725
- if (!Array.isArray(parsed))
27726
- return null;
27727
- const result = [];
27728
- for (const item of parsed) {
27729
- if (!isTodoItem(item))
27730
- return null;
27731
- result.push({
27732
- content: item.content,
27733
- status: item.status,
27734
- priority: item.priority ?? TODO_PRIORITY_MEDIUM
27735
- });
27736
- }
27737
- return result;
27738
- } catch {
27739
- return null;
27740
- }
27741
- }
27742
- function isTodoStatus(value) {
27743
- return typeof value === "string" && TODO_STATUS_SET.has(value);
27744
- }
27745
- function isTodoPriority(value) {
27746
- return typeof value === "string" && TODO_PRIORITY_SET.has(value);
27747
- }
27748
- function isTodoItem(value) {
27749
- if (value === null || typeof value !== "object")
27750
- return false;
27751
- const todo = value;
27752
- return typeof todo.content === "string" && isTodoStatus(todo.status) && (todo.priority === undefined || isTodoPriority(todo.priority));
27753
- }
27754
-
27755
27741
  // src/hooks/magic-context/tool-reclaim.ts
27756
27742
  function buildSyntheticToolReclaimOps(input) {
27757
27743
  const watermark = Math.max(0, input.watermark);
@@ -29265,7 +29251,9 @@ class MemoryAuthorityUnavailableError extends Error {
29265
29251
  }
29266
29252
  }
29267
29253
  var RUST_FAILURE_PARK_THRESHOLD = 3;
29268
- var RUST_PROBE_INTERVAL = 5;
29254
+ var RUST_PARK_RETRY_INTERVAL = 5;
29255
+ var RUST_EMERGENCY_WALL_PCT = 95;
29256
+ var RUST_PARK_PROBE_PRESSURE_BYPASS_PCT = 90;
29269
29257
  var RUST_SEND_TIMEOUT_MS = 15000;
29270
29258
  function isRecord3(value) {
29271
29259
  return value !== null && typeof value === "object";
@@ -29426,10 +29414,10 @@ function messageCacheSignature(message) {
29426
29414
  const parts = Array.isArray(message.parts) ? message.parts : [];
29427
29415
  const serializedParts = JSON.stringify(parts) ?? "null";
29428
29416
  const serializedMessage = JSON.stringify(message) ?? "null";
29429
- return `${messageIdOf(message) ?? ""}:${parts.length}:${Buffer.byteLength(serializedParts)}:${createHash11("sha256").update(serializedMessage).digest("hex")}`;
29417
+ return `${messageIdOf(message) ?? ""}:${parts.length}:${Buffer.byteLength(serializedParts)}:${createHash13("sha256").update(serializedMessage).digest("hex")}`;
29430
29418
  }
29431
29419
  function advanceWireFingerprint(previous, encoded) {
29432
- return createHash11("sha256").update(previous).update("\\0").update(JSON.stringify(encoded) ?? "null").digest("hex");
29420
+ return createHash13("sha256").update(previous).update("\\0").update(JSON.stringify(encoded) ?? "null").digest("hex");
29433
29421
  }
29434
29422
  function buildWireFingerprint(encoded) {
29435
29423
  let fingerprint = "rust-wire-v1";
@@ -29467,7 +29455,8 @@ function formatRustPassLog(args) {
29467
29455
  const timings = args.timings ?? emptyRustPassTimings();
29468
29456
  const measured = timings.prefixGuard + timings.ordinalResolve + timings.stateSync + timings.clone + timings.wireBuild + timings.transport + timings.apply + timings.lkgSnapshot;
29469
29457
  const unattributed = Math.max(0, args.elapsedMs - measured);
29470
- return `rust pass: decision=${args.decision} reason=${args.reason} served_from=${args.servedFrom} in=${args.inputCount} out=${args.outputCount} applied=${args.applied} elapsed=${args.elapsedMs.toFixed(1)} ms module=${args.moduleElapsedMs.toFixed(1)} ms stages=prefix_guard:${timings.prefixGuard.toFixed(1)} ordinal_resolve:${timings.ordinalResolve.toFixed(1)} state_sync:${timings.stateSync.toFixed(1)} clone:${timings.clone.toFixed(1)} wire_build:${timings.wireBuild.toFixed(1)} wire_messages:${timings.wireMessages} transport:${timings.transport.toFixed(1)} transport_pages:${timings.transportPages} transport_bytes:${timings.transportBytes} apply:${timings.apply.toFixed(1)} lkg_snapshot:${timings.lkgSnapshot.toFixed(1)} other:${unattributed.toFixed(1)}`;
29458
+ const rowVersion = Number.isSafeInteger(args.rowVersion) ? args.rowVersion : 0;
29459
+ return `rust pass: decision=${args.decision} reason=${args.reason} served_from=${args.servedFrom} in=${args.inputCount} out=${args.outputCount} applied=${args.applied} row_version=${rowVersion} elapsed=${args.elapsedMs.toFixed(1)} ms module=${args.moduleElapsedMs.toFixed(1)} ms stages=prefix_guard:${timings.prefixGuard.toFixed(1)} ordinal_resolve:${timings.ordinalResolve.toFixed(1)} state_sync:${timings.stateSync.toFixed(1)} clone:${timings.clone.toFixed(1)} wire_build:${timings.wireBuild.toFixed(1)} wire_messages:${timings.wireMessages} transport:${timings.transport.toFixed(1)} transport_pages:${timings.transportPages} transport_bytes:${timings.transportBytes} apply:${timings.apply.toFixed(1)} lkg_snapshot:${timings.lkgSnapshot.toFixed(1)} other:${unattributed.toFixed(1)}`;
29471
29460
  }
29472
29461
  function isSyntheticUserMessage(message) {
29473
29462
  if (!message || messageInfo2(message).role !== "user" || !Array.isArray(message.parts)) {
@@ -29599,6 +29588,19 @@ function passUsage(usage, limit) {
29599
29588
  context_limit_tokens: limit
29600
29589
  };
29601
29590
  }
29591
+ function shouldDisarmRustEmergencyRecovery(input) {
29592
+ if (input.finalWireEstimate?.trusted === true && input.providerProvenLimitTokens > 0 && input.finalWireEstimate.tokens < input.providerProvenLimitTokens * 0.8) {
29593
+ return "trusted-final-wire";
29594
+ }
29595
+ if (!input.materialized || input.usagePercentage >= 80)
29596
+ return null;
29597
+ if (input.recoveryOrigin !== "provider_overflow")
29598
+ return "fresh-usage";
29599
+ if (input.usageEntry?.hasUsageTokens === true && (input.recoveryArmedAt === null || input.usageEntry.updatedAt > input.recoveryArmedAt)) {
29600
+ return "fresh-usage";
29601
+ }
29602
+ return null;
29603
+ }
29602
29604
  function directiveTextOf(response) {
29603
29605
  const directives = isRecord3(response.host_directives) ? response.host_directives : undefined;
29604
29606
  const channel2 = isRecord3(directives?.channel2_nudge) ? directives.channel2_nudge : undefined;
@@ -29615,7 +29617,7 @@ function canonicalizeForChecksum(value) {
29615
29617
  return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonicalizeForChecksum(value[key])]));
29616
29618
  }
29617
29619
  function checksumSeedRows(rows) {
29618
- return createHash11("sha256").update(JSON.stringify(rows.map(canonicalizeForChecksum))).digest("hex");
29620
+ return createHash13("sha256").update(JSON.stringify(rows.map(canonicalizeForChecksum))).digest("hex");
29619
29621
  }
29620
29622
  function authoritySeedRows(db, projectPath, domain) {
29621
29623
  const snapshots = domain === "memories" ? db.prepare("SELECT * FROM memories WHERE project_path = ? ORDER BY id ASC").all(projectPath) : db.prepare(`SELECT n.*
@@ -29756,6 +29758,35 @@ async function prepareRustMemoryAuthority(args) {
29756
29758
  state.memoryAuthorityReady = true;
29757
29759
  args.onProjectPrepared?.(projectPath);
29758
29760
  }
29761
+ var TODO_HEAD_ANCHOR_ID2 = "__magic_context_todo_head__";
29762
+ function syntheticTodoAnchorFromNative(messages) {
29763
+ for (let index = 0;index < messages.length; index += 1) {
29764
+ const message = messages[index];
29765
+ if (!isRecord3(message) || !Array.isArray(message.parts))
29766
+ continue;
29767
+ const part = message.parts.find((candidate) => isRecord3(candidate) && candidate.syntheticTodoMarker === true);
29768
+ if (!isRecord3(part) || typeof part.callID !== "string")
29769
+ continue;
29770
+ const state = isRecord3(part.state) ? part.state : undefined;
29771
+ const input = state && isRecord3(state.input) ? state.input : undefined;
29772
+ const stateJson = normalizeTodoStateJson(input?.todos);
29773
+ if (stateJson === null || computeSyntheticCallId(stateJson) !== part.callID)
29774
+ continue;
29775
+ const previous = messages[index - 1];
29776
+ const previousInfo = isRecord3(previous) && isRecord3(previous.info) ? previous.info : undefined;
29777
+ const messageId2 = previousInfo && typeof previousInfo.id === "string" && previousInfo.id.length > 0 ? previousInfo.id : TODO_HEAD_ANCHOR_ID2;
29778
+ return { callId: part.callID, messageId: messageId2, stateJson };
29779
+ }
29780
+ return null;
29781
+ }
29782
+ function mirrorRustSyntheticTodoAnchor(args) {
29783
+ const anchor = syntheticTodoAnchorFromNative(args.messages);
29784
+ if (anchor) {
29785
+ setPersistedTodoSyntheticAnchor(args.db, args.sessionId, anchor.callId, anchor.messageId, anchor.stateJson);
29786
+ } else if (args.cacheBustingPass) {
29787
+ clearPersistedTodoSyntheticAnchor(args.db, args.sessionId);
29788
+ }
29789
+ }
29759
29790
  function applyNativeMessagesVerbatim(output, response) {
29760
29791
  const nativeMessages = response.native_messages;
29761
29792
  if (typeof nativeMessages === "string") {
@@ -29809,6 +29840,9 @@ function buildTransformBody(args) {
29809
29840
  model_key: args.modelKey,
29810
29841
  provider_id: args.providerId,
29811
29842
  tool_present: args.passInputs.tool_present === true,
29843
+ prompt_surface_preset: args.passInputs.prompt_surface_preset ?? "full",
29844
+ prompt_surface_model_key: args.passInputs.prompt_surface_model_key,
29845
+ prompt_surface_tool_descriptions: args.passInputs.prompt_surface_tool_descriptions ?? {},
29812
29846
  effective_execute_threshold: args.passInputs.effective_execute_threshold,
29813
29847
  history_budget_tokens: args.passInputs.history_budget_tokens,
29814
29848
  clear_reasoning_age: args.passInputs.clear_reasoning_age,
@@ -29855,7 +29889,7 @@ function createRustModeTransform(deps, options) {
29855
29889
  state.passesSincePark = 0;
29856
29890
  state.warningSent = true;
29857
29891
  const warning = "Rust Magic Context is unavailable for this session; retry after the module recovers.";
29858
- sessionLog(sessionId, "rust transform parked after three consecutive failures");
29892
+ sessionLog(sessionId, `mc_rust_park_transition failure_passes=${state.consecutiveFailures} pass_count=${state.passCount} park_count=${state.parkCount}`);
29859
29893
  options.notifyParked?.(sessionId, warning);
29860
29894
  };
29861
29895
  const resetOrdinalMemo = (state) => {
@@ -29988,6 +30022,7 @@ function createRustModeTransform(deps, options) {
29988
30022
  let materializeReason = "none";
29989
30023
  let servedFrom = "none";
29990
30024
  let moduleElapsedMs = 0;
30025
+ let rowVersion = 0;
29991
30026
  let appliedAt;
29992
30027
  let emergencyFailClosed = false;
29993
30028
  const passUsageSnapshot = loadContextUsage(deps.contextUsageMap, deps.db, sessionId);
@@ -30019,7 +30054,7 @@ function createRustModeTransform(deps, options) {
30019
30054
  } catch (error) {
30020
30055
  preflightError ??= error;
30021
30056
  }
30022
- emergencyFailClosed = passUsageSnapshot.percentage >= 95 && resolvedContextLimit !== undefined && resolvedContextLimit > 0;
30057
+ emergencyFailClosed = passUsageSnapshot.percentage >= RUST_EMERGENCY_WALL_PCT && resolvedContextLimit !== undefined && resolvedContextLimit > 0;
30023
30058
  if (overflowState) {
30024
30059
  const detectedLimitMatchesModel = overflowState.detectedContextLimitModelKey === null || overflowState.detectedContextLimitModelKey === modelKey;
30025
30060
  const hasProviderProof = overflowState.detectedContextLimit > 0 && detectedLimitMatchesModel || isProviderOverflowReconfirmed(sessionId);
@@ -30037,6 +30072,7 @@ function createRustModeTransform(deps, options) {
30037
30072
  applied,
30038
30073
  elapsedMs,
30039
30074
  moduleElapsedMs,
30075
+ rowVersion,
30040
30076
  timings
30041
30077
  }));
30042
30078
  if (served) {
@@ -30056,6 +30092,7 @@ function createRustModeTransform(deps, options) {
30056
30092
  const timings2 = isRecord3(response.timings) ? response.timings : undefined;
30057
30093
  const total = timings2?.total;
30058
30094
  moduleElapsedMs = typeof total === "number" && Number.isFinite(total) ? total : 0;
30095
+ rowVersion = typeof response.row_version === "number" && Number.isSafeInteger(response.row_version) ? response.row_version : 0;
30059
30096
  if (timings2 && moduleElapsedMs >= 1000) {
30060
30097
  const detail = Object.entries(timings2).filter(([key, value]) => key !== "total" && typeof value === "number").map(([key, value]) => `${key}:${value.toFixed(1)}`).join(" ");
30061
30098
  if (detail)
@@ -30064,7 +30101,7 @@ function createRustModeTransform(deps, options) {
30064
30101
  };
30065
30102
  if (state.parked) {
30066
30103
  state.passesSincePark += 1;
30067
- if (!emergencyFailClosed && passUsageSnapshot.percentage < 90 && state.passCount % RUST_PROBE_INTERVAL !== 0) {
30104
+ if (!emergencyFailClosed && passUsageSnapshot.percentage < RUST_PARK_PROBE_PRESSURE_BYPASS_PCT && state.passCount % RUST_PARK_RETRY_INTERVAL !== 0) {
30068
30105
  decision = "parked";
30069
30106
  const replayed = replayLastGood(sessionId, messages, output, sessionMeta.systemPromptTokens);
30070
30107
  if (replayed) {
@@ -30078,6 +30115,7 @@ function createRustModeTransform(deps, options) {
30078
30115
  }
30079
30116
  }
30080
30117
  const reduceAvailability = resolveCtxReduceAvailability(sessionId);
30118
+ resolveTodowriteAvailabilityFromMessages(sessionId, messages);
30081
30119
  const toolPresent = reduceAvailability.frozen && reduceAvailability.callable;
30082
30120
  try {
30083
30121
  if (preflightError)
@@ -30095,6 +30133,7 @@ function createRustModeTransform(deps, options) {
30095
30133
  const midTurn = isMidTurn(deps, sessionId);
30096
30134
  const requestObservedAtMs = Date.now();
30097
30135
  const recoveryNoHeadEscape = overflowState.needsEmergencyRecovery && loadProtectedTailMeta(deps.db, sessionId).recoveryNoEligibleHeadCount >= RECOVERY_NO_HEAD_LIMIT;
30136
+ const promptSurface = resolvePromptSurface(deps.promptSurface, modelKey ?? undefined);
30098
30137
  const passInputs = {
30099
30138
  now_ms: requestObservedAtMs,
30100
30139
  model_key: modelKey,
@@ -30111,6 +30150,9 @@ function createRustModeTransform(deps, options) {
30111
30150
  system_prompt_hash: sessionMeta.systemPromptHash ?? "",
30112
30151
  upgrade_state: readUpgradeState(deps.db, sessionId),
30113
30152
  tool_present: toolPresent,
30153
+ prompt_surface_preset: promptSurface.preset,
30154
+ prompt_surface_model_key: modelKey,
30155
+ prompt_surface_tool_descriptions: deps.promptSurface?.tool_descriptions ?? {},
30114
30156
  protected_tags: deps.protectedTags ?? DEFAULT_PROTECTED_TAGS,
30115
30157
  temporal_awareness: deps.experimentalTemporalAwareness === true,
30116
30158
  channel2_nudge_state: getChannel2NudgeState(deps.db, sessionId),
@@ -30337,6 +30379,7 @@ function createRustModeTransform(deps, options) {
30337
30379
  const pages = buildPagedModuleTransformPayloads(body);
30338
30380
  logStage(sessionId, "wireBuild", wireBuildStartedAt, timings, wireDelta ? `mode=tail_delta input=${encodedInput.length}` : "mode=full");
30339
30381
  let response;
30382
+ let servedFinalWireEstimate;
30340
30383
  for (const [index, page] of pages.entries()) {
30341
30384
  timings.transportBytes += Buffer.byteLength(JSON.stringify(page));
30342
30385
  const transportStartedAt = performance.now();
@@ -30469,6 +30512,9 @@ function createRustModeTransform(deps, options) {
30469
30512
  });
30470
30513
  }
30471
30514
  };
30515
+ const explicitDecision = typeof response.decision === "string" || typeof response.action === "string" || typeof response.cache_bust === "boolean";
30516
+ const decisionUpper = decision.toUpperCase();
30517
+ const cacheBustingPass = response.cache_bust === true || decisionUpper === "HARD" || decisionUpper === "MIGRATE_HARD" || decisionUpper === "EXECUTE" || decisionUpper === "SOFT" || !explicitDecision;
30472
30518
  let appliedMessages;
30473
30519
  const applyStartedAt = performance.now();
30474
30520
  try {
@@ -30484,11 +30530,25 @@ function createRustModeTransform(deps, options) {
30484
30530
  if (typeof boundaryId === "string" && boundaryId.length > 0) {
30485
30531
  assertNativeBoundary(appliedMessages, sessionId, boundaryId);
30486
30532
  }
30533
+ if (!sessionMeta.isSubagent) {
30534
+ mirrorRustSyntheticTodoAnchor({
30535
+ db: deps.db,
30536
+ sessionId,
30537
+ messages: appliedMessages,
30538
+ cacheBustingPass
30539
+ });
30540
+ }
30541
+ if (passInputs.emergency_recovery_armed === true) {
30542
+ servedFinalWireEstimate = estimateFinalWireInputTokens({
30543
+ messages: appliedMessages,
30544
+ systemPromptTokens: sessionMeta.systemPromptTokens,
30545
+ providerID: model?.providerID,
30546
+ modelID: model?.modelID,
30547
+ agentName: deps.getNotificationParams?.(sessionId)?.agent
30548
+ });
30549
+ }
30487
30550
  logStage(sessionId, "apply", applyStartedAt, timings);
30488
30551
  const lkgSnapshotStartedAt = performance.now();
30489
- const explicitDecision = typeof response.decision === "string" || typeof response.action === "string" || typeof response.cache_bust === "boolean";
30490
- const decisionUpper = decision.toUpperCase();
30491
- const cacheBustingPass = response.cache_bust === true || decisionUpper === "HARD" || decisionUpper === "MIGRATE_HARD" || decisionUpper === "EXECUTE" || decisionUpper === "SOFT" || !explicitDecision;
30492
30552
  if (cacheBustingPass || !getSlot(sessionId)) {
30493
30553
  const captured = captureRustResponse(sessionId, messages, response);
30494
30554
  if (cacheBustingPass && !captured) {
@@ -30572,10 +30632,20 @@ function createRustModeTransform(deps, options) {
30572
30632
  sessionLog(sessionId, "rust compartment mirror-back failed (ignored):", error);
30573
30633
  }
30574
30634
  }
30575
- if (materializeReason !== "none" && passUsageSnapshot.percentage < 80 && getOverflowState(deps.db, sessionId).needsEmergencyRecovery) {
30635
+ const currentOverflowState = getOverflowState(deps.db, sessionId, modelKey);
30636
+ const disarmEvidence = currentOverflowState.needsEmergencyRecovery ? shouldDisarmRustEmergencyRecovery({
30637
+ materialized: materializeReason !== "none",
30638
+ usagePercentage: passUsageSnapshot.percentage,
30639
+ recoveryOrigin: currentOverflowState.emergencyRecoveryOrigin,
30640
+ recoveryArmedAt: getEmergencyRecoveryArmedAt(sessionId),
30641
+ usageEntry: deps.contextUsageMap.get(sessionId),
30642
+ finalWireEstimate: servedFinalWireEstimate,
30643
+ providerProvenLimitTokens: currentOverflowState.detectedContextLimit
30644
+ }) : null;
30645
+ if (disarmEvidence) {
30576
30646
  try {
30577
30647
  clearEmergencyRecovery(deps.db, sessionId);
30578
- sessionLog(sessionId, `rust pass disarmed emergency recovery after ${materializeReason} at ${passUsageSnapshot.percentage.toFixed(1)}% usage`);
30648
+ sessionLog(sessionId, `rust pass disarmed emergency recovery via ${disarmEvidence} after ${materializeReason} at ${passUsageSnapshot.percentage.toFixed(1)}% usage`);
30579
30649
  } catch {}
30580
30650
  }
30581
30651
  wireCaches.set(sessionId, pendingWireCache);
@@ -30586,6 +30656,7 @@ function createRustModeTransform(deps, options) {
30586
30656
  sessionLog(sessionId, "rust transform wire invariant failed; LKG replay required", error);
30587
30657
  }
30588
30658
  if (emergencyFailClosed) {
30659
+ sessionLog(sessionId, "mc_rust_emergency_refusal before_lkg");
30589
30660
  markFailure(sessionId, state, error);
30590
30661
  finishPass(false, false);
30591
30662
  throw new EmergencyFailClosedError("Rust Magic Context was unavailable at a provider-proven context limit", { cause: error });
@@ -30605,10 +30676,17 @@ function createRustModeTransform(deps, options) {
30605
30676
  return {
30606
30677
  run,
30607
30678
  clearSession(sessionId) {
30679
+ const projectRoot = states.get(sessionId)?.memoryAuthorityRoot ?? options.projectRoot ?? null;
30608
30680
  dropSlot(sessionId, "session-deleted");
30609
30681
  states.delete(sessionId);
30610
30682
  wireCaches.delete(sessionId);
30611
- options.moduleClient.closeSession?.(sessionId);
30683
+ if (projectRoot && options.moduleClient.deleteSession) {
30684
+ options.moduleClient.deleteSession(sessionId, projectRoot).catch((error) => {
30685
+ sessionLog(sessionId, "rust module session deletion failed:", error);
30686
+ }).finally(() => options.moduleClient.closeSession?.(sessionId));
30687
+ } else {
30688
+ options.moduleClient.closeSession?.(sessionId);
30689
+ }
30612
30690
  },
30613
30691
  invalidateWireState,
30614
30692
  getState(sessionId) {
@@ -32143,7 +32221,8 @@ function createEventHandler2(deps) {
32143
32221
  inputTokens: totalInputTokens
32144
32222
  },
32145
32223
  updatedAt: now,
32146
- lastResponseTime: now
32224
+ lastResponseTime: now,
32225
+ hasUsageTokens: true
32147
32226
  });
32148
32227
  updates.lastContextPercentage = percentage;
32149
32228
  updates.lastInputTokens = totalInputTokens;
@@ -32942,7 +33021,7 @@ function createToolExecuteAfterHook(args) {
32942
33021
  }
32943
33022
 
32944
33023
  // src/hooks/magic-context/system-prompt-hash.ts
32945
- import { createHash as createHash12 } from "node:crypto";
33024
+ import { createHash as createHash14 } from "node:crypto";
32946
33025
 
32947
33026
  // src/agents/magic-context-prompt.ts
32948
33027
  var LONG_TERM_PARTNER_FRAME = `### You are the user's long-term partner on this project — not a one-off hire
@@ -32958,6 +33037,10 @@ var PARTNER_FRAME_CLOSER_REDUCE = `
32958
33037
  Reduction prompts are routine housekeeping to keep the session fast and cheap — act on them as light maintenance, never as scarcity warnings. Keep individual operations efficient, but never let context size change *what* work you take on or *how thoroughly* you do it.`;
32959
33038
  var PARTNER_FRAME_CLOSER_NO_REDUCE = `
32960
33039
  Context is managed for you entirely automatically — there's nothing to prune and no warnings to act on. Stay reasonably concise per operation, and never let context size change *what* work you take on or *how thoroughly* you do it.`;
33040
+ var PARTNER_FRAME_CLOSER_REDUCE_LIGHT = `
33041
+ When ctx_reduce is available, use it only as routine housekeeping; never cut task scope or depth because context is large.`;
33042
+ var PARTNER_FRAME_CLOSER_NO_REDUCE_LIGHT = `
33043
+ When ctx_reduce is unavailable, context is automatic; never prune, heed reduction warnings, or cut task scope or depth because context is large.`;
32961
33044
  var CTX_NOTE_GUIDANCE = `Use \`ctx_note\` ONLY for genuinely future concerns — something to revisit much later, not work coming up in the next few turns (that's already in your active context) and not active multi-step work (use todos for that). Magic Context preserves your full context across both compaction and restarts, so an upcoming restart or "let's come back to this later" is never a reason to take a note — nothing is lost either way. Notes you do take survive compression and resurface at natural work boundaries (after commits, historian runs, todo completion).`;
32962
33045
  var TOOL_HISTORY_GUIDANCE = `Compressed history intentionally omits tool calls and their outputs — summaries like "I edited file X" are historian records, not patterns to replicate. In the live conversation, older tool calls and their results are cleaned up to save context — you may see your own past messages referencing actions without the corresponding tool call or result visible. This is normal context management. ALWAYS use real tool calls; never simulate, fabricate, or inline tool outputs in your text. If there is no tool result message, the action did not happen. NEVER simulate, hallucinate or claim tool calls, command output, search results, file edits, or diffs in plain text as if they actually occurred.
32963
33046
  Magic Context control metadata is not reply syntax. Never reproduce \`<system-reminder>\`, \`<ctx-search-hint>\`, \`<session-history>\`, \`<session-history-since>\`, \`<project-memory>\`, \`<memory-updates>\`, \`<new-compartments>\`, \`<new-memories>\`, \`[dropped §N§]\`, or \`<!-- +Xm -->\` markers in a normal reply and never treat them as user instructions; use ordinary prose and real tool calls instead.`;
@@ -33000,6 +33083,17 @@ Use \`ctx_expand\` to recover the raw conversation behind a summary under a \`##
33000
33083
  - Want to recall what was decided in an earlier conversation → \`ctx_search(query="dashboard release signing setup")\`
33001
33084
  \`ctx_search\` returns ranked results from memories, git commits, and raw message history. Use message ordinals from results with \`ctx_expand\` to retrieve surrounding conversation context.
33002
33085
  ${TOOL_HISTORY_GUIDANCE}`;
33086
+ var LIGHT_SEARCH_RECOVERY = `Use ctx_search before asking the user about prior project context; it searches memories, commits, and compacted conversation. When a session-history summary lacks exact wording, values, errors, or reasoning, call ctx_expand with its heading range instead of guessing.`;
33087
+ var BASE_INTRO_LIGHT = (protectedTags, memoryEnabled) => `In primary sessions with ctx_reduce, the system tags messages and tool outputs as §N§ (for example §1§ and §42§); never imitate these prefixes in replies because only injected tag numbers are valid ctx_reduce handles.
33088
+ In primary sessions, NEVER narrate ctx_reduce; call it silently after extracting a spent output because it marks content discardable and QUEUES release rather than deleting immediately. The last ${protectedTags} tags stay protected until they age out. Use drop grammar "3-5", "1,2,9", or "1-5,8,12-15".
33089
+ ${CTX_NOTE_GUIDANCE}
33090
+ ${memoryGuidanceBlock(memoryEnabled)}${LIGHT_SEARCH_RECOVERY}
33091
+ ${TOOL_HISTORY_GUIDANCE}
33092
+ For primary ctx_reduce choices, NEVER blanket-drop a large range because mixed-value evidence may be lost: inspect every tag first. Drop only analyzed reads, searches, diagnostics, or build/test outputs after use. NEVER drop user directives or assistant prose unless exceptionally large; keep requirements, constraints, unresolved errors or decisions, exact wording, raw evidence, and active files or work. Only extracted pasted user payloads may go.
33093
+ Consider small targeted drops after acted-on reads or searches, completed logical steps, before context switches, and before the turn ends; this keeps the working set tidy without changing task scope.`;
33094
+ var BASE_INTRO_NO_REDUCE_LIGHT = (memoryEnabled) => `${CTX_NOTE_GUIDANCE}
33095
+ ${memoryGuidanceBlock(memoryEnabled)}${LIGHT_SEARCH_RECOVERY}
33096
+ ${TOOL_HISTORY_GUIDANCE}`;
33003
33097
  var GENERIC_SECTION = `
33004
33098
  ### Reduction Triggers
33005
33099
  - After reading files or search results you already acted on — drop raw outputs.
@@ -33016,21 +33110,27 @@ var GENERIC_SECTION = `
33016
33110
  - Your current task requirements and constraints.
33017
33111
  - Recent errors and unresolved decisions.
33018
33112
  - Active work context and files being edited.`;
33113
+ var SMART_NOTE_GUIDANCE_LIGHT = `
33114
+ surface_condition creates a smart note checked nightly against external signals on ctx_note write.`;
33019
33115
  var TEMPORAL_AWARENESS_GUIDANCE = `
33020
33116
  **Temporal awareness**: User messages may be preceded by HTML comments like \`<!-- +12m -->\`, \`<!-- +2h 15m -->\`, or \`<!-- +3d 4h -->\` indicating time elapsed since the previous message's completion. Compartments in \`<session-history>\` carry \`start-date\` and \`end-date\` attributes (YYYY-MM-DD) showing real-time boundaries. Use these when reasoning about workflow pacing, log durations, build times, or how long ago something happened.`;
33021
33117
  var SUBAGENT_REDUCE_INTRO = (protectedTags) => `Messages and tool outputs are tagged with §N§ identifiers (e.g., §1§, §42§).
33022
33118
  Use \`ctx_reduce\` to drop tool outputs you have already finished with, keeping your working context lean. Syntax: "3-5", "1,2,9", or "1-5,8,12-15". The last ${protectedTags} tags are protected.
33023
33119
  Drop silently — do not narrate it. NEVER drop large ranges blindly (e.g., "1-50"); review each tag first. Do not drop user or assistant text messages — only large tool outputs are worth dropping.
33024
33120
  Older tool calls may show \`[dropped §N§]\` sentinels; that is normal context management, not a pattern to copy. ALWAYS make fresh real tool calls when you need data again; never fabricate or inline tool output.`;
33121
+ var SUBAGENT_REDUCE_INTRO_LIGHT = (protectedTags) => `In bounded subagent sessions, the system tags messages and tool outputs as §N§; use only those IDs in ctx_reduce drop ranges such as "3-5", "1,2,9", or "1-5,8,12-15". The last ${protectedTags} tags stay protected.
33122
+ When dropping, do it silently and NEVER choose a large range before reviewing every tag; drop only finished large tool outputs, never user or assistant messages.
33123
+ If older calls show [dropped §N§], never copy that system sentinel because it is not reply syntax; make a fresh real tool call and never fabricate or inline output.`;
33025
33124
  var CAVEMAN_COMPRESSION_WARNING = `
33026
33125
  **BEWARE**: History compression is on; older user AND assistant text — including your own earlier responses — has been deterministically rewritten in a terse caveman style (dropped articles, missing auxiliaries, \`//\` instead of connectives like \`because\`). This is automatic context compression that runs after the fact, not your actual prior wording or the user's. **DO NOT mimic this style in new turns.** Write fresh responses in normal prose. If you notice your output drifting into caveman cadence, that drift is in-context-learning bleeding from the compressed history — consciously revert to full sentences.`;
33027
- function buildMagicContextSection(_agent, protectedTags, ctxReduceCallable = true, dreamerEnabled = false, temporalAwarenessEnabled = false, cavemanTextCompressionEnabled = false, subagentMode = false, language, memoryEnabled = true) {
33126
+ function buildMagicContextSection(_agent, protectedTags, ctxReduceCallable = true, dreamerEnabled = false, temporalAwarenessEnabled = false, cavemanTextCompressionEnabled = false, subagentMode = false, language, memoryEnabled = true, preset = "full", primaryOverride) {
33028
33127
  if (subagentMode) {
33128
+ const intro = preset === "light" ? SUBAGENT_REDUCE_INTRO_LIGHT(protectedTags) : SUBAGENT_REDUCE_INTRO(protectedTags);
33029
33129
  return `## Magic Context
33030
33130
 
33031
- ${SUBAGENT_REDUCE_INTRO(protectedTags)}`;
33131
+ ${intro}`;
33032
33132
  }
33033
- const smartNoteGuidance = dreamerEnabled ? `
33133
+ const smartNoteGuidance = dreamerEnabled ? preset === "light" ? SMART_NOTE_GUIDANCE_LIGHT : `
33034
33134
  When \`surface_condition\` is provided with \`write\`, the note becomes a project-scoped smart note.
33035
33135
  The dreamer evaluates smart note conditions during nightly runs and surfaces them when conditions are met.
33036
33136
  Example: \`ctx_note(action="write", content="Implement X because Y", surface_condition="When PR #42 is merged in this repo")\`` : "";
@@ -33040,13 +33140,32 @@ Example: \`ctx_note(action="write", content="Implement X because Y", surface_con
33040
33140
  const languageGuidance = languageDirective ? `
33041
33141
 
33042
33142
  ${languageDirective}` : "";
33143
+ if (primaryOverride !== undefined) {
33144
+ return `${primaryOverride}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
33145
+ }
33043
33146
  if (!ctxReduceCallable) {
33147
+ if (preset === "light") {
33148
+ return `## Magic Context
33149
+
33150
+ ${LONG_TERM_PARTNER_FRAME}
33151
+ ${PARTNER_FRAME_CLOSER_NO_REDUCE_LIGHT}
33152
+
33153
+ ${BASE_INTRO_NO_REDUCE_LIGHT(memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
33154
+ }
33044
33155
  return `## Magic Context
33045
33156
 
33046
33157
  ${LONG_TERM_PARTNER_FRAME}
33047
33158
  ${PARTNER_FRAME_CLOSER_NO_REDUCE}
33048
33159
 
33049
33160
  ${BASE_INTRO_NO_REDUCE(memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
33161
+ }
33162
+ if (preset === "light") {
33163
+ return `## Magic Context
33164
+
33165
+ ${LONG_TERM_PARTNER_FRAME}
33166
+ ${PARTNER_FRAME_CLOSER_REDUCE_LIGHT}
33167
+
33168
+ ${BASE_INTRO_LIGHT(protectedTags, memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
33050
33169
  }
33051
33170
  return `## Magic Context
33052
33171
 
@@ -33072,6 +33191,11 @@ function isMagicContextInternalAgent(systemPromptContent) {
33072
33191
  return systemPromptContent.includes("You are Historian — the hippocampus of a long-running coding agent.") || systemPromptContent.includes("for the magic-context system") || systemPromptContent.includes("You are Sidekick, a focused memory-retrieval subagent for an AI coding assistant.");
33073
33192
  }
33074
33193
  function createSystemPromptHashHandler(deps) {
33194
+ const promptSurfaceRuntime = deps.promptSurfaceRuntime ?? createPromptSurfaceRuntime({
33195
+ userConfigDirectory: process.cwd(),
33196
+ warn: (message) => console.warn(`[magic-context] config warning: ${message}`)
33197
+ });
33198
+ const guidanceEpochs = createPromptSurfaceGuidanceEpochCache(promptSurfaceRuntime);
33075
33199
  const stickyDateBySession = new Map;
33076
33200
  const handler = async (input, output) => {
33077
33201
  const sessionId = input.sessionID;
@@ -33109,10 +33233,14 @@ function createSystemPromptHashHandler(deps) {
33109
33233
  const subagentReduceMode = isSubagentSession2 && ctxReduceCallable;
33110
33234
  const effectiveCtxReduceEnabled = isSubagentSession2 ? false : ctxReduceCallable;
33111
33235
  const skipGuidanceForDisabledSubagent = isSubagentSession2 && !ctxReduceCallable;
33236
+ const inputModel = input.model;
33237
+ const liveModel = inputModel?.providerID && inputModel.modelID ? { providerID: inputModel.providerID, modelID: inputModel.modelID } : deps.resolveModel?.(sessionId);
33238
+ const modelKey = liveModel?.providerID && liveModel.modelID ? `${liveModel.providerID}/${liveModel.modelID}` : undefined;
33239
+ const promptSurface = guidanceEpochs.resolve(sessionId, deps.promptSurface, modelKey);
33112
33240
  const fullPrompt = output.system.join(`
33113
33241
  `);
33114
33242
  if (fullPrompt.length > 0 && !fullPrompt.includes(MAGIC_CONTEXT_MARKER) && !skipGuidanceForDisabledSubagent) {
33115
- const guidance = buildMagicContextSection(null, deps.protectedTags, effectiveCtxReduceEnabled, deps.dreamerEnabled, deps.experimentalTemporalAwareness, deps.experimentalCavemanTextCompression, subagentReduceMode, deps.language, deps.memoryEnabled !== false);
33243
+ const guidance = buildMagicContextSection(null, deps.protectedTags, effectiveCtxReduceEnabled, deps.dreamerEnabled, deps.experimentalTemporalAwareness, deps.experimentalCavemanTextCompression, subagentReduceMode, deps.language, deps.memoryEnabled !== false, promptSurface.preset, promptSurface.primaryOverride);
33116
33244
  output.system.push(guidance);
33117
33245
  sessionLog(sessionId, `injected generic guidance into system prompt (ctxReduce=${effectiveCtxReduceEnabled}, subagent=${isSubagentSession2}, subagentReduceMode=${subagentReduceMode})`);
33118
33246
  }
@@ -33143,7 +33271,7 @@ function createSystemPromptHashHandler(deps) {
33143
33271
  return;
33144
33272
  if (!availability.frozen)
33145
33273
  return;
33146
- const currentHash = createHash12("md5").update(systemContent).digest("hex");
33274
+ const currentHash = createHash14("md5").update(promptSurfaceHashMaterial(systemContent, promptSurface.preset)).digest("hex");
33147
33275
  if (!sessionMetaEarly) {
33148
33276
  return;
33149
33277
  }
@@ -33181,6 +33309,7 @@ function createSystemPromptHashHandler(deps) {
33181
33309
  return {
33182
33310
  handler,
33183
33311
  clearSession: (sessionId) => {
33312
+ guidanceEpochs.clear(sessionId);
33184
33313
  clearSystemPromptHashSession(sessionId, {
33185
33314
  stickyDateBySession,
33186
33315
  cachedDocsBySession: new Map
@@ -33335,11 +33464,13 @@ function createMagicContextHook(deps) {
33335
33464
  const fence = getSchemaFenceRejection();
33336
33465
  recordHookInitFailure({
33337
33466
  type: "storage",
33338
- reason: migration && blockingProcesses.length > 0 ? {
33467
+ reason: migration && (blockingProcesses.length > 0 || migration.unreadableFile) ? {
33339
33468
  kind: "migration_guard",
33340
33469
  persistedVersion: migration.persistedVersion,
33341
33470
  supportedVersion: migration.supportedVersion,
33342
- blockingProcesses
33471
+ blockingProcesses,
33472
+ ...migration.unreadableFile ? { unreadableFile: migration.unreadableFile } : {},
33473
+ ...migration.unreadableArm ? { unreadableArm: migration.unreadableArm } : {}
33343
33474
  } : fence ? {
33344
33475
  kind: "schema_fence",
33345
33476
  persistedVersion: fence.persistedVersion,
@@ -33631,6 +33762,7 @@ function createMagicContextHook(deps) {
33631
33762
  const client = {
33632
33763
  call: (args) => transport.call(args),
33633
33764
  stateSyncCapabilities: (args) => transport.stateSyncCapabilities(args),
33765
+ deleteSession: (sessionId, projectRoot) => transport.deleteSession(sessionId, projectRoot),
33634
33766
  closeSession: (sessionId) => transport.closeSession(sessionId),
33635
33767
  authorityStatus: (args) => transport.authorityStatus(args),
33636
33768
  authorityPrepare: (args) => transport.authorityPrepare(args),
@@ -33659,6 +33791,23 @@ function createMagicContextHook(deps) {
33659
33791
  return client;
33660
33792
  })();
33661
33793
  const rustModeModuleClient = deps.config.transform_mode === "rust" ? authorityRecoveryModuleClient : undefined;
33794
+ const syncModuleDomain = async (domain) => {
33795
+ if (!rustModeModuleClient?.mirrorPull)
33796
+ return;
33797
+ for (;; ) {
33798
+ const cursor = getMirrorCursor(db, domain);
33799
+ const response = await rustModeModuleClient.mirrorPull({
33800
+ domain,
33801
+ cursor,
33802
+ limit: 1000
33803
+ });
33804
+ const next = applyMirrorPage({ db, page: response.page });
33805
+ if (!response.page.has_more || next === cursor)
33806
+ break;
33807
+ }
33808
+ };
33809
+ const syncModuleNotes = () => syncModuleDomain("notes");
33810
+ const syncModuleMemories = () => syncModuleDomain("memories");
33662
33811
  const rustToolBackends = deps.config.transform_mode === "rust" && rustModeModuleClient ? {
33663
33812
  authorityState: async ({ projectPath: projectPath2, projectRoot, domain }) => {
33664
33813
  if (!rustModeModuleClient.authorityStatus)
@@ -33683,7 +33832,7 @@ function createMagicContextHook(deps) {
33683
33832
  command_id: commandId
33684
33833
  }
33685
33834
  }),
33686
- note: ({
33835
+ note: async ({
33687
33836
  commandId,
33688
33837
  sessionId,
33689
33838
  projectRoot,
@@ -33695,26 +33844,30 @@ function createMagicContextHook(deps) {
33695
33844
  limit,
33696
33845
  offset,
33697
33846
  noteId
33698
- }) => rustModeModuleClient.call({
33699
- sessionId,
33700
- projectRoot,
33701
- method: "ctx_note",
33702
- body: {
33703
- name: "ctx_note",
33704
- arguments: {
33705
- ...commandId ? { command_id: commandId } : {},
33706
- action,
33707
- content,
33708
- memory_project: memoryProject,
33709
- surface_condition: surfaceCondition,
33710
- filter,
33711
- limit,
33712
- offset,
33713
- note_id: noteId
33847
+ }) => {
33848
+ const response = await rustModeModuleClient.call({
33849
+ sessionId,
33850
+ projectRoot,
33851
+ method: "ctx_note",
33852
+ body: {
33853
+ name: "ctx_note",
33854
+ arguments: {
33855
+ ...commandId ? { command_id: commandId } : {},
33856
+ action,
33857
+ content,
33858
+ memory_project: memoryProject,
33859
+ surface_condition: surfaceCondition,
33860
+ filter,
33861
+ limit,
33862
+ offset,
33863
+ note_id: noteId
33864
+ }
33714
33865
  }
33715
- }
33716
- }),
33717
- memory: ({
33866
+ });
33867
+ await syncModuleNotes();
33868
+ return response;
33869
+ },
33870
+ memory: async ({
33718
33871
  commandId,
33719
33872
  sessionId,
33720
33873
  projectRoot,
@@ -33724,23 +33877,27 @@ function createMagicContextHook(deps) {
33724
33877
  category,
33725
33878
  ids,
33726
33879
  reason
33727
- }) => rustModeModuleClient.call({
33728
- sessionId,
33729
- projectRoot,
33730
- method: "ctx_memory",
33731
- body: {
33732
- name: "ctx_memory",
33733
- arguments: {
33734
- ...commandId ? { command_id: commandId } : {},
33735
- action,
33736
- content,
33737
- category,
33738
- ids,
33739
- reason,
33740
- memory_project: memoryProject
33880
+ }) => {
33881
+ const response = await rustModeModuleClient.call({
33882
+ sessionId,
33883
+ projectRoot,
33884
+ method: "ctx_memory",
33885
+ body: {
33886
+ name: "ctx_memory",
33887
+ arguments: {
33888
+ ...commandId ? { command_id: commandId } : {},
33889
+ action,
33890
+ content,
33891
+ category,
33892
+ ids,
33893
+ reason,
33894
+ memory_project: memoryProject
33895
+ }
33741
33896
  }
33742
- }
33743
- }),
33897
+ });
33898
+ await syncModuleMemories();
33899
+ return response;
33900
+ },
33744
33901
  noteEvaluationAvailable: (evaluationProjectPath) => getModuleNoteEvaluationBridge(evaluationProjectPath) !== undefined,
33745
33902
  memorySync: (sessionId) => {
33746
33903
  rustMemorySyncRequestedSessions.add(sessionId);
@@ -33751,21 +33908,6 @@ function createMagicContextHook(deps) {
33751
33908
  return;
33752
33909
  if (getModuleNoteEvaluationBridge(bridgeProjectPath))
33753
33910
  return;
33754
- const syncModuleNotes = async () => {
33755
- for (;; ) {
33756
- const cursor = getMirrorCursor(db, "notes");
33757
- const response = await rustModeModuleClient.mirrorPull?.({
33758
- domain: "notes",
33759
- cursor,
33760
- limit: 1000
33761
- });
33762
- if (!response)
33763
- throw new Error("mirror.pull is unavailable for notes");
33764
- const next = applyMirrorPage({ db, page: response.page });
33765
- if (!response.page.has_more || next === cursor)
33766
- break;
33767
- }
33768
- };
33769
33911
  registerModuleNoteEvaluationBridge(bridgeProjectPath, {
33770
33912
  sync: syncModuleNotes,
33771
33913
  async evaluate({ contextNoteId, sessionId, verdict }) {
@@ -33873,6 +34015,7 @@ function createMagicContextHook(deps) {
33873
34015
  } : undefined,
33874
34016
  maybeAutoEmbedSession,
33875
34017
  transformMode: deps.config.transform_mode,
34018
+ promptSurface: deps.config.prompt_surface,
33876
34019
  rustModeModuleClient,
33877
34020
  tsAuthorityRecoveryModuleClient: authorityRecoveryModuleClient,
33878
34021
  rustMemorySyncRequestedSessions,
@@ -34054,6 +34197,9 @@ function createMagicContextHook(deps) {
34054
34197
  dreamerEnabled: dreamerRunnable,
34055
34198
  memoryEnabled: deps.config.memory?.enabled !== false,
34056
34199
  language: deps.config.language,
34200
+ promptSurface: deps.config.prompt_surface,
34201
+ promptSurfaceRuntime: deps.promptSurfaceRuntime,
34202
+ resolveModel: resolveLiveModel,
34057
34203
  historyRefreshSessions,
34058
34204
  systemPromptRefreshSessions,
34059
34205
  pendingMaterializationSessions,
@@ -34194,6 +34340,7 @@ async function createSessionHooksAsync(args) {
34194
34340
  compactionHandler,
34195
34341
  liveSessionState,
34196
34342
  rustModeModuleClient: args.rustModeModuleClient,
34343
+ promptSurfaceRuntime: args.promptSurfaceRuntime,
34197
34344
  config: buildMagicContextHookConfig(pluginConfig)
34198
34345
  });
34199
34346
  return {
@@ -35024,7 +35171,7 @@ function registerRpcHandlers(rpcServer, args) {
35024
35171
  const db = getDb();
35025
35172
  if (!db)
35026
35173
  return { ok: false, error: "db unavailable" };
35027
- const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-k72ejkkh.js");
35174
+ const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-zc915ceq.js");
35028
35175
  const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-6njqewzk.js");
35029
35176
  log(`[rpc] recomp requested for session ${sessionId}`);
35030
35177
  const ctx = await buildManagedCtx(db);
@@ -35040,7 +35187,7 @@ function registerRpcHandlers(rpcServer, args) {
35040
35187
  const db = getDb();
35041
35188
  if (!db)
35042
35189
  return { ok: false, error: "db unavailable" };
35043
- const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-k72ejkkh.js");
35190
+ const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-zc915ceq.js");
35044
35191
  const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-6njqewzk.js");
35045
35192
  log(`[rpc] session-upgrade requested for session ${sessionId}`);
35046
35193
  const ctx = await buildManagedCtx(db);
@@ -35057,7 +35204,7 @@ function registerRpcHandlers(rpcServer, args) {
35057
35204
  if (!db)
35058
35205
  return { ok: false, error: "db unavailable" };
35059
35206
  try {
35060
- const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-xt41zbw4.js");
35207
+ const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-53cjs6mr.js");
35061
35208
  updateSessionMeta2(db, sessionId, { upgradeRemindedAt: Date.now() });
35062
35209
  return { ok: true };
35063
35210
  } catch (error) {
@@ -36343,7 +36490,7 @@ Mark discardable once processed: large outputs you've summarized, repeated or re
36343
36490
  Keep: user messages, unresolved errors, raw evidence you haven't extracted yet, and outputs whose exact wording may matter later.
36344
36491
  Never blanket-mark large ranges (e.g. "1-50") — review what each tag holds first.`;
36345
36492
  // src/tools/ctx-reduce/tools.ts
36346
- import { createHash as createHash13 } from "node:crypto";
36493
+ import { createHash as createHash15 } from "node:crypto";
36347
36494
  import { tool as tool4 } from "@opencode-ai/plugin";
36348
36495
 
36349
36496
  // src/features/magic-context/range-parser.ts
@@ -36413,11 +36560,11 @@ function createCtxReduceTool(deps) {
36413
36560
  const stableId = `oc-${sessionId}-${callId}`;
36414
36561
  if (Buffer.byteLength(stableId) <= 128)
36415
36562
  return stableId;
36416
- return `oc-${createHash13("sha256").update(stableId).digest("hex")}`;
36563
+ return `oc-${createHash15("sha256").update(stableId).digest("hex")}`;
36417
36564
  }
36418
36565
  fallbackCommandSequence += 1;
36419
36566
  const monotonicId = `oc-${sessionId}-${fallbackCommandSequence}`;
36420
- return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash13("sha256").update(monotonicId).digest("hex")}`;
36567
+ return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash15("sha256").update(monotonicId).digest("hex")}`;
36421
36568
  };
36422
36569
  return tool4({
36423
36570
  description: CTX_REDUCE_DESCRIPTION,
@@ -36813,10 +36960,23 @@ function createToolRegistry(args) {
36813
36960
  rustToolBackends
36814
36961
  }) : {}
36815
36962
  };
36816
- for (const toolDefinition of Object.values(allTools)) {
36963
+ const promptSurfaceRuntime = args.promptSurfaceRuntime ?? createPromptSurfaceRuntime({
36964
+ harness: "opencode",
36965
+ directory: ctx.directory,
36966
+ warn: (message) => console.warn(`[magic-context] config warning: ${message}`)
36967
+ });
36968
+ const registration = promptSurfaceRuntime.resolveRegistration(args.registrationPromptSurface ?? pluginConfig.prompt_surface);
36969
+ const surfacedTools = Object.fromEntries(Object.entries(allTools).map(([toolId, definition]) => [
36970
+ toolId,
36971
+ {
36972
+ ...definition,
36973
+ description: registration.descriptionFor(toolId, definition.description ?? "")
36974
+ }
36975
+ ]));
36976
+ for (const toolDefinition of Object.values(surfacedTools)) {
36817
36977
  normalizeToolArgSchemas(toolDefinition);
36818
36978
  }
36819
- return allTools;
36979
+ return surfacedTools;
36820
36980
  }
36821
36981
 
36822
36982
  // src/shared/exit-abort-registry.ts
@@ -36844,15 +37004,15 @@ function unregisterExitAbort(controller) {
36844
37004
  import { randomBytes, timingSafeEqual } from "node:crypto";
36845
37005
  import {
36846
37006
  chmodSync,
36847
- mkdirSync as mkdirSync3,
37007
+ mkdirSync as mkdirSync2,
36848
37008
  readdirSync,
36849
- readFileSync as readFileSync7,
36850
- renameSync as renameSync4,
36851
- rmSync as rmSync3,
36852
- unlinkSync as unlinkSync2,
36853
- writeFileSync as writeFileSync5
37009
+ readFileSync as readFileSync6,
37010
+ renameSync as renameSync3,
37011
+ rmSync as rmSync2,
37012
+ unlinkSync,
37013
+ writeFileSync as writeFileSync4
36854
37014
  } from "node:fs";
36855
- import { dirname as dirname5 } from "node:path";
37015
+ import { dirname as dirname4 } from "node:path";
36856
37016
  var MAX_BODY_BYTES = 1048576;
36857
37017
  var WS_AUTH_TIMEOUT_MS = 5000;
36858
37018
  var WS_CLOSE_UNAUTHORIZED = 4401;
@@ -36926,28 +37086,28 @@ class MagicContextRpcServer {
36926
37086
  this.port = server.port ?? 0;
36927
37087
  try {
36928
37088
  this.warnIfOtherLiveInstance();
36929
- const dir = dirname5(this.portFilePath);
37089
+ const dir = dirname4(this.portFilePath);
36930
37090
  const enforcePrivatePermissions = shouldEnforcePrivateStoragePermissions();
36931
37091
  if (enforcePrivatePermissions) {
36932
- mkdirSync3(dir, { recursive: true, mode: 448 });
37092
+ mkdirSync2(dir, { recursive: true, mode: 448 });
36933
37093
  try {
36934
37094
  chmodSync(dir, 448);
36935
37095
  } catch {}
36936
37096
  } else {
36937
- mkdirSync3(dir, { recursive: true });
37097
+ mkdirSync2(dir, { recursive: true });
36938
37098
  }
36939
37099
  const tmpPath = `${this.portFilePath}.tmp`;
36940
37100
  try {
36941
- rmSync3(tmpPath, { force: true });
37101
+ rmSync2(tmpPath, { force: true });
36942
37102
  } catch {}
36943
- writeFileSync5(tmpPath, JSON.stringify({
37103
+ writeFileSync4(tmpPath, JSON.stringify({
36944
37104
  port: this.port,
36945
37105
  pid: process.pid,
36946
37106
  started_at: this.startedAt,
36947
37107
  token: this.token,
36948
37108
  instance_id: this.instanceId
36949
37109
  }), enforcePrivatePermissions ? { encoding: "utf-8", mode: 384 } : { encoding: "utf-8" });
36950
- renameSync4(tmpPath, this.portFilePath);
37110
+ renameSync3(tmpPath, this.portFilePath);
36951
37111
  if (enforcePrivatePermissions) {
36952
37112
  try {
36953
37113
  chmodSync(this.portFilePath, 384);
@@ -36974,7 +37134,7 @@ class MagicContextRpcServer {
36974
37134
  this.server = null;
36975
37135
  }
36976
37136
  try {
36977
- unlinkSync2(this.portFilePath);
37137
+ unlinkSync(this.portFilePath);
36978
37138
  } catch {}
36979
37139
  }
36980
37140
  warnIfOtherLiveInstance() {
@@ -36982,7 +37142,7 @@ class MagicContextRpcServer {
36982
37142
  for (const entry of readdirSync(this.portDir)) {
36983
37143
  if (!entry.startsWith("port-") || !entry.endsWith(".json"))
36984
37144
  continue;
36985
- const record = parseRpcPortFile(readFileSync7(`${this.portDir}/${entry}`, "utf-8"));
37145
+ const record = parseRpcPortFile(readFileSync6(`${this.portDir}/${entry}`, "utf-8"));
36986
37146
  if (!record || record.pid === process.pid || !isPidAlive(record.pid))
36987
37147
  continue;
36988
37148
  log(`[rpc] another Magic Context RPC server is active for this project (pid ${record.pid}, port ${record.port}); starting separate instance on a new port`);
@@ -37122,7 +37282,13 @@ var server = async (ctx) => {
37122
37282
  warn: (m) => log(`[magic-context] ${m}`),
37123
37283
  info: (m) => log(`[magic-context] ${m}`)
37124
37284
  });
37125
- const pluginConfig = loadPluginConfig(ctx.directory);
37285
+ const loadedPluginConfig = loadPluginConfigDetailed(ctx.directory);
37286
+ const pluginConfig = loadedPluginConfig.config;
37287
+ const promptSurfaceRuntime = createPromptSurfaceRuntime({
37288
+ harness: "opencode",
37289
+ directory: ctx.directory,
37290
+ warn: (message) => log(`[magic-context] config warning: ${message}`)
37291
+ });
37126
37292
  if (configMigrationWarnings.length > 0) {
37127
37293
  pluginConfig.configWarnings = [
37128
37294
  ...configMigrationWarnings,
@@ -37182,7 +37348,8 @@ var server = async (ctx) => {
37182
37348
  ctx,
37183
37349
  pluginConfig,
37184
37350
  liveSessionState,
37185
- rustModeModuleClient
37351
+ rustModeModuleClient,
37352
+ promptSurfaceRuntime
37186
37353
  });
37187
37354
  const magicContextRuntime = {
37188
37355
  magicContext: hooks.magicContext,
@@ -37207,7 +37374,8 @@ var server = async (ctx) => {
37207
37374
  ctx,
37208
37375
  pluginConfig,
37209
37376
  liveSessionState,
37210
- rustModeModuleClient
37377
+ rustModeModuleClient,
37378
+ promptSurfaceRuntime
37211
37379
  });
37212
37380
  if (!reopened.magicContext)
37213
37381
  return false;
@@ -37224,7 +37392,9 @@ var server = async (ctx) => {
37224
37392
  const tools5 = createToolRegistry({
37225
37393
  ctx,
37226
37394
  pluginConfig,
37227
- rustToolBackends: magicContextRuntime.rustToolBackends
37395
+ rustToolBackends: magicContextRuntime.rustToolBackends,
37396
+ promptSurfaceRuntime,
37397
+ registrationPromptSurface: loadedPluginConfig.registrationPromptSurface
37228
37398
  });
37229
37399
  if (pluginConfig.enabled && magicContextRuntime.magicContext) {
37230
37400
  try {
@@ -37330,7 +37500,7 @@ var server = async (ctx) => {
37330
37500
  {
37331
37501
  const fence = getSchemaFenceRejection();
37332
37502
  if (fence) {
37333
- import("./conflict-warning-hook-fvpfvt0w.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
37503
+ import("./conflict-warning-hook-p2pmhvn7.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
37334
37504
  }
37335
37505
  }
37336
37506
  if (conflictResult?.hasConflict) {
@@ -37351,7 +37521,7 @@ var server = async (ctx) => {
37351
37521
  } = await import("./announcement-gms2nhya.js");
37352
37522
  if (shouldShowAnnouncement2()) {
37353
37523
  setTimeout(() => {
37354
- import("./conflict-warning-hook-fvpfvt0w.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION2, ANNOUNCEMENT_FEATURES2, ANNOUNCEMENT_FOOTER2, markAnnouncementSeen2)).catch(() => {});
37524
+ import("./conflict-warning-hook-p2pmhvn7.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION2, ANNOUNCEMENT_FEATURES2, ANNOUNCEMENT_FOOTER2, markAnnouncementSeen2)).catch(() => {});
37355
37525
  }, 8000);
37356
37526
  }
37357
37527
  } catch {}