@cortexkit/opencode-magic-context 0.47.0 → 0.49.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 (425) 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/{announcement-y35wzg2r.js → announcement-fp14dw0n.js} +3 -2
  4. package/dist/auto-search-worker.js +27 -30
  5. package/dist/config/index.d.ts.map +1 -1
  6. package/dist/config/mural-model-deprecation.d.ts +15 -0
  7. package/dist/config/mural-model-deprecation.d.ts.map +1 -0
  8. package/dist/config/project-security.d.ts +0 -3
  9. package/dist/config/project-security.d.ts.map +1 -1
  10. package/dist/config/schema/magic-context.d.ts +10 -6
  11. package/dist/config/schema/magic-context.d.ts.map +1 -1
  12. package/dist/{conflict-warning-hook-z44ynfz7.js → conflict-warning-hook-kzx4dmk1.js} +12 -10
  13. package/dist/{context-wq4ffwyb.js → context-nj5f293n.js} +2765 -1925
  14. package/dist/{derive-budgets-ke12jnnh.js → derive-budgets-qz5rrr08.js} +4 -3
  15. package/dist/embedding-activity-g1dhes6g.js +10 -0
  16. package/dist/embedding-backfill-aetxv1vt.js +21 -0
  17. package/dist/embedding-cache-mgyr73ef.js +16 -0
  18. package/dist/embedding-worker.js +11 -9
  19. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +1 -0
  21. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  22. package/dist/features/magic-context/dreamer/task-config.d.ts +3 -3
  23. package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
  24. package/dist/features/magic-context/dreamer/task-executor.d.ts +1 -1
  25. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  26. package/dist/features/magic-context/dreamer/task-registry.d.ts +1 -0
  27. package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
  28. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  29. package/dist/features/magic-context/git-commits/search-git-commits.d.ts +2 -0
  30. package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -1
  31. package/dist/features/magic-context/message-index-async.d.ts +16 -3
  32. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  33. package/dist/features/magic-context/message-index-bounded.d.ts +17 -0
  34. package/dist/features/magic-context/message-index-bounded.d.ts.map +1 -0
  35. package/dist/features/magic-context/message-index.d.ts +7 -1
  36. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  37. package/dist/features/magic-context/mural/render-trigger.d.ts +7 -4
  38. package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
  39. package/dist/features/magic-context/pi-content-decisions.d.ts +7 -1
  40. package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -1
  41. package/dist/features/magic-context/search-rerank.d.ts +35 -0
  42. package/dist/features/magic-context/search-rerank.d.ts.map +1 -0
  43. package/dist/features/magic-context/search.d.ts +40 -0
  44. package/dist/features/magic-context/search.d.ts.map +1 -1
  45. package/dist/features/magic-context/session-activity.d.ts.map +1 -1
  46. package/dist/features/magic-context/smart-notes/runner.d.ts +1 -0
  47. package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
  48. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  49. package/dist/features/magic-context/storage-meta-persisted.d.ts +13 -2
  50. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  51. package/dist/features/magic-context/storage-meta-session.d.ts +7 -1
  52. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
  53. package/dist/features/magic-context/storage-meta.d.ts +1 -1
  54. package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
  55. package/dist/features/magic-context/storage-session-tables.d.ts +2 -0
  56. package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
  57. package/dist/features/magic-context/storage-tag-identity-revision.d.ts +50 -0
  58. package/dist/features/magic-context/storage-tag-identity-revision.d.ts.map +1 -0
  59. package/dist/features/magic-context/storage-tags.d.ts +153 -4
  60. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  61. package/dist/features/magic-context/storage.d.ts +1 -1
  62. package/dist/features/magic-context/storage.d.ts.map +1 -1
  63. package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
  64. package/dist/features/magic-context/tagger.d.ts +2 -0
  65. package/dist/features/magic-context/tagger.d.ts.map +1 -1
  66. package/dist/features/magic-context/transform-decision-log.d.ts +4 -1
  67. package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
  68. package/dist/harness-e4avh192.js +10 -0
  69. package/dist/hooks/magic-context/active-anthropic-turn.d.ts +2 -0
  70. package/dist/hooks/magic-context/active-anthropic-turn.d.ts.map +1 -1
  71. package/dist/hooks/magic-context/auto-search-deadline.d.ts.map +1 -1
  72. package/dist/hooks/magic-context/auto-search-replay.fixture.d.ts +24 -0
  73. package/dist/hooks/magic-context/auto-search-replay.fixture.d.ts.map +1 -0
  74. package/dist/hooks/magic-context/auto-search-runner.d.ts +1 -1
  75. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  76. package/dist/hooks/magic-context/auto-search-worker-client.d.ts +34 -3
  77. package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -1
  78. package/dist/hooks/magic-context/command-handler.d.ts +3 -0
  79. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  80. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  81. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  82. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  83. package/dist/hooks/magic-context/emergency-fail-closed.d.ts +28 -0
  84. package/dist/hooks/magic-context/emergency-fail-closed.d.ts.map +1 -1
  85. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  86. package/dist/hooks/magic-context/historian-host-runner.d.ts +8 -0
  87. package/dist/hooks/magic-context/historian-host-runner.d.ts.map +1 -1
  88. package/dist/hooks/magic-context/hook.d.ts +3 -2
  89. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  90. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  91. package/dist/hooks/magic-context/latest-thinking-recovery.d.ts +7 -0
  92. package/dist/hooks/magic-context/latest-thinking-recovery.d.ts.map +1 -1
  93. package/dist/hooks/magic-context/lkg-persist.d.ts +4 -3
  94. package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
  95. package/dist/hooks/magic-context/lkg-replay.d.ts +13 -8
  96. package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
  97. package/dist/hooks/magic-context/lkg-slot.d.ts +139 -2
  98. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  99. package/dist/hooks/magic-context/message-search-accepting-silent-worker.fixture.d.ts +2 -0
  100. package/dist/hooks/magic-context/message-search-accepting-silent-worker.fixture.d.ts.map +1 -0
  101. package/dist/hooks/magic-context/oc-stall-r2-warmup-worker.fixture.d.ts +2 -0
  102. package/dist/hooks/magic-context/oc-stall-r2-warmup-worker.fixture.d.ts.map +1 -0
  103. package/dist/hooks/magic-context/oc-stall-search-review.fixture.d.ts +2 -0
  104. package/dist/hooks/magic-context/oc-stall-search-review.fixture.d.ts.map +1 -0
  105. package/dist/hooks/magic-context/opencode1-to-model-messages.fixture.d.ts +63 -0
  106. package/dist/hooks/magic-context/opencode1-to-model-messages.fixture.d.ts.map +1 -0
  107. package/dist/hooks/magic-context/pass-outcome.d.ts +1 -0
  108. package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -1
  109. package/dist/hooks/magic-context/provider-visible-parts.d.ts +45 -0
  110. package/dist/hooks/magic-context/provider-visible-parts.d.ts.map +1 -0
  111. package/dist/hooks/magic-context/raw-ordinal-warmup-silent-worker.fixture.d.ts +2 -0
  112. package/dist/hooks/magic-context/raw-ordinal-warmup-silent-worker.fixture.d.ts.map +1 -0
  113. package/dist/hooks/magic-context/raw-ordinal-warmup-worker.d.ts +2 -0
  114. package/dist/hooks/magic-context/raw-ordinal-warmup-worker.d.ts.map +1 -0
  115. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts +87 -0
  116. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -0
  117. package/dist/hooks/magic-context/read-session-chunk.d.ts +19 -1
  118. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  119. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
  120. package/dist/hooks/magic-context/read-session-formatting.d.ts +5 -0
  121. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  122. package/dist/hooks/magic-context/read-session-raw.d.ts +118 -1
  123. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  124. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
  125. package/dist/hooks/magic-context/reasoning-budget.d.ts.map +1 -1
  126. package/dist/hooks/magic-context/rust-mode-transform.d.ts +36 -0
  127. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  128. package/dist/hooks/magic-context/sentinel.d.ts +41 -1
  129. package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
  130. package/dist/hooks/magic-context/shared-compartment-boundaries.d.ts +8 -1
  131. package/dist/hooks/magic-context/shared-compartment-boundaries.d.ts.map +1 -1
  132. package/dist/hooks/magic-context/strict-thinking-prefix.d.ts +8 -0
  133. package/dist/hooks/magic-context/strict-thinking-prefix.d.ts.map +1 -0
  134. package/dist/hooks/magic-context/strip-content.d.ts +14 -2
  135. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  136. package/dist/hooks/magic-context/system-prompt-hash.d.ts +1 -0
  137. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  138. package/dist/hooks/magic-context/tag-messages.d.ts +8 -0
  139. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  140. package/dist/hooks/magic-context/tag-owner-warmup.d.ts +6 -0
  141. package/dist/hooks/magic-context/tag-owner-warmup.d.ts.map +1 -0
  142. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  143. package/dist/hooks/magic-context/token-count-exact.d.ts +35 -0
  144. package/dist/hooks/magic-context/token-count-exact.d.ts.map +1 -0
  145. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +13 -0
  146. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  147. package/dist/hooks/magic-context/transform.d.ts +9 -2
  148. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  149. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  150. package/dist/{index-q6hef7fh.js → index-0sahzkwr.js} +6 -19
  151. package/dist/{index-k5bdx1bx.js → index-0w56v4fm.js} +3 -5
  152. package/dist/{index-5gq3b2ya.js → index-1bt88epp.js} +227 -205
  153. package/dist/{index-cwf6s3ay.js → index-1g30axtz.js} +3279 -2907
  154. package/dist/{index-5a2r0p9f.js → index-1r0k9js3.js} +20 -13
  155. package/dist/index-2bvekkfy.js +11 -0
  156. package/dist/{index-6d9e1m08.js → index-2jcbj7r1.js} +13301 -13225
  157. package/dist/index-2jgwttpt.js +3269 -0
  158. package/dist/index-4dhv7mqz.js +131 -0
  159. package/dist/{index-sj29b3z2.js → index-4mjhqadz.js} +3 -3
  160. package/dist/{index-0c82743p.js → index-57mrqed8.js} +17 -15
  161. package/dist/{index-b35pxds2.js → index-58e3y90n.js} +1 -18
  162. package/dist/index-7jzrrxap.js +931 -0
  163. package/dist/index-8ajstryz.js +18 -0
  164. package/dist/{index-sfpzqvdz.js → index-8cd2j99z.js} +2 -3
  165. package/dist/{index-6wkcswft.js → index-9qjqq45k.js} +29 -19
  166. package/dist/{index-adwfkpex.js → index-9rt53q79.js} +23 -23
  167. package/dist/index-b7mv1jx3.js +1060 -0
  168. package/dist/index-d9vfe7xq.js +16 -0
  169. package/dist/{index-gg8j07zz.js → index-ezmszwbd.js} +8 -6
  170. package/dist/index-fb3zxn06.js +13 -0
  171. package/dist/index-fr0wbhdn.js +43 -0
  172. package/dist/{index-mc22ayvf.js → index-ghc9f0n7.js} +11 -9
  173. package/dist/index-gzcmtmar.js +171 -0
  174. package/dist/{index-w2t4ah5j.js → index-h2py7207.js} +6762 -7400
  175. package/dist/index-h2wc01qk.js +120 -0
  176. package/dist/index-h5zfkjyk.js +1277 -0
  177. package/dist/{index-92bp57hg.js → index-ha87j7a8.js} +1343 -149
  178. package/dist/index-hj2q50k0.js +856 -0
  179. package/dist/{index-wx8a6bw3.js → index-kb9nn0a0.js} +270 -53
  180. package/dist/index-kmpvemph.js +1314 -0
  181. package/dist/index-kp5qe690.js +3030 -0
  182. package/dist/{index-m5fe6jch.js → index-kq57tdf0.js} +152 -2453
  183. package/dist/{v2/server-fq7kq32k.js → index-mfkzp7qj.js} +1 -16
  184. package/dist/{v2/server-njt3np1k.js → index-nm6a8xpd.js} +220 -961
  185. package/dist/{index-hybnrwq0.js → index-nsjyysj0.js} +137 -130
  186. package/dist/index-nydv6g8r.js +3569 -0
  187. package/dist/index-pavzsdc6.js +17 -0
  188. package/dist/index-peshmj6h.js +152 -0
  189. package/dist/index-pxwp2hjk.js +571 -0
  190. package/dist/{v2/server-yr3zj7e7.js → index-qt1qqasc.js} +6 -7
  191. package/dist/{v2/server-51dv1pr5.js → index-qx53vezw.js} +301 -27
  192. package/dist/{index-rrrsepyw.js → index-s4j7t92z.js} +90 -85
  193. package/dist/{index-9pk9exrb.js → index-stbr4ce6.js} +18 -18
  194. package/dist/{index-fzbvakh0.js → index-tqf7yg27.js} +3 -3
  195. package/dist/index-vkbqdnkj.js +2307 -0
  196. package/dist/{index-8da2zjhz.js → index-z1tjp257.js} +9 -7
  197. package/dist/index.d.ts.map +1 -1
  198. package/dist/index.js +608 -349
  199. package/dist/logger-ewak5q1s.js +20 -0
  200. package/dist/message-index-bounded-h0mrd4pr.js +124 -0
  201. package/dist/{v2/message-time-backfill-1f9tzvcs.js → message-time-backfill-8x06r9kx.js} +8 -6
  202. package/dist/migration-worker.js +25 -18
  203. package/dist/{model-resolution-xhfmyyvy.js → model-resolution-nx97z3x7.js} +1 -1
  204. package/dist/plugin/dream-timer.d.ts +1 -1
  205. package/dist/plugin/dream-timer.d.ts.map +1 -1
  206. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -0
  207. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  208. package/dist/plugin/host-stall-profiler-report.d.ts +1 -66
  209. package/dist/plugin/host-stall-profiler-report.d.ts.map +1 -1
  210. package/dist/plugin/host-stall-profiler.d.ts +2 -95
  211. package/dist/plugin/host-stall-profiler.d.ts.map +1 -1
  212. package/dist/plugin/messages-transform.d.ts +0 -13
  213. package/dist/plugin/messages-transform.d.ts.map +1 -1
  214. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  215. package/dist/plugin/tool-registry.d.ts.map +1 -1
  216. package/dist/project-embedding-registry-rtt0djyb.js +88 -0
  217. package/dist/raw-ordinal-warmup-worker.js +60 -0
  218. package/dist/{read-session-chunk-4jey7hpt.js → read-session-chunk-ty89v75e.js} +17 -9
  219. package/dist/read-session-raw-8sjbc9h0.js +60 -0
  220. package/dist/recomp-orchestrator-4f1yyd1q.js +57 -0
  221. package/dist/{v2/safe-notification-target-eb1n1vfb.js → safe-notification-target-q0cyrx3x.js} +4 -2
  222. package/dist/search-pz4f4wge.js +45 -0
  223. package/dist/{v2/send-session-notification-c0wtscea.js → send-session-notification-38cd5dqt.js} +10 -7
  224. package/dist/shared/auto-search-lifecycle.d.ts +14 -0
  225. package/dist/shared/auto-search-lifecycle.d.ts.map +1 -1
  226. package/dist/shared/conflict-detector.d.ts.map +1 -1
  227. package/dist/shared/host-stall-profiler-bun.d.ts +46 -0
  228. package/dist/shared/host-stall-profiler-bun.d.ts.map +1 -0
  229. package/dist/shared/host-stall-profiler-common.d.ts +58 -0
  230. package/dist/shared/host-stall-profiler-common.d.ts.map +1 -0
  231. package/dist/shared/host-stall-profiler-node.d.ts +36 -0
  232. package/dist/shared/host-stall-profiler-node.d.ts.map +1 -0
  233. package/dist/shared/host-stall-profiler-report.d.ts +68 -0
  234. package/dist/shared/host-stall-profiler-report.d.ts.map +1 -0
  235. package/dist/shared/host-stall-profiler.d.ts +5 -0
  236. package/dist/shared/host-stall-profiler.d.ts.map +1 -0
  237. package/dist/shared/logger.d.ts.map +1 -1
  238. package/dist/shared/model-resolution.d.ts +2 -3
  239. package/dist/shared/model-resolution.d.ts.map +1 -1
  240. package/dist/shared/models-dev-temperature.d.ts +18 -0
  241. package/dist/shared/models-dev-temperature.d.ts.map +1 -0
  242. package/dist/shared/project-directory-key.d.ts +16 -0
  243. package/dist/shared/project-directory-key.d.ts.map +1 -1
  244. package/dist/shared/sqlite.d.ts +30 -0
  245. package/dist/shared/sqlite.d.ts.map +1 -1
  246. package/dist/shared/stable-json.d.ts.map +1 -1
  247. package/dist/shared/subagent-temperature.d.ts +46 -0
  248. package/dist/shared/subagent-temperature.d.ts.map +1 -0
  249. package/dist/shared/user-facing-codes.d.ts +0 -5
  250. package/dist/shared/user-facing-codes.d.ts.map +1 -1
  251. package/dist/sqlite-context-pragmas-mv9jqwjh.js +6 -0
  252. package/dist/sqlite-mhjkerzq.js +46 -0
  253. package/dist/storage-memory-07fx57k6.js +71 -0
  254. package/dist/storage-tags-k0pda32s.js +133 -0
  255. package/dist/{task-config-v81k8jvk.js → task-config-cgpg0nvh.js} +2 -2
  256. package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
  257. package/dist/tools/ctx-note/constants.d.ts +4 -0
  258. package/dist/tools/ctx-note/constants.d.ts.map +1 -1
  259. package/dist/tools/ctx-note/tools.d.ts +1 -0
  260. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  261. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  262. package/dist/tools/ctx-search/tools.d.ts.map +1 -1
  263. package/dist/tools/ctx-search/types.d.ts +1 -0
  264. package/dist/tools/ctx-search/types.d.ts.map +1 -1
  265. package/dist/tools/parameter-descriptions.d.ts +2 -2
  266. package/dist/tools/parameter-descriptions.d.ts.map +1 -1
  267. package/dist/{transform-postprocess-phase-z5hzpsxv.js → transform-postprocess-phase-tck4g20s.js} +35 -20
  268. package/dist/transformers-node-wasm.js +18415 -18415
  269. package/dist/v2/auto-search-worker.js +27 -30
  270. package/dist/v2/{context-14v1hr8b.js → context-crbt6p1y.js} +4708 -4218
  271. package/dist/v2/{derive-budgets-nc9avxz8.js → derive-budgets-fgej9j46.js} +4 -3
  272. package/dist/v2/embedding-activity-g1dhes6g.js +10 -0
  273. package/dist/v2/embedding-backfill-ph1qfyn3.js +21 -0
  274. package/dist/v2/embedding-cache-mgyr73ef.js +16 -0
  275. package/dist/v2/embedding-worker.js +12 -9
  276. package/dist/v2/fold/host-media.d.ts +4 -0
  277. package/dist/v2/fold/host-media.d.ts.map +1 -1
  278. package/dist/v2/fold/memory-cache.d.ts +70 -0
  279. package/dist/v2/fold/memory-cache.d.ts.map +1 -0
  280. package/dist/v2/fold/native-codec.d.ts +10 -0
  281. package/dist/v2/fold/native-codec.d.ts.map +1 -0
  282. package/dist/v2/fold/native-replay.d.ts +58 -0
  283. package/dist/v2/fold/native-replay.d.ts.map +1 -0
  284. package/dist/v2/fold/policy.d.ts +24 -0
  285. package/dist/v2/fold/policy.d.ts.map +1 -0
  286. package/dist/v2/harness-e4avh192.js +10 -0
  287. package/dist/v2/hidden-child-native.d.ts.map +1 -1
  288. package/dist/v2/hidden-completion.d.ts +7 -0
  289. package/dist/v2/hidden-completion.d.ts.map +1 -1
  290. package/dist/v2/hooks/context.d.ts +2 -2
  291. package/dist/v2/hooks/context.d.ts.map +1 -1
  292. package/dist/v2/hooks/dream-manual.d.ts +1 -1
  293. package/dist/v2/hooks/dream-manual.d.ts.map +1 -1
  294. package/dist/v2/hooks/dream-timer.d.ts.map +1 -1
  295. package/dist/v2/hooks/dream-trigger.d.ts +5 -3
  296. package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
  297. package/dist/v2/hooks/generate.d.ts +9 -2
  298. package/dist/v2/hooks/generate.d.ts.map +1 -1
  299. package/dist/v2/hooks/payload.d.ts.map +1 -1
  300. package/dist/v2/hooks/tools.d.ts.map +1 -1
  301. package/dist/v2/hooks/types.d.ts +6 -0
  302. package/dist/v2/hooks/types.d.ts.map +1 -1
  303. package/dist/v2/logger-pj02s7sr.js +19 -0
  304. package/dist/v2/message-index-bounded-xwqdywxg.js +123 -0
  305. package/dist/{message-time-backfill-r5epkzj3.js → v2/message-time-backfill-cje68egj.js} +7 -7
  306. package/dist/v2/migration-worker.js +24 -17
  307. package/dist/v2/{model-resolution-xhfmyyvy.js → model-resolution-nx97z3x7.js} +1 -1
  308. package/dist/v2/project-embedding-registry-d6m7tyxr.js +86 -0
  309. package/dist/v2/raw-ordinal-warmup-worker.js +60 -0
  310. package/dist/v2/{read-session-chunk-gyyv7w2r.js → read-session-chunk-8p5mdryx.js} +16 -8
  311. package/dist/v2/read-session-raw-j8dvp7f4.js +59 -0
  312. package/dist/v2/recomp-orchestrator-ckfgt6wq.js +57 -0
  313. package/dist/{safe-notification-target-43r8jsxw.js → v2/safe-notification-target-y3p1hce9.js} +3 -3
  314. package/dist/v2/search-ym8rehhz.js +45 -0
  315. package/dist/{send-session-notification-0m68ms3n.js → v2/send-session-notification-5m0yapqx.js} +9 -8
  316. package/dist/v2/{server-rz514f14.js → server-19zjmn02.js} +2044 -2060
  317. package/dist/v2/server-1tk82krw.js +796 -0
  318. package/dist/v2/server-2bvekkfy.js +11 -0
  319. package/dist/v2/{server-ajzeteqw.js → server-2ra6pwf3.js} +1 -18
  320. package/dist/v2/server-2s6ayq3t.js +1048 -0
  321. package/dist/v2/{server-fcdehk1s.js → server-2s9qz6n7.js} +4 -4
  322. package/dist/v2/server-3j4d00kf.js +171 -0
  323. package/dist/v2/{server-14vq4kpm.js → server-3t0q2cqx.js} +3 -3
  324. package/dist/v2/server-4dhv7mqz.js +131 -0
  325. package/dist/v2/server-4ez8mntn.js +3213 -0
  326. package/dist/v2/{server-6r257mf5.js → server-676xw7at.js} +3 -3
  327. package/dist/v2/{server-vs5gpnd4.js → server-6byqfbqf.js} +165 -145
  328. package/dist/v2/server-7ekna9zs.js +120 -0
  329. package/dist/v2/server-7h861yms.js +1272 -0
  330. package/dist/v2/server-7jzrrxap.js +931 -0
  331. package/dist/v2/server-8ajstryz.js +18 -0
  332. package/dist/v2/{server-sfpzqvdz.js → server-8cd2j99z.js} +2 -3
  333. package/dist/v2/{server-cpepxy2q.js → server-8k2agx29.js} +14 -12
  334. package/dist/v2/server-c5rrgrcd.js +3545 -0
  335. package/dist/v2/server-d9vfe7xq.js +16 -0
  336. package/dist/v2/server-fb3zxn06.js +13 -0
  337. package/dist/v2/server-fr0wbhdn.js +43 -0
  338. package/dist/v2/{server-y10vbq6y.js → server-hb6xhh9q.js} +11 -1053
  339. package/dist/v2/server-jvxzm1jy.js +3023 -0
  340. package/dist/v2/{server-wx8a6bw3.js → server-kb9nn0a0.js} +270 -53
  341. package/dist/{index-5eqk6z3s.js → v2/server-kzns2hbz.js} +301 -27
  342. package/dist/{index-rrbbspwh.js → v2/server-mfkzp7qj.js} +1 -16
  343. package/dist/v2/server-pavzsdc6.js +17 -0
  344. package/dist/v2/{server-vd4e7174.js → server-pj4pjv02.js} +21 -17
  345. package/dist/v2/{server-e0c1b7a7.js → server-q4ph9bwn.js} +1340 -148
  346. package/dist/{index-yr3zj7e7.js → v2/server-qt1qqasc.js} +6 -7
  347. package/dist/v2/{server-qdjnb2z1.js → server-r5p3b1wy.js} +11 -9
  348. package/dist/v2/{server-d0sraw7m.js → server-sa8jvrfc.js} +291 -286
  349. package/dist/v2/server-ss95ky04.js +1048 -0
  350. package/dist/v2/{server-1qbnzc80.js → server-t4k4qexw.js} +142 -150
  351. package/dist/{index-x3kwrmqk.js → v2/server-v4mewb78.js} +35 -792
  352. package/dist/v2/server-w32kmdez.js +154 -0
  353. package/dist/v2/{server-nf82q6pt.js → server-x4hscabv.js} +5547 -5449
  354. package/dist/v2/server-xwz4dqh9.js +569 -0
  355. package/dist/v2/{server-efhwzx05.js → server-ycw9qqcy.js} +23 -23
  356. package/dist/v2/{server-50hvkg3v.js → server-zm570tr2.js} +160 -158
  357. package/dist/v2/server-zp53y8js.js +1311 -0
  358. package/dist/v2/server.js +16 -14
  359. package/dist/v2/sqlite-context-pragmas-mv9jqwjh.js +6 -0
  360. package/dist/v2/sqlite-mhjkerzq.js +46 -0
  361. package/dist/v2/storage-memory-07fx57k6.js +71 -0
  362. package/dist/v2/storage-tags-8vw924zn.js +132 -0
  363. package/dist/v2/store-reader.d.ts +24 -2
  364. package/dist/v2/store-reader.d.ts.map +1 -1
  365. package/dist/v2/{task-config-tbndqyny.js → task-config-x0hq3qfd.js} +2 -2
  366. package/dist/v2/transformers-node-wasm.js +18415 -18415
  367. package/dist/v2/tui/index.d.ts.map +1 -1
  368. package/dist/v2/tui/types.d.ts +1 -10
  369. package/dist/v2/tui/types.d.ts.map +1 -1
  370. package/dist/v2/{wrapup-orchestrator-nbz854vc.js → wrapup-orchestrator-a7efxaax.js} +51 -30
  371. package/dist/wrapup-orchestrator-barbc6h9.js +44 -0
  372. package/package.json +4 -3
  373. package/src/agents/magic-context-prompt.ts +27 -2
  374. package/src/agents/smart-notes-enabled.test.ts +294 -0
  375. package/src/agents/smart-notes-on.golden.json +70 -0
  376. package/src/config/index.test.ts +67 -1
  377. package/src/config/index.ts +2 -0
  378. package/src/config/latch-permanence-guard.test.ts +4 -0
  379. package/src/config/mural-model-deprecation.ts +24 -0
  380. package/src/config/project-security.hostile-matrix.test.ts +4 -44
  381. package/src/config/project-security.test.ts +9 -14
  382. package/src/config/project-security.ts +13 -55
  383. package/src/config/schema/magic-context.test.ts +2 -2
  384. package/src/config/schema/magic-context.ts +16 -10
  385. package/src/features/magic-context/dreamer/task-registry.ts +6 -0
  386. package/src/shared/auto-search-lifecycle.ts +43 -0
  387. package/src/shared/conflict-detector.test.ts +56 -0
  388. package/src/shared/conflict-detector.ts +16 -5
  389. package/src/shared/host-stall-profiler-bun.ts +358 -0
  390. package/src/shared/host-stall-profiler-common.ts +159 -0
  391. package/src/shared/host-stall-profiler-node.test.ts +234 -0
  392. package/src/shared/host-stall-profiler-node.ts +274 -0
  393. package/src/shared/host-stall-profiler-report.ts +248 -0
  394. package/src/shared/host-stall-profiler.ts +57 -0
  395. package/src/shared/logger.test.ts +38 -0
  396. package/src/shared/logger.ts +10 -2
  397. package/src/shared/model-resolution.test.ts +54 -17
  398. package/src/shared/model-resolution.ts +6 -17
  399. package/src/shared/models-dev-temperature.ts +107 -0
  400. package/src/shared/project-directory-key.test.ts +59 -0
  401. package/src/shared/project-directory-key.ts +20 -0
  402. package/src/shared/sqlite.test.ts +52 -0
  403. package/src/shared/sqlite.ts +339 -23
  404. package/src/shared/stable-json-linear.test.ts +109 -0
  405. package/src/shared/stable-json.ts +37 -7
  406. package/src/shared/subagent-temperature.test.ts +270 -0
  407. package/src/shared/subagent-temperature.ts +110 -0
  408. package/src/shared/user-facing-codes.ts +2 -6
  409. package/src/shared/write-transaction-attribution.test.ts +2 -2
  410. package/src/v2/tui/host-contract.test.ts +41 -67
  411. package/src/v2/tui/index.ts +6 -214
  412. package/src/v2/tui/types.ts +5 -17
  413. package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts +0 -45
  414. package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts.map +0 -1
  415. package/dist/features/magic-context/checkout-claim.d.ts +0 -155
  416. package/dist/features/magic-context/checkout-claim.d.ts.map +0 -1
  417. package/dist/index-bb36vgr3.js +0 -6608
  418. package/dist/index-fnn5pjtt.js +0 -6554
  419. package/dist/recomp-orchestrator-rervg6q4.js +0 -42
  420. package/dist/v2/recomp-orchestrator-42vjba7p.js +0 -42
  421. package/dist/v2/server-3trjk1hx.js +0 -6360
  422. package/dist/v2/server-nm9n3aqq.js +0 -6461
  423. package/dist/wrapup-orchestrator-b2dztrar.js +0 -29
  424. /package/dist/{index-5prbx026.js → index-2pp04pmg.js} +0 -0
  425. /package/dist/v2/{index-5prbx026.js → index-2pp04pmg.js} +0 -0
