@cortexkit/opencode-magic-context 0.49.33 → 0.49.35

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 (229) hide show
  1. package/dist/auto-search-worker.js +11 -6
  2. package/dist/chunk-embedding-write-worker.js +16 -14
  3. package/dist/{compaction-marker-candidates-31h86ph0.js → compaction-marker-candidates-g0p67ced.js} +3 -2
  4. package/dist/compaction-marker-candidates-worker.js +1 -1
  5. package/dist/{compartment-chunk-embedding-5q5gj67r.js → compartment-chunk-embedding-y4136are.js} +8 -7
  6. package/dist/{conflict-warning-hook-xgskea1v.js → conflict-warning-hook-hhw8z5ak.js} +9 -8
  7. package/dist/{context-jyzkstnr.js → context-fk8e3h9p.js} +1400 -701
  8. package/dist/{derive-budgets-pqybnx09.js → derive-budgets-htj16n4x.js} +3 -2
  9. package/dist/embedding-backfill-q6n72sy0.js +27 -0
  10. package/dist/embedding-worker-process.js +2 -1
  11. package/dist/embedding-worker.js +5 -4
  12. package/dist/expand-attachments-h33jbgyz.js +21 -0
  13. package/dist/features/magic-context/auto-search-diagnostics.d.ts +21 -0
  14. package/dist/features/magic-context/auto-search-diagnostics.d.ts.map +1 -0
  15. package/dist/features/magic-context/compaction-marker.d.ts +22 -6
  16. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  17. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +1 -1
  18. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  19. package/dist/features/magic-context/search.d.ts +4 -0
  20. package/dist/features/magic-context/search.d.ts.map +1 -1
  21. package/dist/features/magic-context/storage-meta-persisted.d.ts +7 -0
  22. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  23. package/dist/features/magic-context/store-generation-rebase-labels.d.ts +6 -0
  24. package/dist/features/magic-context/store-generation-rebase-labels.d.ts.map +1 -0
  25. package/dist/features/magic-context/store-generation-rebase.d.ts.map +1 -1
  26. package/dist/{history-owner-36wp3mkb.js → history-owner-0z620wgz.js} +3 -2
  27. package/dist/hooks/magic-context/apply-operations.d.ts +20 -3
  28. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  29. package/dist/hooks/magic-context/auto-search-observation.d.ts +13 -0
  30. package/dist/hooks/magic-context/auto-search-observation.d.ts.map +1 -0
  31. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  32. package/dist/hooks/magic-context/auto-search-worker-client.d.ts +5 -1
  33. package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -1
  34. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +5 -5
  35. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  36. package/dist/hooks/magic-context/compaction-marker-publication.d.ts +9 -0
  37. package/dist/hooks/magic-context/compaction-marker-publication.d.ts.map +1 -0
  38. package/dist/hooks/magic-context/compartment-commit-hashes.d.ts +4 -0
  39. package/dist/hooks/magic-context/compartment-commit-hashes.d.ts.map +1 -0
  40. package/dist/hooks/magic-context/compartment-runner-validation.d.ts +1 -0
  41. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
  42. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/final-wire-completeness.d.ts +15 -0
  44. package/dist/hooks/magic-context/final-wire-completeness.d.ts.map +1 -0
  45. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  47. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts +1 -0
  48. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -1
  49. package/dist/hooks/magic-context/read-session-chunk.d.ts +11 -0
  50. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  51. package/dist/hooks/magic-context/read-session-formatting.d.ts +2 -0
  52. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  53. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  54. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  55. package/dist/{index-as2amvn3.js → index-0c7p8mq5.js} +6 -531
  56. package/dist/{index-51rdvtkz.js → index-1rhgxqs8.js} +2 -2
  57. package/dist/index-2amn2s73.js +123 -0
  58. package/dist/{index-c7phnbvk.js → index-2p37txes.js} +1 -1
  59. package/dist/index-2qbtqg1w.js +529 -0
  60. package/dist/{index-waktfbjy.js → index-2v6nvy3k.js} +4 -4
  61. package/dist/{index-dq5xzeb9.js → index-3d3872c6.js} +7 -5
  62. package/dist/{index-qr2mb02j.js → index-3j9t1v4n.js} +55 -21
  63. package/dist/{index-2xh37qn5.js → index-4bgk5ztz.js} +576 -5524
  64. package/dist/{index-b88dwwrh.js → index-4xyjr62e.js} +1 -1
  65. package/dist/index-66a50f3e.js +777 -0
  66. package/dist/{index-94ef0qe2.js → index-87ctnzz9.js} +33 -5
  67. package/dist/{index-xrnsygfq.js → index-9wnbnx8f.js} +1 -1
  68. package/dist/{index-3fkk2gwj.js → index-b6xz3qbe.js} +246 -420
  69. package/dist/{index-0fe4q77z.js → index-brg2w6qc.js} +146 -134
  70. package/dist/{index-spwjbkc7.js → index-dnqqqc5f.js} +1 -1
  71. package/dist/index-dy7w6wm4.js +194 -0
  72. package/dist/{index-3jmx3fae.js → index-ezv6dz3y.js} +37 -7
  73. package/dist/index-f297z1n8.js +4557 -0
  74. package/dist/{index-qgh1qwjj.js → index-f9b3vtt1.js} +1 -1
  75. package/dist/{index-v15ne3a3.js → index-faxb7mck.js} +2 -2
  76. package/dist/{index-rrv26qjz.js → index-fw42ms3m.js} +1 -1
  77. package/dist/{index-t5pck3ss.js → index-fxbk7gk3.js} +1 -1
  78. package/dist/{index-wfybj1dw.js → index-g4t7850m.js} +2 -2
  79. package/dist/{index-hbt0sbv2.js → index-gyaa159j.js} +18 -276
  80. package/dist/{index-4pnsgvfk.js → index-hacf2tyx.js} +1 -1
  81. package/dist/{index-s1n8dd2n.js → index-jkanybgq.js} +2 -2
  82. package/dist/{index-2743x98y.js → index-jn0ddrhp.js} +29 -138
  83. package/dist/{index-h7tgn49j.js → index-jrfre9ah.js} +5 -222
  84. package/dist/{index-kfyb3k6n.js → index-jz5bk7xd.js} +2 -2
  85. package/dist/{index-np3rgfw4.js → index-ksv0a31x.js} +3 -3
  86. package/dist/{index-7kkphb6c.js → index-nj360hcs.js} +4 -4
  87. package/dist/{index-gkee6p4g.js → index-p56dszfp.js} +3 -3
  88. package/dist/{index-4s4zq97n.js → index-pq0dpwrc.js} +4 -4
  89. package/dist/{index-rfxzazzy.js → index-pswsyf1w.js} +4 -4
  90. package/dist/{index-y1qwzvxn.js → index-pztqab6k.js} +2 -2
  91. package/dist/{index-rverk2vz.js → index-qncw9hey.js} +1 -1
  92. package/dist/index-qx8j6kds.js +270 -0
  93. package/dist/{index-kq5w68dp.js → index-txs8tce6.js} +1 -1
  94. package/dist/index-vzhhr1ht.js +532 -0
  95. package/dist/index-wh9fxds5.js +265 -0
  96. package/dist/{index-b7w46fp2.js → index-x2mrq5xv.js} +170 -48
  97. package/dist/{index-43vqx0za.js → index-xwwsbsd3.js} +15 -13
  98. package/dist/index-z4p0ry94.js +222 -0
  99. package/dist/index-z9zygwse.js +89 -0
  100. package/dist/{index-v7287tzq.js → index-zhqwda72.js} +19 -8
  101. package/dist/index.js +83 -72
  102. package/dist/{logger-94kew5wm.js → logger-qwnbcfj9.js} +2 -1
  103. package/dist/{message-fts-rowid-map-va36knh4.js → message-fts-rowid-map-xg7hr0mk.js} +5 -4
  104. package/dist/{message-index-bounded-zq7a5nm6.js → message-index-bounded-narw7bnz.js} +12 -11
  105. package/dist/{message-time-backfill-4qva0b4f.js → message-time-backfill-39bm498k.js} +3 -2
  106. package/dist/migration-worker.js +13 -11
  107. package/dist/{project-embedding-registry-6yex0r9f.js → project-embedding-registry-tdz7985n.js} +13 -11
  108. package/dist/raw-ordinal-warmup-worker.js +12 -7
  109. package/dist/{read-session-chunk-1ndphmb8.js → read-session-chunk-vmg1zjg0.js} +15 -10
  110. package/dist/{read-session-raw-b2sd67v4.js → read-session-raw-mncmzbm9.js} +3 -2
  111. package/dist/recomp-orchestrator-qyyhnc9b.js +68 -0
  112. package/dist/render-c5p0k846.js +43 -0
  113. package/dist/{safe-notification-target-mkr9yzvr.js → safe-notification-target-wztd7bgk.js} +3 -2
  114. package/dist/{search-archive-sr07c6aj.js → search-archive-0ny7p3bw.js} +13 -11
  115. package/dist/{search-040pac3a.js → search-f6hwvcxk.js} +26 -23
  116. package/dist/{send-session-notification-vz86nt79.js → send-session-notification-0gwcz3fw.js} +7 -6
  117. package/dist/{storage-tags-6hvkk01c.js → storage-tags-zx1023km.js} +5 -4
  118. package/dist/store-620rjzt9.js +21 -0
  119. package/dist/store-reader-yh19h38c.js +14 -0
  120. package/dist/tools/ctx-expand/render.d.ts +5 -3
  121. package/dist/tools/ctx-expand/render.d.ts.map +1 -1
  122. package/dist/tools/ctx-expand/search-archive.d.ts.map +1 -1
  123. package/dist/tools/ctx-expand/tools.d.ts +2 -0
  124. package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
  125. package/dist/tools/ctx-expand/v2-archive-reader.d.ts +33 -0
  126. package/dist/tools/ctx-expand/v2-archive-reader.d.ts.map +1 -0
  127. package/dist/{transform-postprocess-phase-zx1peqma.js → transform-postprocess-phase-807ff6t2.js} +36 -30
  128. package/dist/v2/auto-search-worker.js +11 -6
  129. package/dist/v2/chunk-embedding-write-worker.js +16 -14
  130. package/dist/v2/{compaction-marker-candidates-m4vmye3w.js → compaction-marker-candidates-t1aq6gsj.js} +3 -2
  131. package/dist/v2/compaction-marker-candidates-worker.js +1 -1
  132. package/dist/v2/{compartment-chunk-embedding-rc31e6md.js → compartment-chunk-embedding-ncsk0r9e.js} +8 -7
  133. package/dist/v2/{context-3c4z2wj5.js → context-znqfkap4.js} +1725 -1095
  134. package/dist/v2/{derive-budgets-knf763tt.js → derive-budgets-sa0v7bz0.js} +4 -3
  135. package/dist/v2/embedding-backfill-11j425e0.js +26 -0
  136. package/dist/v2/embedding-worker-process.js +2 -1
  137. package/dist/v2/embedding-worker.js +5 -4
  138. package/dist/v2/expand-attachments-h33jbgyz.js +21 -0
  139. package/dist/v2/fold/idle.d.ts +15 -0
  140. package/dist/v2/fold/idle.d.ts.map +1 -0
  141. package/dist/v2/fold/native-replay-v3.d.ts +68 -0
  142. package/dist/v2/fold/native-replay-v3.d.ts.map +1 -0
  143. package/dist/v2/fold/native-replay.d.ts +58 -2
  144. package/dist/v2/fold/native-replay.d.ts.map +1 -1
  145. package/dist/v2/fold/policy.d.ts +2 -1
  146. package/dist/v2/fold/policy.d.ts.map +1 -1
  147. package/dist/v2/{history-owner-ad0crnrn.js → history-owner-fpka43cn.js} +3 -2
  148. package/dist/v2/hooks/context.d.ts.map +1 -1
  149. package/dist/v2/hooks/expand-attachments.d.ts +8 -0
  150. package/dist/v2/hooks/expand-attachments.d.ts.map +1 -0
  151. package/dist/v2/hooks/overflow-recovery.d.ts +45 -0
  152. package/dist/v2/hooks/overflow-recovery.d.ts.map +1 -0
  153. package/dist/v2/hooks/store.d.ts +7 -2
  154. package/dist/v2/hooks/store.d.ts.map +1 -1
  155. package/dist/v2/{logger-p34mjtja.js → logger-4cj6d03m.js} +2 -1
  156. package/dist/v2/{message-fts-rowid-map-78awh03v.js → message-fts-rowid-map-rmk571mb.js} +5 -4
  157. package/dist/v2/{message-index-bounded-jvgz7vk9.js → message-index-bounded-620bppw7.js} +12 -11
  158. package/dist/v2/{message-time-backfill-zvthw6xb.js → message-time-backfill-0c4h7sg6.js} +3 -2
  159. package/dist/v2/migration-worker.js +13 -11
  160. package/dist/v2/ordinal-range.fixture.d.ts +7 -0
  161. package/dist/v2/ordinal-range.fixture.d.ts.map +1 -0
  162. package/dist/v2/{project-embedding-registry-1x5qe2fy.js → project-embedding-registry-bm5fe1a8.js} +13 -11
  163. package/dist/v2/raw-ordinal-warmup-worker.js +12 -7
  164. package/dist/v2/{read-session-chunk-djzgm4jg.js → read-session-chunk-qfwv1k71.js} +15 -10
  165. package/dist/v2/{read-session-raw-5x088amc.js → read-session-raw-q294t8xs.js} +3 -2
  166. package/dist/v2/recomp-orchestrator-fcnjref7.js +67 -0
  167. package/dist/v2/render-98a1qv0b.js +42 -0
  168. package/dist/v2/{safe-notification-target-khnzg57c.js → safe-notification-target-gphhast7.js} +3 -2
  169. package/dist/v2/{search-archive-n3dhns4r.js → search-archive-r0y1bafr.js} +13 -11
  170. package/dist/v2/{search-q3wkpe8t.js → search-z1zqzsmh.js} +25 -22
  171. package/dist/v2/{send-session-notification-x5nzy34v.js → send-session-notification-fst6hkg7.js} +7 -6
  172. package/dist/v2/{server-rb8m4vry.js → server-1xesqm5h.js} +146 -134
  173. package/dist/v2/server-2amn2s73.js +123 -0
  174. package/dist/v2/{server-6g98c227.js → server-3schkz95.js} +4 -4
  175. package/dist/v2/server-468mya5v.js +209 -0
  176. package/dist/v2/server-55v5hpth.js +270 -0
  177. package/dist/v2/server-5jp38p98.js +532 -0
  178. package/dist/v2/{server-qjvk4a9t.js → server-69m30b21.js} +1 -1
  179. package/dist/v2/{server-d01pe8q5.js → server-7ccxt4nq.js} +14 -216
  180. package/dist/v2/{server-3mz2qh5a.js → server-969cdpmg.js} +1 -1
  181. package/dist/v2/{server-835q39kd.js → server-9k0mjef7.js} +2 -2
  182. package/dist/v2/{server-qc915kw2.js → server-bez34e60.js} +4 -4
  183. package/dist/v2/{server-nxas8v1d.js → server-bpvsvtph.js} +3 -3
  184. package/dist/v2/{server-ab8017gw.js → server-bxpz2dcn.js} +29 -138
  185. package/dist/v2/{server-bsgd4dk1.js → server-dcws5831.js} +2 -2
  186. package/dist/v2/server-ef1mskas.js +777 -0
  187. package/dist/v2/{server-1bw1wcbp.js → server-f0j864ma.js} +1 -1
  188. package/dist/v2/{server-aqbm9c8d.js → server-fqj6ddpr.js} +632 -5540
  189. package/dist/v2/{server-rr4cbkr0.js → server-hnknwaz8.js} +37 -7
  190. package/dist/v2/{server-h1byrhwx.js → server-hsf0qsn5.js} +19 -8
  191. package/dist/v2/{server-6495nmn9.js → server-jb6tjyeb.js} +5 -222
  192. package/dist/v2/{server-2aasmpsp.js → server-kkxzwa6w.js} +4 -4
  193. package/dist/v2/{server-a7x00tw8.js → server-mfn1yf9d.js} +1 -1
  194. package/dist/v2/{server-tkdabx8q.js → server-q0z2q2dx.js} +5 -530
  195. package/dist/v2/{server-n14edf07.js → server-qa74bj91.js} +77 -17
  196. package/dist/v2/server-qf2kzsh2.js +4513 -0
  197. package/dist/v2/{server-gyy4k6mf.js → server-qmmkhz2z.js} +1 -1
  198. package/dist/v2/{server-29qp8nz4.js → server-qxzbmtqt.js} +1 -1
  199. package/dist/v2/{server-hwag0khr.js → server-r3chnxs5.js} +4 -4
  200. package/dist/v2/{server-vr4szghm.js → server-rktnzs89.js} +2 -2
  201. package/dist/v2/{server-6vd2n183.js → server-s9xgyyj9.js} +1 -1
  202. package/dist/v2/{server-53eh1r8r.js → server-sd8hvzte.js} +2 -2
  203. package/dist/v2/{server-k3t06fxr.js → server-sefxj8k1.js} +1 -1
  204. package/dist/v2/{server-v77xa5wj.js → server-tpt7bwq8.js} +1 -1
  205. package/dist/v2/{server-awr8qa4c.js → server-ws5exe6q.js} +2 -2
  206. package/dist/v2/server-x4m6xcn4.js +194 -0
  207. package/dist/v2/{server-806rzhs6.js → server-xbtw0p9t.js} +1 -1
  208. package/dist/v2/{server-cqjvxyrp.js → server-xy7w7hrd.js} +2 -2
  209. package/dist/v2/server-ypf1ap0v.js +529 -0
  210. package/dist/v2/server-z4p0ry94.js +222 -0
  211. package/dist/v2/server-z9zygwse.js +89 -0
  212. package/dist/v2/{server-ab1g0wn9.js → server-zzgtgqmd.js} +2 -2
  213. package/dist/v2/server.js +6 -5
  214. package/dist/v2/{storage-tags-18nbaanf.js → storage-tags-19s0ebf0.js} +5 -4
  215. package/dist/v2/store-reader-cgx47zkp.js +14 -0
  216. package/dist/v2/store-reader.d.ts +9 -2
  217. package/dist/v2/store-reader.d.ts.map +1 -1
  218. package/dist/v2/store-vdm8v3jd.js +21 -0
  219. package/dist/v2/v2-archive-reader-t2c0eypn.js +11 -0
  220. package/dist/v2/{wrapup-orchestrator-ga5vfmwr.js → wrapup-orchestrator-aqpqsveg.js} +46 -39
  221. package/dist/v2-archive-reader-tm2eayp2.js +11 -0
  222. package/dist/wrapup-orchestrator-k5yp19a6.js +55 -0
  223. package/package.json +1 -1
  224. package/src/shared/sqlite-transaction-mode-guard.test.ts +4 -0
  225. package/dist/embedding-backfill-0jgtqxen.js +0 -25
  226. package/dist/recomp-orchestrator-skqzzvby.js +0 -62
  227. package/dist/v2/embedding-backfill-f43hd8y6.js +0 -24
  228. package/dist/v2/recomp-orchestrator-qfqdvbta.js +0 -61
  229. package/dist/wrapup-orchestrator-dy8r3gp8.js +0 -49
