@unbrained/pm-cli 2026.7.1 → 2026.7.3

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 (625) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/CHANGELOG.md +25 -0
  3. package/CONTRIBUTING.md +2 -2
  4. package/README.md +1 -1
  5. package/dist/cli/commander-usage.d.ts +2 -0
  6. package/dist/cli/commander-usage.js +110 -86
  7. package/dist/cli/commander-usage.js.map +1 -1
  8. package/dist/cli/commands/activity.js +79 -57
  9. package/dist/cli/commands/activity.js.map +1 -1
  10. package/dist/cli/commands/aggregate.js +102 -79
  11. package/dist/cli/commands/aggregate.js.map +1 -1
  12. package/dist/cli/commands/calendar.js +278 -243
  13. package/dist/cli/commands/calendar.js.map +1 -1
  14. package/dist/cli/commands/close-many.js +176 -114
  15. package/dist/cli/commands/close-many.js.map +1 -1
  16. package/dist/cli/commands/close.js +157 -129
  17. package/dist/cli/commands/close.js.map +1 -1
  18. package/dist/cli/commands/comments-audit.js +50 -42
  19. package/dist/cli/commands/comments-audit.js.map +1 -1
  20. package/dist/cli/commands/config.d.ts +2 -0
  21. package/dist/cli/commands/config.js +443 -879
  22. package/dist/cli/commands/config.js.map +1 -1
  23. package/dist/cli/commands/context.js +365 -287
  24. package/dist/cli/commands/context.js.map +1 -1
  25. package/dist/cli/commands/contracts.js +352 -238
  26. package/dist/cli/commands/contracts.js.map +1 -1
  27. package/dist/cli/commands/create.js +32 -17
  28. package/dist/cli/commands/create.js.map +1 -1
  29. package/dist/cli/commands/dedupe-audit.js +46 -39
  30. package/dist/cli/commands/dedupe-audit.js.map +1 -1
  31. package/dist/cli/commands/dedupe-merge.js +88 -69
  32. package/dist/cli/commands/dedupe-merge.js.map +1 -1
  33. package/dist/cli/commands/extension/doctor.js +56 -67
  34. package/dist/cli/commands/extension/doctor.js.map +1 -1
  35. package/dist/cli/commands/extension/shared.js +21 -15
  36. package/dist/cli/commands/extension/shared.js.map +1 -1
  37. package/dist/cli/commands/get.js +114 -81
  38. package/dist/cli/commands/get.js.map +1 -1
  39. package/dist/cli/commands/health.d.ts +17 -0
  40. package/dist/cli/commands/health.js +545 -417
  41. package/dist/cli/commands/health.js.map +1 -1
  42. package/dist/cli/commands/history-compact.js +209 -140
  43. package/dist/cli/commands/history-compact.js.map +1 -1
  44. package/dist/cli/commands/history-redact.js +162 -119
  45. package/dist/cli/commands/history-redact.js.map +1 -1
  46. package/dist/cli/commands/history-repair.js +120 -85
  47. package/dist/cli/commands/history-repair.js.map +1 -1
  48. package/dist/cli/commands/init-agent-guidance.js +32 -19
  49. package/dist/cli/commands/init-agent-guidance.js.map +1 -1
  50. package/dist/cli/commands/init.d.ts +8 -2
  51. package/dist/cli/commands/init.js +263 -162
  52. package/dist/cli/commands/init.js.map +1 -1
  53. package/dist/cli/commands/list.js +152 -102
  54. package/dist/cli/commands/list.js.map +1 -1
  55. package/dist/cli/commands/next.js +60 -40
  56. package/dist/cli/commands/next.js.map +1 -1
  57. package/dist/cli/commands/plan.js +373 -298
  58. package/dist/cli/commands/plan.js.map +1 -1
  59. package/dist/cli/commands/profile.js +23 -15
  60. package/dist/cli/commands/profile.js.map +1 -1
  61. package/dist/cli/commands/recurrence-parsers.js +43 -25
  62. package/dist/cli/commands/recurrence-parsers.js.map +1 -1
  63. package/dist/cli/commands/reindex.d.ts +21 -5
  64. package/dist/cli/commands/reindex.js +345 -205
  65. package/dist/cli/commands/reindex.js.map +1 -1
  66. package/dist/cli/commands/restore.d.ts +8 -7
  67. package/dist/cli/commands/restore.js +105 -69
  68. package/dist/cli/commands/restore.js.map +1 -1
  69. package/dist/cli/commands/schema.js +33 -30
  70. package/dist/cli/commands/schema.js.map +1 -1
  71. package/dist/cli/commands/search.d.ts +10 -2
  72. package/dist/cli/commands/search.js +503 -470
  73. package/dist/cli/commands/search.js.map +1 -1
  74. package/dist/cli/commands/telemetry.js +98 -87
  75. package/dist/cli/commands/telemetry.js.map +1 -1
  76. package/dist/cli/commands/test-all.js +237 -168
  77. package/dist/cli/commands/test-all.js.map +1 -1
  78. package/dist/cli/commands/test.d.ts +6 -5
  79. package/dist/cli/commands/test.js +424 -344
  80. package/dist/cli/commands/test.js.map +1 -1
  81. package/dist/cli/commands/update-many.js +57 -42
  82. package/dist/cli/commands/update-many.js.map +1 -1
  83. package/dist/cli/commands/update.d.ts +1 -1
  84. package/dist/cli/commands/update.js +738 -671
  85. package/dist/cli/commands/update.js.map +1 -1
  86. package/dist/cli/commands/validate.d.ts +20 -1
  87. package/dist/cli/commands/validate.js +478 -343
  88. package/dist/cli/commands/validate.js.map +1 -1
  89. package/dist/cli/error-guidance.js +406 -361
  90. package/dist/cli/error-guidance.js.map +1 -1
  91. package/dist/cli/extension-command-help.js +27 -19
  92. package/dist/cli/extension-command-help.js.map +1 -1
  93. package/dist/cli/help-json-payload.js +57 -49
  94. package/dist/cli/help-json-payload.js.map +1 -1
  95. package/dist/cli/main.d.ts +47 -0
  96. package/dist/cli/main.js +474 -371
  97. package/dist/cli/main.js.map +1 -1
  98. package/dist/cli/migration-gates.js +22 -45
  99. package/dist/cli/migration-gates.js.map +1 -1
  100. package/dist/cli/register-list-query.js +299 -310
  101. package/dist/cli/register-list-query.js.map +1 -1
  102. package/dist/cli/register-mutation.js +763 -779
  103. package/dist/cli/register-mutation.js.map +1 -1
  104. package/dist/cli/register-operations.js +386 -362
  105. package/dist/cli/register-operations.js.map +1 -1
  106. package/dist/cli/register-setup.js +120 -101
  107. package/dist/cli/register-setup.js.map +1 -1
  108. package/dist/cli/registration-helpers.d.ts +4 -0
  109. package/dist/cli/registration-helpers.js +45 -56
  110. package/dist/cli/registration-helpers.js.map +1 -1
  111. package/dist/cli-bundle/chunks/{activity-DBLQVIP6.js → activity-5YWLSPGE.js} +9 -9
  112. package/dist/cli-bundle/chunks/activity-BIML7K2D.js +16 -0
  113. package/dist/cli-bundle/chunks/{aggregate-SDF7DUOD.js → aggregate-2V2M3JZU.js} +107 -83
  114. package/dist/cli-bundle/chunks/{aggregate-SDF7DUOD.js.map → aggregate-2V2M3JZU.js.map} +2 -2
  115. package/dist/cli-bundle/chunks/{aggregate-JTEF4BP7.js → aggregate-EK7DXML7.js} +108 -84
  116. package/dist/cli-bundle/chunks/aggregate-EK7DXML7.js.map +1 -0
  117. package/dist/cli-bundle/chunks/{append-LOVPGVPT.js → append-EZESUVJT.js} +8 -8
  118. package/dist/cli-bundle/chunks/{append-QCFJSDFL.js → append-JFG4WQMG.js} +8 -8
  119. package/dist/cli-bundle/chunks/{chunk-TP5Q5ZD3.js → chunk-32IUNTG4.js} +158 -119
  120. package/dist/cli-bundle/chunks/chunk-32IUNTG4.js.map +1 -0
  121. package/dist/cli-bundle/chunks/{chunk-BHO33VBQ.js → chunk-3W2HJKJX.js} +3 -3
  122. package/dist/cli-bundle/chunks/{chunk-VARHOHYV.js → chunk-4EXFFP7T.js} +86 -52
  123. package/dist/cli-bundle/chunks/chunk-4EXFFP7T.js.map +7 -0
  124. package/dist/cli-bundle/chunks/{chunk-4DUVCVLZ.js → chunk-4PFVUUYV.js} +2 -2
  125. package/dist/cli-bundle/chunks/{chunk-JSU5P7VS.js → chunk-4WB6S4YX.js} +308 -184
  126. package/dist/cli-bundle/chunks/chunk-4WB6S4YX.js.map +1 -0
  127. package/dist/cli-bundle/chunks/{chunk-HXTQJXWT.js → chunk-572FKBRL.js} +61 -102
  128. package/dist/cli-bundle/chunks/chunk-572FKBRL.js.map +1 -0
  129. package/dist/cli-bundle/chunks/{chunk-IJYK2T43.js → chunk-5E7N4T2Z.js} +2 -2
  130. package/dist/cli-bundle/chunks/{chunk-NKZAN7BD.js → chunk-5IZUBZBR.js} +3 -3
  131. package/dist/cli-bundle/chunks/{chunk-NOLPZMSV.js → chunk-5JIWFWOZ.js} +2 -2
  132. package/dist/cli-bundle/chunks/{chunk-FFMQB7WR.js → chunk-67LARBDL.js} +493 -404
  133. package/dist/cli-bundle/chunks/chunk-67LARBDL.js.map +1 -0
  134. package/dist/cli-bundle/chunks/{chunk-6AQZPVHQ.js → chunk-6CDCWKSX.js} +4 -4
  135. package/dist/cli-bundle/chunks/{chunk-3K2M5OYU.js → chunk-6KRFL33E.js} +308 -184
  136. package/dist/cli-bundle/chunks/chunk-6KRFL33E.js.map +7 -0
  137. package/dist/cli-bundle/chunks/{chunk-LB6TP6MC.js → chunk-6NYJGMTY.js} +2 -2
  138. package/dist/cli-bundle/chunks/{chunk-SLMUGTK3.js → chunk-7CLLC75T.js} +4 -4
  139. package/dist/cli-bundle/chunks/{chunk-2466X6E4.js → chunk-7LYO6S5A.js} +8 -8
  140. package/dist/cli-bundle/chunks/{chunk-W4ULYO7Z.js → chunk-A3OQ7TFW.js} +8 -8
  141. package/dist/cli-bundle/chunks/{chunk-5CGRF3L5.js → chunk-AIKU3IIL.js} +153 -90
  142. package/dist/cli-bundle/chunks/chunk-AIKU3IIL.js.map +1 -0
  143. package/dist/cli-bundle/chunks/{chunk-WYDHYJPO.js → chunk-AJHYQCBJ.js} +39 -5
  144. package/dist/cli-bundle/chunks/chunk-AJHYQCBJ.js.map +7 -0
  145. package/dist/cli-bundle/chunks/{chunk-VZDBVEZR.js → chunk-B4O5S7I3.js} +79 -57
  146. package/dist/cli-bundle/chunks/{chunk-VZDBVEZR.js.map → chunk-B4O5S7I3.js.map} +2 -2
  147. package/dist/cli-bundle/chunks/{chunk-OTUHB4HS.js → chunk-BE2SR6QL.js} +92 -77
  148. package/dist/cli-bundle/chunks/chunk-BE2SR6QL.js.map +1 -0
  149. package/dist/cli-bundle/chunks/{chunk-JLM7BHI7.js → chunk-BI4R7HI2.js} +75 -53
  150. package/dist/cli-bundle/chunks/chunk-BI4R7HI2.js.map +7 -0
  151. package/dist/cli-bundle/chunks/{chunk-AXIDKKAT.js → chunk-CXR3CMBQ.js} +33 -6
  152. package/dist/cli-bundle/chunks/chunk-CXR3CMBQ.js.map +1 -0
  153. package/dist/cli-bundle/chunks/{chunk-ZETXE4SE.js → chunk-ECU6MMTQ.js} +713 -613
  154. package/dist/cli-bundle/chunks/chunk-ECU6MMTQ.js.map +1 -0
  155. package/dist/cli-bundle/chunks/{chunk-2D4HATP2.js → chunk-EJ2OCBHF.js} +54 -30
  156. package/dist/cli-bundle/chunks/chunk-EJ2OCBHF.js.map +1 -0
  157. package/dist/cli-bundle/chunks/{chunk-BDTISOSD.js → chunk-EQURFOMH.js} +41 -26
  158. package/dist/cli-bundle/chunks/chunk-EQURFOMH.js.map +7 -0
  159. package/dist/cli-bundle/chunks/{chunk-GJ326ZKX.js → chunk-ER4ME5U2.js} +3 -3
  160. package/dist/cli-bundle/chunks/{chunk-HZZEHPRG.js → chunk-ERG65A2L.js} +2 -2
  161. package/dist/cli-bundle/chunks/{chunk-IZBR4NRW.js → chunk-F6WNBITZ.js} +157 -113
  162. package/dist/cli-bundle/chunks/chunk-F6WNBITZ.js.map +7 -0
  163. package/dist/cli-bundle/chunks/{chunk-L5OEFZQG.js → chunk-FH2H3CBD.js} +3 -3
  164. package/dist/cli-bundle/chunks/{chunk-JPECA746.js → chunk-FUFFPIYA.js} +2 -2
  165. package/dist/cli-bundle/chunks/{chunk-CF7RL6FR.js → chunk-FZJM2TXF.js} +110 -73
  166. package/dist/cli-bundle/chunks/chunk-FZJM2TXF.js.map +1 -0
  167. package/dist/cli-bundle/chunks/{chunk-27BXPBAY.js → chunk-GUYNUXQT.js} +3 -3
  168. package/dist/cli-bundle/chunks/{chunk-MAUKX7JC.js → chunk-GVJE5T7Q.js} +2 -2
  169. package/dist/cli-bundle/chunks/{chunk-3J6JRJ3I.js → chunk-HB4FAT3O.js} +42 -60
  170. package/dist/cli-bundle/chunks/chunk-HB4FAT3O.js.map +7 -0
  171. package/dist/cli-bundle/chunks/{chunk-55SNVXRQ.js → chunk-HQAF23Q2.js} +626 -484
  172. package/dist/cli-bundle/chunks/chunk-HQAF23Q2.js.map +7 -0
  173. package/dist/cli-bundle/chunks/{chunk-ZRP4VG5U.js → chunk-JBZ2NTKX.js} +2 -2
  174. package/dist/cli-bundle/chunks/{chunk-RMMQ74TG.js → chunk-JPATY4SE.js} +54 -30
  175. package/dist/cli-bundle/chunks/chunk-JPATY4SE.js.map +7 -0
  176. package/dist/cli-bundle/chunks/{chunk-IPYBJWTE.js → chunk-K5DT2YKM.js} +109 -72
  177. package/dist/cli-bundle/chunks/chunk-K5DT2YKM.js.map +7 -0
  178. package/dist/cli-bundle/chunks/{chunk-EJUDVUYZ.js → chunk-KEZOIPCR.js} +3 -3
  179. package/dist/cli-bundle/chunks/{chunk-RVUALSJF.js → chunk-KHVGM5CS.js} +466 -365
  180. package/dist/cli-bundle/chunks/chunk-KHVGM5CS.js.map +7 -0
  181. package/dist/cli-bundle/chunks/{chunk-YITK2PJ6.js → chunk-KS6ATO47.js} +288 -175
  182. package/dist/cli-bundle/chunks/chunk-KS6ATO47.js.map +7 -0
  183. package/dist/cli-bundle/chunks/{chunk-7R4QEMZZ.js → chunk-L4SLHV6G.js} +463 -362
  184. package/dist/cli-bundle/chunks/chunk-L4SLHV6G.js.map +1 -0
  185. package/dist/cli-bundle/chunks/{chunk-RLDHZHQS.js → chunk-LBE5QFMZ.js} +158 -114
  186. package/dist/cli-bundle/chunks/chunk-LBE5QFMZ.js.map +1 -0
  187. package/dist/cli-bundle/chunks/{chunk-22WKIL3H.js → chunk-LCWQP6NM.js} +76 -54
  188. package/dist/cli-bundle/chunks/chunk-LCWQP6NM.js.map +1 -0
  189. package/dist/cli-bundle/chunks/{chunk-KNPEF7QG.js → chunk-LOWVNZBZ.js} +91 -76
  190. package/dist/cli-bundle/chunks/chunk-LOWVNZBZ.js.map +7 -0
  191. package/dist/cli-bundle/chunks/{chunk-HYTGA6GI.js → chunk-MDHWWBNZ.js} +3 -3
  192. package/dist/cli-bundle/chunks/{chunk-N74UMG5H.js → chunk-MEZZZBYX.js} +2 -2
  193. package/dist/cli-bundle/chunks/{chunk-V3NOKJF2.js → chunk-MHRS5FUX.js} +288 -175
  194. package/dist/cli-bundle/chunks/chunk-MHRS5FUX.js.map +1 -0
  195. package/dist/cli-bundle/chunks/{chunk-3XZCOZ5J.js → chunk-NOIEVOK5.js} +391 -313
  196. package/dist/cli-bundle/chunks/chunk-NOIEVOK5.js.map +1 -0
  197. package/dist/cli-bundle/chunks/{chunk-SDR5J34Q.js → chunk-NZ7QIUP5.js} +4 -4
  198. package/dist/cli-bundle/chunks/{chunk-UYUYDGIB.js → chunk-OGLGI22K.js} +115 -67
  199. package/dist/cli-bundle/chunks/{chunk-UYUYDGIB.js.map → chunk-OGLGI22K.js.map} +1 -1
  200. package/dist/cli-bundle/chunks/{chunk-DDPTYJIM.js → chunk-P5L7Z2O6.js} +2 -2
  201. package/dist/cli-bundle/chunks/{chunk-BZCEN4JA.js → chunk-PULUSQAV.js} +492 -403
  202. package/dist/cli-bundle/chunks/chunk-PULUSQAV.js.map +7 -0
  203. package/dist/cli-bundle/chunks/{chunk-3VGN2UWE.js → chunk-QCDTQCMW.js} +22 -30
  204. package/dist/cli-bundle/chunks/chunk-QCDTQCMW.js.map +1 -0
  205. package/dist/cli-bundle/chunks/{chunk-4A3BJ675.js → chunk-QNNQAAZ5.js} +24 -18
  206. package/dist/cli-bundle/chunks/{chunk-4A3BJ675.js.map → chunk-QNNQAAZ5.js.map} +1 -1
  207. package/dist/cli-bundle/chunks/{chunk-MDPEOIGN.js → chunk-RAHINBVP.js} +60 -101
  208. package/dist/cli-bundle/chunks/chunk-RAHINBVP.js.map +7 -0
  209. package/dist/cli-bundle/chunks/{chunk-CWFNTKQJ.js → chunk-RJH5VQHW.js} +43 -61
  210. package/dist/cli-bundle/chunks/chunk-RJH5VQHW.js.map +1 -0
  211. package/dist/cli-bundle/chunks/{chunk-OGXLACHC.js → chunk-SU2E4AWU.js} +6 -6
  212. package/dist/cli-bundle/chunks/{chunk-HPPFYYOV.js → chunk-SU3TB4NS.js} +2 -2
  213. package/dist/cli-bundle/chunks/{chunk-JWXRETDF.js → chunk-SYE6WMV6.js} +626 -484
  214. package/dist/cli-bundle/chunks/chunk-SYE6WMV6.js.map +1 -0
  215. package/dist/cli-bundle/chunks/{chunk-NWMZWYYB.js → chunk-T3P7PMZP.js} +42 -27
  216. package/dist/cli-bundle/chunks/chunk-T3P7PMZP.js.map +1 -0
  217. package/dist/cli-bundle/chunks/{chunk-G7I7DEZA.js → chunk-T4XBKJ3F.js} +4 -4
  218. package/dist/cli-bundle/chunks/{chunk-RH5ZBYFD.js → chunk-T6AXEBOP.js} +23 -17
  219. package/dist/cli-bundle/chunks/{chunk-RH5ZBYFD.js.map → chunk-T6AXEBOP.js.map} +2 -2
  220. package/dist/cli-bundle/chunks/{chunk-5QFDBI4F.js → chunk-TQ6AX5SQ.js} +58 -69
  221. package/dist/cli-bundle/chunks/{chunk-5QFDBI4F.js.map → chunk-TQ6AX5SQ.js.map} +2 -2
  222. package/dist/cli-bundle/chunks/{chunk-4XOIEKSD.js → chunk-U3S2B7TA.js} +86 -52
  223. package/dist/cli-bundle/chunks/chunk-U3S2B7TA.js.map +1 -0
  224. package/dist/cli-bundle/chunks/{chunk-VICZWYGZ.js → chunk-U5TR4N7J.js} +7 -7
  225. package/dist/cli-bundle/chunks/{chunk-EVMTBV6V.js → chunk-UMNQZS4H.js} +3 -3
  226. package/dist/cli-bundle/chunks/{chunk-A7FPBAQS.js → chunk-WJA3PXW7.js} +7 -7
  227. package/dist/cli-bundle/chunks/{chunk-RGEMWD6Q.js → chunk-WRYERRZX.js} +157 -118
  228. package/dist/cli-bundle/chunks/chunk-WRYERRZX.js.map +7 -0
  229. package/dist/cli-bundle/chunks/{chunk-NUHHPVVS.js → chunk-WYOIIFSE.js} +712 -612
  230. package/dist/cli-bundle/chunks/chunk-WYOIIFSE.js.map +7 -0
  231. package/dist/cli-bundle/chunks/{chunk-4DSGXSBL.js → chunk-XRYSCRZR.js} +116 -68
  232. package/dist/cli-bundle/chunks/{chunk-4DSGXSBL.js.map → chunk-XRYSCRZR.js.map} +3 -3
  233. package/dist/cli-bundle/chunks/{chunk-NU2UEROZ.js → chunk-YF746GTH.js} +59 -70
  234. package/dist/cli-bundle/chunks/{chunk-NU2UEROZ.js.map → chunk-YF746GTH.js.map} +1 -1
  235. package/dist/cli-bundle/chunks/{chunk-JMP4E6D7.js → chunk-YPWUSH72.js} +390 -312
  236. package/dist/cli-bundle/chunks/{chunk-JMP4E6D7.js.map → chunk-YPWUSH72.js.map} +2 -2
  237. package/dist/cli-bundle/chunks/{chunk-QCWF6IYD.js → chunk-YSDFIY7N.js} +3 -3
  238. package/dist/cli-bundle/chunks/{chunk-UZIWVBE6.js → chunk-YSGTMDWC.js} +2 -2
  239. package/dist/cli-bundle/chunks/{chunk-NFDPYAIP.js → chunk-YVKZ3ANP.js} +21 -29
  240. package/dist/cli-bundle/chunks/chunk-YVKZ3ANP.js.map +7 -0
  241. package/dist/cli-bundle/chunks/{chunk-OKQ22KTH.js → chunk-Z4DGFQDH.js} +80 -58
  242. package/dist/cli-bundle/chunks/{chunk-OKQ22KTH.js.map → chunk-Z4DGFQDH.js.map} +1 -1
  243. package/dist/cli-bundle/chunks/{chunk-64HNBBFQ.js → chunk-Z5F6XZXE.js} +6 -6
  244. package/dist/cli-bundle/chunks/{chunk-AVEE5EHK.js → chunk-Z7RPDF2Y.js} +3 -3
  245. package/dist/cli-bundle/chunks/{chunk-3S2KT7NG.js → chunk-ZFTKYWIF.js} +152 -89
  246. package/dist/cli-bundle/chunks/chunk-ZFTKYWIF.js.map +7 -0
  247. package/dist/cli-bundle/chunks/{claim-T3GCKV7C.js → claim-2BGBGSVI.js} +8 -8
  248. package/dist/cli-bundle/chunks/{claim-EMQLYPRW.js → claim-5GU7OE67.js} +8 -8
  249. package/dist/cli-bundle/chunks/close-6YODBUIV.js +14 -0
  250. package/dist/cli-bundle/chunks/{close-TQYAAFJP.js → close-AFVKPR57.js} +7 -7
  251. package/dist/cli-bundle/chunks/{close-many-BG5QQIDQ.js → close-many-7KLOSYLP.js} +186 -122
  252. package/dist/cli-bundle/chunks/close-many-7KLOSYLP.js.map +7 -0
  253. package/dist/cli-bundle/chunks/{close-many-LDRVEQY2.js → close-many-JKUJMHLG.js} +187 -123
  254. package/dist/cli-bundle/chunks/close-many-JKUJMHLG.js.map +1 -0
  255. package/dist/cli-bundle/chunks/{comments-YUXJRZPQ.js → comments-DNWHEBOS.js} +9 -9
  256. package/dist/cli-bundle/chunks/{comments-QCKR2YY2.js → comments-RW23R3VE.js} +9 -9
  257. package/dist/cli-bundle/chunks/config-AUM5WBYA.js +1072 -0
  258. package/dist/cli-bundle/chunks/config-AUM5WBYA.js.map +7 -0
  259. package/dist/cli-bundle/chunks/config-OZWSA2NP.js +1062 -0
  260. package/dist/cli-bundle/chunks/config-OZWSA2NP.js.map +1 -0
  261. package/dist/cli-bundle/chunks/{context-B6275WPX.js → context-OYXRGY7S.js} +12 -12
  262. package/dist/cli-bundle/chunks/{context-OCZ3FJ4Z.js → context-PKCEHQY3.js} +12 -12
  263. package/dist/cli-bundle/chunks/{contracts-HN7ABKLP.js → contracts-L6ODXNUM.js} +320 -199
  264. package/dist/cli-bundle/chunks/contracts-L6ODXNUM.js.map +7 -0
  265. package/dist/cli-bundle/chunks/{contracts-W4FZVVD6.js → contracts-X74F2GSM.js} +321 -200
  266. package/dist/cli-bundle/chunks/contracts-X74F2GSM.js.map +1 -0
  267. package/dist/cli-bundle/chunks/{copy-DEM4DATS.js → copy-6XOR3HKN.js} +5 -5
  268. package/dist/cli-bundle/chunks/{copy-BTJOSKKT.js → copy-I4NCLBR4.js} +5 -5
  269. package/dist/cli-bundle/chunks/{create-RLRJMRTM.js → create-PM45M6PE.js} +12 -12
  270. package/dist/cli-bundle/chunks/create-Z7YCH3BE.js +28 -0
  271. package/dist/cli-bundle/chunks/{delete-BHK7VB2Z.js → delete-7YXHYG67.js} +5 -5
  272. package/dist/cli-bundle/chunks/{delete-LSVHAB4Y.js → delete-LPISP43T.js} +5 -5
  273. package/dist/cli-bundle/chunks/{deps-XHYXWEPT.js → deps-N2T26FME.js} +5 -5
  274. package/dist/cli-bundle/chunks/{deps-4UDFJRUA.js → deps-WATKQDE3.js} +5 -5
  275. package/dist/cli-bundle/chunks/{docs-GYZNVS26.js → docs-6LQ3GLM7.js} +7 -7
  276. package/dist/cli-bundle/chunks/{docs-26S44RXU.js → docs-Z3X6JZLT.js} +7 -7
  277. package/dist/cli-bundle/chunks/{eval-UYF3ZPVO.js → eval-6DCLG52D.js} +10 -10
  278. package/dist/cli-bundle/chunks/{eval-PGRVIJQU.js → eval-Y3ZCUTHK.js} +10 -10
  279. package/dist/cli-bundle/chunks/{extension-CPSLJQVE.js → extension-BNINIMT7.js} +11 -11
  280. package/dist/cli-bundle/chunks/{extension-CXJ6RELI.js → extension-QWE4YYK5.js} +11 -11
  281. package/dist/cli-bundle/chunks/{files-NQHEXUZD.js → files-6SGKHS6O.js} +7 -7
  282. package/dist/cli-bundle/chunks/{files-MBNICQFM.js → files-FUYPSOFJ.js} +7 -7
  283. package/dist/cli-bundle/chunks/{focus-DWYIG7GU.js → focus-2Q3K76G2.js} +6 -6
  284. package/dist/cli-bundle/chunks/{focus-XZW5423D.js → focus-ATLBWXXD.js} +6 -6
  285. package/dist/cli-bundle/chunks/{gc-LPVMKJQJ.js → gc-RUYEMNRF.js} +3 -3
  286. package/dist/cli-bundle/chunks/{gc-7GQYOS2G.js → gc-TDWSDR66.js} +3 -3
  287. package/dist/cli-bundle/chunks/{get-A7MAOHCU.js → get-2WGLX74N.js} +120 -80
  288. package/dist/cli-bundle/chunks/get-2WGLX74N.js.map +7 -0
  289. package/dist/cli-bundle/chunks/{get-DSDEKJ3L.js → get-LY6M2JIM.js} +121 -81
  290. package/dist/cli-bundle/chunks/get-LY6M2JIM.js.map +1 -0
  291. package/dist/cli-bundle/chunks/{health-3IPFLKXB.js → health-4RKHYS3T.js} +535 -371
  292. package/dist/cli-bundle/chunks/health-4RKHYS3T.js.map +1 -0
  293. package/dist/cli-bundle/chunks/{health-GZXGBZ36.js → health-TMFVNYRA.js} +534 -370
  294. package/dist/cli-bundle/chunks/health-TMFVNYRA.js.map +7 -0
  295. package/dist/cli-bundle/chunks/history-CGNQJXFE.js +18 -0
  296. package/dist/cli-bundle/chunks/{history-NERDJNUB.js → history-SGRRS72R.js} +8 -8
  297. package/dist/cli-bundle/chunks/{history-compact-2WRZ2WK4.js → history-compact-LOED43R3.js} +213 -134
  298. package/dist/cli-bundle/chunks/history-compact-LOED43R3.js.map +7 -0
  299. package/dist/cli-bundle/chunks/{history-compact-HR7BB4LR.js → history-compact-V5DNAQHH.js} +214 -135
  300. package/dist/cli-bundle/chunks/history-compact-V5DNAQHH.js.map +1 -0
  301. package/dist/cli-bundle/chunks/{history-redact-O3NBCNWC.js → history-redact-IRL7WJ3E.js} +9 -9
  302. package/dist/cli-bundle/chunks/history-redact-N3JK7VBW.js +19 -0
  303. package/dist/cli-bundle/chunks/{history-repair-XA3LC4GA.js → history-repair-4WVBVHFR.js} +124 -84
  304. package/dist/cli-bundle/chunks/history-repair-4WVBVHFR.js.map +1 -0
  305. package/dist/cli-bundle/chunks/{history-repair-LCMOS45X.js → history-repair-PGYQJMGD.js} +123 -83
  306. package/dist/cli-bundle/chunks/history-repair-PGYQJMGD.js.map +7 -0
  307. package/dist/cli-bundle/chunks/{init-64XDLQJB.js → init-4GESW7RM.js} +12 -12
  308. package/dist/cli-bundle/chunks/init-XIDPABA4.js +22 -0
  309. package/dist/cli-bundle/chunks/{learnings-LPKCSJX7.js → learnings-4BHWFFUV.js} +9 -9
  310. package/dist/cli-bundle/chunks/{learnings-JR6MA5TI.js → learnings-4FJY7WIW.js} +9 -9
  311. package/dist/cli-bundle/chunks/{list-G5Y65VF6.js → list-472TIOVK.js} +8 -8
  312. package/dist/cli-bundle/chunks/{list-DNBJVO3E.js → list-D7BF5CL2.js} +8 -8
  313. package/dist/cli-bundle/chunks/{next-FYTQF6HG.js → next-D5STGWI2.js} +71 -46
  314. package/dist/cli-bundle/chunks/next-D5STGWI2.js.map +1 -0
  315. package/dist/cli-bundle/chunks/{next-BCERKDUR.js → next-SFQZVX2B.js} +70 -45
  316. package/dist/cli-bundle/chunks/next-SFQZVX2B.js.map +7 -0
  317. package/dist/cli-bundle/chunks/{notes-2BMU3VVQ.js → notes-6KNOSLIT.js} +9 -9
  318. package/dist/cli-bundle/chunks/{notes-6KTGO2OJ.js → notes-W4UEICGF.js} +9 -9
  319. package/dist/cli-bundle/chunks/{plan-RKZHQVXR.js → plan-JO6V7BXO.js} +373 -279
  320. package/dist/cli-bundle/chunks/plan-JO6V7BXO.js.map +1 -0
  321. package/dist/cli-bundle/chunks/{plan-4WXEQCTN.js → plan-MJQW5XK3.js} +372 -278
  322. package/dist/cli-bundle/chunks/plan-MJQW5XK3.js.map +7 -0
  323. package/dist/cli-bundle/chunks/{profile-4OMM32CD.js → profile-3TOTMUR4.js} +27 -19
  324. package/dist/cli-bundle/chunks/profile-3TOTMUR4.js.map +7 -0
  325. package/dist/cli-bundle/chunks/{profile-QLER5ENE.js → profile-WIQY2KCV.js} +28 -20
  326. package/dist/cli-bundle/chunks/profile-WIQY2KCV.js.map +1 -0
  327. package/dist/cli-bundle/chunks/register-list-query-ELBHCCFI.js +416 -0
  328. package/dist/cli-bundle/chunks/register-list-query-ELBHCCFI.js.map +7 -0
  329. package/dist/cli-bundle/chunks/register-list-query-GAPQ6DM3.js +406 -0
  330. package/dist/cli-bundle/chunks/register-list-query-GAPQ6DM3.js.map +1 -0
  331. package/dist/cli-bundle/chunks/{register-mutation-KK7PHYYU.js → register-mutation-ROFE2YPC.js} +729 -702
  332. package/dist/cli-bundle/chunks/register-mutation-ROFE2YPC.js.map +7 -0
  333. package/dist/cli-bundle/chunks/{register-mutation-ENNDUAZG.js → register-mutation-SJWMVIJ2.js} +730 -703
  334. package/dist/cli-bundle/chunks/register-mutation-SJWMVIJ2.js.map +1 -0
  335. package/dist/cli-bundle/chunks/{register-operations-HZ6XERQG.js → register-operations-IADFVH53.js} +389 -365
  336. package/dist/cli-bundle/chunks/register-operations-IADFVH53.js.map +7 -0
  337. package/dist/cli-bundle/chunks/register-operations-MEKU3AKC.js +510 -0
  338. package/dist/cli-bundle/chunks/register-operations-MEKU3AKC.js.map +1 -0
  339. package/dist/cli-bundle/chunks/{register-setup-ZKJ53RS7.js → register-setup-3QJY43CY.js} +128 -103
  340. package/dist/cli-bundle/chunks/register-setup-3QJY43CY.js.map +7 -0
  341. package/dist/cli-bundle/chunks/{register-setup-P67EMBDJ.js → register-setup-AJWUSSQX.js} +129 -104
  342. package/dist/cli-bundle/chunks/register-setup-AJWUSSQX.js.map +1 -0
  343. package/dist/cli-bundle/chunks/{restore-4MHZFJ2E.js → restore-44IHMMZZ.js} +9 -9
  344. package/dist/cli-bundle/chunks/restore-EXHU34EU.js +17 -0
  345. package/dist/cli-bundle/chunks/{scheduling-shortcuts-LB6DOLRL.js → scheduling-shortcuts-OLHNLAZY.js} +12 -12
  346. package/dist/cli-bundle/chunks/{scheduling-shortcuts-UTOYKLXQ.js → scheduling-shortcuts-TSBK4AY5.js} +12 -12
  347. package/dist/cli-bundle/chunks/{schema-73HR2OJW.js → schema-IB2NZZWD.js} +7 -7
  348. package/dist/cli-bundle/chunks/{schema-U6LJKSIR.js → schema-VBCELP5G.js} +7 -7
  349. package/dist/cli-bundle/chunks/{search-AXPXKZER.js → search-7UBETML4.js} +10 -10
  350. package/dist/cli-bundle/chunks/{search-KILGT37L.js → search-R227JOL6.js} +10 -10
  351. package/dist/cli-bundle/chunks/{stats-W5KNVJWQ.js → stats-FAG7COEH.js} +6 -6
  352. package/dist/cli-bundle/chunks/{stats-PSYVVTNZ.js → stats-MCK7PLYS.js} +6 -6
  353. package/dist/cli-bundle/chunks/{telemetry-GAHHQTOS.js → telemetry-DRPDZMAO.js} +84 -70
  354. package/dist/cli-bundle/chunks/telemetry-DRPDZMAO.js.map +7 -0
  355. package/dist/cli-bundle/chunks/{telemetry-BZUF6H7G.js → telemetry-GVVUQSJQ.js} +85 -71
  356. package/dist/cli-bundle/chunks/telemetry-GVVUQSJQ.js.map +1 -0
  357. package/dist/cli-bundle/chunks/{test-PWDIZ255.js → test-QY44WAMR.js} +15 -15
  358. package/dist/cli-bundle/chunks/{test-ACD52Z3S.js → test-SY76DZTO.js} +15 -15
  359. package/dist/cli-bundle/chunks/test-all-QD6QAEG7.js +430 -0
  360. package/dist/cli-bundle/chunks/test-all-QD6QAEG7.js.map +7 -0
  361. package/dist/cli-bundle/chunks/test-all-USPJHXFR.js +427 -0
  362. package/dist/cli-bundle/chunks/test-all-USPJHXFR.js.map +1 -0
  363. package/dist/cli-bundle/chunks/{test-runs-UXIXPDKU.js → test-runs-MG5VIGSK.js} +185 -147
  364. package/dist/cli-bundle/chunks/test-runs-MG5VIGSK.js.map +1 -0
  365. package/dist/cli-bundle/chunks/{test-runs-PLRAZEFW.js → test-runs-QIR5MJPL.js} +184 -146
  366. package/dist/cli-bundle/chunks/test-runs-QIR5MJPL.js.map +7 -0
  367. package/dist/cli-bundle/chunks/update-A7EICML6.js +24 -0
  368. package/dist/cli-bundle/chunks/{update-KFX2SIAC.js → update-IKJZWLQC.js} +15 -15
  369. package/dist/cli-bundle/chunks/{update-many-RNSBX2TA.js → update-many-BEMTDA2X.js} +84 -69
  370. package/dist/cli-bundle/chunks/{update-many-RNSBX2TA.js.map → update-many-BEMTDA2X.js.map} +1 -1
  371. package/dist/cli-bundle/chunks/{update-many-Z5GJS5LC.js → update-many-RATAARHU.js} +83 -68
  372. package/dist/cli-bundle/chunks/{update-many-Z5GJS5LC.js.map → update-many-RATAARHU.js.map} +2 -2
  373. package/dist/cli-bundle/chunks/{upgrade-BRL6KCOJ.js → upgrade-NWMR3VQL.js} +11 -11
  374. package/dist/cli-bundle/chunks/{upgrade-HAK6JG2O.js → upgrade-VU46BLJZ.js} +11 -11
  375. package/dist/cli-bundle/chunks/{validate-X5W76YJL.js → validate-GAJ6FUSI.js} +451 -321
  376. package/dist/cli-bundle/chunks/validate-GAJ6FUSI.js.map +1 -0
  377. package/dist/cli-bundle/chunks/{validate-MTUVL5VC.js → validate-NRY6MFXN.js} +450 -320
  378. package/dist/cli-bundle/chunks/validate-NRY6MFXN.js.map +7 -0
  379. package/dist/cli-bundle/main.js +1107 -916
  380. package/dist/cli-bundle/main.js.map +3 -3
  381. package/dist/core/config/nested-settings.js +89 -67
  382. package/dist/core/config/nested-settings.js.map +1 -1
  383. package/dist/core/governance/metadata-coverage.js +20 -28
  384. package/dist/core/governance/metadata-coverage.js.map +1 -1
  385. package/dist/core/history/drift-scan.js +93 -81
  386. package/dist/core/history/drift-scan.js.map +1 -1
  387. package/dist/core/item/item-type-definition.js +14 -14
  388. package/dist/core/item/item-type-definition.js.map +1 -1
  389. package/dist/core/item/type-registry.js +114 -99
  390. package/dist/core/item/type-registry.js.map +1 -1
  391. package/dist/core/output/mutation-projection.js +42 -26
  392. package/dist/core/output/mutation-projection.js.map +1 -1
  393. package/dist/core/schema/runtime-schema.js +97 -80
  394. package/dist/core/schema/runtime-schema.js.map +1 -1
  395. package/dist/core/schema/status-defs-file.js +26 -3
  396. package/dist/core/schema/status-defs-file.js.map +1 -1
  397. package/dist/core/search/corpus.js +25 -19
  398. package/dist/core/search/corpus.js.map +1 -1
  399. package/dist/core/search/semantic-defaults.js +64 -37
  400. package/dist/core/search/semantic-defaults.js.map +1 -1
  401. package/dist/core/search/vector-stores.js +32 -17
  402. package/dist/core/search/vector-stores.js.map +1 -1
  403. package/dist/core/sentry/helpers.js +31 -28
  404. package/dist/core/sentry/helpers.js.map +1 -1
  405. package/dist/core/sentry/instrument.js +54 -43
  406. package/dist/core/sentry/instrument.js.map +1 -1
  407. package/dist/core/shared/memo.d.ts +12 -0
  408. package/dist/core/shared/memo.js +25 -0
  409. package/dist/core/shared/memo.js.map +1 -0
  410. package/dist/core/shared/serialization.js +24 -14
  411. package/dist/core/shared/serialization.js.map +1 -1
  412. package/dist/core/shared/time.js +26 -4
  413. package/dist/core/shared/time.js.map +1 -1
  414. package/dist/core/store/front-matter-cache.d.ts +5 -0
  415. package/dist/core/store/front-matter-cache.js +316 -171
  416. package/dist/core/store/front-matter-cache.js.map +1 -1
  417. package/dist/core/store/item-store.js +33 -26
  418. package/dist/core/store/item-store.js.map +1 -1
  419. package/dist/core/store/settings.js +247 -203
  420. package/dist/core/store/settings.js.map +1 -1
  421. package/dist/core/test/background-runs.js +189 -160
  422. package/dist/core/test/background-runs.js.map +1 -1
  423. package/dist/sdk/cli-contracts/flag-contracts.js +71 -99
  424. package/dist/sdk/cli-contracts/flag-contracts.js.map +1 -1
  425. package/dist/sdk/compose.js +51 -42
  426. package/dist/sdk/compose.js.map +1 -1
  427. package/docs/AGENT_GUIDE.md +2 -2
  428. package/docs/ARCHITECTURE.md +2 -2
  429. package/docs/COMMANDS.md +8 -4
  430. package/docs/CONFIGURATION.md +1 -1
  431. package/docs/EXTENSIONS.md +12 -12
  432. package/docs/ONBOARDING.md +4 -2
  433. package/docs/README.md +2 -0
  434. package/docs/examples/starter-extension/README.md +11 -10
  435. package/marketplace.json +3 -3
  436. package/package.json +2 -2
  437. package/packages/pm-beads/extensions/beads/runtime.ts +240 -167
  438. package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +65 -58
  439. package/packages/pm-todos/extensions/todos/runtime.ts +65 -42
  440. package/plugins/pm-claude/.claude-plugin/plugin.json +2 -2
  441. package/plugins/pm-claude/README.md +6 -3
  442. package/plugins/pm-claude/commands/pm-init.md +1 -1
  443. package/dist/cli-bundle/chunks/activity-AW6XVFH6.js +0 -16
  444. package/dist/cli-bundle/chunks/aggregate-JTEF4BP7.js.map +0 -1
  445. package/dist/cli-bundle/chunks/chunk-22WKIL3H.js.map +0 -1
  446. package/dist/cli-bundle/chunks/chunk-2D4HATP2.js.map +0 -1
  447. package/dist/cli-bundle/chunks/chunk-3J6JRJ3I.js.map +0 -7
  448. package/dist/cli-bundle/chunks/chunk-3K2M5OYU.js.map +0 -7
  449. package/dist/cli-bundle/chunks/chunk-3S2KT7NG.js.map +0 -7
  450. package/dist/cli-bundle/chunks/chunk-3VGN2UWE.js.map +0 -1
  451. package/dist/cli-bundle/chunks/chunk-3XZCOZ5J.js.map +0 -1
  452. package/dist/cli-bundle/chunks/chunk-4XOIEKSD.js.map +0 -1
  453. package/dist/cli-bundle/chunks/chunk-55SNVXRQ.js.map +0 -7
  454. package/dist/cli-bundle/chunks/chunk-5CGRF3L5.js.map +0 -1
  455. package/dist/cli-bundle/chunks/chunk-7R4QEMZZ.js.map +0 -1
  456. package/dist/cli-bundle/chunks/chunk-AXIDKKAT.js.map +0 -1
  457. package/dist/cli-bundle/chunks/chunk-BDTISOSD.js.map +0 -7
  458. package/dist/cli-bundle/chunks/chunk-BZCEN4JA.js.map +0 -7
  459. package/dist/cli-bundle/chunks/chunk-CF7RL6FR.js.map +0 -1
  460. package/dist/cli-bundle/chunks/chunk-CWFNTKQJ.js.map +0 -1
  461. package/dist/cli-bundle/chunks/chunk-FFMQB7WR.js.map +0 -1
  462. package/dist/cli-bundle/chunks/chunk-HXTQJXWT.js.map +0 -1
  463. package/dist/cli-bundle/chunks/chunk-IPYBJWTE.js.map +0 -7
  464. package/dist/cli-bundle/chunks/chunk-IZBR4NRW.js.map +0 -7
  465. package/dist/cli-bundle/chunks/chunk-JLM7BHI7.js.map +0 -7
  466. package/dist/cli-bundle/chunks/chunk-JSU5P7VS.js.map +0 -1
  467. package/dist/cli-bundle/chunks/chunk-JWXRETDF.js.map +0 -1
  468. package/dist/cli-bundle/chunks/chunk-KNPEF7QG.js.map +0 -7
  469. package/dist/cli-bundle/chunks/chunk-MDPEOIGN.js.map +0 -7
  470. package/dist/cli-bundle/chunks/chunk-NFDPYAIP.js.map +0 -7
  471. package/dist/cli-bundle/chunks/chunk-NUHHPVVS.js.map +0 -7
  472. package/dist/cli-bundle/chunks/chunk-NWMZWYYB.js.map +0 -1
  473. package/dist/cli-bundle/chunks/chunk-OTUHB4HS.js.map +0 -1
  474. package/dist/cli-bundle/chunks/chunk-RGEMWD6Q.js.map +0 -7
  475. package/dist/cli-bundle/chunks/chunk-RLDHZHQS.js.map +0 -1
  476. package/dist/cli-bundle/chunks/chunk-RMMQ74TG.js.map +0 -7
  477. package/dist/cli-bundle/chunks/chunk-RVUALSJF.js.map +0 -7
  478. package/dist/cli-bundle/chunks/chunk-TP5Q5ZD3.js.map +0 -1
  479. package/dist/cli-bundle/chunks/chunk-V3NOKJF2.js.map +0 -1
  480. package/dist/cli-bundle/chunks/chunk-VARHOHYV.js.map +0 -7
  481. package/dist/cli-bundle/chunks/chunk-WYDHYJPO.js.map +0 -7
  482. package/dist/cli-bundle/chunks/chunk-YITK2PJ6.js.map +0 -7
  483. package/dist/cli-bundle/chunks/chunk-ZETXE4SE.js.map +0 -1
  484. package/dist/cli-bundle/chunks/close-E6ZZGCJY.js +0 -14
  485. package/dist/cli-bundle/chunks/close-many-BG5QQIDQ.js.map +0 -7
  486. package/dist/cli-bundle/chunks/close-many-LDRVEQY2.js.map +0 -1
  487. package/dist/cli-bundle/chunks/config-DMSU64QO.js +0 -1541
  488. package/dist/cli-bundle/chunks/config-DMSU64QO.js.map +0 -7
  489. package/dist/cli-bundle/chunks/config-QH2DICD6.js +0 -1531
  490. package/dist/cli-bundle/chunks/config-QH2DICD6.js.map +0 -1
  491. package/dist/cli-bundle/chunks/contracts-HN7ABKLP.js.map +0 -7
  492. package/dist/cli-bundle/chunks/contracts-W4FZVVD6.js.map +0 -1
  493. package/dist/cli-bundle/chunks/create-OH3BDGBB.js +0 -28
  494. package/dist/cli-bundle/chunks/get-A7MAOHCU.js.map +0 -7
  495. package/dist/cli-bundle/chunks/get-DSDEKJ3L.js.map +0 -1
  496. package/dist/cli-bundle/chunks/health-3IPFLKXB.js.map +0 -1
  497. package/dist/cli-bundle/chunks/health-GZXGBZ36.js.map +0 -7
  498. package/dist/cli-bundle/chunks/history-WSZHY3PN.js +0 -18
  499. package/dist/cli-bundle/chunks/history-compact-2WRZ2WK4.js.map +0 -7
  500. package/dist/cli-bundle/chunks/history-compact-HR7BB4LR.js.map +0 -1
  501. package/dist/cli-bundle/chunks/history-redact-MP6CH7U5.js +0 -19
  502. package/dist/cli-bundle/chunks/history-repair-LCMOS45X.js.map +0 -7
  503. package/dist/cli-bundle/chunks/history-repair-XA3LC4GA.js.map +0 -1
  504. package/dist/cli-bundle/chunks/init-PAX32BJA.js +0 -22
  505. package/dist/cli-bundle/chunks/next-BCERKDUR.js.map +0 -7
  506. package/dist/cli-bundle/chunks/next-FYTQF6HG.js.map +0 -1
  507. package/dist/cli-bundle/chunks/plan-4WXEQCTN.js.map +0 -7
  508. package/dist/cli-bundle/chunks/plan-RKZHQVXR.js.map +0 -1
  509. package/dist/cli-bundle/chunks/profile-4OMM32CD.js.map +0 -7
  510. package/dist/cli-bundle/chunks/profile-QLER5ENE.js.map +0 -1
  511. package/dist/cli-bundle/chunks/register-list-query-7LV46VAU.js +0 -400
  512. package/dist/cli-bundle/chunks/register-list-query-7LV46VAU.js.map +0 -1
  513. package/dist/cli-bundle/chunks/register-list-query-SNG5PGA4.js +0 -410
  514. package/dist/cli-bundle/chunks/register-list-query-SNG5PGA4.js.map +0 -7
  515. package/dist/cli-bundle/chunks/register-mutation-ENNDUAZG.js.map +0 -1
  516. package/dist/cli-bundle/chunks/register-mutation-KK7PHYYU.js.map +0 -7
  517. package/dist/cli-bundle/chunks/register-operations-C6OWLDSH.js +0 -486
  518. package/dist/cli-bundle/chunks/register-operations-C6OWLDSH.js.map +0 -1
  519. package/dist/cli-bundle/chunks/register-operations-HZ6XERQG.js.map +0 -7
  520. package/dist/cli-bundle/chunks/register-setup-P67EMBDJ.js.map +0 -1
  521. package/dist/cli-bundle/chunks/register-setup-ZKJ53RS7.js.map +0 -7
  522. package/dist/cli-bundle/chunks/restore-YALDGTQR.js +0 -17
  523. package/dist/cli-bundle/chunks/telemetry-BZUF6H7G.js.map +0 -1
  524. package/dist/cli-bundle/chunks/telemetry-GAHHQTOS.js.map +0 -7
  525. package/dist/cli-bundle/chunks/test-all-L2MDDUCA.js +0 -358
  526. package/dist/cli-bundle/chunks/test-all-L2MDDUCA.js.map +0 -1
  527. package/dist/cli-bundle/chunks/test-all-RBZ6DLU2.js +0 -361
  528. package/dist/cli-bundle/chunks/test-all-RBZ6DLU2.js.map +0 -7
  529. package/dist/cli-bundle/chunks/test-runs-PLRAZEFW.js.map +0 -7
  530. package/dist/cli-bundle/chunks/test-runs-UXIXPDKU.js.map +0 -1
  531. package/dist/cli-bundle/chunks/update-AMRSOIWP.js +0 -24
  532. package/dist/cli-bundle/chunks/validate-MTUVL5VC.js.map +0 -7
  533. package/dist/cli-bundle/chunks/validate-X5W76YJL.js.map +0 -1
  534. /package/dist/cli-bundle/chunks/{activity-DBLQVIP6.js.map → activity-5YWLSPGE.js.map} +0 -0
  535. /package/dist/cli-bundle/chunks/{activity-AW6XVFH6.js.map → activity-BIML7K2D.js.map} +0 -0
  536. /package/dist/cli-bundle/chunks/{append-LOVPGVPT.js.map → append-EZESUVJT.js.map} +0 -0
  537. /package/dist/cli-bundle/chunks/{append-QCFJSDFL.js.map → append-JFG4WQMG.js.map} +0 -0
  538. /package/dist/cli-bundle/chunks/{chunk-BHO33VBQ.js.map → chunk-3W2HJKJX.js.map} +0 -0
  539. /package/dist/cli-bundle/chunks/{chunk-4DUVCVLZ.js.map → chunk-4PFVUUYV.js.map} +0 -0
  540. /package/dist/cli-bundle/chunks/{chunk-IJYK2T43.js.map → chunk-5E7N4T2Z.js.map} +0 -0
  541. /package/dist/cli-bundle/chunks/{chunk-NKZAN7BD.js.map → chunk-5IZUBZBR.js.map} +0 -0
  542. /package/dist/cli-bundle/chunks/{chunk-NOLPZMSV.js.map → chunk-5JIWFWOZ.js.map} +0 -0
  543. /package/dist/cli-bundle/chunks/{chunk-6AQZPVHQ.js.map → chunk-6CDCWKSX.js.map} +0 -0
  544. /package/dist/cli-bundle/chunks/{chunk-LB6TP6MC.js.map → chunk-6NYJGMTY.js.map} +0 -0
  545. /package/dist/cli-bundle/chunks/{chunk-SLMUGTK3.js.map → chunk-7CLLC75T.js.map} +0 -0
  546. /package/dist/cli-bundle/chunks/{chunk-2466X6E4.js.map → chunk-7LYO6S5A.js.map} +0 -0
  547. /package/dist/cli-bundle/chunks/{chunk-W4ULYO7Z.js.map → chunk-A3OQ7TFW.js.map} +0 -0
  548. /package/dist/cli-bundle/chunks/{chunk-GJ326ZKX.js.map → chunk-ER4ME5U2.js.map} +0 -0
  549. /package/dist/cli-bundle/chunks/{chunk-HZZEHPRG.js.map → chunk-ERG65A2L.js.map} +0 -0
  550. /package/dist/cli-bundle/chunks/{chunk-L5OEFZQG.js.map → chunk-FH2H3CBD.js.map} +0 -0
  551. /package/dist/cli-bundle/chunks/{chunk-JPECA746.js.map → chunk-FUFFPIYA.js.map} +0 -0
  552. /package/dist/cli-bundle/chunks/{chunk-27BXPBAY.js.map → chunk-GUYNUXQT.js.map} +0 -0
  553. /package/dist/cli-bundle/chunks/{chunk-MAUKX7JC.js.map → chunk-GVJE5T7Q.js.map} +0 -0
  554. /package/dist/cli-bundle/chunks/{chunk-ZRP4VG5U.js.map → chunk-JBZ2NTKX.js.map} +0 -0
  555. /package/dist/cli-bundle/chunks/{chunk-EJUDVUYZ.js.map → chunk-KEZOIPCR.js.map} +0 -0
  556. /package/dist/cli-bundle/chunks/{chunk-HYTGA6GI.js.map → chunk-MDHWWBNZ.js.map} +0 -0
  557. /package/dist/cli-bundle/chunks/{chunk-N74UMG5H.js.map → chunk-MEZZZBYX.js.map} +0 -0
  558. /package/dist/cli-bundle/chunks/{chunk-SDR5J34Q.js.map → chunk-NZ7QIUP5.js.map} +0 -0
  559. /package/dist/cli-bundle/chunks/{chunk-DDPTYJIM.js.map → chunk-P5L7Z2O6.js.map} +0 -0
  560. /package/dist/cli-bundle/chunks/{chunk-OGXLACHC.js.map → chunk-SU2E4AWU.js.map} +0 -0
  561. /package/dist/cli-bundle/chunks/{chunk-HPPFYYOV.js.map → chunk-SU3TB4NS.js.map} +0 -0
  562. /package/dist/cli-bundle/chunks/{chunk-G7I7DEZA.js.map → chunk-T4XBKJ3F.js.map} +0 -0
  563. /package/dist/cli-bundle/chunks/{chunk-VICZWYGZ.js.map → chunk-U5TR4N7J.js.map} +0 -0
  564. /package/dist/cli-bundle/chunks/{chunk-EVMTBV6V.js.map → chunk-UMNQZS4H.js.map} +0 -0
  565. /package/dist/cli-bundle/chunks/{chunk-A7FPBAQS.js.map → chunk-WJA3PXW7.js.map} +0 -0
  566. /package/dist/cli-bundle/chunks/{chunk-QCWF6IYD.js.map → chunk-YSDFIY7N.js.map} +0 -0
  567. /package/dist/cli-bundle/chunks/{chunk-UZIWVBE6.js.map → chunk-YSGTMDWC.js.map} +0 -0
  568. /package/dist/cli-bundle/chunks/{chunk-64HNBBFQ.js.map → chunk-Z5F6XZXE.js.map} +0 -0
  569. /package/dist/cli-bundle/chunks/{chunk-AVEE5EHK.js.map → chunk-Z7RPDF2Y.js.map} +0 -0
  570. /package/dist/cli-bundle/chunks/{claim-T3GCKV7C.js.map → claim-2BGBGSVI.js.map} +0 -0
  571. /package/dist/cli-bundle/chunks/{claim-EMQLYPRW.js.map → claim-5GU7OE67.js.map} +0 -0
  572. /package/dist/cli-bundle/chunks/{close-E6ZZGCJY.js.map → close-6YODBUIV.js.map} +0 -0
  573. /package/dist/cli-bundle/chunks/{close-TQYAAFJP.js.map → close-AFVKPR57.js.map} +0 -0
  574. /package/dist/cli-bundle/chunks/{comments-YUXJRZPQ.js.map → comments-DNWHEBOS.js.map} +0 -0
  575. /package/dist/cli-bundle/chunks/{comments-QCKR2YY2.js.map → comments-RW23R3VE.js.map} +0 -0
  576. /package/dist/cli-bundle/chunks/{context-B6275WPX.js.map → context-OYXRGY7S.js.map} +0 -0
  577. /package/dist/cli-bundle/chunks/{context-OCZ3FJ4Z.js.map → context-PKCEHQY3.js.map} +0 -0
  578. /package/dist/cli-bundle/chunks/{copy-DEM4DATS.js.map → copy-6XOR3HKN.js.map} +0 -0
  579. /package/dist/cli-bundle/chunks/{copy-BTJOSKKT.js.map → copy-I4NCLBR4.js.map} +0 -0
  580. /package/dist/cli-bundle/chunks/{create-RLRJMRTM.js.map → create-PM45M6PE.js.map} +0 -0
  581. /package/dist/cli-bundle/chunks/{create-OH3BDGBB.js.map → create-Z7YCH3BE.js.map} +0 -0
  582. /package/dist/cli-bundle/chunks/{delete-BHK7VB2Z.js.map → delete-7YXHYG67.js.map} +0 -0
  583. /package/dist/cli-bundle/chunks/{delete-LSVHAB4Y.js.map → delete-LPISP43T.js.map} +0 -0
  584. /package/dist/cli-bundle/chunks/{deps-XHYXWEPT.js.map → deps-N2T26FME.js.map} +0 -0
  585. /package/dist/cli-bundle/chunks/{deps-4UDFJRUA.js.map → deps-WATKQDE3.js.map} +0 -0
  586. /package/dist/cli-bundle/chunks/{docs-GYZNVS26.js.map → docs-6LQ3GLM7.js.map} +0 -0
  587. /package/dist/cli-bundle/chunks/{docs-26S44RXU.js.map → docs-Z3X6JZLT.js.map} +0 -0
  588. /package/dist/cli-bundle/chunks/{eval-UYF3ZPVO.js.map → eval-6DCLG52D.js.map} +0 -0
  589. /package/dist/cli-bundle/chunks/{eval-PGRVIJQU.js.map → eval-Y3ZCUTHK.js.map} +0 -0
  590. /package/dist/cli-bundle/chunks/{extension-CPSLJQVE.js.map → extension-BNINIMT7.js.map} +0 -0
  591. /package/dist/cli-bundle/chunks/{extension-CXJ6RELI.js.map → extension-QWE4YYK5.js.map} +0 -0
  592. /package/dist/cli-bundle/chunks/{files-NQHEXUZD.js.map → files-6SGKHS6O.js.map} +0 -0
  593. /package/dist/cli-bundle/chunks/{files-MBNICQFM.js.map → files-FUYPSOFJ.js.map} +0 -0
  594. /package/dist/cli-bundle/chunks/{focus-DWYIG7GU.js.map → focus-2Q3K76G2.js.map} +0 -0
  595. /package/dist/cli-bundle/chunks/{focus-XZW5423D.js.map → focus-ATLBWXXD.js.map} +0 -0
  596. /package/dist/cli-bundle/chunks/{gc-LPVMKJQJ.js.map → gc-RUYEMNRF.js.map} +0 -0
  597. /package/dist/cli-bundle/chunks/{gc-7GQYOS2G.js.map → gc-TDWSDR66.js.map} +0 -0
  598. /package/dist/cli-bundle/chunks/{history-WSZHY3PN.js.map → history-CGNQJXFE.js.map} +0 -0
  599. /package/dist/cli-bundle/chunks/{history-NERDJNUB.js.map → history-SGRRS72R.js.map} +0 -0
  600. /package/dist/cli-bundle/chunks/{history-redact-O3NBCNWC.js.map → history-redact-IRL7WJ3E.js.map} +0 -0
  601. /package/dist/cli-bundle/chunks/{history-redact-MP6CH7U5.js.map → history-redact-N3JK7VBW.js.map} +0 -0
  602. /package/dist/cli-bundle/chunks/{init-64XDLQJB.js.map → init-4GESW7RM.js.map} +0 -0
  603. /package/dist/cli-bundle/chunks/{init-PAX32BJA.js.map → init-XIDPABA4.js.map} +0 -0
  604. /package/dist/cli-bundle/chunks/{learnings-LPKCSJX7.js.map → learnings-4BHWFFUV.js.map} +0 -0
  605. /package/dist/cli-bundle/chunks/{learnings-JR6MA5TI.js.map → learnings-4FJY7WIW.js.map} +0 -0
  606. /package/dist/cli-bundle/chunks/{list-G5Y65VF6.js.map → list-472TIOVK.js.map} +0 -0
  607. /package/dist/cli-bundle/chunks/{list-DNBJVO3E.js.map → list-D7BF5CL2.js.map} +0 -0
  608. /package/dist/cli-bundle/chunks/{notes-2BMU3VVQ.js.map → notes-6KNOSLIT.js.map} +0 -0
  609. /package/dist/cli-bundle/chunks/{notes-6KTGO2OJ.js.map → notes-W4UEICGF.js.map} +0 -0
  610. /package/dist/cli-bundle/chunks/{restore-4MHZFJ2E.js.map → restore-44IHMMZZ.js.map} +0 -0
  611. /package/dist/cli-bundle/chunks/{restore-YALDGTQR.js.map → restore-EXHU34EU.js.map} +0 -0
  612. /package/dist/cli-bundle/chunks/{scheduling-shortcuts-LB6DOLRL.js.map → scheduling-shortcuts-OLHNLAZY.js.map} +0 -0
  613. /package/dist/cli-bundle/chunks/{scheduling-shortcuts-UTOYKLXQ.js.map → scheduling-shortcuts-TSBK4AY5.js.map} +0 -0
  614. /package/dist/cli-bundle/chunks/{schema-73HR2OJW.js.map → schema-IB2NZZWD.js.map} +0 -0
  615. /package/dist/cli-bundle/chunks/{schema-U6LJKSIR.js.map → schema-VBCELP5G.js.map} +0 -0
  616. /package/dist/cli-bundle/chunks/{search-AXPXKZER.js.map → search-7UBETML4.js.map} +0 -0
  617. /package/dist/cli-bundle/chunks/{search-KILGT37L.js.map → search-R227JOL6.js.map} +0 -0
  618. /package/dist/cli-bundle/chunks/{stats-W5KNVJWQ.js.map → stats-FAG7COEH.js.map} +0 -0
  619. /package/dist/cli-bundle/chunks/{stats-PSYVVTNZ.js.map → stats-MCK7PLYS.js.map} +0 -0
  620. /package/dist/cli-bundle/chunks/{test-PWDIZ255.js.map → test-QY44WAMR.js.map} +0 -0
  621. /package/dist/cli-bundle/chunks/{test-ACD52Z3S.js.map → test-SY76DZTO.js.map} +0 -0
  622. /package/dist/cli-bundle/chunks/{update-AMRSOIWP.js.map → update-A7EICML6.js.map} +0 -0
  623. /package/dist/cli-bundle/chunks/{update-KFX2SIAC.js.map → update-IKJZWLQC.js.map} +0 -0
  624. /package/dist/cli-bundle/chunks/{upgrade-BRL6KCOJ.js.map → upgrade-NWMR3VQL.js.map} +0 -0
  625. /package/dist/cli-bundle/chunks/{upgrade-HAK6JG2O.js.map → upgrade-VU46BLJZ.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