@cortexkit/opencode-magic-context 0.22.5 → 0.23.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 (149) hide show
  1. package/dist/agents/magic-context-prompt.d.ts +1 -1
  2. package/dist/agents/magic-context-prompt.d.ts.map +1 -1
  3. package/dist/agents/permissions.d.ts +4 -4
  4. package/dist/agents/permissions.d.ts.map +1 -1
  5. package/dist/config/project-security.d.ts +5 -0
  6. package/dist/config/project-security.d.ts.map +1 -1
  7. package/dist/config/schema/magic-context.d.ts +0 -13
  8. package/dist/config/schema/magic-context.d.ts.map +1 -1
  9. package/dist/features/magic-context/dreamer/task-prompts.d.ts +1 -1
  10. package/dist/features/magic-context/dreamer/task-prompts.d.ts.map +1 -1
  11. package/dist/features/magic-context/memory/constants.d.ts +7 -0
  12. package/dist/features/magic-context/memory/constants.d.ts.map +1 -1
  13. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  14. package/dist/features/magic-context/storage-db.d.ts +1 -1
  15. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  16. package/dist/features/magic-context/storage-meta-persisted.d.ts +83 -15
  17. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  18. package/dist/features/magic-context/storage-meta-shared.d.ts +9 -1
  19. package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
  20. package/dist/features/magic-context/storage-meta.d.ts +1 -1
  21. package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
  22. package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
  23. package/dist/features/magic-context/storage-tags.d.ts +118 -1
  24. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  25. package/dist/features/magic-context/storage.d.ts +2 -2
  26. package/dist/features/magic-context/storage.d.ts.map +1 -1
  27. package/dist/features/magic-context/tagger.d.ts +12 -2
  28. package/dist/features/magic-context/tagger.d.ts.map +1 -1
  29. package/dist/features/magic-context/tool-owner-backfill.d.ts +2 -1
  30. package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
  31. package/dist/features/magic-context/types.d.ts +8 -0
  32. package/dist/features/magic-context/types.d.ts.map +1 -1
  33. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  34. package/dist/hooks/magic-context/channel2-delivery.d.ts +22 -0
  35. package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -0
  36. package/dist/hooks/magic-context/command-handler.d.ts +0 -1
  37. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  38. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  39. package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
  40. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  41. package/dist/hooks/magic-context/compartment-runner-types.d.ts +5 -0
  42. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
  44. package/dist/hooks/magic-context/compartment-trigger.d.ts +47 -2
  45. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +117 -0
  47. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -0
  48. package/dist/hooks/magic-context/emergency-drop.d.ts +86 -0
  49. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -0
  50. package/dist/hooks/magic-context/event-handler.d.ts +6 -4
  51. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  52. package/dist/hooks/magic-context/execute-flush.d.ts.map +1 -1
  53. package/dist/hooks/magic-context/execute-status.d.ts +1 -1
  54. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  55. package/dist/hooks/magic-context/heuristic-cleanup.d.ts +10 -3
  56. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  57. package/dist/hooks/magic-context/hook-handlers.d.ts +3 -9
  58. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  59. package/dist/hooks/magic-context/hook.d.ts +3 -5
  60. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  61. package/dist/hooks/magic-context/note-visibility.d.ts +1 -1
  62. package/dist/hooks/magic-context/protected-tail-boundary.d.ts +132 -0
  63. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -0
  64. package/dist/hooks/magic-context/read-session-chunk.d.ts +55 -0
  65. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  66. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  67. package/dist/hooks/magic-context/read-session-raw.d.ts +91 -0
  68. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  69. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +70 -0
  70. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -0
  71. package/dist/hooks/magic-context/send-session-notification.d.ts +2 -1
  72. package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
  73. package/dist/hooks/magic-context/system-prompt-hash.d.ts +0 -1
  74. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  75. package/dist/hooks/magic-context/tag-messages.d.ts +3 -0
  76. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  77. package/dist/hooks/magic-context/todo-view.d.ts +1 -1
  78. package/dist/hooks/magic-context/tool-drop-target.d.ts +9 -0
  79. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  80. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +15 -0
  81. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  82. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +7 -10
  83. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  84. package/dist/hooks/magic-context/transform.d.ts +14 -9
  85. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  86. package/dist/hooks/magic-context/upgrade-reminder.d.ts +2 -1
  87. package/dist/hooks/magic-context/upgrade-reminder.d.ts.map +1 -1
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +5133 -1095
  90. package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
  91. package/dist/plugin/hooks/create-session-hooks.d.ts +1 -1
  92. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  93. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  94. package/dist/plugin/tool-registry.d.ts.map +1 -1
  95. package/dist/shared/announcement.d.ts +4 -6
  96. package/dist/shared/announcement.d.ts.map +1 -1
  97. package/dist/shared/live-server-client.d.ts +50 -0
  98. package/dist/shared/live-server-client.d.ts.map +1 -0
  99. package/dist/shared/prompt-context.d.ts +31 -0
  100. package/dist/shared/prompt-context.d.ts.map +1 -0
  101. package/dist/shared/rpc-types.d.ts +0 -3
  102. package/dist/shared/rpc-types.d.ts.map +1 -1
  103. package/dist/shared/safe-notification-target.d.ts +23 -0
  104. package/dist/shared/safe-notification-target.d.ts.map +1 -0
  105. package/dist/shared/tag-transcript.d.ts.map +1 -1
  106. package/dist/shared/transcript-opencode.d.ts.map +1 -1
  107. package/dist/shared/transcript.d.ts +15 -1
  108. package/dist/shared/transcript.d.ts.map +1 -1
  109. package/dist/tools/ctx-expand/constants.d.ts +1 -1
  110. package/dist/tools/ctx-expand/constants.d.ts.map +1 -1
  111. package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
  112. package/dist/tools/ctx-memory/constants.d.ts +1 -1
  113. package/dist/tools/ctx-memory/constants.d.ts.map +1 -1
  114. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  115. package/dist/tools/ctx-memory/types.d.ts +7 -3
  116. package/dist/tools/ctx-memory/types.d.ts.map +1 -1
  117. package/dist/tools/ctx-note/constants.d.ts +1 -1
  118. package/dist/tools/ctx-note/constants.d.ts.map +1 -1
  119. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  120. package/dist/tools/ctx-note/types.d.ts +4 -0
  121. package/dist/tools/ctx-note/types.d.ts.map +1 -1
  122. package/dist/tools/ctx-search/constants.d.ts +1 -1
  123. package/dist/tools/ctx-search/constants.d.ts.map +1 -1
  124. package/dist/tui/data/context-db.d.ts.map +1 -1
  125. package/package.json +2 -1
  126. package/src/shared/announcement.test.ts +18 -0
  127. package/src/shared/announcement.ts +35 -20
  128. package/src/shared/live-server-client.ts +152 -0
  129. package/src/shared/prompt-context.ts +135 -0
  130. package/src/shared/rpc-types.ts +0 -3
  131. package/src/shared/safe-notification-target.test.ts +97 -0
  132. package/src/shared/safe-notification-target.ts +102 -0
  133. package/src/shared/tag-transcript.test.ts +34 -8
  134. package/src/shared/tag-transcript.ts +110 -8
  135. package/src/shared/transcript-opencode.ts +15 -5
  136. package/src/shared/transcript.ts +20 -2
  137. package/src/tui/data/context-db.ts +0 -3
  138. package/src/tui/index.tsx +2 -5
  139. package/src/tui/slots/sidebar-content.tsx +1 -26
  140. package/dist/hooks/magic-context/apply-context-nudge.d.ts +0 -5
  141. package/dist/hooks/magic-context/apply-context-nudge.d.ts.map +0 -1
  142. package/dist/hooks/magic-context/nudge-bands.d.ts +0 -6
  143. package/dist/hooks/magic-context/nudge-bands.d.ts.map +0 -1
  144. package/dist/hooks/magic-context/nudge-injection.d.ts +0 -7
  145. package/dist/hooks/magic-context/nudge-injection.d.ts.map +0 -1
  146. package/dist/hooks/magic-context/nudge-placement-store.d.ts +0 -15
  147. package/dist/hooks/magic-context/nudge-placement-store.d.ts.map +0 -1
  148. package/dist/hooks/magic-context/nudger.d.ts +0 -21
  149. package/dist/hooks/magic-context/nudger.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"conflict-warning-hook.d.ts","sourceRoot":"","sources":["../../src/plugin/conflict-warning-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAqLlE;;GAEG;AACH,wBAAsB,mBAAmB,CACrC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,cAAc,GAC/B,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CACzC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAqHf;AAkCD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC1C,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAkEf;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CACxC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GAC/D,OAAO,CAAC,IAAI,CAAC,CAkCf;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CACzC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,EAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACpC,OAAO,CAAC,IAAI,CAAC,CA8Df"}