@@ -0,0 +1,265 @@
1
+ import {
2
+ sanitizeDiagnosticText
3
+ } from "./index-z4p0ry94.js";
4
+
5
+ // src/features/magic-context/fail-closed-block.ts
6
+ var FAIL_CLOSED_DOCTOR_COMMAND = "npx @cortexkit/magic-context@latest doctor";
7
+ var FAIL_CLOSED_REPROBE_EVERY_N = 5;
8
+ function attachFailClosedBlockingProcessEvidence(process, evidence) {
9
+ Object.defineProperties(process, {
10
+ startTime: { configurable: true, value: evidence.startTime },
11
+ commandLine: { configurable: true, value: evidence.commandLine }
12
+ });
13
+ return process;
14
+ }
15
+
16
+ class FailClosedBlockingError extends Error {
17
+ code = "FAIL_CLOSED_BLOCKING";
18
+ reason;
19
+ constructor(message, reason, options) {
20
+ super(message, options);
21
+ this.name = "FailClosedBlockingError";
22
+ this.reason = reason;
23
+ }
24
+ }
25
+ var OPENCODE_INTERNAL_AGENT_NAMES = new Set(["title", "summary", "compaction"]);
26
+ function isMagicContextHiddenAgentName(agent) {
27
+ if (agent === "smart-note-compiler" || agent.startsWith("smart-note-")) {
28
+ return true;
29
+ }
30
+ if (agent === "historian" || agent.startsWith("historian-"))
31
+ return true;
32
+ if (agent === "dreamer" || agent.startsWith("dreamer-"))
33
+ return true;
34
+ return false;
35
+ }
36
+ var MAX_FORMATTED_BLOCKING_PROCESSES = 8;
37
+ var MAX_FORMATTED_COMMAND_LINE_LENGTH = 80;
38
+ function normalizeFailClosedProcessKind(process) {
39
+ switch (process.kind) {
40
+ case "OpenCode server":
41
+ case "OpenCode instance (TUI/CLI)":
42
+ case "Pi":
43
+ case "process":
44
+ return process.kind;
45
+ }
46
+ switch (process.harness?.trim().toLowerCase()) {
47
+ case "opencode server":
48
+ return "OpenCode server";
49
+ case "opencode instance (tui/cli)":
50
+ case "opencode instance":
51
+ return "OpenCode instance (TUI/CLI)";
52
+ case "pi":
53
+ case "pi harness":
54
+ case "omp":
55
+ return "Pi";
56
+ default:
57
+ return "process";
58
+ }
59
+ }
60
+ function formatFailClosedProcessStartTime(startTime) {
61
+ if (!Number.isFinite(startTime) || startTime <= 0)
62
+ return "unverified";
63
+ try {
64
+ const parts = new Intl.DateTimeFormat("en-US", {
65
+ day: "numeric",
66
+ hour: "2-digit",
67
+ minute: "2-digit",
68
+ month: "short",
69
+ hour12: false
70
+ }).formatToParts(new Date(startTime));
71
+ const values = Object.fromEntries(parts.map(({ type, value }) => [type, value]));
72
+ if (!values.month || !values.day || !values.hour || !values.minute)
73
+ return "unverified";
74
+ return `${values.month} ${values.day} ${values.hour}:${values.minute}`;
75
+ } catch {
76
+ return "unverified";
77
+ }
78
+ }
79
+ function formatFailClosedCommandLine(commandLine) {
80
+ if (typeof commandLine !== "string" || commandLine.trim().length === 0)
81
+ return "unverified";
82
+ try {
83
+ const normalized = commandLine.replaceAll("\x00", " ").replace(/\s+/g, " ").trim();
84
+ if (normalized.length === 0)
85
+ return "unverified";
86
+ const sanitized = sanitizeDiagnosticText(normalized).trim();
87
+ if (sanitized.length === 0)
88
+ return "unverified";
89
+ return sanitized.length > MAX_FORMATTED_COMMAND_LINE_LENGTH ? `${sanitized.slice(0, MAX_FORMATTED_COMMAND_LINE_LENGTH - 3)}...` : sanitized;
90
+ } catch {
91
+ return "unverified";
92
+ }
93
+ }
94
+ function formatFailClosedBlockingProcesses(processes) {
95
+ const uniqueProcesses = new Map;
96
+ for (const process of processes) {
97
+ if (!Number.isInteger(process.pid) || process.pid <= 0)
98
+ continue;
99
+ const candidate = {
100
+ kind: normalizeFailClosedProcessKind(process),
101
+ pid: process.pid,
102
+ startTime: process.startTime,
103
+ commandLine: process.commandLine
104
+ };
105
+ const previous = uniqueProcesses.get(process.pid);
106
+ if (!previous || previous.kind === "process" && candidate.kind !== "process") {
107
+ uniqueProcesses.set(process.pid, candidate);
108
+ } else {
109
+ uniqueProcesses.set(process.pid, {
110
+ ...previous,
111
+ startTime: previous.startTime ?? candidate.startTime,
112
+ commandLine: previous.commandLine ?? candidate.commandLine
113
+ });
114
+ }
115
+ }
116
+ const entries = [...uniqueProcesses.values()];
117
+ const visible = entries.slice(0, MAX_FORMATTED_BLOCKING_PROCESSES);
118
+ const rendered = visible.map(({ kind, pid }) => `${kind} (PID ${pid})`);
119
+ const omitted = entries.length - visible.length;
120
+ if (omitted > 0)
121
+ rendered.push(`${omitted} more blocking process(es)`);
122
+ if (rendered.length === 0)
123
+ return "a live process";
124
+ const summary = rendered.length === 1 ? rendered[0] : `${rendered.slice(0, -1).join(", ")}, and ${rendered.at(-1)}`;
125
+ const evidence = entries.map(({ kind, pid, startTime, commandLine }) => `- PID ${pid}: ${kind}, started ${formatFailClosedProcessStartTime(startTime)}, cmd: ${formatFailClosedCommandLine(commandLine)}`).join(`
126
+ `);
127
+ return `${summary}
128
+ Blocking process evidence:
129
+ ${evidence}`;
130
+ }
131
+ function formatFailClosedBlockingMessage(reason) {
132
+ if (reason.kind === "migration_guard") {
133
+ if (reason.unreadableFile) {
134
+ const arm = reason.unreadableArm ?? "io";
135
+ const recovery = arm === "io" ? `If none of these processes are running, it is safe to delete ${reason.unreadableFile} and retry.` : `The file may be a recent incomplete write; retry after the file is older than the ten-minute grace window, or stop the relevant process before deleting it.`;
136
+ return [
137
+ `Magic Context cannot migrate the shared database because RPC discovery file ${reason.unreadableFile} is uncertain (${arm} arm), so the absence of a live process cannot be proven.`,
138
+ recovery,
139
+ `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
140
+ ].join(" ");
141
+ }
142
+ return [
143
+ `Magic Context cannot migrate the shared database (one database serves every project on this machine) because ${formatFailClosedBlockingProcesses(reason.blockingProcesses)} may be running an older Magic Context build that would fail against the migrated database.`,
144
+ `The database is at upstream migration v${reason.persistedVersion}; this build needs v${reason.supportedVersion}.`,
145
+ "Restart the blocking process — even one from a different project — and it will pick up the new build and migrate on start; or shut it down and retry.",
146
+ "If that host loads a pinned or cached older Magic Context build, a restart alone is not enough: stop it or update its Magic Context build, then start this host once so it migrates the database with nothing older attached.",
147
+ `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
148
+ ].join(" ");
149
+ }
150
+ if (reason.kind === "schema_fence") {
151
+ return [
152
+ `Magic Context cannot operate: this Magic Context build is older than the database; upgrade/restart this harness (upstream migration lane v${reason.persistedVersion}, build supports through v${reason.supportedVersion}).`,
153
+ `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
154
+ ].join(" ");
155
+ }
156
+ const cause = reason.cause.trim().length > 0 ? reason.cause.trim() : "unknown storage error";
157
+ return [
158
+ `Magic Context cannot operate: persistent storage failed (${cause}).`,
159
+ "The plugin will not silently degrade to native compaction while enabled.",
160
+ `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
161
+ ].join(" ");
162
+ }
163
+ function formatFailClosedBlockingSummary(reason) {
164
+ if (reason.kind === "migration_guard") {
165
+ if (reason.unreadableFile) {
166
+ return `Magic Context cannot migrate the shared database from v${reason.persistedVersion} to v${reason.supportedVersion}: RPC discovery file ${reason.unreadableFile} could not be read, so an older host may still be attached.`;
167
+ }
168
+ const blockers = reason.blockingProcesses.filter((process) => Number.isInteger(process.pid) && process.pid > 0).map((process) => `${normalizeFailClosedProcessKind(process)} (PID ${process.pid})`);
169
+ const named = blockers.length > 0 ? blockers.join(", ") : "a live process";
170
+ return `Magic Context cannot migrate the shared database from v${reason.persistedVersion} to v${reason.supportedVersion} while ${named} may still run an older Magic Context build. Stop or update that host, then start this one once.`;
171
+ }
172
+ if (reason.kind === "schema_fence") {
173
+ return `Magic Context cannot operate: the shared database is at v${reason.persistedVersion}, newer than this build supports (v${reason.supportedVersion}). Update and restart this host.`;
174
+ }
175
+ const cause = reason.cause.trim().length > 0 ? reason.cause.trim() : "unknown storage error";
176
+ return `Magic Context cannot operate: persistent storage failed (${cause}).`;
177
+ }
178
+ function createFailClosedBlockingError(reason, options) {
179
+ return new FailClosedBlockingError(formatFailClosedBlockingMessage(reason), reason, options);
180
+ }
181
+ function isFailClosedBlockingError(error) {
182
+ return error instanceof FailClosedBlockingError || typeof error === "object" && error !== null && error.name === "FailClosedBlockingError" && error.code === "FAIL_CLOSED_BLOCKING";
183
+ }
184
+ function shouldBypassFailClosedBlock(input) {
185
+ if (input.isPiSubagentEnv === true)
186
+ return true;
187
+ if (input.isInternalChildSession === true)
188
+ return true;
189
+ const agent = typeof input.agent === "string" ? input.agent.trim() : "";
190
+ if (agent.length === 0)
191
+ return false;
192
+ if (OPENCODE_INTERNAL_AGENT_NAMES.has(agent))
193
+ return true;
194
+ if (isMagicContextHiddenAgentName(agent))
195
+ return true;
196
+ return false;
197
+ }
198
+ function resolveAgentNameFromMessages(messages) {
199
+ for (let i = messages.length - 1;i >= 0; i -= 1) {
200
+ const info = messages[i]?.info;
201
+ if (!info || typeof info !== "object")
202
+ continue;
203
+ const agent = info.agent;
204
+ if (typeof agent === "string" && agent.length > 0)
205
+ return agent;
206
+ }
207
+ return;
208
+ }
209
+ function createFailClosedController(options) {
210
+ const reprobeEveryN = Math.max(1, options?.reprobeEveryN ?? FAIL_CLOSED_REPROBE_EVERY_N);
211
+ let reason = null;
212
+ let blockedPassCount = 0;
213
+ return {
214
+ arm(next) {
215
+ reason = next;
216
+ blockedPassCount = 0;
217
+ },
218
+ clear() {
219
+ reason = null;
220
+ blockedPassCount = 0;
221
+ },
222
+ isArmed() {
223
+ return reason !== null;
224
+ },
225
+ getReason() {
226
+ return reason;
227
+ },
228
+ async enforce(input) {
229
+ if (!reason)
230
+ return;
231
+ if (!input.blockingEnabled)
232
+ return;
233
+ if (input.exempt)
234
+ return;
235
+ blockedPassCount += 1;
236
+ const shouldReprobe = typeof input.tryReopen === "function" && (blockedPassCount === 1 || blockedPassCount % reprobeEveryN === 0);
237
+ if (shouldReprobe) {
238
+ try {
239
+ const healed = await input.tryReopen?.();
240
+ if (healed) {
241
+ reason = null;
242
+ blockedPassCount = 0;
243
+ return;
244
+ }
245
+ } catch {}
246
+ }
247
+ const blockedReason = reason;
248
+ if (!blockedReason)
249
+ return;
250
+ throw createFailClosedBlockingError(blockedReason);
251
+ }
252
+ };
253
+ }
254
+ var lastHookInitFailure = null;
255
+ function recordHookInitFailure(failure) {
256
+ lastHookInitFailure = failure;
257
+ }
258
+ function clearHookInitFailure() {
259
+ lastHookInitFailure = null;
260
+ }
261
+ function getLastHookInitFailure() {
262
+ return lastHookInitFailure;
263
+ }
264
+
265
+ export { FAIL_CLOSED_DOCTOR_COMMAND, attachFailClosedBlockingProcessEvidence, formatFailClosedBlockingMessage, formatFailClosedBlockingSummary, createFailClosedBlockingError, isFailClosedBlockingError, shouldBypassFailClosedBlock, resolveAgentNameFromMessages, createFailClosedController, recordHookInitFailure, clearHookInitFailure, getLastHookInitFailure };
@@ -7,7 +7,7 @@ import {
7
7
  getTemporalDecisions,
8
8
  freezeTemporalDecisions,
9
9
  stableStringify
10
- } from "./index-xrnsygfq.js";
10
+ } from "./index-9wnbnx8f.js";
11
11
  import {
12
12
  protectedToolTagNumbers,
13
13
  stripPersistedAssistantText,
@@ -74,19 +74,19 @@ import {
74
74
  adoptNullOwnerToolTag2,
75
75
  getCandidateToolOwners2,
76
76
  pickNearestPriorOwner2
77
- } from "./index-np3rgfw4.js";
77
+ } from "./index-ksv0a31x.js";
78
78
  import {
79
79
  textMentionsRecentCommit,
80
80
  hasMeaningfulUserText2,
81
81
  estimateTokens
82
- } from "./index-b88dwwrh.js";
82
+ } from "./index-4xyjr62e.js";
83
83
  import {
84
84
  getMagicContextStorageDir
85
85
  } from "./index-g2q4htwp.js";