@@ -1,20 +1,27 @@
1
1
  import {
2
- log
3
- } from "./index-hybnrwq0.js";
2
+ Priority,
3
+ AdmissionClass,
4
+ SocketClosedError,
5
+ SocketTimeoutError,
6
+ StaleRouteHandleError,
7
+ SubcClient,
8
+ isConsumerReconnectTransient
9
+ } from "./index-vkbqdnkj.js";
4
10
  import {
5
- resolveWorkspaceShareCategories,
6
- resolveWorkspaceIdentitySet,
7
- expandWorkspaceIdentitySetWithAliases,
8
- resolveStoredPathWorkspaceIdentity,
9
- sourceNameForMemory
10
- } from "./index-x3kwrmqk.js";
11
+ getHarness2
12
+ } from "./index-pavzsdc6.js";
13
+ import {
14
+ getDataDir
15
+ } from "./index-0sahzkwr.js";
16
+ import {
17
+ log2
18
+ } from "./index-nsjyysj0.js";
19
+ import {
20
+ buildCanonicalChunkTextFromFts,
21
+ loadCompartmentChunkEmbeddingsForSearch
22
+ } from "./index-b7mv1jx3.js";
11
23
  import {
12
- loadCompartmentChunkEmbeddingsForSearch,
13
- getIndexedMessageCorpusSize,
14
24
  recordEmbeddingMeasurement,
15
- getNotes,
16
- getActivePrimers,
17
- cosineSimilarity,
18
25
  saveCommitEmbedding,
19
26
  loadProjectCommitEmbeddings,
20
27
  loadUnembeddedCommits,
@@ -22,29 +29,813 @@ import {
22
29
  upsertCommits,
23
30
  getLatestIndexedCommitSha,
24
31
  enforceProjectCap,
25
- getProjectEmbeddings,
26
- contentSha256,
27
- getShadowEmbeddingMeasurementCohort,
28
- getPrimaryEmbeddingMeasurementCohort,
29
- embedShadowTextForProject,
30
- enqueueShadowEmbeddingItems,
31
- getProjectEmbeddingSnapshot,
32
- embedItemsForProject,
32
+ contentSha2562,
33
+ getShadowEmbeddingMeasurementCohort2,
34
+ getPrimaryEmbeddingMeasurementCohort2,
35
+ embedShadowTextForProject2,
36
+ enqueueShadowEmbeddingItems2,
37
+ getProjectEmbeddingSnapshot2,
38
+ embedItemsForProject2
39
+ } from "./index-kp5qe690.js";
40
+ import {
41
+ getProjectEmbeddings2
42
+ } from "./index-4dhv7mqz.js";
43
+ import {
44
+ cosineSimilarity,
33
45
  isEmbeddingEnabled,
34
46
  embedText,
35
- ensureMemoryEmbeddings,
36
- ModuleMemoryAuthorityError,
37
- getMemoriesByProject,
38
- getMemoriesByProjects,
39
- updateMemoryRetrievalCount,
47
+ ensureMemoryEmbeddings2
48
+ } from "./index-peshmj6h.js";
49
+ import {
50
+ ModuleMemoryAuthorityError2,
51
+ getMemoriesByProject2,
52
+ getMemoriesByProjects2,
53
+ updateMemoryRetrievalCount2
54
+ } from "./index-7jzrrxap.js";
55
+ import {
56
+ USER_FACING_FAILURES,
57
+ getNotes,
58
+ getActivePrimers,
40
59
  relaxedFtsQuery,
41
60
  sanitizeFtsQuery,
42
61
  searchMemoriesFTS,
43
62
  searchMemoriesFTSUnion
44
- } from "./index-fnn5pjtt.js";
63
+ } from "./index-kmpvemph.js";
64
+ import {
65
+ isRecord
66
+ } from "./index-nydv6g8r.js";
67
+ import {
68
+ getIndexedMessageCorpusSize
69
+ } from "./index-hj2q50k0.js";
70
+ import {
71
+ resolveWorkspaceShareCategories,
72
+ resolveWorkspaceIdentitySet,
73
+ expandWorkspaceIdentitySetWithAliases,
74
+ resolveStoredPathWorkspaceIdentity,
75
+ sourceNameForMemory
76
+ } from "./index-nm6a8xpd.js";
45
77
  import {
46
78
  isKnownAutocommit
47
- } from "./index-b35pxds2.js";
79
+ } from "./index-8ajstryz.js";
80
+
81
+ // src/hooks/magic-context/module-transport.ts
82
+ import { realpathSync } from "node:fs";
83
+ import { join } from "node:path";
84
+
85
+ // src/hooks/magic-context/reply-pages.ts
86
+ import { createHash } from "node:crypto";
87
+ var MAX_REPLY_BYTES = 128 * 1024 * 1024;
88
+ var MAX_PAGE_BYTES = 512 * 1024;
89
+ function fail() {
90
+ throw Object.assign(new Error("Incomplete or invalid module reply; abandon this pass"), {
91
+ code: "reply_page_invalid"
92
+ });
93
+ }
94
+ async function assembleReplyPages(response, fetchPage) {
95
+ if (!isRecord(response) || !("reply_page" in response))
96
+ return response;
97
+ const first = response.reply_page;
98
+ if (!isRecord(first))
99
+ fail();
100
+ const { id, total, bytes } = first;
101
+ if (typeof id !== "string" || !/^[a-f0-9]{64}$/.test(id) || typeof total !== "number" || !Number.isSafeInteger(total) || total < 2 || total > 4096 || typeof bytes !== "number" || !Number.isSafeInteger(bytes) || bytes <= 0 || bytes > MAX_REPLY_BYTES)
102
+ fail();
103
+ const chunks = [];
104
+ let received = 0;
105
+ for (let index = 0;index < total; index += 1) {
106
+ const envelope = index === 0 ? response : await fetchPage(id, index);
107
+ if (!isRecord(envelope) || !isRecord(envelope.reply_page))
108
+ fail();
109
+ const page = envelope.reply_page;
110
+ if (page.id !== id || page.index !== index || page.total !== total || page.bytes !== bytes || typeof page.data !== "string")
111
+ fail();
112
+ if (Buffer.byteLength(JSON.stringify(envelope)) > MAX_PAGE_BYTES)
113
+ fail();
114
+ const chunk = Buffer.from(page.data, "utf8");
115
+ received += chunk.length;
116
+ if (received > bytes)
117
+ fail();
118
+ chunks.push(chunk);
119
+ }
120
+ if (received !== bytes)
121
+ fail();
122
+ const rebuilt = Buffer.concat(chunks, received);
123
+ if (createHash("sha256").update(rebuilt).digest("hex") !== id)
124
+ fail();
125
+ return JSON.parse(rebuilt.toString("utf8"));
126
+ }
127
+
128
+ // src/hooks/magic-context/single-store-refusal.ts
129
+ var SINGLE_STORE_MIGRATION_REQUIRED_CODE = "single_store_migration_required";
130
+ function renderSingleStoreMigrationRequiredRefusal() {
131
+ const failure = USER_FACING_FAILURES.single_store_migration_required;
132
+ return `${failure.sentence} ${failure.action} (${failure.code})`;
133
+ }
134
+
135
+ class SingleStoreMigrationRequiredError extends Error {
136
+ code = SINGLE_STORE_MIGRATION_REQUIRED_CODE;
137
+ constructor(options) {
138
+ super(renderSingleStoreMigrationRequiredRefusal(), options);
139
+ this.name = "SingleStoreMigrationRequiredError";
140
+ }
141
+ }
142
+ function singleStoreMigrationRequiredFailure(error) {
143
+ let current = error;
144
+ const seen = new Set;
145
+ while (current !== null && typeof current === "object" && !seen.has(current)) {
146
+ seen.add(current);
147
+ if (current instanceof SingleStoreMigrationRequiredError)
148
+ return current;
149
+ const frame = current;
150
+ if (frame.code === SINGLE_STORE_MIGRATION_REQUIRED_CODE || frame.code === "single_store_state_split") {
151
+ return new SingleStoreMigrationRequiredError({ cause: error });
152
+ }
153
+ current = frame.cause;
154
+ }
155
+ return null;
156
+ }
157
+ function projectNeedsSingleStoreMigration(db, projectPath) {
158
+ const table = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'authority_managed'").get();
159
+ return Boolean(table && db.prepare("SELECT 1 FROM authority_managed WHERE project_path = ?").get(projectPath));
160
+ }
161
+
162
+ // src/hooks/magic-context/store-ahead-refusal.ts
163
+ var STORE_AHEAD_OF_BINARY_CODE = "store_ahead_of_binary";
164
+ function renderStoreAheadOfBinaryRefusal(versions) {
165
+ const failure = USER_FACING_FAILURES.store_ahead_of_binary;
166
+ const sentence = versions ? `Magic Context refused to start: its store (store.db) is at schema v${versions.dbVersion} but this ck-mc build only knows up to v${versions.binaryMax}.` : failure.sentence;
167
+ return `${sentence} ${failure.action} (${failure.code})`;
168
+ }
169
+
170
+ class StoreAheadOfBinaryError extends Error {
171
+ code = STORE_AHEAD_OF_BINARY_CODE;
172
+ versions;
173
+ constructor(versions, options) {
174
+ super(renderStoreAheadOfBinaryRefusal(versions), options);
175
+ this.name = "StoreAheadOfBinaryError";
176
+ this.versions = versions;
177
+ }
178
+ }
179
+ function isRecord2(value) {
180
+ return value !== null && typeof value === "object";
181
+ }
182
+ function nonNegativeInteger(value) {
183
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : null;
184
+ }
185
+ function versionsFromDetail(detail) {
186
+ if (!isRecord2(detail))
187
+ return null;
188
+ const dbVersion = nonNegativeInteger(detail.db_version);
189
+ const binaryMax = nonNegativeInteger(detail.binary_max);
190
+ return dbVersion !== null && binaryMax !== null ? { dbVersion, binaryMax } : null;
191
+ }
192
+ function versionsFromMessage(message) {
193
+ if (typeof message !== "string")
194
+ return null;
195
+ const match = /db_version=(\d+) binary_max=(\d+)/.exec(message) ?? /schema v(\d+) but this ck-mc build only knows up to v(\d+)/.exec(message);
196
+ if (!match)
197
+ return null;
198
+ return { dbVersion: Number(match[1]), binaryMax: Number(match[2]) };
199
+ }
200
+ function storeAheadOfBinaryFailure(error) {
201
+ let current = error;
202
+ const seen = new Set;
203
+ while (isRecord2(current) && !seen.has(current)) {
204
+ seen.add(current);
205
+ if (current instanceof StoreAheadOfBinaryError)
206
+ return current;
207
+ if (current.code === STORE_AHEAD_OF_BINARY_CODE) {
208
+ const versions = versionsFromDetail(current.detail) ?? versionsFromMessage(current.message);
209
+ return new StoreAheadOfBinaryError(versions, { cause: error });
210
+ }
211
+ current = current.cause;
212
+ }
213
+ return null;
214
+ }
215
+
216
+ // src/hooks/magic-context/module-transport.ts
217
+ var DEFAULT_MODULE_ID = "magic-context";
218
+ var CONNECT_BACKOFF_INITIAL_MS = 1000;
219
+ var CONNECT_BACKOFF_MAX_MS = 30000;
220
+ var CONNECT_BACKOFF_WAIT_BUDGET_MS = 12000;
221
+ var CONNECT_BACKOFF_WAIT_JITTER_MS = 100;
222
+ var HANDSHAKE_TIMEOUT_MS = 2000;
223
+ var MODULE_SEND_TIMEOUT_MS = 15000;
224
+ var TRANSFORM_PAGE_UPLOAD_TIMEOUT_MS = 5000;
225
+ var TRANSFORM_COLD_START_EXECUTE_TIMEOUT_MS = 15000;
226
+ var TRANSFORM_COLD_START_EXECUTE_TIMEOUT_PER_MESSAGE_MS = 2;
227
+ var TRANSFORM_COLD_START_EXECUTE_TIMEOUT_MAX_MS = 90000;
228
+ function transformColdStartExecuteTimeoutMs(seedMessageCount) {
229
+ const messages = Number.isSafeInteger(seedMessageCount) ? Math.max(0, seedMessageCount) : 0;
230
+ return Math.min(TRANSFORM_COLD_START_EXECUTE_TIMEOUT_MAX_MS, TRANSFORM_COLD_START_EXECUTE_TIMEOUT_MS + messages * TRANSFORM_COLD_START_EXECUTE_TIMEOUT_PER_MESSAGE_MS);
231
+ }
232
+ var MAX_WRAPUP_REQUEST_BUDGET_MS = 3800000;
233
+ var SERIAL_LANE_MAX_WAITERS = 16;
234
+ var SERIAL_LANE_MAX_WAITERS_PER_SESSION = 8;
235
+ var SERIAL_LANE_MIN_REMAINING_MS = 25;
236
+ var CANONICAL_ROOT_CACHE_MAX_ENTRIES = 256;
237
+ function getDefaultSubcConnectionFile() {
238
+ return join(getDataDir(), "cortexkit", "run", "subc-connection.json");
239
+ }
240
+ function errorChainSome(error, predicate) {
241
+ let current = error;
242
+ const seen = new Set;
243
+ while (isRecord(current) && !seen.has(current)) {
244
+ seen.add(current);
245
+ if (predicate(current))
246
+ return true;
247
+ current = current.cause;
248
+ }
249
+ return false;
250
+ }
251
+ function isStaleOrDeadRouteFailure(error) {
252
+ return errorChainSome(error, (current) => {
253
+ const code = typeof current.code === "string" ? current.code : "";
254
+ const name = typeof current.name === "string" ? current.name : "";
255
+ const message = typeof current.message === "string" ? current.message : "";
256
+ return [
257
+ "stale_route_handle",
258
+ "route_closed",
259
+ "unknown_channel",
260
+ "unrecognized_channel",
261
+ "route_gone"
262
+ ].includes(code) || name === "StaleRouteHandleError" || /route handle \(\d+,\s*\d+\) is not live on the current connection/i.test(message) || /\b(?:unknown|unrecognized) channel\b/i.test(message);
263
+ });
264
+ }
265
+ function isDeadlineFailure(error) {
266
+ if (error instanceof SocketTimeoutError)
267
+ return true;
268
+ return errorChainSome(error, (current) => {
269
+ const code = typeof current.code === "string" ? current.code : "";
270
+ return ["ETIMEDOUT", "request_deadline", "deadline_exceeded_no_drop_observed"].includes(code);
271
+ });
272
+ }
273
+ function isConnectionFailure(error) {
274
+ if (error instanceof SocketClosedError || error instanceof SocketTimeoutError || error instanceof StaleRouteHandleError || isConsumerReconnectTransient(error) || isStaleOrDeadRouteFailure(error)) {
275
+ return true;
276
+ }
277
+ return errorChainSome(error, (current) => {
278
+ const code = typeof current.code === "string" ? current.code : "";
279
+ const message = typeof current.message === "string" ? current.message : "";
280
+ return [
281
+ "ENOENT",
282
+ "ECONNREFUSED",
283
+ "ECONNRESET",
284
+ "EPIPE",
285
+ "ETIMEDOUT",
286
+ "request_deadline",
287
+ "deadline_exceeded_no_drop_observed",
288
+ "connection_dropped",
289
+ "SUBC_CONNECTION_BACKOFF"
290
+ ].includes(code) || /\bclient closed\b|\bconnection closed\b|\bclosed the connection\b/i.test(message);
291
+ });
292
+ }
293
+ function routeOpenWithoutAmbientConsumerIdentity(client, target, identity, options = {}) {
294
+ return client.routeOpen(target, identity, {
295
+ ...options,
296
+ consumerIdentity: null
297
+ });
298
+ }
299
+ function isModuleTransportGenerationChangedResult(value) {
300
+ return isRecord(value) && value.transport_status === "connection_generation_changed" && typeof value.previous_generation === "number" && typeof value.current_generation === "number";
301
+ }
302
+ function moduleRequestBody(body, method) {
303
+ if (!isRecord(body))
304
+ return body;
305
+ const facade = typeof body.name === "string" && isRecord(body.arguments);
306
+ return { ...body, ...facade ? {} : { method }, accept_reply_pages: true };
307
+ }
308
+
309
+ class SubcModuleTransport {
310
+ connectionFile;
311
+ moduleId;
312
+ requestTimeoutMs;
313
+ routeSessionPrefix;
314
+ client = null;
315
+ routes = new Map;
316
+ routeOpenings = new Map;
317
+ canonicalRootCache = new Map;
318
+ sessionLanes = new Map;
319
+ queuedLaneWaiters = 0;
320
+ wrapupSessions = new Map;
321
+ nextProbeMs = 0;
322
+ connectionPromise = null;
323
+ backoffMs = CONNECT_BACKOFF_INITIAL_MS;
324
+ connectionGeneration = 0;
325
+ stateSyncCapabilityCache = null;
326
+ getCachedStateSyncCapabilities() {
327
+ const cached = this.stateSyncCapabilityCache;
328
+ if (!cached || cached.generation !== this.connectionGeneration)
329
+ return;
330
+ return cached.capabilities;
331
+ }
332
+ invalidateStateSyncCapabilities() {
333
+ this.stateSyncCapabilityCache = null;
334
+ }
335
+ async stateSyncCapabilities(args) {
336
+ const cached = this.getCachedStateSyncCapabilities();
337
+ if (cached)
338
+ return cached;
339
+ const response = await this.call({
340
+ sessionId: args.sessionId,
341
+ projectRoot: args.projectRoot,
342
+ method: "session.status",
343
+ body: { method: "session.status", v: 1, session_id: args.sessionId }
344
+ });
345
+ const raw = isRecord(response) ? response : {};
346
+ const value = isRecord(raw.result) ? raw.result : raw;
347
+ const epochs = isRecord(value.epochs) ? value.epochs : {};
348
+ const capabilities = {
349
+ state_sync_deltas: epochs.state_sync_deltas === true,
350
+ ...epochs.state_sync_resume === true ? { state_sync_resume: true } : {}
351
+ };
352
+ this.stateSyncCapabilityCache = { generation: this.connectionGeneration, capabilities };
353
+ return capabilities;
354
+ }
355
+ constructor(connectionFile, moduleId = DEFAULT_MODULE_ID, requestTimeoutMs = MODULE_SEND_TIMEOUT_MS, routeSessionPrefix = "") {
356
+ this.connectionFile = connectionFile;
357
+ this.moduleId = moduleId;
358
+ this.requestTimeoutMs = requestTimeoutMs;
359
+ this.routeSessionPrefix = routeSessionPrefix;
360
+ }
361
+ deadlineError(detail) {
362
+ const error = new Error(`module transport deadline expired ${detail}`);
363
+ error.code = "ETIMEDOUT";
364
+ return error;
365
+ }
366
+ laneTimeoutError() {
367
+ return this.deadlineError("while queued");
368
+ }
369
+ connectionChangedError(detail) {
370
+ const error = new Error(detail);
371
+ error.code = "ECONNRESET";
372
+ return error;
373
+ }
374
+ async beforeDeadline(operation, deadlineMs, detail) {
375
+ operation.catch(() => {});
376
+ const remainingMs = deadlineMs - Date.now();
377
+ if (remainingMs <= 0)
378
+ throw this.deadlineError(detail);
379
+ let timer;
380
+ try {
381
+ return await Promise.race([
382
+ operation,
383
+ new Promise((_resolve, reject) => {
384
+ timer = setTimeout(() => reject(this.deadlineError(detail)), remainingMs);
385
+ })
386
+ ]);
387
+ } finally {
388
+ if (timer)
389
+ clearTimeout(timer);
390
+ }
391
+ }
392
+ cleanupLane(sessionId, lane) {
393
+ if (!lane.active && lane.waiters.length === 0 && this.sessionLanes.get(sessionId) === lane) {
394
+ this.sessionLanes.delete(sessionId);
395
+ }
396
+ }
397
+ laneRelease(sessionId, lane) {
398
+ let released = false;
399
+ return () => {
400
+ if (released)
401
+ return;
402
+ released = true;
403
+ lane.active = false;
404
+ this.dispatchNextLaneWaiter(sessionId, lane);
405
+ };
406
+ }
407
+ dispatchNextLaneWaiter(sessionId, lane) {
408
+ if (lane.active)
409
+ return;
410
+ while (lane.waiters.length > 0) {
411
+ const waiter = lane.waiters.shift();
412
+ if (!waiter)
413
+ continue;
414
+ this.queuedLaneWaiters = Math.max(0, this.queuedLaneWaiters - 1);
415
+ if (waiter.settled)
416
+ continue;
417
+ waiter.settled = true;
418
+ clearTimeout(waiter.timer);
419
+ waiter.signal?.removeEventListener("abort", waiter.onAbort);
420
+ if (waiter.signal?.aborted) {
421
+ waiter.reject(waiter.signal.reason ?? new Error("module transport call aborted"));
422
+ continue;
423
+ }
424
+ if (waiter.deadlineMs - Date.now() < SERIAL_LANE_MIN_REMAINING_MS) {
425
+ waiter.reject(this.laneTimeoutError());
426
+ continue;
427
+ }
428
+ lane.active = true;
429
+ waiter.resolve(this.laneRelease(sessionId, lane));
430
+ return;
431
+ }
432
+ this.cleanupLane(sessionId, lane);
433
+ }
434
+ queueFullError() {
435
+ const error = new Error("module transport queue is full");
436
+ error.code = "EBUSY";
437
+ return error;
438
+ }
439
+ acquireCorrectnessLane(sessionId, signal, deadlineMs) {
440
+ if (signal?.aborted) {
441
+ return Promise.reject(signal.reason ?? new Error("module transport call aborted"));
442
+ }
443
+ if (deadlineMs - Date.now() < SERIAL_LANE_MIN_REMAINING_MS) {
444
+ return Promise.reject(this.laneTimeoutError());
445
+ }
446
+ const lane = this.sessionLanes.get(sessionId) ?? { active: false, waiters: [] };
447
+ this.sessionLanes.set(sessionId, lane);
448
+ if (!lane.active && lane.waiters.length === 0) {
449
+ lane.active = true;
450
+ return Promise.resolve(this.laneRelease(sessionId, lane));
451
+ }
452
+ if (this.queuedLaneWaiters >= SERIAL_LANE_MAX_WAITERS || lane.waiters.length >= SERIAL_LANE_MAX_WAITERS_PER_SESSION) {
453
+ return Promise.reject(this.queueFullError());
454
+ }
455
+ return new Promise((resolve, reject) => {
456
+ const waiter = {};
457
+ const removeAndReject = (error) => {
458
+ if (waiter.settled)
459
+ return;
460
+ waiter.settled = true;
461
+ clearTimeout(waiter.timer);
462
+ signal?.removeEventListener("abort", waiter.onAbort);
463
+ const index = lane.waiters.indexOf(waiter);
464
+ if (index >= 0) {
465
+ lane.waiters.splice(index, 1);
466
+ this.queuedLaneWaiters = Math.max(0, this.queuedLaneWaiters - 1);
467
+ }
468
+ reject(error);
469
+ this.cleanupLane(sessionId, lane);
470
+ };
471
+ waiter.signal = signal;
472
+ waiter.deadlineMs = deadlineMs;
473
+ waiter.resolve = resolve;
474
+ waiter.reject = reject;
475
+ waiter.settled = false;
476
+ waiter.onAbort = () => removeAndReject(signal?.reason ?? new Error("module transport call aborted"));
477
+ waiter.timer = setTimeout(() => removeAndReject(this.laneTimeoutError()), Math.max(0, deadlineMs - Date.now()));
478
+ signal?.addEventListener("abort", waiter.onAbort, { once: true });
479
+ lane.waiters.push(waiter);
480
+ this.queuedLaneWaiters += 1;
481
+ });
482
+ }
483
+ async call(args) {
484
+ const callStartedAt = performance.now();
485
+ const timings = {
486
+ lane: 0,
487
+ route: 0,
488
+ encode: 0,
489
+ issue: 0,
490
+ responseWait: 0,
491
+ settle: 0
492
+ };
493
+ const wrapupInFlight = (this.wrapupSessions.get(args.sessionId) ?? 0) > 0;
494
+ const attemptTimeoutMs = args.timeoutMs ?? (args.method === "session.wrapup" || args.method === "session.status" && wrapupInFlight ? MAX_WRAPUP_REQUEST_BUDGET_MS : args.attemptClass === "transform_series_execute" ? TRANSFORM_COLD_START_EXECUTE_TIMEOUT_MS : args.method === "transform" ? Math.min(this.requestTimeoutMs, TRANSFORM_PAGE_UPLOAD_TIMEOUT_MS) : this.requestTimeoutMs);
495
+ const tracksWrapup = args.method === "session.wrapup";
496
+ if (tracksWrapup) {
497
+ this.wrapupSessions.set(args.sessionId, (this.wrapupSessions.get(args.sessionId) ?? 0) + 1);
498
+ }
499
+ const finishWrapupTracking = () => {
500
+ if (!tracksWrapup)
501
+ return;
502
+ const remaining = (this.wrapupSessions.get(args.sessionId) ?? 1) - 1;
503
+ if (remaining > 0)
504
+ this.wrapupSessions.set(args.sessionId, remaining);
505
+ else
506
+ this.wrapupSessions.delete(args.sessionId);
507
+ };
508
+ const laneDeadlineMs = Date.now() + attemptTimeoutMs;
509
+ let releaseLane = () => {};
510
+ try {
511
+ const outsideSessionOrder = args.method.startsWith("historian.");
512
+ if (!args.bypassSessionLane && !outsideSessionOrder) {
513
+ releaseLane = await this.acquireCorrectnessLane(args.sessionId, args.signal, laneDeadlineMs);
514
+ }
515
+ } catch (error) {
516
+ finishWrapupTracking();
517
+ if (args.method === "state_sync" && isDeadlineFailure(error)) {
518
+ const body = isRecord(args.body) ? args.body : {};
519
+ throw Object.assign(new Error(`state_sync timeout stage=correctness_lane page=${body.seed_batch_index ?? 0}/${body.seed_batch_total ?? 1} series=${body.seed_id ?? "delta"} budget_ms=${attemptTimeoutMs}`), {
520
+ code: "state_sync_timeout",
521
+ stage: "correctness_lane",
522
+ page: body.seed_batch_index ?? 0,
523
+ pages: body.seed_batch_total ?? 1,
524
+ series: body.seed_id ?? null,
525
+ cause: error
526
+ });
527
+ }
528
+ throw error;
529
+ }
530
+ timings.lane = performance.now() - callStartedAt;
531
+ let rejectAbort;
532
+ const aborted = new Promise((_resolve, reject) => {
533
+ rejectAbort = reject;
534
+ });
535
+ aborted.catch(() => {});
536
+ const onAbort = () => rejectAbort(args.signal?.reason ?? new Error("module transport call aborted"));
537
+ args.signal?.addEventListener("abort", onAbort, { once: true });
538
+ try {
539
+ for (let attempt = 0;attempt < 2; attempt += 1) {
540
+ let ensuredRoute = null;
541
+ let initialResponseReceived = false;
542
+ try {
543
+ if (args.signal?.aborted) {
544
+ throw args.signal.reason ?? new Error("module transport call aborted");
545
+ }
546
+ const attemptDeadlineMs = Date.now() + attemptTimeoutMs;
547
+ const routeStartedAt = performance.now();
548
+ ensuredRoute = await this.ensureRoute(args.sessionId, args.projectRoot, attemptDeadlineMs, args.signal);
549
+ if (args.signal?.aborted) {
550
+ throw args.signal.reason ?? new Error("module transport call aborted");
551
+ }
552
+ timings.route += performance.now() - routeStartedAt;
553
+ const encodeStartedAt = performance.now();
554
+ const body = args.body instanceof Uint8Array ? args.body : Buffer.from(JSON.stringify(moduleRequestBody(args.body, args.method)));
555
+ timings.encode += performance.now() - encodeStartedAt;
556
+ const issueStartedAt = performance.now();
557
+ const request = ensuredRoute.client.request(ensuredRoute.route, body, {
558
+ priority: Priority.Background,
559
+ admissionClass: AdmissionClass.Normal,
560
+ timeoutMs: Math.max(1, attemptDeadlineMs - Date.now())
561
+ });
562
+ timings.issue += performance.now() - issueStartedAt;
563
+ const waitStartedAt = performance.now();
564
+ const response = await this.beforeDeadline(Promise.race([request, aborted]), attemptDeadlineMs, "waiting for the module response");
565
+ timings.responseWait += performance.now() - waitStartedAt;
566
+ initialResponseReceived = true;
567
+ if (this.client !== ensuredRoute.client || this.connectionGeneration !== ensuredRoute.generation) {
568
+ throw this.connectionChangedError("subc connection changed while awaiting the module response");
569
+ }
570
+ const pageRoute = ensuredRoute;
571
+ const assembled = await assembleReplyPages(response, async (id, index) => {
572
+ if (args.signal?.aborted)
573
+ throw args.signal.reason;
574
+ const page = await this.beforeDeadline(Promise.race([
575
+ pageRoute.client.request(pageRoute.route, Buffer.from(JSON.stringify({
576
+ method: "reply.page",
577
+ reply_page_id: id,
578
+ reply_page_index: index
579
+ })), {
580
+ priority: Priority.Background,
581
+ admissionClass: AdmissionClass.Normal,
582
+ timeoutMs: Math.max(1, attemptDeadlineMs - Date.now())
583
+ }),
584
+ aborted
585
+ ]), attemptDeadlineMs, "waiting for a module reply page");
586
+ if (this.client !== pageRoute.client || this.connectionGeneration !== pageRoute.generation) {
587
+ throw this.connectionChangedError("subc connection changed during reply paging");
588
+ }
589
+ return page;
590
+ });
591
+ return assembled;
592
+ } catch (error) {
593
+ if (args.signal?.aborted)
594
+ throw args.signal.reason ?? error;
595
+ const migration = singleStoreMigrationRequiredFailure(error);
596
+ if (migration)
597
+ throw migration;
598
+ const storeAhead = storeAheadOfBinaryFailure(error);
599
+ if (storeAhead)
600
+ throw storeAhead;
601
+ if (args.method === "state_sync" && isDeadlineFailure(error)) {
602
+ const body = isRecord(args.body) ? args.body : {};
603
+ throw Object.assign(new Error(`state_sync timeout stage=module_ack page=${body.seed_batch_index ?? 0}/${body.seed_batch_total ?? 1} series=${body.seed_id ?? "delta"} budget_ms=${attemptTimeoutMs}`), {
604
+ code: "state_sync_timeout",
605
+ stage: "module_ack",
606
+ page: body.seed_batch_index ?? 0,
607
+ pages: body.seed_batch_total ?? 1,
608
+ series: body.seed_id ?? null,
609
+ cause: error
610
+ });
611
+ }
612
+ if (args.attemptClass === "transform_series_execute" && isDeadlineFailure(error)) {
613
+ throw error;
614
+ }
615
+ if (isConnectionFailure(error)) {
616
+ const previousGeneration = ensuredRoute?.generation ?? this.connectionGeneration;
617
+ if (ensuredRoute) {
618
+ this.dropRoute(ensuredRoute.routeKey, ensuredRoute.route);
619
+ this.invalidateConnection(ensuredRoute.client);
620
+ } else {
621
+ this.invalidateConnection();
622
+ }
623
+ const locallyUnsent = isRecord(error) && error.name === "StaleRouteHandleError" && error.code === "stale_route_handle";
624
+ if (attempt === 0 && ensuredRoute && !initialResponseReceived && locallyUnsent && !args.generationSensitive) {
625
+ continue;
626
+ }
627
+ if (args.method === "transform") {
628
+ if (!ensuredRoute)
629
+ throw error;
630
+ throw Object.assign(new Error("Transform transport interrupted; abandon this pass"), { code: "transform_transport_interrupted", cause: error });
631
+ }
632
+ if (args.generationSensitive && !args.signal?.aborted) {
633
+ return {
634
+ transport_status: "connection_generation_changed",
635
+ previous_generation: previousGeneration,
636
+ current_generation: this.connectionGeneration
637
+ };
638
+ }
639
+ if (attempt === 0 && !args.signal?.aborted)
640
+ continue;
641
+ }
642
+ throw error;
643
+ }
644
+ }
645
+ throw new Error("module transport route retry exhausted");
646
+ } finally {
647
+ args.signal?.removeEventListener("abort", onAbort);
648
+ finishWrapupTracking();
649
+ releaseLane();
650
+ timings.settle = Math.max(0, performance.now() - callStartedAt - timings.lane - timings.route - timings.encode - timings.issue - timings.responseWait);
651
+ args.onTimings?.(timings);
652
+ }
653
+ }
654
+ async deleteSession(sessionId, projectRoot) {
655
+ await this.call({
656
+ sessionId,
657
+ projectRoot,
658
+ method: "session.delete",
659
+ body: { method: "session.delete", v: 1, session_id: sessionId }
660
+ });
661
+ }
662
+ closeSession(sessionId) {
663
+ const client = this.client;
664
+ const prefix = `${sessionId}\x00`;
665
+ const routes = [...this.routes.entries()].filter(([key]) => key.startsWith(prefix));
666
+ for (const [key, cachedRoute] of routes) {
667
+ this.routes.delete(key);
668
+ if (client) {
669
+ client.closeRoute(cachedRoute.route).catch((error) => {
670
+ if (this.client === client && isConnectionFailure(error)) {
671
+ this.invalidateConnection(client);
672
+ }
673
+ });
674
+ }
675
+ }
676
+ if (routes.length === 0 && this.sessionLanes.get(sessionId)?.active) {
677
+ this.invalidateConnection(client);
678
+ }
679
+ }
680
+ async ensureRoute(sessionId, rawProjectRoot, deadlineMs = Date.now() + this.requestTimeoutMs, signal) {
681
+ const projectRoot = this.canonicalRoot(rawProjectRoot);
682
+ const routeKey = `${sessionId}\x00${projectRoot}`;
683
+ const client = await this.ensureConnected(signal);
684
+ const generation = this.connectionGeneration;
685
+ const existing = this.routes.get(routeKey);
686
+ if (existing?.generation === generation) {
687
+ return { client, route: existing.route, routeKey, generation };
688
+ }
689
+ if (existing)
690
+ this.routes.delete(routeKey);
691
+ const opening = this.routeOpenings.get(routeKey);
692
+ if (opening?.client === client && opening.generation === generation) {
693
+ return await opening.promise;
694
+ }
695
+ const promise = (async () => {
696
+ const target = { kind: "tool_provider", module_id: this.moduleId };
697
+ const identity = {
698
+ project_root: projectRoot,
699
+ harness: getHarness2(),
700
+ session: `${this.routeSessionPrefix}${sessionId}`
701
+ };
702
+ const route = await this.beforeDeadline(routeOpenWithoutAmbientConsumerIdentity(client, target, identity), deadlineMs, "opening the module route");
703
+ if (this.client !== client || generation !== this.connectionGeneration) {
704
+ await client.closeRoute(route).catch(() => {
705
+ return;
706
+ });
707
+ throw this.connectionChangedError("subc connection changed while opening module route");
708
+ }
709
+ this.routes.set(routeKey, { route, generation });
710
+ return { client, route, routeKey, generation };
711
+ })();
712
+ const routeOpening = { client, generation, promise };
713
+ this.routeOpenings.set(routeKey, routeOpening);
714
+ try {
715
+ return await promise;
716
+ } finally {
717
+ if (this.routeOpenings.get(routeKey) === routeOpening) {
718
+ this.routeOpenings.delete(routeKey);
719
+ }
720
+ }
721
+ }
722
+ dropRoute(routeKey, route) {
723
+ const existing = this.routes.get(routeKey);
724
+ if (!existing || route && existing.route !== route)
725
+ return;
726
+ this.routes.delete(routeKey);
727
+ }
728
+ canonicalRoot(root) {
729
+ const cached = this.canonicalRootCache.get(root);
730
+ if (cached !== undefined) {
731
+ this.canonicalRootCache.delete(root);
732
+ this.canonicalRootCache.set(root, cached);
733
+ return cached;
734
+ }
735
+ let resolved = root;
736
+ try {
737
+ resolved = realpathSync.native(root);
738
+ } catch {}
739
+ this.canonicalRootCache.set(root, resolved);
740
+ while (this.canonicalRootCache.size > CANONICAL_ROOT_CACHE_MAX_ENTRIES) {
741
+ const oldestRoot = this.canonicalRootCache.keys().next().value;
742
+ if (oldestRoot === undefined)
743
+ break;
744
+ this.canonicalRootCache.delete(oldestRoot);
745
+ }
746
+ return resolved;
747
+ }
748
+ connectClient() {
749
+ return SubcClient.connect({
750
+ connectionFile: this.connectionFile,
751
+ handshakeTimeoutMs: HANDSHAKE_TIMEOUT_MS
752
+ });
753
+ }
754
+ backoffActiveError() {
755
+ const error = new Error(`subc connection backoff active until ${this.nextProbeMs}`);
756
+ error.code = "SUBC_CONNECTION_BACKOFF";
757
+ return error;
758
+ }
759
+ sleepAbortable(durationMs, signal) {
760
+ return new Promise((resolve, reject) => {
761
+ if (signal?.aborted) {
762
+ reject(signal.reason ?? new Error("module transport call aborted"));
763
+ return;
764
+ }
765
+ const onAbort = () => {
766
+ clearTimeout(timer);
767
+ signal?.removeEventListener("abort", onAbort);
768
+ reject(signal?.reason ?? new Error("module transport call aborted"));
769
+ };
770
+ const timer = setTimeout(() => {
771
+ signal?.removeEventListener("abort", onAbort);
772
+ resolve();
773
+ }, Math.max(0, durationMs));
774
+ signal?.addEventListener("abort", onAbort, { once: true });
775
+ });
776
+ }
777
+ async ensureConnected(signal) {
778
+ if (this.client)
779
+ return this.client;
780
+ if (this.connectionPromise)
781
+ return await this.connectionPromise;
782
+ let now = Date.now();
783
+ if (now < this.nextProbeMs) {
784
+ const remainingMs = this.nextProbeMs - now;
785
+ if (remainingMs > CONNECT_BACKOFF_WAIT_BUDGET_MS)
786
+ throw this.backoffActiveError();
787
+ const jitterMs = Math.floor(Math.random() * CONNECT_BACKOFF_WAIT_JITTER_MS);
788
+ await this.sleepAbortable(remainingMs + jitterMs, signal);
789
+ if (this.client)
790
+ return this.client;
791
+ if (this.connectionPromise)
792
+ return await this.connectionPromise;
793
+ now = Date.now();
794
+ if (now < this.nextProbeMs)
795
+ throw this.backoffActiveError();
796
+ }
797
+ const generation = this.connectionGeneration;
798
+ const connecting = (async () => {
799
+ let candidate = null;
800
+ try {
801
+ candidate = await this.connectClient();
802
+ if (generation !== this.connectionGeneration) {
803
+ candidate.close();
804
+ throw this.connectionChangedError("subc connection attempt was superseded");
805
+ }
806
+ this.client = candidate;
807
+ this.routes.clear();
808
+ this.backoffMs = CONNECT_BACKOFF_INITIAL_MS;
809
+ this.nextProbeMs = 0;
810
+ return candidate;
811
+ } catch (error) {
812
+ candidate?.close();
813
+ if (generation === this.connectionGeneration)
814
+ this.invalidateConnection();
815
+ this.nextProbeMs = Date.now() + this.backoffMs;
816
+ this.backoffMs = Math.min(this.backoffMs * 2, CONNECT_BACKOFF_MAX_MS);
817
+ throw error;
818
+ }
819
+ })();
820
+ this.connectionPromise = connecting;
821
+ try {
822
+ return await connecting;
823
+ } finally {
824
+ if (this.connectionPromise === connecting)
825
+ this.connectionPromise = null;
826
+ }
827
+ }
828
+ invalidateConnection(client = this.client) {
829
+ if (client && this.client !== client)
830
+ return;
831
+ this.connectionGeneration += 1;
832
+ this.invalidateStateSyncCapabilities();
833
+ this.client = null;
834
+ this.routes.clear();
835
+ this.routeOpenings.clear();
836
+ client?.close();
837
+ }
838
+ }
48
839
 