1
+ {"version":3,"file":"conflict-warning-hook.d.ts","sourceRoot":"","sources":["../../src/plugin/conflict-warning-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAsLlE;;GAEG;AACH,wBAAsB,mBAAmB,CACrC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,cAAc,GAC/B,OAAO,CAAC,IAAI,CAAC,CAqDf;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CACzC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAwHf;AAkCD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC1C,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAsEf;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CACxC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GAC/D,OAAO,CAAC,IAAI,CAAC,CAsCf;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CACzC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,EAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACpC,OAAO,CAAC,IAAI,CAAC,CAkEf"}
@@ -38,7 +38,7 @@ export declare function createSessionHooks(args: {
38
38
  };
39
39
  }) => Promise<void>;
40
40
  "command.execute.before": (input: unknown, output: unknown) => Promise<unknown>;
41
- "tool.execute.after": (input: unknown) => Promise<void>;
41
+ "tool.execute.after": (input: unknown, output?: unknown) => Promise<void>;
42
42
  } | null;
43
43
  };
44
44
  //# sourceMappingURL=create-session-hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAU7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;;;;;;qBAwDwlK,CAAC;;;;;;;;;;;;qBAA9nD,CAAC;mBAAyB,CAAC;iBAAuB,CAAC;iBAAuB,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;0BAAmk1B,CAAC;;;;;;EAD3o8B"}