86
86
  import {
87
87
  log2,
88
88
  sessionLog2
89
- } from "./index-h7tgn49j.js";
89
+ } from "./index-jrfre9ah.js";
90
90
  import {
91
91
  inRootAsyncContext2,
92
92
  getTagIdentityWriteGeneration2,
@@ -94,17 +94,12 @@ import {
94
94
  assertTransformWrite2,
95
95
  isTransientSqliteError2
96
96
  } from "./index-gzy5w8ya.js";
97
- import {
98
- getProjectEmbeddingSnapshot2,
99
- embedTextForProject2,
100
- embedBatchForProject2
101
- } from "./index-2743x98y.js";
102
97
  import {
103
98
  createWorkerShutdown
104
99
  } from "./index-cpjk5jd2.js";
105
100
  import {
106
101
  runSessionWarmupWorker
107
- } from "./index-rverk2vz.js";
102
+ } from "./index-qncw9hey.js";
108
103
  import {
109
104
  getMaxM0MutationId,
110
105
  getLastCompartmentEndMessage,
@@ -121,30 +116,12 @@ import {
121
116
  clearPendingMaterialization,
122
117
  saveSourceContent,
123
118
  replaceSourceContent,
124
- getSourceContents,
125
- compareOpenCodeMessagesByCanonicalOrder,
126
- prepareCompactionMarkerCandidates,
127
- MARKER_SUMMARY_TEXT,
128
- applyDeferredCompactionMarker,
129
- injectTemporalMarkers,
130
- clearInjectionCache,
131
- getVisibleMemoryIds,
132
- renderCompartmentInjection,
133
- MaterializeContentionError,
134
- mustMaterialize,
135
- hydrateCachedM0Mural,
136
- prepareCachedM0M1Replay,
137
- hasCompleteCachedM0M1,
138
- injectM0M1,
139
- observeNoteNudgeServe,
140
- peekNoteNudgeText,
141
- markNoteNudgeDelivered,
142
- getActiveCompartmentRun
143
- } from "./index-2xh37qn5.js";
119
+ getSourceContents
120
+ } from "./index-f297z1n8.js";
144
121
  import {
145
122
  cleanSearchText,
146
123
  matchedSearchSnippet
147
- } from "./index-4s4zq97n.js";
124
+ } from "./index-pq0dpwrc.js";
148
125
  import {
149
126
  stripSystemInjection,
150
127
  isTextPart,
@@ -242,10 +219,15 @@ import {
242
219
  extractToolCallObservation,
243
220
  ToolMutationBatch,
244
221
  createToolDropTarget
245
- } from "./index-0fe4q77z.js";
222
+ } from "./index-brg2w6qc.js";
246
223
  import {
247
224
  isValidLanguageCode
248
225
  } from "./index-nxrsns5x.js";