49
840
  // src/features/magic-context/git-commits/git-log-reader.ts
50
841
  import { execFile } from "node:child_process";
@@ -96,19 +887,19 @@ async function readGitCommitsResult(directory, options = {}) {
96
887
  } catch (error) {
97
888
  const message = error instanceof Error ? error.message : String(error);
98
889
  if (exclusion && message.includes("bad object")) {
99
- log(`[git-commits] indexed tip ${exclusion.slice(0, 7)} is missing for ${projectLabel}; reading the full window`);
890
+ log2(`[git-commits] indexed tip ${exclusion.slice(0, 7)} is missing for ${projectLabel}; reading the full window`);
100
891
  return readGitCommitsResult(directory, { ...options, excludeReachableFrom: undefined });
101
892
  }
102
893
  const failure = classifyGitLogFailure(message);
103
894
  if (failure === "transient") {
104
- log(`[git-commits] readGitCommits failed for ${projectLabel}: ${message.slice(0, 500)}`);
895
+ log2(`[git-commits] readGitCommits failed for ${projectLabel}: ${message.slice(0, 500)}`);
105
896
  } else {
106
- log(`[git-commits] ${projectLabel} is not indexable (${failure})`);
897
+ log2(`[git-commits] ${projectLabel} is not indexable (${failure})`);
107
898
  }
108
899
  return { commits: [], failure };
109
900
  }
