@unbrained/pm-cli 2026.7.1 → 2026.7.2

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 (563) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cli/commander-usage.d.ts +2 -0
  3. package/dist/cli/commander-usage.js +58 -47
  4. package/dist/cli/commander-usage.js.map +1 -1
  5. package/dist/cli/commands/aggregate.js +102 -79
  6. package/dist/cli/commands/aggregate.js.map +1 -1
  7. package/dist/cli/commands/calendar.js +278 -243
  8. package/dist/cli/commands/calendar.js.map +1 -1
  9. package/dist/cli/commands/close-many.js +89 -68
  10. package/dist/cli/commands/close-many.js.map +1 -1
  11. package/dist/cli/commands/close.js +157 -129
  12. package/dist/cli/commands/close.js.map +1 -1
  13. package/dist/cli/commands/comments-audit.js +50 -42
  14. package/dist/cli/commands/comments-audit.js.map +1 -1
  15. package/dist/cli/commands/config.d.ts +2 -0
  16. package/dist/cli/commands/config.js +443 -879
  17. package/dist/cli/commands/config.js.map +1 -1
  18. package/dist/cli/commands/context.js +365 -287
  19. package/dist/cli/commands/context.js.map +1 -1
  20. package/dist/cli/commands/contracts.js +352 -238
  21. package/dist/cli/commands/contracts.js.map +1 -1
  22. package/dist/cli/commands/dedupe-audit.js +46 -39
  23. package/dist/cli/commands/dedupe-audit.js.map +1 -1
  24. package/dist/cli/commands/dedupe-merge.js +88 -69
  25. package/dist/cli/commands/dedupe-merge.js.map +1 -1
  26. package/dist/cli/commands/get.js +114 -81
  27. package/dist/cli/commands/get.js.map +1 -1
  28. package/dist/cli/commands/health.d.ts +17 -0
  29. package/dist/cli/commands/health.js +446 -307
  30. package/dist/cli/commands/health.js.map +1 -1
  31. package/dist/cli/commands/history-compact.js +209 -140
  32. package/dist/cli/commands/history-compact.js.map +1 -1
  33. package/dist/cli/commands/history-redact.js +162 -119
  34. package/dist/cli/commands/history-redact.js.map +1 -1
  35. package/dist/cli/commands/history-repair.js +120 -85
  36. package/dist/cli/commands/history-repair.js.map +1 -1
  37. package/dist/cli/commands/init.d.ts +8 -2
  38. package/dist/cli/commands/init.js +263 -162
  39. package/dist/cli/commands/init.js.map +1 -1
  40. package/dist/cli/commands/list.js +152 -102
  41. package/dist/cli/commands/list.js.map +1 -1
  42. package/dist/cli/commands/next.js +49 -32
  43. package/dist/cli/commands/next.js.map +1 -1
  44. package/dist/cli/commands/plan.js +373 -298
  45. package/dist/cli/commands/plan.js.map +1 -1
  46. package/dist/cli/commands/recurrence-parsers.js +43 -25
  47. package/dist/cli/commands/recurrence-parsers.js.map +1 -1
  48. package/dist/cli/commands/reindex.d.ts +21 -5
  49. package/dist/cli/commands/reindex.js +345 -205
  50. package/dist/cli/commands/reindex.js.map +1 -1
  51. package/dist/cli/commands/restore.d.ts +8 -7
  52. package/dist/cli/commands/restore.js +105 -69
  53. package/dist/cli/commands/restore.js.map +1 -1
  54. package/dist/cli/commands/schema.js +33 -30
  55. package/dist/cli/commands/schema.js.map +1 -1
  56. package/dist/cli/commands/search.d.ts +10 -2
  57. package/dist/cli/commands/search.js +503 -470
  58. package/dist/cli/commands/search.js.map +1 -1
  59. package/dist/cli/commands/telemetry.js +98 -87
  60. package/dist/cli/commands/telemetry.js.map +1 -1
  61. package/dist/cli/commands/test-all.js +237 -168
  62. package/dist/cli/commands/test-all.js.map +1 -1
  63. package/dist/cli/commands/test.d.ts +6 -5
  64. package/dist/cli/commands/test.js +424 -344
  65. package/dist/cli/commands/test.js.map +1 -1
  66. package/dist/cli/commands/update-many.js +57 -42
  67. package/dist/cli/commands/update-many.js.map +1 -1
  68. package/dist/cli/commands/update.d.ts +1 -1
  69. package/dist/cli/commands/update.js +738 -671
  70. package/dist/cli/commands/update.js.map +1 -1
  71. package/dist/cli/commands/validate.d.ts +18 -1
  72. package/dist/cli/commands/validate.js +466 -343
  73. package/dist/cli/commands/validate.js.map +1 -1
  74. package/dist/cli/error-guidance.js +399 -357
  75. package/dist/cli/error-guidance.js.map +1 -1
  76. package/dist/cli/main.d.ts +47 -0
  77. package/dist/cli/main.js +428 -341
  78. package/dist/cli/main.js.map +1 -1
  79. package/dist/cli/migration-gates.js +22 -45
  80. package/dist/cli/migration-gates.js.map +1 -1
  81. package/dist/cli/register-list-query.js +94 -105
  82. package/dist/cli/register-list-query.js.map +1 -1
  83. package/dist/cli/register-mutation.js +400 -416
  84. package/dist/cli/register-mutation.js.map +1 -1
  85. package/dist/cli/register-operations.js +86 -66
  86. package/dist/cli/register-operations.js.map +1 -1
  87. package/dist/cli/register-setup.js +120 -101
  88. package/dist/cli/register-setup.js.map +1 -1
  89. package/dist/cli-bundle/chunks/{activity-DBLQVIP6.js → activity-CUC4JY3U.js} +9 -9
  90. package/dist/cli-bundle/chunks/activity-WEIEMM73.js +16 -0
  91. package/dist/cli-bundle/chunks/{aggregate-JTEF4BP7.js → aggregate-DKUTRY6R.js} +108 -84
  92. package/dist/cli-bundle/chunks/aggregate-DKUTRY6R.js.map +1 -0
  93. package/dist/cli-bundle/chunks/{aggregate-SDF7DUOD.js → aggregate-SW5PNGCS.js} +107 -83
  94. package/dist/cli-bundle/chunks/{aggregate-SDF7DUOD.js.map → aggregate-SW5PNGCS.js.map} +2 -2
  95. package/dist/cli-bundle/chunks/{append-QCFJSDFL.js → append-H32VOR2Y.js} +6 -6
  96. package/dist/cli-bundle/chunks/{append-LOVPGVPT.js → append-UBM632FK.js} +6 -6
  97. package/dist/cli-bundle/chunks/{chunk-RLDHZHQS.js → chunk-2227673O.js} +158 -114
  98. package/dist/cli-bundle/chunks/chunk-2227673O.js.map +1 -0
  99. package/dist/cli-bundle/chunks/{chunk-SLMUGTK3.js → chunk-2ASNV4DH.js} +4 -4
  100. package/dist/cli-bundle/chunks/{chunk-UZIWVBE6.js → chunk-2CHRYUXL.js} +2 -2
  101. package/dist/cli-bundle/chunks/{chunk-NWMZWYYB.js → chunk-2KWL5NPW.js} +42 -27
  102. package/dist/cli-bundle/chunks/chunk-2KWL5NPW.js.map +1 -0
  103. package/dist/cli-bundle/chunks/{chunk-NFDPYAIP.js → chunk-36UGKF4O.js} +21 -29
  104. package/dist/cli-bundle/chunks/chunk-36UGKF4O.js.map +7 -0
  105. package/dist/cli-bundle/chunks/{chunk-NU2UEROZ.js → chunk-3AZUFQK6.js} +6 -6
  106. package/dist/cli-bundle/chunks/{chunk-LB6TP6MC.js → chunk-3LCUASYG.js} +2 -2
  107. package/dist/cli-bundle/chunks/{chunk-HPPFYYOV.js → chunk-3Q2HBMTI.js} +2 -2
  108. package/dist/cli-bundle/chunks/{chunk-IPYBJWTE.js → chunk-4NUOWFBT.js} +109 -72
  109. package/dist/cli-bundle/chunks/chunk-4NUOWFBT.js.map +7 -0
  110. package/dist/cli-bundle/chunks/{chunk-W4ULYO7Z.js → chunk-55XRYWEG.js} +6 -6
  111. package/dist/cli-bundle/chunks/{chunk-HXTQJXWT.js → chunk-5GVTFFTC.js} +2 -2
  112. package/dist/cli-bundle/chunks/{chunk-BDTISOSD.js → chunk-5PGBHRY3.js} +41 -26
  113. package/dist/cli-bundle/chunks/chunk-5PGBHRY3.js.map +7 -0
  114. package/dist/cli-bundle/chunks/{chunk-YITK2PJ6.js → chunk-66Z3X7ZG.js} +261 -161
  115. package/dist/cli-bundle/chunks/chunk-66Z3X7ZG.js.map +7 -0
  116. package/dist/cli-bundle/chunks/{chunk-NUHHPVVS.js → chunk-6ITZLD4T.js} +712 -612
  117. package/dist/cli-bundle/chunks/chunk-6ITZLD4T.js.map +7 -0
  118. package/dist/cli-bundle/chunks/{chunk-V3NOKJF2.js → chunk-6YCYF2AI.js} +262 -162
  119. package/dist/cli-bundle/chunks/chunk-6YCYF2AI.js.map +1 -0
  120. package/dist/cli-bundle/chunks/{chunk-BZCEN4JA.js → chunk-6ZMBJRDJ.js} +492 -403
  121. package/dist/cli-bundle/chunks/chunk-6ZMBJRDJ.js.map +7 -0
  122. package/dist/cli-bundle/chunks/{chunk-CF7RL6FR.js → chunk-7MYWF4ZX.js} +110 -73
  123. package/dist/cli-bundle/chunks/chunk-7MYWF4ZX.js.map +1 -0
  124. package/dist/cli-bundle/chunks/{chunk-RVUALSJF.js → chunk-7NSPKJUS.js} +356 -285
  125. package/dist/cli-bundle/chunks/chunk-7NSPKJUS.js.map +7 -0
  126. package/dist/cli-bundle/chunks/{chunk-4DSGXSBL.js → chunk-7TH5NMVB.js} +95 -53
  127. package/dist/cli-bundle/chunks/chunk-7TH5NMVB.js.map +7 -0
  128. package/dist/cli-bundle/chunks/{chunk-ZETXE4SE.js → chunk-7W4H4K26.js} +713 -613
  129. package/dist/cli-bundle/chunks/chunk-7W4H4K26.js.map +1 -0
  130. package/dist/cli-bundle/chunks/{chunk-64HNBBFQ.js → chunk-A6VOGKBA.js} +6 -6
  131. package/dist/cli-bundle/chunks/{chunk-WYDHYJPO.js → chunk-AIAIXG7I.js} +2 -2
  132. package/dist/cli-bundle/chunks/{chunk-CWFNTKQJ.js → chunk-AJEBCRIY.js} +5 -5
  133. package/dist/cli-bundle/chunks/{chunk-VZDBVEZR.js → chunk-B4O5S7I3.js} +79 -57
  134. package/dist/cli-bundle/chunks/{chunk-VZDBVEZR.js.map → chunk-B4O5S7I3.js.map} +2 -2
  135. package/dist/cli-bundle/chunks/{chunk-NOLPZMSV.js → chunk-BTX5MIQF.js} +2 -2
  136. package/dist/cli-bundle/chunks/{chunk-RH5ZBYFD.js → chunk-BVZZN2LH.js} +3 -3
  137. package/dist/cli-bundle/chunks/{chunk-27BXPBAY.js → chunk-CYBDUHNO.js} +3 -3
  138. package/dist/cli-bundle/chunks/{chunk-A7FPBAQS.js → chunk-CZPVDLD2.js} +4 -4
  139. package/dist/cli-bundle/chunks/{chunk-3VGN2UWE.js → chunk-EMPGXBUF.js} +22 -30
  140. package/dist/cli-bundle/chunks/chunk-EMPGXBUF.js.map +1 -0
  141. package/dist/cli-bundle/chunks/{chunk-JPECA746.js → chunk-EUKTMRN3.js} +2 -2
  142. package/dist/cli-bundle/chunks/{chunk-2466X6E4.js → chunk-FFOQHGNH.js} +6 -6
  143. package/dist/cli-bundle/chunks/{chunk-JLM7BHI7.js → chunk-GFMSLORL.js} +6 -6
  144. package/dist/cli-bundle/chunks/{chunk-SDR5J34Q.js → chunk-GRRG3MCT.js} +4 -4
  145. package/dist/cli-bundle/chunks/{chunk-GJ326ZKX.js → chunk-H4GRLYJS.js} +3 -3
  146. package/dist/cli-bundle/chunks/{chunk-OGXLACHC.js → chunk-HQTPRV4D.js} +6 -6
  147. package/dist/cli-bundle/chunks/{chunk-7R4QEMZZ.js → chunk-I66WE2HE.js} +354 -283
  148. package/dist/cli-bundle/chunks/chunk-I66WE2HE.js.map +1 -0
  149. package/dist/cli-bundle/chunks/{chunk-BHO33VBQ.js → chunk-IEEJQCZ4.js} +3 -3
  150. package/dist/cli-bundle/chunks/{chunk-JMP4E6D7.js → chunk-IG5JYZGU.js} +390 -312
  151. package/dist/cli-bundle/chunks/{chunk-JMP4E6D7.js.map → chunk-IG5JYZGU.js.map} +2 -2
  152. package/dist/cli-bundle/chunks/{chunk-4DUVCVLZ.js → chunk-JMK5GCK2.js} +2 -2
  153. package/dist/cli-bundle/chunks/{chunk-3K2M5OYU.js → chunk-JXAUVO6X.js} +258 -169
  154. package/dist/cli-bundle/chunks/{chunk-3K2M5OYU.js.map → chunk-JXAUVO6X.js.map} +2 -2
  155. package/dist/cli-bundle/chunks/{chunk-AXIDKKAT.js → chunk-K2VYLVX4.js} +2 -2
  156. package/dist/cli-bundle/chunks/{chunk-EJUDVUYZ.js → chunk-KCO2EAN5.js} +3 -3
  157. package/dist/cli-bundle/chunks/{chunk-6AQZPVHQ.js → chunk-KIYCOJ63.js} +4 -4
  158. package/dist/cli-bundle/chunks/{chunk-ZRP4VG5U.js → chunk-KLXF7NCC.js} +2 -2
  159. package/dist/cli-bundle/chunks/{chunk-QCWF6IYD.js → chunk-KN3URLKS.js} +3 -3
  160. package/dist/cli-bundle/chunks/{chunk-N74UMG5H.js → chunk-LRKMWUUV.js} +2 -2
  161. package/dist/cli-bundle/chunks/{chunk-AVEE5EHK.js → chunk-LTRAF2D7.js} +3 -3
  162. package/dist/cli-bundle/chunks/{chunk-VARHOHYV.js → chunk-MNBPX5JS.js} +55 -36
  163. package/dist/cli-bundle/chunks/chunk-MNBPX5JS.js.map +7 -0
  164. package/dist/cli-bundle/chunks/{chunk-IJYK2T43.js → chunk-MRD4T5LF.js} +2 -2
  165. package/dist/cli-bundle/chunks/{chunk-G7I7DEZA.js → chunk-N2JSWVWG.js} +4 -4
  166. package/dist/cli-bundle/chunks/{chunk-5QFDBI4F.js → chunk-N3QCJS4M.js} +6 -6
  167. package/dist/cli-bundle/chunks/{chunk-JSU5P7VS.js → chunk-NRZS637N.js} +258 -169
  168. package/dist/cli-bundle/chunks/chunk-NRZS637N.js.map +1 -0
  169. package/dist/cli-bundle/chunks/{chunk-4A3BJ675.js → chunk-OTUJZKGI.js} +3 -3
  170. package/dist/cli-bundle/chunks/{chunk-5CGRF3L5.js → chunk-Q6K2OACU.js} +153 -90
  171. package/dist/cli-bundle/chunks/chunk-Q6K2OACU.js.map +1 -0
  172. package/dist/cli-bundle/chunks/{chunk-3XZCOZ5J.js → chunk-Q6NXOHS6.js} +391 -313
  173. package/dist/cli-bundle/chunks/chunk-Q6NXOHS6.js.map +1 -0
  174. package/dist/cli-bundle/chunks/{chunk-HZZEHPRG.js → chunk-QH3FSKRJ.js} +2 -2
  175. package/dist/cli-bundle/chunks/{chunk-4XOIEKSD.js → chunk-RM37OPYK.js} +56 -37
  176. package/dist/cli-bundle/chunks/chunk-RM37OPYK.js.map +1 -0
  177. package/dist/cli-bundle/chunks/{chunk-NKZAN7BD.js → chunk-S62UANU7.js} +3 -3
  178. package/dist/cli-bundle/chunks/{chunk-RMMQ74TG.js → chunk-SPM2XLWI.js} +37 -28
  179. package/dist/cli-bundle/chunks/chunk-SPM2XLWI.js.map +7 -0
  180. package/dist/cli-bundle/chunks/{chunk-3J6JRJ3I.js → chunk-SYNKD3ZG.js} +5 -5
  181. package/dist/cli-bundle/chunks/{chunk-FFMQB7WR.js → chunk-SYVUU7EK.js} +493 -404
  182. package/dist/cli-bundle/chunks/chunk-SYVUU7EK.js.map +1 -0
  183. package/dist/cli-bundle/chunks/{chunk-UYUYDGIB.js → chunk-TPOFWBMY.js} +95 -53
  184. package/dist/cli-bundle/chunks/chunk-TPOFWBMY.js.map +1 -0
  185. package/dist/cli-bundle/chunks/{chunk-OTUHB4HS.js → chunk-TTHCEV5Q.js} +92 -77
  186. package/dist/cli-bundle/chunks/chunk-TTHCEV5Q.js.map +1 -0
  187. package/dist/cli-bundle/chunks/{chunk-L5OEFZQG.js → chunk-U2BEEM2X.js} +3 -3
  188. package/dist/cli-bundle/chunks/{chunk-KNPEF7QG.js → chunk-UGLU6Q2I.js} +91 -76
  189. package/dist/cli-bundle/chunks/chunk-UGLU6Q2I.js.map +7 -0
  190. package/dist/cli-bundle/chunks/{chunk-EVMTBV6V.js → chunk-UT73HUPC.js} +3 -3
  191. package/dist/cli-bundle/chunks/{chunk-VICZWYGZ.js → chunk-UTSH5GWX.js} +4 -4
  192. package/dist/cli-bundle/chunks/{chunk-IZBR4NRW.js → chunk-UWKEJMZU.js} +157 -113
  193. package/dist/cli-bundle/chunks/chunk-UWKEJMZU.js.map +7 -0
  194. package/dist/cli-bundle/chunks/{chunk-3S2KT7NG.js → chunk-W47SML5B.js} +152 -89
  195. package/dist/cli-bundle/chunks/chunk-W47SML5B.js.map +7 -0
  196. package/dist/cli-bundle/chunks/{chunk-RGEMWD6Q.js → chunk-WJAMWAHZ.js} +157 -118
  197. package/dist/cli-bundle/chunks/chunk-WJAMWAHZ.js.map +7 -0
  198. package/dist/cli-bundle/chunks/{chunk-JWXRETDF.js → chunk-XCHUVHKU.js} +626 -484
  199. package/dist/cli-bundle/chunks/chunk-XCHUVHKU.js.map +1 -0
  200. package/dist/cli-bundle/chunks/{chunk-55SNVXRQ.js → chunk-XEWQKDYZ.js} +626 -484
  201. package/dist/cli-bundle/chunks/chunk-XEWQKDYZ.js.map +7 -0
  202. package/dist/cli-bundle/chunks/{chunk-TP5Q5ZD3.js → chunk-XTHQWXVC.js} +158 -119
  203. package/dist/cli-bundle/chunks/chunk-XTHQWXVC.js.map +1 -0
  204. package/dist/cli-bundle/chunks/{chunk-MDPEOIGN.js → chunk-XWGEMNBR.js} +2 -2
  205. package/dist/cli-bundle/chunks/{chunk-HYTGA6GI.js → chunk-Y4NRKBFW.js} +3 -3
  206. package/dist/cli-bundle/chunks/{chunk-2D4HATP2.js → chunk-YLZZ6T54.js} +38 -29
  207. package/dist/cli-bundle/chunks/chunk-YLZZ6T54.js.map +1 -0
  208. package/dist/cli-bundle/chunks/{chunk-22WKIL3H.js → chunk-YPKFV2JR.js} +6 -6
  209. package/dist/cli-bundle/chunks/{chunk-OKQ22KTH.js → chunk-Z4DGFQDH.js} +80 -58
  210. package/dist/cli-bundle/chunks/{chunk-OKQ22KTH.js.map → chunk-Z4DGFQDH.js.map} +1 -1
  211. package/dist/cli-bundle/chunks/{chunk-DDPTYJIM.js → chunk-ZNHEYCDD.js} +2 -2
  212. package/dist/cli-bundle/chunks/{chunk-MAUKX7JC.js → chunk-ZNT7KEWE.js} +2 -2
  213. package/dist/cli-bundle/chunks/{claim-T3GCKV7C.js → claim-SENTPZBN.js} +8 -8
  214. package/dist/cli-bundle/chunks/{claim-EMQLYPRW.js → claim-Z7MEQCBT.js} +8 -8
  215. package/dist/cli-bundle/chunks/{close-TQYAAFJP.js → close-424MX4CU.js} +7 -7
  216. package/dist/cli-bundle/chunks/close-YCWQQPDS.js +14 -0
  217. package/dist/cli-bundle/chunks/{close-many-LDRVEQY2.js → close-many-2IV4J2TR.js} +102 -81
  218. package/dist/cli-bundle/chunks/close-many-2IV4J2TR.js.map +1 -0
  219. package/dist/cli-bundle/chunks/{close-many-BG5QQIDQ.js → close-many-SWY34BII.js} +101 -80
  220. package/dist/cli-bundle/chunks/close-many-SWY34BII.js.map +7 -0
  221. package/dist/cli-bundle/chunks/{comments-YUXJRZPQ.js → comments-4FGNTSNV.js} +8 -8
  222. package/dist/cli-bundle/chunks/{comments-QCKR2YY2.js → comments-7YS5MY5X.js} +8 -8
  223. package/dist/cli-bundle/chunks/config-BZJKK7FZ.js +1062 -0
  224. package/dist/cli-bundle/chunks/config-BZJKK7FZ.js.map +1 -0
  225. package/dist/cli-bundle/chunks/config-G74GISC4.js +1072 -0
  226. package/dist/cli-bundle/chunks/config-G74GISC4.js.map +7 -0
  227. package/dist/cli-bundle/chunks/{context-OCZ3FJ4Z.js → context-LHVKJSPJ.js} +12 -12
  228. package/dist/cli-bundle/chunks/{context-B6275WPX.js → context-ZQY54JNS.js} +12 -12
  229. package/dist/cli-bundle/chunks/{contracts-HN7ABKLP.js → contracts-CP2EZJC7.js} +320 -199
  230. package/dist/cli-bundle/chunks/contracts-CP2EZJC7.js.map +7 -0
  231. package/dist/cli-bundle/chunks/{contracts-W4FZVVD6.js → contracts-FIZLMP7O.js} +321 -200
  232. package/dist/cli-bundle/chunks/contracts-FIZLMP7O.js.map +1 -0
  233. package/dist/cli-bundle/chunks/{copy-DEM4DATS.js → copy-GYNQQPW2.js} +5 -5
  234. package/dist/cli-bundle/chunks/{copy-BTJOSKKT.js → copy-TLW7JTQT.js} +5 -5
  235. package/dist/cli-bundle/chunks/{create-RLRJMRTM.js → create-VSKYSOCD.js} +12 -12
  236. package/dist/cli-bundle/chunks/create-XTMAPS7I.js +28 -0
  237. package/dist/cli-bundle/chunks/{delete-LSVHAB4Y.js → delete-4W5JYCEG.js} +5 -5
  238. package/dist/cli-bundle/chunks/{delete-BHK7VB2Z.js → delete-ANTOTI2I.js} +5 -5
  239. package/dist/cli-bundle/chunks/{deps-XHYXWEPT.js → deps-HPPE6MJN.js} +5 -5
  240. package/dist/cli-bundle/chunks/{deps-4UDFJRUA.js → deps-ZQZN54EZ.js} +5 -5
  241. package/dist/cli-bundle/chunks/{docs-GYZNVS26.js → docs-RPOVFMP3.js} +7 -7
  242. package/dist/cli-bundle/chunks/{docs-26S44RXU.js → docs-XJNYBJGE.js} +7 -7
  243. package/dist/cli-bundle/chunks/{eval-PGRVIJQU.js → eval-DM6JBZTS.js} +10 -10
  244. package/dist/cli-bundle/chunks/{eval-UYF3ZPVO.js → eval-RFBI5FGS.js} +10 -10
  245. package/dist/cli-bundle/chunks/{extension-CPSLJQVE.js → extension-B3YY4WY5.js} +11 -11
  246. package/dist/cli-bundle/chunks/{extension-CXJ6RELI.js → extension-TTSEFQTS.js} +11 -11
  247. package/dist/cli-bundle/chunks/{files-NQHEXUZD.js → files-5D65CHGE.js} +7 -7
  248. package/dist/cli-bundle/chunks/{files-MBNICQFM.js → files-GPIG77EN.js} +7 -7
  249. package/dist/cli-bundle/chunks/{focus-XZW5423D.js → focus-C3PEJV2C.js} +6 -6
  250. package/dist/cli-bundle/chunks/{focus-DWYIG7GU.js → focus-ZHN7WIGX.js} +6 -6
  251. package/dist/cli-bundle/chunks/{gc-LPVMKJQJ.js → gc-D4JQ6OWN.js} +3 -3
  252. package/dist/cli-bundle/chunks/{gc-7GQYOS2G.js → gc-VZIXDL32.js} +3 -3
  253. package/dist/cli-bundle/chunks/{get-DSDEKJ3L.js → get-GIBRUUOP.js} +121 -81
  254. package/dist/cli-bundle/chunks/get-GIBRUUOP.js.map +1 -0
  255. package/dist/cli-bundle/chunks/{get-A7MAOHCU.js → get-IOVAN6RU.js} +120 -80
  256. package/dist/cli-bundle/chunks/get-IOVAN6RU.js.map +7 -0
  257. package/dist/cli-bundle/chunks/{health-3IPFLKXB.js → health-L2U3AFKV.js} +437 -265
  258. package/dist/cli-bundle/chunks/health-L2U3AFKV.js.map +1 -0
  259. package/dist/cli-bundle/chunks/{health-GZXGBZ36.js → health-MM7AWXYF.js} +436 -264
  260. package/dist/cli-bundle/chunks/health-MM7AWXYF.js.map +7 -0
  261. package/dist/cli-bundle/chunks/history-DD7L7BNL.js +18 -0
  262. package/dist/cli-bundle/chunks/{history-NERDJNUB.js → history-IL7XCEX2.js} +8 -8
  263. package/dist/cli-bundle/chunks/{history-compact-HR7BB4LR.js → history-compact-HALOTOU7.js} +214 -135
  264. package/dist/cli-bundle/chunks/history-compact-HALOTOU7.js.map +1 -0
  265. package/dist/cli-bundle/chunks/{history-compact-2WRZ2WK4.js → history-compact-MV25P7DM.js} +213 -134
  266. package/dist/cli-bundle/chunks/history-compact-MV25P7DM.js.map +7 -0
  267. package/dist/cli-bundle/chunks/history-redact-IX4YEWMY.js +19 -0
  268. package/dist/cli-bundle/chunks/{history-redact-O3NBCNWC.js → history-redact-VYCWQFK7.js} +9 -9
  269. package/dist/cli-bundle/chunks/{history-repair-XA3LC4GA.js → history-repair-44MODPQF.js} +124 -84
  270. package/dist/cli-bundle/chunks/history-repair-44MODPQF.js.map +1 -0
  271. package/dist/cli-bundle/chunks/{history-repair-LCMOS45X.js → history-repair-CPNAOCNF.js} +123 -83
  272. package/dist/cli-bundle/chunks/history-repair-CPNAOCNF.js.map +7 -0
  273. package/dist/cli-bundle/chunks/{init-64XDLQJB.js → init-F27NHENZ.js} +12 -12
  274. package/dist/cli-bundle/chunks/init-HHVQQP6C.js +22 -0
  275. package/dist/cli-bundle/chunks/{learnings-LPKCSJX7.js → learnings-HJVDQIGY.js} +8 -8
  276. package/dist/cli-bundle/chunks/{learnings-JR6MA5TI.js → learnings-XSFSUUWK.js} +8 -8
  277. package/dist/cli-bundle/chunks/{list-G5Y65VF6.js → list-HPMEKCAA.js} +8 -8
  278. package/dist/cli-bundle/chunks/{list-DNBJVO3E.js → list-VMPWTURB.js} +8 -8
  279. package/dist/cli-bundle/chunks/{next-BCERKDUR.js → next-ETXF2ZCN.js} +59 -37
  280. package/dist/cli-bundle/chunks/next-ETXF2ZCN.js.map +7 -0
  281. package/dist/cli-bundle/chunks/{next-FYTQF6HG.js → next-QM6YJIIS.js} +60 -38
  282. package/dist/cli-bundle/chunks/next-QM6YJIIS.js.map +1 -0
  283. package/dist/cli-bundle/chunks/{notes-2BMU3VVQ.js → notes-GDZIKGR6.js} +8 -8
  284. package/dist/cli-bundle/chunks/{notes-6KTGO2OJ.js → notes-WDDBPC4D.js} +8 -8
  285. package/dist/cli-bundle/chunks/{plan-RKZHQVXR.js → plan-BGDR73Z6.js} +373 -279
  286. package/dist/cli-bundle/chunks/plan-BGDR73Z6.js.map +1 -0
  287. package/dist/cli-bundle/chunks/{plan-4WXEQCTN.js → plan-C5IMM335.js} +372 -278
  288. package/dist/cli-bundle/chunks/plan-C5IMM335.js.map +7 -0
  289. package/dist/cli-bundle/chunks/{profile-QLER5ENE.js → profile-CCOKZ2IQ.js} +9 -9
  290. package/dist/cli-bundle/chunks/{profile-4OMM32CD.js → profile-HUCENIEQ.js} +9 -9
  291. package/dist/cli-bundle/chunks/{register-list-query-7LV46VAU.js → register-list-query-ROSNIL52.js} +80 -83
  292. package/dist/cli-bundle/chunks/register-list-query-ROSNIL52.js.map +1 -0
  293. package/dist/cli-bundle/chunks/{register-list-query-SNG5PGA4.js → register-list-query-XN4ZRHSV.js} +79 -82
  294. package/dist/cli-bundle/chunks/register-list-query-XN4ZRHSV.js.map +7 -0
  295. package/dist/cli-bundle/chunks/{register-mutation-ENNDUAZG.js → register-mutation-CFSB2MS3.js} +403 -382
  296. package/dist/cli-bundle/chunks/register-mutation-CFSB2MS3.js.map +1 -0
  297. package/dist/cli-bundle/chunks/{register-mutation-KK7PHYYU.js → register-mutation-KRLAHEL2.js} +402 -381
  298. package/dist/cli-bundle/chunks/register-mutation-KRLAHEL2.js.map +7 -0
  299. package/dist/cli-bundle/chunks/{register-operations-HZ6XERQG.js → register-operations-4PASGJDB.js} +112 -93
  300. package/dist/cli-bundle/chunks/register-operations-4PASGJDB.js.map +7 -0
  301. package/dist/cli-bundle/chunks/{register-operations-C6OWLDSH.js → register-operations-MBN4KGUM.js} +113 -94
  302. package/dist/cli-bundle/chunks/register-operations-MBN4KGUM.js.map +1 -0
  303. package/dist/cli-bundle/chunks/{register-setup-P67EMBDJ.js → register-setup-VIAWYFP5.js} +129 -104
  304. package/dist/cli-bundle/chunks/register-setup-VIAWYFP5.js.map +1 -0
  305. package/dist/cli-bundle/chunks/{register-setup-ZKJ53RS7.js → register-setup-ZCGKHDKL.js} +128 -103
  306. package/dist/cli-bundle/chunks/register-setup-ZCGKHDKL.js.map +7 -0
  307. package/dist/cli-bundle/chunks/{restore-4MHZFJ2E.js → restore-4CBWUMCX.js} +9 -9
  308. package/dist/cli-bundle/chunks/restore-5UEAGG3W.js +17 -0
  309. package/dist/cli-bundle/chunks/{scheduling-shortcuts-LB6DOLRL.js → scheduling-shortcuts-6VFKNKCM.js} +12 -12
  310. package/dist/cli-bundle/chunks/{scheduling-shortcuts-UTOYKLXQ.js → scheduling-shortcuts-ERHCVTEM.js} +12 -12
  311. package/dist/cli-bundle/chunks/{schema-73HR2OJW.js → schema-TDGK6N3I.js} +7 -7
  312. package/dist/cli-bundle/chunks/{schema-U6LJKSIR.js → schema-UE5KKAUX.js} +7 -7
  313. package/dist/cli-bundle/chunks/{search-KILGT37L.js → search-FP7MEU4S.js} +10 -10
  314. package/dist/cli-bundle/chunks/{search-AXPXKZER.js → search-K4CFLQ5S.js} +10 -10
  315. package/dist/cli-bundle/chunks/{stats-PSYVVTNZ.js → stats-NJJCALEZ.js} +6 -6
  316. package/dist/cli-bundle/chunks/{stats-W5KNVJWQ.js → stats-XT6QRKQY.js} +6 -6
  317. package/dist/cli-bundle/chunks/{telemetry-GAHHQTOS.js → telemetry-5SQ5UDXC.js} +84 -70
  318. package/dist/cli-bundle/chunks/telemetry-5SQ5UDXC.js.map +7 -0
  319. package/dist/cli-bundle/chunks/{telemetry-BZUF6H7G.js → telemetry-HVXFZA2U.js} +85 -71
  320. package/dist/cli-bundle/chunks/telemetry-HVXFZA2U.js.map +1 -0
  321. package/dist/cli-bundle/chunks/{test-ACD52Z3S.js → test-UFSJ5YIO.js} +15 -15
  322. package/dist/cli-bundle/chunks/{test-PWDIZ255.js → test-YCDAUBWF.js} +15 -15
  323. package/dist/cli-bundle/chunks/test-all-2BWKY3GQ.js +427 -0
  324. package/dist/cli-bundle/chunks/test-all-2BWKY3GQ.js.map +1 -0
  325. package/dist/cli-bundle/chunks/test-all-PM7UYN42.js +430 -0
  326. package/dist/cli-bundle/chunks/test-all-PM7UYN42.js.map +7 -0
  327. package/dist/cli-bundle/chunks/{test-runs-UXIXPDKU.js → test-runs-FK5E75AA.js} +185 -147
  328. package/dist/cli-bundle/chunks/test-runs-FK5E75AA.js.map +1 -0
  329. package/dist/cli-bundle/chunks/{test-runs-PLRAZEFW.js → test-runs-H4TGWGRN.js} +184 -146
  330. package/dist/cli-bundle/chunks/test-runs-H4TGWGRN.js.map +7 -0
  331. package/dist/cli-bundle/chunks/update-MTCFES6X.js +24 -0
  332. package/dist/cli-bundle/chunks/{update-KFX2SIAC.js → update-Y5WQVT5O.js} +15 -15
  333. package/dist/cli-bundle/chunks/{update-many-Z5GJS5LC.js → update-many-6YAYYRLE.js} +82 -67
  334. package/dist/cli-bundle/chunks/{update-many-Z5GJS5LC.js.map → update-many-6YAYYRLE.js.map} +2 -2
  335. package/dist/cli-bundle/chunks/{update-many-RNSBX2TA.js → update-many-JTKKSA7Y.js} +83 -68
  336. package/dist/cli-bundle/chunks/{update-many-RNSBX2TA.js.map → update-many-JTKKSA7Y.js.map} +1 -1
  337. package/dist/cli-bundle/chunks/{upgrade-HAK6JG2O.js → upgrade-DTAHZ236.js} +11 -11
  338. package/dist/cli-bundle/chunks/{upgrade-BRL6KCOJ.js → upgrade-JUDU7YL4.js} +11 -11
  339. package/dist/cli-bundle/chunks/{validate-MTUVL5VC.js → validate-732RWS5W.js} +440 -320
  340. package/dist/cli-bundle/chunks/validate-732RWS5W.js.map +7 -0
  341. package/dist/cli-bundle/chunks/{validate-X5W76YJL.js → validate-W7H5TEDC.js} +441 -321
  342. package/dist/cli-bundle/chunks/validate-W7H5TEDC.js.map +1 -0
  343. package/dist/cli-bundle/main.js +945 -812
  344. package/dist/cli-bundle/main.js.map +3 -3
  345. package/dist/core/config/nested-settings.js +89 -67
  346. package/dist/core/config/nested-settings.js.map +1 -1
  347. package/dist/core/governance/metadata-coverage.js +20 -28
  348. package/dist/core/governance/metadata-coverage.js.map +1 -1
  349. package/dist/core/history/drift-scan.js +93 -81
  350. package/dist/core/history/drift-scan.js.map +1 -1
  351. package/dist/core/item/item-type-definition.js +14 -14
  352. package/dist/core/item/item-type-definition.js.map +1 -1
  353. package/dist/core/item/type-registry.js +87 -82
  354. package/dist/core/item/type-registry.js.map +1 -1
  355. package/dist/core/output/mutation-projection.js +42 -26
  356. package/dist/core/output/mutation-projection.js.map +1 -1
  357. package/dist/core/schema/runtime-schema.js +34 -28
  358. package/dist/core/schema/runtime-schema.js.map +1 -1
  359. package/dist/core/search/semantic-defaults.js +64 -37
  360. package/dist/core/search/semantic-defaults.js.map +1 -1
  361. package/dist/core/search/vector-stores.js +32 -17
  362. package/dist/core/search/vector-stores.js.map +1 -1
  363. package/dist/core/sentry/helpers.js +31 -28
  364. package/dist/core/sentry/helpers.js.map +1 -1
  365. package/dist/core/sentry/instrument.js +54 -43
  366. package/dist/core/sentry/instrument.js.map +1 -1
  367. package/dist/core/store/front-matter-cache.js +239 -153
  368. package/dist/core/store/front-matter-cache.js.map +1 -1
  369. package/dist/core/store/item-store.js +33 -26
  370. package/dist/core/store/item-store.js.map +1 -1
  371. package/dist/core/store/settings.js +247 -203
  372. package/dist/core/store/settings.js.map +1 -1
  373. package/dist/core/test/background-runs.js +189 -160
  374. package/dist/core/test/background-runs.js.map +1 -1
  375. package/package.json +2 -2
  376. package/packages/pm-beads/extensions/beads/runtime.ts +240 -167
  377. package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +65 -58
  378. package/packages/pm-todos/extensions/todos/runtime.ts +65 -42
  379. package/dist/cli-bundle/chunks/activity-AW6XVFH6.js +0 -16
  380. package/dist/cli-bundle/chunks/aggregate-JTEF4BP7.js.map +0 -1
  381. package/dist/cli-bundle/chunks/chunk-2D4HATP2.js.map +0 -1
  382. package/dist/cli-bundle/chunks/chunk-3S2KT7NG.js.map +0 -7
  383. package/dist/cli-bundle/chunks/chunk-3VGN2UWE.js.map +0 -1
  384. package/dist/cli-bundle/chunks/chunk-3XZCOZ5J.js.map +0 -1
  385. package/dist/cli-bundle/chunks/chunk-4DSGXSBL.js.map +0 -7
  386. package/dist/cli-bundle/chunks/chunk-4XOIEKSD.js.map +0 -1
  387. package/dist/cli-bundle/chunks/chunk-55SNVXRQ.js.map +0 -7
  388. package/dist/cli-bundle/chunks/chunk-5CGRF3L5.js.map +0 -1
  389. package/dist/cli-bundle/chunks/chunk-7R4QEMZZ.js.map +0 -1
  390. package/dist/cli-bundle/chunks/chunk-BDTISOSD.js.map +0 -7
  391. package/dist/cli-bundle/chunks/chunk-BZCEN4JA.js.map +0 -7
  392. package/dist/cli-bundle/chunks/chunk-CF7RL6FR.js.map +0 -1
  393. package/dist/cli-bundle/chunks/chunk-FFMQB7WR.js.map +0 -1
  394. package/dist/cli-bundle/chunks/chunk-IPYBJWTE.js.map +0 -7
  395. package/dist/cli-bundle/chunks/chunk-IZBR4NRW.js.map +0 -7
  396. package/dist/cli-bundle/chunks/chunk-JSU5P7VS.js.map +0 -1
  397. package/dist/cli-bundle/chunks/chunk-JWXRETDF.js.map +0 -1
  398. package/dist/cli-bundle/chunks/chunk-KNPEF7QG.js.map +0 -7
  399. package/dist/cli-bundle/chunks/chunk-NFDPYAIP.js.map +0 -7
  400. package/dist/cli-bundle/chunks/chunk-NUHHPVVS.js.map +0 -7
  401. package/dist/cli-bundle/chunks/chunk-NWMZWYYB.js.map +0 -1
  402. package/dist/cli-bundle/chunks/chunk-OTUHB4HS.js.map +0 -1
  403. package/dist/cli-bundle/chunks/chunk-RGEMWD6Q.js.map +0 -7
  404. package/dist/cli-bundle/chunks/chunk-RLDHZHQS.js.map +0 -1
  405. package/dist/cli-bundle/chunks/chunk-RMMQ74TG.js.map +0 -7
  406. package/dist/cli-bundle/chunks/chunk-RVUALSJF.js.map +0 -7
  407. package/dist/cli-bundle/chunks/chunk-TP5Q5ZD3.js.map +0 -1
  408. package/dist/cli-bundle/chunks/chunk-UYUYDGIB.js.map +0 -1
  409. package/dist/cli-bundle/chunks/chunk-V3NOKJF2.js.map +0 -1
  410. package/dist/cli-bundle/chunks/chunk-VARHOHYV.js.map +0 -7
  411. package/dist/cli-bundle/chunks/chunk-YITK2PJ6.js.map +0 -7
  412. package/dist/cli-bundle/chunks/chunk-ZETXE4SE.js.map +0 -1
  413. package/dist/cli-bundle/chunks/close-E6ZZGCJY.js +0 -14
  414. package/dist/cli-bundle/chunks/close-many-BG5QQIDQ.js.map +0 -7
  415. package/dist/cli-bundle/chunks/close-many-LDRVEQY2.js.map +0 -1
  416. package/dist/cli-bundle/chunks/config-DMSU64QO.js +0 -1541
  417. package/dist/cli-bundle/chunks/config-DMSU64QO.js.map +0 -7
  418. package/dist/cli-bundle/chunks/config-QH2DICD6.js +0 -1531
  419. package/dist/cli-bundle/chunks/config-QH2DICD6.js.map +0 -1
  420. package/dist/cli-bundle/chunks/contracts-HN7ABKLP.js.map +0 -7
  421. package/dist/cli-bundle/chunks/contracts-W4FZVVD6.js.map +0 -1
  422. package/dist/cli-bundle/chunks/create-OH3BDGBB.js +0 -28
  423. package/dist/cli-bundle/chunks/get-A7MAOHCU.js.map +0 -7
  424. package/dist/cli-bundle/chunks/get-DSDEKJ3L.js.map +0 -1
  425. package/dist/cli-bundle/chunks/health-3IPFLKXB.js.map +0 -1
  426. package/dist/cli-bundle/chunks/health-GZXGBZ36.js.map +0 -7
  427. package/dist/cli-bundle/chunks/history-WSZHY3PN.js +0 -18
  428. package/dist/cli-bundle/chunks/history-compact-2WRZ2WK4.js.map +0 -7
  429. package/dist/cli-bundle/chunks/history-compact-HR7BB4LR.js.map +0 -1
  430. package/dist/cli-bundle/chunks/history-redact-MP6CH7U5.js +0 -19
  431. package/dist/cli-bundle/chunks/history-repair-LCMOS45X.js.map +0 -7
  432. package/dist/cli-bundle/chunks/history-repair-XA3LC4GA.js.map +0 -1
  433. package/dist/cli-bundle/chunks/init-PAX32BJA.js +0 -22
  434. package/dist/cli-bundle/chunks/next-BCERKDUR.js.map +0 -7
  435. package/dist/cli-bundle/chunks/next-FYTQF6HG.js.map +0 -1
  436. package/dist/cli-bundle/chunks/plan-4WXEQCTN.js.map +0 -7
  437. package/dist/cli-bundle/chunks/plan-RKZHQVXR.js.map +0 -1
  438. package/dist/cli-bundle/chunks/register-list-query-7LV46VAU.js.map +0 -1
  439. package/dist/cli-bundle/chunks/register-list-query-SNG5PGA4.js.map +0 -7
  440. package/dist/cli-bundle/chunks/register-mutation-ENNDUAZG.js.map +0 -1
  441. package/dist/cli-bundle/chunks/register-mutation-KK7PHYYU.js.map +0 -7
  442. package/dist/cli-bundle/chunks/register-operations-C6OWLDSH.js.map +0 -1
  443. package/dist/cli-bundle/chunks/register-operations-HZ6XERQG.js.map +0 -7
  444. package/dist/cli-bundle/chunks/register-setup-P67EMBDJ.js.map +0 -1
  445. package/dist/cli-bundle/chunks/register-setup-ZKJ53RS7.js.map +0 -7
  446. package/dist/cli-bundle/chunks/restore-YALDGTQR.js +0 -17
  447. package/dist/cli-bundle/chunks/telemetry-BZUF6H7G.js.map +0 -1
  448. package/dist/cli-bundle/chunks/telemetry-GAHHQTOS.js.map +0 -7
  449. package/dist/cli-bundle/chunks/test-all-L2MDDUCA.js +0 -358
  450. package/dist/cli-bundle/chunks/test-all-L2MDDUCA.js.map +0 -1
  451. package/dist/cli-bundle/chunks/test-all-RBZ6DLU2.js +0 -361
  452. package/dist/cli-bundle/chunks/test-all-RBZ6DLU2.js.map +0 -7
  453. package/dist/cli-bundle/chunks/test-runs-PLRAZEFW.js.map +0 -7
  454. package/dist/cli-bundle/chunks/test-runs-UXIXPDKU.js.map +0 -1
  455. package/dist/cli-bundle/chunks/update-AMRSOIWP.js +0 -24
  456. package/dist/cli-bundle/chunks/validate-MTUVL5VC.js.map +0 -7
  457. package/dist/cli-bundle/chunks/validate-X5W76YJL.js.map +0 -1
  458. /package/dist/cli-bundle/chunks/{activity-DBLQVIP6.js.map → activity-CUC4JY3U.js.map} +0 -0
  459. /package/dist/cli-bundle/chunks/{activity-AW6XVFH6.js.map → activity-WEIEMM73.js.map} +0 -0
  460. /package/dist/cli-bundle/chunks/{append-QCFJSDFL.js.map → append-H32VOR2Y.js.map} +0 -0
  461. /package/dist/cli-bundle/chunks/{append-LOVPGVPT.js.map → append-UBM632FK.js.map} +0 -0
  462. /package/dist/cli-bundle/chunks/{chunk-SLMUGTK3.js.map → chunk-2ASNV4DH.js.map} +0 -0
  463. /package/dist/cli-bundle/chunks/{chunk-UZIWVBE6.js.map → chunk-2CHRYUXL.js.map} +0 -0
  464. /package/dist/cli-bundle/chunks/{chunk-NU2UEROZ.js.map → chunk-3AZUFQK6.js.map} +0 -0
  465. /package/dist/cli-bundle/chunks/{chunk-LB6TP6MC.js.map → chunk-3LCUASYG.js.map} +0 -0
  466. /package/dist/cli-bundle/chunks/{chunk-HPPFYYOV.js.map → chunk-3Q2HBMTI.js.map} +0 -0
  467. /package/dist/cli-bundle/chunks/{chunk-W4ULYO7Z.js.map → chunk-55XRYWEG.js.map} +0 -0
  468. /package/dist/cli-bundle/chunks/{chunk-HXTQJXWT.js.map → chunk-5GVTFFTC.js.map} +0 -0
  469. /package/dist/cli-bundle/chunks/{chunk-64HNBBFQ.js.map → chunk-A6VOGKBA.js.map} +0 -0
  470. /package/dist/cli-bundle/chunks/{chunk-WYDHYJPO.js.map → chunk-AIAIXG7I.js.map} +0 -0
  471. /package/dist/cli-bundle/chunks/{chunk-CWFNTKQJ.js.map → chunk-AJEBCRIY.js.map} +0 -0
  472. /package/dist/cli-bundle/chunks/{chunk-NOLPZMSV.js.map → chunk-BTX5MIQF.js.map} +0 -0
  473. /package/dist/cli-bundle/chunks/{chunk-RH5ZBYFD.js.map → chunk-BVZZN2LH.js.map} +0 -0
  474. /package/dist/cli-bundle/chunks/{chunk-27BXPBAY.js.map → chunk-CYBDUHNO.js.map} +0 -0
  475. /package/dist/cli-bundle/chunks/{chunk-A7FPBAQS.js.map → chunk-CZPVDLD2.js.map} +0 -0
  476. /package/dist/cli-bundle/chunks/{chunk-JPECA746.js.map → chunk-EUKTMRN3.js.map} +0 -0
  477. /package/dist/cli-bundle/chunks/{chunk-2466X6E4.js.map → chunk-FFOQHGNH.js.map} +0 -0
  478. /package/dist/cli-bundle/chunks/{chunk-JLM7BHI7.js.map → chunk-GFMSLORL.js.map} +0 -0
  479. /package/dist/cli-bundle/chunks/{chunk-SDR5J34Q.js.map → chunk-GRRG3MCT.js.map} +0 -0
  480. /package/dist/cli-bundle/chunks/{chunk-GJ326ZKX.js.map → chunk-H4GRLYJS.js.map} +0 -0
  481. /package/dist/cli-bundle/chunks/{chunk-OGXLACHC.js.map → chunk-HQTPRV4D.js.map} +0 -0
  482. /package/dist/cli-bundle/chunks/{chunk-BHO33VBQ.js.map → chunk-IEEJQCZ4.js.map} +0 -0
  483. /package/dist/cli-bundle/chunks/{chunk-4DUVCVLZ.js.map → chunk-JMK5GCK2.js.map} +0 -0
  484. /package/dist/cli-bundle/chunks/{chunk-AXIDKKAT.js.map → chunk-K2VYLVX4.js.map} +0 -0
  485. /package/dist/cli-bundle/chunks/{chunk-EJUDVUYZ.js.map → chunk-KCO2EAN5.js.map} +0 -0
  486. /package/dist/cli-bundle/chunks/{chunk-6AQZPVHQ.js.map → chunk-KIYCOJ63.js.map} +0 -0
  487. /package/dist/cli-bundle/chunks/{chunk-ZRP4VG5U.js.map → chunk-KLXF7NCC.js.map} +0 -0
  488. /package/dist/cli-bundle/chunks/{chunk-QCWF6IYD.js.map → chunk-KN3URLKS.js.map} +0 -0
  489. /package/dist/cli-bundle/chunks/{chunk-N74UMG5H.js.map → chunk-LRKMWUUV.js.map} +0 -0
  490. /package/dist/cli-bundle/chunks/{chunk-AVEE5EHK.js.map → chunk-LTRAF2D7.js.map} +0 -0
  491. /package/dist/cli-bundle/chunks/{chunk-IJYK2T43.js.map → chunk-MRD4T5LF.js.map} +0 -0
  492. /package/dist/cli-bundle/chunks/{chunk-G7I7DEZA.js.map → chunk-N2JSWVWG.js.map} +0 -0
  493. /package/dist/cli-bundle/chunks/{chunk-5QFDBI4F.js.map → chunk-N3QCJS4M.js.map} +0 -0
  494. /package/dist/cli-bundle/chunks/{chunk-4A3BJ675.js.map → chunk-OTUJZKGI.js.map} +0 -0
  495. /package/dist/cli-bundle/chunks/{chunk-HZZEHPRG.js.map → chunk-QH3FSKRJ.js.map} +0 -0
  496. /package/dist/cli-bundle/chunks/{chunk-NKZAN7BD.js.map → chunk-S62UANU7.js.map} +0 -0
  497. /package/dist/cli-bundle/chunks/{chunk-3J6JRJ3I.js.map → chunk-SYNKD3ZG.js.map} +0 -0
  498. /package/dist/cli-bundle/chunks/{chunk-L5OEFZQG.js.map → chunk-U2BEEM2X.js.map} +0 -0
  499. /package/dist/cli-bundle/chunks/{chunk-EVMTBV6V.js.map → chunk-UT73HUPC.js.map} +0 -0
  500. /package/dist/cli-bundle/chunks/{chunk-VICZWYGZ.js.map → chunk-UTSH5GWX.js.map} +0 -0
  501. /package/dist/cli-bundle/chunks/{chunk-MDPEOIGN.js.map → chunk-XWGEMNBR.js.map} +0 -0
  502. /package/dist/cli-bundle/chunks/{chunk-HYTGA6GI.js.map → chunk-Y4NRKBFW.js.map} +0 -0
  503. /package/dist/cli-bundle/chunks/{chunk-22WKIL3H.js.map → chunk-YPKFV2JR.js.map} +0 -0
  504. /package/dist/cli-bundle/chunks/{chunk-DDPTYJIM.js.map → chunk-ZNHEYCDD.js.map} +0 -0
  505. /package/dist/cli-bundle/chunks/{chunk-MAUKX7JC.js.map → chunk-ZNT7KEWE.js.map} +0 -0
  506. /package/dist/cli-bundle/chunks/{claim-T3GCKV7C.js.map → claim-SENTPZBN.js.map} +0 -0
  507. /package/dist/cli-bundle/chunks/{claim-EMQLYPRW.js.map → claim-Z7MEQCBT.js.map} +0 -0
  508. /package/dist/cli-bundle/chunks/{close-TQYAAFJP.js.map → close-424MX4CU.js.map} +0 -0
  509. /package/dist/cli-bundle/chunks/{close-E6ZZGCJY.js.map → close-YCWQQPDS.js.map} +0 -0
  510. /package/dist/cli-bundle/chunks/{comments-YUXJRZPQ.js.map → comments-4FGNTSNV.js.map} +0 -0
  511. /package/dist/cli-bundle/chunks/{comments-QCKR2YY2.js.map → comments-7YS5MY5X.js.map} +0 -0
  512. /package/dist/cli-bundle/chunks/{context-OCZ3FJ4Z.js.map → context-LHVKJSPJ.js.map} +0 -0
  513. /package/dist/cli-bundle/chunks/{context-B6275WPX.js.map → context-ZQY54JNS.js.map} +0 -0
  514. /package/dist/cli-bundle/chunks/{copy-DEM4DATS.js.map → copy-GYNQQPW2.js.map} +0 -0
  515. /package/dist/cli-bundle/chunks/{copy-BTJOSKKT.js.map → copy-TLW7JTQT.js.map} +0 -0
  516. /package/dist/cli-bundle/chunks/{create-RLRJMRTM.js.map → create-VSKYSOCD.js.map} +0 -0
  517. /package/dist/cli-bundle/chunks/{create-OH3BDGBB.js.map → create-XTMAPS7I.js.map} +0 -0
  518. /package/dist/cli-bundle/chunks/{delete-LSVHAB4Y.js.map → delete-4W5JYCEG.js.map} +0 -0
  519. /package/dist/cli-bundle/chunks/{delete-BHK7VB2Z.js.map → delete-ANTOTI2I.js.map} +0 -0
  520. /package/dist/cli-bundle/chunks/{deps-XHYXWEPT.js.map → deps-HPPE6MJN.js.map} +0 -0
  521. /package/dist/cli-bundle/chunks/{deps-4UDFJRUA.js.map → deps-ZQZN54EZ.js.map} +0 -0
  522. /package/dist/cli-bundle/chunks/{docs-GYZNVS26.js.map → docs-RPOVFMP3.js.map} +0 -0
  523. /package/dist/cli-bundle/chunks/{docs-26S44RXU.js.map → docs-XJNYBJGE.js.map} +0 -0
  524. /package/dist/cli-bundle/chunks/{eval-PGRVIJQU.js.map → eval-DM6JBZTS.js.map} +0 -0
  525. /package/dist/cli-bundle/chunks/{eval-UYF3ZPVO.js.map → eval-RFBI5FGS.js.map} +0 -0
  526. /package/dist/cli-bundle/chunks/{extension-CPSLJQVE.js.map → extension-B3YY4WY5.js.map} +0 -0
  527. /package/dist/cli-bundle/chunks/{extension-CXJ6RELI.js.map → extension-TTSEFQTS.js.map} +0 -0
  528. /package/dist/cli-bundle/chunks/{files-NQHEXUZD.js.map → files-5D65CHGE.js.map} +0 -0
  529. /package/dist/cli-bundle/chunks/{files-MBNICQFM.js.map → files-GPIG77EN.js.map} +0 -0
  530. /package/dist/cli-bundle/chunks/{focus-XZW5423D.js.map → focus-C3PEJV2C.js.map} +0 -0
  531. /package/dist/cli-bundle/chunks/{focus-DWYIG7GU.js.map → focus-ZHN7WIGX.js.map} +0 -0
  532. /package/dist/cli-bundle/chunks/{gc-LPVMKJQJ.js.map → gc-D4JQ6OWN.js.map} +0 -0
  533. /package/dist/cli-bundle/chunks/{gc-7GQYOS2G.js.map → gc-VZIXDL32.js.map} +0 -0
  534. /package/dist/cli-bundle/chunks/{history-WSZHY3PN.js.map → history-DD7L7BNL.js.map} +0 -0
  535. /package/dist/cli-bundle/chunks/{history-NERDJNUB.js.map → history-IL7XCEX2.js.map} +0 -0
  536. /package/dist/cli-bundle/chunks/{history-redact-MP6CH7U5.js.map → history-redact-IX4YEWMY.js.map} +0 -0
  537. /package/dist/cli-bundle/chunks/{history-redact-O3NBCNWC.js.map → history-redact-VYCWQFK7.js.map} +0 -0
  538. /package/dist/cli-bundle/chunks/{init-64XDLQJB.js.map → init-F27NHENZ.js.map} +0 -0
  539. /package/dist/cli-bundle/chunks/{init-PAX32BJA.js.map → init-HHVQQP6C.js.map} +0 -0
  540. /package/dist/cli-bundle/chunks/{learnings-LPKCSJX7.js.map → learnings-HJVDQIGY.js.map} +0 -0
  541. /package/dist/cli-bundle/chunks/{learnings-JR6MA5TI.js.map → learnings-XSFSUUWK.js.map} +0 -0
  542. /package/dist/cli-bundle/chunks/{list-G5Y65VF6.js.map → list-HPMEKCAA.js.map} +0 -0
  543. /package/dist/cli-bundle/chunks/{list-DNBJVO3E.js.map → list-VMPWTURB.js.map} +0 -0
  544. /package/dist/cli-bundle/chunks/{notes-2BMU3VVQ.js.map → notes-GDZIKGR6.js.map} +0 -0
  545. /package/dist/cli-bundle/chunks/{notes-6KTGO2OJ.js.map → notes-WDDBPC4D.js.map} +0 -0
  546. /package/dist/cli-bundle/chunks/{profile-QLER5ENE.js.map → profile-CCOKZ2IQ.js.map} +0 -0
  547. /package/dist/cli-bundle/chunks/{profile-4OMM32CD.js.map → profile-HUCENIEQ.js.map} +0 -0
  548. /package/dist/cli-bundle/chunks/{restore-4MHZFJ2E.js.map → restore-4CBWUMCX.js.map} +0 -0
  549. /package/dist/cli-bundle/chunks/{restore-YALDGTQR.js.map → restore-5UEAGG3W.js.map} +0 -0
  550. /package/dist/cli-bundle/chunks/{scheduling-shortcuts-LB6DOLRL.js.map → scheduling-shortcuts-6VFKNKCM.js.map} +0 -0
  551. /package/dist/cli-bundle/chunks/{scheduling-shortcuts-UTOYKLXQ.js.map → scheduling-shortcuts-ERHCVTEM.js.map} +0 -0
  552. /package/dist/cli-bundle/chunks/{schema-73HR2OJW.js.map → schema-TDGK6N3I.js.map} +0 -0
  553. /package/dist/cli-bundle/chunks/{schema-U6LJKSIR.js.map → schema-UE5KKAUX.js.map} +0 -0
  554. /package/dist/cli-bundle/chunks/{search-KILGT37L.js.map → search-FP7MEU4S.js.map} +0 -0
  555. /package/dist/cli-bundle/chunks/{search-AXPXKZER.js.map → search-K4CFLQ5S.js.map} +0 -0
  556. /package/dist/cli-bundle/chunks/{stats-PSYVVTNZ.js.map → stats-NJJCALEZ.js.map} +0 -0
  557. /package/dist/cli-bundle/chunks/{stats-W5KNVJWQ.js.map → stats-XT6QRKQY.js.map} +0 -0
  558. /package/dist/cli-bundle/chunks/{test-ACD52Z3S.js.map → test-UFSJ5YIO.js.map} +0 -0
  559. /package/dist/cli-bundle/chunks/{test-PWDIZ255.js.map → test-YCDAUBWF.js.map} +0 -0
  560. /package/dist/cli-bundle/chunks/{update-AMRSOIWP.js.map → update-MTCFES6X.js.map} +0 -0
  561. /package/dist/cli-bundle/chunks/{update-KFX2SIAC.js.map → update-Y5WQVT5O.js.map} +0 -0
  562. /package/dist/cli-bundle/chunks/{upgrade-HAK6JG2O.js.map → upgrade-DTAHZ236.js.map} +0 -0
  563. /package/dist/cli-bundle/chunks/{upgrade-BRL6KCOJ.js.map → upgrade-JUDU7YL4.js.map} +0 -0