226
+ import {
227
+ getProjectEmbeddingSnapshot2,
228
+ embedTextForProject2,
229
+ embedBatchForProject2
230
+ } from "./index-jn0ddrhp.js";
249
231
  import {
250
232
  isEmbeddingHostBusy2
251
233
  } from "./index-qt1qqasc.js";
@@ -253,17 +235,38 @@ import {
253
235
  openCodeDbExists,
254
236
  withReadOnlySessionDb,
255
237
  getMessageTimesFromOpenCodeDb
256
- } from "./index-y1qwzvxn.js";
238
+ } from "./index-pztqab6k.js";
257
239
  import {
258
240
  BoundedSessionMap
259
- } from "./index-s1n8dd2n.js";
241
+ } from "./index-jkanybgq.js";
260
242
  import {
261
243
  getMessageIndexEpoch,
262
- isMessageIndexSearchable
263
- } from "./index-94ef0qe2.js";
244
+ isMessageIndexSearchable,
245
+ createAutoSearchDiagnostics
246
+ } from "./index-87ctnzz9.js";
247
+ import {
248
+ compareOpenCodeMessagesByCanonicalOrder,
249
+ prepareCompactionMarkerCandidates,
250
+ MARKER_SUMMARY_TEXT,
251
+ applyDeferredCompactionMarker,
252
+ injectTemporalMarkers,
253
+ clearInjectionCache,
254
+ getVisibleMemoryIds,
255
+ renderCompartmentInjection,
256
+ MaterializeContentionError,
257
+ mustMaterialize,
258
+ hydrateCachedM0Mural,
259
+ prepareCachedM0M1Replay,
260
+ hasCompleteCachedM0M1,
261
+ injectM0M1,
262
+ observeNoteNudgeServe,
263
+ peekNoteNudgeText,
264
+ markNoteNudgeDelivered,
265
+ getActiveCompartmentRun
266
+ } from "./index-4bgk5ztz.js";
264
267
  import {
265
268
  userFacingFailureCode
266
- } from "./index-as2amvn3.js";
269
+ } from "./index-0c7p8mq5.js";
267
270
  import {
268
271
  normalizeProtectedToolName,
269
272
  mergeProtectedTools
@@ -273,7 +276,7 @@ import {
273
276
  } from "./index-y8v6yerm.js";
274
277
  import {
275
278
  logSlowWriteTransaction
276
- } from "./index-t5pck3ss.js";
279
+ } from "./index-fxbk7gk3.js";
277
280
 
