@cortexkit/opencode-magic-context 0.48.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 (203) hide show
  1. package/dist/auto-search-worker.js +3 -3
  2. package/dist/{conflict-warning-hook-w8cykrnf.js → conflict-warning-hook-kzx4dmk1.js} +7 -7
  3. package/dist/{context-m0cy262m.js → context-nj5f293n.js} +96 -43
  4. package/dist/{derive-budgets-sg0xsq7s.js → derive-budgets-qz5rrr08.js} +2 -2
  5. package/dist/embedding-backfill-aetxv1vt.js +21 -0
  6. package/dist/embedding-worker.js +4 -4
  7. package/dist/features/magic-context/git-commits/search-git-commits.d.ts +2 -0
  8. package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -1
  9. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  10. package/dist/features/magic-context/pi-content-decisions.d.ts +1 -1
  11. package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -1
  12. package/dist/features/magic-context/search-rerank.d.ts +35 -0
  13. package/dist/features/magic-context/search-rerank.d.ts.map +1 -0
  14. package/dist/features/magic-context/search.d.ts +11 -0
  15. package/dist/features/magic-context/search.d.ts.map +1 -1
  16. package/dist/features/magic-context/storage-meta-persisted.d.ts +13 -2
  17. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  18. package/dist/features/magic-context/storage-meta-session.d.ts +1 -1
  19. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
  20. package/dist/features/magic-context/storage-meta.d.ts +1 -1
  21. package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
  22. package/dist/features/magic-context/storage-session-tables.d.ts +2 -0
  23. package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
  24. package/dist/features/magic-context/storage-tag-identity-revision.d.ts +29 -9
  25. package/dist/features/magic-context/storage-tag-identity-revision.d.ts.map +1 -1
  26. package/dist/features/magic-context/storage-tags.d.ts +9 -0
  27. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  28. package/dist/features/magic-context/storage.d.ts +1 -1
  29. package/dist/features/magic-context/storage.d.ts.map +1 -1
  30. package/dist/features/magic-context/tagger.d.ts +2 -0
  31. package/dist/features/magic-context/tagger.d.ts.map +1 -1
  32. package/dist/features/magic-context/transform-decision-log.d.ts +3 -0
  33. package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
  34. package/dist/hooks/magic-context/auto-search-deadline.d.ts.map +1 -1
  35. package/dist/hooks/magic-context/auto-search-replay.fixture.d.ts +24 -0
  36. package/dist/hooks/magic-context/auto-search-replay.fixture.d.ts.map +1 -0
  37. package/dist/hooks/magic-context/auto-search-runner.d.ts +1 -1
  38. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  39. package/dist/hooks/magic-context/auto-search-worker-client.d.ts +2 -0
  40. package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -1
  41. package/dist/hooks/magic-context/command-handler.d.ts +2 -0
  42. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/emergency-fail-closed.d.ts +28 -0
  44. package/dist/hooks/magic-context/emergency-fail-closed.d.ts.map +1 -1
  45. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/historian-host-runner.d.ts +8 -0
  47. package/dist/hooks/magic-context/historian-host-runner.d.ts.map +1 -1
  48. package/dist/hooks/magic-context/hook.d.ts +2 -1
  49. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  50. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  51. package/dist/hooks/magic-context/latest-thinking-recovery.d.ts +7 -0
  52. package/dist/hooks/magic-context/latest-thinking-recovery.d.ts.map +1 -1
  53. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  54. package/dist/hooks/magic-context/pass-outcome.d.ts +1 -0
  55. package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -1
  56. package/dist/hooks/magic-context/read-session-chunk.d.ts +7 -1
  57. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  58. package/dist/hooks/magic-context/read-session-raw.d.ts +35 -0
  59. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  60. package/dist/hooks/magic-context/rust-mode-transform.d.ts +36 -0
  61. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  62. package/dist/hooks/magic-context/shared-compartment-boundaries.d.ts +8 -1
  63. package/dist/hooks/magic-context/shared-compartment-boundaries.d.ts.map +1 -1
  64. package/dist/hooks/magic-context/strict-thinking-prefix.d.ts +8 -0
  65. package/dist/hooks/magic-context/strict-thinking-prefix.d.ts.map +1 -0
  66. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  67. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +13 -0
  68. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  69. package/dist/hooks/magic-context/transform.d.ts +1 -0
  70. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  71. package/dist/{index-db7zwa3v.js → index-1bt88epp.js} +93 -9
  72. package/dist/{index-f0h6xwqm.js → index-1g30axtz.js} +229 -67
  73. package/dist/{index-k1xb52kd.js → index-1r0k9js3.js} +5 -5
  74. package/dist/{index-692jzy0p.js → index-2jcbj7r1.js} +122 -371
  75. package/dist/{index-bdckkfw6.js → index-2jgwttpt.js} +16 -8
  76. package/dist/{index-2y0s2hep.js → index-4mjhqadz.js} +1 -1
  77. package/dist/{index-pdecwzrd.js → index-57mrqed8.js} +1 -1
  78. package/dist/{index-ty64eqcn.js → index-9qjqq45k.js} +3 -3
  79. package/dist/{index-yq8n9qcb.js → index-9rt53q79.js} +4 -4
  80. package/dist/{index-pg50n748.js → index-b7mv1jx3.js} +4 -4
  81. package/dist/{index-mmyh6d8f.js → index-ezmszwbd.js} +6 -4
  82. package/dist/{index-fbv1dn35.js → index-gzcmtmar.js} +1 -1
  83. package/dist/{index-0an7742d.js → index-h2py7207.js} +549 -973
  84. package/dist/{index-0qhce371.js → index-h2wc01qk.js} +2 -2
  85. package/dist/{index-dhwzyd54.js → index-h5zfkjyk.js} +160 -25
  86. package/dist/{index-q2tqeqde.js → index-ha87j7a8.js} +1229 -78
  87. package/dist/{index-14cjxt20.js → index-hj2q50k0.js} +45 -8
  88. package/dist/{index-cb7emxgj.js → index-kmpvemph.js} +336 -6
  89. package/dist/{index-c43kr12f.js → index-kp5qe690.js} +7 -7
  90. package/dist/{index-bhvjj0ys.js → index-kq57tdf0.js} +2 -2
  91. package/dist/{index-7mx8v0pw.js → index-nm6a8xpd.js} +4 -4
  92. package/dist/{index-8j7gqj40.js → index-nsjyysj0.js} +6 -2
  93. package/dist/{index-k9nnwad5.js → index-nydv6g8r.js} +44 -7
  94. package/dist/{index-5zygecde.js → index-peshmj6h.js} +4 -4
  95. package/dist/{index-knh4y330.js → index-pxwp2hjk.js} +7 -2
  96. package/dist/{index-1qb0z7wa.js → index-qx53vezw.js} +1 -1
  97. package/dist/{index-q7h7csab.js → index-s4j7t92z.js} +9 -9
  98. package/dist/{index-z8e0psj8.js → index-stbr4ce6.js} +3 -3
  99. package/dist/{index-jcbd3znx.js → index-tqf7yg27.js} +1 -1
  100. package/dist/{index-72nhv486.js → index-vkbqdnkj.js} +2 -2
  101. package/dist/{index-eeezr5zz.js → index-z1tjp257.js} +1 -1
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/index.js +61 -44
  104. package/dist/{logger-d3wex3dz.js → logger-ewak5q1s.js} +1 -1
  105. package/dist/{message-index-bounded-7ezbgddp.js → message-index-bounded-h0mrd4pr.js} +13 -13
  106. package/dist/{message-time-backfill-brbd63hv.js → message-time-backfill-8x06r9kx.js} +2 -2
  107. package/dist/migration-worker.js +9 -9
  108. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -0
  109. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  110. package/dist/plugin/tool-registry.d.ts.map +1 -1
  111. package/dist/{project-embedding-registry-7qzptcw7.js → project-embedding-registry-rtt0djyb.js} +9 -9
  112. package/dist/raw-ordinal-warmup-worker.js +4 -4
  113. package/dist/{read-session-chunk-6k83m4fj.js → read-session-chunk-ty89v75e.js} +10 -8
  114. package/dist/{read-session-raw-3g9qy1xa.js → read-session-raw-8sjbc9h0.js} +5 -3
  115. package/dist/{recomp-orchestrator-d3fp1cy0.js → recomp-orchestrator-4f1yyd1q.js} +25 -25
  116. package/dist/{safe-notification-target-5ffqq32m.js → safe-notification-target-q0cyrx3x.js} +2 -2
  117. package/dist/{search-epax1ecv.js → search-pz4f4wge.js} +20 -20
  118. package/dist/{send-session-notification-erecz4y4.js → send-session-notification-38cd5dqt.js} +5 -5
  119. package/dist/shared/auto-search-lifecycle.d.ts +14 -0
  120. package/dist/shared/auto-search-lifecycle.d.ts.map +1 -1
  121. package/dist/shared/logger.d.ts.map +1 -1
  122. package/dist/shared/models-dev-temperature.d.ts +18 -0
  123. package/dist/shared/models-dev-temperature.d.ts.map +1 -0
  124. package/dist/shared/project-directory-key.d.ts +16 -0
  125. package/dist/shared/project-directory-key.d.ts.map +1 -1
  126. package/dist/shared/subagent-temperature.d.ts +46 -0
  127. package/dist/shared/subagent-temperature.d.ts.map +1 -0
  128. package/dist/{storage-tags-d3b0v2ss.js → storage-tags-k0pda32s.js} +6 -4
  129. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  130. package/dist/tools/ctx-search/tools.d.ts.map +1 -1
  131. package/dist/tools/ctx-search/types.d.ts +1 -0
  132. package/dist/tools/ctx-search/types.d.ts.map +1 -1
  133. package/dist/{transform-postprocess-phase-spcy2qre.js → transform-postprocess-phase-tck4g20s.js} +25 -25
  134. package/dist/v2/auto-search-worker.js +3 -3
  135. package/dist/v2/{context-sf98kstd.js → context-crbt6p1y.js} +809 -1052
  136. package/dist/v2/{derive-budgets-3vc0y84t.js → derive-budgets-fgej9j46.js} +3 -3
  137. package/dist/v2/embedding-backfill-ph1qfyn3.js +21 -0
  138. package/dist/v2/embedding-worker.js +4 -4
  139. package/dist/v2/hidden-child-native.d.ts.map +1 -1
  140. package/dist/v2/hidden-completion.d.ts +7 -0
  141. package/dist/v2/hidden-completion.d.ts.map +1 -1
  142. package/dist/v2/hooks/context.d.ts.map +1 -1
  143. package/dist/v2/hooks/dream-trigger.d.ts +4 -1
  144. package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
  145. package/dist/v2/hooks/generate.d.ts +9 -2
  146. package/dist/v2/hooks/generate.d.ts.map +1 -1
  147. package/dist/v2/{logger-mxd0ym09.js → logger-pj02s7sr.js} +1 -1
  148. package/dist/v2/{message-index-bounded-dy3s2k1e.js → message-index-bounded-xwqdywxg.js} +13 -13
  149. package/dist/v2/{message-time-backfill-gtx1pwk1.js → message-time-backfill-cje68egj.js} +2 -2
  150. package/dist/v2/migration-worker.js +9 -9
  151. package/dist/v2/{project-embedding-registry-1tgba5dv.js → project-embedding-registry-d6m7tyxr.js} +9 -9
  152. package/dist/v2/raw-ordinal-warmup-worker.js +4 -4
  153. package/dist/v2/{read-session-chunk-rh4khdkv.js → read-session-chunk-8p5mdryx.js} +10 -8
  154. package/dist/v2/{read-session-raw-bsbmf0vj.js → read-session-raw-j8dvp7f4.js} +5 -3
  155. package/dist/v2/{recomp-orchestrator-az61rfcg.js → recomp-orchestrator-ckfgt6wq.js} +26 -26
  156. package/dist/v2/{safe-notification-target-73ax1p5v.js → safe-notification-target-y3p1hce9.js} +2 -2
  157. package/dist/v2/{search-nzkwrc6n.js → search-ym8rehhz.js} +20 -20
  158. package/dist/v2/{send-session-notification-6km439kn.js → send-session-notification-5m0yapqx.js} +5 -5
  159. package/dist/v2/{server-x2g40a71.js → server-19zjmn02.js} +2 -2
  160. package/dist/v2/{server-sggvvzhb.js → server-1tk82krw.js} +45 -8
  161. package/dist/v2/{server-vqpf3167.js → server-2s6ayq3t.js} +2 -2
  162. package/dist/v2/{server-z2037m6z.js → server-2s9qz6n7.js} +2 -2
  163. package/dist/v2/{server-k228xhjg.js → server-3j4d00kf.js} +1 -1
  164. package/dist/v2/{server-aan4q8mx.js → server-3t0q2cqx.js} +1 -1
  165. package/dist/v2/{server-2fbhp79z.js → server-4ez8mntn.js} +16 -8
  166. package/dist/v2/{server-zxhgvsf9.js → server-676xw7at.js} +1 -1
  167. package/dist/v2/{server-52awr2mw.js → server-6byqfbqf.js} +93 -9
  168. package/dist/v2/{server-qye6ykf7.js → server-7ekna9zs.js} +2 -2
  169. package/dist/v2/{server-g5r0n3b6.js → server-7h861yms.js} +160 -25
  170. package/dist/v2/{server-v06jcv0w.js → server-8k2agx29.js} +1 -1
  171. package/dist/v2/{server-686jg6eb.js → server-c5rrgrcd.js} +44 -7
  172. package/dist/v2/{server-4k748ke6.js → server-hb6xhh9q.js} +2 -2
  173. package/dist/v2/{server-7wwc2nga.js → server-jvxzm1jy.js} +7 -7
  174. package/dist/v2/{server-1r6pmz4f.js → server-kzns2hbz.js} +1 -1
  175. package/dist/v2/{server-xdfwt6kh.js → server-pj4pjv02.js} +2 -2
  176. package/dist/v2/{server-psqc7e9n.js → server-q4ph9bwn.js} +1227 -78
  177. package/dist/v2/{server-8pyt7hev.js → server-sa8jvrfc.js} +9 -9
  178. package/dist/v2/{server-ezhze64f.js → server-ss95ky04.js} +4 -4
  179. package/dist/v2/{server-5m3dt5r1.js → server-t4k4qexw.js} +6 -2
  180. package/dist/v2/{server-e0vdaae2.js → server-v4mewb78.js} +4 -4
  181. package/dist/v2/{server-gjcr4w98.js → server-w32kmdez.js} +4 -4
  182. package/dist/v2/{server-k8x2rbxc.js → server-x4hscabv.js} +119 -365
  183. package/dist/v2/{server-yczc713m.js → server-xwz4dqh9.js} +7 -2
  184. package/dist/v2/{server-xxm59eww.js → server-ycw9qqcy.js} +4 -4
  185. package/dist/v2/{server-8tqanswc.js → server-zp53y8js.js} +331 -4
  186. package/dist/v2/server.js +4 -4
  187. package/dist/v2/{storage-tags-w4tv77sn.js → storage-tags-8vw924zn.js} +6 -4
  188. package/dist/v2/store-reader.d.ts +8 -2
  189. package/dist/v2/store-reader.d.ts.map +1 -1
  190. package/dist/v2/{wrapup-orchestrator-mz7efs7w.js → wrapup-orchestrator-a7efxaax.js} +26 -26
  191. package/dist/wrapup-orchestrator-barbc6h9.js +44 -0
  192. package/package.json +1 -1
  193. package/src/shared/auto-search-lifecycle.ts +43 -0
  194. package/src/shared/logger.test.ts +38 -0
  195. package/src/shared/logger.ts +10 -2
  196. package/src/shared/models-dev-temperature.ts +107 -0
  197. package/src/shared/project-directory-key.test.ts +59 -0
  198. package/src/shared/project-directory-key.ts +20 -0
  199. package/src/shared/subagent-temperature.test.ts +270 -0
  200. package/src/shared/subagent-temperature.ts +110 -0
  201. package/dist/embedding-backfill-9rcm1mfy.js +0 -21
  202. package/dist/v2/embedding-backfill-vn8g1nh1.js +0 -21
  203. package/dist/wrapup-orchestrator-amzta1t4.js +0 -44