110
901
  if (stdout.trim().length === 0) {
111
- log(`[git-commits] readGitCommits returned empty stdout for ${projectLabel} (sinceMs=${options.sinceMs ?? "none"} args=${args.slice(0, 4).join(" ")})`);
902
+ log2(`[git-commits] readGitCommits returned empty stdout for ${projectLabel} (sinceMs=${options.sinceMs ?? "none"} args=${args.slice(0, 4).join(" ")})`);
112
903
  }
113
904
  return { commits: parseGitLogOutput(stdout), failure: null };
114
905
  }
@@ -169,7 +960,7 @@ async function indexCommitsForProject(db, projectPath, directory, options) {
169
960
  nonIndexable: false
170
961
  };
171
962
  if (indexInProgress.has(projectPath)) {
172
- log(`[git-commits] index already in progress for ${projectPath}, skipping`);
963
+ log2(`[git-commits] index already in progress for ${projectPath}, skipping`);
173
964
  return result;
174
965
  }
175
966
  indexInProgress.add(projectPath);
@@ -190,21 +981,21 @@ async function indexCommitsForProject(db, projectPath, directory, options) {
190
981
  }
191
982
  if (commits.length === 0) {
192
983
  result.evicted = enforceProjectCap(db, projectPath, options.maxCommits);
193
- log(`[git-commits] no new commits for ${projectPath} (sinceMs=${sinceMs} latestIndexed=${latestIndexed?.slice(0, 7) ?? "none"} evicted=${result.evicted})`);
984
+ log2(`[git-commits] no new commits for ${projectPath} (sinceMs=${sinceMs} latestIndexed=${latestIndexed?.slice(0, 7) ?? "none"} evicted=${result.evicted})`);
194
985
  return result;
195
986
  }
