@cortexkit/opencode-magic-context 0.35.1 → 0.36.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 (77) hide show
  1. package/README.md +9 -5
  2. package/dist/agents/permissions.d.ts +17 -0
  3. package/dist/agents/permissions.d.ts.map +1 -1
  4. package/dist/{announcement-gms2nhya.js → announcement-6c1g4es4.js} +2 -2
  5. package/dist/config/schema/magic-context.d.ts +10 -0
  6. package/dist/config/schema/magic-context.d.ts.map +1 -1
  7. package/dist/{conflict-warning-hook-p2pmhvn7.js → conflict-warning-hook-dw9fs934.js} +4 -4
  8. package/dist/{derive-budgets-9crp0cvd.js → derive-budgets-88mxk2w1.js} +3 -3
  9. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +2 -0
  10. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  11. package/dist/features/magic-context/dreamer/task-executor.d.ts +1 -0
  12. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  13. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  14. package/dist/features/magic-context/smart-notes/condition-compiler.d.ts +37 -0
  15. package/dist/features/magic-context/smart-notes/condition-compiler.d.ts.map +1 -0
  16. package/dist/features/magic-context/smart-notes/runner.d.ts +1 -0
  17. package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
  18. package/dist/features/magic-context/smart-notes/storage.d.ts +3 -3
  19. package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
  20. package/dist/features/magic-context/storage-db.d.ts +1 -1
  21. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  22. package/dist/features/magic-context/storage-notes.d.ts +13 -0
  23. package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
  24. package/dist/features/magic-context/storage.d.ts +1 -1
  25. package/dist/features/magic-context/storage.d.ts.map +1 -1
  26. package/dist/hooks/magic-context/hook.d.ts +3 -0
  27. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  28. package/dist/hooks/magic-context/lkg-slot.d.ts +15 -1
  29. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  30. package/dist/hooks/magic-context/module-state-sync.d.ts +6 -0
  31. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  32. package/dist/hooks/magic-context/module-transport.d.ts +9 -0
  33. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  34. package/dist/hooks/magic-context/raw-fallback-context-limit.d.ts +10 -0
  35. package/dist/hooks/magic-context/raw-fallback-context-limit.d.ts.map +1 -0
  36. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  37. package/dist/hooks/magic-context/rust-mode-transform.d.ts +7 -2
  38. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  39. package/dist/{index-8aaadh98.js → index-37rt2bka.js} +2 -2
  40. package/dist/{index-fkyamz2w.js → index-3nfgbsp4.js} +99 -56
  41. package/dist/{index-w0nygb4p.js → index-3tnkymva.js} +2 -2
  42. package/dist/{index-k1esqfwk.js → index-f1tnb3vm.js} +1 -1
  43. package/dist/{index-kvrcg31b.js → index-mmrhhk9a.js} +8 -1
  44. package/dist/{index-h5zjfesc.js → index-nsx2n9eg.js} +3 -3
  45. package/dist/{index-dmr999a2.js → index-qf20mv7e.js} +1 -1
  46. package/dist/{index-73xz0247.js → index-tsgs7td8.js} +1 -1
  47. package/dist/{index-ry8rh8cv.js → index-wgvxkqpx.js} +5 -4
  48. package/dist/{index-dpdnjawy.js → index-z8v31d85.js} +5 -5
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +781 -116
  51. package/dist/plugin/dream-timer.d.ts +1 -0
  52. package/dist/plugin/dream-timer.d.ts.map +1 -1
  53. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -0
  54. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  55. package/dist/plugin/messages-transform.d.ts +5 -5
  56. package/dist/plugin/messages-transform.d.ts.map +1 -1
  57. package/dist/{recomp-orchestrator-29f4rqax.js → recomp-orchestrator-7wbbvf87.js} +7 -7
  58. package/dist/{safe-notification-target-q9jk5n44.js → safe-notification-target-c11fdda2.js} +3 -3
  59. package/dist/{send-session-notification-sr5g06hz.js → send-session-notification-bgtf4853.js} +4 -4
  60. package/dist/shared/data-path.d.ts +27 -0
  61. package/dist/shared/data-path.d.ts.map +1 -1
  62. package/dist/shared/harness-provider-map.d.ts +23 -20
  63. package/dist/shared/harness-provider-map.d.ts.map +1 -1
  64. package/dist/shared/prompt-surface-runtime.d.ts +15 -2
  65. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
  66. package/dist/{storage-meta-session-ev8b55a9.js → storage-meta-session-kh5egr11.js} +4 -4
  67. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  68. package/package.json +3 -3
  69. package/src/agents/permissions.ts +87 -0
  70. package/src/config/compaction-accessor-guard.test.ts +9 -4
  71. package/src/config/schema/magic-context.test.ts +2 -0
  72. package/src/config/schema/magic-context.ts +15 -0
  73. package/src/shared/data-path.test.ts +65 -9
  74. package/src/shared/data-path.ts +66 -1
  75. package/src/shared/harness-provider-map.test.ts +42 -1
  76. package/src/shared/harness-provider-map.ts +48 -26
  77. package/src/shared/prompt-surface-runtime.ts +13 -5
package/dist/index.js CHANGED
@@ -25,6 +25,14 @@ import {
25
25
  GLOBAL_USER_PROFILE_PROJECT_PATH,
26
26
  HISTORIAN_EDITOR_SYSTEM_PROMPT,
27
27
  LATEST_SUPPORTED_VERSION,
28
+ LKG_SNAPSHOT_ARRAY,
29
+ LKG_SNAPSHOT_BOOLEAN,
30
+ LKG_SNAPSHOT_KEY,
31
+ LKG_SNAPSHOT_NULL,
32
+ LKG_SNAPSHOT_NUMBER,
33
+ LKG_SNAPSHOT_OBJECT,
34
+ LKG_SNAPSHOT_STRING,
35
+ LKG_SNAPSHOT_UNDEFINED,
28
36
  MARKER_SUMMARY_TEXT,
29
37
  MAX_EXECUTE_THRESHOLD,
30
38
  MagicContextConfigSchema,
@@ -230,6 +238,7 @@ import {
230
238
  isPidAlive,
231
239
  isProviderOverflowReconfirmed,
232
240
  lkgContentDigest,
241
+ lkgContentDigestFromFields,
233
242
  loadCompartmentChunkEmbeddingsForSearch,
234
243
  loadPersistedUsage,
235
244
  loadProjectCommitEmbeddings,
@@ -382,7 +391,7 @@ import {
382
391
  upsertCommits,
383
392
  verificationFileExists,
384
393
  withContentLanguageDirective
385
- } from "./index-fkyamz2w.js";
394
+ } from "./index-3nfgbsp4.js";
386
395
  import {
387
396
  deriveHistorianChunkTokens,
388
397
  deriveTriggerBudget,
@@ -394,7 +403,7 @@ import {
394
403
  setOutputReserveConfig,
395
404
  setStoragePrivatePermissionEnforcement,
396
405
  shouldEnforcePrivateStoragePermissions
397
- } from "./index-ry8rh8cv.js";
406
+ } from "./index-wgvxkqpx.js";
398
407
  import {
399
408
  modelBodyField,
400
409
  resolveFallbackChain
@@ -406,7 +415,7 @@ import {
406
415
  getErrorMessage,
407
416
  sendIgnoredMessage,
408
417
  sendUserPrompt
409
- } from "./index-h5zjfesc.js";
418
+ } from "./index-nsx2n9eg.js";
410
419
  import {
411
420
  ToolMutationBatch,
412
421
  advanceToolReclaimWatermark,
@@ -463,7 +472,7 @@ import {
463
472
  textMentionsRecentCommit,
464
473
  updateSessionMeta,
465
474
  withRawSessionMessageCache
466
- } from "./index-dpdnjawy.js";
475
+ } from "./index-z8v31d85.js";
467
476
  import {
468
477
  Database,
469
478
  closeQuietly,
@@ -472,12 +481,12 @@ import {
472
481
  isMidTurn,
473
482
  openCodeDbExists,
474
483
  withReadOnlySessionDb
475
- } from "./index-w0nygb4p.js";
484
+ } from "./index-3tnkymva.js";
476
485
  import {
477
486
  cleanupConflictWarnings,
478
487
  detectConflicts,
479
488
  sendConflictWarning
480
- } from "./index-8aaadh98.js";
489
+ } from "./index-37rt2bka.js";
481
490
  import {
482
491
  detectConfigFile,
483
492
  parseJsonc,
@@ -491,7 +500,7 @@ import {
491
500
  isValidSemver,
492
501
  markAnnouncementSeen,
493
502
  shouldShowAnnouncement
494
- } from "./index-dmr999a2.js";
503
+ } from "./index-qf20mv7e.js";
495
504
  import {
496
505
  acknowledgeNotifications,
497
506
  drainNotifications,
@@ -499,17 +508,17 @@ import {
499
508
  pushNotification,
500
509
  registerNotificationSink
501
510
  } from "./index-d62ypazr.js";
502
- import"./index-73xz0247.js";
511
+ import"./index-tsgs7td8.js";
503
512
  import {
504
513
  log,
505
514
  sessionLog
506
- } from "./index-k1esqfwk.js";
515
+ } from "./index-f1tnb3vm.js";
507
516
  import {
508
517
  getDataDir,
509
518
  getHarness,
510
519
  getMagicContextStorageDir,
511
520
  getOpenCodeStorageDir
512
- } from "./index-kvrcg31b.js";
521
+ } from "./index-mmrhhk9a.js";
513
522
  import {
514
523
  resolvePromptContext
515
524
  } from "./index-szf8w1p5.js";
@@ -8370,6 +8379,49 @@ function buildAllowOnlyPermission(allowedTools, agentLabel) {
8370
8379
  }
8371
8380
  return permission;
8372
8381
  }