@@ -1,9 +1,25 @@
1
+ import {
2
+ Priority,
3
+ AdmissionClass,
4
+ SocketClosedError,
5
+ SocketTimeoutError,
6
+ StaleRouteHandleError,
7
+ SubcClient,
8
+ isConsumerReconnectTransient
9
+ } from "./index-vkbqdnkj.js";
10
+ import {
11
+ getHarness2
12
+ } from "./index-pavzsdc6.js";
13
+ import {
14
+ getDataDir
15
+ } from "./index-0sahzkwr.js";
1
16
  import {
2
17
  log2
3
- } from "./index-8j7gqj40.js";
18
+ } from "./index-nsjyysj0.js";
4
19
  import {
20
+ buildCanonicalChunkTextFromFts,
5
21
  loadCompartmentChunkEmbeddingsForSearch
6
- } from "./index-pg50n748.js";
22
+ } from "./index-b7mv1jx3.js";
7
23
  import {
8
24
  recordEmbeddingMeasurement,
9
25
  saveCommitEmbedding,
@@ -20,7 +36,7 @@ import {
20
36
  enqueueShadowEmbeddingItems2,
21
37
  getProjectEmbeddingSnapshot2,
22
38
  embedItemsForProject2
23
- } from "./index-c43kr12f.js";
39
+ } from "./index-kp5qe690.js";
24
40
  import {
25
41
  getProjectEmbeddings2
26
42
  } from "./index-4dhv7mqz.js";