196
- log(`[git-commits] read ${commits.length} commits for ${projectPath} (sinceMs=${sinceMs} latestIndexed=${latestIndexed?.slice(0, 7) ?? "none"})`);
987
+ log2(`[git-commits] read ${commits.length} commits for ${projectPath} (sinceMs=${sinceMs} latestIndexed=${latestIndexed?.slice(0, 7) ?? "none"})`);
197
988
  const upsert = upsertCommits(db, projectPath, commits);
198
989
  result.inserted = upsert.inserted;
199
990
  result.updated = upsert.updated;
200
991
  result.evicted = enforceProjectCap(db, projectPath, options.maxCommits);
201
- const snapshot = getProjectEmbeddingSnapshot(projectPath);
992
+ const snapshot = getProjectEmbeddingSnapshot2(projectPath);
202
993
  if (options.skipEmbed || !snapshot?.gitCommitEnabled) {
203
- log(`[git-commits] indexed ${projectPath}: scanned=${result.scanned} inserted=${result.inserted} updated=${result.updated} evicted=${result.evicted} embedded=0 (embedding skipped: skipEmbed=${options.skipEmbed === true} gitCommitEnabled=${snapshot?.gitCommitEnabled === true})`);
994
+ log2(`[git-commits] indexed ${projectPath}: scanned=${result.scanned} inserted=${result.inserted} updated=${result.updated} evicted=${result.evicted} embedded=0 (embedding skipped: skipEmbed=${options.skipEmbed === true} gitCommitEnabled=${snapshot?.gitCommitEnabled === true})`);
204
995
  return result;
205
996
  }
206
997
  result.embedded = await embedUnembeddedCommits(db, projectPath);
207
- log(`[git-commits] indexed ${projectPath}: scanned=${result.scanned} inserted=${result.inserted} updated=${result.updated} evicted=${result.evicted} embedded=${result.embedded}`);
998
+ log2(`[git-commits] indexed ${projectPath}: scanned=${result.scanned} inserted=${result.inserted} updated=${result.updated} evicted=${result.evicted} embedded=${result.embedded}`);
208
999
  return result;