1
+ {"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAO7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;;;;;;qBAuDuuK,CAAC;;;;;;;;;;;;qBAApzD,CAAC;mBAAyB,CAAC;iBAAuB,CAAC;iBAAuB,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;0BAA+4zB,CAAC;;;;;;EADh76B"}
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,OAAO,EACH,KAAK,eAAe,IAAI,QAAQ,EAGnC,MAAM,mCAAmC,CAAC;AAY3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAqBlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA0FzE,wBAAgB,oBAAoB,CAChC,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,EAK9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,eAAe,CA2VjB;AAED,wBAAgB,iBAAiB,CAC7B,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,GAC/B,YAAY,CAuKd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC,GACF,IAAI,CAgON"}
1
+ {"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,OAAO,EACH,KAAK,eAAe,IAAI,QAAQ,EAGnC,MAAM,mCAAmC,CAAC;AAY3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAqBlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA0FzE,wBAAgB,oBAAoB,CAChC,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,EAK9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,eAAe,CA2VjB;AAED,wBAAgB,iBAAiB,CAC7B,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,GAC/B,YAAY,CA+Jd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC,GACF,IAAI,CAgON"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/plugin/tool-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAiB1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;CAC1C,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA6EjC"}
1
+ {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/plugin/tool-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAiB1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;CAC1C,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAiFjC"}
@@ -18,7 +18,7 @@
18
18
  * Bump only when there are user-visible changes worth a startup dialog.
19
19
  * Does NOT need to match the published package version.
20
20
  */
21
- export declare const ANNOUNCEMENT_VERSION = "0.22.0";
21
+ export declare const ANNOUNCEMENT_VERSION = "0.23.0";
22
22
  /**
23
23
  * Short, user-facing bullet strings. Keep each line ~80 chars or shorter so the
24
24
  * TUI dialog renders cleanly without horizontal scroll on a typical terminal.
@@ -33,11 +33,9 @@ export declare const ANNOUNCEMENT_FEATURES: ReadonlyArray<string>;
33
33
  */
34
34
  export declare const ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/F2uWxjGnU";
35
35
  /**
36
- * Read the most recently dismissed announcement version, or `""` if none.
37
- *
38
- * Best-effort: any read failure returns `""` (which forces the announcement to
39
- * re-show). The cost of a spurious second dialog is much smaller than the cost
40
- * of suppressing a real announcement due to a transient FS error.
36
+ * Read the most recently dismissed announcement version, or `""` if none can be
37
+ * returned. Callers that need to distinguish first-run from read/corruption
38
+ * failures should use the internal tri-state path in `shouldShowAnnouncement`.
41
39
  */
42
40
  export declare function readLastAnnouncedVersion(): string;
43
41
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"announcement.d.ts","sourceRoot":"","sources":["../../src/shared/announcement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,MAAM,CAMvD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,qDAAqD,CAAC;AAQtF;;;;;;GAMG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAQjD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAS1D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAUhD"}
1
+ {"version":3,"file":"announcement.d.ts","sourceRoot":"","sources":["../../src/shared/announcement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,MAAM,CAMvD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,qDAAqD,CAAC;AAyBtF;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAGjD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAS1D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAehD"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Live-server client for the Channel 2 ctx_reduce ceiling nudge (a synthetic
3
+ * user `<system-reminder>` delivered via `promptAsync`).
4
+ *
5
+ * WHY a separate client instead of the plugin-provided `input.client`:
6
+ * OpenCode's plugin `input.client` routes through `Server.Default().app.fetch`,
7
+ * which uses a SEPARATE Effect `memoMap` from the live HTTP listener the UI
8
+ * uses. `SessionRunState` lives per-memoMap, so a plugin-origin `promptAsync`
9
+ * observes an "idle" runner while the live turn is still running, `ensureRunning`
10
+ * fails to coalesce, and OpenCode persists duplicate assistant children
11
+ * (upstream bug anomalyco/opencode#28202). Building a `createOpencodeClient`
12
+ * aimed at `input.serverUrl` via `globalThis.fetch` enters the SAME live
13
+ * listener, so `ensureRunning` sees the real run and coalesces — the synthetic
14
+ * message lands at the tail after the current assistant step.
15
+ *
16
+ * The live listener is only reachable on OpenCode Desktop (Electron+Node) and
17
+ * TUI launched with `--port 0`; plain TUI binds an internal listener that 404s
18
+ * `/session/*`. We probe once at init and cache per `serverUrl`. When
19
+ * unreachable, Channel 2 is DISABLED (Channel 1 + 85% force-materialization
20
+ * remain the backstop) — MC deliberately does NOT fall back to the in-process
21
+ * client because that would knowingly trigger #28202.
22
+ */
23
+ import { createOpencodeClient } from "@opencode-ai/sdk";
24
+ export type LiveServerClient = ReturnType<typeof createOpencodeClient>;
25
+ /**
26
+ * Cached `createOpencodeClient` aimed at the live HTTP listener for the given
27
+ * `(serverUrl, directory)`. One client is reused across deliveries.
28
+ */
29
+ export declare function getLiveServerClient(serverUrl: string, directory: string): LiveServerClient;
30
+ /**
31
+ * Probe whether `serverUrl` serves OpenCode's HTTP API within `timeoutMs`.
32
+ * `true` only when `/session` proves the API is usable: any 2xx, or 401/403
33
+ * (auth-protected listener still exists). `false` for 404 (plain TUI internal
34
+ * listener), 5xx, connection refused, DNS failure, timeout, or malformed URL.
35
+ * Records the result + timestamp in the per-serverUrl cache.
36
+ */
37
+ export declare function probeServerReachable(serverUrl: string | undefined, timeoutMs?: number): Promise<boolean>;
38
+ /** Record a probe result directly (test helper / explicit override). */
39
+ export declare function setLiveServerWakeAvailable(serverUrl: string | undefined, available: boolean): void;
40
+ /**
41
+ * Should Channel 2 deliver through the live-server client for `serverUrl`?
42
+ * Returns false when never probed or the last probe failed. A stale decision
43
+ * (older than the TTL) returns false so the caller re-probes before delivering.
44
+ */
45
+ export declare function useLiveServerWake(serverUrl?: string): boolean;
46
+ /** True when a usable (non-stale) probe decision exists, regardless of outcome. */
47
+ export declare function hasFreshProbe(serverUrl?: string): boolean;
48
+ /** Test helper — reset both caches between cases. */
49
+ export declare function __resetLiveServerClientForTests(): void;
50
+ //# sourceMappingURL=live-server-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-server-client.d.ts","sourceRoot":"","sources":["../../src/shared/live-server-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AA0BvE;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAY1F;AAcD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACtC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,SAAO,GACjB,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED,wEAAwE;AACxE,wBAAgB,0BAA0B,CACtC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,OAAO,GACnB,IAAI,CAMN;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAM7D;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAKzD;AAED,qDAAqD;AACrD,wBAAgB,+BAA+B,IAAI,IAAI,CAGtD"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Resolve the newest effective prompt context (agent + model + variant) for a
3
+ * session by reading recent messages from the OpenCode HTTP API.
4
+ *
5
+ * WHY: a Channel 2 ceiling nudge sends a synthetic user message via
6
+ * `promptAsync` with `noReply:false` (it DOES trigger an assistant turn).
7
+ * OpenCode's `createUserMessage` resolves variant relative to the chosen
8
+ * agent; passing model alone makes OpenCode pick the default agent whose model
9
+ * check then fails, bypassing the active variant and busting the provider
10
+ * prefix cache the prior turn warmed. So we pass agent + model + variant
11
+ * explicitly, mirroring the resolution AFT/opencode-xtra use for their wake
12
+ * notifications.
13
+ *
14
+ * Walk newest→oldest and merge field-by-field so the newest context-bearing
15
+ * message wins while older messages only fill fields it did not provide. Read
16
+ * BOTH the flat shape (`info.providerID`) used by AssistantMessage and the
17
+ * nested shape (`info.model.providerID`) used by UserMessage.
18
+ *
19
+ * Bounded via `query.limit` — the legacy `/session/{id}/message` endpoint
20
+ * hydrates the ENTIRE session without it (30k-45k messages on large sessions).
21
+ */
22
+ export interface ResolvedPromptContext {
23
+ agent?: string;
24
+ model?: {
25
+ providerID: string;
26
+ modelID: string;
27
+ };
28
+ variant?: string;
29
+ }
30
+ export declare function resolvePromptContext(client: unknown, sessionId: string): Promise<ResolvedPromptContext | null>;
31
+ //# sourceMappingURL=prompt-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-context.d.ts","sourceRoot":"","sources":["../../src/shared/prompt-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,WAAW,qBAAqB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAuED,wBAAsB,oBAAoB,CACtC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAkCvC"}
@@ -95,7 +95,6 @@ export interface StatusDetail extends SidebarSnapshot {
95
95
  activeBytes: number;
96
96
  lastResponseTime: number;
97
97
  lastNudgeTokens: number;
98
- lastNudgeBand: string;
99
98
  lastTransformError: string | null;
100
99
  isSubagent: boolean;
101
100
  pendingOps: Array<{
@@ -119,9 +118,7 @@ export interface StatusDetail extends SidebarSnapshot {
119
118
  */
120
119
  executeThresholdTokens?: number;
121
120
  protectedTagCount: number;
122
- nudgeInterval: number;
123
121
  historyBudgetPercentage: number;
124
- nextNudgeAfter: number;
125
122
  historyBlockTokens: number;
126
123
  compressionBudget: number | null;
127
124
  compressionUsage: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export declare function isDefaultSessionTitle(title: string): boolean;
2
+ export interface SafeTargetOptions {
3
+ /** Total title checks before giving up (default 4). */
4
+ attempts?: number;
5
+ /** Delay between checks in ms (default 15s). */
6
+ delayMs?: number;
7
+ }
8
+ /**
9
+ * Resolve whether `sessionId` is safe to receive an ignored-message post.
10
+ *
11
+ * - "safe": the session has a real (non-default) title, or the title is
12
+ * unreadable (fail-open).
13
+ * - "skip": the session still has OpenCode's default title after all
14
+ * attempts — posting now could permanently suppress its title generation.
15
+ * The caller must leave its delivered/seen marker unset so a later
16
+ * startup retries.
17
+ *
18
+ * The retry window exists for the common startup case: plugin init fires a
19
+ * few seconds after launch, the user prompts shortly after, and the title
20
+ * lands within seconds of that first prompt.
21
+ */
22
+ export declare function waitForSafeNotificationTarget(client: unknown, sessionId: string, options?: SafeTargetOptions): Promise<"safe" | "skip">;
23
+ //# sourceMappingURL=safe-notification-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-notification-target.d.ts","sourceRoot":"","sources":["../../src/shared/safe-notification-target.ts"],"names":[],"mappings":"AAkCA,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5D;AAyBD,MAAM,WAAW,iBAAiB;IAC9B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,6BAA6B,CAC/C,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,iBAAiB,GAC5B,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,CAe1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"tag-transcript.d.ts","sourceRoot":"","sources":["../../src/shared/tag-transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAGzE,OAAO,EAAwB,KAAK,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAMrF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,cAAc,CAAC;AAE/D,MAAM,WAAW,oBAAoB;IACjC;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;OAOG;IACH,2BAA2B,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC;AAyDD,wBAAgB,aAAa,CACzB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,eAAe,EACnB,OAAO,GAAE,oBAAyB,GACnC,mBAAmB,CA8MrB"}
1
+ {"version":3,"file":"tag-transcript.d.ts","sourceRoot":"","sources":["../../src/shared/tag-transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAQzE,OAAO,EAAwB,KAAK,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAQrF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,cAAc,CAAC;AAE/D,MAAM,WAAW,oBAAoB;IACjC;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;OAOG;IACH,2BAA2B,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC;AA8DD,wBAAgB,aAAa,CACzB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,eAAe,EACnB,OAAO,GAAE,oBAAyB,GACnC,mBAAmB,CAiPrB"}
@@ -1 +1 @@
1
- {"version":3,"file":"transcript-opencode.d.ts","sourceRoot":"","sources":["../../src/shared/transcript-opencode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAGH,OAAO,KAAK,EACR,UAAU,EAIb,MAAM,cAAc,CAAC;AAEtB;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,KAAK,EAAE,OAAO,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,mBAAmB,EAAE,GAAG,UAAU,CA2BpF"}
1
+ {"version":3,"file":"transcript-opencode.d.ts","sourceRoot":"","sources":["../../src/shared/transcript-opencode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAIH,OAAO,KAAK,EACR,UAAU,EAIb,MAAM,cAAc,CAAC;AAEtB;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,KAAK,EAAE,OAAO,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,mBAAmB,EAAE,GAAG,UAAU,CA2BpF"}
@@ -106,12 +106,16 @@ export interface TranscriptPart {
106
106
  * for non-tool parts.
107
107
  * - inputByteSize: serialized argument size; used by historian
108
108
  * pressure projection to estimate post-drop savings.
109
+ * - inputTokenCount: real-tokenizer count of the same serialized
110
+ * argument, stored on the tag so token-budget consumers SUM stored
111
+ * counts instead of re-tokenizing. 0 for non-tool parts.
109
112
  *
110
- * For non-tool parts both fields are undefined.
113
+ * For non-tool parts both byte fields are undefined/0.
111
114
  */
112
115
  getToolMetadata(): {
113
116
  toolName: string | undefined;
114
117
  inputByteSize: number;
118
+ inputTokenCount: number;
115
119
  };
116
120
  /**
117
121
  * Replace this part with a sentinel placeholder. Sentinels look like
@@ -127,6 +131,16 @@ export interface TranscriptPart {
127
131
  * replaced (e.g. it's already a sentinel, or it's an image part).
128
132
  */
129
133
  replaceWithSentinel(sentinelText: string): boolean;
134
+ /**
135
+ * Optional: serialized byte size of the part's REAL payload, including
136
+ * non-text content (images, structured data) that `getText()` can't
137
+ * surface. Used by emergency-drop reclaim accounting so an image-only
138
+ * tool result is sized by its actual payload, not treated as ~0 bytes.
139
+ * Adapters that can compute this (e.g. Pi's tool_result proxy, which
140
+ * closes over the raw content array) should implement it; callers fall
141
+ * back to the text/JSON estimate when it's absent.
142
+ */
143
+ rawByteSize?(): number;
130
144
  }
131
145
  /**
132
146
  * A single message in the transcript, exposing role + ordered parts.
@@ -1 +1 @@
1
- {"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src/shared/transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,2EAA2E;AAC3E,MAAM,MAAM,kBAAkB,GACxB,MAAM,GACN,UAAU,GACV,UAAU,GACV,aAAa,GACb,OAAO,GACP,MAAM,GACN,YAAY,GACZ,SAAS,CAAC;AAEhB;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,cAAc;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAElC;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IAEhC;;;;;;;OAOG;IACH,OAAO,IAAI,MAAM,GAAG,SAAS,CAAC;IAE9B;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAElC;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAExC;;;;;;;;OAQG;IACH,eAAe,IAAI;QAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IAE3E;;;;;;;;;;;;OAYG;IACH,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;CACtD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAC9B;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,IAAI,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAEjE,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC;CACpC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAU;IACvB,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAEvC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAEpC;;;;;;;;;;;;;OAaG;IACH,MAAM,IAAI,IAAI,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,EAAE,kBAAiC,CAAC"}
1
+ {"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src/shared/transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,2EAA2E;AAC3E,MAAM,MAAM,kBAAkB,GACxB,MAAM,GACN,UAAU,GACV,UAAU,GACV,aAAa,GACb,OAAO,GACP,MAAM,GACN,YAAY,GACZ,SAAS,CAAC;AAEhB;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,cAAc;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAElC;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IAEhC;;;;;;;OAOG;IACH,OAAO,IAAI,MAAM,GAAG,SAAS,CAAC;IAE9B;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAElC;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAExC;;;;;;;;;;;OAWG;IACH,eAAe,IAAI;QACf,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;QAC7B,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC;KAC3B,CAAC;IAEF;;;;;;;;;;;;OAYG;IACH,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;IAEnD;;;;;;;;OAQG;IACH,WAAW,CAAC,IAAI,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAC9B;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,IAAI,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAEjE,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC;CACpC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAU;IACvB,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAEvC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAEpC;;;;;;;;;;;;;OAaG;IACH,MAAM,IAAI,IAAI,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,EAAE,kBAAiC,CAAC"}
@@ -1,3 +1,3 @@
1
- export declare const CTX_EXPAND_DESCRIPTION: string;
1
+ export declare const CTX_EXPAND_DESCRIPTION = "Recover the original conversation from your compacted history.\n\nOlder parts of this session are summarized into <compartment> blocks inside <session-history> \u2014 e.g. <compartment start=\"120\" end=\"245\" title=\"Fixed tagger collision\">. Each one replaces the raw messages in that ordinal range with a summary. When the summary isn't enough \u2014 you need exact wording, a specific value, an error message, or the reasoning behind a decision \u2014 expand the range:\n\nctx_expand(start=120, end=245) \u2190 the compartment's own start/end attributes\n\nReturns the raw transcript as [N] U:/A: lines, capped at ~15K tokens; an oversized range returns the head and tells you where to continue. Also works with ordinals from ctx_search message results \u2014 expand a window around a hit (e.g. start=N-10, end=N+5). Ranges after the last compartment are your live tail \u2014 already visible in context, not expandable.";
2
2
  export declare const CTX_EXPAND_TOKEN_BUDGET = 15000;
3
3
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-expand/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,QAGwD,CAAC;AAE5F,eAAO,MAAM,uBAAuB,QAAS,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-expand/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,o6BAM+T,CAAC;AAEnW,eAAO,MAAM,uBAAuB,QAAS,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-expand/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAEhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAK5E,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,eAAe,CAAC;CACvB;AA8DD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAI5F"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-expand/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAEhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAK5E,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,eAAe,CAAC;CACvB;AAkED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAI5F"}
@@ -1,4 +1,4 @@
1
1
  export declare const CTX_MEMORY_TOOL_NAME = "ctx_memory";
2
- export declare const CTX_MEMORY_DESCRIPTION = "Manage cross-session project memories. Primary sessions can write new memories or delete stale ones. Dreamer sessions can also list, update, merge, and archive memories. Memories persist across sessions and are automatically injected into new sessions.\n\nSupported actions: write, delete, list, update, merge, archive.";
2
+ export declare const CTX_MEMORY_DESCRIPTION = "Durable project knowledge shared across every session on this project.\n\nYour active memories are already visible in <project-memory> (each with its id), and every future session starts with them \u2014 write one when you learn something future sessions must know: a project rule, an architectural fact, a hard-won constraint, a config value, or a naming convention. Keep each memory one standalone fact, phrased to make sense without this session's context.\n\nActions:\n- write: save a new memory (content + category).\n- update: rewrite one memory whose fact changed (ids: [one], content).\n- archive: retire wrong or obsolete memories (ids: [one or more], optional reason).\n- merge: collapse duplicates into one memory (ids: [two or more], content).\n\nExample: ctx_memory(action=\"write\", category=\"CONSTRAINTS\", content=\"Pi stores sessions as JSONL under ~/.pi/agent/sessions/, not SQLite\")";
3
3
  export declare const DEFAULT_SEARCH_LIMIT = 10;
4
4
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-memory/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,eAAe,CAAC;AACjD,eAAO,MAAM,sBAAsB,oUAE6B,CAAC;AACjE,eAAO,MAAM,oBAAoB,KAAK,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-memory/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,eAAe,CAAC;AACjD,eAAO,MAAM,sBAAsB,44BAUwG,CAAC;AAC5I,eAAO,MAAM,oBAAoB,KAAK,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-memory/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AA6BhE,OAAO,EAIH,KAAK,iBAAiB,EACzB,MAAM,SAAS,CAAC;AAsjBjB,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAI5F"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-memory/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AA+BhE,OAAO,EAKH,KAAK,iBAAiB,EACzB,MAAM,SAAS,CAAC;AAwlBjB,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAI5F"}
@@ -1,13 +1,17 @@
1
1
  import type { MemorySourceType } from "../../features/magic-context/memory";
2
2
  import type { Database } from "../../shared/sqlite";
3
- export declare const CTX_MEMORY_ACTIONS: readonly ["write", "delete"];
4
- export declare const CTX_MEMORY_DREAMER_ACTIONS: readonly ["write", "delete", "list", "update", "merge", "archive"];
3
+ export declare const CTX_MEMORY_ACTIONS: readonly ["write", "archive", "update", "merge"];
4
+ export declare const CTX_MEMORY_DREAMER_ACTIONS: readonly ["write", "archive", "update", "merge", "list"];
5
5
  export type CtxMemoryAction = (typeof CTX_MEMORY_DREAMER_ACTIONS)[number];
6
6
  export interface CtxMemoryArgs {
7
7
  action: CtxMemoryAction;
8
8
  content?: string;
9
9
  category?: string;
10
- id?: number;
10
+ /**
11
+ * Target memory id(s). One unified parameter for all id-taking actions:
12
+ * update requires exactly one, archive one or more (batch), merge two or
13
+ * more. The former scalar `id` param was folded in here.
14
+ */
11
15
  ids?: number[];
12
16
  limit?: number;
13
17
  reason?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-memory/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,eAAO,MAAM,kBAAkB,8BAA+B,CAAC;AAE/D,eAAO,MAAM,0BAA0B,oEAM7B,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,QAAQ,CAAC;IACb,uBAAuB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E;;;;;;;;;;OAUG;IACH,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,eAAe,EAAE,CAAC;IACnC,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-memory/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AASpD,eAAO,MAAM,kBAAkB,kDAAmD,CAAC;AAEnF,eAAO,MAAM,0BAA0B,0DAA2C,CAAC;AAEnF,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,QAAQ,CAAC;IACb,uBAAuB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E;;;;;;;;;;OAUG;IACH,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,eAAe,EAAE,CAAC;IACnC,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC"}
@@ -1,2 +1,2 @@
1
- export declare const CTX_NOTE_DESCRIPTION = "Save or inspect durable session notes that persist for this session.\nUse this for short goals, constraints, decisions, or reminders worth carrying forward.\n\nActions:\n- `write`: Append one note. Optionally provide `surface_condition` to create a smart note.\n- `read`: Show current notes. Defaults to active session notes + ready smart notes; use `filter` to inspect all, pending, ready, active, or dismissed notes.\n- `dismiss`: Dismiss a note by `note_id`.\n- `update`: Update a note by `note_id`.\n\n**Smart Notes**: When `surface_condition` is provided with `write`, the note becomes a project-scoped smart note. A separate background process (the dreamer) periodically checks the condition using ONLY external, verifiable signals: GitHub state via `gh` CLI, web pages, files on disk, git history, etc. The dreamer cannot read your current conversation, cannot detect when the user says something, and has no memory of context that lives only in this session.\n\nWrite a smart note ONLY when the surface_condition is something an external agent with read-only tools can definitively check:\n\n\u2713 GOOD conditions (externally verifiable):\n- \"When PR #42 in cortexkit/magic-context is merged\"\n- \"When the file packages/plugin/src/foo.ts contains a function named bar\"\n- \"When the latest release tag is >= v0.22.0\"\n- \"When the GitHub Actions workflow runs/123 succeeds\"\n\n\u2717 BAD conditions (require knowing this session's context):\n- \"When the user mentions the worktree system has landed\" \u2192 dreamer cannot see user messages\n- \"When they ask to re-run the audit fixes\" \u2192 dreamer cannot see future requests\n- \"When we revisit this code path\" \u2192 no observable signal\n- \"When relevant to the current discussion\" \u2192 no observable signal\n- \"After we finish the current refactor\" \u2192 no externally checkable boundary\n\nIf you want context that surfaces based on what's happening in your session, use a regular note (omit surface_condition) \u2014 those show up on natural work boundaries within this session. If you want a reminder tied to your future work without a clean external trigger, just write a regular note describing what to do; you'll see it when you read notes later.\n\nExample: `ctx_note(action=\"write\", content=\"Implement X because Y\", surface_condition=\"When PR #42 in cortexkit/magic-context is merged\")`\n\nHistorian reads these notes, deduplicates them, and rewrites the remaining useful notes over time.";
1
+ export declare const CTX_NOTE_DESCRIPTION = "Working notes for this session's future \u2014 reminders, follow-ups, and things to revisit later.\n\nUse a note when something matters LATER but not in the next few steps: \"revisit the retry logic after the release\", \"user wants the dashboard polish batched\", \"flaky test to investigate when touching CI\". Don't use notes for active multi-step work (use todos) or for durable project knowledge that should outlive this session (use ctx_memory). Notes resurface automatically at natural work boundaries and whenever you read them.\n\nActions:\n- write: save a note (content). Add surface_condition to make it a smart note (below).\n- read: list notes, newest first. Default: latest active session notes + ready smart notes; page older ones with limit/offset, or inspect other states with filter.\n- update / dismiss: change or retire a note by note_id.\n\nSmart notes: pass surface_condition and the note stays hidden until a background checker confirms the condition \u2014 using ONLY externally verifiable signals (GitHub state via gh, files on disk, git history, web pages). It cannot see this conversation, so the condition must be checkable from outside:\n\u2713 \"When PR #42 in cortexkit/magic-context is merged\"\n\u2713 \"When the latest release tag is >= v0.22.0\"\n\u2713 \"When packages/plugin/src/foo.ts contains a function named bar\"\n\u2717 \"When the user mentions X\" / \"when we revisit Y\" / \"after we finish this refactor\" \u2014 no external signal; write a regular note instead.\n\nExample: 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\")";
2
2
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-note/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,mgFA8BkE,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-note/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,upDAeoI,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-note/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAYhE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAIpD,MAAM,WAAW,eAAe;IAC5B,EAAE,EAAE,QAAQ,CAAC;IACb,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;CACtD;AA2QD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAIxF"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-note/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAYhE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAIpD,MAAM,WAAW,eAAe;IAC5B,EAAE,EAAE,QAAQ,CAAC;IACb,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;CACtD;AAoTD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAIxF"}
@@ -4,6 +4,10 @@ export interface CtxNoteArgs {
4
4
  content?: string;
5
5
  surface_condition?: string;
6
6
  filter?: CtxNoteReadFilter;
7
+ /** Max notes per section for read, newest first (default 25). */
8
+ limit?: number;
9
+ /** Skip this many newest notes for read — pages older ones (default 0). */
10
+ offset?: number;
7
11
  note_id?: number;
8
12
  }
9
13
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-note/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAAC;AAErF,MAAM,WAAW,WAAW;IACxB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-note/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAAC;AAErF,MAAM,WAAW,WAAW;IACxB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -1,4 +1,4 @@
1
1
  export declare const CTX_SEARCH_TOOL_NAME = "ctx_search";
2
- export declare const CTX_SEARCH_DESCRIPTION: string;
2
+ export declare const CTX_SEARCH_DESCRIPTION = "Your long-term recall for this project \u2014 search everything that ever happened here, not just what's currently visible.\n\nReach for it when something feels familiar but isn't in view: \"did we solve this before?\", \"what did we decide about X?\", \"when did this break?\", \"where does Y live?\". Results only contain things you CANNOT currently see \u2014 memories already shown in <project-memory> and the live conversation tail are filtered out.\n\nSources (omit for a broad search across all):\n- memory: curated cross-session project knowledge \u2014 rules, constraints, conventions.\n- message: the raw conversation behind your compacted history. Hits include message ordinals \u2014 expand the surrounding exchange with ctx_expand(start=N-10, end=N+5).\n- git_commit: this repository's commit history.\n\nPicking sources:\n- \"when did this change / was this working before\" \u2192 [\"git_commit\", \"message\"]\n- \"did we discuss this earlier\" \u2192 [\"message\"]\n- \"what's our convention / rule for X\" \u2192 [\"memory\"]";
3
3
  export declare const DEFAULT_CTX_SEARCH_LIMIT = 10;
4
4
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-search/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,eAAe,CAAC;AACjD,eAAO,MAAM,sBAAsB,QAkBvB,CAAC;AACb,eAAO,MAAM,wBAAwB,KAAK,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-search/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,eAAe,CAAC;AACjD,eAAO,MAAM,sBAAsB,whCAYiB,CAAC;AACrD,eAAO,MAAM,wBAAwB,KAAK,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA0B,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpG,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAe9C,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOrD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAO/B;AA4FD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CA4B1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CA4CvB;AAED,qCAAqC;AACrC,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvE;AAED;mFACmF;AACnF,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQxE;AAED;;iDAEiD;AACjD,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUhF;AAED,MAAM,WAAW,UAAU;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAkBrE;AAED,wEAAwE;AACxE,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAQtD;AAED,yDAAyD;AACzD,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAyBjF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAWtF"}
1
+ {"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA0B,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpG,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAe9C,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOrD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAO/B;AA4FD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CA4B1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CAyCvB;AAED,qCAAqC;AACrC,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvE;AAED;mFACmF;AACnF,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQxE;AAED;;iDAEiD;AACjD,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUhF;AAED,MAAM,WAAW,UAAU;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAkBrE;AAED,wEAAwE;AACxE,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAQtD;AAED,yDAAyD;AACzD,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAyBjF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAWtF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-magic-context",
3
- "version": "0.22.5",
3
+ "version": "0.23.0",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",
@@ -50,6 +50,7 @@
50
50
  "devDependencies": {
51
51
  "@biomejs/biome": "^2.4.7",
52
52
  "@types/better-sqlite3": "^7.6.13",
53
+ "@types/bun": "^1.3.10",
53
54
  "@types/node": "^22.0.0",
54
55
  "bun-types": "^1.3.10",
55
56
  "typescript": "^5.8.0"
@@ -140,6 +140,24 @@ describe("shouldShowAnnouncement gating", () => {
140
140
  expect(shouldShowAnnouncement()).toBe(false);
141
141
  });
142
142
 
143
+ test("does not seed or advance state when an existing state file is unreadable/corrupt", async () => {
144
+ const mod = await import(`./announcement?t=${Date.now()}-corrupt`);
145
+ const { ANNOUNCEMENT_VERSION, ANNOUNCEMENT_FEATURES, shouldShowAnnouncement } = mod;
146
+
147
+ if (!ANNOUNCEMENT_VERSION || ANNOUNCEMENT_FEATURES.length === 0) {
148
+ expect(shouldShowAnnouncement()).toBe(false);
149
+ return;
150
+ }
151
+
152
+ const dir = path.join(tmpRoot, "cortexkit", "magic-context");
153
+ const file = path.join(dir, "last_announced_version");
154
+ fs.mkdirSync(dir, { recursive: true });
155
+ fs.writeFileSync(file, "");
156
+
157
+ expect(shouldShowAnnouncement()).toBe(false);
158
+ expect(fs.readFileSync(file, "utf-8")).toBe("");
159
+ });
160
+
143
161
  test("returns true when a different (older) version is marked", async () => {
144
162
  const mod = await import(`./announcement?t=${Date.now()}-older`);
145
163
  const {
@@ -23,18 +23,18 @@ import { getMagicContextStorageDir } from "./data-path";
23
23
  * Bump only when there are user-visible changes worth a startup dialog.
24
24
  * Does NOT need to match the published package version.
25
25
  */
26
- export const ANNOUNCEMENT_VERSION = "0.22.0";
26
+ export const ANNOUNCEMENT_VERSION = "0.23.0";
27
27
 
28
28
  /**
29
29
  * Short, user-facing bullet strings. Keep each line ~80 chars or shorter so the
30
30
  * TUI dialog renders cleanly without horizontal scroll on a typical terminal.
31
31
  */
32
32
  export const ANNOUNCEMENT_FEATURES: ReadonlyArray<string> = [
33
- "NOW ON BY DEFAULT — Temporal awareness: the agent sees elapsed-time markers (e.g. +2h 15m) between messages and dated compartments, so it knows how long ago things happened. Opt out with temporal_awareness: false.",
34
- "NOW ON BY DEFAULT Auto-search hints: each turn a background ctx_search whispers a compact 'vague recall' when something relevant exists in your memories, past conversation, or git history. No full content injected. Opt out with memory.auto_search.enabled: false.",
35
- "Experimental features graduated to stable config: temporal_awareness and caveman_text_compression are now top-level keys; auto_search and git_commit_indexing moved under memory.* . Run `doctor` to migrate old experimental.* settings (your opt-ins/opt-outs are preserved).",
36
- "git_commit_indexing (make project history semantically searchable) stays opt-in enable with memory.git_commit_indexing.enabled: true.",
37
- "Audit hardening across both harnesses: memory config-bypass fix, supersede-delta cache-stability fixes, and dashboard correctness fixes.",
33
+ "Smarter context nudges: gentle <system-reminder> notes on tool outputs replace the old chat nudges quieter, cache-safe, and they now also help subagents manage their own context.",
34
+ "The agent can now maintain its own project memories: update, archive (batch), and merge the memories it sees not just write new ones. Memory categories are schema-enforced.",
35
+ "Big-session performance: historian trigger and token math moved off the database hot path multi-second stalls on large sessions are gone (measured 250ms 2.4ms per pass).",
36
+ "History compaction unstuck for sparse sessions: the protected-tail boundary is now size-based, so sessions with few user turns compact reliably instead of growing forever (issue #132).",
37
+ "Fixed: session titles no longer fail to generate in fresh directories (issue #129), plus 20+ correctness fixes from three audit rounds.",
38
38
  ];
39
39
 
40
40
  /**
@@ -52,23 +52,33 @@ function getStateFilePath(): string {
52
52
  return path.join(getMagicContextStorageDir(), STATE_FILENAME);
53
53
  }
54
54
 
55
- /**
56
- * Read the most recently dismissed announcement version, or `""` if none.
57
- *
58
- * Best-effort: any read failure returns `""` (which forces the announcement to
59
- * re-show). The cost of a spurious second dialog is much smaller than the cost
60
- * of suppressing a real announcement due to a transient FS error.
61
- */
62
- export function readLastAnnouncedVersion(): string {
55
+ type AnnouncementStateRead =
56
+ | { status: "missing" }
57
+ | { status: "valid"; version: string }
58
+ | { status: "error" };
59
+
60
+ function readAnnouncementState(): AnnouncementStateRead {
63
61
  try {
64
62
  const file = getStateFilePath();
65
- if (!fs.existsSync(file)) return "";
66
- return fs.readFileSync(file, "utf-8").trim();
63
+ if (!fs.existsSync(file)) return { status: "missing" };
64
+ const version = fs.readFileSync(file, "utf-8").trim();
65
+ if (!version) return { status: "error" };
66
+ return { status: "valid", version };
67
67
  } catch {
68
- return "";
68
+ return { status: "error" };
69
69
  }
70
70
  }
71
71
 
72
+ /**
73
+ * Read the most recently dismissed announcement version, or `""` if none can be
74
+ * returned. Callers that need to distinguish first-run from read/corruption
75
+ * failures should use the internal tri-state path in `shouldShowAnnouncement`.
76
+ */
77
+ export function readLastAnnouncedVersion(): string {
78
+ const state = readAnnouncementState();
79
+ return state.status === "valid" ? state.version : "";
80
+ }
81
+
72
82
  /**
73
83
  * Persist `version` as the most recently dismissed announcement. Best-effort:
74
84
  * write failures are swallowed so dialog-confirm flows never throw on storage
@@ -108,12 +118,17 @@ export function markAnnouncementSeen(version: string): void {
108
118
  */
109
119
  export function shouldShowAnnouncement(): boolean {
110
120
  if (!ANNOUNCEMENT_VERSION || ANNOUNCEMENT_FEATURES.length === 0) return false;
111
- const lastVersion = readLastAnnouncedVersion();
112
- if (!lastVersion) {
121
+ const state = readAnnouncementState();
122
+ if (state.status === "missing") {
113
123
  // No prior state: fresh install or wiped sandbox. Seed to current and
114
124
  // skip the announcement so we never pester first-run / ephemeral envs.
115
125
  markAnnouncementSeen(ANNOUNCEMENT_VERSION);
116
126
  return false;
117
127
  }
118
- return lastVersion !== ANNOUNCEMENT_VERSION;
128
+ if (state.status === "error") {
129
+ // A corrupt or temporarily unreadable existing state file is not first-run.
130
+ // Do not advance the version; a later successful boot can still show it.
131
+ return false;
132
+ }
133
+ return state.version !== ANNOUNCEMENT_VERSION;
119
134
  }