@@ -29,7 +45,7 @@ import {
29
45
  isEmbeddingEnabled,
30
46
  embedText,
31
47
  ensureMemoryEmbeddings2
32
- } from "./index-5zygecde.js";
48
+ } from "./index-peshmj6h.js";
33
49
  import {
34
50
  ModuleMemoryAuthorityError2,
35
51
  getMemoriesByProject2,
@@ -37,27 +53,790 @@ import {
37
53
  updateMemoryRetrievalCount2
38
54
  } from "./index-7jzrrxap.js";
39
55
  import {
56
+ USER_FACING_FAILURES,
40
57
  getNotes,
41
58
  getActivePrimers,
42
59
  relaxedFtsQuery,
43
60
  sanitizeFtsQuery,
44
61
  searchMemoriesFTS,
45
62
  searchMemoriesFTSUnion
46
- } from "./index-cb7emxgj.js";
63
+ } from "./index-kmpvemph.js";
64
+ import {
65
+ isRecord
66
+ } from "./index-nydv6g8r.js";
47
67
  import {
48
68
  getIndexedMessageCorpusSize
49
- } from "./index-14cjxt20.js";
69
+ } from "./index-hj2q50k0.js";
50
70
  import {
51
71
  resolveWorkspaceShareCategories,
52
72
  resolveWorkspaceIdentitySet,
53
73
  expandWorkspaceIdentitySetWithAliases,
54
74
  resolveStoredPathWorkspaceIdentity,
55
75
  sourceNameForMemory
56
- } from "./index-7mx8v0pw.js";
76
+ } from "./index-nm6a8xpd.js";
57
77
  import {
58
78
  isKnownAutocommit
59
79
  } from "./index-8ajstryz.js";