209
1000
  } finally {
210
1001
  indexInProgress.delete(projectPath);
@@ -214,7 +1005,7 @@ async function embedUnembeddedCommits(db, projectPath) {
214
1005
  if (embedInProgress.has(projectPath)) {
215
1006
  return 0;
216
1007
  }
217
- const snapshot = getProjectEmbeddingSnapshot(projectPath);
1008
+ const snapshot = getProjectEmbeddingSnapshot2(projectPath);
218
1009
  if (!snapshot?.gitCommitEnabled) {
219
1010
  return 0;
220
1011
  }
@@ -229,10 +1020,10 @@ async function embedUnembeddedCommits(db, projectPath) {
229
1020
  break;
230
1021
  let embeddedThisBatch = 0;
231
1022
  try {
232
- const result = await embedItemsForProject(projectPath, rows.map((row) => ({
1023
+ const result = await embedItemsForProject2(projectPath, rows.map((row) => ({
233
1024
  id: `commit:${row.sha}`,
234
1025
  text: row.message,
235
- contentSha256: contentSha256(row.message)
1026
+ contentSha256: contentSha2562(row.message)
236
1027
  })), undefined, db, projectPath);
237
1028
  if (!result)
238
1029
  break;
@@ -245,9 +1036,9 @@ async function embedUnembeddedCommits(db, projectPath) {
245
1036
  embeddedThisBatch += 1;
246
1037
  }
247
1038
  }).immediate();
248
- enqueueShadowEmbeddingItems(projectPath, "commit", rows.filter((row) => result.vectors.has(`commit:${row.sha}`)).map((row) => row.sha));
1039
+ enqueueShadowEmbeddingItems2(projectPath, "commit", rows.filter((row) => result.vectors.has(`commit:${row.sha}`)).map((row) => row.sha));
249
1040
  } catch (error) {
250
- log(`[git-commits] embed batch failed for ${projectPath}: ${error instanceof Error ? error.message : String(error)}`);
1041
+ log2(`[git-commits] embed batch failed for ${projectPath}: ${error instanceof Error ? error.message : String(error)}`);
251
1042
  break;
252
1043
  }
253
1044
  if (embeddedThisBatch === 0)
@@ -258,7 +1049,7 @@ async function embedUnembeddedCommits(db, projectPath) {
258
1049
  }
259
1050
  if (total > 0) {
260
1051
  const totalEmbedded = countEmbeddedCommits(db, projectPath, snapshot.modelId);
261
- log(`[git-commits] embedded ${total} commits for ${projectPath} (total embedded: ${totalEmbedded})`);
1052
+ log2(`[git-commits] embedded ${total} commits for ${projectPath} (total embedded: ${totalEmbedded})`);
262
1053
  }
263
1054
  return total;
264
1055
  } finally {
@@ -395,7 +1186,7 @@ function searchGitCommitsSync(db, projectPath, query, options) {
395
1186
  ftsCandidates.push(rowToCommit(row));
396
1187
  }
397
1188
  } catch (error) {
398
- log(`[git-commits] FTS query failed for "${trimmed}": ${error instanceof Error ? error.message : String(error)}`);
1189
+ log2(`[git-commits] FTS query failed for "${trimmed}": ${error instanceof Error ? error.message : String(error)}`);
399
1190
  }
400
1191
  }
401
1192
  if (ftsCandidates.length === 0) {
@@ -426,6 +1217,19 @@ function searchGitCommitsSync(db, projectPath, query, options) {
426
1217
  for (const row of rows)
427
1218
  bySha.set(row.sha, rowToCommit(row));
428
1219
  }
1220
+ if (options.captureLanes) {
1221
+ const fts = [...bySha.values()].filter((commit) => ftsScores.has(commit.sha)).map((commit) => ({
1222
+ commit,
1223
+ matchType: "fts",
1224
+ score: (ftsScores.get(commit.sha) ?? 0) * singleSourcePenalty
1225
+ })).sort((a, b) => b.score - a.score || b.commit.committedAtMs - a.commit.committedAtMs).slice(0, 25);
1226
+ const vector = [...bySha.values()].filter((commit) => (semanticScores.get(commit.sha) ?? 0) > 0).map((commit) => ({
1227
+ commit,
1228
+ matchType: "semantic",
1229
+ score: semanticScores.get(commit.sha) ?? 0
1230
+ })).sort((a, b) => b.score - a.score || b.commit.committedAtMs - a.commit.committedAtMs).slice(0, 25);
1231
+ options.captureLanes(fts, vector);
1232
+ }
429
1233
  const results = [];
430
1234
  for (const [sha, commit] of bySha.entries()) {
431
1235
  const sem = semanticScores.get(sha);
@@ -565,7 +1369,7 @@ function withMessageFtsSessionFilter(db, sessionId, read) {
565
1369
  }
566
1370
 
567
1371
  // src/features/magic-context/search-measurement.ts
568
- import { createHash } from "node:crypto";
1372
+ import { createHash as createHash2 } from "node:crypto";
569
1373
  function resultId(result) {
570
1374
  switch (result.source) {
571
1375
  case "memory":
@@ -584,15 +1388,15 @@ function resultId(result) {
584
1388
  }
585
1389
  async function recordShadowMeasurement(args) {
586
1390
  try {
587
- const shadowCohort = getShadowEmbeddingMeasurementCohort(args.projectPath);
1391
+ const shadowCohort = getShadowEmbeddingMeasurementCohort2(args.projectPath);
588
1392
  if (!shadowCohort)
589
1393
  return;
590
- const primaryCohort = getPrimaryEmbeddingMeasurementCohort(args.projectPath);
1394
+ const primaryCohort = getPrimaryEmbeddingMeasurementCohort2(args.projectPath);
591
1395
  const shadowStartedAt = Date.now();
592
1396
  let shadowFailed = false;
593
1397
  let shadowResults = [];
594
1398
  try {
595
- const vector = await embedShadowTextForProject(args.projectPath, args.query);
1399
+ const vector = await embedShadowTextForProject2(args.projectPath, args.query);
596
1400
  if (!vector) {
597
1401
  shadowFailed = true;
598
1402
  } else {
@@ -648,11 +1452,273 @@ async function recordShadowMeasurement(args) {
648
1452
  }
649
1453
  });
650
1454
  } catch (error) {
651
- log("[magic-context] shadow embedding measurement failed:", error);
1455
+ log2("[magic-context] shadow embedding measurement failed:", error);
652
1456
  }
653
1457
  }
654
1458
  function sha256(value) {
655
- return createHash("sha256").update(value).digest("hex");
1459
+ return createHash2("sha256").update(value).digest("hex");
1460
+ }
1461
+
1462
+ // src/features/magic-context/search-rerank.ts
1463
+ var RERANK_MODEL = "gte-reranker-modernbert-base-f32";
1464
+ var RERANK_LANE_LIMIT = 25;
1465
+ var DEADLINE_MS = 1500;
1466
+ function isProseQuery(query) {
1467
+ const text = query.trim();
1468
+ if (!text || /[\n;]|^["'`]|["'`]$/.test(text))
1469
+ return false;
1470
+ if (/^(?:error\b|cannot\b|failed\b|panic\b|traceback\b|assertion\b|SQLITE_|TypeError\b|ReferenceError\b|SyntaxError\b)/i.test(text))
1471
+ return false;
1472
+ if (/\b(?:[A-Z][A-Z_]+:|\w*(?:Error|Exception):)|\bat\s+\S+\s*\(/.test(text))
1473
+ return false;
1474
+ const words = text.replace(/[?!.]$/, "").split(/\s+/);
1475
+ if (words.length < 3)
1476
+ return false;
1477
+ const plain = words.filter((word) => /^[a-zA-Z]+(?:['’-][a-zA-Z]+)*$/.test(word));
1478
+ if (/^(?:how|why|what|where|when|which|who)\b/i.test(text))
1479
+ return plain.length >= 3;
1480
+ return words.length >= 4 && plain.length >= 3 && !/[\\/]|::|=/.test(text);
1481
+ }
1482
+ function emptySearchLanes() {
1483
+ return {
1484
+ memory_fts: [],
1485
+ memory_vector: [],
1486
+ primer_fts: [],
1487
+ primer_vector: [],
1488
+ message_fts: [],
1489
+ chunk_vector: [],
1490
+ git_fts: [],
1491
+ git_vector: [],
1492
+ notes: []
1493
+ };
1494
+ }
1495
+ function searchResultKey(hit) {
1496
+ switch (hit.source) {
1497
+ case "memory":
1498
+ return `memory:${hit.memoryId}`;
1499
+ case "primer":
1500
+ return `primer:${hit.primerId}`;
1501
+ case "message":
1502
+ return `message:${hit.messageId}`;
1503
+ case "compartment":
1504
+ return `compartment:${hit.compartmentId}`;
1505
+ case "git_commit":
1506
+ return `git_commit:${hit.sha}`;
1507
+ case "note":
1508
+ return `note:${hit.noteId}`;
1509
+ }
1510
+ }
1511
+ function fuseSearchLanes(lanes) {
1512
+ const compartments = lanes.chunk_vector.filter((hit) => hit.source === "compartment");
1513
+ const fused = new Map;
1514
+ for (const [name, lane] of Object.entries(lanes)) {
1515
+ const seen = new Set;
1516
+ lane.slice(0, RERANK_LANE_LIMIT).forEach((original, index) => {
1517
+ const hit = name === "message_fts" && original.source === "message" ? compartments.find((chunk) => original.messageOrdinal >= chunk.startOrdinal && original.messageOrdinal <= chunk.endOrdinal) ?? original : original;
1518
+ const key = searchResultKey(hit);
1519
+ if (seen.has(key))
1520
+ return;
1521
+ seen.add(key);
1522
+ const prior = fused.get(key);
1523
+ const score = 1 / (60 + index + 1);
1524
+ if (prior)
1525
+ prior.score += score;
1526
+ else
1527
+ fused.set(key, { hit, score, order: fused.size });
1528
+ });
1529
+ }
1530
+ return [...fused.values()].sort((a, b) => b.score - a.score || a.order - b.order).slice(0, 20).map((row) => row.hit);
1531
+ }
1532
+ function truncateUtf8(text, bytes) {
1533
+ const buffer = Buffer.from(text);
1534
+ let end = Math.min(buffer.length, bytes);
1535
+ while (end > 0 && end < buffer.length && (buffer[end] & 192) === 128)
1536
+ end--;
1537
+ return buffer.subarray(0, end).toString("utf8");
1538
+ }
1539
+ function candidateText(location, title, body) {
1540
+ const header = `${truncateUtf8(location.replaceAll(`
1541
+ `, " "), 200)}
1542
+ ${truncateUtf8(title.replaceAll(`
1543
+ `, " "), 120)}
1544
+ `;
1545
+ return header + truncateUtf8(body, 1024 - Buffer.byteLength(header));
1546
+ }
1547
+
1548
+ class RerankFailure extends Error {
1549
+ reason;
1550
+ constructor(reason) {
1551
+ super(reason);
1552
+ this.reason = reason;
1553
+ }
1554
+ }
1555
+ function unwrap(value) {
1556
+ if (!value || typeof value !== "object")
1557
+ throw new RerankFailure("validation");
1558
+ const outer = value;
1559
+ const body = outer.result ?? outer;
1560
+ if (!body || typeof body !== "object")
1561
+ throw new RerankFailure("validation");
1562
+ if (body.error) {
1563
+ const error = body.error;
1564
+ throw new RerankFailure(error.code ?? "synapse_error");
1565
+ }
1566
+ return body;
1567
+ }
1568
+ function pinReranker(value) {
1569
+ const body = unwrap(value);
1570
+ const models = body.models;
1571
+ const model = Array.isArray(models) ? models.find((row) => row?.model_id === RERANK_MODEL) : null;
1572
+ if (model?.certified !== true || model.fingerprints?.length !== 1 || typeof model.fingerprints[0] !== "string" || !/^[a-f0-9]{64}$/.test(model.fingerprints[0]) || !Number.isSafeInteger(body.table_epoch))
1573
+ throw new RerankFailure("catalog_validation");
1574
+ return { fingerprint: model.fingerprints[0], tableEpoch: body.table_epoch };
1575
+ }
1576
+ var loggedReasons = new Set;
1577
+ function logRerankFallback(reason) {
1578
+ if (loggedReasons.has(reason))
1579
+ return;
1580
+ loggedReasons.add(reason);
1581
+ log2(`[ctx_search] rerank fallback (${reason}); retaining original ranking`);
1582
+ }
1583
+ function reasonOf(error) {
1584
+ if (error instanceof RerankFailure)
1585
+ return error.reason;
1586
+ if (error && typeof error === "object" && "code" in error) {
1587
+ const code = String(error.code);
1588
+ return ["ENOENT", "ECONNREFUSED"].includes(code) ? "missing_synapse" : code;
1589
+ }
1590
+ return "synapse_error";
1591
+ }
1592
+ async function bounded(promise) {
1593
+ let timer;
1594
+ try {
1595
+ return await Promise.race([
1596
+ promise,
1597
+ new Promise((_, reject) => {
1598
+ timer = setTimeout(() => reject(new RerankFailure("deadline_exceeded")), DEADLINE_MS);
1599
+ })
1600
+ ]);
1601
+ } finally {
1602
+ clearTimeout(timer);
1603
+ }
1604
+ }
1605
+ var connections = new Map;
1606
+ async function connect(connectionFile) {
1607
+ let connection = connections.get(connectionFile);
1608
+ if (!connection) {
1609
+ connection = SubcClient.connect({ connectionFile });
1610
+ connections.set(connectionFile, connection);
1611
+ connection.catch(() => connections.delete(connectionFile));
1612
+ }
1613
+ return bounded(connection);
1614
+ }
1615
+ async function prepareReranker(projectRoot, sessionId, connectionFile, injectedClient) {
1616
+ try {
1617
+ if (injectedClient === null)
1618
+ throw new RerankFailure("missing_synapse");
1619
+ const client = injectedClient ?? await connect(connectionFile ?? getDefaultSubcConnectionFile());
1620
+ const identity = {
1621
+ project_root: projectRoot,
1622
+ harness: "magic-context",
1623
+ session: sessionId
1624
+ };
1625
+ const lane = pinReranker(await bounded(client.call("synapse", "models.list", {}, { timeoutMs: DEADLINE_MS, targetKind: "management_surface", identity })));
1626
+ return { client, lane, identity };
1627
+ } catch (error) {
1628
+ logRerankFallback(reasonOf(error));
1629
+ return null;
1630
+ }
1631
+ }
1632
+ async function rerankSearchResults(session, query, baseline, pool, texts, limit) {
1633
+ if (!pool.length)
1634
+ return baseline;
1635
+ try {
1636
+ if (pool.length > 20 || texts.length !== pool.length || texts.some((text) => Buffer.byteLength(text) > 1024))
1637
+ throw new RerankFailure("validation");
1638
+ const body = unwrap(await bounded(session.client.call("synapse", "rerank.score", {
1639
+ model: RERANK_MODEL,
1640
+ query,
1641
+ candidates: texts,
1642
+ required_fingerprint: session.lane.fingerprint,
1643
+ allow_equivalent: false,
1644
+ accept_declared: false,
1645
+ max_queue_ms: 100,
1646
+ deadline_ms: DEADLINE_MS
1647
+ }, {
1648
+ timeoutMs: DEADLINE_MS,
1649
+ targetKind: "management_surface",
1650
+ identity: session.identity
1651
+ })));
1652
+ if (body.fingerprint !== session.lane.fingerprint)
1653
+ throw new RerankFailure("fingerprint_mismatch");
1654
+ if (body.table_epoch !== session.lane.tableEpoch)
1655
+ throw new RerankFailure("epoch_mismatch");
1656
+ if (!Array.isArray(body.scores) || body.scores.length !== pool.length || body.scores.some((score) => typeof score !== "number" || !Number.isFinite(score)))
1657
+ throw new RerankFailure("validation");
1658
+ const scores = body.scores;
1659
+ return pool.map((hit, index) => ({ hit, index, score: scores[index] })).sort((a, b) => b.score - a.score || a.index - b.index).slice(0, limit).map((row) => row.hit);
1660
+ } catch (error) {
1661
+ logRerankFallback(reasonOf(error));
1662
+ return baseline;
1663
+ }
1664
+ }
1665
+ function candidateTexts(db, sessionId, projectPath, pool) {
1666
+ return pool.map((hit) => {
1667
+ const id = searchResultKey(hit).split(":").slice(1).join(":");
1668
+ let location = `${hit.source} ${id} ${projectPath}`;
1669
+ let title = hit.content.split(`
1670
+ `)[0];
1671
+ let body = hit.content;
1672
+ switch (hit.source) {
1673
+ case "memory": {
1674
+ const row = db.prepare("SELECT content FROM memories WHERE id=?").get(hit.memoryId);
1675
+ body = row.content;
1676
+ title = body.split(`
1677
+ `)[0];
1678
+ break;
1679
+ }
1680
+ case "primer": {
1681
+ const row = db.prepare("SELECT question, answer FROM primers WHERE id=?").get(hit.primerId);
1682
+ title = row.question;
1683
+ body = `Q: ${row.question}
1684
+ A: ${row.answer}`;
1685
+ break;
1686
+ }
1687
+ case "git_commit": {
1688
+ const row = db.prepare("SELECT message FROM git_commits WHERE sha=?").get(hit.sha);
1689
+ body = row.message;
1690
+ title = `${hit.shortSha} ${body.split(`
1691
+ `)[0]}`;
1692
+ break;
1693
+ }
1694
+ case "note": {
1695
+ const row = db.prepare("SELECT content, ready_reason AS reason FROM notes WHERE id=?").get(hit.noteId);
1696
+ body = `${row.content}${row.reason ? `
1697
+ Reason: ${row.reason}` : ""}`;
1698
+ title = body.split(`
1699
+ `)[0];
1700
+ break;
1701
+ }
1702
+ case "message": {
1703
+ const mapped = db.prepare(`SELECT f.content FROM message_fts_rowid_map m
1704
+ JOIN message_history_fts f ON f.rowid=m.fts_rowid
1705
+ WHERE m.session_id=? AND m.message_ordinal=? AND f.message_id=?`).get(sessionId, hit.messageOrdinal, hit.messageId);
1706
+ const row = mapped ?? db.prepare("SELECT content FROM message_history_fts WHERE session_id=? AND message_id=? ORDER BY CAST(message_ordinal AS INTEGER) LIMIT 1").get(sessionId, hit.messageId);
1707
+ body = row.content;
1708
+ title = `${hit.role}: ${body.split(`
1709
+ `)[0]}`;
1710
+ location = `message ${hit.messageId} ${sessionId} @${hit.messageOrdinal}`;
1711
+ break;
1712
+ }
1713
+ case "compartment": {
1714
+ title = hit.title;
1715
+ location = `compartment ${hit.compartmentId} ${hit.sessionId} @${hit.startOrdinal}-${hit.endOrdinal}`;
1716
+ body = buildCanonicalChunkTextFromFts(db, hit.sessionId, hit.startOrdinal, hit.endOrdinal) ?? "";
1717
+ break;
1718
+ }
1719
+ }
1720
+ return candidateText(location, title, body);
1721
+ });
656
1722
  }
657
1723
 
658
1724
  // src/features/magic-context/search.ts
@@ -677,13 +1743,34 @@ var sessionFirstMessageSearchDiagnosticStatements = new WeakMap;
677
1743
  var messageSearchDiagnosticStatementsWithDateRange = new WeakMap;
678
1744
  var batchedMessageSearchStatements = new WeakMap;
679
1745
  var batchedFtsCountStatements = new WeakMap;
680
- function createUnifiedSearchDiagnostics() {
1746
+ function createUnifiedSearchDiagnostics2() {
681
1747
  return {
682
1748
  suppressedVisibleMemoryIds: [],
683
1749
  suppressedLiveMessageMatches: 0,
684
1750
  gitCommitUnavailable: null
685
1751
  };
686
1752
  }
1753
+ function searchMessageHistory2(db, request) {
1754
+ const diagnostics = request.collectDiagnostics ? createUnifiedSearchDiagnostics2() : undefined;
1755
+ const capture = request.captureLimit ? { limit: request.captureLimit, results: [] } : undefined;
1756
+ const results = searchMessages({
1757
+ db,
1758
+ sessionId: request.sessionId,
1759
+ query: request.query,
1760
+ limit: request.limit,
1761
+ maxOrdinal: request.maxOrdinal,
1762
+ probes: request.probes,
1763
+ relaxedRecall: request.relaxedRecall,
1764
+ diagnostics,
1765
+ dateRange: request.dateRange,
1766
+ capture
1767
+ });
1768
+ return {
1769
+ results,
1770
+ laneResults: capture?.results,
1771
+ suppressedLiveMessageMatches: diagnostics?.suppressedLiveMessageMatches ?? 0
1772
+ };
1773
+ }
687
1774
  function normalizeLimit(limit) {
688
1775
  if (typeof limit !== "number" || !Number.isFinite(limit)) {
689
1776
  return DEFAULT_UNIFIED_SEARCH_LIMIT;
@@ -703,7 +1790,7 @@ function timestampIsInRange(timestamp, range) {
703
1790
  }
704
1791
  var ID_SHAPED_QUERY_MAX_TOKENS = 5;
705
1792
  var ID_SHAPED_TOKEN = /^#?\d+$/;
706
- function parseIdShapedQuery(query) {
1793
+ function parseIdShapedQuery2(query) {
707
1794
  const trimmed = query.trim();
708
1795
  if (trimmed.length === 0) {
709
1796
  return null;
@@ -978,8 +2065,8 @@ async function getSemanticScores(args) {
978
2065
  return semanticScores;
979
2066
  }
980
2067
  if (!args.workspace?.isWorkspaced) {
981
- const cachedEmbeddings = getProjectEmbeddings(args.db, args.projectPath, args.queryModelId);
982
- const embeddings = args.backfillMemoryEmbeddings === false ? cachedEmbeddings : await ensureMemoryEmbeddings({
2068
+ const cachedEmbeddings = getProjectEmbeddings2(args.db, args.projectPath, args.queryModelId);
2069
+ const embeddings = args.backfillMemoryEmbeddings === false ? cachedEmbeddings : await ensureMemoryEmbeddings2({
983
2070
  db: args.db,
984
2071
  projectIdentity: args.projectPath,
985
2072
  memories: args.memories,
@@ -1006,8 +2093,8 @@ async function getSemanticScores(args) {
1006
2093
  }
1007
2094
  const ownMemories = memoriesByIdentity.get(args.projectPath) ?? [];
1008
2095
  if (ownMemories.length > 0 && args.backfillMemoryEmbeddings !== false) {
1009
- const ownEmbeddings = getProjectEmbeddings(args.db, args.projectPath, args.queryModelId);
1010
- await ensureMemoryEmbeddings({
2096
+ const ownEmbeddings = getProjectEmbeddings2(args.db, args.projectPath, args.queryModelId);
2097
+ await ensureMemoryEmbeddings2({
1011
2098
  db: args.db,
1012
2099
  projectIdentity: args.projectPath,
1013
2100
  memories: ownMemories,
@@ -1018,7 +2105,7 @@ async function getSemanticScores(args) {
1018
2105
  const memberMemories = memoriesByIdentity.get(identity) ?? [];
1019
2106
  if (memberMemories.length === 0)
1020
2107
  continue;
1021
- const cachedEmbeddings = getProjectEmbeddings(args.db, identity, args.queryModelId);
2108
+ const cachedEmbeddings = getProjectEmbeddings2(args.db, identity, args.queryModelId);
1022
2109
  for (const memory of memberMemories) {
1023
2110
  const memoryEmbedding = cachedEmbeddings.get(memory.id);
1024
2111
  if (!memoryEmbedding || memoryEmbedding.modelId !== args.queryModelId)
@@ -1032,7 +2119,7 @@ function getFtsMatches(args) {
1032
2119
  try {
1033
2120
  return args.workspace?.isWorkspaced ? searchMemoriesFTSUnion(args.db, args.workspace.expandedIdentities, args.query, args.limit, args.workspace.ownIdentities, args.workspace.shareCategories, args.dateRange) : searchMemoriesFTS(args.db, args.projectPath, args.query, args.limit, args.dateRange);
1034
2121
  } catch (error) {
1035
- log(`[search] FTS query failed for "${args.query}": ${error instanceof Error ? error.message : String(error)}`);
2122
+ log2(`[search] FTS query failed for "${args.query}": ${error instanceof Error ? error.message : String(error)}`);
1036
2123
  return [];
1037
2124
  }
1038
2125
  }
@@ -1047,7 +2134,7 @@ function selectSemanticCandidates(args) {
1047
2134
  if (args.queryModelId && args.queryModelId !== "off") {
1048
2135
  const embeddingProjects = args.workspace?.isWorkspaced ? args.workspace.identities : [args.projectPath];
1049
2136
  for (const projectPath of embeddingProjects) {
1050
- const storedEmbeddings = getProjectEmbeddings(args.db, projectPath, args.queryModelId);
2137
+ const storedEmbeddings = getProjectEmbeddings2(args.db, projectPath, args.queryModelId);
1051
2138
  for (const memoryId of storedEmbeddings.keys()) {
1052
2139
  candidateIds.add(memoryId);
1053
2140
  }
@@ -1073,7 +2160,7 @@ function mergeMemoryResults(args) {
1073
2160
  score = SEMANTIC_WEIGHT * semanticScore + FTS_WEIGHT * ftsScore;
1074
2161
  matchType = "hybrid";
1075
2162
  } else if (semanticScore !== undefined) {
1076
- score = semanticScore * SINGLE_SOURCE_PENALTY;
2163
+ score = semanticScore * (args.singleSourcePenalty ?? SINGLE_SOURCE_PENALTY);
1077
2164
  matchType = "semantic";
1078
2165
  } else if (ftsScore !== undefined) {
1079
2166
  score = ftsScore * SINGLE_SOURCE_PENALTY;
@@ -1110,7 +2197,7 @@ async function searchMemories(args) {
1110
2197
  if (!args.memoryEnabled) {
1111
2198
  return { results: [], suppressedVisibleIds: [] };
1112
2199
  }
1113
- const unfilteredMemories = args.workspace?.isWorkspaced ? getMemoriesByProjects(args.db, args.workspace.expandedIdentities, ["active", "permanent"], Date.now(), args.workspace.ownIdentities, args.workspace.shareCategories) : getMemoriesByProject(args.db, args.projectPath);
2200
+ const unfilteredMemories = args.workspace?.isWorkspaced ? getMemoriesByProjects2(args.db, args.workspace.expandedIdentities, ["active", "permanent"], Date.now(), args.workspace.ownIdentities, args.workspace.shareCategories) : getMemoriesByProject2(args.db, args.projectPath);
1114
2201
  const memories = unfilteredMemories.filter((memory) => timestampIsInRange(memory.createdAt, args.dateRange));
1115
2202
  if (memories.length === 0) {
1116
2203
  return { results: [], suppressedVisibleIds: [] };
@@ -1141,25 +2228,45 @@ async function searchMemories(args) {
1141
2228
  queryModelId: args.queryModelId,
1142
2229
  workspace: args.workspace
1143
2230
  });
2231
+ const sourceNameByMemoryId = sourceNamesForSearchMemories({
2232
+ memories,
2233
+ projectPath: args.projectPath,
2234
+ workspace: args.workspace ?? {
2235
+ identities: [args.projectPath],
2236
+ expandedIdentities: [args.projectPath],
2237
+ namesByIdentity: new Map,
2238
+ canonicalIdentityByStoredPath: new Map([[args.projectPath, args.projectPath]]),
2239
+ ownIdentities: [args.projectPath],
2240
+ shareCategories: null,
2241
+ isWorkspaced: false
2242
+ }
2243
+ });
2244
+ if (args.lanes) {
2245
+ args.lanes.memory_fts = mergeMemoryResults({
2246
+ memories,
2247
+ semanticScores: new Map,
2248
+ ftsScores,
2249
+ sourceNameByMemoryId,
2250
+ limit: 25,
2251
+ visibleMemoryIds: args.visibleMemoryIds
2252
+ }).results;
2253
+ args.lanes.memory_vector = mergeMemoryResults({
2254
+ memories,
2255
+ semanticScores,
2256
+ ftsScores: new Map,
2257
+ sourceNameByMemoryId,
2258
+ singleSourcePenalty: 1,
2259
+ limit: 25,
2260
+ visibleMemoryIds: args.visibleMemoryIds
2261
+ }).results;
2262
+ }
1144
2263
  return mergeMemoryResults({
1145
2264
  memories,
1146
2265
  semanticScores,
1147
2266
  ftsScores,
1148
2267
  limit: args.limit,
1149
2268
  visibleMemoryIds: args.visibleMemoryIds,
1150
- sourceNameByMemoryId: sourceNamesForSearchMemories({
1151
- memories,
1152
- projectPath: args.projectPath,
1153
- workspace: args.workspace ?? {
1154
- identities: [args.projectPath],
1155
- expandedIdentities: [args.projectPath],
1156
- namesByIdentity: new Map,
1157
- canonicalIdentityByStoredPath: new Map([[args.projectPath, args.projectPath]]),
1158
- ownIdentities: [args.projectPath],
1159
- shareCategories: null,
1160
- isWorkspaced: false
1161
- }
1162
- })
2269
+ sourceNameByMemoryId
1163
2270
  });
1164
2271
  }
1165
2272
  function linearDecayScore(rank, total) {
@@ -1292,7 +2399,9 @@ function searchMessages(args) {
1292
2399
  }
1293
2400
  function searchMessagesInSnapshot(args, sessionFirst) {
1294
2401
  const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
1295
- const fetchLimit = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.limit * 3 : args.limit;
2402
+ const baselineFetchLimit = cutoff !== null ? args.limit * 3 : args.limit;
2403
+ const captureFetchLimit = args.capture ? cutoff !== null ? args.capture.limit * 3 : args.capture.limit : 0;
2404
+ const fetchLimit = Math.max(baselineFetchLimit, captureFetchLimit);
1296
2405
  const baseQuery = sanitizeFtsQuery(args.query.trim());
1297
2406
  const probes = args.probes ?? [];
1298
2407
  if (probes.length === 0) {
@@ -1312,15 +2421,20 @@ function searchMessagesInSnapshot(args, sessionFirst) {
1312
2421
  args.diagnostics.suppressedLiveMessageMatches = outcome.suppressedCount;
1313
2422
  }
1314
2423
  const rows = outcome.rows.length > 0 || !args.relaxedRecall ? outcome.rows : runMessageFtsQuery(args.db, args.sessionId, relaxedFtsQuery(args.query), fetchLimit, cutoff, args.dateRange, sessionFirst);
1315
- const filtered = rows.slice(0, args.limit);
1316
- return filtered.map((row, rank) => ({
1317
- source: "message",
1318
- content: previewText(row.content),
1319
- score: linearDecayScore(rank, filtered.length),
1320
- messageOrdinal: row.messageOrdinal,
1321
- messageId: row.messageId,
1322
- role: row.role
1323
- }));
2424
+ const renderRows = (limit) => {
2425
+ const filtered = rows.slice(0, limit);
2426
+ return filtered.map((row, rank) => ({
2427
+ source: "message",
2428
+ content: previewText(row.content),
2429
+ score: linearDecayScore(rank, filtered.length),
2430
+ messageOrdinal: row.messageOrdinal,
2431
+ messageId: row.messageId,
2432
+ role: row.role
2433
+ }));
2434
+ };
2435
+ if (args.capture)
2436
+ args.capture.results = renderRows(args.capture.limit);
2437
+ return renderRows(args.limit);
1324
2438
  }
1325
2439
  const sanitizedProbes = probes.map((probe) => ({ probe, query: sanitizeFtsQuery(probe) })).filter((entry) => entry.query.length > 0);
1326
2440
  const corpusSize = getIndexedMessageCorpusSize(args.db, args.sessionId, cutoff);
@@ -1360,39 +2474,44 @@ function searchMessagesInSnapshot(args, sessionFirst) {
1360
2474
  queryLists.push({ rows: rowsByQuery[queryIndex] ?? [], weight });
1361
2475
  queryIndex += 1;
1362
2476
  });
1363
- const fused = new Map;
1364
- for (const list of queryLists) {
1365
- list.rows.forEach((row, rank) => {
1366
- const rrf = list.weight / (RRF_K + rank);
1367
- const existing = fused.get(row.messageId);
1368
- if (existing) {
1369
- existing.score += rrf;
1370
- } else {
1371
- fused.set(row.messageId, { row, score: rrf });
2477
+ const rankProbeLists = (rowLimit, resultLimit) => {
2478
+ const fused = new Map;
2479
+ for (const list of queryLists) {
2480
+ list.rows.slice(0, rowLimit).forEach((row, rank) => {
2481
+ const rrf = list.weight / (RRF_K + rank);
2482
+ const existing = fused.get(row.messageId);
2483
+ if (existing) {
2484
+ existing.score += rrf;
2485
+ } else {
2486
+ fused.set(row.messageId, { row, score: rrf });
2487
+ }
2488
+ });
2489
+ }
2490
+ for (const entry of fused.values()) {
2491
+ let best = 0;
2492
+ for (const probe of probes) {
2493
+ const weight = probeWeights.get(probe) ?? 0;
2494
+ if (weight > best && containsProbeVerbatim(entry.row.content, [probe])) {
2495
+ best = weight;
2496
+ }
1372
2497
  }
1373
- });
1374
- }
1375
- for (const entry of fused.values()) {
1376
- let best = 0;
1377
- for (const probe of probes) {
1378
- const weight = probeWeights.get(probe) ?? 0;
1379
- if (weight > best && containsProbeVerbatim(entry.row.content, [probe])) {
1380
- best = weight;
2498
+ if (best > 0) {
2499
+ entry.score += best * VERBATIM_RANK_BONUS;
1381
2500
  }
1382
2501
  }
1383
- if (best > 0) {
1384
- entry.score += best * VERBATIM_RANK_BONUS;
1385
- }
1386
- }
1387
- const ranked = [...fused.values()].sort((a, b) => b.score !== a.score ? b.score - a.score : a.row.messageOrdinal - b.row.messageOrdinal).slice(0, args.limit);
1388
- return ranked.map((entry, rank) => ({
1389
- source: "message",
1390
- content: previewText(entry.row.content),
1391
- score: linearDecayScore(rank, ranked.length),
1392
- messageOrdinal: entry.row.messageOrdinal,
1393
- messageId: entry.row.messageId,
1394
- role: entry.row.role
1395
- }));
2502
+ const ranked = [...fused.values()].sort((a, b) => b.score !== a.score ? b.score - a.score : a.row.messageOrdinal - b.row.messageOrdinal).slice(0, resultLimit);
2503
+ return ranked.map((entry, rank) => ({
2504
+ source: "message",
2505
+ content: previewText(entry.row.content),
2506
+ score: linearDecayScore(rank, ranked.length),
2507
+ messageOrdinal: entry.row.messageOrdinal,
2508
+ messageId: entry.row.messageId,
2509
+ role: entry.row.role
2510
+ }));
2511
+ };
2512
+ if (args.capture)
2513
+ args.capture.results = rankProbeLists(captureFetchLimit, args.capture.limit);
2514
+ return rankProbeLists(baselineFetchLimit, args.limit);
1396
2515
  }
1397
2516
  var NOTE_SEARCHABLE_STATUSES = ["active", "pending", "ready"];
1398
2517
  var MAX_NOTE_KEYWORD_SCORE = 3.5;
@@ -1662,12 +2781,17 @@ function toGitCommitResult(hit) {
1662
2781
  function searchGitCommits(args) {
1663
2782
  if (args.limit <= 0)
1664
2783
  return [];
2784
+ const lanes = args.lanes;
1665
2785
  const hits = searchGitCommitsSync(args.db, args.projectPath, args.query, {
1666
2786
  limit: args.limit,
1667
2787
  queryEmbedding: args.queryEmbedding,
1668
2788
  queryModelId: args.queryModelId,
1669
2789
  from: args.dateRange?.from,
1670
- to: args.dateRange?.to
2790
+ to: args.dateRange?.to,
2791
+ captureLanes: lanes ? (fts, vector) => {
2792
+ lanes.git_fts = fts.map(toGitCommitResult);
2793
+ lanes.git_vector = vector.map(toGitCommitResult);
2794
+ } : undefined
1671
2795
  });
1672
2796
  return hits.map(toGitCommitResult);
1673
2797
  }
@@ -1689,13 +2813,44 @@ function searchPrimers(args) {
1689
2813
  WHERE primers_fts MATCH ? AND p.project_path = ? AND p.status = 'active'
1690
2814
  ${args.dateRange === null ? "" : "AND p.created_at BETWEEN ? AND ?"}
1691
2815
  ORDER BY rank ASC
1692
- LIMIT ?`).all(ftsQuery, args.projectPath, ...args.dateRange === null ? [] : [args.dateRange.from, args.dateRange.to], args.limit * 3);
1693
- rows.forEach((row, index) => {
1694
- ftsRanks.set(row.id, linearDecayScore(index, rows.length));
2816
+ LIMIT ?`).all(ftsQuery, args.projectPath, ...args.dateRange === null ? [] : [args.dateRange.from, args.dateRange.to], args.lanes ? Math.max(args.limit * 3, 225) : args.limit * 3);
2817
+ const baselineRows = rows.slice(0, args.limit * 3);
2818
+ baselineRows.forEach((row, index) => {
2819
+ ftsRanks.set(row.id, linearDecayScore(index, baselineRows.length));
1695
2820
  });
2821
+ if (args.lanes) {
2822
+ const byId = new Map(primers.map((primer) => [primer.id, primer]));
2823
+ args.lanes.primer_fts = rows.flatMap((row, index) => {
2824
+ const primer = byId.get(row.id);
2825
+ return primer ? [
2826
+ {
2827
+ source: "primer",
2828
+ primerId: primer.id,
2829
+ content: previewText(primerText(primer)),
2830
+ question: primer.question,
2831
+ support: primer.totalSupport,
2832
+ lastObservedAt: primer.lastObservedAt,
2833
+ matchType: "fts",
2834
+ score: linearDecayScore(index, rows.length)
2835
+ }
2836
+ ] : [];
2837
+ }).slice(0, 25);
2838
+ }
1696
2839
  }
2840
+ const vectorResults = [];
1697
2841
  const scored = primers.map((primer) => {
1698
2842
  const semantic = args.queryEmbedding && primer.questionEmbedding && primer.questionEmbeddingModelId === args.queryModelId ? normalizeCosineScore(cosineSimilarity(args.queryEmbedding, primer.questionEmbedding)) : 0;
2843
+ if (args.lanes && semantic > 0)
2844
+ vectorResults.push({
2845
+ source: "primer",
2846
+ primerId: primer.id,
2847
+ content: previewText(primerText(primer)),
2848
+ question: primer.question,
2849
+ support: primer.totalSupport,
2850
+ lastObservedAt: primer.lastObservedAt,
2851
+ matchType: "semantic",
2852
+ score: semantic
2853
+ });
1699
2854
  const fts = ftsRanks.get(primer.id) ?? 0;
1700
2855
  if (semantic <= 0 && fts <= 0)
1701
2856
  return null;
@@ -1711,6 +2866,8 @@ function searchPrimers(args) {
1711
2866
  matchType: semantic > 0 && fts > 0 ? "hybrid" : semantic > 0 ? "semantic" : "fts"
1712
2867
  };
1713
2868
  }).filter((result) => result !== null).sort((a, b) => b.score - a.score || b.support - a.support || a.primerId - b.primerId).slice(0, args.limit);
2869
+ if (args.lanes)
2870
+ args.lanes.primer_vector = vectorResults.sort((a, b) => b.score - a.score || b.support - a.support || a.primerId - b.primerId).slice(0, 25);
1714
2871
  return scored;
1715
2872
  }
1716
2873
  function resolveSources(sources) {
@@ -1737,7 +2894,7 @@ function memoriesToIdLookupResults(args) {
1737
2894
  sourceName: args.sourceNameByMemoryId?.get(memory.id)
1738
2895
  }));
1739
2896
  }
1740
- function resolveMemoriesByIdsForSearch(args) {
2897
+ function resolveMemoriesByIdsForSearch2(args) {
1741
2898
  if (args.diagnostics) {
1742
2899
  args.diagnostics.suppressedVisibleMemoryIds = [];
1743
2900
  }
@@ -1745,7 +2902,7 @@ function resolveMemoriesByIdsForSearch(args) {
1745
2902
  return null;
1746
2903
  }
1747
2904
  const workspace = resolveSearchWorkspaceContext(args.db, args.projectPath);
1748
- const fetched = workspace.isWorkspaced ? getMemoriesByProjects(args.db, workspace.expandedIdentities, ["active", "permanent", "archived"], Date.now(), workspace.ownIdentities, workspace.shareCategories) : getMemoriesByProject(args.db, args.projectPath, ["active", "permanent", "archived"]);
2905
+ const fetched = workspace.isWorkspaced ? getMemoriesByProjects2(args.db, workspace.expandedIdentities, ["active", "permanent", "archived"], Date.now(), workspace.ownIdentities, workspace.shareCategories) : getMemoriesByProject2(args.db, args.projectPath, ["active", "permanent", "archived"]);
1749
2906
  if (fetched.length === 0) {
1750
2907
  return null;
1751
2908
  }
@@ -1781,13 +2938,15 @@ function resolveMemoriesByIdsForSearch(args) {
1781
2938
  })
1782
2939
  });
1783
2940
  }
1784
- async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
2941
+ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
1785
2942
  const trimmedQuery = query.trim();
1786
2943
  const measurementStartedAt = Date.now();
1787
2944
  if (trimmedQuery.length === 0 || options.signal?.aborted) {
1788
2945
  return [];
1789
2946
  }
1790
2947
  const limit = normalizeLimit(options.limit);
2948
+ const reranker = options.explicitSearch && options.rerank !== false && isProseQuery(trimmedQuery) ? await prepareReranker(projectPath, sessionId, options.rerankConnectionFile, options.rerankClient) : null;
2949
+ const lanes = reranker || options.captureRerankLanes ? emptySearchLanes() : undefined;
1791
2950
  const dateRange = normalizeDateRange(options.from, options.to);
1792
2951
  const tierLimit = Math.max(limit * 3, DEFAULT_UNIFIED_SEARCH_LIMIT);
1793
2952
  if (options.diagnostics) {
@@ -1812,28 +2971,44 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
1812
2971
  const runCompartmentChunks = runMessages && embeddingEnabled;
1813
2972
  const needsEmbedding = (runMemory || runGitCommits || runCompartmentChunks || runPrimers) && embeddingEnabled && isEmbeddingRuntimeEnabled();
1814
2973
  const queryEmbeddingPromise = needsEmbedding ? embedQuery(trimmedQuery, options.signal).catch((error) => {
1815
- log(`[search] query embedding failed: ${error instanceof Error ? error.message : String(error)}`);
2974
+ log2(`[search] query embedding failed: ${error instanceof Error ? error.message : String(error)}`);
1816
2975
  return null;
1817
2976
  }) : Promise.resolve(null);
1818
2977
  await Promise.resolve();
1819
2978
  if (options.signal?.aborted)
1820
2979
  return [];
1821
2980
  const messageProbes = options.explicitSearch ? extractLiteralProbes(trimmedQuery) : [];
1822
- const messageResults = runMessages ? searchMessages({
1823
- db,
1824
- sessionId,
1825
- query: trimmedQuery,
1826
- limit: tierLimit,
1827
- maxOrdinal: options.maxMessageOrdinal,
1828
- probes: messageProbes,
1829
- relaxedRecall: options.explicitSearch,
1830
- diagnostics: options.diagnostics,
1831
- dateRange
1832
- }) : [];
2981
+ let messageResults = [];
2982
+ if (runMessages) {
2983
+ const messageRequest = {
2984
+ sessionId,
2985
+ query: trimmedQuery,
2986
+ limit: tierLimit,
2987
+ captureLimit: lanes ? 75 : undefined,
2988
+ maxOrdinal: options.maxMessageOrdinal,
2989
+ probes: messageProbes,
2990
+ relaxedRecall: options.explicitSearch,
2991
+ collectDiagnostics: options.diagnostics !== undefined,
2992
+ dateRange
2993
+ };
2994
+ const delegated = options.searchMessageHistory ? await options.searchMessageHistory(messageRequest).catch((error) => {
2995
+ log2(`[search] off-thread message search failed: ${error instanceof Error ? error.message : String(error)}`);
2996
+ return null;
2997
+ }) : null;
2998
+ if (delegated && options.signal?.aborted)
2999
+ return [];
3000
+ const outcome = delegated ?? searchMessageHistory2(db, messageRequest);
3001
+ if (options.diagnostics) {
3002
+ options.diagnostics.suppressedLiveMessageMatches = outcome.suppressedLiveMessageMatches;
3003
+ }
3004
+ messageResults = outcome.results;
3005
+ if (lanes)
3006
+ lanes.message_fts = (outcome.laneResults ?? outcome.results).slice(0, 25);
3007
+ }
1833
3008
  const capturedQuery = await queryEmbeddingPromise;
1834
3009
  if (options.signal?.aborted)
1835
3010
  return [];
1836
- const embeddingSnapshot = getProjectEmbeddingSnapshot(projectPath);
3011
+ const embeddingSnapshot = getProjectEmbeddingSnapshot2(projectPath);
1837
3012
  const queryContract = capturedQuery instanceof Float32Array || capturedQuery === null ? null : capturedQuery;
1838
3013
  const generationIsCurrent = queryContract === null || embeddingSnapshot !== null && embeddingSnapshot.generation === queryContract.generation;
1839
3014
  const queryEmbedding = generationIsCurrent ? queryContract?.vector ?? (capturedQuery instanceof Float32Array ? capturedQuery : null) : null;
@@ -1845,14 +3020,16 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
1845
3020
  sessionId,
1846
3021
  projectPath,
1847
3022
  queryEmbedding,
1848
- limit: tierLimit,
3023
+ limit: lanes ? Math.max(tierLimit, 25) : tierLimit,
1849
3024
  maxOrdinal: options.maxMessageOrdinal,
1850
3025
  modelId: chunkModelId && chunkModelId !== "off" ? chunkModelId : null,
1851
3026
  dateRange
1852
3027
  }) : [];
3028
+ if (lanes)
3029
+ lanes.chunk_vector = compartmentResults.slice(0, 25);
1853
3030
  const messageLikeResults = mergeMessageAndCompartmentResults({
1854
3031
  messages: messageResults,
1855
- compartments: compartmentResults,
3032
+ compartments: compartmentResults.slice(0, tierLimit),
1856
3033
  limit: tierLimit
1857
3034
  });
1858
3035
  const [memoryOutcome, gitCommitResults, primerResults, noteResults] = await Promise.all([
@@ -1867,6 +3044,7 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
1867
3044
  workspace,
1868
3045
  visibleMemoryIds: options.visibleMemoryIds,
1869
3046
  backfillMemoryEmbeddings: options.backfillMemoryEmbeddings,
3047
+ lanes,
1870
3048
  dateRange
1871
3049
  }) : Promise.resolve({
1872
3050
  results: [],
@@ -1879,7 +3057,8 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
1879
3057
  limit: tierLimit,
1880
3058
  queryEmbedding,
1881
3059
  queryModelId: embeddingModelId && embeddingModelId !== "off" ? embeddingModelId : null,
1882
- dateRange
3060
+ dateRange,
3061
+ lanes
1883
3062
  })) : Promise.resolve([]),
1884
3063
  runPrimers ? Promise.resolve(searchPrimers({
1885
3064
  db,
@@ -1888,14 +3067,15 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
1888
3067
  limit: tierLimit,
1889
3068
  queryEmbedding,
1890
3069
  queryModelId: embeddingModelId && embeddingModelId !== "off" ? embeddingModelId : null,
1891
- dateRange
3070
+ dateRange,
3071
+ lanes
1892
3072
  })) : Promise.resolve([]),
1893
3073
  runNotes ? Promise.resolve(searchNotes({
1894
3074
  db,
1895
3075
  sessionId,
1896
3076
  projectPath,
1897
3077
  query: trimmedQuery,
1898
- limit: tierLimit,
3078
+ limit: lanes ? Math.max(tierLimit, 25) : tierLimit,
1899
3079
  probes: messageProbes,
1900
3080
  dateRange
1901
3081
  })) : Promise.resolve([])
@@ -1903,24 +3083,38 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
1903
3083
  if (options.diagnostics) {
1904
3084
  options.diagnostics.suppressedVisibleMemoryIds = memoryOutcome.suppressedVisibleIds;
1905
3085
  }
1906
- const results = [
3086
+ let results = [
1907
3087
  ...memoryOutcome.results,
1908
3088
  ...primerResults,
1909
3089
  ...messageLikeResults,
1910
3090
  ...gitCommitResults,
1911
3091
  ...noteResults
1912
3092
  ].sort(compareUnifiedResults).slice(0, limit);
3093
+ const originalResults = results;
3094
+ const originalLatencyMs = Date.now() - measurementStartedAt;
3095
+ if (lanes) {
3096
+ lanes.notes = noteResults.slice(0, 25);
3097
+ options.captureRerankLanes?.(lanes);
3098
+ }
3099
+ if (reranker && lanes) {
3100
+ const pool = fuseSearchLanes(lanes);
3101
+ try {
3102
+ results = await rerankSearchResults(reranker, trimmedQuery, results, pool, candidateTexts(db, sessionId, projectPath, pool), limit);
3103
+ } catch {
3104
+ logRerankFallback("candidate_validation");
3105
+ }
3106
+ }
1913
3107
  if (!options.measurementDisabled) {
1914
3108
  recordShadowMeasurement({
1915
3109
  db,
1916
3110
  sessionId,
1917
3111
  projectPath,
1918
3112
  query: trimmedQuery,
1919
- options,
1920
- primaryResults: results,
3113
+ options: { ...options, rerank: false, captureRerankLanes: undefined },
3114
+ primaryResults: originalResults,
1921
3115
  primaryQuery: queryContract,
1922
- primaryLatencyMs: Date.now() - measurementStartedAt,
1923
- search: unifiedSearch
3116
+ primaryLatencyMs: originalLatencyMs,
3117
+ search: unifiedSearch2
1924
3118
  });
1925
3119
  }
1926
3120
  const countRetrievals = options.countRetrievals ?? true;
@@ -1930,9 +3124,9 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
1930
3124
  db.transaction(() => {
1931
3125
  for (const memoryId of memoryIds) {
1932
3126
  try {
1933
- updateMemoryRetrievalCount(db, memoryId);
3127
+ updateMemoryRetrievalCount2(db, memoryId);
1934
3128
  } catch (error) {
1935
- if (error instanceof ModuleMemoryAuthorityError)
3129
+ if (error instanceof ModuleMemoryAuthorityError2)
1936
3130
  continue;
1937
3131
  throw error;
1938
3132
  }
@@ -2032,7 +3226,7 @@ function formatSearchDiagnosticLines(results, diagnostics) {
2032
3226
  }
2033
3227
  return lines;
2034
3228
  }
2035
- function formatSearchResults(query, results, currentSessionId, diagnostics) {
3229
+ function formatSearchResults2(query, results, currentSessionId, diagnostics) {
2036
3230
  const diagnosticLines = formatSearchDiagnosticLines(results, diagnostics);
2037
3231
  if (results.length === 0) {
2038
3232
  if (diagnosticLines.length > 0) {
@@ -2060,4 +3254,4 @@ ${bodyParts.join(`
2060
3254
  `)}`;
2061
3255
  }
2062
3256
 
2063
- export { indexCommitsForProject, embedUnembeddedCommits, createUnifiedSearchDiagnostics, parseIdShapedQuery, resolveMemoriesByIdsForSearch, unifiedSearch, formatSearchResults };
3257
+ export { renderSingleStoreMigrationRequiredRefusal, SingleStoreMigrationRequiredError, singleStoreMigrationRequiredFailure, projectNeedsSingleStoreMigration, STORE_AHEAD_OF_BINARY_CODE, storeAheadOfBinaryFailure, TRANSFORM_PAGE_UPLOAD_TIMEOUT_MS, transformColdStartExecuteTimeoutMs, MAX_WRAPUP_REQUEST_BUDGET_MS, getDefaultSubcConnectionFile, isModuleTransportGenerationChangedResult, SubcModuleTransport, indexCommitsForProject, embedUnembeddedCommits, createUnifiedSearchDiagnostics2, searchMessageHistory2, parseIdShapedQuery2, resolveMemoriesByIdsForSearch2, unifiedSearch2, formatSearchResults2 };