@@ -4,7 +4,7 @@
4
4
  * Implements the pm search command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="abfd6249-f15e-50a9-867a-69c5d305e97e")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="fe9c6a3a-fb99-53ed-9a6c-8c32bb745364")}catch(e){}}();
8
8
  import fs from "node:fs/promises";
9
9
  import path from "node:path";
10
10
  import { coerceNumberInRange, toNonEmptyStringOrUndefined } from "../../core/shared/primitives.js";
@@ -117,8 +117,6 @@ const LONG_QUERY_PHRASE_MULTIPLIER = 6;
117
117
  const ALL_TERMS_COVERAGE_BONUS = 40;
118
118
  const EXACT_ID_MATCH_SCORE = 1_000;
119
119
  const SHORT_ID_MATCH_SCORE = 900;
120
- const IMPLICIT_HYBRID_EMBEDDING_TIMEOUT_MS = 8_000;
121
- const IMPLICIT_HYBRID_VECTOR_TIMEOUT_MS = 8_000;
122
120
  // GH-157 matched-text highlighting (--highlight): markers wrapping each matching
123
121
  // token run, and the number of characters of surrounding context retained on
124
122
  // each side of the first match in a field. The «…» guillemets are single
@@ -272,16 +270,6 @@ export function classifyImplicitSemanticFallbackReason(error) {
272
270
  }