60
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
+ }
839
+
61
840
  // src/features/magic-context/git-commits/git-log-reader.ts
62
841
  import { execFile } from "node:child_process";
63
842
  import { promisify } from "node:util";
@@ -438,6 +1217,19 @@ function searchGitCommitsSync(db, projectPath, query, options) {
438
1217
  for (const row of rows)
439
1218
  bySha.set(row.sha, rowToCommit(row));
440
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
+ }
441
1233
  const results = [];
442
1234
  for (const [sha, commit] of bySha.entries()) {
443
1235
  const sem = semanticScores.get(sha);
@@ -577,7 +1369,7 @@ function withMessageFtsSessionFilter(db, sessionId, read) {
577
1369
  }
578
1370
 
579
1371
  // src/features/magic-context/search-measurement.ts
580
- import { createHash } from "node:crypto";
1372
+ import { createHash as createHash2 } from "node:crypto";
581
1373
  function resultId(result) {
582
1374
  switch (result.source) {
583
1375
  case "memory":
@@ -664,7 +1456,269 @@ async function recordShadowMeasurement(args) {
664
1456
  }
665
1457
  }
666
1458
  function sha256(value) {
667
- 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
+ });
668
1722
  }
669
1723
 
670
1724
  // src/features/magic-context/search.ts
