@cortexkit/opencode-magic-context 0.34.2 → 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 (88) 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/task-executor.d.ts.map +1 -1
  15. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  16. package/dist/features/magic-context/mural/compress-cues.d.ts +6 -2
  17. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  18. package/dist/features/magic-context/mural/storage-mural-cues.d.ts +4 -4
  19. package/dist/hooks/magic-context/compartment-runner-historian.d.ts +2 -14
  20. package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
  21. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  22. package/dist/hooks/magic-context/compartment-runner-validation.d.ts +16 -2
  23. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
  24. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  25. package/dist/hooks/magic-context/hook.d.ts +10 -3
  26. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  27. package/dist/hooks/magic-context/module-state-sync.d.ts +1 -1
  28. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  29. package/dist/hooks/magic-context/module-transport.d.ts +2 -1
  30. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  31. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  32. package/dist/hooks/magic-context/read-session-chunk.d.ts +5 -0
  33. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  34. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +2 -0
  35. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
  36. package/dist/hooks/magic-context/rust-mode-transform.d.ts +6 -0
  37. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  38. package/dist/hooks/magic-context/system-prompt-hash.d.ts +19 -5
  39. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  40. package/dist/hooks/magic-context/transform.d.ts +3 -0
  41. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  42. package/dist/index-0c9dmw9m.js +116 -0
  43. package/dist/{index-z70pxrq1.js → index-4anesz49.js} +726 -611
  44. package/dist/{index-dtas91s5.js → index-8aaadh98.js} +7 -119
  45. package/dist/{index-b563sga5.js → index-h8mk7vpa.js} +541 -7
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +796 -809
  48. package/dist/plugin/hooks/create-session-hooks.d.ts +12 -0
  49. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  50. package/dist/plugin/rpc-handlers.d.ts +1 -0
  51. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  52. package/dist/plugin/tool-registry.d.ts +4 -0
  53. package/dist/plugin/tool-registry.d.ts.map +1 -1
  54. package/dist/{recomp-orchestrator-6cd3nrt7.js → recomp-orchestrator-zc915ceq.js} +3 -2
  55. package/dist/shared/index.d.ts +2 -0
  56. package/dist/shared/index.d.ts.map +1 -1
  57. package/dist/shared/prompt-surface-runtime.d.ts +43 -0
  58. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -0
  59. package/dist/shared/prompt-surface.d.ts +49 -0
  60. package/dist/shared/prompt-surface.d.ts.map +1 -0
  61. package/dist/{storage-meta-session-xt41zbw4.js → storage-meta-session-53cjs6mr.js} +1 -1
  62. package/dist/tools/ctx-expand/tools.d.ts +1 -0
  63. package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
  64. package/dist/tools/ctx-memory/tools.d.ts +1 -0
  65. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  66. package/dist/tools/ctx-note/tools.d.ts +1 -0
  67. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  68. package/dist/tools/ctx-reduce/tools.d.ts +1 -0
  69. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  70. package/dist/tools/ctx-search/tools.d.ts +1 -0
  71. package/dist/tools/ctx-search/tools.d.ts.map +1 -1
  72. package/dist/tools/light-descriptions.d.ts +6 -0
  73. package/dist/tools/light-descriptions.d.ts.map +1 -0
  74. package/package.json +1 -1
  75. package/src/agents/magic-context-prompt.test.ts +144 -0
  76. package/src/agents/magic-context-prompt.ts +53 -2
  77. package/src/config/index.test.ts +53 -0
  78. package/src/config/index.ts +4 -0
  79. package/src/config/project-security.test.ts +20 -0
  80. package/src/config/project-security.ts +23 -0
  81. package/src/config/schema/magic-context.test.ts +58 -0
  82. package/src/config/schema/magic-context.ts +61 -1
  83. package/src/shared/index.ts +2 -0
  84. package/src/shared/prompt-surface-a1-golden.md +458 -0
  85. package/src/shared/prompt-surface-runtime.test.ts +141 -0
  86. package/src/shared/prompt-surface-runtime.ts +250 -0
  87. package/src/shared/prompt-surface.test.ts +109 -0
  88. 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,