273
271
  return "error";
274
272
  }
275
- function buildImplicitSemanticFallbackWarning(error) {
276
- const reason = classifyImplicitSemanticFallbackReason(error);
277
- if (reason === "timeout") {
278
- return "search_implicit_semantic_fallback:timeout:using_keyword_mode";
279
- }
280
- if (reason === "connection") {
281
- return "search_implicit_semantic_fallback:connection:using_keyword_mode";
282
- }
283
- return "search_implicit_semantic_fallback:error:using_keyword_mode";
284
- }
285
273
  // Explicit --semantic/--hybrid searches must never hard-fail an agent when the
286
274
  // embedding/vector backend is unreachable or unconfigured: degrade to keyword
287
275
  // search and surface a machine-readable warning instead of an unknown_error.
@@ -440,7 +428,6 @@ export const _testOnlySearchCommand = {
440
428
  buildExplicitSemanticFallbackWarning,
441
429
  buildCompactSearchFilterSummary,
442
430
  buildHybridLexicalScore,
443
- buildImplicitSemanticFallbackWarning,
444
431
  buildRerankCorpus,
445
432
  buildSemanticHits,
446
433
  classifyImplicitSemanticFallbackReason,
@@ -1270,8 +1257,15 @@ function resolveExtensionVectorAdapter(settings) {
1270
1257
  if (typeof query !== "function") {
1271
1258
  return null;
1272
1259
  }
1260
+ const upsert = runtimeDefinition.upsert;
1261
+ const runtimeAdapterName = toOptionalNonEmptyString(runtimeDefinition.name) ??
1262
+ toOptionalNonEmptyString(resolved.definition.name) ??
1263
+ adapterName ??
1264
+ "extension";
1273
1265
  return {
1266
+ adapterName: runtimeAdapterName,
1274
1267
  query: query,
1268
+ ...(typeof upsert === "function" ? { upsert: upsert } : {}),
1275
1269
  };
1276
1270
  }
1277
1271
  /* c8 ignore stop */
@@ -1485,59 +1479,162 @@ function buildRerankCorpus(document) {
1485
1479
  }
1486
1480
  /* c8 ignore stop */
1487
1481
  /* c8 ignore start -- semantic expansion/rerank fallback matrices are covered by end-to-end semantic search tests */
1488
- async function computeSemanticOrHybridHits(context) {
1489
- const semanticLimit = context.limit ?? context.maxResults;
1490
- const embeddingOptions = context.embeddingTimeoutMs !== undefined ? { timeout_ms: context.embeddingTimeoutMs } : {};
1491
- const vectorQueryOptions = context.vectorQueryTimeoutMs !== undefined ? { timeout_ms: context.vectorQueryTimeoutMs } : {};
1492
- const queryTrimmed = context.query.trim();
1482
+ async function resolveExpandedSemanticQueries(context, queryTrimmed) {
1493
1483
  const baseExpandedQueries = context.queryExpansion.enabled
1494
1484
  ? buildDeterministicQueryExpansions(queryTrimmed, context.queryExpansion.max_queries)
1495
1485
  : [queryTrimmed];
1496
- let expandedQueries = baseExpandedQueries.length > 0 ? baseExpandedQueries : [queryTrimmed];
1497
- if (context.queryExpansion.enabled) {
1498
- if (context.queryExpansionExtension?.expand) {
1499
- try {
1500
- const rawExpansion = await Promise.resolve(context.queryExpansionExtension.expand({
1501
- query: queryTrimmed,
1502
- mode: context.requestedMode,
1503
- settings: context.settings,
1504
- }));
1505
- const extensionExpansion = normalizeQueryExpansionOutput(rawExpansion);
1506
- expandedQueries = mergeQueryExpansions(expandedQueries, extensionExpansion, context.queryExpansion.max_queries);
1507
- }
1508
- catch {
1509
- context.warnings.push(`search_query_expansion_provider_failed:${context.queryExpansionExtension.providerName}:using_builtin`);
1510
- }
1486
+ const expandedQueries = baseExpandedQueries.length > 0 ? baseExpandedQueries : [queryTrimmed];
1487
+ if (!context.queryExpansion.enabled) {
1488
+ return expandedQueries;
1489
+ }
1490
+ if (context.queryExpansionExtension?.expand) {
1491
+ try {
1492
+ const rawExpansion = await Promise.resolve(context.queryExpansionExtension.expand({
1493
+ query: queryTrimmed,
1494
+ mode: context.requestedMode,
1495
+ settings: context.settings,
1496
+ }));
1497
+ return mergeQueryExpansions(expandedQueries, normalizeQueryExpansionOutput(rawExpansion), context.queryExpansion.max_queries);
1511
1498
  }
1512
- else if (context.queryExpansion.provider &&
1513
- context.queryExpansion.provider !== "openai" &&
1514
- context.queryExpansion.provider !== "ollama") {
1515
- context.warnings.push(`search_query_expansion_provider_unavailable:${context.queryExpansion.provider}:using_builtin`);
1499
+ catch {
1500
+ context.warnings.push(`search_query_expansion_provider_failed:${context.queryExpansionExtension.providerName}:using_builtin`);
1501
+ return expandedQueries;
1516
1502
  }
1517
1503
  }
1518
- const queryVectors = await executeEmbeddingRequest(context.provider, expandedQueries, embeddingOptions);
1519
- const executeVectorQueryWithFallback = async (semanticVector) => {
1520
- if (context.extensionVectorAdapter?.query) {
1521
- try {
1522
- return await Promise.resolve(context.extensionVectorAdapter.query({
1523
- vector: semanticVector,
1524
- limit: semanticLimit,
1525
- settings: context.settings,
1526
- }));
1527
- }
1528
- catch (error) {
1529
- if (!context.vectorStore) {
1530
- throw new PmCliError(`Extension vector adapter query failed and no built-in fallback store is configured (${error instanceof Error ? error.message : String(error)})`, EXIT_CODE.GENERIC_FAILURE);
1531
- }
1532
- return await executeVectorQuery(context.vectorStore, semanticVector, semanticLimit, vectorQueryOptions);
1533
- }
1504
+ if (context.queryExpansion.provider &&
1505
+ context.queryExpansion.provider !== "openai" &&
1506
+ context.queryExpansion.provider !== "ollama") {
1507
+ context.warnings.push(`search_query_expansion_provider_unavailable:${context.queryExpansion.provider}:using_builtin`);
1508
+ }
1509
+ return expandedQueries;
1510
+ }
1511
+ async function executeSemanticVectorQuery(context, semanticVector, semanticLimit, vectorQueryOptions) {
1512
+ if (context.extensionVectorAdapter?.query) {
1513
+ try {
1514
+ return await Promise.resolve(context.extensionVectorAdapter.query({
1515
+ vector: semanticVector,
1516
+ limit: semanticLimit,
1517
+ settings: context.settings,
1518
+ }));
1534
1519
  }
1535
- if (context.vectorStore) {
1520
+ catch (error) {
1521
+ if (!context.vectorStore) {
1522
+ throw new PmCliError(`Extension vector adapter query failed and no built-in fallback store is configured (${error instanceof Error ? error.message : String(error)})`, EXIT_CODE.GENERIC_FAILURE);
1523
+ }
1524
+ context.warnings.push(`search_vector_adapter_failed:${context.extensionVectorAdapter.adapterName}:using_builtin`);
1536
1525
  return await executeVectorQuery(context.vectorStore, semanticVector, semanticLimit, vectorQueryOptions);
1537
1526
  }
1538
- throw new PmCliError("Semantic search requires either a configured vector store or an extension vector adapter query handler", EXIT_CODE.USAGE);
1539
- };
1540
- const queryVectorGroups = await Promise.all(queryVectors.map(async (semanticVector) => await executeVectorQueryWithFallback(semanticVector)));
1527
+ }
1528
+ if (context.vectorStore) {
1529
+ return await executeVectorQuery(context.vectorStore, semanticVector, semanticLimit, vectorQueryOptions);
1530
+ }
1531
+ throw new PmCliError("Semantic search requires either a configured vector store or an extension vector adapter query handler", EXIT_CODE.USAGE);
1532
+ }
1533
+ function buildRerankCandidateContexts(hybridHits, filteredById, topK) {
1534
+ const sortedForCandidates = [...hybridHits].sort((left, right) => {
1535
+ if (left.score !== right.score) {
1536
+ return right.score - left.score;
1537
+ }
1538
+ return left.item.id.localeCompare(right.item.id);
1539
+ });
1540
+ return sortedForCandidates
1541
+ .slice(0, topK)
1542
+ .map((hit) => {
1543
+ const document = filteredById.get(hit.item.id);
1544
+ return document ? { hit, text: buildRerankCorpus(document) } : null;
1545
+ })
1546
+ .filter((entry) => entry !== null);
1547
+ }
1548
+ async function resolveExtensionRerankScores(context, queryTrimmed, candidateContexts) {
1549
+ if (!context.rerankExtension?.rerank) {
1550
+ return null;
1551
+ }
1552
+ try {
1553
+ const rawRerank = await Promise.resolve(context.rerankExtension.rerank({
1554
+ query: queryTrimmed,
1555
+ mode: "hybrid",
1556
+ model: context.rerank.model,
1557
+ top_k: context.rerank.top_k,
1558
+ settings: context.settings,
1559
+ candidates: candidateContexts.map((entry) => ({
1560
+ id: entry.hit.item.id,
1561
+ text: entry.text,
1562
+ score: entry.hit.score,
1563
+ })),
1564
+ }));
1565
+ const normalizedRerank = normalizeRerankOutput(rawRerank);
1566
+ if (normalizedRerank.length > 0) {
1567
+ return new Map(normalizedRerank.map((entry) => [entry.id, entry.score]));
1568
+ }
1569
+ context.warnings.push(`search_rerank_provider_invalid_response:${context.rerankExtension.providerName}:using_builtin`);
1570
+ return null;
1571
+ }
1572
+ catch {
1573
+ context.warnings.push(`search_rerank_provider_failed:${context.rerankExtension.providerName}:using_builtin`);
1574
+ return null;
1575
+ }
1576
+ }
1577
+ async function resolveRerankScores(context, queryTrimmed, candidateContexts) {
1578
+ const extensionScores = await resolveExtensionRerankScores(context, queryTrimmed, candidateContexts);
1579
+ if (extensionScores) {
1580
+ return extensionScores;
1581
+ }
1582
+ const rerankCandidates = candidateContexts.map((entry) => ({
1583
+ id: entry.hit.item.id,
1584
+ text: entry.text,
1585
+ }));
1586
+ try {
1587
+ return await rerankCandidatesWithEmbeddings(context.provider, context.rerank.model, queryTrimmed, rerankCandidates, context.embeddingTimeoutMs);
1588
+ }
1589
+ catch {
1590
+ context.warnings.push("search_rerank_failed:using_hybrid_scores");
1591
+ return null;
1592
+ }
1593
+ }
1594
+ function applyRerankScores(hybridHits, rerankScores) {
1595
+ const rerankedIds = new Set(rerankScores.keys());
1596
+ const rerankedHits = hybridHits.map((hit) => {
1597
+ const rerankScore = rerankScores.get(hit.item.id);
1598
+ if (rerankScore === undefined) {
1599
+ return hit;
1600
+ }
1601
+ const matchedFields = new Set(hit.matched_fields);
1602
+ matchedFields.add("rerank");
1603
+ return {
1604
+ ...hit,
1605
+ score: rerankScore,
1606
+ matched_fields: [...matchedFields].sort((left, right) => left.localeCompare(right)),
1607
+ };
1608
+ });
1609
+ rerankedHits.sort((left, right) => {
1610
+ const leftWasReranked = rerankedIds.has(left.item.id);
1611
+ const rightWasReranked = rerankedIds.has(right.item.id);
1612
+ if (leftWasReranked !== rightWasReranked) {
1613
+ return leftWasReranked ? -1 : 1;
1614
+ }
1615
+ if (left.score !== right.score) {
1616
+ return right.score - left.score;
1617
+ }
1618
+ return left.item.id.localeCompare(right.item.id);
1619
+ });
1620
+ return rerankedHits;
1621
+ }
1622
+ async function applyHybridRerank(context, queryTrimmed, hybridHits, filteredById) {
1623
+ if (!context.rerank.enabled || hybridHits.length <= 1) {
1624
+ return hybridHits;
1625
+ }
1626
+ const candidateContexts = buildRerankCandidateContexts(hybridHits, filteredById, context.rerank.top_k);
1627
+ const rerankScores = await resolveRerankScores(context, queryTrimmed, candidateContexts);
1628
+ return rerankScores && rerankScores.size > 0 ? applyRerankScores(hybridHits, rerankScores) : hybridHits;
1629
+ }
1630
+ async function computeSemanticOrHybridHits(context) {
1631
+ const semanticLimit = context.limit ?? context.maxResults;
1632
+ const embeddingOptions = context.embeddingTimeoutMs !== undefined ? { timeout_ms: context.embeddingTimeoutMs } : {};
1633
+ const vectorQueryOptions = context.vectorQueryTimeoutMs !== undefined ? { timeout_ms: context.vectorQueryTimeoutMs } : {};
1634
+ const queryTrimmed = context.query.trim();
1635
+ const expandedQueries = await resolveExpandedSemanticQueries(context, queryTrimmed);
1636
+ const queryVectors = await executeEmbeddingRequest(context.provider, expandedQueries, embeddingOptions);
1637
+ const queryVectorGroups = await Promise.all(queryVectors.map(async (semanticVector) => await executeSemanticVectorQuery(context, semanticVector, semanticLimit, vectorQueryOptions)));
1541
1638
  const vectorHits = mergeVectorHitsById(queryVectorGroups);
1542
1639
  const filteredById = new Map(context.filteredDocuments.map((document) => [document.metadata.id, document]));
1543
1640
  const { semanticHits, semanticScores } = buildSemanticHits(vectorHits, filteredById);
@@ -1547,91 +1644,7 @@ async function computeSemanticOrHybridHits(context) {
1547
1644
  // semantic mode, where it otherwise carries no vector hit at all.
1548
1645
  return { hits: forceExactIdHitsToTop(semanticHits, context.keywordHits), vectorMatchCount };
1549
1646
  }
1550
- let hybridHits = combineHybridHits(filteredById, semanticScores, context.keywordHits, context.hybridSemanticWeight);
1551
- if (context.rerank.enabled && hybridHits.length > 1) {
1552
- const sortedForCandidates = [...hybridHits].sort((left, right) => {
1553
- if (left.score !== right.score) {
1554
- return right.score - left.score;
1555
- }
1556
- return left.item.id.localeCompare(right.item.id);
1557
- });
1558
- const candidateHits = sortedForCandidates.slice(0, context.rerank.top_k);
1559
- const candidateContexts = candidateHits
1560
- .map((hit) => {
1561
- const document = filteredById.get(hit.item.id);
1562
- if (!document) {
1563
- return null;
1564
- }
1565
- return { hit, text: buildRerankCorpus(document) };
1566
- })
1567
- .filter((entry) => entry !== null);
1568
- const rerankCandidates = candidateContexts.map((entry) => ({
1569
- id: entry.hit.item.id,
1570
- text: entry.text,
1571
- }));
1572
- let rerankScores = null;
1573
- if (context.rerankExtension?.rerank) {
1574
- try {
1575
- const rawRerank = await Promise.resolve(context.rerankExtension.rerank({
1576
- query: queryTrimmed,
1577
- mode: "hybrid",
1578
- model: context.rerank.model,
1579
- top_k: context.rerank.top_k,
1580
- settings: context.settings,
1581
- candidates: candidateContexts.map((entry) => ({
1582
- id: entry.hit.item.id,
1583
- text: entry.text,
1584
- score: entry.hit.score,
1585
- })),
1586
- }));
1587
- const normalizedRerank = normalizeRerankOutput(rawRerank);
1588
- if (normalizedRerank.length > 0) {
1589
- rerankScores = new Map(normalizedRerank.map((entry) => [entry.id, entry.score]));
1590
- }
1591
- else {
1592
- context.warnings.push(`search_rerank_provider_invalid_response:${context.rerankExtension.providerName}:using_builtin`);
1593
- }
1594
- }
1595
- catch {
1596
- context.warnings.push(`search_rerank_provider_failed:${context.rerankExtension.providerName}:using_builtin`);
1597
- }
1598
- }
1599
- if (!rerankScores) {
1600
- try {
1601
- rerankScores = await rerankCandidatesWithEmbeddings(context.provider, context.rerank.model, queryTrimmed, rerankCandidates, context.embeddingTimeoutMs);
1602
- }
1603
- catch {
1604
- context.warnings.push("search_rerank_failed:using_hybrid_scores");
1605
- }
1606
- }
1607
- if (rerankScores && rerankScores.size > 0) {
1608
- const rerankedIds = new Set(rerankScores.keys());
1609
- hybridHits = hybridHits.map((hit) => {
1610
- const rerankScore = rerankScores.get(hit.item.id);
1611
- if (rerankScore === undefined) {
1612
- return hit;
1613
- }
1614
- const matchedFields = new Set(hit.matched_fields);
1615
- matchedFields.add("rerank");
1616
- return {
1617
- ...hit,
1618
- score: rerankScore,
1619
- matched_fields: [...matchedFields].sort((left, right) => left.localeCompare(right)),
1620
- };
1621
- });
1622
- hybridHits.sort((left, right) => {
1623
- const leftWasReranked = rerankedIds.has(left.item.id);
1624
- const rightWasReranked = rerankedIds.has(right.item.id);
1625
- if (leftWasReranked !== rightWasReranked) {
1626
- return leftWasReranked ? -1 : 1;
1627
- }
1628
- if (left.score !== right.score) {
1629
- return right.score - left.score;
1630
- }
1631
- return left.item.id.localeCompare(right.item.id);
1632
- });
1633
- }
1634
- }
1647
+ const hybridHits = await applyHybridRerank(context, queryTrimmed, combineHybridHits(filteredById, semanticScores, context.keywordHits, context.hybridSemanticWeight), filteredById);
1635
1648
  return {
1636
1649
  // GH-281: applied LAST (after any rerank reordering) so an exact full-ID /
1637
1650
  // short-ID keyword match always ranks #1 in hybrid mode regardless of the
@@ -1751,14 +1764,15 @@ function projectSearchHits(hits, projection) {
1751
1764
  return projected;
1752
1765
  });
1753
1766
  }
1754
- /**
1755
- * Implements run search for the public runtime surface of this module.
1756
- */
1757
- export async function runSearch(rawQuery, rawOptions, global) {
1758
- // GH-157 inline query syntax: pull `field:value` filter tokens out of the raw
1759
- // query before any other parsing. Explicit flags win — an inline token only
1760
- // applies when its flag is unset, and a conflicting token surfaces as a
1761
- // warning. The residual keyword text drives tokenization/scoring as usual.
1767
+ function resolveQueryExpansionExtension(queryExpansion) {
1768
+ const provider = resolveExtensionSearchProviderByName(queryExpansion.provider ?? undefined);
1769
+ return provider?.queryExpansion ? { providerName: provider.providerName, expand: provider.queryExpansion } : null;
1770
+ }
1771
+ function resolveRerankExtension(settings) {
1772
+ const provider = resolveExtensionSearchProviderByName(toOptionalNonEmptyString(settings.search?.provider));
1773
+ return provider?.rerank ? { providerName: provider.providerName, rerank: provider.rerank } : null;
1774
+ }
1775
+ function prepareSearchInput(rawQuery, rawOptions) {
1762
1776
  const inlineWarnings = [];
1763
1777
  const inlineParse = parseInlineQueryFilters(rawQuery);
1764
1778
  const hasInlineFilters = Object.keys(inlineParse.inlineFilters).length > 0;
@@ -1772,372 +1786,391 @@ export async function runSearch(rawQuery, rawOptions, global) {
1772
1786
  }
1773
1787
  const query = hasInlineFilters ? inlineParse.residualQuery : rawQuery;
1774
1788
  const options = applyInlineQueryFilters(rawOptions, inlineParse.inlineFilters, inlineWarnings);
1775
- const highlight = options.highlight === true;
1776
- const includeLinked = parseIncludeLinked(options.includeLinked);
1777
- const titleExact = parseTitleExact(options.titleExact);
1778
- const phraseExact = parsePhraseExact(options.phraseExact);
1779
- const matchMode = parseMatchMode(typeof options.matchMode === "string" ? options.matchMode : undefined);
1780
- const minScoreOverride = parseMinScoreOverride(options.minScore);
1781
- const countOnly = options.count === true;
1782
- const tokens = parseTokens(query);
1783
- const normalizedQuery = normalizeSearchPhrase(query);
1784
- const limit = parseLimit(options.limit);
1785
- const projection = parseProjectionConfig(options);
1786
- const modeWasExplicit = typeof options.mode === "string" && options.mode.trim().length > 0;
1789
+ return {
1790
+ query,
1791
+ options,
1792
+ inlineWarnings,
1793
+ highlight: options.highlight === true,
1794
+ includeLinked: parseIncludeLinked(options.includeLinked),
1795
+ titleExact: parseTitleExact(options.titleExact),
1796
+ phraseExact: parsePhraseExact(options.phraseExact),
1797
+ matchMode: parseMatchMode(typeof options.matchMode === "string" ? options.matchMode : undefined),
1798
+ minScoreOverride: parseMinScoreOverride(options.minScore),
1799
+ countOnly: options.count === true,
1800
+ tokens: parseTokens(query),
1801
+ normalizedQuery: normalizeSearchPhrase(query),
1802
+ limit: parseLimit(options.limit),
1803
+ projection: parseProjectionConfig(options),
1804
+ modeWasExplicit: typeof options.mode === "string" && options.mode.trim().length > 0,
1805
+ };
1806
+ }
1807
+ async function resolveSearchRuntimeContext(prepared, global) {
1787
1808
  const pmRoot = resolvePmRoot(process.cwd(), global.path);
1788
1809
  if (!(await pathExists(getSettingsPath(pmRoot)))) {
1789
1810
  throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
1790
1811
  }
1791
1812
  const storedSettings = await readSettings(pmRoot);
1792
- const runtimeDefaultsResolution = resolveSettingsWithSemanticRuntimeDefaults(storedSettings);
1793
- const settings = runtimeDefaultsResolution.settings;
1813
+ const settings = resolveSettingsWithSemanticRuntimeDefaults(storedSettings).settings;
1794
1814
  const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
1795
1815
  const runtimeFieldRegistry = resolveRuntimeFieldRegistry(settings.schema);
1796
- validateSearchProjectionFields(projection, runtimeFieldRegistry);
1797
- const runtimeFieldFilters = collectRuntimeFilterValues(options, runtimeFieldRegistry, "search");
1798
- // `pm search --status` resolves strictly (a typo'd status surfaces a
1799
- // did-you-mean hint) so agents can scope retrieval to open work and drop
1800
- // closed-history noise without re-listing. Resolved before the corpus scan so
1801
- // an invalid value fails fast.
1802
- const statusFilter = parseStatusFilterCsv(typeof options.status === "string" ? options.status : undefined, statusRegistry, { strict: true });
1816
+ validateSearchProjectionFields(prepared.projection, runtimeFieldRegistry);
1817
+ const runtimeFieldFilters = collectRuntimeFilterValues(prepared.options, runtimeFieldRegistry, "search");
1803
1818
  const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
1804
- const maxResults = resolveSearchMaxResults(settings);
1805
- // pm-cstl: --min-score overrides the persistent search.score_threshold for this
1806
- // query only; the effective threshold is reflected in filters.score_threshold.
1807
- const scoreThreshold = minScoreOverride ?? resolveSearchScoreThreshold(settings);
1808
- const semanticWeightProvided = options.semanticWeight !== undefined;
1809
- const semanticWeightOverride = parseSemanticWeightOverride(options.semanticWeight);
1810
- const hybridSemanticWeight = semanticWeightOverride ?? resolveHybridSemanticWeight(settings);
1811
- const tuning = resolveSearchTuning(settings);
1812
1819
  const providerResolution = resolveEmbeddingProviders(settings);
1813
1820
  const vectorResolution = resolveVectorStores(settings);
1814
1821
  const extensionSearchProvider = resolveExtensionSearchProvider(settings);
1815
1822
  const extensionVectorAdapter = resolveExtensionVectorAdapter(settings);
1816
- // pm-75k9: offline BM25 lexical provider. When active, a semantic/hybrid query
1817
- // ranks the corpus locally with BM25 instead of requiring an embedding service
1818
- // + vector store — enabling dense-quality offline retrieval in air-gapped, CI,
1819
- // and zero-setup environments. Resolved here so the semantic block can branch.
1820
- const bm25Mode = resolveBuiltInBm25Mode({
1821
- configuredProvider: toOptionalNonEmptyString(settings.search?.provider),
1822
- hasEmbeddingProvider: providerResolution.active !== null,
1823
- hasExtensionSearchProvider: extensionSearchProvider !== null,
1824
- });
1823
+ const semanticWeightOverride = parseSemanticWeightOverride(prepared.options.semanticWeight);
1825
1824
  const queryExpansion = resolveQueryExpansionConfig(settings, providerResolution.active?.name ?? null);
1826
1825
  const rerank = resolveRerankConfig(settings, providerResolution.active?.model ?? toOptionalNonEmptyString(settings.search?.embedding_model) ?? "text-embedding-3-small");
1827
- const queryExpansionProvider = resolveExtensionSearchProviderByName(queryExpansion.provider ?? undefined);
1828
- const queryExpansionExtension = queryExpansionProvider?.queryExpansion
1829
- ? { providerName: queryExpansionProvider.providerName, expand: queryExpansionProvider.queryExpansion }
1830
- : null;
1831
- const rerankProvider = resolveExtensionSearchProviderByName(toOptionalNonEmptyString(settings.search?.provider));
1832
- const rerankExtension = rerankProvider?.rerank
1833
- ? { providerName: rerankProvider.providerName, rerank: rerankProvider.rerank }
1834
- : null;
1835
- let effectiveMode = parseMode(options.mode, {
1836
- hasProvider: providerResolution.active !== null || extensionSearchProvider !== null,
1837
- hasVectorStore: vectorResolution.active !== null || extensionVectorAdapter !== null,
1838
- });
1839
- const loadedDocuments = await loadDocuments(pmRoot, settings.item_format ?? "toon", typeRegistry.type_to_folder, settings.schema);
1840
- const warnings = loadedDocuments.warnings;
1841
- if (inlineWarnings.length > 0) {
1842
- warnings.push(...inlineWarnings);
1826
+ return {
1827
+ pmRoot,
1828
+ settings,
1829
+ statusRegistry,
1830
+ runtimeFieldRegistry,
1831
+ runtimeFieldFilters,
1832
+ typeRegistry,
1833
+ maxResults: resolveSearchMaxResults(settings),
1834
+ scoreThreshold: prepared.minScoreOverride ?? resolveSearchScoreThreshold(settings),
1835
+ semanticWeightProvided: prepared.options.semanticWeight !== undefined,
1836
+ semanticWeightOverride,
1837
+ hybridSemanticWeight: semanticWeightOverride ?? resolveHybridSemanticWeight(settings),
1838
+ tuning: resolveSearchTuning(settings),
1839
+ providerResolution,
1840
+ vectorResolution,
1841
+ extensionSearchProvider,
1842
+ extensionVectorAdapter,
1843
+ bm25Mode: resolveBuiltInBm25Mode({
1844
+ configuredProvider: toOptionalNonEmptyString(settings.search?.provider),
1845
+ hasEmbeddingProvider: providerResolution.active !== null,
1846
+ hasExtensionSearchProvider: extensionSearchProvider !== null,
1847
+ }),
1848
+ queryExpansion,
1849
+ queryExpansionExtension: resolveQueryExpansionExtension(queryExpansion),
1850
+ rerank,
1851
+ rerankExtension: resolveRerankExtension(settings),
1852
+ effectiveMode: parseMode(prepared.options.mode, {
1853
+ hasProvider: providerResolution.active !== null || extensionSearchProvider !== null,
1854
+ hasVectorStore: vectorResolution.active !== null || extensionVectorAdapter !== null,
1855
+ }),
1856
+ };
1857
+ }
1858
+ async function loadFilteredSearchCorpus(prepared, runtime) {
1859
+ const loadedDocuments = await loadDocuments(runtime.pmRoot, runtime.settings.item_format ?? "toon", runtime.typeRegistry.type_to_folder, runtime.settings.schema);
1860
+ const statusFilter = parseStatusFilterCsv(typeof prepared.options.status === "string" ? prepared.options.status : undefined, runtime.statusRegistry, { strict: true });
1861
+ const lifecycleClassifier = lifecycleClassifierFromStatusRegistry(runtime.statusRegistry);
1862
+ const metadataFilteredDocuments = applyFilters(loadedDocuments.documents, prepared.options, runtime.typeRegistry, runtime.runtimeFieldFilters, statusFilter, lifecycleClassifier);
1863
+ return {
1864
+ warnings: loadedDocuments.warnings,
1865
+ allDocuments: loadedDocuments.documents,
1866
+ filteredDocuments: applyExactQueryFilters(metadataFilteredDocuments, prepared.normalizedQuery, {
1867
+ titleExact: prepared.titleExact,
1868
+ phraseExact: prepared.phraseExact || prepared.matchMode === "exact",
1869
+ }),
1870
+ };
1871
+ }
1872
+ async function collectLinkedCorpusById(includeLinked, effectiveMode, filteredDocuments) {
1873
+ const linkedCorpusById = new Map();
1874
+ if (!includeLinked || (effectiveMode !== "keyword" && effectiveMode !== "hybrid")) {
1875
+ return linkedCorpusById;
1843
1876
  }
1844
- if (effectiveMode === "hybrid" && semanticWeightProvided && semanticWeightOverride === undefined) {
1845
- warnings.push("search_hybrid_semantic_weight_override_invalid:using_settings_default");
1877
+ const projectRoot = process.cwd();
1878
+ const linkedCorpusRoots = await resolveLinkedCorpusRoots(projectRoot, resolveGlobalPmRoot(projectRoot));
1879
+ const linkedCorpusEntries = await Promise.all(filteredDocuments.map(async (document) => [document.metadata.id, await loadLinkedCorpus(document, linkedCorpusRoots)]));
1880
+ for (const [id, corpus] of linkedCorpusEntries) {
1881
+ linkedCorpusById.set(id, corpus);
1882
+ }
1883
+ return linkedCorpusById;
1884
+ }
1885
+ async function computeKeywordSearchHits(prepared, runtime, filteredDocuments) {
1886
+ const linkedCorpusById = await collectLinkedCorpusById(prepared.includeLinked, runtime.effectiveMode, filteredDocuments);
1887
+ const applyCoverageBonus = prepared.matchMode === "or";
1888
+ return filteredDocuments
1889
+ .map((document) => buildHybridLexicalScore(document, prepared.tokens, prepared.normalizedQuery, prepared.includeLinked, linkedCorpusById, runtime.tuning, runtime.settings.id_prefix, applyCoverageBonus))
1890
+ .filter((entry) => entry !== null)
1891
+ .filter((entry) => prepared.matchMode !== "and" || entry.matched_all_terms === true);
1892
+ }
1893
+ function buildEmptySearchResultFromContext(response, countOnly) {
1894
+ return emptySearchResult(response.query, response.effectiveMode, response.matchMode, response.options, response.includeLinked, response.scoreThreshold, response.hybridSemanticWeight, response.queryExpansion, response.rerank, response.projection, response.warnings, response.runtimeFieldFilters, countOnly);
1895
+ }
1896
+ async function executeBuiltInBm25Search(prepared, runtime, filteredDocuments, keywordHits, warnings) {
1897
+ if (runtime.bm25Mode === null || runtime.effectiveMode === "keyword") {
1898
+ return null;
1846
1899
  }
1847
- const allDocuments = loadedDocuments.documents;
1848
- const lifecycleClassifier = lifecycleClassifierFromStatusRegistry(statusRegistry);
1849
- const metadataFilteredDocuments = applyFilters(allDocuments, options, typeRegistry, runtimeFieldFilters, statusFilter, lifecycleClassifier);
1850
- const filteredDocuments = applyExactQueryFilters(metadataFilteredDocuments, normalizedQuery, {
1851
- titleExact,
1852
- // --match-mode exact reuses the exact-phrase containment logic so the whole
1853
- // normalized query must appear as a contiguous phrase in some searchable field.
1854
- phraseExact: phraseExact || matchMode === "exact",
1900
+ const hits = computeBuiltInBm25Hits({
1901
+ requestedMode: runtime.effectiveMode,
1902
+ query: prepared.query,
1903
+ filteredDocuments,
1904
+ keywordHits,
1905
+ corpusFields: resolveSearchCorpusFields(runtime.settings),
1906
+ bm25Params: resolveBm25Params(runtime.settings),
1907
+ hybridSemanticWeight: runtime.hybridSemanticWeight,
1855
1908
  });
1856
- if (effectiveMode === "keyword" && (filteredDocuments.length === 0 || limit === 0)) {
1857
- return emptySearchResult(query, effectiveMode, matchMode, options, includeLinked, scoreThreshold, hybridSemanticWeight, queryExpansion, rerank, projection, warnings, runtimeFieldFilters, countOnly);
1909
+ if (runtime.bm25Mode === "auto-fallback") {
1910
+ warnings.push(`search_${runtime.effectiveMode}_offline_bm25:no_embedding_provider:using_lexical_bm25`);
1858
1911
  }
1859
- const projectRoot = process.cwd();
1860
- const globalRoot = resolveGlobalPmRoot(projectRoot);
1861
- const linkedCorpusById = new Map();
1862
- if (includeLinked && (effectiveMode === "keyword" || effectiveMode === "hybrid")) {
1863
- const linkedCorpusRoots = await resolveLinkedCorpusRoots(projectRoot, globalRoot);
1864
- const linkedCorpusEntries = await Promise.all(filteredDocuments.map(async (document) => [document.metadata.id, await loadLinkedCorpus(document, linkedCorpusRoots)]));
1865
- for (const [id, corpus] of linkedCorpusEntries) {
1866
- linkedCorpusById.set(id, corpus);
1912
+ return hits;
1913
+ }
1914
+ async function executeExtensionSearchProvider(prepared, runtime, filteredDocuments, filteredById) {
1915
+ if (!runtime.extensionSearchProvider) {
1916
+ return null;
1917
+ }
1918
+ const canUseBuiltInSemantic = runtime.providerResolution.active !== null &&
1919
+ (runtime.vectorResolution.active !== null || runtime.extensionVectorAdapter !== null);
1920
+ try {
1921
+ const providerResponse = await Promise.resolve(runtime.extensionSearchProvider.query({
1922
+ query: prepared.query,
1923
+ mode: runtime.effectiveMode,
1924
+ tokens: prepared.tokens,
1925
+ options: prepared.options,
1926
+ settings: runtime.settings,
1927
+ documents: filteredDocuments,
1928
+ }));
1929
+ return normalizeExtensionProviderHits(runtime.extensionSearchProvider.providerName, providerResponse, filteredById);
1930
+ }
1931
+ catch (error) {
1932
+ if (!canUseBuiltInSemantic) {
1933
+ throw new PmCliError(`Extension search provider "${runtime.extensionSearchProvider.providerName}" failed: ${error instanceof Error ? error.message : String(error)}`, EXIT_CODE.GENERIC_FAILURE);
1867
1934
  }
1935
+ return null;
1868
1936
  }
1869
- // GH-181: the all-terms coverage RANKING bonus only applies in default OR mode
1870
- // (no hard term filter) so multi-term queries prefer items covering all tokens.
1871
- // and/exact modes hard-filter instead, so the additive bonus would be redundant.
1872
- const applyCoverageBonus = matchMode === "or";
1873
- const keywordHits = filteredDocuments
1874
- .map((document) => buildHybridLexicalScore(document, tokens, normalizedQuery,
1875
- // Linked corpus is only collected into linkedCorpusById when the user
1876
- // passed --include-linked (and mode is keyword/hybrid), so pass the
1877
- // parsed flag directly rather than re-deriving it from the mode.
1878
- includeLinked, linkedCorpusById, tuning, settings.id_prefix, applyCoverageBonus))
1879
- .filter((entry) => entry !== null)
1880
- // --match-mode and: hard-filter to items where EVERY distinct query token
1881
- // matched some searchable field.
1882
- .filter((entry) => matchMode !== "and" || entry.matched_all_terms === true);
1937
+ }
1938
+ function maybeApplyNoVectorFallback(effectiveMode, semanticResult, keywordHits, warnings) {
1939
+ if (semanticResult.vectorMatchCount > 0) {
1940
+ return semanticResult.hits;
1941
+ }
1942
+ warnings.push(`search_${effectiveMode}_degraded:no_vector_matches:results_are_lexical`);
1943
+ return effectiveMode === "semantic" ? keywordHits : semanticResult.hits;
1944
+ }
1945
+ async function prepareBuiltInSemanticSearch(runtime, effectiveMode, filteredDocuments, warnings, modeWasExplicit) {
1946
+ const builtInSemanticWillRun = !runtime.extensionSearchProvider &&
1947
+ runtime.providerResolution.active !== null &&
1948
+ (runtime.vectorResolution.active !== null || runtime.extensionVectorAdapter !== null);
1949
+ if (modeWasExplicit && builtInSemanticWillRun) {
1950
+ await maybeEmitVectorIndexStaleWarning(runtime.pmRoot, filteredDocuments, warnings);
1951
+ }
1952
+ if (!runtime.extensionSearchProvider) {
1953
+ requireSemanticDependencies(effectiveMode, runtime.providerResolution, runtime.vectorResolution, runtime.extensionVectorAdapter !== null);
1954
+ }
1955
+ }
1956
+ async function executeSemanticSearch(input) {
1957
+ const { prepared, runtime, filteredDocuments, keywordHits, warnings, modeWasExplicit } = input;
1883
1958
  let hits = keywordHits;
1884
- // pm-75k9: offline BM25 path. Runs entirely in-process (no embedding service,
1885
- // vector store, or HTTP), so it sits OUTSIDE the semantic try/catch fallback
1886
- // block below it cannot fail on a backend error. Empty corpus / limit-0 are
1887
- // handled by the shared threshold+limit path that follows, so no early-return
1888
- // guard is needed here.
1889
- const useBuiltInBm25 = bm25Mode !== null && effectiveMode !== "keyword";
1890
- if (bm25Mode !== null && effectiveMode !== "keyword") {
1891
- hits = computeBuiltInBm25Hits({
1892
- requestedMode: effectiveMode,
1893
- query,
1894
- filteredDocuments,
1895
- keywordHits,
1896
- corpusFields: resolveSearchCorpusFields(settings),
1897
- bm25Params: resolveBm25Params(settings),
1898
- hybridSemanticWeight,
1899
- });
1900
- if (bm25Mode === "auto-fallback") {
1901
- warnings.push(`search_${effectiveMode}_offline_bm25:no_embedding_provider:using_lexical_bm25`);
1902
- }
1959
+ const bm25Hits = await executeBuiltInBm25Search(prepared, runtime, filteredDocuments, keywordHits, warnings);
1960
+ const semanticMode = runtime.effectiveMode;
1961
+ if (bm25Hits !== null || semanticMode === "keyword") {
1962
+ return { effectiveMode: runtime.effectiveMode, hits: bm25Hits ?? hits };
1903
1963
  }
1904
- /* c8 ignore start -- semantic/provider fallback + compact/count warning-shape permutations are covered by integration command-contract tests */
1905
- if (effectiveMode !== "keyword" && !useBuiltInBm25) {
1906
- // Surface vector-index staleness once per query so agents notice when a
1907
- // refresh is overdue. Only emitted when:
1908
- // (1) the user explicitly asked for semantic/hybrid mode (implicit
1909
- // upgrades fall back silently to keyword on any failure path below
1910
- // and shouldn't carry noise), AND
1911
- // (2) the BUILT-IN semantic path is what will run — an extension search
1912
- // provider has its own indexing lifecycle and the local ledger we
1913
- // read is irrelevant to it.
1914
- const builtInSemanticWillRun = !extensionSearchProvider &&
1915
- providerResolution.active !== null &&
1916
- (vectorResolution.active !== null || extensionVectorAdapter !== null);
1917
- if (modeWasExplicit && builtInSemanticWillRun) {
1918
- await maybeEmitVectorIndexStaleWarning(pmRoot, filteredDocuments, warnings);
1919
- }
1920
- try {
1921
- if (!extensionSearchProvider) {
1922
- requireSemanticDependencies(effectiveMode, providerResolution, vectorResolution, extensionVectorAdapter !== null);
1923
- }
1924
- if (filteredDocuments.length === 0 || limit === 0) {
1925
- return emptySearchResult(query, effectiveMode, matchMode, options, includeLinked, scoreThreshold, hybridSemanticWeight, queryExpansion, rerank, projection, warnings, runtimeFieldFilters, countOnly);
1926
- }
1927
- const filteredById = new Map(filteredDocuments.map((document) => [document.metadata.id, document]));
1928
- const canUseBuiltInSemantic = providerResolution.active !== null && (vectorResolution.active !== null || extensionVectorAdapter !== null);
1929
- if (extensionSearchProvider) {
1930
- try {
1931
- const providerResponse = await Promise.resolve(extensionSearchProvider.query({
1932
- query,
1933
- mode: effectiveMode,
1934
- tokens,
1935
- options,
1936
- settings,
1937
- documents: filteredDocuments,
1938
- }));
1939
- hits = normalizeExtensionProviderHits(extensionSearchProvider.providerName, providerResponse, filteredById);
1940
- }
1941
- catch (error) {
1942
- if (!canUseBuiltInSemantic) {
1943
- throw new PmCliError(`Extension search provider "${extensionSearchProvider.providerName}" failed: ${error instanceof Error ? error.message : String(error)}`, EXIT_CODE.GENERIC_FAILURE);
1944
- }
1945
- }
1946
- }
1947
- if (hits === keywordHits) {
1948
- const implicitHybridMode = !modeWasExplicit && effectiveMode === "hybrid";
1949
- const { provider, vectorStore } = requireSemanticDependencies(effectiveMode, providerResolution, vectorResolution, extensionVectorAdapter !== null);
1950
- const semanticResult = await computeSemanticOrHybridHits({
1951
- requestedMode: effectiveMode,
1952
- query,
1953
- filteredDocuments,
1954
- keywordHits,
1955
- hybridSemanticWeight,
1956
- limit,
1957
- maxResults,
1958
- provider,
1959
- vectorStore,
1960
- extensionVectorAdapter,
1961
- queryExpansion,
1962
- queryExpansionExtension,
1963
- rerank,
1964
- rerankExtension,
1965
- warnings,
1966
- settings,
1967
- /* c8 ignore next 5 -- reserved for future implicit-hybrid auto-mode; current parseMode defaults keyword when mode is omitted */
1968
- ...(implicitHybridMode
1969
- ? {
1970
- embeddingTimeoutMs: IMPLICIT_HYBRID_EMBEDDING_TIMEOUT_MS,
1971
- vectorQueryTimeoutMs: IMPLICIT_HYBRID_VECTOR_TIMEOUT_MS,
1972
- }
1973
- : {}),
1974
- });
1975
- hits = semanticResult.hits;
1976
- // The semantic/hybrid query ran without error, but vector ranking
1977
- // contributed no hits for this query/filter set. Pure semantic mode would
1978
- // otherwise return an empty set, so degrade to the locally computed
1979
- // keyword hits (hybrid already blends them in) and warn so agents do not
1980
- // mistake them for true vector ranking. The reported mode is left
1981
- // unchanged; the warning is the signal.
1982
- if (semanticResult.vectorMatchCount === 0) {
1983
- if (effectiveMode === "semantic") {
1984
- hits = keywordHits;
1985
- }
1986
- warnings.push(`search_${effectiveMode}_degraded:no_vector_matches:results_are_lexical`);
1987
- }
1988
- }
1989
- }
1990
- catch (error) {
1991
- // Any semantic/hybrid attempt that fails (backend down, timeout, or the
1992
- // project is not configured for semantic search) degrades to keyword mode
1993
- // so agents are never blocked. Keyword hits are always computed locally
1994
- // before this point, so the fallback is guaranteed to succeed.
1995
- const fallbackWarning = modeWasExplicit
1996
- ? buildExplicitSemanticFallbackWarning(effectiveMode, error)
1997
- /* c8 ignore next -- reserved for future implicit semantic/hybrid auto-mode fallback */
1998
- : buildImplicitSemanticFallbackWarning(error);
1999
- effectiveMode = "keyword";
2000
- hits = keywordHits;
2001
- warnings.push(fallbackWarning);
1964
+ try {
1965
+ await prepareBuiltInSemanticSearch(runtime, semanticMode, filteredDocuments, warnings, modeWasExplicit);
1966
+ if (filteredDocuments.length === 0 || prepared.limit === 0) {
1967
+ return { effectiveMode: runtime.effectiveMode, hits: [] };
2002
1968
  }
2003
- }
2004
- // GH-281: an exact full-ID / short-ID match is always retained regardless of
2005
- // the (possibly user-raised --min-score) threshold so the exact-target lookup
2006
- // is never silently dropped in any mode.
2007
- const thresholded = hits.filter((entry) => entry.exact_id_match === true || entry.score >= scoreThreshold);
2008
- const sorted = sortHits(thresholded, statusRegistry);
2009
- // total = matched hits after filters + threshold, BEFORE limit truncation.
2010
- const total = sorted.length;
2011
- // GH-181: keyword mode now also falls back to the configured max_results (50)
2012
- // default when --limit is omitted, so a broad query no longer returns ALL hits.
2013
- const resolvedLimit = limit ?? maxResults;
2014
- const limited = sorted.slice(0, resolvedLimit);
2015
- const projectionFields = projection.mode === "full" ? null : [...projection.fields];
2016
- const compactSummaryMode = projection.mode === "compact" && options.compact === true;
2017
- // --count: count-only response. Skips projecting/returning hit rows entirely so
2018
- // an agent asking "how many" pays minimal tokens. `count` carries the matched
2019
- // total (post-filter, post-threshold, pre-limit).
2020
- if (countOnly) {
2021
- if (compactSummaryMode) {
2022
- const compactFilters = buildCompactSearchFilterSummary({
2023
- mode: effectiveMode,
2024
- matchMode,
2025
- options,
2026
- includeLinked,
2027
- titleExact,
2028
- phraseExact,
2029
- scoreThreshold,
2030
- hybridSemanticWeight,
2031
- runtimeFieldFilters,
1969
+ const filteredById = new Map(filteredDocuments.map((document) => [document.metadata.id, document]));
1970
+ hits = await executeExtensionSearchProvider(prepared, runtime, filteredDocuments, filteredById) ?? hits;
1971
+ if (hits === keywordHits) {
1972
+ const { provider, vectorStore } = requireSemanticDependencies(semanticMode, runtime.providerResolution, runtime.vectorResolution, runtime.extensionVectorAdapter !== null);
1973
+ const semanticResult = await computeSemanticOrHybridHits({
1974
+ requestedMode: semanticMode,
1975
+ query: prepared.query,
1976
+ filteredDocuments,
1977
+ keywordHits,
1978
+ hybridSemanticWeight: runtime.hybridSemanticWeight,
1979
+ limit: prepared.limit,
1980
+ maxResults: runtime.maxResults,
1981
+ provider,
1982
+ vectorStore,
1983
+ extensionVectorAdapter: runtime.extensionVectorAdapter,
1984
+ queryExpansion: runtime.queryExpansion,
1985
+ queryExpansionExtension: runtime.queryExpansionExtension,
1986
+ rerank: runtime.rerank,
1987
+ rerankExtension: runtime.rerankExtension,
1988
+ warnings,
1989
+ settings: runtime.settings,
2032
1990
  });
2033
- return {
2034
- query: query.trim(),
2035
- mode: effectiveMode,
2036
- items: [],
2037
- count: total,
2038
- total,
2039
- count_only: true,
2040
- filters: compactFilters,
2041
- ...(warnings.length > 0 ? { warnings } : {}),
2042
- };
1991
+ hits = maybeApplyNoVectorFallback(semanticMode, semanticResult, keywordHits, warnings);
2043
1992
  }
2044
- return {
2045
- query: query.trim(),
2046
- mode: effectiveMode,
1993
+ return { effectiveMode: runtime.effectiveMode, hits };
1994
+ }
1995
+ catch (error) {
1996
+ warnings.push(buildExplicitSemanticFallbackWarning(runtime.effectiveMode, error));
1997
+ return { effectiveMode: "keyword", hits: keywordHits };
1998
+ }
1999
+ }
2000
+ function buildCountOnlySearchResult(response, total) {
2001
+ if (response.projection.mode === "compact" && response.options.compact === true) {
2002
+ return withSearchWarnings({
2003
+ query: response.query.trim(),
2004
+ mode: response.effectiveMode,
2047
2005
  items: [],
2048
2006
  count: total,
2049
2007
  total,
2050
2008
  count_only: true,
2051
- filters: buildVerboseSearchFilters({
2052
- effectiveMode,
2053
- matchMode,
2054
- options,
2055
- includeLinked,
2056
- titleExact,
2057
- phraseExact,
2058
- scoreThreshold,
2059
- hybridSemanticWeight,
2060
- queryExpansion,
2061
- rerank,
2062
- runtimeFieldFilters,
2009
+ filters: buildCompactSearchFilterSummary({
2010
+ mode: response.effectiveMode,
2011
+ matchMode: response.matchMode,
2012
+ options: response.options,
2013
+ includeLinked: response.includeLinked,
2014
+ titleExact: response.titleExact,
2015
+ phraseExact: response.phraseExact,
2016
+ scoreThreshold: response.scoreThreshold,
2017
+ hybridSemanticWeight: response.hybridSemanticWeight,
2018
+ runtimeFieldFilters: response.runtimeFieldFilters,
2063
2019
  }),
2064
- projection: {
2065
- mode: projection.mode,
2066
- fields: projectionFields,
2067
- },
2068
- now: nowIso(),
2069
- ...(warnings.length > 0 ? { warnings } : {}),
2070
- };
2020
+ }, response.warnings);
2071
2021
  }
2072
- // GH-157 --highlight: attach per-field matched-text snippets to the returned
2073
- // page of hits (only the post-limit slice pays the cost). In compact/fields
2074
- // projections we add "highlights" to the projected field set so the snippets
2075
- // are actually emitted; full mode already carries them on the hit.
2076
- let projectedHits = limited;
2077
- let effectiveProjection = projection;
2078
- if (highlight) {
2079
- const documentById = new Map(filteredDocuments.map((document) => [document.metadata.id, document]));
2080
- projectedHits = limited.map((hit) => ({
2081
- ...hit,
2082
- highlights: buildHitHighlights(documentById.get(hit.item.id), hit.matched_fields, tokens),
2083
- }));
2084
- if (projection.mode !== "full" && !projection.fields.includes("highlights")) {
2085
- effectiveProjection = { mode: projection.mode, fields: [...projection.fields, "highlights"] };
2086
- }
2022
+ const projectionFields = response.projection.mode === "full" ? null : [...response.projection.fields];
2023
+ return withSearchWarnings({
2024
+ query: response.query.trim(),
2025
+ mode: response.effectiveMode,
2026
+ items: [],
2027
+ count: total,
2028
+ total,
2029
+ count_only: true,
2030
+ filters: buildVerboseSearchFilters({
2031
+ effectiveMode: response.effectiveMode,
2032
+ matchMode: response.matchMode,
2033
+ options: response.options,
2034
+ includeLinked: response.includeLinked,
2035
+ titleExact: response.titleExact,
2036
+ phraseExact: response.phraseExact,
2037
+ scoreThreshold: response.scoreThreshold,
2038
+ hybridSemanticWeight: response.hybridSemanticWeight,
2039
+ queryExpansion: response.queryExpansion,
2040
+ rerank: response.rerank,
2041
+ runtimeFieldFilters: response.runtimeFieldFilters,
2042
+ }),
2043
+ projection: {
2044
+ mode: response.projection.mode,
2045
+ fields: projectionFields,
2046
+ },
2047
+ now: nowIso(),
2048
+ }, response.warnings);
2049
+ }
2050
+ function withSearchWarnings(result, warnings) {
2051
+ if (warnings.length === 0) {
2052
+ return result;
2087
2053
  }
2088
- const projectedItems = projectSearchHits(projectedHits, effectiveProjection);
2089
- const finalProjectionFields = effectiveProjection.mode === "full" ? null : [...effectiveProjection.fields];
2090
- // Surface the pre-limit total only when the limit actually dropped rows.
2091
- const truncationExtras = limited.length < total ? { total } : {};
2092
- if (compactSummaryMode) {
2093
- const compactFilters = buildCompactSearchFilterSummary({
2094
- mode: effectiveMode,
2095
- matchMode,
2096
- options,
2097
- includeLinked,
2098
- titleExact,
2099
- phraseExact,
2100
- scoreThreshold,
2101
- hybridSemanticWeight,
2102
- runtimeFieldFilters,
2103
- });
2104
- return {
2105
- query: query.trim(),
2106
- mode: effectiveMode,
2054
+ return { ...result, warnings };
2055
+ }
2056
+ function attachSearchHighlights(prepared, filteredDocuments, limited) {
2057
+ if (!prepared.highlight) {
2058
+ return { hits: limited, projection: prepared.projection };
2059
+ }
2060
+ const documentById = new Map(filteredDocuments.map((document) => [document.metadata.id, document]));
2061
+ const hits = limited.map((hit) => ({
2062
+ ...hit,
2063
+ highlights: buildHitHighlights(documentById.get(hit.item.id), hit.matched_fields, prepared.tokens),
2064
+ }));
2065
+ if (prepared.projection.mode === "full" || prepared.projection.fields.includes("highlights")) {
2066
+ return { hits, projection: prepared.projection };
2067
+ }
2068
+ return { hits, projection: { mode: prepared.projection.mode, fields: [...prepared.projection.fields, "highlights"] } };
2069
+ }
2070
+ function buildSearchResultForHits(response, projectedItems, total, limitedCount, effectiveProjection) {
2071
+ const truncationExtras = limitedCount < total ? { total } : {};
2072
+ if (response.projection.mode === "compact" && response.options.compact === true) {
2073
+ return withSearchWarnings({
2074
+ query: response.query.trim(),
2075
+ mode: response.effectiveMode,
2107
2076
  items: projectedItems,
2108
2077
  count: projectedItems.length,
2109
2078
  ...truncationExtras,
2110
- filters: compactFilters,
2111
- ...(warnings.length > 0 ? { warnings } : {}),
2112
- };
2079
+ filters: buildCompactSearchFilterSummary({
2080
+ mode: response.effectiveMode,
2081
+ matchMode: response.matchMode,
2082
+ options: response.options,
2083
+ includeLinked: response.includeLinked,
2084
+ titleExact: response.titleExact,
2085
+ phraseExact: response.phraseExact,
2086
+ scoreThreshold: response.scoreThreshold,
2087
+ hybridSemanticWeight: response.hybridSemanticWeight,
2088
+ runtimeFieldFilters: response.runtimeFieldFilters,
2089
+ }),
2090
+ }, response.warnings);
2113
2091
  }
2114
- /* c8 ignore stop */
2092
+ const finalProjectionFields = effectiveProjection.mode === "full" ? null : [...effectiveProjection.fields];
2115
2093
  return {
2116
- query: query.trim(),
2117
- mode: effectiveMode,
2094
+ query: response.query.trim(),
2095
+ mode: response.effectiveMode,
2118
2096
  items: projectedItems,
2119
2097
  count: projectedItems.length,
2120
2098
  ...truncationExtras,
2121
2099
  filters: buildVerboseSearchFilters({
2122
- effectiveMode,
2123
- matchMode,
2124
- options,
2125
- includeLinked,
2126
- titleExact,
2127
- phraseExact,
2128
- scoreThreshold,
2129
- hybridSemanticWeight,
2130
- queryExpansion,
2131
- rerank,
2132
- runtimeFieldFilters,
2100
+ effectiveMode: response.effectiveMode,
2101
+ matchMode: response.matchMode,
2102
+ options: response.options,
2103
+ includeLinked: response.includeLinked,
2104
+ titleExact: response.titleExact,
2105
+ phraseExact: response.phraseExact,
2106
+ scoreThreshold: response.scoreThreshold,
2107
+ hybridSemanticWeight: response.hybridSemanticWeight,
2108
+ queryExpansion: response.queryExpansion,
2109
+ rerank: response.rerank,
2110
+ runtimeFieldFilters: response.runtimeFieldFilters,
2133
2111
  }),
2134
2112
  projection: {
2135
2113
  mode: effectiveProjection.mode,
2136
2114
  fields: finalProjectionFields,
2137
2115
  },
2138
2116
  now: nowIso(),
2139
- ...(warnings.length > 0 ? { warnings } : {}),
2117
+ ...(response.warnings.length > 0 ? { warnings: response.warnings } : {}),
2140
2118
  };
2141
2119
  }
2120
+ /**
2121
+ * Implements run search for the public runtime surface of this module.
2122
+ */
2123
+ export async function runSearch(rawQuery, rawOptions, global) {
2124
+ const prepared = prepareSearchInput(rawQuery, rawOptions);
2125
+ const runtime = await resolveSearchRuntimeContext(prepared, global);
2126
+ const corpus = await loadFilteredSearchCorpus(prepared, runtime);
2127
+ const warnings = corpus.warnings;
2128
+ warnings.push(...prepared.inlineWarnings);
2129
+ if (runtime.effectiveMode === "hybrid" && runtime.semanticWeightProvided && runtime.semanticWeightOverride === undefined) {
2130
+ warnings.push("search_hybrid_semantic_weight_override_invalid:using_settings_default");
2131
+ }
2132
+ const responseBase = {
2133
+ query: prepared.query,
2134
+ matchMode: prepared.matchMode,
2135
+ options: prepared.options,
2136
+ includeLinked: prepared.includeLinked,
2137
+ titleExact: prepared.titleExact,
2138
+ phraseExact: prepared.phraseExact,
2139
+ scoreThreshold: runtime.scoreThreshold,
2140
+ hybridSemanticWeight: runtime.hybridSemanticWeight,
2141
+ queryExpansion: runtime.queryExpansion,
2142
+ rerank: runtime.rerank,
2143
+ projection: prepared.projection,
2144
+ warnings,
2145
+ runtimeFieldFilters: runtime.runtimeFieldFilters,
2146
+ };
2147
+ if (runtime.effectiveMode === "keyword" && (corpus.filteredDocuments.length === 0 || prepared.limit === 0)) {
2148
+ return buildEmptySearchResultFromContext({ ...responseBase, effectiveMode: runtime.effectiveMode }, prepared.countOnly);
2149
+ }
2150
+ const keywordHits = await computeKeywordSearchHits(prepared, runtime, corpus.filteredDocuments);
2151
+ const modeResult = await executeSemanticSearch({
2152
+ prepared,
2153
+ runtime,
2154
+ filteredDocuments: corpus.filteredDocuments,
2155
+ keywordHits,
2156
+ warnings,
2157
+ modeWasExplicit: prepared.modeWasExplicit,
2158
+ });
2159
+ if (modeResult.effectiveMode !== "keyword" && modeResult.hits.length === 0 && (corpus.filteredDocuments.length === 0 || prepared.limit === 0)) {
2160
+ return buildEmptySearchResultFromContext({ ...responseBase, effectiveMode: modeResult.effectiveMode }, prepared.countOnly);
2161
+ }
2162
+ const thresholded = modeResult.hits.filter((entry) => entry.exact_id_match === true || entry.score >= runtime.scoreThreshold);
2163
+ const sorted = sortHits(thresholded, runtime.statusRegistry);
2164
+ const total = sorted.length;
2165
+ const resolvedLimit = prepared.limit ?? runtime.maxResults;
2166
+ const limited = sorted.slice(0, resolvedLimit);
2167
+ const response = { ...responseBase, effectiveMode: modeResult.effectiveMode };
2168
+ if (prepared.countOnly) {
2169
+ return buildCountOnlySearchResult(response, total);
2170
+ }
2171
+ const { hits: projectedHits, projection: effectiveProjection } = attachSearchHighlights(prepared, corpus.filteredDocuments, limited);
2172
+ const projectedItems = projectSearchHits(projectedHits, effectiveProjection);
2173
+ return buildSearchResultForHits(response, projectedItems, total, limited.length, effectiveProjection);
2174
+ }
2142
2175
  //# sourceMappingURL=search.js.map
2143
- //# debugId=abfd6249-f15e-50a9-867a-69c5d305e97e
2176
+ //# debugId=fe9c6a3a-fb99-53ed-9a6c-8c32bb745364