8382
+ function isPermissionAction(value) {
8383
+ return value === "ask" || value === "allow" || value === "deny";
8384
+ }
8385
+ function isPermissionMap(value) {
8386
+ return value !== null && typeof value === "object" && !Array.isArray(value);
8387
+ }
8388
+ function denyTaskRoutingToAgents(permission, internalAgentIds) {
8389
+ const configured = isPermissionAction(permission) ? { "*": permission } : isPermissionMap(permission) ? permission : {};
8390
+ const { task, ...otherPermissions } = configured;
8391
+ const configuredTask = isPermissionAction(task) ? { "*": task } : isPermissionMap(task) ? task : {};
8392
+ const internalAgentIdSet = new Set(internalAgentIds);
8393
+ const retainedTask = Object.fromEntries(Object.entries(configuredTask).filter(([agentId]) => !internalAgentIdSet.has(agentId)));
8394
+ return {
8395
+ ...otherPermissions,
8396
+ task: {
8397
+ ...retainedTask,
8398
+ ...Object.fromEntries(internalAgentIds.map((agentId) => [agentId, "deny"]))
8399
+ }
8400
+ };
8401
+ }
8402
+ var BUILTIN_TASK_CALLER_IDS = ["build", "plan"];
8403
+ function isTaskRoutingCaller(agentId, config) {
8404
+ const mode = config.mode;
8405
+ if (mode === "primary")
8406
+ return true;
8407
+ if (mode === "subagent" || mode === "all")
8408
+ return false;
8409
+ return agentId === "build" || agentId === "plan";
8410
+ }
8411
+ function denyTaskRoutingToCallerAgents(agentConfigs, internalAgentIds) {
8412
+ const result = { ...agentConfigs };
8413
+ const candidateIds = new Set([...BUILTIN_TASK_CALLER_IDS, ...Object.keys(agentConfigs)]);
8414
+ for (const agentId of candidateIds) {
8415
+ const agentConfig = agentConfigs[agentId] ?? {};
8416
+ if (!isTaskRoutingCaller(agentId, agentConfig))
8417
+ continue;
8418
+ result[agentId] = {
8419
+ ...agentConfig,
8420
+ permission: denyTaskRoutingToAgents(agentConfig.permission, internalAgentIds)
8421
+ };
8422
+ }
8423
+ return result;
8424
+ }
8373
8425
  function applyDisallowedTools(defaults, disallowed) {
8374
8426
  if (disallowed.includes("*"))
8375
8427
  return [];
@@ -11523,6 +11575,7 @@ var CONNECT_BACKOFF_INITIAL_MS = 1000;
11523
11575
  var CONNECT_BACKOFF_MAX_MS = 30000;
11524
11576
  var HANDSHAKE_TIMEOUT_MS = 2000;
11525
11577
  var MODULE_SEND_TIMEOUT_MS = 15000;
11578
+ var TRANSFORM_SEND_TIMEOUT_MS = 5000;
11526
11579
  var SERIAL_LANE_MAX_WAITERS = 16;
11527
11580
  var SERIAL_LANE_MIN_REMAINING_MS = 25;
11528
11581
  var CANONICAL_ROOT_CACHE_MAX_ENTRIES = 256;
@@ -11558,15 +11611,21 @@ function isConnectionFailure(error) {
11558
11611
  if (error instanceof SocketClosedError || error instanceof SocketTimeoutError || error instanceof StaleRouteHandleError || isConsumerReconnectTransient(error) || isStaleOrDeadRouteFailure(error)) {
11559
11612
  return true;
11560
11613
  }
11561
- return errorChainSome(error, (current) => [
11562
- "ENOENT",
11563
- "ECONNREFUSED",
11564
- "ECONNRESET",
11565
- "EPIPE",
11566
- "ETIMEDOUT",
11567
- "request_deadline",
11568
- "SUBC_CONNECTION_BACKOFF"
11569
- ].includes(typeof current.code === "string" ? current.code : ""));
11614
+ return errorChainSome(error, (current) => {
11615
+ const code = typeof current.code === "string" ? current.code : "";
11616
+ const message = typeof current.message === "string" ? current.message : "";
11617
+ return [
11618
+ "ENOENT",
11619
+ "ECONNREFUSED",
11620
+ "ECONNRESET",
11621
+ "EPIPE",
11622
+ "ETIMEDOUT",
11623
+ "request_deadline",
11624
+ "deadline_exceeded_no_drop_observed",
11625
+ "connection_dropped",
11626
+ "SUBC_CONNECTION_BACKOFF"
11627
+ ].includes(code) || /\bclient closed\b|\bconnection closed\b|\bclosed the connection\b/i.test(message);
11628
+ });
11570
11629
  }
11571
11630
 
11572
11631
  class SubcModuleTransport {
@@ -11584,7 +11643,20 @@ class SubcModuleTransport {
11584
11643
  authorityBindRoot = "";
11585
11644
  backoffMs = CONNECT_BACKOFF_INITIAL_MS;
11586
11645
  connectionGeneration = 0;
11646
+ stateSyncCapabilityCache = null;
11647
+ getCachedStateSyncCapabilities() {
11648
+ const cached = this.stateSyncCapabilityCache;
11649
+ if (!cached || cached.generation !== this.connectionGeneration)
11650
+ return;
11651
+ return cached.capabilities;
11652
+ }
11653
+ invalidateStateSyncCapabilities() {
11654
+ this.stateSyncCapabilityCache = null;
11655
+ }
11587
11656
  async stateSyncCapabilities(args) {
11657
+ const cached = this.getCachedStateSyncCapabilities();
11658
+ if (cached)
11659
+ return cached;
11588
11660
  const response = await this.call({
11589
11661
  sessionId: args.sessionId,
11590
11662
  projectRoot: args.projectRoot,
@@ -11594,7 +11666,9 @@ class SubcModuleTransport {
11594
11666
  const raw = isRecord(response) ? response : {};
11595
11667
  const value = isRecord(raw.result) ? raw.result : raw;
11596
11668
  const epochs = isRecord(value.epochs) ? value.epochs : {};
11597
- return { state_sync_deltas: epochs.state_sync_deltas === true };
11669
+ const capabilities = { state_sync_deltas: epochs.state_sync_deltas === true };
11670
+ this.stateSyncCapabilityCache = { generation: this.connectionGeneration, capabilities };
11671
+ return capabilities;
11598
11672
  }
11599
11673
  constructor(connectionFile, moduleId = DEFAULT_MODULE_ID, requestTimeoutMs = MODULE_SEND_TIMEOUT_MS, routeSessionPrefix = "") {
11600
11674
  this.connectionFile = connectionFile ?? getDefaultConnectionFile();
@@ -11602,11 +11676,31 @@ class SubcModuleTransport {
11602
11676
  this.requestTimeoutMs = requestTimeoutMs;
11603
11677
  this.routeSessionPrefix = routeSessionPrefix;
11604
11678
  }
11605
- laneTimeoutError() {
11606
- const error = new Error("module transport deadline expired while queued");
11679
+ deadlineError(detail) {
11680
+ const error = new Error(`module transport deadline expired ${detail}`);
11607
11681
  error.code = "ETIMEDOUT";
11608
11682
  return error;
11609
11683
  }
11684
+ laneTimeoutError() {
11685
+ return this.deadlineError("while queued");
11686
+ }
11687
+ async beforeDeadline(operation, deadlineMs, detail) {
11688
+ const remainingMs = deadlineMs - Date.now();
11689
+ if (remainingMs <= 0)
11690
+ throw this.deadlineError(detail);
11691
+ let timer;
11692
+ try {
11693
+ return await Promise.race([
11694
+ operation,
11695
+ new Promise((_resolve, reject) => {
11696
+ timer = setTimeout(() => reject(this.deadlineError(detail)), remainingMs);
11697
+ })
11698
+ ]);
11699
+ } finally {
11700
+ if (timer)
11701
+ clearTimeout(timer);
11702
+ }
11703
+ }
11610
11704
  laneRelease() {
11611
11705
  let released = false;
11612
11706
  return () => {
@@ -11684,8 +11778,9 @@ class SubcModuleTransport {
11684
11778
  });
11685
11779
  }
11686
11780
  async call(args) {
11687
- const deadlineMs = Date.now() + (args.timeoutMs ?? this.requestTimeoutMs);
11688
- const releaseLane = await this.acquireCorrectnessLane(args.sessionId, args.signal, deadlineMs);
11781
+ const attemptTimeoutMs = args.timeoutMs ?? (args.method === "transform" ? Math.min(this.requestTimeoutMs, TRANSFORM_SEND_TIMEOUT_MS) : this.requestTimeoutMs);
11782
+ const laneDeadlineMs = Date.now() + attemptTimeoutMs;
11783
+ const releaseLane = await this.acquireCorrectnessLane(args.sessionId, args.signal, laneDeadlineMs);
11689
11784
  const onAbort = () => this.invalidateConnection();
11690
11785
  args.signal?.addEventListener("abort", onAbort, { once: true });
11691
11786
  try {
@@ -11695,21 +11790,18 @@ class SubcModuleTransport {
11695
11790
  if (args.signal?.aborted) {
11696
11791
  throw args.signal.reason ?? new Error("module transport call aborted");
11697
11792
  }
11698
- const remainingMs = deadlineMs - Date.now();
11699
- if (remainingMs < SERIAL_LANE_MIN_REMAINING_MS)
11700
- throw this.laneTimeoutError();
11701
- ensuredRoute = await this.ensureRoute(args.sessionId, args.projectRoot);
11793
+ const attemptDeadlineMs = Date.now() + attemptTimeoutMs;
11794
+ ensuredRoute = await this.ensureRoute(args.sessionId, args.projectRoot, attemptDeadlineMs);
11702
11795
  if (args.signal?.aborted) {
11703
11796
  throw args.signal.reason ?? new Error("module transport call aborted");
11704
11797
  }
11705
- return await ensuredRoute.client.request(ensuredRoute.route, args.body, {
11798
+ return await this.beforeDeadline(ensuredRoute.client.request(ensuredRoute.route, args.body, {
11706
11799
  priority: Priority.Background,
11707
11800
  admissionClass: AdmissionClass.Normal,
11708
- timeoutMs: Math.max(1, deadlineMs - Date.now())
11709
- });
11801
+ timeoutMs: Math.max(1, attemptDeadlineMs - Date.now())
11802
+ }), attemptDeadlineMs, "waiting for the module response");
11710
11803
  } catch (error) {
11711
- const staleOrDeadRoute = isStaleOrDeadRouteFailure(error);
11712
- if (staleOrDeadRoute) {
11804
+ if (isConnectionFailure(error)) {
11713
11805
  if (ensuredRoute) {
11714
11806
  this.dropRoute(ensuredRoute.routeKey, ensuredRoute.route);
11715
11807
  this.invalidateConnection(ensuredRoute.client);
@@ -11718,8 +11810,6 @@ class SubcModuleTransport {
11718
11810
  }
11719
11811
  if (attempt === 0 && !args.signal?.aborted)
11720
11812
  continue;
11721
- } else if (isConnectionFailure(error)) {
11722
- this.invalidateConnection(ensuredRoute?.client);
11723
11813
  }
11724
11814
  throw error;
11725
11815
  }
@@ -11821,7 +11911,7 @@ class SubcModuleTransport {
11821
11911
  this.invalidateConnection(client);
11822
11912
  }
11823
11913
  }
11824
- async ensureRoute(sessionId, rawProjectRoot) {
11914
+ async ensureRoute(sessionId, rawProjectRoot, deadlineMs = Date.now() + this.requestTimeoutMs) {
11825
11915
  const projectRoot = this.canonicalRoot(rawProjectRoot);
11826
11916
  const routeKey = `${sessionId}\x00${projectRoot}`;
11827
11917
  const client = await this.ensureConnected();
@@ -11838,7 +11928,7 @@ class SubcModuleTransport {
11838
11928
  harness: getHarness(),
11839
11929
  session: `${this.routeSessionPrefix}${sessionId}`
11840
11930
  };
11841
- const route = await client.routeOpen(target, identity);
11931
+ const route = await this.beforeDeadline(client.routeOpen(target, identity), deadlineMs, "opening the module route");
11842
11932
  if (this.client !== client || generation !== this.connectionGeneration) {
11843
11933
  await client.closeRoute(route).catch(() => {
11844
11934
  return;
@@ -11915,6 +12005,7 @@ class SubcModuleTransport {
11915
12005
  if (client && this.client && client !== this.client)
11916
12006
  return;
11917
12007
  this.connectionGeneration += 1;
12008
+ this.invalidateStateSyncCapabilities();
11918
12009
  this.client = null;
11919
12010
  this.routes.clear();
11920
12011
  client?.close();
@@ -15068,16 +15159,16 @@ function claimExpectedState(db, expected) {
15068
15159
  WHERE id = ? AND type = 'smart' AND status = 'pending'
15069
15160
  AND content = ? AND surface_condition IS ? AND updated_at = ?${statusClause}`).run(...params).changes > 0;
15070
15161
  }
15071
- function getDueCompiledSmartNoteChecks(db, projectPath, now, limit) {
15072
- return getPendingSmartNotes(db, projectPath).map(toSmartNote).filter((note) => note.checkStatus === "compiled" && note.compiledCheck !== null && note.policyVersion === SMART_NOTE_CHECK_POLICY_VERSION && (note.checkQuarantinedUntil === null || note.checkQuarantinedUntil <= now) && (note.checkNextDueAt === null || note.checkNextDueAt <= now)).sort((a, b) => (a.checkNextDueAt ?? 0) - (b.checkNextDueAt ?? 0) || a.id - b.id).slice(0, Math.max(1, limit));
15162
+ function getDueCompiledSmartNoteChecks(db, projectPath, now, limit, retinaHandoff = false) {
15163
+ return getPendingSmartNotes(db, projectPath).filter((note) => !retinaHandoff || note.compileStatus !== "compiled").map(toSmartNote).filter((note) => note.checkStatus === "compiled" && note.compiledCheck !== null && note.policyVersion === SMART_NOTE_CHECK_POLICY_VERSION && (note.checkQuarantinedUntil === null || note.checkQuarantinedUntil <= now) && (note.checkNextDueAt === null || note.checkNextDueAt <= now)).sort((a, b) => (a.checkNextDueAt ?? 0) - (b.checkNextDueAt ?? 0) || a.id - b.id).slice(0, Math.max(1, limit));
15073
15164
  }
15074
- function getSmartNotesNeedingCompilation(db, projectPath, now, limit) {
15075
- return getPendingSmartNotes(db, projectPath).map(toSmartNote).filter((note) => (note.checkNextDueAt === null || note.checkNextDueAt <= now) && (note.checkStatus === "uncompiled" || note.checkStatus === "failing" || note.compiledCheck === null || note.policyVersion !== SMART_NOTE_CHECK_POLICY_VERSION)).sort((a, b) => a.createdAt - b.createdAt || a.id - b.id).slice(0, Math.max(1, limit));
15165
+ function getSmartNotesNeedingCompilation(db, projectPath, now, limit, retinaHandoff = false) {
15166
+ return getPendingSmartNotes(db, projectPath).filter((note) => !retinaHandoff || note.compileStatus !== "compiled").map(toSmartNote).filter((note) => (note.checkNextDueAt === null || note.checkNextDueAt <= now) && (note.checkStatus === "uncompiled" || note.checkStatus === "failing" || note.compiledCheck === null || note.policyVersion !== SMART_NOTE_CHECK_POLICY_VERSION)).sort((a, b) => a.createdAt - b.createdAt || a.id - b.id).slice(0, Math.max(1, limit));
15076
15167
  }
15077
- function getStaleCompiledSmartNotes(db, projectPath, now, limit) {
15168
+ function getStaleCompiledSmartNotes(db, projectPath, now, limit, retinaHandoff = false) {
15078
15169
  const staleBefore = now - SMART_NOTE_CHECK_MAX_STALENESS_MS;
15079
15170
  const livenessBefore = now - SMART_NOTE_CHECK_LIVENESS_RECHECK_MS;
15080
- return getPendingSmartNotes(db, projectPath).map(toSmartNote).filter((note) => note.checkStatus === "compiled" && note.compiledCheck !== null && note.policyVersion === SMART_NOTE_CHECK_POLICY_VERSION && note.checkFalseSinceAt !== null && note.checkFalseSinceAt <= staleBefore && (note.checkLastLivenessAt === null || note.checkLastLivenessAt <= livenessBefore)).sort((a, b) => (a.checkFalseSinceAt ?? 0) - (b.checkFalseSinceAt ?? 0) || a.id - b.id).slice(0, Math.max(1, limit));
15171
+ return getPendingSmartNotes(db, projectPath).filter((note) => !retinaHandoff || note.compileStatus !== "compiled").map(toSmartNote).filter((note) => note.checkStatus === "compiled" && note.compiledCheck !== null && note.policyVersion === SMART_NOTE_CHECK_POLICY_VERSION && note.checkFalseSinceAt !== null && note.checkFalseSinceAt <= staleBefore && (note.checkLastLivenessAt === null || note.checkLastLivenessAt <= livenessBefore)).sort((a, b) => (a.checkFalseSinceAt ?? 0) - (b.checkFalseSinceAt ?? 0) || a.id - b.id).slice(0, Math.max(1, limit));
15081
15172
  }
15082
15173
  function storeCompiledSmartNoteCheck(db, args) {
15083
15174
  db.prepare(`UPDATE notes
@@ -15173,7 +15264,7 @@ var MAX_FAILURES_BEFORE_REAUTHOR = 3;
15173
15264
  async function runDueCompiledSmartNoteChecks(args) {
15174
15265
  const startedAt = Date.now();
15175
15266
  const now = args.now ?? startedAt;
15176
- const due = getDueCompiledSmartNoteChecks(args.db, args.projectIdentity, now, args.maxChecks ?? DEFAULT_MAX_CHECKS);
15267
+ const due = getDueCompiledSmartNoteChecks(args.db, args.projectIdentity, now, args.maxChecks ?? DEFAULT_MAX_CHECKS, args.retinaHandoff);
15177
15268
  let ran = 0;
15178
15269
  let surfaced = 0;
15179
15270
  let failed = 0;
@@ -15303,7 +15394,8 @@ async function evaluateSmartNotes(args) {
15303
15394
  const projectRoot = args.sessionDirectory ?? args.projectIdentity;
15304
15395
  const moduleBridge = getModuleNoteEvaluationBridge(args.projectIdentity);
15305
15396
  await moduleBridge?.sync();
15306
- const pendingAtStart = getPendingSmartNotes(args.db, args.projectIdentity).length;
15397
+ const pendingNotes = () => getPendingSmartNotes(args.db, args.projectIdentity).filter((note) => !args.retinaHandoff || note.compileStatus !== "compiled");
15398
+ const pendingAtStart = pendingNotes().length;
15307
15399
  if (pendingAtStart === 0) {
15308
15400
  log("[dreamer] smart notes: no pending notes");
15309
15401
  return { surfaced: 0, pending: 0, ran: false };
@@ -15327,7 +15419,7 @@ async function evaluateSmartNotes(args) {
15327
15419
  let didWork = false;
15328
15420
  try {
15329
15421
  if (moduleBridge) {
15330
- const candidates2 = getPendingSmartNotes(args.db, args.projectIdentity).slice(0, MAX_COMPILE_PER_RUN);
15422
+ const candidates2 = pendingNotes().slice(0, MAX_COMPILE_PER_RUN);
15331
15423
  for (const note of candidates2) {
15332
15424
  if (Date.now() >= args.deadline)
15333
15425
  break;
@@ -15348,7 +15440,7 @@ async function evaluateSmartNotes(args) {
15348
15440
  surfaced += 1;
15349
15441
  }
15350
15442
  await moduleBridge.sync();
15351
- const pending2 = getPendingSmartNotes(args.db, args.projectIdentity).length;
15443
+ const pending2 = pendingNotes().length;
15352
15444
  return { surfaced, pending: pending2, ran: didWork };
15353
15445
  }
15354
15446
  const dueRun = await runDueCompiledSmartNoteChecks({
@@ -15358,11 +15450,12 @@ async function evaluateSmartNotes(args) {
15358
15450
  maxChecks: 10,
15359
15451
  sweepBudgetMs: 1e4,
15360
15452
  leaseHeld,
15361
- signal: leaseAbortController.signal
15453
+ signal: leaseAbortController.signal,
15454
+ retinaHandoff: args.retinaHandoff
15362
15455
  });
15363
15456
  surfaced += dueRun.surfaced;
15364
15457
  didWork ||= dueRun.ran > 0;
15365
- const candidates = getSmartNotesNeedingCompilation(args.db, args.projectIdentity, Date.now(), MAX_COMPILE_PER_RUN);
15458
+ const candidates = getSmartNotesNeedingCompilation(args.db, args.projectIdentity, Date.now(), MAX_COMPILE_PER_RUN, args.retinaHandoff);
15366
15459
  for (const note of candidates) {
15367
15460
  if (Date.now() >= args.deadline)
15368
15461
  break;
@@ -15372,7 +15465,7 @@ async function evaluateSmartNotes(args) {
15372
15465
  if (compiled)
15373
15466
  surfaced += 1;
15374
15467
  }
15375
- const stale = getStaleCompiledSmartNotes(args.db, args.projectIdentity, Date.now(), MAX_FALLBACK_PER_RUN);
15468
+ const stale = getStaleCompiledSmartNotes(args.db, args.projectIdentity, Date.now(), MAX_FALLBACK_PER_RUN, args.retinaHandoff);
15376
15469
  for (const note of stale) {
15377
15470
  if (Date.now() >= args.deadline)
15378
15471
  break;
@@ -15382,7 +15475,7 @@ async function evaluateSmartNotes(args) {
15382
15475
  if (met)
15383
15476
  surfaced += 1;
15384
15477
  }
15385
- const fallbackNotes = getPendingSmartNotes(args.db, args.projectIdentity).filter((note) => note.checkStatus === "fallback").slice(0, MAX_FALLBACK_PER_RUN);
15478
+ const fallbackNotes = pendingNotes().filter((note) => note.checkStatus === "fallback").slice(0, MAX_FALLBACK_PER_RUN);
15386
15479
  for (const note of fallbackNotes) {
15387
15480
  if (Date.now() >= args.deadline)
15388
15481
  break;
@@ -17917,7 +18010,8 @@ function createDreamTaskExecutor(deps) {
17917
18010
  leaseKey,
17918
18011
  deadline,
17919
18012
  model: config.model,
17920
- fallbackModels: config.fallbackModels
18013
+ fallbackModels: config.fallbackModels,
18014
+ retinaHandoff: deps.retinaHandoff
17921
18015
  });
17922
18016
  recordRun("completed", null, {
17923
18017
  smartNotesSurfaced: result.surfaced,
@@ -19133,6 +19227,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
19133
19227
  dreamerModel: dreamerConfig.model,
19134
19228
  mural: reg.mural,
19135
19229
  memoryInjectionBudgetTokens: reg.memoryInjectionBudgetTokens,
19230
+ retinaHandoff: reg.retinaHandoff,
19136
19231
  transformMode: reg.transformMode,
19137
19232
  moduleClient: reg.moduleClient,
19138
19233
  onProgress: (progress, completedTask) => reg.onDreamerProgress?.(progress, completedTask)
@@ -19176,7 +19271,8 @@ async function runCompiledSmartNoteSweep(reg, db) {
19176
19271
  const result = await runDueCompiledSmartNoteChecks({
19177
19272
  db,
19178
19273
  projectIdentity: reg.projectIdentity,
19179
- projectRoot: reg.directory
19274
+ projectRoot: reg.directory,
19275
+ retinaHandoff: reg.retinaHandoff
19180
19276
  });
19181
19277
  if (result.ran > 0) {
19182
19278
  log(`[dreamer] compiled smart-note sweep ${reg.projectIdentity}: ran=${result.ran} surfaced=${result.surfaced} logic_failed=${result.failed} network_failed=${result.networkFailed}`);
@@ -25051,7 +25147,7 @@ function readAuthoritySeqMismatch(error) {
25051
25147
  async function syncModuleState(args) {
25052
25148
  let force = args.force;
25053
25149
  const adoption = args.options?.authoritySeqAdoption ?? { used: false };
25054
- let stateSyncDeltas = args.options?.stateSyncDeltas;
25150
+ let stateSyncDeltas = args.options?.stateSyncDeltas ?? args.client.getCachedStateSyncCapabilities?.()?.state_sync_deltas;
25055
25151
  if (stateSyncDeltas === undefined && args.client.stateSyncCapabilities) {
25056
25152
  try {
25057
25153
  stateSyncDeltas = (await args.client.stateSyncCapabilities({
@@ -25110,6 +25206,20 @@ async function syncModuleState(args) {
25110
25206
  }
25111
25207
  }
25112
25208
 
25209
+ // src/hooks/magic-context/raw-fallback-context-limit.ts
25210
+ class RawFallbackContextLimitError extends Error {
25211
+ estimatedTokens;
25212
+ contextLimitTokens;
25213
+ code = "RAW_FALLBACK_CONTEXT_LIMIT";
25214
+ recoverable = true;
25215
+ constructor(estimatedTokens, contextLimitTokens, options) {
25216
+ super(`Magic Context could not safely serve the raw prompt: the best local estimate is ${estimatedTokens.toLocaleString()} tokens, above the known ${contextLimitTokens.toLocaleString()}-token context limit. Retry the turn so the module can reconnect.`, options);
25217
+ this.estimatedTokens = estimatedTokens;
25218
+ this.contextLimitTokens = contextLimitTokens;
25219
+ this.name = "RawFallbackContextLimitError";
25220
+ }
25221
+ }
25222
+
25113
25223
  // src/hooks/magic-context/todo-view.ts
25114
25224
  import { createHash as createHash11 } from "node:crypto";
25115
25225
  var TODO_STATUS_PENDING = "pending";
@@ -29321,34 +29431,26 @@ function updateFnv1a32(hash, value) {
29321
29431
  }
29322
29432
  return next;
29323
29433
  }
29324
- var SNAPSHOT_ARRAY = Symbol("array");
29325
- var SNAPSHOT_OBJECT = Symbol("object");
29326
- var SNAPSHOT_KEY = Symbol("key");
29327
- var SNAPSHOT_STRING = Symbol("string");
29328
- var SNAPSHOT_NUMBER = Symbol("number");
29329
- var SNAPSHOT_BOOLEAN = Symbol("boolean");
29330
- var SNAPSHOT_NULL = Symbol("null");
29331
- var SNAPSHOT_UNDEFINED = Symbol("undefined");
29332
29434
  function isSnapshotObjectChild(value) {
29333
29435
  return value !== undefined && typeof value !== "function" && typeof value !== "symbol";
29334
29436
  }
29335
29437
  function visitMessageContentFields(value, visitor) {
29336
29438
  if (value === null)
29337
- return visitor.field(SNAPSHOT_NULL);
29439
+ return visitor.field(LKG_SNAPSHOT_NULL);
29338
29440
  if (typeof value === "string") {
29339
- return visitor.field(SNAPSHOT_STRING) && visitor.field(value);
29441
+ return visitor.field(LKG_SNAPSHOT_STRING) && visitor.field(value);
29340
29442
  }
29341
29443
  if (typeof value === "number") {
29342
- return visitor.field(SNAPSHOT_NUMBER) && visitor.field(value);
29444
+ return visitor.field(LKG_SNAPSHOT_NUMBER) && visitor.field(value);
29343
29445
  }
29344
29446
  if (typeof value === "boolean") {
29345
- return visitor.field(SNAPSHOT_BOOLEAN) && visitor.field(value);
29447
+ return visitor.field(LKG_SNAPSHOT_BOOLEAN) && visitor.field(value);
29346
29448
  }
29347
29449
  if (value === undefined || typeof value === "function" || typeof value === "symbol") {
29348
- return visitor.field(SNAPSHOT_UNDEFINED);
29450
+ return visitor.field(LKG_SNAPSHOT_UNDEFINED);
29349
29451
  }
29350
29452
  if (Array.isArray(value)) {
29351
- if (!visitor.field(SNAPSHOT_ARRAY) || !visitor.field(value.length))
29453
+ if (!visitor.field(LKG_SNAPSHOT_ARRAY) || !visitor.field(value.length))
29352
29454
  return false;
29353
29455
  for (const item of value) {
29354
29456
  if (!visitMessageContentFields(item, visitor))
@@ -29357,7 +29459,7 @@ function visitMessageContentFields(value, visitor) {
29357
29459
  return true;
29358
29460
  }
29359
29461
  if (typeof value === "object") {
29360
- if (!visitor.field(SNAPSHOT_OBJECT))
29462
+ if (!visitor.field(LKG_SNAPSHOT_OBJECT))
29361
29463
  return false;
29362
29464
  const objectToken = visitor.beginObject();
29363
29465
  if (objectToken === undefined)
@@ -29370,13 +29472,13 @@ function visitMessageContentFields(value, visitor) {
29370
29472
  if (!isSnapshotObjectChild(child))
29371
29473
  continue;
29372
29474
  entryCount += 1;
29373
- if (!visitor.field(SNAPSHOT_KEY) || !visitor.field(key) || !visitMessageContentFields(child, visitor)) {
29475
+ if (!visitor.field(LKG_SNAPSHOT_KEY) || !visitor.field(key) || !visitMessageContentFields(child, visitor)) {
29374
29476
  return false;
29375
29477
  }
29376
29478
  }
29377
29479
  return visitor.endObject(objectToken, entryCount);
29378
29480
  }
29379
- return visitor.field(SNAPSHOT_UNDEFINED);
29481
+ return visitor.field(LKG_SNAPSHOT_UNDEFINED);
29380
29482
  }
29381
29483
  function messageContentFields(message) {
29382
29484
  const fields = [];
@@ -29587,7 +29689,10 @@ function ensureState(states, sessionId) {
29587
29689
  memoryAuthorityProject: null,
29588
29690
  memoryAuthorityRoot: null,
29589
29691
  memoryAuthorityReady: false,
29590
- authorityMemorySyncSkipLogged: false
29692
+ authorityMemorySyncSkipLogged: false,
29693
+ lkgCaptureSequence: 0,
29694
+ lkgLastCapturedRowVersion: 0,
29695
+ lkgSyncCaptureRequired: false
29591
29696
  };
29592
29697
  states.set(sessionId, state);
29593
29698
  }
@@ -29901,6 +30006,7 @@ function buildTransformBody(args) {
29901
30006
  function createRustModeTransform(deps, options) {
29902
30007
  const states = new Map;
29903
30008
  const wireCaches = new Map;
30009
+ const scheduleLkgCapture = options.scheduleLkgCapture ?? ((capture) => setImmediate(capture));
29904
30010
  const timeoutMs = Math.max(1, options.moduleTimeoutMs ?? RUST_SEND_TIMEOUT_MS);
29905
30011
  const logStage = (sessionId, stage, startedAt, timings, extra) => {
29906
30012
  const elapsed = Math.max(0, performance.now() - startedAt);
@@ -30019,28 +30125,50 @@ function createRustModeTransform(deps, options) {
30019
30125
  sessionLog(sessionId, "lkg_replay_served");
30020
30126
  return true;
30021
30127
  };
30022
- const captureRustResponse = (sessionId, input, response) => {
30023
- const ids = input.map((message) => message.info.id);
30024
- if (ids.some((id) => typeof id !== "string") || new Set(ids).size !== ids.length || ids.length === 0) {
30025
- return false;
30128
+ const prepareRustCapture = (state, sessionId, input, inputSnapshots, response, responseRowVersion) => {
30129
+ state.lkgCaptureSequence += 1;
30130
+ const inputIds = input.map((message) => message.info.id);
30131
+ if (inputIds.some((id) => typeof id !== "string") || new Set(inputIds).size !== inputIds.length || inputIds.length === 0 || inputSnapshots.length !== inputIds.length) {
30132
+ return null;
30026
30133
  }
30027
- const inputContentDigests = input.map((message) => lkgContentDigest(message));
30028
- if (inputContentDigests.some((digest) => digest === null))
30029
- return false;
30030
30134
  const native = response.native_messages;
30031
30135
  const jsonPrefix = typeof native === "string" ? native : JSON.stringify(native);
30032
30136
  if (typeof jsonPrefix !== "string")
30033
- return false;
30137
+ return null;
30034
30138
  const keys = resolveLkgModelKeys(input);
30035
- return captureSlot(sessionId, {
30139
+ return {
30140
+ sessionId,
30141
+ inputIds,
30142
+ inputSnapshots,
30036
30143
  jsonPrefix,
30037
- inputIdSeq: ids,
30038
- inputContentDigests,
30039
- lastInputMessageId: ids[ids.length - 1],
30040
30144
  modelKey: keys.modelKey,
30041
30145
  providerKey: keys.providerKey,
30042
- capturedAt: Date.now()
30146
+ capturedAt: Date.now(),
30147
+ rowVersion: responseRowVersion,
30148
+ captureSequence: state.lkgCaptureSequence
30149
+ };
30150
+ };
30151
+ const commitRustCapture = (state, plan) => {
30152
+ if (states.get(plan.sessionId) !== state || plan.captureSequence !== state.lkgCaptureSequence || plan.rowVersion < state.lkgLastCapturedRowVersion) {
30153
+ return "superseded";
30154
+ }
30155
+ const inputContentDigests = plan.inputSnapshots.map((snapshot) => lkgContentDigestFromFields(snapshot.fields));
30156
+ const captured = captureSlot(plan.sessionId, {
30157
+ jsonPrefix: plan.jsonPrefix,
30158
+ inputIdSeq: plan.inputIds,
30159
+ inputContentDigests,
30160
+ lastInputMessageId: plan.inputIds[plan.inputIds.length - 1],
30161
+ modelKey: plan.modelKey,
30162
+ providerKey: plan.providerKey,
30163
+ capturedAt: plan.capturedAt,
30164
+ rowVersion: plan.rowVersion,
30165
+ captureSequence: plan.captureSequence
30043
30166
  });
30167
+ if (!captured)
30168
+ throw new Error("LKG slot rejected the prepared snapshot");
30169
+ state.lkgLastCapturedRowVersion = plan.rowVersion;
30170
+ state.lkgSyncCaptureRequired = false;
30171
+ return "captured";
30044
30172
  };
30045
30173
  const run = async (sessionId, messages, output, sessionMeta) => {
30046
30174
  const passStartedAt = performance.now();
@@ -30098,6 +30226,30 @@ function createRustModeTransform(deps, options) {
30098
30226
  const hasProviderProof = overflowState.detectedContextLimit > 0 && detectedLimitMatchesModel || isProviderOverflowReconfirmed(sessionId);
30099
30227
  emergencyFailClosed ||= overflowState.needsEmergencyRecovery && overflowState.emergencyRecoveryOrigin === "provider_overflow" && hasProviderProof;
30100
30228
  }
30229
+ const serveRawFallback = (cause) => {
30230
+ const contextLimit = resolvedContextLimit ?? (overflowState && overflowState.detectedContextLimit > 0 ? overflowState.detectedContextLimit : undefined);
30231
+ if (contextLimit !== undefined) {
30232
+ try {
30233
+ const estimate = estimateFinalWireInputTokens({
30234
+ messages,
30235
+ systemPromptTokens: sessionMeta.systemPromptTokens,
30236
+ providerID: model?.providerID,
30237
+ modelID: model?.modelID,
30238
+ agentName: deps.getNotificationParams?.(sessionId)?.agent
30239
+ });
30240
+ if (estimate.tokens > contextLimit) {
30241
+ sessionLog(sessionId, `raw_fallback_over_context_limit estimated=${estimate.tokens} limit=${contextLimit}`);
30242
+ throw new RawFallbackContextLimitError(estimate.tokens, contextLimit, {
30243
+ cause
30244
+ });
30245
+ }
30246
+ } catch (error) {
30247
+ if (error instanceof RawFallbackContextLimitError)
30248
+ throw error;
30249
+ }
30250
+ }
30251
+ replaceMessagesInPlace(output, messages);
30252
+ };
30101
30253
  const finishPass = (applied, served = true) => {
30102
30254
  const elapsedAt = applied && appliedAt !== undefined ? appliedAt : performance.now();
30103
30255
  const elapsedMs = Math.max(0, elapsedAt - passStartedAt);
@@ -30128,11 +30280,19 @@ function createRustModeTransform(deps, options) {
30128
30280
  servedFrom = typeof response.served_from === "string" ? response.served_from : "unknown";
30129
30281
  materializeReason = typeof response.materialize_reason === "string" && response.materialize_reason.length > 0 ? response.materialize_reason : "none";
30130
30282
  const timings2 = isRecord3(response.timings) ? response.timings : undefined;
30131
- const total = timings2?.total;
30132
- moduleElapsedMs = typeof total === "number" && Number.isFinite(total) ? total : 0;
30283
+ const applyOnceTotal = timings2?.total;
30284
+ const handlerTotal = timings2?.handler_total;
30285
+ moduleElapsedMs = typeof handlerTotal === "number" && Number.isFinite(handlerTotal) ? handlerTotal : typeof applyOnceTotal === "number" && Number.isFinite(applyOnceTotal) ? applyOnceTotal : 0;
30133
30286
  rowVersion = typeof response.row_version === "number" && Number.isSafeInteger(response.row_version) ? response.row_version : 0;
30287
+ if (timings2 && (typeof timings2.handler_total === "number" || typeof timings2.native_cache_reused_messages === "number" || typeof timings2.native_cache_encoded_messages === "number")) {
30288
+ const stage = (name) => {
30289
+ const value = timings2[name];
30290
+ return typeof value === "number" && Number.isFinite(value) ? value.toFixed(1) : "n/a";
30291
+ };
30292
+ sessionLog(sessionId, `rust module stages: handler=${stage("handler_total")} apply_once=${stage("total")} ` + `request_to_handler=${stage("request_observed_to_handler")} ` + `projection=${stage("projection")} selection=${stage("selection")} ` + `build_output=${stage("build_output")} store_commit=${stage("store_commit")} ` + `post_attach=${stage("post_attach")} response_encode=${stage("response_encode")} ` + `native_cache_reused=${stage("native_cache_reused_messages")} ` + `native_cache_encoded=${stage("native_cache_encoded_messages")}`);
30293
+ }
30134
30294
  if (timings2 && moduleElapsedMs >= 1000) {
30135
- const detail = Object.entries(timings2).filter(([key, value]) => key !== "total" && typeof value === "number").map(([key, value]) => `${key}:${value.toFixed(1)}`).join(" ");
30295
+ const detail = Object.entries(timings2).filter(([key, value]) => key !== "total" && key !== "handler_total" && typeof value === "number").map(([key, value]) => `${key}:${value.toFixed(1)}`).join(" ");
30136
30296
  if (detail)
30137
30297
  sessionLog(sessionId, `rust module stages (slow pass): ${detail}`);
30138
30298
  }
@@ -30146,7 +30306,12 @@ function createRustModeTransform(deps, options) {
30146
30306
  servedFrom = "lkg";
30147
30307
  } else {
30148
30308
  servedFrom = "raw";
30149
- replaceMessagesInPlace(output, messages);
30309
+ try {
30310
+ serveRawFallback();
30311
+ } catch (error) {
30312
+ finishPass(false, false);
30313
+ throw error;
30314
+ }
30150
30315
  }
30151
30316
  finishPass(false);
30152
30317
  return;
@@ -30306,10 +30471,12 @@ function createRustModeTransform(deps, options) {
30306
30471
  };
30307
30472
  }
30308
30473
  }
30474
+ const getCachedStateSyncCapabilities = options.moduleClient.getCachedStateSyncCapabilities;
30309
30475
  const stateSyncCapabilities = options.moduleClient.stateSyncCapabilities;
30310
30476
  const stateSyncResult = await syncModuleState({
30311
30477
  client: {
30312
30478
  call: callModule,
30479
+ getCachedStateSyncCapabilities: getCachedStateSyncCapabilities ? () => getCachedStateSyncCapabilities.call(options.moduleClient) : undefined,
30313
30480
  stateSyncCapabilities: stateSyncCapabilities ? (capabilityArgs) => stateSyncCapabilities.call(options.moduleClient, capabilityArgs) : undefined
30314
30481
  },
30315
30482
  state,
@@ -30434,6 +30601,7 @@ function createRustModeTransform(deps, options) {
30434
30601
  throw new Error("rust module returned no transform response");
30435
30602
  captureResponseTelemetry(response);
30436
30603
  if (isNeedFullSync(response)) {
30604
+ options.moduleClient.invalidateStateSyncCapabilities?.();
30437
30605
  state.forceFullWire = true;
30438
30606
  if (wireDelta) {
30439
30607
  const retryOrdinalStartedAt = performance.now();
@@ -30587,13 +30755,43 @@ function createRustModeTransform(deps, options) {
30587
30755
  }
30588
30756
  logStage(sessionId, "apply", applyStartedAt, timings);
30589
30757
  const lkgSnapshotStartedAt = performance.now();
30590
- if (cacheBustingPass || !getSlot(sessionId)) {
30591
- const captured = captureRustResponse(sessionId, messages, response);
30592
- if (cacheBustingPass && !captured) {
30593
- dropSlot(sessionId, "lkg_refresh_declined");
30758
+ const capturePlan = prepareRustCapture(state, sessionId, messages, pendingWireCache.rawContentSnapshots, response, rowVersion);
30759
+ let captureMode = "async";
30760
+ const captureFailed = (mode, error) => {
30761
+ if (states.get(sessionId) !== state || capturePlan && capturePlan.captureSequence !== state.lkgCaptureSequence) {
30762
+ return;
30763
+ }
30764
+ dropSlot(sessionId, `lkg_${mode}_capture_failed`);
30765
+ state.lkgSyncCaptureRequired = true;
30766
+ sessionLog(sessionId, `LKG ${mode.toUpperCase()} CAPTURE FAILED; forcing synchronous capture on the next applied pass:`, error);
30767
+ };
30768
+ if (!capturePlan) {
30769
+ captureMode = "declined";
30770
+ captureFailed("async", new Error("LKG snapshot preparation was rejected"));
30771
+ } else if (state.lkgSyncCaptureRequired) {
30772
+ captureMode = "sync_recovery";
30773
+ try {
30774
+ commitRustCapture(state, capturePlan);
30775
+ } catch (error) {
30776
+ captureFailed("sync", error);
30777
+ }
30778
+ } else {
30779
+ try {
30780
+ scheduleLkgCapture(() => {
30781
+ const asyncStartedAt = performance.now();
30782
+ try {
30783
+ const result = commitRustCapture(state, capturePlan);
30784
+ logTransformTiming(sessionId, "rust.lkg_snapshot_async", asyncStartedAt, `result=${result} row_version=${capturePlan.rowVersion}`);
30785
+ } catch (error) {
30786
+ captureFailed("async", error);
30787
+ }
30788
+ });
30789
+ } catch (error) {
30790
+ captureMode = "schedule_failed";
30791
+ captureFailed("async", error);
30594
30792
  }
30595
30793
  }
30596
- logStage(sessionId, "lkgSnapshot", lkgSnapshotStartedAt, timings, cacheBustingPass ? "captured=true" : "captured=false");
30794
+ logStage(sessionId, "lkgSnapshot", lkgSnapshotStartedAt, timings, `mode=${captureMode} row_version=${rowVersion}`);
30597
30795
  const applyReplaceStartedAt = performance.now();
30598
30796
  replaceMessagesInPlace(output, appliedMessages);
30599
30797
  logStage(sessionId, "apply", applyReplaceStartedAt, timings);
@@ -30700,13 +30898,19 @@ function createRustModeTransform(deps, options) {
30700
30898
  throw new EmergencyFailClosedError("Rust Magic Context was unavailable at a provider-proven context limit", { cause: error });
30701
30899
  }
30702
30900
  const replayed = replayLastGood(sessionId, messages, output, sessionMeta.systemPromptTokens);
30703
- if (!replayed)
30704
- replaceMessagesInPlace(output, messages);
30705
30901
  servedFrom = replayed ? "lkg" : "raw";
30706
30902
  if (decision.toLowerCase() !== "need_full_sync")
30707
30903
  decision = "error";
30708
30904
  materializeReason = "none";
30709
30905
  markFailure(sessionId, state, error);
30906
+ if (!replayed) {
30907
+ try {
30908
+ serveRawFallback(error);
30909
+ } catch (rawFallbackError) {
30910
+ finishPass(false, false);
30911
+ throw rawFallbackError;
30912
+ }
30913
+ }
30710
30914
  finishPass(false);
30711
30915
  return;
30712
30916
  }
@@ -34130,6 +34334,7 @@ function createMagicContextHook(deps) {
34130
34334
  }),
34131
34335
  userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreaming),
34132
34336
  language: deps.config.language,
34337
+ retinaHandoff: deps.config.smart_notes?.retina_handoff === true,
34133
34338
  transformMode: deps.config.transform_mode,
34134
34339
  moduleClient: rustModeModuleClient,
34135
34340
  onProgress: (progress, completedTask) => {
@@ -34215,6 +34420,7 @@ function createMagicContextHook(deps) {
34215
34420
  language: deps.config.language,
34216
34421
  mural: deps.config.mural,
34217
34422
  memoryInjectionBudgetTokens: deps.config.memory?.injection_budget_tokens,
34423
+ retinaHandoff: deps.config.smart_notes?.retina_handoff === true,
34218
34424
  transformMode: deps.config.transform_mode,
34219
34425
  moduleClient: rustModeModuleClient,
34220
34426
  onProgress: (progress, completedTask) => {
@@ -34443,6 +34649,8 @@ function createMessagesTransformHandler(args) {
34443
34649
  await magicContext?.["experimental.chat.messages.transform"]?.(input, output);
34444
34650
  return output.messages;
34445
34651
  } catch (error) {
34652
+ if (error instanceof RawFallbackContextLimitError)
34653
+ throw error;
34446
34654
  if (error instanceof EmergencyFailClosedError || isFailClosedBlockingError(error)) {
34447
34655
  if (!args.compactionOff)
34448
34656
  throw error;
@@ -35182,7 +35390,7 @@ function registerRpcHandlers(rpcServer, args) {
35182
35390
  }
35183
35391
  });
35184
35392
  const buildManagedCtx = async (db) => {
35185
- const { deriveHistorianChunkTokens: deriveHistorianChunkTokens2, resolveHistorianContextLimit: resolveHistorianContextLimit2 } = await import("./derive-budgets-9crp0cvd.js");
35393
+ const { deriveHistorianChunkTokens: deriveHistorianChunkTokens2, resolveHistorianContextLimit: resolveHistorianContextLimit2 } = await import("./derive-budgets-88mxk2w1.js");
35186
35394
  const { resolveFallbackChain: resolveFallbackChain2 } = await import("./resolve-fallbacks-5n5tvge1.js");
35187
35395
  const { userMemoryCollectionEnabled: userMemoryCollectionEnabled2 } = await import("./task-config-gbp7r23g.js");
35188
35396
  const DEFAULT_HISTORIAN_TIMEOUT_MS2 = 600000;
@@ -35209,8 +35417,8 @@ function registerRpcHandlers(rpcServer, args) {
35209
35417
  const db = getDb();
35210
35418
  if (!db)
35211
35419
  return { ok: false, error: "db unavailable" };
35212
- const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-29f4rqax.js");
35213
- const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-sr5g06hz.js");
35420
+ const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-7wbbvf87.js");
35421
+ const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bgtf4853.js");
35214
35422
  log(`[rpc] recomp requested for session ${sessionId}`);
35215
35423
  const ctx = await buildManagedCtx(db);
35216
35424
  runManagedRecomp2(ctx, sessionId).then((message) => {
@@ -35225,8 +35433,8 @@ function registerRpcHandlers(rpcServer, args) {
35225
35433
  const db = getDb();
35226
35434
  if (!db)
35227
35435
  return { ok: false, error: "db unavailable" };
35228
- const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-29f4rqax.js");
35229
- const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-sr5g06hz.js");
35436
+ const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-7wbbvf87.js");
35437
+ const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bgtf4853.js");
35230
35438
  log(`[rpc] session-upgrade requested for session ${sessionId}`);
35231
35439
  const ctx = await buildManagedCtx(db);
35232
35440
  runManagedUpgrade2(ctx, sessionId).then((message) => {
@@ -35242,7 +35450,7 @@ function registerRpcHandlers(rpcServer, args) {
35242
35450
  if (!db)
35243
35451
  return { ok: false, error: "db unavailable" };
35244
35452
  try {
35245
- const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-ev8b55a9.js");
35453
+ const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-kh5egr11.js");
35246
35454
  updateSessionMeta2(db, sessionId, { upgradeRemindedAt: Date.now() });
35247
35455
  return { ok: true };
35248
35456
  } catch (error) {
@@ -36198,6 +36406,447 @@ Smart notes: pass surface_condition and the note stays hidden until a background
36198
36406
  Example: ctx_note(action="write", content="Re-run the perf benchmark once the boundary rework ships", surface_condition="When the latest release tag is >= v0.23.0")`;
36199
36407
  // src/tools/ctx-note/tools.ts
36200
36408
  import { tool as tool3 } from "@opencode-ai/plugin";
36409
+
36410
+ // src/features/magic-context/smart-notes/condition-compiler.ts
36411
+ import { existsSync as existsSync11 } from "node:fs";
36412
+ import { isAbsolute as isAbsolute4 } from "node:path";
36413
+
36414
+ // ../retina-local-fs/src/path-fence.ts
36415
+ import { lstat as lstat2, readlink, realpath as realpath2 } from "node:fs/promises";
36416
+ import { homedir as homedir4 } from "node:os";
36417
+ import { basename, dirname as dirname4, isAbsolute as isAbsolute3, join as join6, relative, resolve as resolve3, sep } from "node:path";
36418
+
36419
+ // ../retina-local-fs/src/errors.ts
36420
+ class ProviderError extends Error {
36421
+ code;
36422
+ constructor(code, message) {
36423
+ super(message);
36424
+ this.code = code;
36425
+ this.name = "ProviderError";
36426
+ }
36427
+ }
36428
+
36429
+ // ../retina-local-fs/src/path-fence.ts
36430
+ async function resolveAndFenceProviderPath(configuredPath, options) {
36431
+ const configuredHomePath = resolve3(options.homeDirectory ?? process.env.HOME ?? homedir4());
36432
+ let home;
36433
+ try {
36434
+ home = await realpath2(configuredHomePath);
36435
+ } catch (error) {
36436
+ throw fsError(configuredHomePath, error);
36437
+ }
36438
+ const expanded = configuredPath.startsWith("~/") ? join6(home, configuredPath.slice(2)) : configuredPath === "~" ? home : configuredPath;
36439
+ const absolute = isAbsolute3(expanded) ? resolve3(expanded) : resolve3(options.cwd ?? process.cwd(), expanded);
36440
+ const canonical = await canonicalPath(absolute, options.allowMissing);
36441
+ if (isFencedPath(canonical, home)) {
36442
+ throw new ProviderError("fenced_path", `Refusing fenced path: ${canonical}`);
36443
+ }
36444
+ return canonical;
36445
+ }
36446
+ async function canonicalPath(path6, allowMissing) {
36447
+ try {
36448
+ return await realpath2(path6);
36449
+ } catch (error) {
36450
+ if (!allowMissing || !isMissingError(error)) {
36451
+ throw fsError(path6, error);
36452
+ }
36453
+ const suffix = [];
36454
+ let candidate = path6;
36455
+ while (true) {
36456
+ try {
36457
+ const metadata = await lstat2(candidate);
36458
+ if (metadata.isSymbolicLink()) {
36459
+ const target = await readlink(candidate);
36460
+ const resolvedTarget = resolve3(dirname4(candidate), target);
36461
+ return canonicalPath(join6(resolvedTarget, ...suffix), true);
36462
+ }
36463
+ } catch (candidateError) {
36464
+ if (!isMissingError(candidateError)) {
36465
+ throw fsError(path6, candidateError);
36466
+ }
36467
+ }
36468
+ const parent = dirname4(candidate);
36469
+ if (parent === candidate) {
36470
+ throw fsError(path6, error);
36471
+ }
36472
+ suffix.unshift(basename(candidate));
36473
+ candidate = parent;
36474
+ try {
36475
+ return join6(await realpath2(candidate), ...suffix);
36476
+ } catch (parentError) {
36477
+ if (!isMissingError(parentError)) {
36478
+ throw fsError(path6, parentError);
36479
+ }
36480
+ }
36481
+ }
36482
+ }
36483
+ }
36484
+ function isFencedPath(canonicalPath2, homeDirectory) {
36485
+ const home = resolve3(homeDirectory);
36486
+ const cortexkitRoot = join6(home, ".local", "share", "cortexkit");
36487
+ const relativeToCortexkit = relative(cortexkitRoot, canonicalPath2);
36488
+ const insideCortexkit = relativeToCortexkit !== "" && relativeToCortexkit !== ".." && !relativeToCortexkit.startsWith(`..${sep}`) && !isAbsolute3(relativeToCortexkit);
36489
+ const parts = insideCortexkit ? relativeToCortexkit.split(sep) : [];
36490
+ const pathParts = canonicalPath2.split(sep).filter(Boolean);
36491
+ const name = basename(canonicalPath2);
36492
+ const catalogDirectoryCarveIn = pathParts.includes("catalog");
36493
+ const moduleBinCarveIn = parts.length >= 2 && parts[1] === "bin";
36494
+ const catalogJsonCarveIn = name.endsWith(".json") && name.includes("catalog");
36495
+ if (catalogDirectoryCarveIn || moduleBinCarveIn || catalogJsonCarveIn) {
36496
+ return false;
36497
+ }
36498
+ const inFencedRoot = insideCortexkit && ["plexus", "claustrum", "staging"].includes(parts[0] ?? "");
36499
+ const fencedBasename = name.includes("binding-key") || name.endsWith(".handle");
36500
+ const plexusStore = insideCortexkit && parts[0] === "plexus" && name.startsWith("store.db");
36501
+ return inFencedRoot || fencedBasename || plexusStore;
36502
+ }
36503
+ function fsError(path6, error) {
36504
+ const message = error instanceof Error ? error.message : String(error);
36505
+ return new ProviderError("unreadable_path", `Could not read ${path6}: ${message}`);
36506
+ }
36507
+ function isMissingError(error) {
36508
+ return error !== null && typeof error === "object" && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
36509
+ }
36510
+
36511
+ // ../retina-local-fs/src/provider.ts
36512
+ import { execFile as execFile3 } from "node:child_process";
36513
+ import { promisify as promisify3 } from "node:util";
36514
+ var execFileAsync3 = promisify3(execFile3);
36515
+ function parseSemver(value) {
36516
+ const match = /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(value);
36517
+ if (!match) {
36518
+ throw new ProviderError("invalid_config", `Invalid semantic version: ${value}`);
36519
+ }
36520
+ return {
36521
+ major: Number(match[1]),
36522
+ minor: Number(match[2]),
36523
+ patch: Number(match[3]),
36524
+ prerelease: match[4] ? match[4].split(".").map((part) => /^\d+$/.test(part) ? Number(part) : part) : []
36525
+ };
36526
+ }
36527
+ function validateProviderConfig(input) {
36528
+ try {
36529
+ return { success: true, config: parseConfig(input) };
36530
+ } catch (error) {
36531
+ return {
36532
+ success: false,
36533
+ reason: error instanceof Error ? error.message : String(error)
36534
+ };
36535
+ }
36536
+ }
36537
+ function parseConfig(value) {
36538
+ const config = requireObject(value, "config");
36539
+ if ("any" in config) {
36540
+ requireOnlyKeys(config, ["any"], "compound config");
36541
+ if (!Array.isArray(config.any) || config.any.length < 1 || config.any.length > 4) {
36542
+ invalid("config.any must contain between 1 and 4 predicates");
36543
+ }
36544
+ return { any: config.any.map(parseAtomicPredicate) };
36545
+ }
36546
+ return parseAtomicPredicate(config);
36547
+ }
36548
+ function parseAtomicPredicate(value) {
36549
+ const predicate = requireObject(value, "predicate");
36550
+ if (typeof predicate.kind !== "string") {
36551
+ invalid("predicate.kind must be a string");
36552
+ }
36553
+ switch (predicate.kind) {
36554
+ case "file_contains":
36555
+ requireOnlyKeys(predicate, ["kind", "path", "needle", "absent", "resolved_path_exists"], predicate.kind);
36556
+ return {
36557
+ kind: predicate.kind,
36558
+ path: requireString(predicate.path, "path"),
36559
+ needle: requireString(predicate.needle, "needle", true),
36560
+ ...optionalBoolean(predicate.absent, "absent") === undefined ? {} : { absent: predicate.absent },
36561
+ ...predicateAudit(predicate)
36562
+ };
36563
+ case "path_exists":
36564
+ requireOnlyKeys(predicate, ["kind", "path", "gone", "resolved_path_exists"], predicate.kind);
36565
+ return {
36566
+ kind: predicate.kind,
36567
+ path: requireString(predicate.path, "path"),
36568
+ ...optionalBoolean(predicate.gone, "gone") === undefined ? {} : { gone: predicate.gone },
36569
+ ...predicateAudit(predicate)
36570
+ };
36571
+ case "mtime_after":
36572
+ requireOnlyKeys(predicate, ["kind", "path", "since_ms", "resolved_path_exists"], predicate.kind);
36573
+ return {
36574
+ kind: predicate.kind,
36575
+ path: requireString(predicate.path, "path"),
36576
+ since_ms: requireFiniteNumber(predicate.since_ms, "since_ms"),
36577
+ ...predicateAudit(predicate)
36578
+ };
36579
+ case "git_commit_after":
36580
+ requireOnlyKeys(predicate, ["kind", "repo_path", "ref", "sha", "resolved_path_exists"], predicate.kind);
36581
+ return {
36582
+ kind: predicate.kind,
36583
+ repo_path: requireString(predicate.repo_path, "repo_path"),
36584
+ sha: requireString(predicate.sha, "sha"),
36585
+ ...predicate.ref === undefined ? {} : { ref: requireString(predicate.ref, "ref") },
36586
+ ...predicateAudit(predicate)
36587
+ };
36588
+ case "git_tag_matching": {
36589
+ requireOnlyKeys(predicate, ["kind", "repo_path", "pattern", "above", "resolved_path_exists"], predicate.kind);
36590
+ const above = predicate.above === undefined ? undefined : requireString(predicate.above, "above");
36591
+ if (above !== undefined) {
36592
+ parseSemver(above);
36593
+ }
36594
+ return {
36595
+ kind: predicate.kind,
36596
+ repo_path: requireString(predicate.repo_path, "repo_path"),
36597
+ pattern: requireString(predicate.pattern, "pattern"),
36598
+ ...above === undefined ? {} : { above },
36599
+ ...predicateAudit(predicate)
36600
+ };
36601
+ }
36602
+ default:
36603
+ invalid(`Unsupported predicate kind: ${predicate.kind}`);
36604
+ }
36605
+ }
36606
+ function requireObject(value, field) {
36607
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
36608
+ invalid(`${field} must be an object`);
36609
+ }
36610
+ return value;
36611
+ }
36612
+ function requireOnlyKeys(value, allowed, field) {
36613
+ const unknown = Object.keys(value).filter((key) => !allowed.includes(key));
36614
+ if (unknown.length > 0) {
36615
+ invalid(`${field} contains unknown field(s): ${unknown.join(", ")}`);
36616
+ }
36617
+ }
36618
+ function requireString(value, field, allowEmpty = false) {
36619
+ if (typeof value !== "string" || !allowEmpty && value.length === 0) {
36620
+ invalid(`${field} must be ${allowEmpty ? "a string" : "a non-empty string"}`);
36621
+ }
36622
+ return value;
36623
+ }
36624
+ function predicateAudit(predicate) {
36625
+ const exists = optionalBoolean(predicate.resolved_path_exists, "resolved_path_exists");
36626
+ return exists === undefined ? {} : { resolved_path_exists: exists };
36627
+ }
36628
+ function optionalBoolean(value, field) {
36629
+ if (value !== undefined && typeof value !== "boolean") {
36630
+ invalid(`${field} must be a boolean`);
36631
+ }
36632
+ return value;
36633
+ }
36634
+ function requireFiniteNumber(value, field) {
36635
+ if (typeof value !== "number" || !Number.isFinite(value)) {
36636
+ invalid(`${field} must be a finite number`);
36637
+ }
36638
+ return value;
36639
+ }
36640
+ function invalid(message) {
36641
+ throw new ProviderError("invalid_config", message);
36642
+ }
36643
+
36644
+ // src/features/magic-context/smart-notes/condition-compiler.ts
36645
+ var RETINA_LOCAL_FS_PROVIDER = "local-fs";
36646
+ var VALUE = String.raw`(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\S+)`;
36647
+ async function compileSurfaceCondition(surfaceCondition, options) {
36648
+ const parsed = parseCondition(surfaceCondition, options.projectPath);
36649
+ if (parsed === null)
36650
+ return { status: "plain" };
36651
+ const now = (options.now ?? Date.now)();
36652
+ const resolvePath = options.resolvePath ?? (async (path6) => {
36653
+ const resolved = await resolveAndFenceProviderPath(path6, {
36654
+ allowMissing: true,
36655
+ homeDirectory: options.homeDirectory,
36656
+ cwd: options.projectPath
36657
+ });
36658
+ return { path: resolved, exists: existsSync11(resolved) };
36659
+ });
36660
+ let predicates;
36661
+ try {
36662
+ predicates = [];
36663
+ for (const predicate of parsed) {
36664
+ predicates.push(await resolvePredicate(predicate, resolvePath, now));
36665
+ }
36666
+ } catch (error) {
36667
+ const code = error !== null && typeof error === "object" && "code" in error ? error.code : undefined;
36668
+ return {
36669
+ status: "refused",
36670
+ reason: code === "fenced_path" ? "fenced path" : "path resolution failed"
36671
+ };
36672
+ }
36673
+ const candidate = predicates.length === 1 ? predicates[0] : { any: predicates };
36674
+ const validation = validateProviderConfig(candidate);
36675
+ if (!validation.success) {
36676
+ return {
36677
+ status: "refused",
36678
+ reason: `provider schema: ${singleLine(validation.reason)}`.slice(0, 180)
36679
+ };
36680
+ }
36681
+ return {
36682
+ status: "compiled",
36683
+ provider: RETINA_LOCAL_FS_PROVIDER,
36684
+ config: validation.config,
36685
+ compiledAt: now
36686
+ };
36687
+ }
36688
+ function conditionCompileStorageFields(result) {
36689
+ if (result.status === "compiled") {
36690
+ return {
36691
+ compiledProvider: result.provider,
36692
+ compiledConfig: JSON.stringify(result.config),
36693
+ compiledAt: result.compiledAt,
36694
+ compileStatus: result.status
36695
+ };
36696
+ }
36697
+ return {
36698
+ compiledProvider: null,
36699
+ compiledConfig: null,
36700
+ compiledAt: null,
36701
+ compileStatus: result.status
36702
+ };
36703
+ }
36704
+ function conditionCompileReplySuffix(result) {
36705
+ if (result.status === "compiled") {
36706
+ return `
36707
+ - Retina provider: ${result.provider}`;
36708
+ }
36709
+ if (result.status === "refused") {
36710
+ return `
36711
+ - Retina compile refused: ${result.reason}`;
36712
+ }
36713
+ return "";
36714
+ }
36715
+ function parseCondition(surfaceCondition, projectPath) {
36716
+ const trimmed = surfaceCondition.trim();
36717
+ const either = trimmed.match(/^either\s+(.+)$/i);
36718
+ if (!either) {
36719
+ const predicate = parseAtomicCondition(trimmed, projectPath);
36720
+ return predicate ? [predicate] : null;
36721
+ }
36722
+ const clauses = splitOrClauses(either[1]);
36723
+ if (clauses.length < 2)
36724
+ return null;
36725
+ const predicates = clauses.map((clause) => parseAtomicCondition(clause, projectPath));
36726
+ return predicates.every((predicate) => predicate !== null) ? predicates : null;
36727
+ }
36728
+ function parseAtomicCondition(text, projectPath) {
36729
+ const fileContains = text.match(new RegExp(`^(?:when\\s+)?file\\s+(${VALUE})\\s+(no longer contains|contains)\\s+(.+)$`, "i"));
36730
+ if (fileContains) {
36731
+ const needle = unquote(fileContains[3].trim());
36732
+ if (needle === null)
36733
+ return null;
36734
+ return {
36735
+ kind: "file_contains",
36736
+ path: unquote(fileContains[1]) ?? fileContains[1],
36737
+ needle,
36738
+ ...fileContains[2].toLowerCase() === "no longer contains" ? { absent: true } : {}
36739
+ };
36740
+ }
36741
+ const commit = text.match(new RegExp(`^(?:when\\s+)?(?:repo(?:sitory)?\\s+)?(${VALUE})\\s+has\\s+a\\s+commit\\s+(?:after|newer than)\\s+([0-9a-f]{7,64})$`, "i"));
36742
+ if (commit) {
36743
+ return {
36744
+ kind: "git_commit_after",
36745
+ repo_path: unquote(commit[1]) ?? commit[1],
36746
+ sha: commit[2]
36747
+ };
36748
+ }
36749
+ const tag = text.match(new RegExp(`^(?:when\\s+)?a\\s+tag\\s+(?:(?:matching\\s+(${VALUE})(?:\\s+above\\s+semver\\s+(${VALUE}))?)|(?:above\\s+semver\\s+(${VALUE})))\\s+appears(?:\\s+in\\s+(?:repo(?:sitory)?\\s+)?(${VALUE}))?$`, "i"));
36750
+ if (tag) {
36751
+ const pattern = tag[1] ? unquote(tag[1]) : "*";
36752
+ const above = unquote(tag[2] ?? tag[3] ?? "");
36753
+ const repoPath = tag[4] ? unquote(tag[4]) : projectPath;
36754
+ if (pattern === null || above === null || repoPath === null)
36755
+ return null;
36756
+ return {
36757
+ kind: "git_tag_matching",
36758
+ repo_path: repoPath,
36759
+ pattern,
36760
+ ...above.length > 0 ? { above } : {}
36761
+ };
36762
+ }
36763
+ const mtime = text.match(new RegExp(`^(?:when\\s+)?(?:file\\s+)?(${VALUE})\\s+(changes|is rebuilt|mtime moves)$`, "i"));
36764
+ if (mtime) {
36765
+ return {
36766
+ kind: "mtime_after",
36767
+ path: unquote(mtime[1]) ?? mtime[1]
36768
+ };
36769
+ }
36770
+ const pathExists = text.match(new RegExp(`^(?:when\\s+)?(?:path\\s+)?(${VALUE})\\s+(exists|is gone)$`, "i"));
36771
+ if (pathExists) {
36772
+ return {
36773
+ kind: "path_exists",
36774
+ path: unquote(pathExists[1]) ?? pathExists[1],
36775
+ ...pathExists[2].toLowerCase() === "is gone" ? { gone: true } : {}
36776
+ };
36777
+ }
36778
+ return null;
36779
+ }
36780
+ async function resolvePredicate(predicate, resolvePath, now) {
36781
+ const configuredPath = "repo_path" in predicate ? predicate.repo_path : predicate.path;
36782
+ const resolved = await resolvePath(configuredPath);
36783
+ const sourceIsResolvable = isAbsolute4(configuredPath) || configuredPath === "~" || configuredPath.startsWith("~/");
36784
+ const audit = sourceIsResolvable && resolved.exists ? {} : { resolved_path_exists: false };
36785
+ switch (predicate.kind) {
36786
+ case "file_contains":
36787
+ return { ...predicate, path: resolved.path, ...audit };
36788
+ case "path_exists":
36789
+ return { ...predicate, path: resolved.path, ...audit };
36790
+ case "mtime_after":
36791
+ return { kind: predicate.kind, path: resolved.path, since_ms: now, ...audit };
36792
+ case "git_commit_after":
36793
+ return { ...predicate, repo_path: resolved.path, ...audit };
36794
+ case "git_tag_matching":
36795
+ return { ...predicate, repo_path: resolved.path, ...audit };
36796
+ }
36797
+ }
36798
+ function splitOrClauses(text) {
36799
+ const clauses = [];
36800
+ let start = 0;
36801
+ let quote = null;
36802
+ let escaped = false;
36803
+ for (let index = 0;index < text.length; index += 1) {
36804
+ const character = text[index];
36805
+ if (escaped) {
36806
+ escaped = false;
36807
+ continue;
36808
+ }
36809
+ if (quote && character === "\\") {
36810
+ escaped = true;
36811
+ continue;
36812
+ }
36813
+ if (character === '"' || character === "'") {
36814
+ quote = quote === character ? null : quote === null ? character : quote;
36815
+ continue;
36816
+ }
36817
+ if (quote !== null)
36818
+ continue;
36819
+ const separator = text.slice(index).match(/^\s+or\s+/i);
36820
+ if (!separator)
36821
+ continue;
36822
+ clauses.push(text.slice(start, index).trim());
36823
+ index += separator[0].length - 1;
36824
+ start = index + 1;
36825
+ }
36826
+ clauses.push(text.slice(start).trim());
36827
+ return clauses.filter(Boolean);
36828
+ }
36829
+ function unquote(value) {
36830
+ if (value.length < 2)
36831
+ return value;
36832
+ const quote = value[0];
36833
+ if (quote !== '"' && quote !== "'" || value.at(-1) !== quote)
36834
+ return value;
36835
+ if (quote === '"') {
36836
+ try {
36837
+ const parsed = JSON.parse(value);
36838
+ return typeof parsed === "string" ? parsed : null;
36839
+ } catch {
36840
+ return null;
36841
+ }
36842
+ }
36843
+ return value.slice(1, -1).replace(/\\'/g, "'").replace(/\\\\/g, "\\");
36844
+ }
36845
+ function singleLine(value) {
36846
+ return value.replace(/\s+/g, " ").trim();
36847
+ }
36848
+
36849
+ // src/tools/ctx-note/tools.ts
36201
36850
  function captureAnchorOrdinal(db, sessionId) {
36202
36851
  try {
36203
36852
  const ordinal = getLastIndexedOrdinal(db, sessionId);
@@ -36423,16 +37072,21 @@ function createCtxNoteTool(deps) {
36423
37072
  if (!projectIdentity) {
36424
37073
  return "Error: Could not resolve project identity for smart note.";
36425
37074
  }
37075
+ const surfaceCondition = args.surface_condition.trim();
37076
+ const compilation = await compileSurfaceCondition(surfaceCondition, {
37077
+ projectPath: toolContext.directory
37078
+ });
36426
37079
  const note2 = addNote(deps.db, "smart", {
36427
37080
  content,
36428
37081
  projectPath: projectIdentity,
36429
37082
  sessionId,
36430
- surfaceCondition: args.surface_condition.trim(),
36431
- anchorOrdinal
37083
+ surfaceCondition,
37084
+ anchorOrdinal,
37085
+ ...conditionCompileStorageFields(compilation)
36432
37086
  });
36433
37087
  return `Created smart note #${note2.id}. Dreamer will evaluate the condition during nightly runs:
36434
37088
  - Content: ${content}
36435
- - Condition: ${args.surface_condition.trim()}`;
37089
+ - Condition: ${surfaceCondition}${conditionCompileReplySuffix(compilation)}`;
36436
37090
  }
36437
37091
  const note = addNote(deps.db, "session", { sessionId, content, anchorOrdinal });
36438
37092
  return `Saved session note #${note.id}.`;
@@ -36459,8 +37113,15 @@ function createCtxNoteTool(deps) {
36459
37113
  const updates = {};
36460
37114
  if (args.content?.trim())
36461
37115
  updates.content = args.content.trim();
36462
- if (args.surface_condition?.trim())
36463
- updates.surfaceCondition = args.surface_condition.trim();
37116
+ let compilation;
37117
+ if (args.surface_condition?.trim()) {
37118
+ const surfaceCondition = args.surface_condition.trim();
37119
+ updates.surfaceCondition = surfaceCondition;
37120
+ compilation = await compileSurfaceCondition(surfaceCondition, {
37121
+ projectPath: toolContext.directory
37122
+ });
37123
+ Object.assign(updates, conditionCompileStorageFields(compilation));
37124
+ }
36464
37125
  if (!updates.content && !updates.surfaceCondition) {
36465
37126
  return "Error: Provide 'content' and/or 'surface_condition' to update.";
36466
37127
  }
@@ -36481,7 +37142,7 @@ function createCtxNoteTool(deps) {
36481
37142
  parts.push(`Condition: ${updates.surfaceCondition}`);
36482
37143
  return `Updated note #${noteId}:
36483
37144
  ${parts.join(`
36484
- `)}`;
37145
+ `)}${compilation ? conditionCompileReplySuffix(compilation) : ""}`;
36485
37146
  }
36486
37147
  const limit = typeof args.limit === "number" && args.limit > 0 ? Math.floor(args.limit) : DEFAULT_READ_LIMIT;
36487
37148
  const offset = typeof args.offset === "number" && args.offset > 0 ? Math.floor(args.offset) : 0;
@@ -37050,7 +37711,7 @@ import {
37050
37711
  unlinkSync,
37051
37712
  writeFileSync as writeFileSync4
37052
37713
  } from "node:fs";
37053
- import { dirname as dirname4 } from "node:path";
37714
+ import { dirname as dirname5 } from "node:path";
37054
37715
  var MAX_BODY_BYTES = 1048576;
37055
37716
  var WS_AUTH_TIMEOUT_MS = 5000;
37056
37717
  var WS_CLOSE_UNAUTHORIZED = 4401;
@@ -37124,7 +37785,7 @@ class MagicContextRpcServer {
37124
37785
  this.port = server.port ?? 0;
37125
37786
  try {
37126
37787
  this.warnIfOtherLiveInstance();
37127
- const dir = dirname4(this.portFilePath);
37788
+ const dir = dirname5(this.portFilePath);
37128
37789
  const enforcePrivatePermissions = shouldEnforcePrivateStoragePermissions();
37129
37790
  if (enforcePrivatePermissions) {
37130
37791
  mkdirSync2(dir, { recursive: true, mode: 448 });
@@ -37357,7 +38018,7 @@ var server = async (ctx) => {
37357
38018
  `);
37358
38019
  setTimeout(async () => {
37359
38020
  try {
37360
- const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-sr5g06hz.js");
38021
+ const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bgtf4853.js");
37361
38022
  const clientWithSessions = ctx.client;
37362
38023
  const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
37363
38024
  const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
@@ -37501,6 +38162,7 @@ var server = async (ctx) => {
37501
38162
  memoryEnabled: pluginConfig.memory?.enabled === true,
37502
38163
  memoryInjectionBudgetTokens: pluginConfig.memory?.injection_budget_tokens,
37503
38164
  mural: pluginConfig.mural,
38165
+ retinaHandoff: pluginConfig.smart_notes.retina_handoff,
37504
38166
  gitCommitIndexing: pluginConfig.memory.git_commit_indexing?.enabled ? {
37505
38167
  enabled: true,
37506
38168
  since_days: pluginConfig.memory.git_commit_indexing.since_days,
@@ -37538,7 +38200,7 @@ var server = async (ctx) => {
37538
38200
  {
37539
38201
  const fence = getSchemaFenceRejection();
37540
38202
  if (fence) {
37541
- import("./conflict-warning-hook-p2pmhvn7.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
38203
+ import("./conflict-warning-hook-dw9fs934.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
37542
38204
  }
37543
38205
  }
37544
38206
  if (conflictResult?.hasConflict) {
@@ -37556,10 +38218,10 @@ var server = async (ctx) => {
37556
38218
  ANNOUNCEMENT_FEATURES: ANNOUNCEMENT_FEATURES2,
37557
38219
  ANNOUNCEMENT_FOOTER: ANNOUNCEMENT_FOOTER2,
37558
38220
  markAnnouncementSeen: markAnnouncementSeen2
37559
- } = await import("./announcement-gms2nhya.js");
38221
+ } = await import("./announcement-6c1g4es4.js");
37560
38222
  if (shouldShowAnnouncement2()) {
37561
38223
  setTimeout(() => {
37562
- import("./conflict-warning-hook-p2pmhvn7.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION2, ANNOUNCEMENT_FEATURES2, ANNOUNCEMENT_FOOTER2, markAnnouncementSeen2)).catch(() => {});
38224
+ import("./conflict-warning-hook-dw9fs934.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION2, ANNOUNCEMENT_FEATURES2, ANNOUNCEMENT_FOOTER2, markAnnouncementSeen2)).catch(() => {});
37563
38225
  }, 8000);
37564
38226
  }
37565
38227
  } catch {}
@@ -37686,14 +38348,17 @@ var server = async (ctx) => {
37686
38348
  historianDisallowed: pluginConfig.historian?.disallowed_tools ?? []
37687
38349
  });
37688
38350
  const agentConfig = { ...config.agent ?? {} };
38351
+ const agentConfigRecord = agentConfig;
38352
+ const internalAgentIds = registrations.map((registration) => registration.id);
37689
38353
  for (const reg of registrations) {
37690
38354
  if (typeof reg.prompt !== "string" || reg.prompt.length === 0) {
37691
38355
  log(`[magic-context] skipping hidden agent '${reg.id}' — prompt unavailable at config time (dir=${ctx.directory}); will re-register on a later complete pass`);
37692
38356
  continue;
37693
38357
  }
37694
- agentConfig[reg.id] = buildHiddenAgentConfig(reg.prompt, reg.allowedTools, reg.maxSteps, reg.overrides, reg.id, reg.lockPermissions === true, reg.description);
38358
+ agentConfigRecord[reg.id] = buildHiddenAgentConfig(reg.prompt, reg.allowedTools, reg.maxSteps, reg.overrides, reg.id, reg.lockPermissions === true, reg.description);
37695
38359
  }
37696
- config.agent = agentConfig;
38360
+ const callerAgentConfig = denyTaskRoutingToCallerAgents(agentConfigRecord, internalAgentIds);
38361
+ config.agent = callerAgentConfig;
37697
38362
  } catch (error) {
37698
38363
  const e = error;
37699
38364
  log(`[magic-context] config hook failed (commands/agents NOT registered; transform still active): ${e?.message ?? error}`, e?.stack ? { stackHead: e.stack.split(`