@@ -698,6 +1752,7 @@ function createUnifiedSearchDiagnostics2() {
698
1752
  }
699
1753
  function searchMessageHistory2(db, request) {
700
1754
  const diagnostics = request.collectDiagnostics ? createUnifiedSearchDiagnostics2() : undefined;
1755
+ const capture = request.captureLimit ? { limit: request.captureLimit, results: [] } : undefined;
701
1756
  const results = searchMessages({
702
1757
  db,
703
1758
  sessionId: request.sessionId,
@@ -707,10 +1762,12 @@ function searchMessageHistory2(db, request) {
707
1762
  probes: request.probes,
708
1763
  relaxedRecall: request.relaxedRecall,
709
1764
  diagnostics,
710
- dateRange: request.dateRange
1765
+ dateRange: request.dateRange,
1766
+ capture
711
1767
  });
712
1768
  return {
713
1769
  results,
1770
+ laneResults: capture?.results,
714
1771
  suppressedLiveMessageMatches: diagnostics?.suppressedLiveMessageMatches ?? 0
715
1772
  };
716
1773
  }
@@ -1103,7 +2160,7 @@ function mergeMemoryResults(args) {
1103
2160
  score = SEMANTIC_WEIGHT * semanticScore + FTS_WEIGHT * ftsScore;
1104
2161
  matchType = "hybrid";
1105
2162
  } else if (semanticScore !== undefined) {
1106
- score = semanticScore * SINGLE_SOURCE_PENALTY;
2163
+ score = semanticScore * (args.singleSourcePenalty ?? SINGLE_SOURCE_PENALTY);
1107
2164
  matchType = "semantic";
1108
2165
  } else if (ftsScore !== undefined) {
1109
2166
  score = ftsScore * SINGLE_SOURCE_PENALTY;
@@ -1171,25 +2228,45 @@ async function searchMemories(args) {
1171
2228
  queryModelId: args.queryModelId,
1172
2229
  workspace: args.workspace
1173
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
+ }
1174
2263
  return mergeMemoryResults({
1175
2264
  memories,
1176
2265
  semanticScores,
1177
2266
  ftsScores,
1178
2267
  limit: args.limit,
1179
2268
  visibleMemoryIds: args.visibleMemoryIds,
1180
- sourceNameByMemoryId: sourceNamesForSearchMemories({
1181
- memories,
1182
- projectPath: args.projectPath,
1183
- workspace: args.workspace ?? {
1184
- identities: [args.projectPath],
1185
- expandedIdentities: [args.projectPath],
1186
- namesByIdentity: new Map,
1187
- canonicalIdentityByStoredPath: new Map([[args.projectPath, args.projectPath]]),
1188
- ownIdentities: [args.projectPath],
1189
- shareCategories: null,
1190
- isWorkspaced: false
1191
- }
1192
- })
2269
+ sourceNameByMemoryId
1193
2270
  });
1194
2271
  }
1195
2272
  function linearDecayScore(rank, total) {
@@ -1322,7 +2399,9 @@ function searchMessages(args) {
1322
2399
  }
1323
2400
  function searchMessagesInSnapshot(args, sessionFirst) {
1324
2401
  const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
1325
- 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);
1326
2405
  const baseQuery = sanitizeFtsQuery(args.query.trim());
1327
2406
  const probes = args.probes ?? [];
1328
2407
  if (probes.length === 0) {
@@ -1342,15 +2421,20 @@ function searchMessagesInSnapshot(args, sessionFirst) {
1342
2421
  args.diagnostics.suppressedLiveMessageMatches = outcome.suppressedCount;
1343
2422
  }
1344
2423
  const rows = outcome.rows.length > 0 || !args.relaxedRecall ? outcome.rows : runMessageFtsQuery(args.db, args.sessionId, relaxedFtsQuery(args.query), fetchLimit, cutoff, args.dateRange, sessionFirst);
1345
- const filtered = rows.slice(0, args.limit);
1346
- return filtered.map((row, rank) => ({
1347
- source: "message",
1348
- content: previewText(row.content),
1349
- score: linearDecayScore(rank, filtered.length),
1350
- messageOrdinal: row.messageOrdinal,
1351
- messageId: row.messageId,
1352
- role: row.role
1353
- }));
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);
1354
2438
  }
1355
2439
  const sanitizedProbes = probes.map((probe) => ({ probe, query: sanitizeFtsQuery(probe) })).filter((entry) => entry.query.length > 0);
1356
2440
  const corpusSize = getIndexedMessageCorpusSize(args.db, args.sessionId, cutoff);
@@ -1390,39 +2474,44 @@ function searchMessagesInSnapshot(args, sessionFirst) {
1390
2474
  queryLists.push({ rows: rowsByQuery[queryIndex] ?? [], weight });
1391
2475
  queryIndex += 1;
1392
2476
  });