278
281
  // src/features/magic-context/tagger.ts
279
282
  var TOOL_COMPOSITE_KEY_SEP = "\x00";
@@ -1262,6 +1265,32 @@ function selectAutoSearchResults(results, threshold) {
1262
1265
  return results.filter((result) => relevance(result) >= threshold).sort((left, right) => relevance(right) - relevance(left));
1263
1266
  }
1264
1267
 
1268
+ // src/hooks/magic-context/auto-search-observation.ts
1269
+ var disabledTurns = new WeakMap;
1270
+ function logDisabledAutoSearch(db, sessionId, messageId, threshold, startedAt) {
1271
+ const sessions = disabledTurns.get(db) ?? new Map;
1272
+ disabledTurns.set(db, sessions);
1273
+ if (sessions.get(sessionId) === messageId)
1274
+ return;
1275
+ sessions.set(sessionId, messageId);
1276
+ observeAutoSearch(sessionId, threshold, startedAt).finish("disabled");
1277
+ }
1278
+ function observeAutoSearch(sessionId, threshold, startedAt) {
1279
+ const diagnostics = createAutoSearchDiagnostics(threshold);
1280
+ let logged = false;
1281
+ return {
1282
+ diagnostics,
1283
+ finish(outcome, reason) {
1284
+ if (logged)
1285
+ return;
1286
+ logged = true;
1287
+ const lanes = Object.entries(diagnostics.lanes).map(([lane, value]) => `${lane}:${value.top?.toFixed(3) ?? "none"}`).join(",");
1288
+ const nearMisses = Object.values(diagnostics.lanes).reduce((sum, lane) => sum + lane.nearMisses, 0);
1289
+ sessionLog2(sessionId, `auto-search: decision outcome=${outcome}${reason ? ` reason=${reason}` : ""} lanes=${lanes || "none"} nearMisses=${nearMisses} threshold=${threshold} pool=${diagnostics.pool} rows=${diagnostics.poolRows ?? "unknown"} workerStarted=${diagnostics.workerStarted ?? "unknown"} peek=${diagnostics.peek} elapsedMs=${Math.round(performance.now() - startedAt)}`);
1290
+ }
1291
+ };
1292
+ }
1293
+
1265
1294
  // src/hooks/magic-context/auto-search-worker-client.ts