@@ -220,7 +223,6 @@ import {
220
223
  insertUserMemoryCandidates,
221
224
  invalidateMemory,
222
225
  invalidateProject,
223
- invalidateTrueRawTokenCache,
224
226
  isConsumerReconnectTransient,
225
227
  isDatabasePersisted,
226
228
  isEmbeddingEnabled,
@@ -241,6 +243,7 @@ import {
241
243
  markProjectLoadUntrusted,
242
244
  memoryNeedsCue,
243
245
  mergeMemoryStats,
246
+ migrateMagicContextConfigLocations,
244
247
  mustMaterialize,
245
248
  nextDueAtMs,
246
249
  nextOccurrence,
@@ -262,6 +265,7 @@ import {
262
265
  prepareCompartmentInjection,
263
266
  primerOccurrenceKey,
264
267
  primerOccurrenceUtcDay,
268
+ promptSurfaceHashMaterial,
265
269
  promptSyncWithValidatedOutputRetry,
266
270
  pruneAutoSearchHintDecisions,
267
271
  pruneExpiredUserMemoryCandidates,
@@ -309,10 +313,14 @@ import {
309
313
  resetProtectedTailNoEligibleHead,
310
314
  resolveCompactionModeRecord,
311
315
  resolveGitTopLevel,
316
+ resolveLegacyConfigSources,
317
+ resolveLegacyConfigSourcesForHarness,
318
+ resolveModelConfigOrDefault,
312
319
  resolveOpenCodeProtectedTailBoundary,
313
320
  resolveProjectIdentity,
314
321
  resolveProjectIdentityForSession,
315
322
  resolveProjectIdentityStrict,
323
+ resolvePromptSurface,
316
324
  resolveStoredPathWorkspaceIdentity,
317
325
  resolveWorkspaceIdentitySet,
318
326
  resolveWorkspaceShareCategories,
@@ -374,7 +382,7 @@ import {
374
382
  upsertCommits,
375
383
  verificationFileExists,
376
384
  withContentLanguageDirective
377
- } from "./index-z70pxrq1.js";
385
+ } from "./index-4anesz49.js";
378
386
  import {
379
387
  deriveHistorianChunkTokens,
380
388
  deriveTriggerBudget,
@@ -411,6 +419,7 @@ import {
411
419
  createToolDropTarget,
412
420
  deleteIndexedMessage,
413
421
  estimateTokens,
422
+ estimateTrueRawMessageTokens,
414
423
  extractInMemoryMessageViews,
415
424
  extractTexts,
416
425
  extractToolCallObservation,
@@ -424,6 +433,7 @@ import {
424
433
  hasMeaningfulUserText,
425
434
  indexMessagesAfterOrdinal,
426
435
  indexSingleMessage,
436
+ invalidateTrueRawTokenCache,
427
437
  isEditTool,
428
438
  isFilePart,
429
439
  isMessageIndexReconciledThrough,
@@ -453,7 +463,7 @@ import {
453
463
  textMentionsRecentCommit,
454
464
  updateSessionMeta,
455
465
  withRawSessionMessageCache
456
- } from "./index-b563sga5.js";
466
+ } from "./index-h8mk7vpa.js";
457
467
  import {
458
468
  Database,
459
469
  closeQuietly,
@@ -465,12 +475,14 @@ import {
465
475
  } from "./index-fcyvznch.js";
466
476
  import {
467
477
  cleanupConflictWarnings,
468
- detectConfigFile,
469
478
  detectConflicts,
479
+ sendConflictWarning
480
+ } from "./index-8aaadh98.js";
481
+ import {
482
+ detectConfigFile,
470
483
  parseJsonc,
471
- sendConflictWarning,
472
484
  stripJsonComments
473
- } from "./index-dtas91s5.js";
485
+ } from "./index-0c9dmw9m.js";
474
486
  import {
475
487
  ANNOUNCEMENT_FEATURES,
476
488
  ANNOUNCEMENT_FOOTER,
@@ -8190,10 +8202,10 @@ var require_stringify = __commonJS((exports, module) => {
8190
8202
  replacer = null;
8191
8203
  indent = EMPTY;
8192
8204
  };
8193
- 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;
8194
8206
  var join_content = (inside, value, gap) => {
8195
8207
  const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
8196
- return join2(comment, inside, gap);
8208
+ return join(comment, inside, gap);
8197
8209
  };
8198
8210
  var stringify_string = (holder, key, value) => {
8199
8211
  const raw = get_raw_string_literal(holder, key);
@@ -8215,13 +8227,13 @@ var require_stringify = __commonJS((exports, module) => {
8215
8227
  if (i !== 0) {
8216
8228
  inside += COMMA;
8217
8229
  }
8218
- 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);
8219
8231
  inside += before || LF + deeper_gap;
8220
8232
  inside += stringify(i, value, deeper_gap) || STR_NULL;
8221
8233
  inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
8222
8234
  after_comma = process_comments(value, AFTER(i), deeper_gap);
8223
8235
  }
8224
- 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);
8225
8237
  return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
8226
8238
  };
8227
8239
  var object_stringify = (value, gap) => {
@@ -8242,13 +8254,13 @@ var require_stringify = __commonJS((exports, module) => {
8242
8254
  inside += COMMA;
8243
8255
  }
8244
8256
  first = false;
8245
- 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);
8246
8258
  inside += before || LF + deeper_gap;
8247
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);
8248
8260
  after_comma = process_comments(value, AFTER(key), deeper_gap);
8249
8261
  };
8250
8262
  keys.forEach(iteratee);
8251
- 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);
8252
8264
  return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
8253
8265
  };
8254
8266
  function stringify(key, holder, gap) {
@@ -8516,7 +8528,7 @@ function buildHiddenAgentConfig(prompt, allowedTools, maxSteps, overrides, agent
8516
8528
  }
8517
8529
 
8518
8530
  // src/config/index.ts
8519
- import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
8531
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
8520
8532
 
8521
8533
  // src/config/agent-disable.ts
8522
8534
  var COMPACTION_ENABLED_PATH = `compaction${"."}enabled`;
@@ -8578,384 +8590,6 @@ function migrateLegacyAgentEnabledInMemory(rawConfig, warnings) {
8578
8590
  return patched;
8579
8591
  }
8580
8592
 
8581
- // src/config/migrate-config-location.ts
8582
- import {
8583
- closeSync,
8584
- existsSync,
8585
- mkdirSync,
8586
- openSync,
8587
- readFileSync,
8588
- renameSync,
8589
- rmSync,
8590
- statSync,
8591
- unlinkSync,
8592
- writeFileSync
8593
- } from "node:fs";
8594
- import { homedir } from "node:os";
8595
- import { basename, dirname, isAbsolute, join } from "node:path";
8596
- var CONFIG_FILE_BASENAME = "magic-context";
8597
- var MOVED_MARKER_SUFFIX = ".MOVED_READPLEASE";
8598
- function homeDir() {
8599
- if (process.platform === "win32") {
8600
- return process.env.USERPROFILE || process.env.HOME || homedir();
8601
- }
8602
- return process.env.HOME || homedir();
8603
- }
8604
- function configHome() {
8605
- const xdg = process.env.XDG_CONFIG_HOME;
8606
- if (xdg && isAbsolute(xdg))
8607
- return xdg;
8608
- return join(homeDir(), ".config");
8609
- }
8610
- function cortexKitUserConfigBasePath() {
8611
- return join(configHome(), "cortexkit", CONFIG_FILE_BASENAME);
8612
- }
8613
- function cortexKitProjectConfigBasePath(directory) {
8614
- return join(directory, ".cortexkit", CONFIG_FILE_BASENAME);
8615
- }
8616
- function resolveCortexKitUserConfigPath() {
8617
- return `${cortexKitUserConfigBasePath()}.jsonc`;
8618
- }
8619
- function resolveCortexKitProjectConfigPath(directory) {
8620
- return `${cortexKitProjectConfigBasePath(directory)}.jsonc`;
8621
- }
8622
- function legacySourcesForBase(basePath, label) {
8623
- return [
8624
- { path: `${basePath}.jsonc`, label: `${label} magic-context.jsonc` },
8625
- { path: `${basePath}.json`, label: `${label} magic-context.json` }
8626
- ];
8627
- }
8628
- function userScopeConfigPaths() {
8629
- return new Set([
8630
- `${cortexKitUserConfigBasePath()}.jsonc`,
8631
- `${cortexKitUserConfigBasePath()}.json`,
8632
- join(configHome(), "opencode", `${CONFIG_FILE_BASENAME}.jsonc`),
8633
- join(configHome(), "opencode", `${CONFIG_FILE_BASENAME}.json`),
8634
- join(homeDir(), ".pi", "agent", `${CONFIG_FILE_BASENAME}.jsonc`),
8635
- join(homeDir(), ".pi", "agent", `${CONFIG_FILE_BASENAME}.json`)
8636
- ]);
8637
- }
8638
- function resolveLegacyConfigSources(directory) {
8639
- const userPaths = userScopeConfigPaths();
8640
- return {
8641
- user: [
8642
- ...legacySourcesForBase(join(configHome(), "opencode", CONFIG_FILE_BASENAME), "OpenCode user"),
8643
- ...legacySourcesForBase(join(homeDir(), ".pi", "agent", CONFIG_FILE_BASENAME), "Pi user")
8644
- ],
8645
- project: [
8646
- ...legacySourcesForBase(join(directory, CONFIG_FILE_BASENAME), "project root"),
8647
- ...legacySourcesForBase(join(directory, ".opencode", CONFIG_FILE_BASENAME), "OpenCode project"),
8648
- ...legacySourcesForBase(join(directory, ".pi", CONFIG_FILE_BASENAME), "Pi project")
8649
- ].filter((source) => !userPaths.has(source.path))
8650
- };
8651
- }
8652
- function resolveLegacyConfigSourcesForHarness(directory, harness) {
8653
- if (harness === "pi") {
8654
- return {
8655
- user: legacySourcesForBase(join(homeDir(), ".pi", "agent", CONFIG_FILE_BASENAME), "Pi user"),
8656
- project: legacySourcesForBase(join(directory, ".pi", CONFIG_FILE_BASENAME), "Pi project")
8657
- };
8658
- }
8659
- return {
8660
- user: legacySourcesForBase(join(configHome(), "opencode", CONFIG_FILE_BASENAME), "OpenCode user"),
8661
- project: [
8662
- ...legacySourcesForBase(join(directory, CONFIG_FILE_BASENAME), "project root"),
8663
- ...legacySourcesForBase(join(directory, ".opencode", CONFIG_FILE_BASENAME), "OpenCode project")
8664
- ]
8665
- };
8666
- }
8667
- function stripJsoncForParse(input) {
8668
- let out = "";
8669
- let inString = false;
8670
- let escaped = false;
8671
- for (let i = 0;i < input.length; i++) {
8672
- const ch = input[i];
8673
- const next = input[i + 1];
8674
- if (inString) {
8675
- out += ch;
8676
- if (escaped)
8677
- escaped = false;
8678
- else if (ch === "\\")
8679
- escaped = true;
8680
- else if (ch === '"')
8681
- inString = false;
8682
- continue;
8683
- }
8684
- if (ch === '"') {
8685
- inString = true;
8686
- out += ch;
8687
- continue;
8688
- }
8689
- if (ch === "/" && next === "/") {
8690
- while (i < input.length && input[i] !== `
8691
- `)
8692
- i++;
8693
- out += `
8694
- `;
8695
- continue;
8696
- }
8697
- if (ch === "/" && next === "*") {
8698
- i += 2;
8699
- while (i < input.length && !(input[i] === "*" && input[i + 1] === "/"))
8700
- i++;
8701
- i++;
8702
- out += " ";
8703
- continue;
8704
- }
8705
- out += ch;
8706
- }
8707
- let withoutTrailingCommas = "";
8708
- inString = false;
8709
- escaped = false;
8710
- for (let i = 0;i < out.length; i++) {
8711
- const ch = out[i];
8712
- if (inString) {
8713
- withoutTrailingCommas += ch;
8714
- if (escaped)
8715
- escaped = false;
8716
- else if (ch === "\\")
8717
- escaped = true;
8718
- else if (ch === '"')
8719
- inString = false;
8720
- continue;
8721
- }
8722
- if (ch === '"') {
8723
- inString = true;
8724
- withoutTrailingCommas += ch;
8725
- continue;
8726
- }
8727
- if (ch === ",") {
8728
- let j = i + 1;
8729
- while (j < out.length && /\s/.test(out[j]))
8730
- j++;
8731
- if (out[j] === "}" || out[j] === "]")
8732
- continue;
8733
- }
8734
- withoutTrailingCommas += ch;
8735
- }
8736
- return withoutTrailingCommas;
8737
- }
8738
- function sortJson(value) {
8739
- if (Array.isArray(value))
8740
- return value.map(sortJson);
8741
- if (value && typeof value === "object") {
8742
- const sorted = {};
8743
- for (const key of Object.keys(value).sort()) {
8744
- sorted[key] = sortJson(value[key]);
8745
- }
8746
- return sorted;
8747
- }
8748
- return value;
8749
- }
8750
- function normalizedJsoncSemantics(content) {
8751
- return JSON.stringify(sortJson(JSON.parse(stripJsoncForParse(content))));
8752
- }
8753
- function fileSemanticsMatch(a, b) {
8754
- try {
8755
- return normalizedJsoncSemantics(a) === normalizedJsoncSemantics(b);
8756
- } catch {
8757
- return a === b;
8758
- }
8759
- }
8760
- var CONFIG_LOCK_STALE_MS = 4000;
8761
- function acquireConfigMigrationLock(lockDir) {
8762
- for (let attempt = 0;attempt < 2; attempt++) {
8763
- try {
8764
- mkdirSync(lockDir, { recursive: false });
8765
- return () => {
8766
- try {
8767
- rmSync(lockDir, { recursive: true, force: true });
8768
- } catch {}
8769
- };
8770
- } catch (err) {
8771
- const code = err?.code;
8772
- if (code !== "EEXIST")
8773
- throw err;
8774
- try {
8775
- const ageMs = Date.now() - statSync(lockDir).mtimeMs;
8776
- if (ageMs > CONFIG_LOCK_STALE_MS) {
8777
- rmSync(lockDir, { recursive: true, force: true });
8778
- continue;
8779
- }
8780
- } catch {
8781
- continue;
8782
- }
8783
- return null;
8784
- }
8785
- }
8786
- return null;
8787
- }
8788
- function atomicCopyConfigFile(sourcePath, targetPath) {
8789
- mkdirSync(dirname(targetPath), { recursive: true });
8790
- const tmpPath = join(dirname(targetPath), `.${basename(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
8791
- let fd = null;
8792
- try {
8793
- fd = openSync(tmpPath, "wx", 384);
8794
- writeFileSync(fd, readFileSync(sourcePath));
8795
- closeSync(fd);
8796
- fd = null;
8797
- renameSync(tmpPath, targetPath);
8798
- } catch (err) {
8799
- if (fd !== null) {
8800
- try {
8801
- closeSync(fd);
8802
- } catch {}
8803
- }
8804
- try {
8805
- unlinkSync(tmpPath);
8806
- } catch {}
8807
- throw err;
8808
- }
8809
- }
8810
- function atomicWriteConfigFile(targetPath, content) {
8811
- mkdirSync(dirname(targetPath), { recursive: true });
8812
- const tmpPath = join(dirname(targetPath), `.${basename(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
8813
- let fd = null;
8814
- try {
8815
- fd = openSync(tmpPath, "wx", 384);
8816
- writeFileSync(fd, content);
8817
- closeSync(fd);
8818
- fd = null;
8819
- renameSync(tmpPath, targetPath);
8820
- } catch (err) {
8821
- if (fd !== null) {
8822
- try {
8823
- closeSync(fd);
8824
- } catch {}
8825
- }
8826
- try {
8827
- unlinkSync(tmpPath);
8828
- } catch {}
8829
- throw err;
8830
- }
8831
- }
8832
- function movedMarkerContent(targetPath, originalName, originalContent) {
8833
- const header = [
8834
- "// Magic Context configuration moved.",
8835
- "//",
8836
- "// Magic Context now reads its configuration from one shared CortexKit",
8837
- "// location instead of a per-agent path. The settings that were in this",
8838
- "// file have been moved to:",
8839
- "//",
8840
- `// ${targetPath}`,
8841
- "//",
8842
- "// Edit that file to change Magic Context settings. This location is no",
8843
- "// longer read by Magic Context.",
8844
- "//",
8845
- `// To undo, rename this file back to "${originalName}" (and remove the`,
8846
- "// CortexKit copy above if you want this location to take precedence).",
8847
- "//",
8848
- "// Your original settings are preserved below for reference.",
8849
- "",
8850
- ""
8851
- ].join(`
8852
- `);
8853
- return `${header}${originalContent}`;
8854
- }
8855
- function markLegacySourcesMovedAside(sources, targetPath, logger) {
8856
- const warnings = [];
8857
- const info = logger?.info ?? logger?.log;
8858
- for (const source of sources) {
8859
- const markerPath = `${source.path}${MOVED_MARKER_SUFFIX}`;
8860
- try {
8861
- const original = readFileSync(source.path, "utf-8");
8862
- atomicWriteConfigFile(markerPath, movedMarkerContent(targetPath, basename(source.path), original));
8863
- unlinkSync(source.path);
8864
- info?.(`Moved legacy Magic Context config ${source.path} aside to ${markerPath}; now reading ${targetPath}`);
8865
- } catch (err) {
8866
- const msg = err instanceof Error ? err.message : String(err);
8867
- 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}.`);
8868
- logger?.warn?.(`Could not move legacy Magic Context config ${source.path} aside (${msg}); reading ${targetPath}`);
8869
- }
8870
- }
8871
- return warnings;
8872
- }
8873
- function visibleConfigMigrationWarning(scope, targetPath, paths, reason) {
8874
- const uniquePaths = [...new Set([targetPath, ...paths])];
8875
- 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(" ; ")}`;
8876
- }
8877
- function migrateConfigFile(opts) {
8878
- const warnings = [];
8879
- const existingSources = opts.legacySources.filter((source) => existsSync(source.path));
8880
- const info = opts.logger?.info ?? opts.logger?.log;
8881
- if (existingSources.length === 0) {
8882
- return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
8883
- }
8884
- mkdirSync(dirname(opts.targetPath), { recursive: true });
8885
- const release = acquireConfigMigrationLock(`${opts.targetPath}.lock`);
8886
- if (!release) {
8887
- warnings.push(`Config migration for ${opts.scope} skipped this run (another instance is migrating); will retry on next start.`);
8888
- return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
8889
- }
8890
- try {
8891
- const sources = existingSources.map((source) => ({
8892
- ...source,
8893
- content: readFileSync(source.path, "utf-8")
8894
- }));
8895
- if (existsSync(opts.targetPath)) {
8896
- const targetContent = readFileSync(opts.targetPath, "utf-8");
8897
- const differing2 = sources.filter((source) => !fileSemanticsMatch(source.content, targetContent));
8898
- if (differing2.length > 0) {
8899
- const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, differing2.map((source) => source.path), "the CortexKit target already exists with different settings");
8900
- warnings.push(message);
8901
- opts.logger?.warn?.(message);
8902
- return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
8903
- }
8904
- info?.(`Magic Context ${opts.scope} config already present at ${opts.targetPath}; legacy copies match`);
8905
- warnings.push(...markLegacySourcesMovedAside(sources, opts.targetPath, opts.logger));
8906
- return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
8907
- }
8908
- const first = sources[0];
8909
- const differing = sources.filter((source) => !fileSemanticsMatch(source.content, first.content));
8910
- if (differing.length > 0) {
8911
- const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, sources.map((source) => source.path), "multiple legacy sources have different settings");
8912
- warnings.push(message);
8913
- opts.logger?.warn?.(message);
8914
- return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
8915
- }
8916
- atomicCopyConfigFile(first.path, opts.targetPath);
8917
- info?.(`Migrated Magic Context ${opts.scope} config from ${first.path} to ${opts.targetPath}`);
8918
- warnings.push(...markLegacySourcesMovedAside(sources, opts.targetPath, opts.logger));
8919
- return {
8920
- migrated: true,
8921
- conflict: false,
8922
- sourcePath: first.path,
8923
- targetPath: opts.targetPath,
8924
- warnings
8925
- };
8926
- } catch (err) {
8927
- const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, existingSources.map((source) => source.path), `migration failed (${err instanceof Error ? err.message : String(err)})`);
8928
- warnings.push(message);
8929
- opts.logger?.warn?.(message);
8930
- return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
8931
- } finally {
8932
- release();
8933
- }
8934
- }
8935
- function migrateMagicContextConfigLocations(directory, logger) {
8936
- const warnings = [];
8937
- const legacy = resolveLegacyConfigSources(directory);
8938
- try {
8939
- warnings.push(...migrateConfigFile({
8940
- scope: "user",
8941
- targetPath: resolveCortexKitUserConfigPath(),
8942
- legacySources: legacy.user,
8943
- logger
8944
- }).warnings);
8945
- warnings.push(...migrateConfigFile({
8946
- scope: "project",
8947
- targetPath: resolveCortexKitProjectConfigPath(directory),
8948
- legacySources: legacy.project,
8949
- logger
8950
- }).warnings);
8951
- } catch (err) {
8952
- const msg = err instanceof Error ? err.message : String(err);
8953
- logger?.warn?.(`Magic Context config-location migration error (continuing): ${msg}`);
8954
- warnings.push(`Magic Context config-location migration error: ${msg}`);
8955
- }
8956
- return warnings;
8957
- }
8958
-
8959
8593
  // src/config/migrate-dreamer-v2.ts
8960
8594
  var OLD_VERIFY_TASK = "verify";
8961
8595
  var OLD_CURATE_TASKS = ["consolidate", "archive-stale", "improve"];
@@ -9267,6 +8901,7 @@ function migrateLegacyExperimental(rawConfig, warnings) {
9267
8901
  // src/config/project-security.ts
9268
8902
  var HIDDEN_AGENT_KEYS = ["historian", "dreamer", "sidekick"];
9269
8903
  var HISTORIAN_USER_ONLY_FIELDS = ["model", "fallback_models"];
8904
+ var PROMPT_SURFACE_USER_ONLY_FIELDS = ["guidance_override_path", "tool_descriptions"];
9270
8905
  var AGENT_ESCALATION_FIELDS = ["prompt", "permission", "tools", "system_prompt"];
9271
8906
  var EMBEDDING_DESTINATION_FIELDS = ["endpoint", "provider", "fallback_provider"];
9272
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.";
@@ -9402,6 +9037,19 @@ function stripUnsafeProjectConfigFields(projectRaw) {
9402
9037
  delete storage.enforce_private_permissions;
9403
9038
  warnings.push("Ignoring storage.enforce_private_permissions from project config (security: only user-level config may opt into externally managed shared storage permissions).");
9404
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
+ }
9405
9053
  const pi = projectRaw.pi;
9406
9054
  if (isPlainObject(pi) && "subagent_extensions" in pi) {
9407
9055
  delete pi.subagent_extensions;
@@ -9649,13 +9297,13 @@ function resolveTransformMode(args) {
9649
9297
  }
9650
9298
 
9651
9299
  // src/config/variable.ts
9652
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
9653
- import { homedir as homedir2 } from "node:os";
9654
- 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";
9655
9303
  var ENV_PATTERN = /\{env:([^}]+)\}/g;
9656
9304
  var FILE_PATTERN = /\{file:([^}]+)\}/g;
9657
9305
  function sensitiveFilePathReason(resolvedPath) {
9658
- const home = homedir2();
9306
+ const home = homedir();
9659
9307
  const sensitiveDirs = [
9660
9308
  { dir: resolve(home, ".ssh"), label: "SSH keys" },
9661
9309
  { dir: resolve(home, ".aws"), label: "AWS credentials" },
@@ -9700,7 +9348,7 @@ function substituteConfigVariables(input) {
9700
9348
  if (fileMatches.length === 0) {
9701
9349
  return { text, warnings };
9702
9350
  }
9703
- const configDir = input.configPath ? dirname2(input.configPath) : process.cwd();
9351
+ const configDir = input.configPath ? dirname(input.configPath) : process.cwd();
9704
9352
  let output = "";
9705
9353
  let cursor = 0;
9706
9354
  for (const match of fileMatches) {
@@ -9718,21 +9366,21 @@ function substituteConfigVariables(input) {
9718
9366
  }
9719
9367
  let filePath = rawPath.trim();
9720
9368
  if (filePath.startsWith("~/")) {
9721
- filePath = resolve(homedir2(), filePath.slice(2));
9722
- } else if (!isAbsolute2(filePath)) {
9369
+ filePath = resolve(homedir(), filePath.slice(2));
9370
+ } else if (!isAbsolute(filePath)) {
9723
9371
  filePath = resolve(configDir, filePath);
9724
9372
  }
9725
9373
  const sensitiveReason = sensitiveFilePathReason(filePath);
9726
9374
  if (sensitiveReason) {
9727
9375
  warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
9728
9376
  }
9729
- if (!existsSync2(filePath)) {
9377
+ if (!existsSync(filePath)) {
9730
9378
  warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
9731
9379
  continue;
9732
9380
  }
9733
9381
  let contents;
9734
9382
  try {
9735
- contents = readFileSync2(filePath, "utf-8").trim();
9383
+ contents = readFileSync(filePath, "utf-8").trim();
9736
9384
  } catch (error) {
9737
9385
  const message = error instanceof Error ? error.message : String(error);
9738
9386
  warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
@@ -9752,15 +9400,15 @@ function getProjectConfigBasePath(directory) {
9752
9400
  return cortexKitProjectConfigBasePath(directory);
9753
9401
  }
9754
9402
  function resolveLegacyReadFallback(sources) {
9755
- return { source: sources.find((s) => existsSync3(s.path)) ?? null };
9403
+ return { source: sources.find((s) => existsSync2(s.path)) ?? null };
9756
9404
  }
9757
9405
  function loadConfigFileDetailed(configPath, source) {
9758
- if (!existsSync3(configPath)) {
9406
+ if (!existsSync2(configPath)) {
9759
9407
  return null;
9760
9408
  }
9761
9409
  let rawText;
9762
9410
  try {
9763
- rawText = readFileSync3(configPath, "utf-8");
9411
+ rawText = readFileSync2(configPath, "utf-8");
9764
9412
  } catch (error) {
9765
9413
  return {
9766
9414
  config: {},
@@ -9919,9 +9567,6 @@ function parsePluginConfig(rawConfig, recoveredTopLevelKeys = []) {
9919
9567
  configWarnings: [...preMigrationWarnings, ...warnings]
9920
9568
  };
9921
9569
  }
9922
- function loadPluginConfig(directory) {
9923
- return loadPluginConfigDetailed(directory).config;
9924
- }
9925
9570
  function hasUserTierSubcConfig(config) {
9926
9571
  const subc = config?.subc;
9927
9572
  if (typeof subc !== "object" || subc === null || Array.isArray(subc))
@@ -9977,8 +9622,8 @@ function loadPluginConfigDetailed(directory) {
9977
9622
  const harnessLegacy = resolveLegacyConfigSourcesForHarness(directory, "opencode");
9978
9623
  const userLegacyFallback = userDetected.format === "none" ? resolveLegacyReadFallback(harnessLegacy.user) : { source: null };
9979
9624
  const projectLegacyFallback = projectDetected.format === "none" ? resolveLegacyReadFallback(harnessLegacy.project) : { source: null };
9980
- const legacyUserUnmigrated = userDetected.format === "none" && !userLegacyFallback.source && legacySources.user.some((source) => existsSync3(source.path));
9981
- 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));
9982
9627
  const userLoaded = userDetected.format !== "none" ? loadConfigFileDetailed(userDetected.path, "user") : userLegacyFallback.source ? loadConfigFileDetailed(userLegacyFallback.source.path, "user") : null;
9983
9628
  const projectLoaded = projectDetected.format !== "none" ? loadConfigFileDetailed(projectDetected.path, "project") : projectLegacyFallback.source ? loadConfigFileDetailed(projectLegacyFallback.source.path, "project") : null;
9984
9629
  const allWarnings = [];
@@ -10050,6 +9695,7 @@ function loadPluginConfigDetailed(directory) {
10050
9695
  };
10051
9696
  return {
10052
9697
  config,
9698
+ registrationPromptSurface: trustedBaseConfig.prompt_surface,
10053
9699
  loadOutcome: combinedOutcome({ sources, substitutionFailures, recoveredTopLevelKeys }),
10054
9700
  sources,
10055
9701
  substitutionFailures,
@@ -10098,10 +9744,10 @@ function getMagicContextBuiltinCommands(compactionEnabled = true) {
10098
9744
  }
10099
9745
 
10100
9746
  // src/features/magic-context/dreamer/open-opencode-db.ts
10101
- import { existsSync as existsSync4 } from "node:fs";
9747
+ import { existsSync as existsSync3 } from "node:fs";
10102
9748
  function openOpenCodeDb() {
10103
9749
  const dbPath = getOpenCodeDbPath();
10104
- if (!existsSync4(dbPath)) {
9750
+ if (!existsSync3(dbPath)) {
10105
9751
  log(`[dreamer] OpenCode DB not found at ${dbPath} — skipping OpenCode history scan`);
10106
9752
  return null;
10107
9753
  }
@@ -10588,7 +10234,7 @@ function getLastHookInitFailure() {
10588
10234
 
10589
10235
  // src/features/magic-context/session-project-backfill.ts
10590
10236
  import { randomUUID } from "node:crypto";
10591
- import { existsSync as existsSync5 } from "node:fs";
10237
+ import { existsSync as existsSync4 } from "node:fs";
10592
10238
  var LEASE_TTL_MS = 10 * 60 * 1000;
10593
10239
  var SESSION_PAGE_SIZE = 100;
10594
10240
  var SESSION_QUERY_CHUNK_SIZE = 250;
@@ -10784,7 +10430,7 @@ async function runSessionProjectBackfill(db, source, options = {}) {
10784
10430
  if (!session.directory) {
10785
10431
  result.skippedEmptyDirectories += 1;
10786
10432
  } else {
10787
- const stillExists = existenceCache.get(session.directory) ?? existsSync5(session.directory);
10433
+ const stillExists = existenceCache.get(session.directory) ?? existsSync4(session.directory);
10788
10434
  existenceCache.set(session.directory, stillExists);
10789
10435
  if (!stillExists) {
10790
10436
  result.skippedDeadDirectories += 1;
@@ -11209,45 +10855,45 @@ async function runDeferredV22Backfill(db, options = {}) {
11209
10855
  }
11210
10856
 
11211
10857
  // src/hooks/auto-update-checker/index.ts
11212
- import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as readFileSync5, renameSync as renameSync3, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "node:fs";
11213
- 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";
11214
10860
 
11215
10861
  // src/hooks/auto-update-checker/checker.ts
11216
10862
  var import_comment_json = __toESM(require_src2(), 1);
11217
10863
  import { spawn } from "node:child_process";
11218
10864
  import {
11219
10865
  accessSync,
11220
- existsSync as existsSync6,
10866
+ existsSync as existsSync5,
11221
10867
  constants as fsConstants,
11222
- readFileSync as readFileSync4,
11223
- renameSync as renameSync2,
11224
- statSync as statSync2,
11225
- writeFileSync as writeFileSync2
10868
+ readFileSync as readFileSync3,
10869
+ renameSync,
10870
+ statSync,
10871
+ writeFileSync
11226
10872
  } from "node:fs";
11227
- 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";
11228
10874
  import { fileURLToPath } from "node:url";
11229
10875
 
11230
10876
  // src/hooks/auto-update-checker/constants.ts
11231
- import { homedir as homedir3, platform } from "node:os";
11232
- import { join as join2 } from "node:path";
10877
+ import { homedir as homedir2, platform } from "node:os";
10878
+ import { join } from "node:path";
11233
10879
  var PACKAGE_NAME = "@cortexkit/opencode-magic-context";
11234
10880
  var NPM_REGISTRY_URL = "https://registry.npmjs.org";
11235
10881
  var NPM_FETCH_TIMEOUT = 1e4;
11236
10882
  function getOpenCodeCacheRoot() {
11237
10883
  if (platform() === "win32") {
11238
- return join2(process.env.LOCALAPPDATA ?? homedir3(), "opencode");
10884
+ return join(process.env.LOCALAPPDATA ?? homedir2(), "opencode");
11239
10885
  }
11240
- return join2(homedir3(), ".cache", "opencode");
10886
+ return join(homedir2(), ".cache", "opencode");
11241
10887
  }
11242
10888
  function getOpenCodeConfigRoot() {
11243
10889
  if (platform() === "win32") {
11244
- return join2(process.env.APPDATA ?? join2(homedir3(), "AppData", "Roaming"), "opencode");
10890
+ return join(process.env.APPDATA ?? join(homedir2(), "AppData", "Roaming"), "opencode");
11245
10891
  }
11246
- return join2(process.env.XDG_CONFIG_HOME ?? join2(homedir3(), ".config"), "opencode");
10892
+ return join(process.env.XDG_CONFIG_HOME ?? join(homedir2(), ".config"), "opencode");
11247
10893
  }
11248
- var CACHE_DIR = join2(getOpenCodeCacheRoot(), "packages");
11249
- var USER_OPENCODE_CONFIG = join2(getOpenCodeConfigRoot(), "opencode.json");
11250
- 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");
11251
10897
 
11252
10898
  // src/hooks/auto-update-checker/types.ts
11253
10899
  var NpmPackageEnvelopeSchema = exports_external.object({
@@ -11308,17 +10954,17 @@ function extractChannel(version) {
11308
10954
  }
11309
10955
  function getSurfaceConfigPaths(directory, surface) {
11310
10956
  const name = surface === "server" ? "opencode" : "tui";
11311
- const globalDir = dirname3(USER_OPENCODE_CONFIG);
10957
+ const globalDir = dirname2(USER_OPENCODE_CONFIG);
11312
10958
  const dirs = [
11313
10959
  globalDir,
11314
10960
  directory,
11315
- join3(directory, ".opencode"),
10961
+ join2(directory, ".opencode"),
11316
10962
  process.env.OPENCODE_CONFIG_DIR
11317
10963
  ].filter((value) => Boolean(value));
11318
10964
  const paths = [];
11319
10965
  for (const dir of dirs) {
11320
10966
  for (const extension of ["json", "jsonc"]) {
11321
- const path2 = join3(dir, `${name}.${extension}`);
10967
+ const path2 = join2(dir, `${name}.${extension}`);
11322
10968
  if (!paths.includes(path2))
11323
10969
  paths.push(path2);
11324
10970
  }
@@ -11329,9 +10975,9 @@ function getWinningConfig(directory, surface) {
11329
10975
  let winner = null;
11330
10976
  for (const path2 of getSurfaceConfigPaths(directory, surface)) {
11331
10977
  try {
11332
- if (!existsSync6(path2))
10978
+ if (!existsSync5(path2))
11333
10979
  continue;
11334
- const parsed = parseJsonConfig(readFileSync4(path2, "utf-8"));
10980
+ const parsed = parseJsonConfig(readFileSync3(path2, "utf-8"));
11335
10981
  const entries = getPluginEntries(parsed);
11336
10982
  if (entries.some((entry) => entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`))) {
11337
10983
  if (winner) {
@@ -11354,24 +11000,24 @@ function resolvePathPluginSpec(spec, configPath) {
11354
11000
  return spec.replace(/^file:\/\//, "");
11355
11001
  }
11356
11002
  }
11357
- if (isAbsolute3(spec) || /^[A-Za-z]:[\\/]/.test(spec))
11003
+ if (isAbsolute2(spec) || /^[A-Za-z]:[\\/]/.test(spec))
11358
11004
  return spec;
11359
- return resolve2(dirname3(configPath), spec);
11005
+ return resolve2(dirname2(configPath), spec);
11360
11006
  }
11361
11007
  function findPackageJsonUp(startPath) {
11362
11008
  try {
11363
- const stat = statSync2(startPath);
11364
- let dir = stat.isDirectory() ? startPath : dirname3(startPath);
11009
+ const stat = statSync(startPath);
11010
+ let dir = stat.isDirectory() ? startPath : dirname2(startPath);
11365
11011
  for (let i = 0;i < 10; i++) {
11366
- const pkgPath = join3(dir, "package.json");
11367
- if (existsSync6(pkgPath)) {
11012
+ const pkgPath = join2(dir, "package.json");
11013
+ if (existsSync5(pkgPath)) {
11368
11014
  try {
11369
- const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync4(pkgPath, "utf-8")));
11015
+ const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync3(pkgPath, "utf-8")));
11370
11016
  if (pkg.success && pkg.data.name === PACKAGE_NAME)
11371
11017
  return pkgPath;
11372
11018
  } catch {}
11373
11019
  }
11374
- const parent = dirname3(dir);
11020
+ const parent = dirname2(dir);
11375
11021
  if (parent === dir)
11376
11022
  break;
11377
11023
  dir = parent;
@@ -11382,19 +11028,19 @@ function findPackageJsonUp(startPath) {
11382
11028
  function getLocalDevPath(directory) {
11383
11029
  for (const configPath of getConfigPaths(directory)) {
11384
11030
  try {
11385
- if (!existsSync6(configPath))
11031
+ if (!existsSync5(configPath))
11386
11032
  continue;
11387
- const rawConfig = parseJsonConfig(readFileSync4(configPath, "utf-8"));
11033
+ const rawConfig = parseJsonConfig(readFileSync3(configPath, "utf-8"));
11388
11034
  const plugins = getPluginEntries(rawConfig);
11389
11035
  for (const entry of plugins) {
11390
11036
  if (entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`))
11391
11037
  continue;
11392
- if (entry.startsWith("file://") || entry.startsWith(".") || isAbsolute3(entry)) {
11038
+ if (entry.startsWith("file://") || entry.startsWith(".") || isAbsolute2(entry)) {
11393
11039
  const localPath = resolvePathPluginSpec(entry, configPath);
11394
11040
  const pkgPath = findPackageJsonUp(localPath);
11395
11041
  if (!pkgPath)
11396
11042
  continue;
11397
- const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync4(pkgPath, "utf-8")));
11043
+ const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync3(pkgPath, "utf-8")));
11398
11044
  if (pkg.success && pkg.data.name === PACKAGE_NAME)
11399
11045
  return localPath;
11400
11046
  }
@@ -11411,7 +11057,7 @@ function getLocalDevVersion(directory) {
11411
11057
  const pkgPath = findPackageJsonUp(localPath);
11412
11058
  if (!pkgPath)
11413
11059
  return null;
11414
- const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync4(pkgPath, "utf-8")));
11060
+ const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync3(pkgPath, "utf-8")));
11415
11061
  return pkg.success ? pkg.data.version ?? null : null;
11416
11062
  } catch {
11417
11063
  return null;
@@ -11419,7 +11065,7 @@ function getLocalDevVersion(directory) {
11419
11065
  }
11420
11066
  function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
11421
11067
  try {
11422
- return findPackageJsonUp(dirname3(fileURLToPath(currentModuleUrl)));
11068
+ return findPackageJsonUp(dirname2(fileURLToPath(currentModuleUrl)));
11423
11069
  } catch (err) {
11424
11070
  warn(`[auto-update-checker] Failed to resolve runtime package path: ${String(err)}`);
11425
11071
  return null;
@@ -11460,7 +11106,7 @@ function preflightConfigUpdates(paths, version) {
11460
11106
  for (const path2 of paths) {
11461
11107
  try {
11462
11108
  accessSync(path2, fsConstants.W_OK);
11463
- const original = readFileSync4(path2, "utf-8");
11109
+ const original = readFileSync3(path2, "utf-8");
11464
11110
  const updated = configUpdateContent(original, version);
11465
11111
  if (!updated)
11466
11112
  return null;
@@ -11474,8 +11120,8 @@ function preflightConfigUpdates(paths, version) {
11474
11120
  }
11475
11121
  function writeConfig(path2, content) {
11476
11122
  const tmp = `${path2}.mc-tmp-${process.pid}`;
11477
- writeFileSync2(tmp, content, "utf-8");
11478
- renameSync2(tmp, path2);
11123
+ writeFileSync(tmp, content, "utf-8");
11124
+ renameSync(tmp, path2);
11479
11125
  }
11480
11126
  function restoreConfigs(snapshots) {
11481
11127
  for (const snapshot of snapshots) {
@@ -11489,7 +11135,7 @@ function restoreConfigs(snapshots) {
11489
11135
  function configsHaveSpec(paths, spec) {
11490
11136
  return paths.every((path2) => {
11491
11137
  try {
11492
- const parsed = parseJsonConfig(readFileSync4(path2, "utf-8"));
11138
+ const parsed = parseJsonConfig(readFileSync3(path2, "utf-8"));
11493
11139
  return getPluginEntries(parsed).includes(spec);
11494
11140
  } catch {
11495
11141
  return false;
@@ -11545,8 +11191,8 @@ async function preparePluginUpdate(directory, _pluginInfo, version, options = {}
11545
11191
  return null;
11546
11192
  const spec = `${PACKAGE_NAME}@${version}`;
11547
11193
  const globalServerPaths = [USER_OPENCODE_CONFIG, USER_OPENCODE_CONFIG_JSONC];
11548
- const globalTuiPaths = globalServerPaths.map((path2) => join3(dirname3(path2), "tui.json"));
11549
- 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")));
11550
11196
  const isGlobal = globalServerPaths.includes(paths[0]) && globalTuiPaths.includes(paths[1]);
11551
11197
  if (isGlobal) {
11552
11198
  const hostResult = await runHostPluginInstall(spec, options.signal, options.timeoutMs);
@@ -11579,9 +11225,9 @@ function getCachedVersion(_spec) {
11579
11225
  const candidates = [getCurrentRuntimePackageJsonPath()].filter(isString);
11580
11226
  for (const packageJsonPath of candidates) {
11581
11227
  try {
11582
- if (!existsSync6(packageJsonPath))
11228
+ if (!existsSync5(packageJsonPath))
11583
11229
  continue;
11584
- const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync4(packageJsonPath, "utf-8")));
11230
+ const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync3(packageJsonPath, "utf-8")));
11585
11231
  if (pkg.success && pkg.data.version) {
11586
11232
  if (!_spec)
11587
11233
  cachedPackageVersion = pkg.data.version;
@@ -11679,20 +11325,20 @@ function claimCheckSlot(storageDir, intervalMs) {
11679
11325
  if (!storageDir)
11680
11326
  return true;
11681
11327
  try {
11682
- const file = join4(storageDir, TIMESTAMP_FILENAME);
11683
- if (existsSync7(file)) {
11328
+ const file = join3(storageDir, TIMESTAMP_FILENAME);
11329
+ if (existsSync6(file)) {
11684
11330
  try {
11685
- const raw = JSON.parse(readFileSync5(file, "utf-8"));
11331
+ const raw = JSON.parse(readFileSync4(file, "utf-8"));
11686
11332
  const last = typeof raw.lastCheckedMs === "number" ? raw.lastCheckedMs : 0;
11687
11333
  if (Number.isFinite(last) && Date.now() - last < intervalMs) {
11688
11334
  return false;
11689
11335
  }
11690
11336
  } catch {}
11691
11337
  }
11692
- mkdirSync2(dirname4(file), { recursive: true });
11338
+ mkdirSync(dirname3(file), { recursive: true });
11693
11339
  const tmp = `${file}.tmp.${process.pid}`;
11694
- writeFileSync3(tmp, JSON.stringify({ lastCheckedMs: Date.now() }), "utf-8");
11695
- renameSync3(tmp, file);
11340
+ writeFileSync2(tmp, JSON.stringify({ lastCheckedMs: Date.now() }), "utf-8");
11341
+ renameSync2(tmp, file);
11696
11342
  return true;
11697
11343
  } catch (err) {
11698
11344
  warn2(`[auto-update-checker] Could not coordinate via timestamp file: ${String(err)}`);
@@ -11700,39 +11346,39 @@ function claimCheckSlot(storageDir, intervalMs) {
11700
11346
  }
11701
11347
  }
11702
11348
  function pendingMarkerPath(storageDir) {
11703
- return join4(storageDir ?? getOpenCodeStorageDir(), PENDING_UPDATE_FILENAME);
11349
+ return join3(storageDir ?? getOpenCodeStorageDir(), PENDING_UPDATE_FILENAME);
11704
11350
  }
11705
11351
  function writePendingUpdateMarker(storageDir, update, version) {
11706
11352
  try {
11707
- const dir = storageDir ?? dirname4(pendingMarkerPath(storageDir));
11708
- mkdirSync2(dir, { recursive: true });
11353
+ const dir = storageDir ?? dirname3(pendingMarkerPath(storageDir));
11354
+ mkdirSync(dir, { recursive: true });
11709
11355
  const path2 = pendingMarkerPath(storageDir);
11710
11356
  const temp = `${path2}.tmp.${process.pid}`;
11711
- 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)}
11712
11358
  `, "utf-8");
11713
- renameSync3(temp, path2);
11359
+ renameSync2(temp, path2);
11714
11360
  } catch (err) {
11715
11361
  warn2(`[auto-update-checker] Could not write pending update marker: ${String(err)}`);
11716
11362
  }
11717
11363
  }
11718
11364
  function consumePendingUpdateMarker(storageDir, loadedVersion) {
11719
11365
  const path2 = pendingMarkerPath(storageDir);
11720
- if (!existsSync7(path2))
11366
+ if (!existsSync6(path2))
11721
11367
  return;
11722
11368
  try {
11723
- const marker = JSON.parse(readFileSync5(path2, "utf-8"));
11369
+ const marker = JSON.parse(readFileSync4(path2, "utf-8"));
11724
11370
  const age = Date.now() - (marker.writtenAt ?? 0);
11725
11371
  const olderThanLoaded = typeof marker.version === "string" && typeof loadedVersion === "string" && (compareSemverCore(marker.version, loadedVersion) ?? 0) < 0;
11726
11372
  if (marker.version === loadedVersion && marker.spec === `${PACKAGE_NAME}@${loadedVersion}` && Array.isArray(marker.configPaths) && marker.configPaths.length === 2) {
11727
- rmSync2(path2, { force: true });
11373
+ rmSync(path2, { force: true });
11728
11374
  log(`[auto-update-checker] Pending update applied: ${marker.spec}`);
11729
11375
  } else if (age > PENDING_UPDATE_MAX_AGE_MS || olderThanLoaded) {
11730
- rmSync2(path2, { force: true });
11376
+ rmSync(path2, { force: true });
11731
11377
  warn2("[auto-update-checker] Discarded stale or mismatched pending update marker");
11732
11378
  }
11733
11379
  } catch (err) {
11734
11380
  try {
11735
- rmSync2(path2, { force: true });
11381
+ rmSync(path2, { force: true });
11736
11382
  } catch {}
11737
11383
  warn2(`[auto-update-checker] Discarded corrupt pending update marker: ${String(err)}`);
11738
11384
  }
@@ -11833,7 +11479,7 @@ function createLiveSessionState() {
11833
11479
 
11834
11480
  // src/hooks/magic-context/module-transport.ts
11835
11481
  import { realpathSync as realpathSync2 } from "node:fs";
11836
- import { join as join5 } from "node:path";
11482
+ import { join as join4 } from "node:path";
11837
11483
  var DEFAULT_MODULE_ID = "magic-context";
11838
11484
  var CONNECT_BACKOFF_INITIAL_MS = 1000;
11839
11485
  var CONNECT_BACKOFF_MAX_MS = 30000;
@@ -11843,7 +11489,7 @@ var SERIAL_LANE_MAX_WAITERS = 16;
11843
11489
  var SERIAL_LANE_MIN_REMAINING_MS = 25;
11844
11490
  var CANONICAL_ROOT_CACHE_MAX_ENTRIES = 256;
11845
11491
  function getDefaultConnectionFile() {
11846
- return join5(getDataDir(), "cortexkit", "run", "subc-connection.json");
11492
+ return join4(getDataDir(), "cortexkit", "run", "subc-connection.json");
11847
11493
  }
11848
11494
  function errorChainSome(error, predicate) {
11849
11495
  let current = error;
@@ -12111,6 +11757,14 @@ class SubcModuleTransport {
12111
11757
  throw new Error("mirror.pull omitted page");
12112
11758
  return { page: response.page };
12113
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
+ }
12114
11768
  closeSession(sessionId) {
12115
11769
  const client = this.client;
12116
11770
  const prefix = `${sessionId}\x00`;
@@ -12230,7 +11884,7 @@ class SubcModuleTransport {
12230
11884
  }
12231
11885
 
12232
11886
  // src/plugin/dream-timer.ts
12233
- import { statSync as statSync4 } from "node:fs";
11887
+ import { statSync as statSync3 } from "node:fs";
12234
11888
 
12235
11889
  // src/features/magic-context/dreamer/storage-dream-state.ts
12236
11890
  var getDreamStateStatements = new WeakMap;
@@ -12882,8 +12536,8 @@ function recordRetrospectiveWindowProcessed(db, projectPath, windowKey) {
12882
12536
  }
12883
12537
 
12884
12538
  // src/features/magic-context/dreamer/task-executor.ts
12885
- import { createHash as createHash6 } from "node:crypto";
12886
- import { existsSync as existsSync10 } from "node:fs";
12539
+ import { createHash as createHash8 } from "node:crypto";
12540
+ import { existsSync as existsSync9 } from "node:fs";
12887
12541
 
12888
12542
  // src/agents/dreamer.ts
12889
12543
  var DREAMER_AGENT = "dreamer";
@@ -12894,6 +12548,9 @@ var DREAMER_CLASSIFIER_AGENT = "dreamer-classifier";
12894
12548
  var DREAMER_DOCS_AGENT = "dreamer-docs";
12895
12549
  var DREAMER_REVIEWER_AGENT = "dreamer-reviewer";
12896
12550
 
12551
+ // src/features/magic-context/mural/compress-cues.ts
12552
+ import { createHash as createHash2 } from "node:crypto";
12553
+
12897
12554
  // src/features/magic-context/dreamer/manifest-parser.ts
12898
12555
  function extractCompleteManifestBody(text, rootName) {
12899
12556
  const escapedRoot = rootName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -12927,6 +12584,64 @@ function assertManifestCoversExactly(ids, expectedIds, rootName) {
12927
12584
  }
12928
12585
  }
12929
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
+
12930
12645
  // src/features/magic-context/mural/compress-cues-prompt.ts
12931
12646
  var CUE_BUDGET_HIGH = 90;
12932
12647
  var CUE_BUDGET_LOW = 50;
@@ -13198,7 +12913,7 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
13198
12913
  return text;
13199
12914
  }
13200
12915
  });
13201
- return applyCues(args, chunk, run.validated);
12916
+ return args.moduleRoute ? await applyCuesThroughModule(args, chunk, run.validated, signal) : applyCues(args, chunk, run.validated);
13202
12917
  } catch (error) {
13203
12918
  const desc = describeError(error);
13204
12919
  log(`[dreamer] compress-cues chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
@@ -13256,6 +12971,111 @@ function applyCues(args, chunk, manifestText) {
13256
12971
  });
13257
12972
  return { compressed, skipped };
13258
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
+ }
13259
13079
 
13260
13080
  // src/features/magic-context/user-memory/review-user-memories.ts
13261
13081
  async function reviewUserMemories(args) {
@@ -13465,7 +13285,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
13465
13285
  }
13466
13286
 
13467
13287
  // src/features/magic-context/dreamer/classify.ts
13468
- import { createHash as createHash2 } from "node:crypto";
13288
+ import { createHash as createHash3 } from "node:crypto";
13469
13289
 
13470
13290
  // src/plugin/rust-tool-backends.ts
13471
13291
  function toolCallIdFromContext(context) {
@@ -13500,7 +13320,7 @@ function isRustAuthorityDrainingError(error) {
13500
13320
  }
13501
13321
 
13502
13322
  // src/shared/redaction.ts
13503
- import { homedir as homedir4, userInfo } from "node:os";
13323
+ import { homedir as homedir3, userInfo } from "node:os";
13504
13324
  function escapeRegex(value) {
13505
13325
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
13506
13326
  }
@@ -13549,7 +13369,7 @@ var SECRET_QUALIFIERS = new Set([
13549
13369
  "azure"
13550
13370
  ]);
13551
13371
  function sanitizePathString(value) {
13552
- const home = homedir4();
13372
+ const home = homedir3();
13553
13373
  const username = userInfo().username;
13554
13374
  let sanitized = value;
13555
13375
  if (home) {
@@ -13751,64 +13571,6 @@ function parseClassifyManifest(text) {
13751
13571
  return out;
13752
13572
  }
13753
13573
 
13754
- // src/features/magic-context/dreamer/module-apply.ts
13755
- class DreamerModuleFailureError extends Error {
13756
- transient = true;
13757
- constructor(operation, cause) {
13758
- super(`Rust dreamer ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`);
13759
- this.name = "DreamerModuleFailureError";
13760
- this.cause = cause;
13761
- }
13762
- }
13763
- async function resolveDreamerModuleRoute(args) {
13764
- const transport = args.transformMode === "ts" ? undefined : args.moduleClient;
13765
- if (!transport?.authorityStatus)
13766
- return;
13767
- const contextStoreUuid = getContextStoreUuid(args.db);
13768
- if (!contextStoreUuid)
13769
- throw new Error("Rust dreamer requires a context store identity");
13770
- const result = await transport.authorityStatus({
13771
- context_store_uuid: contextStoreUuid,
13772
- project: args.projectIdentity,
13773
- projectRoot: args.projectRoot,
13774
- domain: "memories"
13775
- });
13776
- if (result.authority?.state !== "MODULE")
13777
- return;
13778
- const generation = result.authority.generation;
13779
- if (typeof generation !== "number")
13780
- throw new Error("Rust authority status omitted generation");
13781
- return {
13782
- moduleClient: transport,
13783
- moduleSessionId: args.projectIdentity,
13784
- moduleProjectRoot: args.projectRoot,
13785
- moduleContextStoreUuid: contextStoreUuid,
13786
- moduleAuthorityGeneration: generation,
13787
- moduleCommandId: args.commandId
13788
- };
13789
- }
13790
- function getModuleMemoryIdentities(db, projectIdentity, contextIds) {
13791
- if (contextIds.length === 0)
13792
- return new Map;
13793
- const placeholders = contextIds.map(() => "?").join(", ");
13794
- const rows = db.prepare(`SELECT identity.context_row_id, identity.module_row_id, live.normalized_hash
13795
- FROM mirror_identity identity
13796
- LEFT JOIN mirror_live_memory_rows live
13797
- ON live.module_project = identity.module_project
13798
- AND live.module_row_id = identity.module_row_id
13799
- WHERE identity.domain = 'memories' AND identity.module_project = ?
13800
- AND identity.context_row_id IN (${placeholders})`).all(projectIdentity, ...contextIds);
13801
- return new Map(rows.flatMap((row) => Number.isInteger(row.context_row_id) && Number.isInteger(row.module_row_id) && typeof row.normalized_hash === "string" ? [
13802
- [
13803
- row.context_row_id,
13804
- {
13805
- moduleId: row.module_row_id,
13806
- normalizedHash: row.normalized_hash
13807
- }
13808
- ]
13809
- ] : []));
13810
- }
13811
-
13812
13574
  // src/features/magic-context/dreamer/classify.ts
13813
13575
  var MIN_POOL_TO_CLASSIFY = 10;
13814
13576
  var FULL_POOL_CEILING = 100;
@@ -14045,7 +13807,7 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
14045
13807
  v: 1,
14046
13808
  session_id: args.moduleSessionId,
14047
13809
  task: "classify",
14048
- 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)}`,
14049
13811
  authority_generation: args.moduleAuthorityGeneration,
14050
13812
  payload: {
14051
13813
  prompt_body: prompt,
@@ -14577,21 +14339,21 @@ function isSecretDeniedPath(repoRelativePath) {
14577
14339
  const segments = normalized.split("/");
14578
14340
  if (segments.includes(".git") || segments.includes("secrets"))
14579
14341
  return true;
14580
- const basename2 = segments.at(-1) ?? "";
14581
- if (basename2 === ".npmrc" || basename2.startsWith(".env"))
14342
+ const basename = segments.at(-1) ?? "";
14343
+ if (basename === ".npmrc" || basename.startsWith(".env"))
14582
14344
  return true;
14583
- if (basename2 === ".pgpass" || basename2 === ".netrc")
14345
+ if (basename === ".pgpass" || basename === ".netrc")
14584
14346
  return true;
14585
- if (SECRET_KEY_EXTENSIONS.some((extension) => basename2.endsWith(extension)))
14347
+ if (SECRET_KEY_EXTENSIONS.some((extension) => basename.endsWith(extension)))
14586
14348
  return true;
14587
- 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_")) {
14588
14350
  return true;
14589
14351
  }
14590
- if (segments.includes(".aws") && basename2 === "credentials")
14352
+ if (segments.includes(".aws") && basename === "credentials")
14591
14353
  return true;
14592
- if (basename2.endsWith(".json")) {
14593
- const serviceAccountJson = basename2.includes("service-account") || basename2.includes("service_account");
14594
- 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"));
14595
14357
  if (serviceAccountJson || gcloudCredentialJson)
14596
14358
  return true;
14597
14359
  }
@@ -14741,7 +14503,7 @@ function throwIfAborted2(signal) {
14741
14503
  }
14742
14504
 
14743
14505
  // src/features/magic-context/smart-notes/compiler.ts
14744
- import { createHash as createHash3 } from "node:crypto";
14506
+ import { createHash as createHash4 } from "node:crypto";
14745
14507
 
14746
14508
  // src/features/magic-context/smart-notes/sandbox-runner.ts
14747
14509
  var asyncModulePromise = null;
@@ -15135,7 +14897,7 @@ function manifestAdvisoryWarnings(code, manifest) {
15135
14897
  return warnings;
15136
14898
  }
15137
14899
  function hashCheck(surfaceCondition, compiledCheck, manifest, checkCron) {
15138
- 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");
15139
14901
  }
15140
14902
  function extractJsonObject(output) {
15141
14903
  const fenced = output.match(/```(?:json)?\s*([\s\S]*?)```/i);
@@ -15833,8 +15595,8 @@ Output exactly JSON: {"met": false}`;
15833
15595
  }
15834
15596
 
15835
15597
  // src/features/magic-context/dreamer/maintain-docs-protected-enforcement.ts
15836
- import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "node:fs";
15837
- 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";
15838
15600
 
15839
15601
  // src/features/magic-context/dreamer/protected-regions.ts
15840
15602
  var PROTECTED_START_TOKEN = "mc:protected START";
@@ -15935,10 +15697,10 @@ var MAINTAIN_DOCS_SNAPSHOT_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
15935
15697
  function snapshotMaintainDocsFiles(docsDir) {
15936
15698
  const snapshot = new Map;
15937
15699
  for (const name of MAINTAIN_DOCS_SNAPSHOT_FILES) {
15938
- const path3 = join6(docsDir, name);
15700
+ const path3 = join5(docsDir, name);
15939
15701
  try {
15940
- if (existsSync8(path3)) {
15941
- snapshot.set(name, readFileSync6(path3, "utf8"));
15702
+ if (existsSync7(path3)) {
15703
+ snapshot.set(name, readFileSync5(path3, "utf8"));
15942
15704
  }
15943
15705
  } catch {}
15944
15706
  }
@@ -15946,14 +15708,14 @@ function snapshotMaintainDocsFiles(docsDir) {
15946
15708
  }
15947
15709
  function enforceMaintainDocsProtectedRegions(args) {
15948
15710
  for (const [fileName, original] of args.snapshot) {
15949
- const path3 = join6(args.docsDir, fileName);
15711
+ const path3 = join5(args.docsDir, fileName);
15950
15712
  try {
15951
- const current = readFileSync6(path3, "utf8");
15713
+ const current = readFileSync5(path3, "utf8");
15952
15714
  const { text, violated } = enforceProtectedRegions(original, current);
15953
15715
  if (!violated) {
15954
15716
  continue;
15955
15717
  }
15956
- writeFileSync4(path3, text, "utf8");
15718
+ writeFileSync3(path3, text, "utf8");
15957
15719
  log(`[dreamer] maintain-docs altered a protected region in ${fileName} — restored from pre-task snapshot`);
15958
15720
  } catch (error) {
15959
15721
  log(`[dreamer] maintain-docs protected-region enforcement failed for ${fileName}: ${error}`);
@@ -15962,10 +15724,10 @@ function enforceMaintainDocsProtectedRegions(args) {
15962
15724
  }
15963
15725
 
15964
15726
  // src/features/magic-context/dreamer/map-memories.ts
15965
- import { createHash as createHash4 } from "node:crypto";
15727
+ import { createHash as createHash5 } from "node:crypto";
15966
15728
 
15967
15729
  // src/features/magic-context/dreamer/map-memories-prompt.ts
15968
- import { existsSync as existsSync9, statSync as statSync3 } from "node:fs";
15730
+ import { existsSync as existsSync8, statSync as statSync2 } from "node:fs";
15969
15731
  import path3 from "node:path";
15970
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.
15971
15733
 
@@ -16003,7 +15765,7 @@ function extractMemoryCandidatePaths(content, repoDir) {
16003
15765
  if (!abs.startsWith(`${root}/`))
16004
15766
  continue;
16005
15767
  try {
16006
- if (existsSync9(abs) && statSync3(abs).isFile())
15768
+ if (existsSync8(abs) && statSync2(abs).isFile())
16007
15769
  found.add(rel);
16008
15770
  } catch {}
16009
15771
  if (found.size >= MAX_SEED_PATHS_PER_MEMORY)
@@ -16223,7 +15985,7 @@ async function applyBatchMappings(args, batch, manifestText) {
16223
15985
  memory_project: args.projectIdentity,
16224
15986
  context_store_uuid: args.moduleRoute.moduleContextStoreUuid,
16225
15987
  authority_generation: args.moduleRoute.moduleAuthorityGeneration,
16226
- 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)}`,
16227
15989
  rows
16228
15990
  }
16229
15991
  }
@@ -17165,7 +16927,69 @@ function evaluateTaskGate(task, ctx) {
17165
16927
  }
17166
16928
 
17167
16929
  // src/features/magic-context/dreamer/verify.ts
17168
- 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
+ }
17169
16993
 
17170
16994
  // src/features/magic-context/dreamer/verify-gate.ts
17171
16995
  import path4 from "node:path";
@@ -17358,6 +17182,7 @@ function parseVerifyManifest(text) {
17358
17182
 
17359
17183
  // src/features/magic-context/dreamer/verify.ts
17360
17184
  var VERIFY_BATCH_SIZE = 50;
17185
+ var IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT = 2;
17361
17186
  function closeBroadCycle(args, cycleStartAt) {
17362
17187
  if (!args.forceBroad || cycleStartAt === undefined)
17363
17188
  return;
@@ -17411,6 +17236,9 @@ async function runVerify(args) {
17411
17236
  }
17412
17237
  const abortController = new AbortController;
17413
17238
  const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
17239
+ let consecutiveProviderFailures = 0;
17240
+ let priorProviderFailureFingerprint = null;
17241
+ let lastProviderFailure = null;
17414
17242
  try {
17415
17243
  for (let i = 0;i < batches.length; i += 1) {
17416
17244
  const remainingMs = Math.max(0, args.deadline - Date.now());
@@ -17425,7 +17253,25 @@ async function runVerify(args) {
17425
17253
  result.remaining -= counts.verified + counts.updated + counts.archived;
17426
17254
  result.batches += 1;
17427
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
+ }
17428
17272
  }
17273
+ if (lastProviderFailure)
17274
+ throw lastProviderFailure;
17429
17275
  result.complete = result.remaining === 0;
17430
17276
  if (result.complete)
17431
17277
  closeBroadCycle(args, gate.broadCycleStartAt);
@@ -17483,7 +17329,14 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
17483
17329
  const text = extractLatestAssistantText(messages);
17484
17330
  if (!text)
17485
17331
  throw new Error("verify returned no output");
17486
- 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
+ }
17487
17340
  return text;
17488
17341
  }
17489
17342
  });
@@ -17491,11 +17344,12 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
17491
17344
  return await applyVerifyManifest(args, batch, run.validated);
17492
17345
  } catch (error) {
17493
17346
  const desc = describeError(error);
17494
- 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);
17495
17349
  recordInvocation4(args, startedAt, { status: "failed", error });
17496
17350
  if (error instanceof DreamerModuleFailureError || signal.aborted)
17497
17351
  throw error;
17498
- return { verified: 0, updated: 0, archived: 0 };
17352
+ return { verified: 0, updated: 0, archived: 0, providerFailure };
17499
17353
  } finally {
17500
17354
  if (agentSessionId && !shouldKeepSubagents()) {
17501
17355
  await args.client.session.delete({
@@ -17567,7 +17421,7 @@ async function applyVerifyManifest(args, batch, manifestText) {
17567
17421
  memory_project: args.projectIdentity,
17568
17422
  context_store_uuid: args.moduleRoute.moduleContextStoreUuid,
17569
17423
  authority_generation: args.moduleRoute.moduleAuthorityGeneration,
17570
- 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)}`,
17571
17425
  rows
17572
17426
  }
17573
17427
  }
@@ -17811,12 +17665,6 @@ function createDreamTaskExecutor(deps) {
17811
17665
  recordRun("completed", null);
17812
17666
  return { status: "completed" };
17813
17667
  }
17814
- if (moduleRoute) {
17815
- const reason = "compress-cues parked: MODULE memory authority has no cue write facade";
17816
- log(`[dreamer] compress-cues: skipped (${reason})`);
17817
- recordRun("failed", reason);
17818
- return { status: "failed", transient: true, error: reason };
17819
- }
17820
17668
  const result = await runCompressCues({
17821
17669
  db,
17822
17670
  client: deps.client,
@@ -17828,6 +17676,7 @@ function createDreamTaskExecutor(deps) {
17828
17676
  deadline,
17829
17677
  model: config.model ?? deps.mural.model ?? deps.dreamerModel,
17830
17678
  fallbackModels: config.fallbackModels,
17679
+ moduleRoute,
17831
17680
  onProgress: (processed) => reportProgress(processed)
17832
17681
  });
17833
17682
  log(`[dreamer] compress-cues: compressed=${result.compressed} skipped=${result.skipped} chunks=${result.chunks} remaining=${result.remaining}`);
@@ -18109,7 +17958,7 @@ function parseFrictionGateVerdict(verdict) {
18109
17958
  }
18110
17959
  function computeRetrospectiveWindowKey(flagged) {
18111
17960
  const anchors = flagged.map((message) => `${message.sessionId}:${message.ts}`).sort().join("|");
18112
- return createHash6("sha256").update(anchors).digest("hex").slice(0, 32);
17961
+ return createHash8("sha256").update(anchors).digest("hex").slice(0, 32);
18113
17962
  }
18114
17963
  function renderFrictionWindow(messages, flaggedOrdinals, radius = 2) {
18115
17964
  const flagged = new Set(flaggedOrdinals);
@@ -18342,8 +18191,8 @@ async function runAgenticTask(config, ctx, helpers) {
18342
18191
  const lastRunAt = getTaskScheduleState(db, projectIdentity, config.task)?.lastRunAt ?? null;
18343
18192
  const maintainDocsSnapshot = task === "maintain-docs" ? snapshotMaintainDocsFiles(docsDir) : undefined;
18344
18193
  const existingDocs = task === "maintain-docs" ? {
18345
- architecture: existsSync10(`${docsDir}/ARCHITECTURE.md`),
18346
- structure: existsSync10(`${docsDir}/STRUCTURE.md`)
18194
+ architecture: existsSync9(`${docsDir}/ARCHITECTURE.md`),
18195
+ structure: existsSync9(`${docsDir}/STRUCTURE.md`)
18347
18196
  } : undefined;
18348
18197
  const userMemories = task === "curate" ? getActiveUserMemories(db).map((um) => ({ id: um.id, content: um.content })) : undefined;
18349
18198
  let curateMemories;
@@ -19056,7 +18905,7 @@ var startupJitters = new Map;
19056
18905
  var nextStartupJitterSlot = 0;
19057
18906
  function directoryStillExists(directory) {
19058
18907
  try {
19059
- return statSync4(directory).isDirectory();
18908
+ return statSync3(directory).isDirectory();
19060
18909
  } catch {
19061
18910
  return false;
19062
18911
  }
@@ -19379,7 +19228,7 @@ function createDreamTimerModuleClient(moduleClient) {
19379
19228
  }
19380
19229
 
19381
19230
  // src/plugin/embedding-bootstrap-helpers.ts
19382
- import { createHash as createHash7 } from "node:crypto";
19231
+ import { createHash as createHash9 } from "node:crypto";
19383
19232
  var EMBEDDING_AFFECTING_KEYS = new Set([
19384
19233
  "embedding.api_key",
19385
19234
  "embedding.endpoint",
@@ -19425,7 +19274,7 @@ var EMBEDDING_WARNING_TERMS = [
19425
19274
  ];
19426
19275
  var loggedFailureSignatures = new Map;
19427
19276
  function sha256Prefix(value, length = 16) {
19428
- return createHash7("sha256").update(value).digest("hex").slice(0, length);
19277
+ return createHash9("sha256").update(value).digest("hex").slice(0, length);
19429
19278
  }
19430
19279
  function warningLooksEmbeddingRelated(message) {
19431
19280
  const lower = message.toLowerCase();
@@ -19729,16 +19578,7 @@ function resolveCacheTtl(cacheTtl, modelKey) {
19729
19578
  if (typeof cacheTtl === "string") {
19730
19579
  return cacheTtl;
19731
19580
  }
19732
- if (modelKey && typeof cacheTtl[modelKey] === "string") {
19733
- return cacheTtl[modelKey];
19734
- }
19735
- if (modelKey) {
19736
- const bareModelId = modelKey.split("/").slice(1).join("/");
19737
- if (bareModelId && typeof cacheTtl[bareModelId] === "string") {
19738
- return cacheTtl[bareModelId];
19739
- }
19740
- }
19741
- return cacheTtl.default ?? "5m";
19581
+ return resolveModelConfigOrDefault(cacheTtl, modelKey, cacheTtl.default ?? "5m");
19742
19582
  }
19743
19583
  var clampWarnSeen = new Set;
19744
19584
  function isFinitePositive(v) {
@@ -22765,7 +22605,7 @@ function replayCavemanCompression(sessionId, db, targets, tags) {
22765
22605
  }
22766
22606
 
22767
22607
  // src/hooks/magic-context/compaction-off-transition.ts
22768
- import { existsSync as existsSync11 } from "node:fs";
22608
+ import { existsSync as existsSync10 } from "node:fs";
22769
22609
  var loggedUnverifiedMarkerCleanupRetry = false;
22770
22610
  var COMPACTION_OFF_FLIP_NOTICE = [
22771
22611
  "## Magic Context — compaction-off mode is now active",
@@ -22800,7 +22640,7 @@ function clearCachedM0Baseline(db, sessionId) {
22800
22640
  return (result.changes ?? 0) > 0;
22801
22641
  }
22802
22642
  function cleanupOffMarkers(sessionId) {
22803
- if (!existsSync11(getOpenCodeDbPath())) {
22643
+ if (!existsSync10(getOpenCodeDbPath())) {
22804
22644
  return { verified: true, removedLineages: 0, removedRows: 0, retainedLineages: 0 };
22805
22645
  }
22806
22646
  return removeMcOwnedCompactionMarkers(sessionId, MARKER_SUMMARY_TEXT);
@@ -23894,7 +23734,7 @@ function createPassOutcome() {
23894
23734
  }
23895
23735
 
23896
23736
  // src/hooks/magic-context/rust-mode-transform.ts
23897
- import { createHash as createHash11 } from "node:crypto";
23737
+ import { createHash as createHash13 } from "node:crypto";
23898
23738
 
23899
23739
  // src/hooks/magic-context/module-state-sync.ts
23900
23740
  import { createHmac, randomUUID as randomUUID5 } from "node:crypto";
@@ -25232,6 +25072,121 @@ async function syncModuleState(args) {
25232
25072
  }
25233
25073
  }
25234
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
+
25235
25190
  // src/hooks/magic-context/transform-context-state.ts
25236
25191
  function loadPersistedUsageWatermark(db, sessionId) {
25237
25192
  const result = db.prepare("SELECT last_response_time FROM session_meta WHERE session_id = ?").get(sessionId);
@@ -25335,7 +25290,7 @@ function containsProbeVerbatim(text, probes) {
25335
25290
  }
25336
25291
 
25337
25292
  // src/features/magic-context/search-measurement.ts
25338
- import { createHash as createHash9 } from "node:crypto";
25293
+ import { createHash as createHash12 } from "node:crypto";
25339
25294
  function resultId(result) {
25340
25295
  switch (result.source) {
25341
25296
  case "memory":
@@ -25422,7 +25377,7 @@ async function recordShadowMeasurement(args) {
25422
25377
  }
25423
25378
  }
25424
25379
  function sha256(value) {
25425
- return createHash9("sha256").update(value).digest("hex");
25380
+ return createHash12("sha256").update(value).digest("hex");
25426
25381
  }
25427
25382
 
25428
25383
  // src/features/magic-context/search.ts
@@ -27783,121 +27738,6 @@ function readFilePath(target) {
27783
27738
  return null;
27784
27739
  }
27785
27740
 
27786
- // src/hooks/magic-context/todo-view.ts
27787
- import { createHash as createHash10 } from "node:crypto";
27788
- var TODO_STATUS_PENDING = "pending";
27789
- var TODO_STATUS_IN_PROGRESS = "in_progress";
27790
- var TODO_STATUS_COMPLETED = "completed";
27791
- var TODO_STATUS_CANCELLED = "cancelled";
27792
- var TODO_PRIORITY_HIGH = "high";
27793
- var TODO_PRIORITY_MEDIUM = "medium";
27794
- var TODO_PRIORITY_LOW = "low";
27795
- var TODO_STATUSES = [
27796
- TODO_STATUS_PENDING,
27797
- TODO_STATUS_IN_PROGRESS,
27798
- TODO_STATUS_COMPLETED,
27799
- TODO_STATUS_CANCELLED
27800
- ];
27801
- var TODO_PRIORITIES = [
27802
- TODO_PRIORITY_HIGH,
27803
- TODO_PRIORITY_MEDIUM,
27804
- TODO_PRIORITY_LOW
27805
- ];
27806
- var TODO_STATUS_SET = new Set(TODO_STATUSES);
27807
- var TODO_PRIORITY_SET = new Set(TODO_PRIORITIES);
27808
- var TERMINAL_STATUSES = new Set([
27809
- TODO_STATUS_COMPLETED,
27810
- TODO_STATUS_CANCELLED
27811
- ]);
27812
- var TITLE_DONE_STATUSES = new Set([TODO_STATUS_COMPLETED]);
27813
- var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
27814
- function normalizeTodoStateJson(todos) {
27815
- if (!Array.isArray(todos))
27816
- return null;
27817
- const normalized = [];
27818
- for (const todo of todos) {
27819
- if (!isTodoItem(todo))
27820
- return null;
27821
- normalized.push({
27822
- content: todo.content,
27823
- status: todo.status,
27824
- priority: todo.priority ?? TODO_PRIORITY_MEDIUM
27825
- });
27826
- }
27827
- return JSON.stringify(normalized);
27828
- }
27829
- function buildSyntheticTodoPart(stateJson) {
27830
- const todos = parseTodoState(stateJson);
27831
- if (todos === null || todos.length === 0)
27832
- return null;
27833
- if (todos.every((t) => TERMINAL_STATUSES.has(t.status)))
27834
- return null;
27835
- const callID = computeSyntheticCallId(stateJson);
27836
- const activeCount = todos.filter((t) => !TITLE_DONE_STATUSES.has(t.status)).length;
27837
- const output = JSON.stringify(todos, null, 2);
27838
- const ts = 0;
27839
- return {
27840
- type: "tool",
27841
- callID,
27842
- tool: "todowrite",
27843
- state: {
27844
- status: "completed",
27845
- input: { todos },
27846
- output,
27847
- title: `${activeCount} todos`,
27848
- metadata: { todos, truncated: false },
27849
- time: { start: ts, end: ts }
27850
- },
27851
- syntheticTodoMarker: true
27852
- };
27853
- }
27854
- function computeSyntheticCallId(stateJson) {
27855
- const hash = createHash10("sha256").update(stateJson).digest("hex").slice(0, 16);
27856
- return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
27857
- }
27858
- function isSyntheticTodoPart(part) {
27859
- if (part === null || typeof part !== "object")
27860
- return false;
27861
- const p = part;
27862
- if (p.syntheticTodoMarker === true)
27863
- return true;
27864
- return p.type === "tool" && p.tool === "todowrite" && typeof p.callID === "string" && p.callID.startsWith(SYNTHETIC_CALL_ID_PREFIX);
27865
- }
27866
- function parseTodoState(stateJson) {
27867
- if (stateJson.length === 0)
27868
- return null;
27869
- try {
27870
- const parsed = JSON.parse(stateJson);
27871
- if (!Array.isArray(parsed))
27872
- return null;
27873
- const result = [];
27874
- for (const item of parsed) {
27875
- if (!isTodoItem(item))
27876
- return null;
27877
- result.push({
27878
- content: item.content,
27879
- status: item.status,
27880
- priority: item.priority ?? TODO_PRIORITY_MEDIUM
27881
- });
27882
- }
27883
- return result;
27884
- } catch {
27885
- return null;
27886
- }
27887
- }
27888
- function isTodoStatus(value) {
27889
- return typeof value === "string" && TODO_STATUS_SET.has(value);
27890
- }
27891
- function isTodoPriority(value) {
27892
- return typeof value === "string" && TODO_PRIORITY_SET.has(value);
27893
- }
27894
- function isTodoItem(value) {
27895
- if (value === null || typeof value !== "object")
27896
- return false;
27897
- const todo = value;
27898
- return typeof todo.content === "string" && isTodoStatus(todo.status) && (todo.priority === undefined || isTodoPriority(todo.priority));
27899
- }
27900
-
27901
27741
  // src/hooks/magic-context/tool-reclaim.ts
27902
27742
  function buildSyntheticToolReclaimOps(input) {
27903
27743
  const watermark = Math.max(0, input.watermark);
@@ -29411,7 +29251,9 @@ class MemoryAuthorityUnavailableError extends Error {
29411
29251
  }
29412
29252
  }
29413
29253
  var RUST_FAILURE_PARK_THRESHOLD = 3;
29414
- 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;
29415
29257
  var RUST_SEND_TIMEOUT_MS = 15000;
29416
29258
  function isRecord3(value) {
29417
29259
  return value !== null && typeof value === "object";
@@ -29572,10 +29414,10 @@ function messageCacheSignature(message) {
29572
29414
  const parts = Array.isArray(message.parts) ? message.parts : [];
29573
29415
  const serializedParts = JSON.stringify(parts) ?? "null";
29574
29416
  const serializedMessage = JSON.stringify(message) ?? "null";
29575
- 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")}`;
29576
29418
  }
29577
29419
  function advanceWireFingerprint(previous, encoded) {
29578
- 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");
29579
29421
  }
29580
29422
  function buildWireFingerprint(encoded) {
29581
29423
  let fingerprint = "rust-wire-v1";
@@ -29613,7 +29455,8 @@ function formatRustPassLog(args) {
29613
29455
  const timings = args.timings ?? emptyRustPassTimings();
29614
29456
  const measured = timings.prefixGuard + timings.ordinalResolve + timings.stateSync + timings.clone + timings.wireBuild + timings.transport + timings.apply + timings.lkgSnapshot;
29615
29457
  const unattributed = Math.max(0, args.elapsedMs - measured);
29616
- 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)}`;
29617
29460
  }
29618
29461
  function isSyntheticUserMessage(message) {
29619
29462
  if (!message || messageInfo2(message).role !== "user" || !Array.isArray(message.parts)) {
@@ -29774,7 +29617,7 @@ function canonicalizeForChecksum(value) {
29774
29617
  return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonicalizeForChecksum(value[key])]));
29775
29618
  }
29776
29619
  function checksumSeedRows(rows) {
29777
- return createHash11("sha256").update(JSON.stringify(rows.map(canonicalizeForChecksum))).digest("hex");
29620
+ return createHash13("sha256").update(JSON.stringify(rows.map(canonicalizeForChecksum))).digest("hex");
29778
29621
  }
29779
29622
  function authoritySeedRows(db, projectPath, domain) {
29780
29623
  const snapshots = domain === "memories" ? db.prepare("SELECT * FROM memories WHERE project_path = ? ORDER BY id ASC").all(projectPath) : db.prepare(`SELECT n.*
@@ -29915,6 +29758,35 @@ async function prepareRustMemoryAuthority(args) {
29915
29758
  state.memoryAuthorityReady = true;
29916
29759
  args.onProjectPrepared?.(projectPath);
29917
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
+ }
29918
29790
  function applyNativeMessagesVerbatim(output, response) {
29919
29791
  const nativeMessages = response.native_messages;
29920
29792
  if (typeof nativeMessages === "string") {
@@ -29968,6 +29840,9 @@ function buildTransformBody(args) {
29968
29840
  model_key: args.modelKey,
29969
29841
  provider_id: args.providerId,
29970
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 ?? {},
29971
29846
  effective_execute_threshold: args.passInputs.effective_execute_threshold,
29972
29847
  history_budget_tokens: args.passInputs.history_budget_tokens,
29973
29848
  clear_reasoning_age: args.passInputs.clear_reasoning_age,
@@ -30014,7 +29889,7 @@ function createRustModeTransform(deps, options) {
30014
29889
  state.passesSincePark = 0;
30015
29890
  state.warningSent = true;
30016
29891
  const warning = "Rust Magic Context is unavailable for this session; retry after the module recovers.";
30017
- 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}`);
30018
29893
  options.notifyParked?.(sessionId, warning);
30019
29894
  };
30020
29895
  const resetOrdinalMemo = (state) => {
@@ -30147,6 +30022,7 @@ function createRustModeTransform(deps, options) {
30147
30022
  let materializeReason = "none";
30148
30023
  let servedFrom = "none";
30149
30024
  let moduleElapsedMs = 0;
30025
+ let rowVersion = 0;
30150
30026
  let appliedAt;
30151
30027
  let emergencyFailClosed = false;
30152
30028
  const passUsageSnapshot = loadContextUsage(deps.contextUsageMap, deps.db, sessionId);
@@ -30178,7 +30054,7 @@ function createRustModeTransform(deps, options) {
30178
30054
  } catch (error) {
30179
30055
  preflightError ??= error;
30180
30056
  }
30181
- emergencyFailClosed = passUsageSnapshot.percentage >= 95 && resolvedContextLimit !== undefined && resolvedContextLimit > 0;
30057
+ emergencyFailClosed = passUsageSnapshot.percentage >= RUST_EMERGENCY_WALL_PCT && resolvedContextLimit !== undefined && resolvedContextLimit > 0;
30182
30058
  if (overflowState) {
30183
30059
  const detectedLimitMatchesModel = overflowState.detectedContextLimitModelKey === null || overflowState.detectedContextLimitModelKey === modelKey;
30184
30060
  const hasProviderProof = overflowState.detectedContextLimit > 0 && detectedLimitMatchesModel || isProviderOverflowReconfirmed(sessionId);
@@ -30196,6 +30072,7 @@ function createRustModeTransform(deps, options) {
30196
30072
  applied,
30197
30073
  elapsedMs,
30198
30074
  moduleElapsedMs,
30075
+ rowVersion,
30199
30076
  timings
30200
30077
  }));
30201
30078
  if (served) {
@@ -30215,6 +30092,7 @@ function createRustModeTransform(deps, options) {
30215
30092
  const timings2 = isRecord3(response.timings) ? response.timings : undefined;
30216
30093
  const total = timings2?.total;
30217
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;
30218
30096
  if (timings2 && moduleElapsedMs >= 1000) {
30219
30097
  const detail = Object.entries(timings2).filter(([key, value]) => key !== "total" && typeof value === "number").map(([key, value]) => `${key}:${value.toFixed(1)}`).join(" ");
30220
30098
  if (detail)
@@ -30223,7 +30101,7 @@ function createRustModeTransform(deps, options) {
30223
30101
  };
30224
30102
  if (state.parked) {
30225
30103
  state.passesSincePark += 1;
30226
- 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) {
30227
30105
  decision = "parked";
30228
30106
  const replayed = replayLastGood(sessionId, messages, output, sessionMeta.systemPromptTokens);
30229
30107
  if (replayed) {
@@ -30255,6 +30133,7 @@ function createRustModeTransform(deps, options) {
30255
30133
  const midTurn = isMidTurn(deps, sessionId);
30256
30134
  const requestObservedAtMs = Date.now();
30257
30135
  const recoveryNoHeadEscape = overflowState.needsEmergencyRecovery && loadProtectedTailMeta(deps.db, sessionId).recoveryNoEligibleHeadCount >= RECOVERY_NO_HEAD_LIMIT;
30136
+ const promptSurface = resolvePromptSurface(deps.promptSurface, modelKey ?? undefined);
30258
30137
  const passInputs = {
30259
30138
  now_ms: requestObservedAtMs,
30260
30139
  model_key: modelKey,
@@ -30271,6 +30150,9 @@ function createRustModeTransform(deps, options) {
30271
30150
  system_prompt_hash: sessionMeta.systemPromptHash ?? "",
30272
30151
  upgrade_state: readUpgradeState(deps.db, sessionId),
30273
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 ?? {},
30274
30156
  protected_tags: deps.protectedTags ?? DEFAULT_PROTECTED_TAGS,
30275
30157
  temporal_awareness: deps.experimentalTemporalAwareness === true,
30276
30158
  channel2_nudge_state: getChannel2NudgeState(deps.db, sessionId),
@@ -30630,6 +30512,9 @@ function createRustModeTransform(deps, options) {
30630
30512
  });
30631
30513
  }
30632
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;
30633
30518
  let appliedMessages;
30634
30519
  const applyStartedAt = performance.now();
30635
30520
  try {
@@ -30645,6 +30530,14 @@ function createRustModeTransform(deps, options) {
30645
30530
  if (typeof boundaryId === "string" && boundaryId.length > 0) {
30646
30531
  assertNativeBoundary(appliedMessages, sessionId, boundaryId);
30647
30532
  }
30533
+ if (!sessionMeta.isSubagent) {
30534
+ mirrorRustSyntheticTodoAnchor({
30535
+ db: deps.db,
30536
+ sessionId,
30537
+ messages: appliedMessages,
30538
+ cacheBustingPass
30539
+ });
30540
+ }
30648
30541
  if (passInputs.emergency_recovery_armed === true) {
30649
30542
  servedFinalWireEstimate = estimateFinalWireInputTokens({
30650
30543
  messages: appliedMessages,
@@ -30656,9 +30549,6 @@ function createRustModeTransform(deps, options) {
30656
30549
  }
30657
30550
  logStage(sessionId, "apply", applyStartedAt, timings);
30658
30551
  const lkgSnapshotStartedAt = performance.now();
30659
- const explicitDecision = typeof response.decision === "string" || typeof response.action === "string" || typeof response.cache_bust === "boolean";
30660
- const decisionUpper = decision.toUpperCase();
30661
- const cacheBustingPass = response.cache_bust === true || decisionUpper === "HARD" || decisionUpper === "MIGRATE_HARD" || decisionUpper === "EXECUTE" || decisionUpper === "SOFT" || !explicitDecision;
30662
30552
  if (cacheBustingPass || !getSlot(sessionId)) {
30663
30553
  const captured = captureRustResponse(sessionId, messages, response);
30664
30554
  if (cacheBustingPass && !captured) {
@@ -30766,6 +30656,7 @@ function createRustModeTransform(deps, options) {
30766
30656
  sessionLog(sessionId, "rust transform wire invariant failed; LKG replay required", error);
30767
30657
  }
30768
30658
  if (emergencyFailClosed) {
30659
+ sessionLog(sessionId, "mc_rust_emergency_refusal before_lkg");
30769
30660
  markFailure(sessionId, state, error);
30770
30661
  finishPass(false, false);
30771
30662
  throw new EmergencyFailClosedError("Rust Magic Context was unavailable at a provider-proven context limit", { cause: error });
@@ -30785,10 +30676,17 @@ function createRustModeTransform(deps, options) {
30785
30676
  return {
30786
30677
  run,
30787
30678
  clearSession(sessionId) {
30679
+ const projectRoot = states.get(sessionId)?.memoryAuthorityRoot ?? options.projectRoot ?? null;
30788
30680
  dropSlot(sessionId, "session-deleted");
30789
30681
  states.delete(sessionId);
30790
30682
  wireCaches.delete(sessionId);
30791
- 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
+ }
30792
30690
  },
30793
30691
  invalidateWireState,
30794
30692
  getState(sessionId) {
@@ -33123,7 +33021,7 @@ function createToolExecuteAfterHook(args) {
33123
33021
  }
33124
33022
 
33125
33023
  // src/hooks/magic-context/system-prompt-hash.ts
33126
- import { createHash as createHash12 } from "node:crypto";
33024
+ import { createHash as createHash14 } from "node:crypto";
33127
33025
 
33128
33026
  // src/agents/magic-context-prompt.ts
33129
33027
  var LONG_TERM_PARTNER_FRAME = `### You are the user's long-term partner on this project — not a one-off hire
@@ -33139,6 +33037,10 @@ var PARTNER_FRAME_CLOSER_REDUCE = `
33139
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.`;
33140
33038
  var PARTNER_FRAME_CLOSER_NO_REDUCE = `
33141
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.`;
33142
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).`;
33143
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.
33144
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.`;
@@ -33181,6 +33083,17 @@ Use \`ctx_expand\` to recover the raw conversation behind a summary under a \`##
33181
33083
  - Want to recall what was decided in an earlier conversation → \`ctx_search(query="dashboard release signing setup")\`
33182
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.
33183
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}`;
33184
33097
  var GENERIC_SECTION = `
33185
33098
  ### Reduction Triggers
33186
33099
  - After reading files or search results you already acted on — drop raw outputs.
@@ -33197,21 +33110,27 @@ var GENERIC_SECTION = `
33197
33110
  - Your current task requirements and constraints.
33198
33111
  - Recent errors and unresolved decisions.
33199
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.`;
33200
33115
  var TEMPORAL_AWARENESS_GUIDANCE = `
33201
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.`;
33202
33117
  var SUBAGENT_REDUCE_INTRO = (protectedTags) => `Messages and tool outputs are tagged with §N§ identifiers (e.g., §1§, §42§).
33203
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.
33204
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.
33205
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.`;
33206
33124
  var CAVEMAN_COMPRESSION_WARNING = `
33207
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.`;
33208
- 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) {
33209
33127
  if (subagentMode) {
33128
+ const intro = preset === "light" ? SUBAGENT_REDUCE_INTRO_LIGHT(protectedTags) : SUBAGENT_REDUCE_INTRO(protectedTags);
33210
33129
  return `## Magic Context
33211
33130
 
33212
- ${SUBAGENT_REDUCE_INTRO(protectedTags)}`;
33131
+ ${intro}`;
33213
33132
  }
33214
- const smartNoteGuidance = dreamerEnabled ? `
33133
+ const smartNoteGuidance = dreamerEnabled ? preset === "light" ? SMART_NOTE_GUIDANCE_LIGHT : `
33215
33134
  When \`surface_condition\` is provided with \`write\`, the note becomes a project-scoped smart note.
33216
33135
  The dreamer evaluates smart note conditions during nightly runs and surfaces them when conditions are met.
33217
33136
  Example: \`ctx_note(action="write", content="Implement X because Y", surface_condition="When PR #42 is merged in this repo")\`` : "";
@@ -33221,13 +33140,32 @@ Example: \`ctx_note(action="write", content="Implement X because Y", surface_con
33221
33140
  const languageGuidance = languageDirective ? `
33222
33141
 
33223
33142
  ${languageDirective}` : "";
33143
+ if (primaryOverride !== undefined) {
33144
+ return `${primaryOverride}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
33145
+ }
33224
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
+ }
33225
33155
  return `## Magic Context
33226
33156
 
33227
33157
  ${LONG_TERM_PARTNER_FRAME}
33228
33158
  ${PARTNER_FRAME_CLOSER_NO_REDUCE}
33229
33159
 
33230
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}`;
33231
33169
  }
33232
33170
  return `## Magic Context
33233
33171
 
@@ -33253,6 +33191,11 @@ function isMagicContextInternalAgent(systemPromptContent) {
33253
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.");
33254
33192
  }
33255
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);
33256
33199
  const stickyDateBySession = new Map;
33257
33200
  const handler = async (input, output) => {
33258
33201
  const sessionId = input.sessionID;
@@ -33290,10 +33233,14 @@ function createSystemPromptHashHandler(deps) {
33290
33233
  const subagentReduceMode = isSubagentSession2 && ctxReduceCallable;
33291
33234
  const effectiveCtxReduceEnabled = isSubagentSession2 ? false : ctxReduceCallable;
33292
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);
33293
33240
  const fullPrompt = output.system.join(`
33294
33241
  `);
33295
33242
  if (fullPrompt.length > 0 && !fullPrompt.includes(MAGIC_CONTEXT_MARKER) && !skipGuidanceForDisabledSubagent) {
33296
- 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);
33297
33244
  output.system.push(guidance);
33298
33245
  sessionLog(sessionId, `injected generic guidance into system prompt (ctxReduce=${effectiveCtxReduceEnabled}, subagent=${isSubagentSession2}, subagentReduceMode=${subagentReduceMode})`);
33299
33246
  }
@@ -33324,7 +33271,7 @@ function createSystemPromptHashHandler(deps) {
33324
33271
  return;
33325
33272
  if (!availability.frozen)
33326
33273
  return;
33327
- const currentHash = createHash12("md5").update(systemContent).digest("hex");
33274
+ const currentHash = createHash14("md5").update(promptSurfaceHashMaterial(systemContent, promptSurface.preset)).digest("hex");
33328
33275
  if (!sessionMetaEarly) {
33329
33276
  return;
33330
33277
  }
@@ -33362,6 +33309,7 @@ function createSystemPromptHashHandler(deps) {
33362
33309
  return {
33363
33310
  handler,
33364
33311
  clearSession: (sessionId) => {
33312
+ guidanceEpochs.clear(sessionId);
33365
33313
  clearSystemPromptHashSession(sessionId, {
33366
33314
  stickyDateBySession,
33367
33315
  cachedDocsBySession: new Map
@@ -33814,6 +33762,7 @@ function createMagicContextHook(deps) {
33814
33762
  const client = {
33815
33763
  call: (args) => transport.call(args),
33816
33764
  stateSyncCapabilities: (args) => transport.stateSyncCapabilities(args),
33765
+ deleteSession: (sessionId, projectRoot) => transport.deleteSession(sessionId, projectRoot),
33817
33766
  closeSession: (sessionId) => transport.closeSession(sessionId),
33818
33767
  authorityStatus: (args) => transport.authorityStatus(args),
33819
33768
  authorityPrepare: (args) => transport.authorityPrepare(args),
@@ -33842,6 +33791,23 @@ function createMagicContextHook(deps) {
33842
33791
  return client;
33843
33792
  })();
33844
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");
33845
33811
  const rustToolBackends = deps.config.transform_mode === "rust" && rustModeModuleClient ? {
33846
33812
  authorityState: async ({ projectPath: projectPath2, projectRoot, domain }) => {
33847
33813
  if (!rustModeModuleClient.authorityStatus)
@@ -33866,7 +33832,7 @@ function createMagicContextHook(deps) {
33866
33832
  command_id: commandId
33867
33833
  }
33868
33834
  }),
33869
- note: ({
33835
+ note: async ({
33870
33836
  commandId,
33871
33837
  sessionId,
33872
33838
  projectRoot,
@@ -33878,26 +33844,30 @@ function createMagicContextHook(deps) {
33878
33844
  limit,
33879
33845
  offset,
33880
33846
  noteId
33881
- }) => rustModeModuleClient.call({
33882
- sessionId,
33883
- projectRoot,
33884
- method: "ctx_note",
33885
- body: {
33886
- name: "ctx_note",
33887
- arguments: {
33888
- ...commandId ? { command_id: commandId } : {},
33889
- action,
33890
- content,
33891
- memory_project: memoryProject,
33892
- surface_condition: surfaceCondition,
33893
- filter,
33894
- limit,
33895
- offset,
33896
- 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
+ }
33897
33865
  }
33898
- }
33899
- }),
33900
- memory: ({
33866
+ });
33867
+ await syncModuleNotes();
33868
+ return response;
33869
+ },
33870
+ memory: async ({
33901
33871
  commandId,
33902
33872
  sessionId,
33903
33873
  projectRoot,
@@ -33907,23 +33877,27 @@ function createMagicContextHook(deps) {
33907
33877
  category,
33908
33878
  ids,
33909
33879
  reason
33910
- }) => rustModeModuleClient.call({
33911
- sessionId,
33912
- projectRoot,
33913
- method: "ctx_memory",
33914
- body: {
33915
- name: "ctx_memory",
33916
- arguments: {
33917
- ...commandId ? { command_id: commandId } : {},
33918
- action,
33919
- content,
33920
- category,
33921
- ids,
33922
- reason,
33923
- 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
+ }
33924
33896
  }
33925
- }
33926
- }),
33897
+ });
33898
+ await syncModuleMemories();
33899
+ return response;
33900
+ },
33927
33901
  noteEvaluationAvailable: (evaluationProjectPath) => getModuleNoteEvaluationBridge(evaluationProjectPath) !== undefined,
33928
33902
  memorySync: (sessionId) => {
33929
33903
  rustMemorySyncRequestedSessions.add(sessionId);
@@ -33934,21 +33908,6 @@ function createMagicContextHook(deps) {
33934
33908
  return;
33935
33909
  if (getModuleNoteEvaluationBridge(bridgeProjectPath))
33936
33910
  return;
33937
- const syncModuleNotes = async () => {
33938
- for (;; ) {
33939
- const cursor = getMirrorCursor(db, "notes");
33940
- const response = await rustModeModuleClient.mirrorPull?.({
33941
- domain: "notes",
33942
- cursor,
33943
- limit: 1000
33944
- });
33945
- if (!response)
33946
- throw new Error("mirror.pull is unavailable for notes");
33947
- const next = applyMirrorPage({ db, page: response.page });
33948
- if (!response.page.has_more || next === cursor)
33949
- break;
33950
- }
33951
- };
33952
33911
  registerModuleNoteEvaluationBridge(bridgeProjectPath, {
33953
33912
  sync: syncModuleNotes,
33954
33913
  async evaluate({ contextNoteId, sessionId, verdict }) {
@@ -34056,6 +34015,7 @@ function createMagicContextHook(deps) {
34056
34015
  } : undefined,
34057
34016
  maybeAutoEmbedSession,
34058
34017
  transformMode: deps.config.transform_mode,
34018
+ promptSurface: deps.config.prompt_surface,
34059
34019
  rustModeModuleClient,
34060
34020
  tsAuthorityRecoveryModuleClient: authorityRecoveryModuleClient,
34061
34021
  rustMemorySyncRequestedSessions,
@@ -34237,6 +34197,9 @@ function createMagicContextHook(deps) {
34237
34197
  dreamerEnabled: dreamerRunnable,
34238
34198
  memoryEnabled: deps.config.memory?.enabled !== false,
34239
34199
  language: deps.config.language,
34200
+ promptSurface: deps.config.prompt_surface,
34201
+ promptSurfaceRuntime: deps.promptSurfaceRuntime,
34202
+ resolveModel: resolveLiveModel,
34240
34203
  historyRefreshSessions,
34241
34204
  systemPromptRefreshSessions,
34242
34205
  pendingMaterializationSessions,
@@ -34377,6 +34340,7 @@ async function createSessionHooksAsync(args) {
34377
34340
  compactionHandler,
34378
34341
  liveSessionState,
34379
34342
  rustModeModuleClient: args.rustModeModuleClient,
34343
+ promptSurfaceRuntime: args.promptSurfaceRuntime,
34380
34344
  config: buildMagicContextHookConfig(pluginConfig)
34381
34345
  });
34382
34346
  return {
@@ -35207,7 +35171,7 @@ function registerRpcHandlers(rpcServer, args) {
35207
35171
  const db = getDb();
35208
35172
  if (!db)
35209
35173
  return { ok: false, error: "db unavailable" };
35210
- const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-6cd3nrt7.js");
35174
+ const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-zc915ceq.js");
35211
35175
  const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-6njqewzk.js");
35212
35176
  log(`[rpc] recomp requested for session ${sessionId}`);
35213
35177
  const ctx = await buildManagedCtx(db);
@@ -35223,7 +35187,7 @@ function registerRpcHandlers(rpcServer, args) {
35223
35187
  const db = getDb();
35224
35188
  if (!db)
35225
35189
  return { ok: false, error: "db unavailable" };
35226
- const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-6cd3nrt7.js");
35190
+ const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-zc915ceq.js");
35227
35191
  const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-6njqewzk.js");
35228
35192
  log(`[rpc] session-upgrade requested for session ${sessionId}`);
35229
35193
  const ctx = await buildManagedCtx(db);
@@ -35240,7 +35204,7 @@ function registerRpcHandlers(rpcServer, args) {
35240
35204
  if (!db)
35241
35205
  return { ok: false, error: "db unavailable" };
35242
35206
  try {
35243
- const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-xt41zbw4.js");
35207
+ const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-53cjs6mr.js");
35244
35208
  updateSessionMeta2(db, sessionId, { upgradeRemindedAt: Date.now() });
35245
35209
  return { ok: true };
35246
35210
  } catch (error) {
@@ -36526,7 +36490,7 @@ Mark discardable once processed: large outputs you've summarized, repeated or re
36526
36490
  Keep: user messages, unresolved errors, raw evidence you haven't extracted yet, and outputs whose exact wording may matter later.
36527
36491
  Never blanket-mark large ranges (e.g. "1-50") — review what each tag holds first.`;
36528
36492
  // src/tools/ctx-reduce/tools.ts
36529
- import { createHash as createHash13 } from "node:crypto";
36493
+ import { createHash as createHash15 } from "node:crypto";
36530
36494
  import { tool as tool4 } from "@opencode-ai/plugin";
36531
36495
 
36532
36496
  // src/features/magic-context/range-parser.ts
@@ -36596,11 +36560,11 @@ function createCtxReduceTool(deps) {
36596
36560
  const stableId = `oc-${sessionId}-${callId}`;
36597
36561
  if (Buffer.byteLength(stableId) <= 128)
36598
36562
  return stableId;
36599
- return `oc-${createHash13("sha256").update(stableId).digest("hex")}`;
36563
+ return `oc-${createHash15("sha256").update(stableId).digest("hex")}`;
36600
36564
  }
36601
36565
  fallbackCommandSequence += 1;
36602
36566
  const monotonicId = `oc-${sessionId}-${fallbackCommandSequence}`;
36603
- 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")}`;
36604
36568
  };
36605
36569
  return tool4({
36606
36570
  description: CTX_REDUCE_DESCRIPTION,
@@ -36996,10 +36960,23 @@ function createToolRegistry(args) {
36996
36960
  rustToolBackends
36997
36961
  }) : {}
36998
36962
  };
36999
- 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)) {
37000
36977
  normalizeToolArgSchemas(toolDefinition);
37001
36978
  }
37002
- return allTools;
36979
+ return surfacedTools;
37003
36980
  }
37004
36981
 
37005
36982
  // src/shared/exit-abort-registry.ts
@@ -37027,15 +37004,15 @@ function unregisterExitAbort(controller) {
37027
37004
  import { randomBytes, timingSafeEqual } from "node:crypto";
37028
37005
  import {
37029
37006
  chmodSync,
37030
- mkdirSync as mkdirSync3,
37007
+ mkdirSync as mkdirSync2,
37031
37008
  readdirSync,
37032
- readFileSync as readFileSync7,
37033
- renameSync as renameSync4,
37034
- rmSync as rmSync3,
37035
- unlinkSync as unlinkSync2,
37036
- writeFileSync as writeFileSync5
37009
+ readFileSync as readFileSync6,
37010
+ renameSync as renameSync3,
37011
+ rmSync as rmSync2,
37012
+ unlinkSync,
37013
+ writeFileSync as writeFileSync4
37037
37014
  } from "node:fs";
37038
- import { dirname as dirname5 } from "node:path";
37015
+ import { dirname as dirname4 } from "node:path";
37039
37016
  var MAX_BODY_BYTES = 1048576;
37040
37017
  var WS_AUTH_TIMEOUT_MS = 5000;
37041
37018
  var WS_CLOSE_UNAUTHORIZED = 4401;
@@ -37109,28 +37086,28 @@ class MagicContextRpcServer {
37109
37086
  this.port = server.port ?? 0;
37110
37087
  try {
37111
37088
  this.warnIfOtherLiveInstance();
37112
- const dir = dirname5(this.portFilePath);
37089
+ const dir = dirname4(this.portFilePath);
37113
37090
  const enforcePrivatePermissions = shouldEnforcePrivateStoragePermissions();
37114
37091
  if (enforcePrivatePermissions) {
37115
- mkdirSync3(dir, { recursive: true, mode: 448 });
37092
+ mkdirSync2(dir, { recursive: true, mode: 448 });
37116
37093
  try {
37117
37094
  chmodSync(dir, 448);
37118
37095
  } catch {}
37119
37096
  } else {
37120
- mkdirSync3(dir, { recursive: true });
37097
+ mkdirSync2(dir, { recursive: true });
37121
37098
  }
37122
37099
  const tmpPath = `${this.portFilePath}.tmp`;
37123
37100
  try {
37124
- rmSync3(tmpPath, { force: true });
37101
+ rmSync2(tmpPath, { force: true });
37125
37102
  } catch {}
37126
- writeFileSync5(tmpPath, JSON.stringify({
37103
+ writeFileSync4(tmpPath, JSON.stringify({
37127
37104
  port: this.port,
37128
37105
  pid: process.pid,
37129
37106
  started_at: this.startedAt,
37130
37107
  token: this.token,
37131
37108
  instance_id: this.instanceId
37132
37109
  }), enforcePrivatePermissions ? { encoding: "utf-8", mode: 384 } : { encoding: "utf-8" });
37133
- renameSync4(tmpPath, this.portFilePath);
37110
+ renameSync3(tmpPath, this.portFilePath);
37134
37111
  if (enforcePrivatePermissions) {
37135
37112
  try {
37136
37113
  chmodSync(this.portFilePath, 384);
@@ -37157,7 +37134,7 @@ class MagicContextRpcServer {
37157
37134
  this.server = null;
37158
37135
  }
37159
37136
  try {
37160
- unlinkSync2(this.portFilePath);
37137
+ unlinkSync(this.portFilePath);
37161
37138
  } catch {}
37162
37139
  }
37163
37140
  warnIfOtherLiveInstance() {
@@ -37165,7 +37142,7 @@ class MagicContextRpcServer {
37165
37142
  for (const entry of readdirSync(this.portDir)) {
37166
37143
  if (!entry.startsWith("port-") || !entry.endsWith(".json"))
37167
37144
  continue;
37168
- const record = parseRpcPortFile(readFileSync7(`${this.portDir}/${entry}`, "utf-8"));
37145
+ const record = parseRpcPortFile(readFileSync6(`${this.portDir}/${entry}`, "utf-8"));
37169
37146
  if (!record || record.pid === process.pid || !isPidAlive(record.pid))
37170
37147
  continue;
37171
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`);
@@ -37305,7 +37282,13 @@ var server = async (ctx) => {
37305
37282
  warn: (m) => log(`[magic-context] ${m}`),
37306
37283
  info: (m) => log(`[magic-context] ${m}`)
37307
37284
  });
37308
- 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
+ });
37309
37292
  if (configMigrationWarnings.length > 0) {
37310
37293
  pluginConfig.configWarnings = [
37311
37294
  ...configMigrationWarnings,
@@ -37365,7 +37348,8 @@ var server = async (ctx) => {
37365
37348
  ctx,
37366
37349
  pluginConfig,
37367
37350
  liveSessionState,
37368
- rustModeModuleClient
37351
+ rustModeModuleClient,
37352
+ promptSurfaceRuntime
37369
37353
  });
37370
37354
  const magicContextRuntime = {
37371
37355
  magicContext: hooks.magicContext,
@@ -37390,7 +37374,8 @@ var server = async (ctx) => {
37390
37374
  ctx,
37391
37375
  pluginConfig,
37392
37376
  liveSessionState,
37393
- rustModeModuleClient
37377
+ rustModeModuleClient,
37378
+ promptSurfaceRuntime
37394
37379
  });
37395
37380
  if (!reopened.magicContext)
37396
37381
  return false;
@@ -37407,7 +37392,9 @@ var server = async (ctx) => {
37407
37392
  const tools5 = createToolRegistry({
37408
37393
  ctx,
37409
37394
  pluginConfig,
37410
- rustToolBackends: magicContextRuntime.rustToolBackends
37395
+ rustToolBackends: magicContextRuntime.rustToolBackends,
37396
+ promptSurfaceRuntime,
37397
+ registrationPromptSurface: loadedPluginConfig.registrationPromptSurface
37411
37398
  });
37412
37399
  if (pluginConfig.enabled && magicContextRuntime.magicContext) {
37413
37400
  try {
@@ -37513,7 +37500,7 @@ var server = async (ctx) => {
37513
37500
  {
37514
37501
  const fence = getSchemaFenceRejection();
37515
37502
  if (fence) {
37516
- 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));
37517
37504
  }
37518
37505
  }
37519
37506
  if (conflictResult?.hasConflict) {
@@ -37534,7 +37521,7 @@ var server = async (ctx) => {
37534
37521
  } = await import("./announcement-gms2nhya.js");
37535
37522
  if (shouldShowAnnouncement2()) {
37536
37523
  setTimeout(() => {
37537
- 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(() => {});
37538
37525
  }, 8000);
37539
37526
  }
37540
37527
  } catch {}