1393
- const fused = new Map;
1394
- for (const list of queryLists) {
1395
- list.rows.forEach((row, rank) => {
1396
- const rrf = list.weight / (RRF_K + rank);
1397
- const existing = fused.get(row.messageId);
1398
- if (existing) {
1399
- existing.score += rrf;
1400
- } else {
1401
- 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
+ }
1402
2497
  }
1403
- });
1404
- }
1405
- for (const entry of fused.values()) {
1406
- let best = 0;
1407
- for (const probe of probes) {
1408
- const weight = probeWeights.get(probe) ?? 0;
1409
- if (weight > best && containsProbeVerbatim(entry.row.content, [probe])) {
1410
- best = weight;
2498
+ if (best > 0) {
2499
+ entry.score += best * VERBATIM_RANK_BONUS;
1411
2500
  }
1412
2501
  }
1413
- if (best > 0) {
1414
- entry.score += best * VERBATIM_RANK_BONUS;
1415
- }
1416
- }
1417
- 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);
1418
- return ranked.map((entry, rank) => ({
1419
- source: "message",
1420
- content: previewText(entry.row.content),
1421
- score: linearDecayScore(rank, ranked.length),
1422
- messageOrdinal: entry.row.messageOrdinal,
1423
- messageId: entry.row.messageId,
1424
- role: entry.row.role
1425
- }));
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);
1426
2515
  }