1266
1295
  import { Worker } from "node:worker_threads";
1267
1296
  var pendingRegistrations = new WeakMap;
@@ -1499,6 +1528,7 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
1499
1528
  readMessages: _readMessages,
1500
1529
  searchMessageHistory: _searchMessageHistory,
1501
1530
  stepTimings: _stepTimings,
1531
+ onAutoSearchDiagnostics: _onAutoSearchDiagnostics,
1502
1532
  ...serializable
1503
1533
  } = options;
1504
1534
  const lifecycle = registerAutoSearchWork(sessionId);
@@ -1540,6 +1570,11 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
1540
1570
  throw new AutoSearchBusyError;
1541
1571
  }
1542
1572
  const { slot, fresh } = lease;
1573
+ if (options.autoSearchDiagnostics) {
1574
+ options.autoSearchDiagnostics.workerStarted = fresh;
1575
+ if (fresh)
1576
+ options.autoSearchDiagnostics.pool = "cold";
1577
+ }
1543
1578
  const worker = slot.worker;
1544
1579
  const detachable = job === "search" && entry.href === defaultAutoSearchWorkerEntry().href;
1545
1580
  const startedAt = performance.now();
@@ -1619,6 +1654,15 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
1619
1654
  const onMessage = async (reply) => {
1620
1655
  if (released)
1621
1656
  return;
1657
+ if (reply.kind === "diagnostics") {
1658
+ if (!settled && options.autoSearchDiagnostics) {
1659
+ const workerStarted = options.autoSearchDiagnostics.workerStarted;
1660
+ Object.assign(options.autoSearchDiagnostics, reply.diagnostics, {
1661
+ workerStarted
1662
+ });
1663
+ }
1664
+ return;
1665
+ }
1622
1666
  if (reply.kind === "result" || reply.kind === "error") {
1623
1667
  if (detachedAt !== undefined) {
1624
1668
  logLateSearch(sessionId, performance.now() - detachedAt, detachedAt - startedAt, ownerVectorMs, reply.kind === "result" ? reply.timings : undefined, reply.kind === "error");
@@ -1954,8 +1998,12 @@ function findLatestMeaningfulUserMessage(messages) {
1954
1998
  async function runAutoSearchHint(args) {
1955
1999
  const startedAt = performance.now();
1956
2000
  const { sessionId, db, messages, options } = args;
1957
- if (!options.enabled)
2001
+ if (!options.enabled) {
2002
+ const tail = findLatestMeaningfulUserMessage(messages);
2003
+ if (tail && typeof tail.info.id === "string" && messages.at(-1) === tail)
2004
+ logDisabledAutoSearch(db, sessionId, tail.info.id, options.scoreThreshold, startedAt);
1958
2005
  return AUTO_SEARCH_OK;
2006
+ }
1959
2007
  const userMsg = findLatestMeaningfulUserMessage(messages);
1960
2008
  if (!userMsg || typeof userMsg.info.id !== "string")
1961
2009
  return AUTO_SEARCH_OK;
@@ -1979,10 +2027,12 @@ async function runAutoSearchHint(args) {
1979
2027
  if (messages.length === 0 || messages[messages.length - 1].info.id !== userMsgId) {
1980
2028
  return AUTO_SEARCH_OK;
1981
2029
  }
2030
+ const observation = observeAutoSearch(sessionId, options.scoreThreshold, startedAt);
1982
2031
  const embeddingSnapshot = getProjectEmbeddingSnapshot2(options.projectPath);
1983
2032
  if (!embeddingSnapshot) {
1984
2033
  queueAutoSearchRegistration(db, options.projectPath, options.directory && options.ensureProjectRegistered ? () => options.ensureProjectRegistered?.(options.directory, db) ?? Promise.resolve() : undefined);
1985
2034
  persistAutoSearchSkip(db, sessionId, userMsgId, "empty");
2035
+ observation.finish("no-candidates", "unregistered");
1986
2036
  return AUTO_SEARCH_OK;
1987
2037
  }
1988
2038
  const writeNoHintAndReconcile = async (reason) => {
@@ -1993,21 +2043,24 @@ async function runAutoSearchHint(args) {
1993
2043
  }, startedAt);
1994
2044
  if (outcome === null) {
1995
2045
  persistAutoSearchSkip(db, sessionId, userMsgId);
2046
+ observation.finish("timeout");
1996
2047
  return { ok: false, kind: "timeout" };
1997
2048
  }
1998
- if (!outcome.ok)
2049
+ if (!outcome.ok) {
2050
+ observation.finish("error", outcome.kind);
1999
2051
  return {
2000
2052
  ok: false,
2001
2053
  kind: outcome.kind === "storage-busy" ? "storage-busy" : "cas-exhaustion"
2002
2054
  };
2055
+ }
2003
2056
  if (outcome.kind === "already-present" && outcome.decision.decision === "hint") {
2004
2057
  appendReminderToUserMessageById(messages, userMsgId, outcome.decision.text);
2005
2058
  }
2059
+ observation.finish(outcome.decision.decision === "hint" ? "attached" : reason === "below-threshold" ? "below-threshold" : reason === "error" ? "error" : "no-candidates", reason);
2006
2060
  return AUTO_SEARCH_OK;
2007
2061
  };
2008
2062
  const rawPartsText = collectUserPromptParts(userMsg);
2009
2063
  if (hasStackedAugmentation(rawPartsText)) {
2010
- sessionLog2(sessionId, "auto-search: skipping — user message already carries augmentation/hint");
2011
2064
  return writeNoHintAndReconcile("stacked");
2012
2065
  }
2013
2066
  const rawPrompt = extractUserPromptText(userMsg);
@@ -2023,6 +2076,7 @@ async function runAutoSearchHint(args) {
2023
2076
  const embeddingEnabled = embeddingSnapshot ? embeddingSnapshot.historyEnabled : options.embeddingEnabled;
2024
2077
  const gitCommitsEnabled = embeddingSnapshot?.gitCommitEnabled ?? options.gitCommitsEnabled ?? false;
2025
2078
  const searchOptions = {
2079
+ autoSearchDiagnostics: observation.diagnostics,
2026
2080
  limit: 10,
2027
2081
  maxMessageOrdinal: Math.max(0, getLastCompartmentEndMessage(db, sessionId)),
2028
2082
  excludeMessageId: userMsgId,
@@ -2049,11 +2103,10 @@ async function runAutoSearchHint(args) {
2049
2103
  if (lifecycleSignal.aborted)
2050
2104
  return AUTO_SEARCH_OK;
2051
2105
  if (error instanceof AutoSearchBusyError) {
2052
- sessionLog2(sessionId, "auto-search: an earlier search of this session is still running, skipping hint for this turn");
2106
+ observation.finish("timeout", "worker-busy");
2053
2107
  persistAutoSearchSkip(db, sessionId, userMsgId);
2054
2108
  return { ok: false, kind: "timeout" };
2055
2109
  }
2056
- log2(`[auto-search] unified search failed for session ${sessionId} (no-hint frozen for this turn): ${error instanceof Error ? error.message : String(error)}`);
2057
2110
  const outcome = await writeNoHintAndReconcile("error");
2058
2111
  return outcome.ok ? { ok: false, kind: "search-failure" } : outcome;
2059
2112
  }
@@ -2061,9 +2114,8 @@ async function runAutoSearchHint(args) {
2061
2114
  return AUTO_SEARCH_OK;
2062
2115
  try {
2063
2116
  if (results === null) {
2064
- sessionLog2(sessionId, `auto-search: timed out after ${AUTO_SEARCH_TIMEOUT_MS}ms, skipping hint for this turn`);
2117
+ observation.finish("timeout");
2065
2118
  persistAutoSearchSkip(db, sessionId, userMsgId);
2066
- sessionLog2(sessionId, "auto-search: skip frozen; retries for this turn are replay-only");
2067
2119
  return { ok: false, kind: "timeout" };
2068
2120
  }
2069
2121
  if (results.length === 0) {
@@ -2071,7 +2123,6 @@ async function runAutoSearchHint(args) {
2071
2123
  }
2072
2124
  results = selectAutoSearchResults(results, options.scoreThreshold);
2073
2125
  if (results.length === 0) {
2074
- sessionLog2(sessionId, `auto-search: no fragment meets relevance threshold ${options.scoreThreshold}`);
2075
2126
  return writeNoHintAndReconcile("below-threshold");
2076
2127
  }
2077
2128
  const hintText = buildAutoSearchHint(results, {
@@ -2091,18 +2142,19 @@ ${hintText}`;
2091
2142
  }, startedAt);
2092
2143
  if (outcome === null) {
2093
2144
  persistAutoSearchSkip(db, sessionId, userMsgId);
2145
+ observation.finish("timeout");
2094
2146
  return { ok: false, kind: "timeout" };
2095
2147
  }
2096
2148
  if (!outcome.ok) {
2149
+ observation.finish("error", outcome.kind);
2097
2150
  if (outcome.kind === "storage-busy")
2098
2151
  return { ok: false, kind: "storage-busy" };
2099
- sessionLog2(sessionId, `auto-search: CAS exhausted for ${userMsgId}; skipping wire append`);
2100
2152
  return { ok: false, kind: "cas-exhaustion" };
2101
2153
  }
2102
2154
  if (outcome.decision.decision === "hint") {
2103
2155
  appendReminderToUserMessageById(messages, userMsgId, outcome.decision.text);
2104
2156
  }
2105
- sessionLog2(sessionId, `auto-search: attached hint to ${userMsgId} (${results.length} fragments, top relevance ${(results[0].relevanceScore ?? results[0].score).toFixed(3)})`);
2157
+ observation.finish(outcome.decision.decision === "hint" ? "attached" : "no-candidates");
2106
2158
  return AUTO_SEARCH_OK;
2107
2159
  } finally {
2108
2160
  if (!lifecycleSignal.aborted && results !== null)
@@ -3473,6 +3525,50 @@ function renderConvertedToolSkeletons(targets, converted) {
3473
3525
  }
3474
3526
  return didMutate;
3475
3527
  }
3528
+ function prepareAgedToolSkeletonConversions(db, sessionId, targets, options = {}) {
3529
+ const candidates = [...targets.keys()].sort((a, b) => a - b);
3530
+ const readRows = (connection) => {
3531
+ const window = getNewestToolTagNumbers2(connection, sessionId, RECENT_TOOL_SKELETON_WINDOW);
3532
+ const recent = new Set(window);
3533
+ const statement = connection.prepare(`SELECT tag_number AS tagNumber, drop_mode AS dropMode, message_id AS callId
3534
+ FROM tags WHERE session_id = ? AND tag_number = ?
3535
+ AND type = 'tool' AND status = 'dropped'
3536
+ AND drop_mode IN ('truncated', 'skeleton_real', 'skeleton_stripped')`);
3537
+ const rows = candidates.filter((id) => !recent.has(id)).flatMap((id) => {
3538
+ const row = statement.get(sessionId, id);
3539
+ return row ? [row] : [];
3540
+ });
3541
+ return { window, rows };
3542
+ };
3543
+ const snapshot = readRows(db);
3544
+ options.prepareRemovals?.(snapshot.rows);
3545
+ const converted = new Map;
3546
+ const plannedRemovals = new Set;
3547
+ for (const row of snapshot.rows) {
3548
+ const target = targets.get(row.tagNumber);
3549
+ if (target?.thinkingDropProtected || target?.thinkingRewriteProtected || target?.identityRepairProtected)
3550
+ continue;
3551
+ if (target?.canDrop?.() !== true || target.prepareDrop?.() === false)
3552
+ continue;
3553
+ if (target.requiresToolArcSkeleton) {
3554
+ const owners = target.mutationParts ? target.mutationParts.map(({ message }) => message).filter((message) => message.info.role === "assistant") : target.message ? [target.message] : [];
3555
+ if (owners.length === 0 || owners.some((message) => !options.thinkingStrippedIds?.has(message.info.id ?? "")))
3556
+ continue;
3557
+ }
3558
+ if (target.cannotRemove?.() === true || target.wouldStrandConversationEnd?.(plannedRemovals) === true)
3559
+ continue;
3560
+ converted.set(row.tagNumber, "full");
3561
+ target.notePlannedRemoval?.(plannedRemovals);
3562
+ }
3563
+ return {
3564
+ converted,
3565
+ isCurrent: (connection) => JSON.stringify(readRows(connection)) === JSON.stringify(snapshot),
3566
+ persist: (connection) => {
3567
+ for (const tagNumber of converted.keys())
3568
+ updateTagDropMode2(connection, sessionId, tagNumber, "full");
3569
+ }
3570
+ };
3571
+ }
3476
3572
  var PENDING_OPERATION_CHUNK_SIZE = 64;
3477
3573
  function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set, onTagReduced, onBatchComplete, onEligibilitySnapshot) {
3478
3574
  let didMutateMessage = false;
@@ -6771,6 +6867,20 @@ async function runPostTransformPhase2(args) {
6771
6867
  }
6772
6868
  }
6773
6869
  }
6870
+ if (!args.fullFeatureMode && canEditWholePrefix && !compactionOff) {
6871
+ const thinkingStrippedIds = new Set([...bindingThinking, ...removedReasoningIds]);
6872
+ for (const id of getMergedReasoningStrippedIds(args.db, args.sessionId)) {
6873
+ if (id.startsWith(THINKING_BINDING_RECOVERY_FROZEN_PREFIX))
6874
+ thinkingStrippedIds.add(id.slice(THINKING_BINDING_RECOVERY_FROZEN_PREFIX.length));
6875
+ }
6876
+ const conversions = prepareAgedToolSkeletonConversions(args.db, args.sessionId, newTargets, { thinkingStrippedIds });
6877
+ args.db.transaction(() => {
6878
+ if (!conversions.isCurrent(args.db))
6879
+ throw new Error("Subagent skeleton candidates changed before commit");
6880
+ conversions.persist(args.db);
6881
+ }).immediate();
6882
+ convertedToolSkeletonsDidMutate = renderConvertedToolSkeletons(newTargets, conversions.converted) || convertedToolSkeletonsDidMutate;
6883
+ }
6774
6884
  const tBatchFinalize = performance.now();
6775
6885
  args.batch?.finalize();
6776
6886
  if (toolReclaimApplicationOpportunity) {
@@ -7181,6 +7291,18 @@ async function runPostTransformPhase2(args) {
7181
7291
  }
7182
7292
  autoSearchHintAppendedThisPass = autoSearchCompletedThisPass && countAutoSearchHints(args.db, args.sessionId) !== autoSearchHintsBefore;
7183
7293
  logTransformTiming(args.sessionId, "pp.autoSearchHint", tAutoSearch);
7294
+ } else if (args.fullFeatureMode && args.autoSearch && !args.autoSearch.enabled && args.projectPath) {
7295
+ await runAutoSearchHint({
7296
+ sessionId: args.sessionId,
7297
+ db: args.db,
7298
+ messages: args.messages,
7299
+ options: {
7300
+ enabled: false,
7301
+ scoreThreshold: args.autoSearch.scoreThreshold,
7302
+ minPromptChars: args.autoSearch.minPromptChars,
7303
+ projectPath: args.projectPath
7304
+ }
7305
+ });
7184
7306
  }
7185
7307
  if (args.fullFeatureMode && canEditWholePrefix) {
7186
7308
  const visibleIds = new Set;