1427
2516
  var NOTE_SEARCHABLE_STATUSES = ["active", "pending", "ready"];
1428
2517
  var MAX_NOTE_KEYWORD_SCORE = 3.5;
@@ -1692,12 +2781,17 @@ function toGitCommitResult(hit) {
1692
2781
  function searchGitCommits(args) {
1693
2782
  if (args.limit <= 0)
1694
2783
  return [];
2784
+ const lanes = args.lanes;
1695
2785
  const hits = searchGitCommitsSync(args.db, args.projectPath, args.query, {
1696
2786
  limit: args.limit,
1697
2787
  queryEmbedding: args.queryEmbedding,
1698
2788
  queryModelId: args.queryModelId,
1699
2789
  from: args.dateRange?.from,
1700
- 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
1701
2795
  });
1702
2796
  return hits.map(toGitCommitResult);
1703
2797
  }
@@ -1719,13 +2813,44 @@ function searchPrimers(args) {
1719
2813
  WHERE primers_fts MATCH ? AND p.project_path = ? AND p.status = 'active'
1720
2814
  ${args.dateRange === null ? "" : "AND p.created_at BETWEEN ? AND ?"}
1721
2815
  ORDER BY rank ASC
1722
- LIMIT ?`).all(ftsQuery, args.projectPath, ...args.dateRange === null ? [] : [args.dateRange.from, args.dateRange.to], args.limit * 3);
1723
- rows.forEach((row, index) => {
1724
- 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));
1725
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
+ }
1726
2839
  }
2840
+ const vectorResults = [];
1727
2841
  const scored = primers.map((primer) => {
1728
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
+ });
1729
2854
  const fts = ftsRanks.get(primer.id) ?? 0;
1730
2855
  if (semantic <= 0 && fts <= 0)
1731
2856
  return null;
@@ -1741,6 +2866,8 @@ function searchPrimers(args) {
1741
2866
  matchType: semantic > 0 && fts > 0 ? "hybrid" : semantic > 0 ? "semantic" : "fts"
1742
2867
  };
1743
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);
1744
2871
  return scored;
1745
2872
  }
1746
2873
  function resolveSources(sources) {
@@ -1818,6 +2945,8 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
1818
2945
  return [];
1819
2946
  }
1820
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;
1821
2950
  const dateRange = normalizeDateRange(options.from, options.to);
1822
2951
  const tierLimit = Math.max(limit * 3, DEFAULT_UNIFIED_SEARCH_LIMIT);
1823
2952
  if (options.diagnostics) {
@@ -1855,6 +2984,7 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
1855
2984
  sessionId,
1856
2985
  query: trimmedQuery,
1857
2986
  limit: tierLimit,
2987
+ captureLimit: lanes ? 75 : undefined,
1858
2988
  maxOrdinal: options.maxMessageOrdinal,
1859
2989
  probes: messageProbes,
1860
2990
  relaxedRecall: options.explicitSearch,
@@ -1872,6 +3002,8 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
1872
3002
  options.diagnostics.suppressedLiveMessageMatches = outcome.suppressedLiveMessageMatches;
1873
3003
  }
1874
3004
  messageResults = outcome.results;
3005
+ if (lanes)
3006
+ lanes.message_fts = (outcome.laneResults ?? outcome.results).slice(0, 25);
1875
3007
  }
1876
3008
  const capturedQuery = await queryEmbeddingPromise;
1877
3009
  if (options.signal?.aborted)
@@ -1888,14 +3020,16 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
1888
3020
  sessionId,
1889
3021
  projectPath,
1890
3022
  queryEmbedding,
1891
- limit: tierLimit,
3023
+ limit: lanes ? Math.max(tierLimit, 25) : tierLimit,
1892
3024
  maxOrdinal: options.maxMessageOrdinal,
1893
3025
  modelId: chunkModelId && chunkModelId !== "off" ? chunkModelId : null,
1894
3026
  dateRange
1895
3027
  }) : [];
3028
+ if (lanes)
3029
+ lanes.chunk_vector = compartmentResults.slice(0, 25);
1896
3030
  const messageLikeResults = mergeMessageAndCompartmentResults({
1897
3031
  messages: messageResults,
1898
- compartments: compartmentResults,
3032
+ compartments: compartmentResults.slice(0, tierLimit),
1899
3033
  limit: tierLimit
1900
3034
  });
1901
3035
  const [memoryOutcome, gitCommitResults, primerResults, noteResults] = await Promise.all([
@@ -1910,6 +3044,7 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
1910
3044
  workspace,
1911
3045
  visibleMemoryIds: options.visibleMemoryIds,
1912
3046
  backfillMemoryEmbeddings: options.backfillMemoryEmbeddings,
3047
+ lanes,
1913
3048
  dateRange
1914
3049
  }) : Promise.resolve({
1915
3050
  results: [],
@@ -1922,7 +3057,8 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
1922
3057
  limit: tierLimit,
1923
3058
  queryEmbedding,
1924
3059
  queryModelId: embeddingModelId && embeddingModelId !== "off" ? embeddingModelId : null,
1925
- dateRange
3060
+ dateRange,
3061
+ lanes
1926
3062
  })) : Promise.resolve([]),
1927
3063
  runPrimers ? Promise.resolve(searchPrimers({
1928
3064
  db,
@@ -1931,14 +3067,15 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
1931
3067
  limit: tierLimit,
1932
3068
  queryEmbedding,
1933
3069
  queryModelId: embeddingModelId && embeddingModelId !== "off" ? embeddingModelId : null,
1934
- dateRange
3070
+ dateRange,
3071
+ lanes
1935
3072
  })) : Promise.resolve([]),
1936
3073
  runNotes ? Promise.resolve(searchNotes({
1937
3074
  db,
1938
3075
  sessionId,
1939
3076
  projectPath,
1940
3077
  query: trimmedQuery,
1941
- limit: tierLimit,
3078
+ limit: lanes ? Math.max(tierLimit, 25) : tierLimit,
1942
3079
  probes: messageProbes,
1943
3080
  dateRange
1944
3081
  })) : Promise.resolve([])
@@ -1946,23 +3083,37 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
1946
3083
  if (options.diagnostics) {
1947
3084
  options.diagnostics.suppressedVisibleMemoryIds = memoryOutcome.suppressedVisibleIds;
1948
3085
  }
1949
- const results = [
3086
+ let results = [
1950
3087
  ...memoryOutcome.results,
1951
3088
  ...primerResults,
1952
3089
  ...messageLikeResults,
1953
3090
  ...gitCommitResults,
1954
3091
  ...noteResults
1955
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
+ }
1956
3107
  if (!options.measurementDisabled) {
1957
3108
  recordShadowMeasurement({
1958
3109
  db,
1959
3110
  sessionId,
1960
3111
  projectPath,
1961
3112
  query: trimmedQuery,
1962
- options,
1963
- primaryResults: results,
3113
+ options: { ...options, rerank: false, captureRerankLanes: undefined },
3114
+ primaryResults: originalResults,
1964
3115
  primaryQuery: queryContract,
1965
- primaryLatencyMs: Date.now() - measurementStartedAt,
3116
+ primaryLatencyMs: originalLatencyMs,
1966
3117
  search: unifiedSearch2
1967
3118
  });
1968
3119
  }
@@ -2103,4 +3254,4 @@ ${bodyParts.join(`
2103
3254
  `)}`;
2104
3255
  }
2105
3256
 
2106
- export { indexCommitsForProject, embedUnembeddedCommits, createUnifiedSearchDiagnostics2, searchMessageHistory2, parseIdShapedQuery2, resolveMemoriesByIdsForSearch2, unifiedSearch2, formatSearchResults2 };
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 };