@unbrained/pm-cli 2026.7.21 → 2026.7.22

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 (506) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +25 -0
  3. package/dist/cli/bundle-integrity.js +3 -3
  4. package/dist/cli/bundle-integrity.js.map +1 -1
  5. package/dist/cli/commands/contracts.d.ts +5 -0
  6. package/dist/cli/commands/contracts.js +8 -6
  7. package/dist/cli/commands/contracts.js.map +1 -1
  8. package/dist/cli/commands/copy.js +36 -20
  9. package/dist/cli/commands/copy.js.map +1 -1
  10. package/dist/cli/commands/create.js +48 -24
  11. package/dist/cli/commands/create.js.map +1 -1
  12. package/dist/cli/commands/merge.d.ts +1 -1
  13. package/dist/cli/commands/merge.js +3 -3
  14. package/dist/cli/commands/merge.js.map +1 -1
  15. package/dist/cli/commands/restore.js +40 -22
  16. package/dist/cli/commands/restore.js.map +1 -1
  17. package/dist/cli/commands/update.js +12 -9
  18. package/dist/cli/commands/update.js.map +1 -1
  19. package/dist/cli/extension-command-help.js +3 -4
  20. package/dist/cli/extension-command-help.js.map +1 -1
  21. package/dist/cli/main.d.ts +3 -2
  22. package/dist/cli/main.js +6 -6
  23. package/dist/cli/main.js.map +1 -1
  24. package/dist/cli/register-list-query.js +33 -21
  25. package/dist/cli/register-list-query.js.map +1 -1
  26. package/dist/cli/register-mutation.js +63 -37
  27. package/dist/cli/register-mutation.js.map +1 -1
  28. package/dist/cli/registration-helpers.d.ts +2 -0
  29. package/dist/cli/registration-helpers.js +3 -2
  30. package/dist/cli/registration-helpers.js.map +1 -1
  31. package/dist/cli-bundle/bundle-manifest.json +349 -341
  32. package/dist/cli-bundle/chunks/{append-7OVFYR3C.js → append-CYMA7RJT.js} +5 -5
  33. package/dist/cli-bundle/chunks/append-H53CAPMP.js +11 -0
  34. package/dist/cli-bundle/chunks/{chunk-PFNHX655.js → chunk-2P7OK4WG.js} +3 -3
  35. package/dist/cli-bundle/chunks/{chunk-EJDGV4GR.js → chunk-3EBGHNNQ.js} +3 -3
  36. package/dist/cli-bundle/chunks/{chunk-DZRV2OPA.js → chunk-3EDFN3VV.js} +2 -2
  37. package/dist/cli-bundle/chunks/{chunk-ZOY5K4D3.js → chunk-3PWJWLLQ.js} +2 -2
  38. package/dist/cli-bundle/chunks/{chunk-VXOOB6YX.js → chunk-3SJAR3CY.js} +4 -4
  39. package/dist/cli-bundle/chunks/{chunk-GTLCVJOE.js → chunk-3WVKMF2A.js} +3 -3
  40. package/dist/cli-bundle/chunks/{chunk-LAV26CQG.js → chunk-42SYYKA4.js} +4 -4
  41. package/dist/cli-bundle/chunks/{chunk-NLR32VFS.js → chunk-4IXLNV7W.js} +2 -2
  42. package/dist/cli-bundle/chunks/{chunk-BKIAH72N.js → chunk-4LTPHDKA.js} +39 -23
  43. package/dist/cli-bundle/chunks/chunk-4LTPHDKA.js.map +1 -0
  44. package/dist/cli-bundle/chunks/{chunk-ABWCF646.js → chunk-4YTQVO3V.js} +5 -5
  45. package/dist/cli-bundle/chunks/{chunk-E5XMKOSB.js → chunk-5EBRMHI6.js} +4 -4
  46. package/dist/cli-bundle/chunks/{chunk-IY6VZ3IW.js → chunk-5FAG2JUC.js} +320 -62
  47. package/dist/cli-bundle/chunks/chunk-5FAG2JUC.js.map +7 -0
  48. package/dist/cli-bundle/chunks/{chunk-GKX4NJ7U.js → chunk-5K5LHZZX.js} +6 -6
  49. package/dist/cli-bundle/chunks/{chunk-T6PPNM7V.js → chunk-5K7BOAB6.js} +4 -4
  50. package/dist/cli-bundle/chunks/{chunk-4QOB7L7I.js → chunk-5MUZ54G2.js} +5 -5
  51. package/dist/cli-bundle/chunks/{chunk-SF3DT5HJ.js → chunk-5QME4KX2.js} +3 -3
  52. package/dist/cli-bundle/chunks/{chunk-RMF7LMBS.js → chunk-6PDGFY3P.js} +27 -17
  53. package/dist/cli-bundle/chunks/{chunk-RMF7LMBS.js.map → chunk-6PDGFY3P.js.map} +2 -2
  54. package/dist/cli-bundle/chunks/{chunk-TRSHFPRZ.js → chunk-6PM6CPPP.js} +5 -5
  55. package/dist/cli-bundle/chunks/{chunk-O4BCOJTZ.js → chunk-7AHRY3ZB.js} +21 -16
  56. package/dist/cli-bundle/chunks/chunk-7AHRY3ZB.js.map +7 -0
  57. package/dist/cli-bundle/chunks/{chunk-OR42SO64.js → chunk-7B36A3VT.js} +4 -4
  58. package/dist/cli-bundle/chunks/{chunk-QWRVBJ4D.js → chunk-7OR2YKKD.js} +2 -2
  59. package/dist/cli-bundle/chunks/{chunk-FPBMLYPI.js → chunk-7QUV54XX.js} +4 -4
  60. package/dist/cli-bundle/chunks/{chunk-WWNL6WMH.js → chunk-7WXW6JHG.js} +2 -2
  61. package/dist/cli-bundle/chunks/{chunk-BXNDKOR2.js → chunk-A2VL5SVG.js} +4 -4
  62. package/dist/cli-bundle/chunks/chunk-AXGDUXJW.js +5 -0
  63. package/dist/cli-bundle/chunks/{chunk-IAQE32BI.js → chunk-B2AVNGG3.js} +4 -4
  64. package/dist/cli-bundle/chunks/{chunk-K36WV5J6.js → chunk-B7O44UBR.js} +71 -8
  65. package/dist/cli-bundle/chunks/chunk-B7O44UBR.js.map +1 -0
  66. package/dist/cli-bundle/chunks/{chunk-HCEBZNC3.js → chunk-BRMPF2RM.js} +4 -4
  67. package/dist/cli-bundle/chunks/{chunk-Z7VWXXJM.js → chunk-BTNKMF2A.js} +4 -4
  68. package/dist/cli-bundle/chunks/{chunk-KH44WBAT.js → chunk-CD4643VW.js} +4 -4
  69. package/dist/cli-bundle/chunks/{chunk-OWXOPDHD.js → chunk-CJEEC5O4.js} +4 -4
  70. package/dist/cli-bundle/chunks/{chunk-PZC2FUOQ.js → chunk-CTPKCZCF.js} +2 -2
  71. package/dist/cli-bundle/chunks/{chunk-7W2UAXXT.js → chunk-D4OBQVL3.js} +10 -10
  72. package/dist/cli-bundle/chunks/{chunk-EWJWSNRU.js → chunk-DM4TYC2A.js} +4 -4
  73. package/dist/cli-bundle/chunks/{chunk-VJQG4BIM.js → chunk-DSFTAQ7T.js} +3 -3
  74. package/dist/cli-bundle/chunks/{chunk-AELMUANP.js → chunk-DVB6SQU7.js} +2 -2
  75. package/dist/cli-bundle/chunks/{chunk-KBLZ3AA5.js → chunk-E3ZWOFSO.js} +4 -4
  76. package/dist/cli-bundle/chunks/chunk-EP25DV6P.js +9 -0
  77. package/dist/cli-bundle/chunks/{chunk-GTK4DTEW.js → chunk-F4VCB4WY.js} +10 -10
  78. package/dist/cli-bundle/chunks/{chunk-V22ZPOKN.js → chunk-F4XAQUQA.js} +6 -6
  79. package/dist/cli-bundle/chunks/{chunk-QOOTOD3W.js → chunk-FGR6IBAF.js} +6 -6
  80. package/dist/cli-bundle/chunks/{chunk-JSLT7WVE.js → chunk-FKBMT2Q6.js} +2 -2
  81. package/dist/cli-bundle/chunks/{chunk-QIH77CAG.js → chunk-G5RLSSIX.js} +2 -2
  82. package/dist/cli-bundle/chunks/{chunk-P7MTHPJQ.js → chunk-GEKRVH3G.js} +2 -2
  83. package/dist/cli-bundle/chunks/{chunk-2L6ZP22J.js → chunk-GSP6IZFU.js} +3 -3
  84. package/dist/cli-bundle/chunks/{chunk-ATBCUC7Y.js → chunk-H3MDK2VU.js} +48 -30
  85. package/dist/cli-bundle/chunks/chunk-H3MDK2VU.js.map +1 -0
  86. package/dist/cli-bundle/chunks/{chunk-ZVZGXPQ5.js → chunk-HYZZM3Q2.js} +2 -2
  87. package/dist/cli-bundle/chunks/{chunk-XJTABV3X.js → chunk-IBWG3OSH.js} +22 -17
  88. package/dist/cli-bundle/chunks/chunk-IBWG3OSH.js.map +1 -0
  89. package/dist/cli-bundle/chunks/{chunk-4XGJLADW.js → chunk-IHY5SX7O.js} +3 -3
  90. package/dist/cli-bundle/chunks/{chunk-UCBDQI5E.js → chunk-IMU7JLUI.js} +7 -7
  91. package/dist/cli-bundle/chunks/{chunk-Z75ONV25.js → chunk-IPAQAJWB.js} +77 -7
  92. package/dist/cli-bundle/chunks/chunk-IPAQAJWB.js.map +7 -0
  93. package/dist/cli-bundle/chunks/{chunk-7RW4JCU2.js → chunk-IQCD6OO3.js} +25 -13
  94. package/dist/cli-bundle/chunks/chunk-IQCD6OO3.js.map +7 -0
  95. package/dist/cli-bundle/chunks/{chunk-YQWCZ5AC.js → chunk-J3ZKFEDM.js} +38 -22
  96. package/dist/cli-bundle/chunks/chunk-J3ZKFEDM.js.map +7 -0
  97. package/dist/cli-bundle/chunks/{chunk-PEQGTJ5Q.js → chunk-JCLXCGIL.js} +3 -3
  98. package/dist/cli-bundle/chunks/{chunk-GROYI4RB.js → chunk-JLTHOYR7.js} +3 -3
  99. package/dist/cli-bundle/chunks/{chunk-JHJSFOAM.js → chunk-JMPVHM44.js} +4 -4
  100. package/dist/cli-bundle/chunks/{chunk-MATHDCGG.js → chunk-JWYG36RV.js} +8 -8
  101. package/dist/cli-bundle/chunks/{chunk-ZTVA4KLN.js → chunk-KEGVMZNA.js} +28 -16
  102. package/dist/cli-bundle/chunks/chunk-KEGVMZNA.js.map +7 -0
  103. package/dist/cli-bundle/chunks/{chunk-VLRGDBLY.js → chunk-KEHOPUHH.js} +4 -4
  104. package/dist/cli-bundle/chunks/{chunk-K55VMLSS.js → chunk-KJ4ZF35M.js} +63 -13
  105. package/dist/cli-bundle/chunks/chunk-KJ4ZF35M.js.map +7 -0
  106. package/dist/cli-bundle/chunks/{chunk-CPX275C6.js → chunk-KPCZL2YK.js} +6 -6
  107. package/dist/cli-bundle/chunks/{chunk-POG76WWZ.js → chunk-L7DZV6EZ.js} +319 -61
  108. package/dist/cli-bundle/chunks/chunk-L7DZV6EZ.js.map +1 -0
  109. package/dist/cli-bundle/chunks/{chunk-FO6OSVEN.js → chunk-LANV45W2.js} +8 -8
  110. package/dist/cli-bundle/chunks/{chunk-LVC72YRD.js → chunk-LC5ZUXWE.js} +7 -7
  111. package/dist/cli-bundle/chunks/{chunk-SY4SFZSD.js → chunk-LE522OXA.js} +55 -30
  112. package/dist/cli-bundle/chunks/chunk-LE522OXA.js.map +7 -0
  113. package/dist/cli-bundle/chunks/{chunk-TVYYO5A7.js → chunk-MBHYQYCS.js} +2 -2
  114. package/dist/cli-bundle/chunks/{chunk-FJIFFBJX.js → chunk-MROP2RNT.js} +66 -74
  115. package/dist/cli-bundle/chunks/chunk-MROP2RNT.js.map +1 -0
  116. package/dist/cli-bundle/chunks/{chunk-7656MAUL.js → chunk-MUAJHL2R.js} +2 -2
  117. package/dist/cli-bundle/chunks/{chunk-R3P6FZJW.js → chunk-N6QCY2AX.js} +43 -25
  118. package/dist/cli-bundle/chunks/chunk-N6QCY2AX.js.map +1 -0
  119. package/dist/cli-bundle/chunks/{chunk-7WCE6Y64.js → chunk-NUQCSV4P.js} +2 -2
  120. package/dist/cli-bundle/chunks/{chunk-SZVB53Y3.js → chunk-O3GFE2PX.js} +3 -3
  121. package/dist/cli-bundle/chunks/{chunk-OY7DMU5P.js → chunk-O43LEUSD.js} +2 -2
  122. package/dist/cli-bundle/chunks/{chunk-AMJPSANK.js → chunk-O7RH6BWP.js} +103 -44
  123. package/dist/cli-bundle/chunks/chunk-O7RH6BWP.js.map +7 -0
  124. package/dist/cli-bundle/chunks/{chunk-NUF7ROFH.js → chunk-OODR5KYF.js} +26 -27
  125. package/dist/cli-bundle/chunks/chunk-OODR5KYF.js.map +1 -0
  126. package/dist/cli-bundle/chunks/{chunk-LZYP423P.js → chunk-OZ25YD4Q.js} +3 -3
  127. package/dist/cli-bundle/chunks/{chunk-VZIZB6QH.js → chunk-PKYKQCTJ.js} +4 -4
  128. package/dist/cli-bundle/chunks/{chunk-UZLJOEAC.js → chunk-PMRED6QZ.js} +3 -3
  129. package/dist/cli-bundle/chunks/{chunk-ADBTSVGK.js → chunk-PPATPPI6.js} +65 -73
  130. package/dist/cli-bundle/chunks/chunk-PPATPPI6.js.map +7 -0
  131. package/dist/cli-bundle/chunks/{chunk-K4CI6Y45.js → chunk-PWGJCP2V.js} +2 -2
  132. package/dist/cli-bundle/chunks/{chunk-UVN66B3M.js → chunk-Q3Z2Y5WJ.js} +2 -2
  133. package/dist/cli-bundle/chunks/{chunk-RNPZYNHS.js → chunk-Q6YZ3VCI.js} +104 -45
  134. package/dist/cli-bundle/chunks/chunk-Q6YZ3VCI.js.map +1 -0
  135. package/dist/cli-bundle/chunks/{chunk-7DOJC3HS.js → chunk-QE5EUHKN.js} +28 -18
  136. package/dist/cli-bundle/chunks/chunk-QE5EUHKN.js.map +1 -0
  137. package/dist/cli-bundle/chunks/{chunk-AS4SAZ5R.js → chunk-QKMMWESK.js} +25 -26
  138. package/dist/cli-bundle/chunks/chunk-QKMMWESK.js.map +7 -0
  139. package/dist/cli-bundle/chunks/{chunk-R7QV7ICM.js → chunk-QSXN2FAN.js} +4 -4
  140. package/dist/cli-bundle/chunks/{chunk-5NTE36LD.js → chunk-RBECHH5K.js} +4 -4
  141. package/dist/cli-bundle/chunks/{chunk-JXCW2TI2.js → chunk-RPNC7M63.js} +8 -8
  142. package/dist/cli-bundle/chunks/{chunk-ICDAQ4TD.js → chunk-S2QQNTA6.js} +26 -14
  143. package/dist/cli-bundle/chunks/chunk-S2QQNTA6.js.map +1 -0
  144. package/dist/cli-bundle/chunks/{chunk-JFD5LPMI.js → chunk-SP3BAXFF.js} +29 -17
  145. package/dist/cli-bundle/chunks/chunk-SP3BAXFF.js.map +1 -0
  146. package/dist/cli-bundle/chunks/{chunk-F2LBF7XJ.js → chunk-SUSFH6F7.js} +5 -5
  147. package/dist/cli-bundle/chunks/{chunk-VHXHVTUU.js → chunk-TDOPC7UY.js} +2 -2
  148. package/dist/cli-bundle/chunks/{chunk-HYW67VJ5.js → chunk-TLF52ZDP.js} +30 -25
  149. package/dist/cli-bundle/chunks/chunk-TLF52ZDP.js.map +1 -0
  150. package/dist/cli-bundle/chunks/{chunk-FSE2IKJQ.js → chunk-TWHG646K.js} +2 -2
  151. package/dist/cli-bundle/chunks/{chunk-OCUBRA6D.js → chunk-U7U7WGEC.js} +4 -4
  152. package/dist/cli-bundle/chunks/{chunk-PONKZPCJ.js → chunk-UFRVIIJ2.js} +4 -4
  153. package/dist/cli-bundle/chunks/{chunk-VNTCM3VW.js → chunk-VKX2VZZH.js} +8 -8
  154. package/dist/cli-bundle/chunks/{chunk-7AVEY74G.js → chunk-VTOCZ343.js} +29 -24
  155. package/dist/cli-bundle/chunks/chunk-VTOCZ343.js.map +7 -0
  156. package/dist/cli-bundle/chunks/{chunk-6JUTHVQS.js → chunk-W2JDNTN3.js} +2 -2
  157. package/dist/cli-bundle/chunks/{chunk-PQSEQD6E.js → chunk-W35PHE44.js} +62 -12
  158. package/dist/cli-bundle/chunks/chunk-W35PHE44.js.map +1 -0
  159. package/dist/cli-bundle/chunks/{chunk-4QSQ6XDK.js → chunk-WT4KXBUD.js} +68 -31
  160. package/dist/cli-bundle/chunks/chunk-WT4KXBUD.js.map +1 -0
  161. package/dist/cli-bundle/chunks/{chunk-RPESLSO5.js → chunk-XC5RVKHH.js} +69 -32
  162. package/dist/cli-bundle/chunks/chunk-XC5RVKHH.js.map +7 -0
  163. package/dist/cli-bundle/chunks/{chunk-QG4GFLQ6.js → chunk-XD6UF2NB.js} +42 -24
  164. package/dist/cli-bundle/chunks/chunk-XD6UF2NB.js.map +7 -0
  165. package/dist/cli-bundle/chunks/{chunk-AF2CCM5U.js → chunk-XKRVX4B3.js} +4 -4
  166. package/dist/cli-bundle/chunks/{chunk-JGUKMMRS.js → chunk-XN4NQZJK.js} +3 -3
  167. package/dist/cli-bundle/chunks/{chunk-3P7UJQOX.js → chunk-YKFMLQNK.js} +2 -2
  168. package/dist/cli-bundle/chunks/{chunk-YCIUJJOD.js → chunk-YKWKMGL7.js} +2 -2
  169. package/dist/cli-bundle/chunks/{chunk-TOBGV45Y.js → chunk-YUKIFPWK.js} +2 -2
  170. package/dist/cli-bundle/chunks/{chunk-72LQ4TKV.js → chunk-YYEZEP3E.js} +3 -3
  171. package/dist/cli-bundle/chunks/{chunk-X3W65QK3.js → chunk-ZEY3XSZQ.js} +5 -5
  172. package/dist/cli-bundle/chunks/{chunk-MWQ2HC2A.js → chunk-ZKOQHLJP.js} +59 -34
  173. package/dist/cli-bundle/chunks/chunk-ZKOQHLJP.js.map +1 -0
  174. package/dist/cli-bundle/chunks/{chunk-QJIKE24M.js → chunk-ZQ3UMKWE.js} +2 -2
  175. package/dist/cli-bundle/chunks/{chunk-4PUUNQDV.js → chunk-ZVVEWHWK.js} +58 -33
  176. package/dist/cli-bundle/chunks/chunk-ZVVEWHWK.js.map +7 -0
  177. package/dist/cli-bundle/chunks/{chunk-OG5DVFMA.js → chunk-ZXE6SNKO.js} +5 -5
  178. package/dist/cli-bundle/chunks/close-GAUIGOQC.js +12 -0
  179. package/dist/cli-bundle/chunks/{close-QEMOYZN3.js → close-SJIEKNY4.js} +5 -5
  180. package/dist/cli-bundle/chunks/{close-many-RZVTUGBG.js → close-many-B6AIC5OQ.js} +15 -14
  181. package/dist/cli-bundle/chunks/close-many-QCINT6I2.js +24 -0
  182. package/dist/cli-bundle/chunks/comments-4SK5EUEJ.js +13 -0
  183. package/dist/cli-bundle/chunks/{comments-TPU7QRBL.js → comments-DM5KV2RS.js} +7 -7
  184. package/dist/cli-bundle/chunks/copy-4KCCLTYQ.js +10 -0
  185. package/dist/cli-bundle/chunks/{copy-DKTSSCK7.js → copy-HEP5SZHB.js} +5 -4
  186. package/dist/cli-bundle/chunks/create-BDKQFPRE.js +30 -0
  187. package/dist/cli-bundle/chunks/{create-EIFBIVNQ.js → create-VCGBCYL2.js} +11 -10
  188. package/dist/cli-bundle/chunks/delete-JWDXPR3H.js +10 -0
  189. package/dist/cli-bundle/chunks/{delete-LCS3VPDH.js → delete-ZSPBTVJD.js} +4 -4
  190. package/dist/cli-bundle/chunks/{deps-YG7UF3VR.js → deps-BZTWWOIE.js} +6 -6
  191. package/dist/cli-bundle/chunks/{deps-UH5EQQUY.js → deps-OVAJOQIE.js} +6 -6
  192. package/dist/cli-bundle/chunks/{docs-G32TK6XS.js → docs-3GFMSWLL.js} +6 -6
  193. package/dist/cli-bundle/chunks/docs-SY2NPT6Y.js +14 -0
  194. package/dist/cli-bundle/chunks/{files-4ALMCSKB.js → files-2SEL4QIU.js} +6 -6
  195. package/dist/cli-bundle/chunks/{files-3H32UQ4K.js → files-FYMMJGNN.js} +6 -6
  196. package/dist/cli-bundle/chunks/focus-4A27YJ2Z.js +10 -0
  197. package/dist/cli-bundle/chunks/{focus-7SOUT5PZ.js → focus-TEUJKTAT.js} +5 -5
  198. package/dist/cli-bundle/chunks/history-compact-7QOKL2NB.js +16 -0
  199. package/dist/cli-bundle/chunks/{history-compact-77BT2LUB.js → history-compact-U7A37VR6.js} +6 -6
  200. package/dist/cli-bundle/chunks/{history-redact-LJPZPNFA.js → history-redact-TNKUO4ZE.js} +4 -4
  201. package/dist/cli-bundle/chunks/{history-redact-PWTTJ3XS.js → history-redact-ZWRUWQY3.js} +4 -4
  202. package/dist/cli-bundle/chunks/{history-repair-I7CBNCV3.js → history-repair-6IU5VWHN.js} +7 -7
  203. package/dist/cli-bundle/chunks/history-repair-GWCGJUM2.js +17 -0
  204. package/dist/cli-bundle/chunks/learnings-DDFAUUX3.js +13 -0
  205. package/dist/cli-bundle/chunks/{learnings-KTYW3AL7.js → learnings-GOEZXMKL.js} +7 -7
  206. package/dist/cli-bundle/chunks/{notes-ZERD3KB2.js → notes-BZWODAEK.js} +7 -7
  207. package/dist/cli-bundle/chunks/notes-OBJ6FL36.js +13 -0
  208. package/dist/cli-bundle/chunks/{plan-OFJUBIM5.js → plan-V57VQTAG.js} +12 -11
  209. package/dist/cli-bundle/chunks/plan-ZMOBD6FX.js +27 -0
  210. package/dist/cli-bundle/chunks/{profile-3THJPIQY.js → profile-BG3N4ETA.js} +9 -9
  211. package/dist/cli-bundle/chunks/{profile-XEZAMMBW.js → profile-XLM45FKV.js} +9 -9
  212. package/dist/cli-bundle/chunks/{register-list-query-BR435Q2H.js → register-list-query-EYYNTGMF.js} +48 -38
  213. package/dist/cli-bundle/chunks/register-list-query-EYYNTGMF.js.map +1 -0
  214. package/dist/cli-bundle/chunks/{register-list-query-RWTWLOBE.js → register-list-query-WGXJPXXY.js} +47 -37
  215. package/dist/cli-bundle/chunks/register-list-query-WGXJPXXY.js.map +7 -0
  216. package/dist/cli-bundle/chunks/{register-mutation-HLWC2WNP.js → register-mutation-3YSDDVOL.js} +131 -105
  217. package/dist/cli-bundle/chunks/register-mutation-3YSDDVOL.js.map +1 -0
  218. package/dist/cli-bundle/chunks/{register-mutation-ZJX5AZM5.js → register-mutation-VDGUMMUY.js} +131 -105
  219. package/dist/cli-bundle/chunks/register-mutation-VDGUMMUY.js.map +7 -0
  220. package/dist/cli-bundle/chunks/{register-operations-744YBJMV.js → register-operations-H4URGAHX.js} +36 -35
  221. package/dist/cli-bundle/chunks/{register-operations-744YBJMV.js.map → register-operations-H4URGAHX.js.map} +1 -1
  222. package/dist/cli-bundle/chunks/{register-operations-UEBJH6AN.js → register-operations-HSO7X77D.js} +34 -33
  223. package/dist/cli-bundle/chunks/{register-operations-UEBJH6AN.js.map → register-operations-HSO7X77D.js.map} +1 -1
  224. package/dist/cli-bundle/chunks/{register-setup-5DA4UZXI.js → register-setup-HZ2KKXK4.js} +13 -13
  225. package/dist/cli-bundle/chunks/{register-setup-6H25M3BH.js → register-setup-WCBKJ3H3.js} +13 -13
  226. package/dist/cli-bundle/chunks/{restore-6TDVSATY.js → restore-3NGRFDPX.js} +7 -6
  227. package/dist/cli-bundle/chunks/restore-LNVNUWHE.js +15 -0
  228. package/dist/cli-bundle/chunks/{schema-TPVTIJPO.js → schema-LMFZ742C.js} +6 -6
  229. package/dist/cli-bundle/chunks/{schema-HFXFSGPG.js → schema-O34O33UW.js} +6 -6
  230. package/dist/cli-bundle/chunks/update-BN6VZSYX.js +24 -0
  231. package/dist/cli-bundle/chunks/{update-LJZCL5SI.js → update-FDLPLKOB.js} +14 -13
  232. package/dist/cli-bundle/chunks/update-many-WCKOPN3K.js +35 -0
  233. package/dist/cli-bundle/chunks/update-many-WCKOPN3K.js.map +7 -0
  234. package/dist/cli-bundle/chunks/update-many-X6DVGOMM.js +39 -0
  235. package/dist/cli-bundle/chunks/update-many-X6DVGOMM.js.map +1 -0
  236. package/dist/cli-bundle/main.js +65 -64
  237. package/dist/cli-bundle/main.js.map +2 -2
  238. package/dist/cli-bundle/sdk-runtime.js +53 -52
  239. package/dist/cli-bundle/sdk-testing.js +6 -6
  240. package/dist/cli-bundle/sdk.js +362 -56
  241. package/dist/cli-bundle/sdk.js.map +4 -4
  242. package/dist/cli.js +10 -4
  243. package/dist/cli.js.map +1 -1
  244. package/dist/core/diagnostics/remediation.js +7 -2
  245. package/dist/core/diagnostics/remediation.js.map +1 -1
  246. package/dist/core/search/background-refresh.d.ts +3 -1
  247. package/dist/core/search/background-refresh.js +34 -6
  248. package/dist/core/search/background-refresh.js.map +1 -1
  249. package/dist/core/search/cache.js +28 -5
  250. package/dist/core/search/cache.js.map +1 -1
  251. package/dist/core/shared/constants.d.ts +2 -0
  252. package/dist/core/shared/constants.js +29 -24
  253. package/dist/core/shared/constants.js.map +1 -1
  254. package/dist/core/store/item-metadata-cache.d.ts +32 -1
  255. package/dist/core/store/item-metadata-cache.js +289 -21
  256. package/dist/core/store/item-metadata-cache.js.map +1 -1
  257. package/dist/core/store/item-store.js +71 -34
  258. package/dist/core/store/item-store.js.map +1 -1
  259. package/dist/core/store/settings.js +9 -3
  260. package/dist/core/store/settings.js.map +1 -1
  261. package/dist/sdk/cli-bootstrap.js +68 -76
  262. package/dist/sdk/cli-bootstrap.js.map +1 -1
  263. package/dist/sdk/compile-cache.d.ts +16 -0
  264. package/dist/sdk/compile-cache.js +73 -0
  265. package/dist/sdk/compile-cache.js.map +1 -0
  266. package/dist/sdk/context-relevance.d.ts +16 -1
  267. package/dist/sdk/context-relevance.js +20 -8
  268. package/dist/sdk/context-relevance.js.map +1 -1
  269. package/dist/sdk/context-signal-store.d.ts +77 -0
  270. package/dist/sdk/context-signal-store.js +201 -0
  271. package/dist/sdk/context-signal-store.js.map +1 -0
  272. package/dist/sdk/dependency-provenance.d.ts +12 -0
  273. package/dist/sdk/dependency-provenance.js +38 -0
  274. package/dist/sdk/dependency-provenance.js.map +1 -0
  275. package/dist/sdk/governance/storage-integrity.d.ts +1 -1
  276. package/dist/sdk/governance/storage-integrity.js +47 -6
  277. package/dist/sdk/governance/storage-integrity.js.map +1 -1
  278. package/dist/sdk/graph/assembly.d.ts +2 -0
  279. package/dist/sdk/graph/assembly.js +51 -4
  280. package/dist/sdk/graph/assembly.js.map +1 -1
  281. package/dist/sdk/graph/run.js +12 -13
  282. package/dist/sdk/graph/run.js.map +1 -1
  283. package/dist/sdk/index.d.ts +5 -0
  284. package/dist/sdk/index.js +7 -2
  285. package/dist/sdk/index.js.map +1 -1
  286. package/dist/sdk/item-metadata-index.d.ts +11 -0
  287. package/dist/sdk/item-metadata-index.js +15 -0
  288. package/dist/sdk/item-metadata-index.js.map +1 -0
  289. package/dist/sdk/merge/index.d.ts +1 -0
  290. package/dist/sdk/merge/index.js +3 -2
  291. package/dist/sdk/merge/index.js.map +1 -1
  292. package/dist/sdk/merge/install.js +25 -9
  293. package/dist/sdk/merge/install.js.map +1 -1
  294. package/dist/sdk/merge/reconcile.d.ts +46 -0
  295. package/dist/sdk/merge/reconcile.js +46 -0
  296. package/dist/sdk/merge/reconcile.js.map +1 -0
  297. package/dist/sdk/query/list.d.ts +5 -4
  298. package/dist/sdk/query/list.js +22 -14
  299. package/dist/sdk/query/list.js.map +1 -1
  300. package/dist/sdk/relationship-history.d.ts +30 -0
  301. package/dist/sdk/relationship-history.js +75 -7
  302. package/dist/sdk/relationship-history.js.map +1 -1
  303. package/dist/sdk/relationship-migration.d.ts +42 -0
  304. package/dist/sdk/relationship-migration.js +78 -0
  305. package/dist/sdk/relationship-migration.js.map +1 -0
  306. package/dist/sdk/structured-mutations.js +4 -25
  307. package/dist/sdk/structured-mutations.js.map +1 -1
  308. package/docs/COMMANDS.md +26 -3
  309. package/docs/CONFIGURATION.md +1 -1
  310. package/docs/MERGE_SAFETY.md +14 -5
  311. package/docs/PERFORMANCE.md +28 -0
  312. package/docs/RELATIONSHIP_GRAPH.md +47 -1
  313. package/docs/SDK.md +78 -5
  314. package/marketplace.json +2 -2
  315. package/package.json +2 -2
  316. package/packages/pm-beads/package.json +1 -1
  317. package/packages/pm-calendar/package.json +1 -1
  318. package/packages/pm-command-kit/package.json +1 -1
  319. package/packages/pm-governance-audit/package.json +1 -1
  320. package/packages/pm-guide-shell/package.json +1 -1
  321. package/packages/pm-kanban/package.json +1 -1
  322. package/packages/pm-lifecycle-hooks/package.json +1 -1
  323. package/packages/pm-linked-test-adapters/package.json +1 -1
  324. package/packages/pm-search-advanced/package.json +1 -1
  325. package/packages/pm-templates/package.json +1 -1
  326. package/packages/pm-todos/package.json +1 -1
  327. package/packages/pm-vcs/package.json +1 -1
  328. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  329. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  330. package/dist/cli-bundle/chunks/append-DFETHAZL.js +0 -11
  331. package/dist/cli-bundle/chunks/chunk-4PUUNQDV.js.map +0 -7
  332. package/dist/cli-bundle/chunks/chunk-4QSQ6XDK.js.map +0 -1
  333. package/dist/cli-bundle/chunks/chunk-7AVEY74G.js.map +0 -7
  334. package/dist/cli-bundle/chunks/chunk-7DOJC3HS.js.map +0 -1
  335. package/dist/cli-bundle/chunks/chunk-7RW4JCU2.js.map +0 -7
  336. package/dist/cli-bundle/chunks/chunk-ADBTSVGK.js.map +0 -7
  337. package/dist/cli-bundle/chunks/chunk-AMJPSANK.js.map +0 -7
  338. package/dist/cli-bundle/chunks/chunk-AS4SAZ5R.js.map +0 -7
  339. package/dist/cli-bundle/chunks/chunk-ATBCUC7Y.js.map +0 -1
  340. package/dist/cli-bundle/chunks/chunk-BKIAH72N.js.map +0 -1
  341. package/dist/cli-bundle/chunks/chunk-FJIFFBJX.js.map +0 -1
  342. package/dist/cli-bundle/chunks/chunk-HYW67VJ5.js.map +0 -1
  343. package/dist/cli-bundle/chunks/chunk-ICDAQ4TD.js.map +0 -1
  344. package/dist/cli-bundle/chunks/chunk-IY6VZ3IW.js.map +0 -7
  345. package/dist/cli-bundle/chunks/chunk-JFD5LPMI.js.map +0 -1
  346. package/dist/cli-bundle/chunks/chunk-K36WV5J6.js.map +0 -1
  347. package/dist/cli-bundle/chunks/chunk-K55VMLSS.js.map +0 -7
  348. package/dist/cli-bundle/chunks/chunk-MWQ2HC2A.js.map +0 -1
  349. package/dist/cli-bundle/chunks/chunk-NUF7ROFH.js.map +0 -1
  350. package/dist/cli-bundle/chunks/chunk-O4BCOJTZ.js.map +0 -7
  351. package/dist/cli-bundle/chunks/chunk-POG76WWZ.js.map +0 -1
  352. package/dist/cli-bundle/chunks/chunk-PQSEQD6E.js.map +0 -1
  353. package/dist/cli-bundle/chunks/chunk-QG4GFLQ6.js.map +0 -7
  354. package/dist/cli-bundle/chunks/chunk-R3P6FZJW.js.map +0 -1
  355. package/dist/cli-bundle/chunks/chunk-RNPZYNHS.js.map +0 -1
  356. package/dist/cli-bundle/chunks/chunk-RPESLSO5.js.map +0 -7
  357. package/dist/cli-bundle/chunks/chunk-SY4SFZSD.js.map +0 -7
  358. package/dist/cli-bundle/chunks/chunk-XJTABV3X.js.map +0 -1
  359. package/dist/cli-bundle/chunks/chunk-YQWCZ5AC.js.map +0 -7
  360. package/dist/cli-bundle/chunks/chunk-Z75ONV25.js.map +0 -7
  361. package/dist/cli-bundle/chunks/chunk-ZTVA4KLN.js.map +0 -7
  362. package/dist/cli-bundle/chunks/close-O5QVZ6ET.js +0 -12
  363. package/dist/cli-bundle/chunks/close-many-5RZXVN4J.js +0 -23
  364. package/dist/cli-bundle/chunks/comments-Z4KV6FU3.js +0 -13
  365. package/dist/cli-bundle/chunks/copy-M7DDI6LS.js +0 -9
  366. package/dist/cli-bundle/chunks/create-RGSPN5GD.js +0 -29
  367. package/dist/cli-bundle/chunks/delete-MD7YXQLH.js +0 -10
  368. package/dist/cli-bundle/chunks/docs-JWWNRC27.js +0 -14
  369. package/dist/cli-bundle/chunks/focus-DRQ6FQH6.js +0 -10
  370. package/dist/cli-bundle/chunks/history-compact-VCKGTX64.js +0 -16
  371. package/dist/cli-bundle/chunks/history-repair-YTDZRK5E.js +0 -17
  372. package/dist/cli-bundle/chunks/learnings-CYNOICKR.js +0 -13
  373. package/dist/cli-bundle/chunks/notes-FGO63FXL.js +0 -13
  374. package/dist/cli-bundle/chunks/plan-SGCDDTYR.js +0 -26
  375. package/dist/cli-bundle/chunks/register-list-query-BR435Q2H.js.map +0 -1
  376. package/dist/cli-bundle/chunks/register-list-query-RWTWLOBE.js.map +0 -7
  377. package/dist/cli-bundle/chunks/register-mutation-HLWC2WNP.js.map +0 -1
  378. package/dist/cli-bundle/chunks/register-mutation-ZJX5AZM5.js.map +0 -7
  379. package/dist/cli-bundle/chunks/restore-RSL7C7LO.js +0 -14
  380. package/dist/cli-bundle/chunks/update-SIA7LH5Y.js +0 -23
  381. package/dist/cli-bundle/chunks/update-many-BDBZVGQL.js +0 -38
  382. package/dist/cli-bundle/chunks/update-many-MOY3A5B3.js +0 -34
  383. /package/dist/cli-bundle/chunks/{append-7OVFYR3C.js.map → append-CYMA7RJT.js.map} +0 -0
  384. /package/dist/cli-bundle/chunks/{append-DFETHAZL.js.map → append-H53CAPMP.js.map} +0 -0
  385. /package/dist/cli-bundle/chunks/{chunk-PFNHX655.js.map → chunk-2P7OK4WG.js.map} +0 -0
  386. /package/dist/cli-bundle/chunks/{chunk-EJDGV4GR.js.map → chunk-3EBGHNNQ.js.map} +0 -0
  387. /package/dist/cli-bundle/chunks/{chunk-DZRV2OPA.js.map → chunk-3EDFN3VV.js.map} +0 -0
  388. /package/dist/cli-bundle/chunks/{chunk-ZOY5K4D3.js.map → chunk-3PWJWLLQ.js.map} +0 -0
  389. /package/dist/cli-bundle/chunks/{chunk-VXOOB6YX.js.map → chunk-3SJAR3CY.js.map} +0 -0
  390. /package/dist/cli-bundle/chunks/{chunk-GTLCVJOE.js.map → chunk-3WVKMF2A.js.map} +0 -0
  391. /package/dist/cli-bundle/chunks/{chunk-LAV26CQG.js.map → chunk-42SYYKA4.js.map} +0 -0
  392. /package/dist/cli-bundle/chunks/{chunk-NLR32VFS.js.map → chunk-4IXLNV7W.js.map} +0 -0
  393. /package/dist/cli-bundle/chunks/{chunk-ABWCF646.js.map → chunk-4YTQVO3V.js.map} +0 -0
  394. /package/dist/cli-bundle/chunks/{chunk-E5XMKOSB.js.map → chunk-5EBRMHI6.js.map} +0 -0
  395. /package/dist/cli-bundle/chunks/{chunk-GKX4NJ7U.js.map → chunk-5K5LHZZX.js.map} +0 -0
  396. /package/dist/cli-bundle/chunks/{chunk-T6PPNM7V.js.map → chunk-5K7BOAB6.js.map} +0 -0
  397. /package/dist/cli-bundle/chunks/{chunk-4QOB7L7I.js.map → chunk-5MUZ54G2.js.map} +0 -0
  398. /package/dist/cli-bundle/chunks/{chunk-SF3DT5HJ.js.map → chunk-5QME4KX2.js.map} +0 -0
  399. /package/dist/cli-bundle/chunks/{chunk-TRSHFPRZ.js.map → chunk-6PM6CPPP.js.map} +0 -0
  400. /package/dist/cli-bundle/chunks/{chunk-OR42SO64.js.map → chunk-7B36A3VT.js.map} +0 -0
  401. /package/dist/cli-bundle/chunks/{chunk-QWRVBJ4D.js.map → chunk-7OR2YKKD.js.map} +0 -0
  402. /package/dist/cli-bundle/chunks/{chunk-FPBMLYPI.js.map → chunk-7QUV54XX.js.map} +0 -0
  403. /package/dist/cli-bundle/chunks/{chunk-WWNL6WMH.js.map → chunk-7WXW6JHG.js.map} +0 -0
  404. /package/dist/cli-bundle/chunks/{chunk-BXNDKOR2.js.map → chunk-A2VL5SVG.js.map} +0 -0
  405. /package/dist/cli-bundle/chunks/{close-QEMOYZN3.js.map → chunk-AXGDUXJW.js.map} +0 -0
  406. /package/dist/cli-bundle/chunks/{chunk-IAQE32BI.js.map → chunk-B2AVNGG3.js.map} +0 -0
  407. /package/dist/cli-bundle/chunks/{chunk-HCEBZNC3.js.map → chunk-BRMPF2RM.js.map} +0 -0
  408. /package/dist/cli-bundle/chunks/{chunk-Z7VWXXJM.js.map → chunk-BTNKMF2A.js.map} +0 -0
  409. /package/dist/cli-bundle/chunks/{chunk-KH44WBAT.js.map → chunk-CD4643VW.js.map} +0 -0
  410. /package/dist/cli-bundle/chunks/{chunk-OWXOPDHD.js.map → chunk-CJEEC5O4.js.map} +0 -0
  411. /package/dist/cli-bundle/chunks/{chunk-PZC2FUOQ.js.map → chunk-CTPKCZCF.js.map} +0 -0
  412. /package/dist/cli-bundle/chunks/{chunk-7W2UAXXT.js.map → chunk-D4OBQVL3.js.map} +0 -0
  413. /package/dist/cli-bundle/chunks/{chunk-EWJWSNRU.js.map → chunk-DM4TYC2A.js.map} +0 -0
  414. /package/dist/cli-bundle/chunks/{chunk-VJQG4BIM.js.map → chunk-DSFTAQ7T.js.map} +0 -0
  415. /package/dist/cli-bundle/chunks/{chunk-AELMUANP.js.map → chunk-DVB6SQU7.js.map} +0 -0
  416. /package/dist/cli-bundle/chunks/{chunk-KBLZ3AA5.js.map → chunk-E3ZWOFSO.js.map} +0 -0
  417. /package/dist/cli-bundle/chunks/{close-O5QVZ6ET.js.map → chunk-EP25DV6P.js.map} +0 -0
  418. /package/dist/cli-bundle/chunks/{chunk-GTK4DTEW.js.map → chunk-F4VCB4WY.js.map} +0 -0
  419. /package/dist/cli-bundle/chunks/{chunk-V22ZPOKN.js.map → chunk-F4XAQUQA.js.map} +0 -0
  420. /package/dist/cli-bundle/chunks/{chunk-QOOTOD3W.js.map → chunk-FGR6IBAF.js.map} +0 -0
  421. /package/dist/cli-bundle/chunks/{chunk-JSLT7WVE.js.map → chunk-FKBMT2Q6.js.map} +0 -0
  422. /package/dist/cli-bundle/chunks/{chunk-QIH77CAG.js.map → chunk-G5RLSSIX.js.map} +0 -0
  423. /package/dist/cli-bundle/chunks/{chunk-P7MTHPJQ.js.map → chunk-GEKRVH3G.js.map} +0 -0
  424. /package/dist/cli-bundle/chunks/{chunk-2L6ZP22J.js.map → chunk-GSP6IZFU.js.map} +0 -0
  425. /package/dist/cli-bundle/chunks/{chunk-ZVZGXPQ5.js.map → chunk-HYZZM3Q2.js.map} +0 -0
  426. /package/dist/cli-bundle/chunks/{chunk-4XGJLADW.js.map → chunk-IHY5SX7O.js.map} +0 -0
  427. /package/dist/cli-bundle/chunks/{chunk-UCBDQI5E.js.map → chunk-IMU7JLUI.js.map} +0 -0
  428. /package/dist/cli-bundle/chunks/{chunk-PEQGTJ5Q.js.map → chunk-JCLXCGIL.js.map} +0 -0
  429. /package/dist/cli-bundle/chunks/{chunk-GROYI4RB.js.map → chunk-JLTHOYR7.js.map} +0 -0
  430. /package/dist/cli-bundle/chunks/{chunk-JHJSFOAM.js.map → chunk-JMPVHM44.js.map} +0 -0
  431. /package/dist/cli-bundle/chunks/{chunk-MATHDCGG.js.map → chunk-JWYG36RV.js.map} +0 -0
  432. /package/dist/cli-bundle/chunks/{chunk-VLRGDBLY.js.map → chunk-KEHOPUHH.js.map} +0 -0
  433. /package/dist/cli-bundle/chunks/{chunk-CPX275C6.js.map → chunk-KPCZL2YK.js.map} +0 -0
  434. /package/dist/cli-bundle/chunks/{chunk-FO6OSVEN.js.map → chunk-LANV45W2.js.map} +0 -0
  435. /package/dist/cli-bundle/chunks/{chunk-LVC72YRD.js.map → chunk-LC5ZUXWE.js.map} +0 -0
  436. /package/dist/cli-bundle/chunks/{chunk-TVYYO5A7.js.map → chunk-MBHYQYCS.js.map} +0 -0
  437. /package/dist/cli-bundle/chunks/{chunk-7656MAUL.js.map → chunk-MUAJHL2R.js.map} +0 -0
  438. /package/dist/cli-bundle/chunks/{chunk-7WCE6Y64.js.map → chunk-NUQCSV4P.js.map} +0 -0
  439. /package/dist/cli-bundle/chunks/{chunk-SZVB53Y3.js.map → chunk-O3GFE2PX.js.map} +0 -0
  440. /package/dist/cli-bundle/chunks/{chunk-OY7DMU5P.js.map → chunk-O43LEUSD.js.map} +0 -0
  441. /package/dist/cli-bundle/chunks/{chunk-LZYP423P.js.map → chunk-OZ25YD4Q.js.map} +0 -0
  442. /package/dist/cli-bundle/chunks/{chunk-VZIZB6QH.js.map → chunk-PKYKQCTJ.js.map} +0 -0
  443. /package/dist/cli-bundle/chunks/{chunk-UZLJOEAC.js.map → chunk-PMRED6QZ.js.map} +0 -0
  444. /package/dist/cli-bundle/chunks/{chunk-K4CI6Y45.js.map → chunk-PWGJCP2V.js.map} +0 -0
  445. /package/dist/cli-bundle/chunks/{chunk-UVN66B3M.js.map → chunk-Q3Z2Y5WJ.js.map} +0 -0
  446. /package/dist/cli-bundle/chunks/{chunk-R7QV7ICM.js.map → chunk-QSXN2FAN.js.map} +0 -0
  447. /package/dist/cli-bundle/chunks/{chunk-5NTE36LD.js.map → chunk-RBECHH5K.js.map} +0 -0
  448. /package/dist/cli-bundle/chunks/{chunk-JXCW2TI2.js.map → chunk-RPNC7M63.js.map} +0 -0
  449. /package/dist/cli-bundle/chunks/{chunk-F2LBF7XJ.js.map → chunk-SUSFH6F7.js.map} +0 -0
  450. /package/dist/cli-bundle/chunks/{chunk-VHXHVTUU.js.map → chunk-TDOPC7UY.js.map} +0 -0
  451. /package/dist/cli-bundle/chunks/{chunk-FSE2IKJQ.js.map → chunk-TWHG646K.js.map} +0 -0
  452. /package/dist/cli-bundle/chunks/{chunk-OCUBRA6D.js.map → chunk-U7U7WGEC.js.map} +0 -0
  453. /package/dist/cli-bundle/chunks/{chunk-PONKZPCJ.js.map → chunk-UFRVIIJ2.js.map} +0 -0
  454. /package/dist/cli-bundle/chunks/{chunk-VNTCM3VW.js.map → chunk-VKX2VZZH.js.map} +0 -0
  455. /package/dist/cli-bundle/chunks/{chunk-6JUTHVQS.js.map → chunk-W2JDNTN3.js.map} +0 -0
  456. /package/dist/cli-bundle/chunks/{chunk-AF2CCM5U.js.map → chunk-XKRVX4B3.js.map} +0 -0
  457. /package/dist/cli-bundle/chunks/{chunk-JGUKMMRS.js.map → chunk-XN4NQZJK.js.map} +0 -0
  458. /package/dist/cli-bundle/chunks/{chunk-3P7UJQOX.js.map → chunk-YKFMLQNK.js.map} +0 -0
  459. /package/dist/cli-bundle/chunks/{chunk-YCIUJJOD.js.map → chunk-YKWKMGL7.js.map} +0 -0
  460. /package/dist/cli-bundle/chunks/{chunk-TOBGV45Y.js.map → chunk-YUKIFPWK.js.map} +0 -0
  461. /package/dist/cli-bundle/chunks/{chunk-72LQ4TKV.js.map → chunk-YYEZEP3E.js.map} +0 -0
  462. /package/dist/cli-bundle/chunks/{chunk-X3W65QK3.js.map → chunk-ZEY3XSZQ.js.map} +0 -0
  463. /package/dist/cli-bundle/chunks/{chunk-QJIKE24M.js.map → chunk-ZQ3UMKWE.js.map} +0 -0
  464. /package/dist/cli-bundle/chunks/{chunk-OG5DVFMA.js.map → chunk-ZXE6SNKO.js.map} +0 -0
  465. /package/dist/cli-bundle/chunks/{close-many-5RZXVN4J.js.map → close-GAUIGOQC.js.map} +0 -0
  466. /package/dist/cli-bundle/chunks/{close-many-RZVTUGBG.js.map → close-SJIEKNY4.js.map} +0 -0
  467. /package/dist/cli-bundle/chunks/{comments-TPU7QRBL.js.map → close-many-B6AIC5OQ.js.map} +0 -0
  468. /package/dist/cli-bundle/chunks/{comments-Z4KV6FU3.js.map → close-many-QCINT6I2.js.map} +0 -0
  469. /package/dist/cli-bundle/chunks/{copy-M7DDI6LS.js.map → comments-4SK5EUEJ.js.map} +0 -0
  470. /package/dist/cli-bundle/chunks/{copy-DKTSSCK7.js.map → comments-DM5KV2RS.js.map} +0 -0
  471. /package/dist/cli-bundle/chunks/{create-RGSPN5GD.js.map → copy-4KCCLTYQ.js.map} +0 -0
  472. /package/dist/cli-bundle/chunks/{create-EIFBIVNQ.js.map → copy-HEP5SZHB.js.map} +0 -0
  473. /package/dist/cli-bundle/chunks/{delete-MD7YXQLH.js.map → create-BDKQFPRE.js.map} +0 -0
  474. /package/dist/cli-bundle/chunks/{delete-LCS3VPDH.js.map → create-VCGBCYL2.js.map} +0 -0
  475. /package/dist/cli-bundle/chunks/{deps-YG7UF3VR.js.map → delete-JWDXPR3H.js.map} +0 -0
  476. /package/dist/cli-bundle/chunks/{deps-UH5EQQUY.js.map → delete-ZSPBTVJD.js.map} +0 -0
  477. /package/dist/cli-bundle/chunks/{docs-JWWNRC27.js.map → deps-BZTWWOIE.js.map} +0 -0
  478. /package/dist/cli-bundle/chunks/{docs-G32TK6XS.js.map → deps-OVAJOQIE.js.map} +0 -0
  479. /package/dist/cli-bundle/chunks/{files-3H32UQ4K.js.map → docs-3GFMSWLL.js.map} +0 -0
  480. /package/dist/cli-bundle/chunks/{files-4ALMCSKB.js.map → docs-SY2NPT6Y.js.map} +0 -0
  481. /package/dist/cli-bundle/chunks/{focus-DRQ6FQH6.js.map → files-2SEL4QIU.js.map} +0 -0
  482. /package/dist/cli-bundle/chunks/{focus-7SOUT5PZ.js.map → files-FYMMJGNN.js.map} +0 -0
  483. /package/dist/cli-bundle/chunks/{history-compact-VCKGTX64.js.map → focus-4A27YJ2Z.js.map} +0 -0
  484. /package/dist/cli-bundle/chunks/{history-compact-77BT2LUB.js.map → focus-TEUJKTAT.js.map} +0 -0
  485. /package/dist/cli-bundle/chunks/{history-redact-PWTTJ3XS.js.map → history-compact-7QOKL2NB.js.map} +0 -0
  486. /package/dist/cli-bundle/chunks/{history-redact-LJPZPNFA.js.map → history-compact-U7A37VR6.js.map} +0 -0
  487. /package/dist/cli-bundle/chunks/{history-repair-I7CBNCV3.js.map → history-redact-TNKUO4ZE.js.map} +0 -0
  488. /package/dist/cli-bundle/chunks/{history-repair-YTDZRK5E.js.map → history-redact-ZWRUWQY3.js.map} +0 -0
  489. /package/dist/cli-bundle/chunks/{learnings-KTYW3AL7.js.map → history-repair-6IU5VWHN.js.map} +0 -0
  490. /package/dist/cli-bundle/chunks/{learnings-CYNOICKR.js.map → history-repair-GWCGJUM2.js.map} +0 -0
  491. /package/dist/cli-bundle/chunks/{notes-FGO63FXL.js.map → learnings-DDFAUUX3.js.map} +0 -0
  492. /package/dist/cli-bundle/chunks/{notes-ZERD3KB2.js.map → learnings-GOEZXMKL.js.map} +0 -0
  493. /package/dist/cli-bundle/chunks/{plan-OFJUBIM5.js.map → notes-BZWODAEK.js.map} +0 -0
  494. /package/dist/cli-bundle/chunks/{plan-SGCDDTYR.js.map → notes-OBJ6FL36.js.map} +0 -0
  495. /package/dist/cli-bundle/chunks/{profile-3THJPIQY.js.map → plan-V57VQTAG.js.map} +0 -0
  496. /package/dist/cli-bundle/chunks/{profile-XEZAMMBW.js.map → plan-ZMOBD6FX.js.map} +0 -0
  497. /package/dist/cli-bundle/chunks/{restore-6TDVSATY.js.map → profile-BG3N4ETA.js.map} +0 -0
  498. /package/dist/cli-bundle/chunks/{restore-RSL7C7LO.js.map → profile-XLM45FKV.js.map} +0 -0
  499. /package/dist/cli-bundle/chunks/{register-setup-5DA4UZXI.js.map → register-setup-HZ2KKXK4.js.map} +0 -0
  500. /package/dist/cli-bundle/chunks/{register-setup-6H25M3BH.js.map → register-setup-WCBKJ3H3.js.map} +0 -0
  501. /package/dist/cli-bundle/chunks/{schema-TPVTIJPO.js.map → restore-3NGRFDPX.js.map} +0 -0
  502. /package/dist/cli-bundle/chunks/{schema-HFXFSGPG.js.map → restore-LNVNUWHE.js.map} +0 -0
  503. /package/dist/cli-bundle/chunks/{update-LJZCL5SI.js.map → schema-LMFZ742C.js.map} +0 -0
  504. /package/dist/cli-bundle/chunks/{update-SIA7LH5Y.js.map → schema-O34O33UW.js.map} +0 -0
  505. /package/dist/cli-bundle/chunks/{update-many-MOY3A5B3.js.map → update-BN6VZSYX.js.map} +0 -0
  506. /package/dist/cli-bundle/chunks/{update-many-BDBZVGQL.js.map → update-FDLPLKOB.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../cli/commands/aggregate.ts","../../../../../../../../sdk/relationship-analytics.ts","../../../../../../../../sdk/graph/centrality.ts","../../../../../../../../sdk/graph/scheduling.ts","../../../../../../../../sdk/graph/durable-cache.ts","../../../../../../../../sdk/graph/remediation.ts","../../../../../../../../sdk/graph/run.ts","../../../../../../../../sdk/item-children.ts","../../../../../../../../sdk/item-schedule.ts","../../../../../../../../cli/commands/get.ts","../../../../../../../../sdk/query/search.ts","../../../../../../../../core/shared/text-normalization.ts","../../../../../../../../core/search/relevance.ts","../../../../../../../../core/search/bm25.ts","../../../../../../../../sdk/query/search-rendering.ts","../../../../../../../../sdk/query/search-pagination.ts","../../../../../../../../sdk/eval.ts","../../../../../../../../core/search/eval.ts"],"sourcesContent":["/**\n * @module cli/commands/aggregate\n *\n * Implements the pm aggregate command surface and its agent-facing runtime behavior.\n */\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { splitCommaList } from \"../../core/shared/split-comma-list.js\";\nimport { nowIso } from \"../../core/shared/time.js\";\nimport { normalizeStatusInput } from \"../../core/item/status.js\";\nimport { parseStatusFilterCsv } from \"../../core/item/status-filter.js\";\nimport {\n resolveRuntimeFieldRegistry,\n resolveRuntimeStatusRegistry,\n type RuntimeStatusRegistry,\n} from \"../../core/schema/runtime-schema.js\";\nimport { resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport { type ItemStatus } from \"../../types/index.js\";\nimport { buildListQueryFilters } from \"./list-filter-shared.js\";\nimport { runList } from \"./list.js\";\n\ntype AggregateGroupField =\n | \"parent\"\n | \"type\"\n | \"priority\"\n | \"status\"\n | \"assignee\"\n | \"tags\"\n | \"sprint\"\n | \"release\";\ntype AggregateGroupValue = string | number | null;\ntype AggregateGroupRecord = Partial<\n Record<AggregateGroupField, AggregateGroupValue>\n>;\ntype AggregateListedItem = {\n type: string;\n status: ItemStatus;\n priority: number;\n parent?: string;\n assignee?: string;\n tags: string[];\n sprint?: string;\n release?: string;\n};\n\nconst AGGREGATE_GROUP_FIELDS: AggregateGroupField[] = [\n \"parent\",\n \"type\",\n \"priority\",\n \"status\",\n \"assignee\",\n \"tags\",\n \"sprint\",\n \"release\",\n];\n\n/** Documents the aggregate options payload exchanged by command, SDK, and package integrations. */\nexport interface AggregateOptions {\n /** Value that configures or reports group by for this contract. */\n groupBy?: string;\n /** Value that configures or reports count for this contract. */\n count?: boolean;\n /** Value that configures or reports completion for this contract. */\n completion?: boolean;\n /** Value that configures or reports sum for this contract. */\n sum?: string;\n /** Value that configures or reports avg for this contract. */\n avg?: string;\n /** Value that configures or reports include unparented for this contract. */\n includeUnparented?: boolean;\n /** Lifecycle state reported for status. */\n status?: string;\n /** Schema type that determines the shape and validation rules for this value. */\n type?: string;\n /** Value that configures or reports tag for this contract. */\n tag?: string;\n /** Value that configures or reports priority for this contract. */\n priority?: string;\n /** Value that configures or reports deadline before for this contract. */\n deadlineBefore?: string;\n /** Value that configures or reports deadline after for this contract. */\n deadlineAfter?: string;\n /** Value that configures or reports assignee for this contract. */\n assignee?: string;\n /** Value that configures or reports assignee filter for this contract. */\n assigneeFilter?: string;\n /** Value that configures or reports parent for this contract. */\n parent?: string;\n /** Value that configures or reports sprint for this contract. */\n sprint?: string;\n /** Value that configures or reports release for this contract. */\n release?: string;\n}\n\n/** Documents the aggregate row payload exchanged by command, SDK, and package integrations. */\nexport interface AggregateRow {\n /** Value that configures or reports group for this contract. */\n group: AggregateGroupRecord;\n /** Human-readable display label for this group. Blank/null group values render with an explicit \"(unassigned)\"-style label (per dimension) so terminal and grep-based consumers are never faced with an ambiguous empty key. The structured `group` record keeps the raw null for machine consumers. */\n group_label: string;\n /** Value that configures or reports count for this contract. */\n count: number;\n /** Value that configures or reports open for this contract. */\n open?: number;\n /** Value that configures or reports in progress for this contract. */\n in_progress?: number;\n /** Value that configures or reports closed for this contract. */\n closed?: number;\n /** Value that configures or reports other for this contract. */\n other?: number;\n /** Value that configures or reports completion pct for this contract. */\n completion_pct?: number;\n /** Number of null entries represented by this result. */\n null_count?: number;\n /** Value that configures or reports sum for this contract. */\n sum?: number | null;\n /** Value that configures or reports avg for this contract. */\n avg?: number | null;\n}\n\n/** Documents the aggregate result payload exchanged by command, SDK, and package integrations. */\nexport interface AggregateResult {\n /** Value that configures or reports groups for this contract. */\n groups: AggregateRow[];\n /** Value that configures or reports count for this contract. */\n count: number;\n /** Value that configures or reports totals for this contract. */\n totals: {\n items_considered: number;\n items_grouped: number;\n items_skipped_unparented: number;\n };\n /** Value that configures or reports filters for this contract. */\n filters: {\n group_by: AggregateGroupField[];\n count: boolean;\n completion: boolean;\n sum?: string | null;\n avg?: string | null;\n numeric_field?: string | null;\n include_unparented: boolean;\n status: ItemStatus | null;\n type: string | null;\n tag: string | null;\n priority: string | null;\n deadline_before: string | null;\n deadline_after: string | null;\n assignee: string | null;\n assignee_filter: string | null;\n parent: string | null;\n sprint: string | null;\n release: string | null;\n };\n /** Value that configures or reports now for this contract. */\n now: string;\n /** Value that configures or reports warnings for this contract. */\n warnings?: string[];\n}\n\nfunction parseStatus(\n raw: string | undefined,\n statusRegistry: RuntimeStatusRegistry,\n): ItemStatus | undefined {\n const statuses = parseStatusFilterCsv(raw, statusRegistry, {\n strict: true,\n flagLabel: \"--status\",\n });\n if (!statuses || statuses.length === 0) {\n return undefined;\n }\n if (statuses.length > 1) {\n throw new PmCliError(\n 'Aggregate --status accepts one status, or the standalone \"all\" sentinel.',\n EXIT_CODE.USAGE,\n );\n }\n return statuses[0];\n}\n\ninterface NumericAggregation {\n field: string;\n sum: boolean;\n avg: boolean;\n}\n\nfunction parseNumericAggregation(\n options: AggregateOptions,\n allowedFields: readonly string[] = [\"estimate\", \"estimated_minutes\", \"priority\"],\n): NumericAggregation | null {\n const sumField = options.sum?.trim();\n const avgField = options.avg?.trim();\n const normalizedSum = sumField && sumField.length > 0 ? sumField : undefined;\n const normalizedAvg = avgField && avgField.length > 0 ? avgField : undefined;\n if (!normalizedSum && !normalizedAvg) {\n return null;\n }\n if (normalizedSum && normalizedAvg && normalizedSum !== normalizedAvg) {\n throw new PmCliError(\n \"Aggregate --sum and --avg must target the same numeric field\",\n EXIT_CODE.USAGE,\n );\n }\n const field = normalizedSum ?? normalizedAvg!;\n if (!allowedFields.includes(field)) {\n throw new PmCliError(\n `Aggregate numeric field \"${field}\" is not registered. Allowed: ${allowedFields.join(\", \")}`,\n EXIT_CODE.USAGE,\n );\n }\n return {\n field,\n sum: normalizedSum !== undefined,\n avg: normalizedAvg !== undefined,\n };\n}\n\nfunction parseGroupBy(raw: string | undefined): AggregateGroupField[] {\n const value = raw?.trim() ?? \"status\";\n if (value.length === 0) {\n throw new PmCliError(\n \"--group-by requires at least one field name\",\n EXIT_CODE.USAGE,\n );\n }\n const requested = splitCommaList(value);\n if (requested.length === 0) {\n throw new PmCliError(\n \"--group-by requires a comma-separated list of fields\",\n EXIT_CODE.USAGE,\n );\n }\n for (const field of requested) {\n if (!AGGREGATE_GROUP_FIELDS.includes(field as AggregateGroupField)) {\n throw new PmCliError(\n `Aggregate group fields must be one of ${AGGREGATE_GROUP_FIELDS.join(\"|\")}; received \"${field}\"`,\n EXIT_CODE.USAGE,\n );\n }\n }\n return requested as AggregateGroupField[];\n}\n\nfunction normalizeTagGroupValue(tags: string[]): string | null {\n const normalized = [\n ...new Set(\n tags\n .map((tag) => tag.trim().toLowerCase())\n .filter((tag) => tag.length > 0),\n ),\n ].sort((left, right) => left.localeCompare(right));\n if (normalized.length === 0) {\n return null;\n }\n return normalized.join(\",\");\n}\n\nfunction resolveGroupValue(\n field: AggregateGroupField,\n item: AggregateListedItem,\n): AggregateGroupValue {\n switch (field) {\n case \"parent\":\n return item.parent ?? null;\n case \"type\":\n return item.type;\n case \"priority\":\n return item.priority;\n case \"status\":\n return item.status;\n case \"assignee\":\n return item.assignee ?? null;\n case \"tags\":\n return normalizeTagGroupValue(item.tags);\n case \"sprint\":\n return item.sprint ?? null;\n case \"release\":\n return item.release ?? null;\n default:\n return null;\n }\n}\n\nfunction compareNullableGroupValue(\n left: AggregateGroupValue | undefined,\n right: AggregateGroupValue | undefined,\n): number {\n const leftValue = left ?? null;\n const rightValue = right ?? null;\n if (leftValue === rightValue) {\n return 0;\n }\n if (leftValue === null) {\n return 1;\n }\n if (rightValue === null) {\n return -1;\n }\n if (typeof leftValue === \"number\" && typeof rightValue === \"number\") {\n return leftValue - rightValue;\n }\n return String(leftValue).localeCompare(String(rightValue));\n}\n\nfunction buildGroupKey(\n groupBy: AggregateGroupField[],\n group: AggregateGroupRecord,\n): string {\n return groupBy\n .map((field) => `${field}:${JSON.stringify(group[field] ?? null)}`)\n .join(\"|\");\n}\n\n/** Explicit display label for an empty/blank group value, keyed by dimension. */\nconst EMPTY_AGGREGATE_GROUP_LABELS: Record<AggregateGroupField, string> = {\n parent: \"(unparented)\",\n type: \"(untyped)\",\n priority: \"(no priority)\",\n status: \"(no status)\",\n assignee: \"(unassigned)\",\n tags: \"(untagged)\",\n sprint: \"(no sprint)\",\n release: \"(no release)\",\n};\n\n/** Render a single group field's value, substituting an explicit label for null. */\nfunction formatGroupFieldLabel(\n field: AggregateGroupField,\n value: AggregateGroupValue | undefined,\n): string {\n if (value === null || value === undefined || value === \"\") {\n return EMPTY_AGGREGATE_GROUP_LABELS[field];\n }\n return String(value);\n}\n\n/** Build the human-readable label for an aggregate row. Single-field grouping yields the bare (possibly substituted) value; multi-field grouping joins each \"field=value\" pair so composite groups stay unambiguous. */\nfunction buildGroupLabel(\n groupBy: AggregateGroupField[],\n group: AggregateGroupRecord,\n): string {\n if (groupBy.length === 1) {\n return formatGroupFieldLabel(groupBy[0], group[groupBy[0]]);\n }\n return groupBy\n .map((field) => `${field}=${formatGroupFieldLabel(field, group[field])}`)\n .join(\" | \");\n}\n\nfunction compareAggregateRows(\n left: AggregateRow,\n right: AggregateRow,\n groupBy: AggregateGroupField[],\n): number {\n for (const field of groupBy) {\n const byField = compareNullableGroupValue(\n left.group[field],\n right.group[field],\n );\n if (byField !== 0) {\n return byField;\n }\n }\n return 0;\n}\n\nfunction readNumericAggregateValue(\n item: AggregateListedItem,\n field: string,\n): number | null {\n const source = item as unknown as Record<string, unknown>;\n const raw = source[field];\n if (typeof raw === \"number\" && Number.isFinite(raw)) {\n return raw;\n }\n if (typeof raw === \"string\") {\n const trimmed = raw.trim();\n if (trimmed.length === 0) {\n return null;\n }\n const parsed = Number(trimmed);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return null;\n}\n\ninterface AggregateAccumulator {\n /** group_label is derived once at finalization, so the accumulator omits it. */\n row: Omit<AggregateRow, \"group_label\">;\n numeric_count: number;\n numeric_sum: number;\n null_count: number;\n open_count: number;\n in_progress_count: number;\n closed_count: number;\n other_count: number;\n}\n\nfunction completionPct(closed: number, total: number): number {\n if (total <= 0) {\n return 0;\n }\n return Math.round((closed / total) * 10000) / 100;\n}\n\nfunction updateCompletionCounts(\n accumulator: AggregateAccumulator,\n status: ItemStatus,\n statusRegistry: RuntimeStatusRegistry,\n): void {\n const normalizedStatus =\n normalizeStatusInput(String(status), statusRegistry) ?? status;\n if (normalizedStatus === statusRegistry.open_status) {\n accumulator.open_count += 1;\n return;\n }\n if (\n normalizedStatus === \"in_progress\" ||\n (statusRegistry.active_statuses.has(normalizedStatus) &&\n normalizedStatus !== statusRegistry.open_status)\n ) {\n accumulator.in_progress_count += 1;\n return;\n }\n if (\n statusRegistry.terminal_done_statuses.has(normalizedStatus) ||\n normalizedStatus === statusRegistry.close_status\n ) {\n accumulator.closed_count += 1;\n return;\n }\n accumulator.other_count += 1;\n}\n\nfunction createAggregateAccumulator(\n group: AggregateGroupRecord,\n numericValue: number | null,\n): AggregateAccumulator {\n return {\n row: {\n group,\n count: 1,\n },\n numeric_count: numericValue === null ? 0 : 1,\n numeric_sum: numericValue ?? 0,\n null_count: numericValue === null ? 1 : 0,\n open_count: 0,\n in_progress_count: 0,\n closed_count: 0,\n other_count: 0,\n };\n}\n\nfunction updateNumericAggregation(\n accumulator: AggregateAccumulator,\n numericValue: number | null,\n): void {\n if (numericValue === null) {\n accumulator.null_count += 1;\n return;\n }\n accumulator.numeric_count += 1;\n accumulator.numeric_sum += numericValue;\n}\n\nfunction updateAggregateAccumulator(params: {\n accumulator: AggregateAccumulator;\n item: AggregateListedItem;\n statusRegistry: RuntimeStatusRegistry;\n includeCompletion: boolean;\n numericAggregation: NumericAggregation | null;\n numericValue: number | null;\n}): void {\n params.accumulator.row.count += 1;\n if (params.includeCompletion) {\n updateCompletionCounts(\n params.accumulator,\n params.item.status,\n params.statusRegistry,\n );\n }\n if (params.numericAggregation !== null) {\n updateNumericAggregation(params.accumulator, params.numericValue);\n }\n}\n\nfunction buildAggregateGroup(\n groupBy: AggregateGroupField[],\n item: AggregateListedItem,\n): AggregateGroupRecord {\n const group: AggregateGroupRecord = {};\n for (const field of groupBy) {\n group[field] = resolveGroupValue(field, item);\n }\n return group;\n}\n\nfunction finalizeAggregateRow(\n entry: AggregateAccumulator,\n groupBy: AggregateGroupField[],\n includeCompletion: boolean,\n numericAggregation: NumericAggregation | null,\n): AggregateRow {\n const row: AggregateRow = {\n ...entry.row,\n group_label: buildGroupLabel(groupBy, entry.row.group),\n };\n if (includeCompletion) {\n row.open = entry.open_count;\n row.in_progress = entry.in_progress_count;\n row.closed = entry.closed_count;\n row.other = entry.other_count;\n row.completion_pct = completionPct(entry.closed_count, entry.row.count);\n }\n if (numericAggregation !== null) {\n row.null_count = entry.null_count;\n if (numericAggregation.sum) {\n row.sum = entry.numeric_sum;\n }\n if (numericAggregation.avg) {\n row.avg =\n entry.numeric_count === 0\n ? null\n : entry.numeric_sum / entry.numeric_count;\n }\n }\n return row;\n}\n\nfunction buildAggregateFilters(params: {\n groupBy: AggregateGroupField[];\n includeCompletion: boolean;\n includeUnparented: boolean;\n status: ItemStatus | undefined;\n options: AggregateOptions;\n numericAggregation: NumericAggregation | null;\n}): AggregateResult[\"filters\"] {\n return {\n group_by: params.groupBy,\n count: true,\n completion: params.includeCompletion,\n include_unparented: params.includeUnparented,\n status: params.status ?? null,\n type: params.options.type ?? null,\n tag: params.options.tag ?? null,\n priority: params.options.priority ?? null,\n deadline_before: params.options.deadlineBefore ?? null,\n deadline_after: params.options.deadlineAfter ?? null,\n assignee: params.options.assignee ?? null,\n assignee_filter: params.options.assigneeFilter ?? null,\n parent: params.options.parent ?? null,\n sprint: params.options.sprint ?? null,\n release: params.options.release ?? null,\n ...(params.numericAggregation !== null\n ? {\n sum: params.options.sum ?? null,\n avg: params.options.avg ?? null,\n numeric_field: params.numericAggregation.field,\n }\n : {}),\n };\n}\n\n/** Implements run aggregate for the public runtime surface of this module. */\nexport async function runAggregate(\n options: AggregateOptions,\n global: GlobalOptions,\n): Promise<AggregateResult> {\n if (options.count === false) {\n throw new PmCliError(\n \"Aggregate grouped counts are always enabled; omit count=false.\",\n EXIT_CODE.USAGE,\n );\n }\n\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n const settings = await readSettings(pmRoot);\n const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);\n const numericFields = [\n \"estimate\",\n \"estimated_minutes\",\n \"priority\",\n ...resolveRuntimeFieldRegistry(settings.schema).definitions\n .filter((definition) => definition.type === \"number\")\n .map((definition) => definition.metadata_key),\n ];\n const groupBy = parseGroupBy(options.groupBy);\n const status = parseStatus(options.status, statusRegistry);\n const numericAggregation = parseNumericAggregation(\n options,\n [...new Set(numericFields)].sort((left, right) => left.localeCompare(right)),\n );\n const includeCompletion = options.completion === true;\n const includeUnparented = options.includeUnparented === true;\n\n const listed = await runList(status, buildListQueryFilters(options), global);\n\n const grouped = new Map<string, AggregateAccumulator>();\n let skippedUnparented = 0;\n let groupedItemCount = 0;\n\n for (const listedItem of listed.items) {\n const item = listedItem as AggregateListedItem;\n const group = buildAggregateGroup(groupBy, item);\n if (\n groupBy.includes(\"parent\") &&\n group.parent === null &&\n !includeUnparented\n ) {\n skippedUnparented += 1;\n continue;\n }\n const key = buildGroupKey(groupBy, group);\n const existing = grouped.get(key);\n const numericValue =\n numericAggregation === null\n ? null\n : readNumericAggregateValue(item, numericAggregation.field);\n if (existing) {\n updateAggregateAccumulator({\n accumulator: existing,\n item,\n statusRegistry,\n includeCompletion,\n numericAggregation,\n numericValue,\n });\n } else {\n const accumulator = createAggregateAccumulator(group, numericValue);\n if (includeCompletion) {\n updateCompletionCounts(accumulator, item.status, statusRegistry);\n }\n grouped.set(key, accumulator);\n }\n groupedItemCount += 1;\n }\n\n const groups = [...grouped.values()]\n .map((entry) =>\n finalizeAggregateRow(\n entry,\n groupBy,\n includeCompletion,\n numericAggregation,\n ),\n )\n .sort((left, right) => compareAggregateRows(left, right, groupBy));\n const warnings =\n listed.warnings && listed.warnings.length > 0 ? listed.warnings : undefined;\n\n return {\n groups,\n count: groups.length,\n totals: {\n items_considered: listed.items.length,\n items_grouped: groupedItemCount,\n items_skipped_unparented: skippedUnparented,\n },\n filters: buildAggregateFilters({\n groupBy,\n includeCompletion,\n includeUnparented,\n status,\n options,\n numericAggregation,\n }),\n now: nowIso(),\n ...(warnings ? { warnings } : {}),\n };\n}\n\n/** Public contract for test only aggregate command, shared by SDK and presentation-layer consumers. */\nexport const _testOnlyAggregateCommand = {\n buildGroupKey,\n compareAggregateRows,\n compareNullableGroupValue,\n completionPct,\n normalizeTagGroupValue,\n parseGroupBy,\n parseNumericAggregation,\n parseStatus,\n readNumericAggregateValue,\n resolveGroupValue,\n updateCompletionCounts,\n};\n","/**\n * @module sdk/relationship-analytics\n *\n * Provides exact, deterministic graph analytics with explicit semantics and\n * provenance suitable for planning, impact analysis, and context selection.\n */\nimport type { RelationshipSnapshot } from \"./relationship-history.js\";\nimport {\n RelationshipGraph,\n RelationshipKindRegistry,\n createRelationshipKindRegistry,\n type RelationshipEdge,\n type RelationshipQueryOptions,\n} from \"./relationships.js\";\n\n/** Exact execution-graph analysis over registered ordering kinds. */\nexport interface RelationshipExecutionAnalysis {\n /** Whether the result is exact rather than sampled or approximate. */\n exact: true;\n /** Whether the order-bearing graph is acyclic. */\n acyclic: boolean;\n /** Deterministic topological order for acyclic nodes. */\n order: string[];\n /** Parallelizable topological layers. */\n layers: string[][];\n /** Nodes with no prerequisites. */\n frontier: string[];\n /** Longest prerequisite distance for each acyclic node. */\n depth: Record<string, number>;\n /** Longest deterministic execution path. */\n criticalPath: string[];\n /** Edge count of the critical path. */\n criticalPathLength: number;\n /** Strongly connected order-bearing components that represent cycles. */\n cycles: string[][];\n /** Semantic provenance for the analysis. */\n provenance: { algorithm: \"kahn-longest-path\"; edgeFamily: \"ordering\" };\n}\n\n/** One affected node with its exact shortest explanation path. */\nexport interface RelationshipImpactRow {\n /** Affected node identifier. */\n id: string;\n /** Shortest relationship distance from the root. */\n distance: number;\n /** Exact path explaining why the node is affected. */\n path: string[];\n}\n\n/** Bounded reverse- or forward-impact result. */\nexport interface RelationshipImpactAnalysis {\n /** Impact origin. */\n root: string;\n /** Deterministic affected-node rows. */\n affected: RelationshipImpactRow[];\n /** Returned rows are exact even when the bounded result is incomplete. */\n exact: true;\n /** Whether configured traversal bounds omitted reachable work. */\n truncated: boolean;\n /** Query work retained for performance and explainability. */\n cost: { visitedNodes: number; inspectedEdges: number };\n}\n\n/** Exact structural summary of the complete graph snapshot. */\nexport interface RelationshipKnowledgeAnalysis {\n /** Weakly connected components, largest then lexicographic. */\n components: string[][];\n /** Strongly connected components over directed stored edges. */\n stronglyConnected: string[][];\n /** Nodes with no relationship edges. */\n orphans: string[];\n /** Maximum-degree nodes and their unique-neighbor degree. */\n hubs: { id: string; degree: number }[];\n /** Whether the result is exact. */\n exact: true;\n /** Semantic provenance for the analysis. */\n provenance: { algorithm: \"component-degree\"; edgeFamily: \"all\" };\n}\n\n/** Edge-level delta between two immutable snapshots. */\nexport interface RelationshipSnapshotComparison {\n /** Earlier snapshot version. */\n fromVersion: number;\n /** Later snapshot version. */\n toVersion: number;\n /** Edges introduced in the later snapshot. */\n added: RelationshipEdge[];\n /** Edges absent from the later snapshot. */\n removed: RelationshipEdge[];\n /** Number of byte-equivalent edges retained. */\n unchangedCount: number;\n /** Whether the comparison is exact. */\n exact: true;\n}\n\n/** Registry override for custom domain semantics. */\nexport interface RelationshipAnalyticsOptions {\n /** Registry used to interpret ordering direction and custom kinds. */\n registry?: RelationshipKindRegistry;\n}\n\nfunction appendNeighbor(\n adjacency: Map<string, Set<string>>,\n source: string,\n target: string,\n): void {\n adjacency.get(source)!.add(target);\n}\n\nfunction createAdjacency(nodes: readonly string[]): Map<string, Set<string>> {\n return new Map(nodes.map((node) => [node, new Set<string>()]));\n}\n\nfunction sortComponents(components: string[][]): string[][] {\n for (const component of components) component.sort();\n return components.sort(\n (left, right) =>\n right.length - left.length || left[0]!.localeCompare(right[0]!),\n );\n}\n\nfunction stableJsonValue(value: unknown): unknown {\n if (Array.isArray(value)) return value.map((entry) => stableJsonValue(entry));\n if (value === null || typeof value !== \"object\") return value;\n const toJSON = (value as { toJSON?: (this: object) => unknown }).toJSON;\n if (typeof toJSON === \"function\") return stableJsonValue(toJSON.call(value));\n return Object.fromEntries(\n Object.entries(value)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, entry]) => [key, stableJsonValue(entry)]),\n );\n}\n\nfunction relationshipEdgeKey(edge: RelationshipEdge): string {\n return JSON.stringify(stableJsonValue(edge));\n}\n\nfunction appendFinishingOrder(\n start: string,\n adjacency: ReadonlyMap<string, ReadonlySet<string>>,\n visited: Set<string>,\n order: string[],\n): void {\n const stack = [{ id: start, expanded: false }];\n while (stack.length > 0) {\n const current = stack.pop()!;\n if (current.expanded) {\n order.push(current.id);\n continue;\n }\n if (visited.has(current.id)) continue;\n visited.add(current.id);\n stack.push({ id: current.id, expanded: true });\n const neighbors = [...adjacency.get(current.id)!].sort().reverse();\n for (const neighbor of neighbors)\n if (!visited.has(neighbor)) stack.push({ id: neighbor, expanded: false });\n }\n}\n\nfunction computeFinishingOrder(\n nodes: readonly string[],\n adjacency: ReadonlyMap<string, ReadonlySet<string>>,\n): string[] {\n const visited = new Set<string>();\n const order: string[] = [];\n for (const start of nodes)\n if (!visited.has(start))\n appendFinishingOrder(start, adjacency, visited, order);\n return order;\n}\n\nfunction collectReverseComponents(\n order: readonly string[],\n reverse: ReadonlyMap<string, ReadonlySet<string>>,\n): string[][] {\n const visited = new Set<string>();\n const components: string[][] = [];\n for (const start of [...order].reverse()) {\n if (visited.has(start)) continue;\n const component: string[] = [];\n const stack = [start];\n visited.add(start);\n while (stack.length > 0) {\n const current = stack.pop()!;\n component.push(current);\n for (const neighbor of reverse.get(current)!) {\n if (visited.has(neighbor)) continue;\n visited.add(neighbor);\n stack.push(neighbor);\n }\n }\n components.push(component);\n }\n return sortComponents(components);\n}\n\nfunction stronglyConnectedComponents(\n nodes: readonly string[],\n adjacency: ReadonlyMap<string, ReadonlySet<string>>,\n): string[][] {\n const reverse = createAdjacency(nodes);\n for (const [source, targets] of adjacency)\n for (const target of targets) appendNeighbor(reverse, target, source);\n return collectReverseComponents(\n computeFinishingOrder(nodes, adjacency),\n reverse,\n );\n}\n\nfunction buildExecutionAdjacency(\n graph: RelationshipGraph,\n registry: RelationshipKindRegistry,\n): Map<string, Set<string>> {\n const adjacency = createAdjacency(graph.nodes());\n for (const edge of graph.edges()) {\n const definition = registry.require(edge.kind);\n if (!definition.ordering) continue;\n // Legacy and JSON-parsed definitions may predate explicit precedence.\n const sourceFirst =\n (definition.precedence ?? \"source_before_target\") ===\n \"source_before_target\";\n appendNeighbor(\n adjacency,\n sourceFirst ? edge.source : edge.target,\n sourceFirst ? edge.target : edge.source,\n );\n }\n return adjacency;\n}\n\nfunction topologicalLayers(\n nodes: readonly string[],\n adjacency: ReadonlyMap<string, ReadonlySet<string>>,\n): string[][] {\n const indegree = new Map(nodes.map((node) => [node, 0]));\n for (const targets of adjacency.values())\n for (const target of targets)\n indegree.set(target, indegree.get(target)! + 1);\n let frontier = nodes.filter((node) => indegree.get(node) === 0).sort();\n const layers: string[][] = [];\n while (frontier.length > 0) {\n layers.push(frontier);\n const next: string[] = [];\n for (const source of frontier) {\n for (const target of adjacency.get(source)!) {\n const remaining = indegree.get(target)! - 1;\n indegree.set(target, remaining);\n if (remaining === 0) next.push(target);\n }\n }\n frontier = next.sort();\n }\n return layers;\n}\n\nfunction longestPath(\n order: readonly string[],\n adjacency: ReadonlyMap<string, ReadonlySet<string>>,\n): { depth: Record<string, number>; path: string[] } {\n const depth = new Map(order.map((node) => [node, 0]));\n const parent = new Map<string, string>();\n for (const source of order) {\n for (const target of adjacency.get(source)!) {\n if (!depth.has(target)) continue;\n const candidate = depth.get(source)! + 1;\n const currentParent = parent.get(target);\n if (\n candidate > depth.get(target)! ||\n (candidate === depth.get(target)! &&\n (currentParent === undefined ||\n source.localeCompare(currentParent) < 0))\n ) {\n depth.set(target, candidate);\n parent.set(target, source);\n }\n }\n }\n const end = [...order].sort(\n (left, right) =>\n depth.get(right)! - depth.get(left)! || left.localeCompare(right),\n )[0];\n const path = end === undefined ? [] : [end];\n while (path[0] !== undefined && parent.has(path[0]!))\n path.unshift(parent.get(path[0]!)!);\n return { depth: Object.fromEntries(depth), path };\n}\n\nfunction reconstructImpactPath(\n root: string,\n target: string,\n parents: ReadonlyMap<string, string>,\n): string[] {\n const path = [target];\n let cursor = target;\n while (cursor !== root) {\n cursor = parents.get(cursor)!;\n path.push(cursor);\n }\n return path.reverse();\n}\n\n/** Analyze registered order-bearing relationships without treating associative cycles as blockers. */\nexport function analyzeRelationshipExecution(\n graph: RelationshipGraph,\n options: RelationshipAnalyticsOptions = {},\n): RelationshipExecutionAnalysis {\n const registry = options.registry ?? createRelationshipKindRegistry();\n const nodes = [...graph.nodes()];\n const adjacency = buildExecutionAdjacency(graph, registry);\n const layers = topologicalLayers(nodes, adjacency);\n const order = layers.flat();\n const acyclic = order.length === nodes.length;\n const cycles = acyclic\n ? []\n : stronglyConnectedComponents(nodes, adjacency).filter(\n (component) =>\n component.length > 1 ||\n adjacency.get(component[0]!)!.has(component[0]!),\n );\n const longest = longestPath(order, adjacency);\n return {\n exact: true,\n acyclic,\n order,\n layers,\n frontier: layers[0] ?? [],\n depth: longest.depth,\n criticalPath: longest.path,\n criticalPathLength: Math.max(0, longest.path.length - 1),\n cycles,\n provenance: { algorithm: \"kahn-longest-path\", edgeFamily: \"ordering\" },\n };\n}\n\n/** Compute bounded impact rows and exact shortest explanation paths. */\nexport function analyzeGraphImpact(\n graph: RelationshipGraph,\n root: string,\n options: RelationshipQueryOptions = {},\n): RelationshipImpactAnalysis {\n const direction = options.direction ?? \"outgoing\";\n const maxDepth = options.maxDepth ?? Number.POSITIVE_INFINITY;\n const limit = options.limit ?? Number.POSITIVE_INFINITY;\n const queue = [{ id: root, depth: 0 }];\n const seen = new Set([root]);\n const parents = new Map<string, string>();\n const affected: RelationshipImpactRow[] = [];\n let visitedNodes = 0;\n let inspectedEdges = 0;\n let truncated = false;\n traversal: for (let index = 0; index < queue.length; index += 1) {\n options.signal?.throwIfAborted();\n const current = queue[index]!;\n visitedNodes += 1;\n const adjacent = graph.adjacency(current.id, {\n direction,\n kinds: options.kinds,\n signal: options.signal,\n });\n inspectedEdges += adjacent.meta.inspectedEdges;\n if (current.depth >= maxDepth) {\n if (adjacent.value.some((id) => !seen.has(id))) truncated = true;\n continue;\n }\n for (const id of adjacent.value) {\n if (seen.has(id)) continue;\n if (affected.length >= limit) {\n truncated = true;\n break traversal;\n }\n seen.add(id);\n parents.set(id, current.id);\n const depth = current.depth + 1;\n affected.push({\n id,\n distance: depth,\n path: reconstructImpactPath(root, id, parents),\n });\n queue.push({ id, depth });\n }\n }\n return {\n root,\n affected,\n exact: true,\n truncated,\n cost: { visitedNodes, inspectedEdges },\n };\n}\n\n/** Analyze weak/strong components, isolates, and exact unique-neighbor hubs. */\nexport function analyzeKnowledgeGraph(\n graph: RelationshipGraph,\n): RelationshipKnowledgeAnalysis {\n const nodes = [...graph.nodes()];\n const weak = createAdjacency(nodes);\n const directed = createAdjacency(nodes);\n for (const edge of graph.edges()) {\n appendNeighbor(weak, edge.source, edge.target);\n appendNeighbor(weak, edge.target, edge.source);\n appendNeighbor(directed, edge.source, edge.target);\n }\n const components: string[][] = [];\n const visited = new Set<string>();\n for (const start of nodes) {\n if (visited.has(start)) continue;\n const component: string[] = [];\n const stack = [start];\n visited.add(start);\n while (stack.length > 0) {\n const current = stack.pop()!;\n component.push(current);\n for (const neighbor of weak.get(current)!) {\n if (visited.has(neighbor)) continue;\n visited.add(neighbor);\n stack.push(neighbor);\n }\n }\n components.push(component);\n }\n const degrees = nodes.map((id) => ({ id, degree: weak.get(id)!.size }));\n const maximum = Math.max(0, ...degrees.map(({ degree }) => degree));\n return {\n components: sortComponents(components),\n stronglyConnected: stronglyConnectedComponents(nodes, directed),\n orphans: degrees.filter(({ degree }) => degree === 0).map(({ id }) => id),\n hubs: degrees.filter(({ degree }) => degree > 0 && degree === maximum),\n exact: true,\n provenance: { algorithm: \"component-degree\", edgeFamily: \"all\" },\n };\n}\n\n/** Compare two immutable relationship snapshots by full normalized edge value. */\nexport function compareRelationshipSnapshots(\n before: RelationshipSnapshot,\n after: RelationshipSnapshot,\n): RelationshipSnapshotComparison {\n const earlier = new Map(\n before.edges.map((edge) => [relationshipEdgeKey(edge), edge]),\n );\n const later = new Map(\n after.edges.map((edge) => [relationshipEdgeKey(edge), edge]),\n );\n return {\n fromVersion: before.version,\n toVersion: after.version,\n added: [...later]\n .filter(([key]) => !earlier.has(key))\n .map(([, edge]) => edge),\n removed: [...earlier]\n .filter(([key]) => !later.has(key))\n .map(([, edge]) => edge),\n unchangedCount: [...earlier.keys()].filter((key) => later.has(key)).length,\n exact: true,\n };\n}\n","/**\n * @module sdk/graph/centrality\n *\n * Structural-importance and fragility analytics over the undirected knowledge\n * graph: exact shortest-path betweenness (Brandes), Wasserman–Faust closeness,\n * undirected degree, and directed fan-in/fan-out per node, plus articulation\n * points and bridges (single points of failure) via an iterative Tarjan\n * low-link search. Every analysis is deterministic, cancellable, exact on the\n * bounded workspace, and reports the visited-node and inspected-edge cost so\n * agents can budget follow-up reads. Adjacency is the simple undirected graph\n * (parallel edges and self-loops collapsed) so a pair connected by any kind\n * counts once.\n */\nimport {\n RelationshipGraph,\n type RelationshipQueryResult,\n} from \"../relationships.js\";\nimport { forEachMatchedRelationshipEdge } from \"./analytics.js\";\nimport { orientOrderingEdge } from \"./traversal.js\";\n\n/** One node ranked by structural centrality with directed fan-in/fan-out. */\nexport interface RelationshipCentralityRow {\n /** Node id. */\n id: string;\n /** Undirected unique-neighbor degree over selected kinds. */\n degree: number;\n /** Distinct ordering predecessors that gate this node (dependency fan-in). */\n inDegree: number;\n /** Distinct ordering successors this node gates (dependency fan-out). */\n outDegree: number;\n /** Shortest-path betweenness centrality, rounded to six decimals. */\n betweenness: number;\n /** Wasserman–Faust closeness centrality, rounded to six decimals. */\n closeness: number;\n}\n\n/** Bounded centrality-analysis controls. */\nexport interface GraphCentralityOptions {\n /** Registered relationship kinds whose edges define adjacency. */\n kinds?: readonly string[];\n /** Abort signal checked once per source sweep. */\n signal?: AbortSignal;\n}\n\n/** Deterministic centrality ranking over the undirected knowledge graph. */\nexport interface RelationshipCentralityAnalysis {\n /** Total indexed graph nodes. */\n nodeCount: number;\n /** Simple undirected edge count over selected kinds. */\n edgeCount: number;\n /** Node rows ranked by betweenness, then degree, then id. */\n rows: RelationshipCentralityRow[];\n}\n\n/** One undirected bridge edge whose removal disconnects its endpoints. */\nexport interface RelationshipBridge {\n /** Lexicographically smaller endpoint. */\n source: string;\n /** Lexicographically larger endpoint. */\n target: string;\n}\n\n/** Bounded cut-structure controls. */\nexport interface GraphCutStructureOptions {\n /** Registered relationship kinds whose edges define adjacency. */\n kinds?: readonly string[];\n /** Abort signal checked once per depth-first step. */\n signal?: AbortSignal;\n}\n\n/** Articulation points and bridges of the undirected knowledge graph. */\nexport interface RelationshipCutStructure {\n /** Sorted articulation-point ids — nodes whose removal adds components. */\n articulationPoints: string[];\n /** Bridge edges sorted by source then target. */\n bridges: RelationshipBridge[];\n}\n\n/** Round a centrality score to six decimals to suppress floating-point noise. */\nfunction roundScore(value: number): number {\n return Math.round(value * 1e6) / 1e6;\n}\n\n/** Add one value to a set-valued map entry, creating the set on demand. */\nfunction addToSetMap(\n map: Map<string, Set<string>>,\n key: string,\n value: string,\n): void {\n const set = map.get(key);\n if (set === undefined) map.set(key, new Set([value]));\n else set.add(value);\n}\n\n/** Build the deterministic simple undirected adjacency over every node. */\nfunction buildSimpleUndirectedAdjacency(\n graph: RelationshipGraph,\n kinds: readonly string[] | undefined,\n): Map<string, string[]> {\n const sets = new Map(graph.nodes().map((id) => [id, new Set<string>()]));\n forEachMatchedRelationshipEdge(graph, kinds, (edge) => {\n sets.get(edge.source)!.add(edge.target);\n sets.get(edge.target)!.add(edge.source);\n });\n const adjacency = new Map<string, string[]>();\n for (const [id, neighbors] of sets) adjacency.set(id, [...neighbors].sort());\n return adjacency;\n}\n\n/**\n * Collect distinct ordering predecessors and successors per node, oriented by\n * each kind's declared precedence so fan-in/fan-out match the SDK's\n * predecessor/successor traversal semantics rather than the stored edge\n * spelling (a `blocked_by` edge counts its target as the predecessor).\n */\nfunction collectOrderingDegrees(\n graph: RelationshipGraph,\n kinds: readonly string[] | undefined,\n): { incoming: Map<string, Set<string>>; outgoing: Map<string, Set<string>> } {\n const incoming = new Map<string, Set<string>>();\n const outgoing = new Map<string, Set<string>>();\n forEachMatchedRelationshipEdge(graph, kinds, (edge, definition) => {\n if (!definition.ordering) return;\n const { predecessor, successor } = orientOrderingEdge(edge, definition);\n // The predecessor gates the successor: predecessor -> successor.\n addToSetMap(outgoing, predecessor, successor);\n addToSetMap(incoming, successor, predecessor);\n });\n return { incoming, outgoing };\n}\n\n/** Single-source shortest-path state accumulated by one Brandes sweep. */\ninterface BrandesSweep {\n /** Nodes in nondecreasing distance (breadth-first dequeue) order. */\n stack: string[];\n /** Number of shortest paths from the source to each node. */\n sigma: Map<string, number>;\n /** Shortest-path predecessors of each node. */\n predecessors: Map<string, string[]>;\n /** Reachable node count excluding the source. */\n reachableCount: number;\n /** Sum of shortest distances to every reachable node. */\n distanceSum: number;\n}\n\n/** Run one breadth-first single-source shortest-path sweep for Brandes accumulation. */\nfunction brandesShortestPaths(\n source: string,\n adjacency: ReadonlyMap<string, readonly string[]>,\n cost: { visitedNodes: number; inspectedEdges: number },\n): BrandesSweep {\n const distance = new Map<string, number>([[source, 0]]);\n const sigma = new Map<string, number>([[source, 1]]);\n const predecessors = new Map<string, string[]>();\n const stack: string[] = [];\n const queue = [source];\n let reachableCount = 0;\n let distanceSum = 0;\n for (let index = 0; index < queue.length; index += 1) {\n const node = queue[index]!;\n cost.visitedNodes += 1;\n stack.push(node);\n const nodeDistance = distance.get(node)!;\n if (node !== source) {\n reachableCount += 1;\n distanceSum += nodeDistance;\n }\n for (const neighbor of adjacency.get(node)!) {\n cost.inspectedEdges += 1;\n if (!distance.has(neighbor)) {\n distance.set(neighbor, nodeDistance + 1);\n queue.push(neighbor);\n }\n if (distance.get(neighbor) === nodeDistance + 1) {\n sigma.set(neighbor, (sigma.get(neighbor) ?? 0) + sigma.get(node)!);\n const predecessorList = predecessors.get(neighbor);\n if (predecessorList === undefined) predecessors.set(neighbor, [node]);\n else predecessorList.push(node);\n }\n }\n }\n return { stack, sigma, predecessors, reachableCount, distanceSum };\n}\n\n/** Fold one completed sweep's dependencies back into the running betweenness totals. */\nfunction accumulateBetweenness(\n sweep: BrandesSweep,\n source: string,\n betweenness: Map<string, number>,\n): void {\n const dependency = new Map<string, number>();\n for (let index = sweep.stack.length - 1; index >= 0; index -= 1) {\n const node = sweep.stack[index]!;\n const share = (1 + (dependency.get(node) ?? 0)) / sweep.sigma.get(node)!;\n for (const predecessor of sweep.predecessors.get(node) ?? []) {\n dependency.set(\n predecessor,\n (dependency.get(predecessor) ?? 0) + sweep.sigma.get(predecessor)! * share,\n );\n }\n if (node !== source)\n betweenness.set(node, (betweenness.get(node) ?? 0) + (dependency.get(node) ?? 0));\n }\n}\n\n/**\n * Wasserman–Faust closeness normalizes reachability so disconnected graphs\n * compare fairly. A reachable count above zero implies a positive distance sum\n * (every shortest distance is at least one), so those two guards suffice.\n */\nfunction wassermanFaustCloseness(sweep: BrandesSweep, nodeCount: number): number {\n if (nodeCount <= 1 || sweep.reachableCount === 0) return 0;\n return (\n (sweep.reachableCount / (nodeCount - 1)) *\n (sweep.reachableCount / sweep.distanceSum)\n );\n}\n\n/** Assemble one ranked centrality row from the accumulated scores. */\nfunction centralityRow(\n id: string,\n adjacency: ReadonlyMap<string, readonly string[]>,\n directed: ReturnType<typeof collectOrderingDegrees>,\n betweenness: Map<string, number>,\n closeness: Map<string, number>,\n): RelationshipCentralityRow {\n return {\n id,\n degree: adjacency.get(id)!.length,\n inDegree: directed.incoming.get(id)?.size ?? 0,\n outDegree: directed.outgoing.get(id)?.size ?? 0,\n // Undirected betweenness double-counts each ordered pair; halve it.\n betweenness: roundScore((betweenness.get(id) ?? 0) / 2),\n // Every node is a sweep source, so closeness is always populated.\n closeness: roundScore(closeness.get(id)!),\n };\n}\n\n/**\n * Compute exact shortest-path betweenness (Brandes), Wasserman–Faust closeness,\n * undirected degree, and directed fan-in/fan-out for every node over the simple\n * undirected graph induced by the selected kinds. Rows rank by betweenness, then\n * degree, then id. The result is exact on the bounded workspace; callers bound\n * the returned rows for token-aware projection.\n */\nexport function computeRelationshipCentrality(\n graph: RelationshipGraph,\n options: GraphCentralityOptions = {},\n): RelationshipQueryResult<RelationshipCentralityAnalysis> {\n const adjacency = buildSimpleUndirectedAdjacency(graph, options.kinds);\n const directed = collectOrderingDegrees(graph, options.kinds);\n const nodes = graph.nodes();\n const betweenness = new Map<string, number>();\n const closeness = new Map<string, number>();\n const cost = { visitedNodes: 0, inspectedEdges: 0 };\n for (const source of nodes) {\n options.signal?.throwIfAborted();\n const sweep = brandesShortestPaths(source, adjacency, cost);\n closeness.set(source, wassermanFaustCloseness(sweep, nodes.length));\n accumulateBetweenness(sweep, source, betweenness);\n }\n let degreeSum = 0;\n for (const neighbors of adjacency.values()) degreeSum += neighbors.length;\n const rows = nodes\n .map((id) => centralityRow(id, adjacency, directed, betweenness, closeness))\n .sort(\n (left, right) =>\n right.betweenness - left.betweenness ||\n right.degree - left.degree ||\n left.id.localeCompare(right.id),\n );\n return {\n value: { nodeCount: nodes.length, edgeCount: degreeSum / 2, rows },\n meta: {\n visitedNodes: cost.visitedNodes,\n inspectedEdges: cost.inspectedEdges,\n truncated: false,\n },\n };\n}\n\n/** Order one bridge endpoint pair deterministically. */\nfunction orderedBridge(left: string, right: string): RelationshipBridge {\n return left <= right\n ? { source: left, target: right }\n : { source: right, target: left };\n}\n\n/** Mutable depth-first frame for the iterative articulation/bridge search. */\ninterface CutFrame {\n /** Node owned by this frame. */\n node: string;\n /** Depth-first tree parent, or null at a component root. */\n parent: string | null;\n /** Next unexplored neighbor index in the node's adjacency. */\n neighborIndex: number;\n /** Depth-first tree children discovered through this frame. */\n children: number;\n}\n\n/** Shared low-link state threaded through the iterative cut-structure search. */\ninterface CutState {\n /** Discovery index per visited node. */\n discovery: Map<string, number>;\n /** Low-link value per visited node. */\n low: Map<string, number>;\n /** Monotonic discovery counter. */\n timer: number;\n /** Articulation points found so far. */\n articulation: Set<string>;\n /** Bridge edges found so far. */\n bridges: RelationshipBridge[];\n /** Adjacency reads performed. */\n inspectedEdges: number;\n}\n\n/**\n * Advance the top frame by one neighbor: descend into an undiscovered neighbor,\n * or relax the low-link against a back edge. Returns the discovered child frame\n * to push, or undefined when the step consumed a back edge or the tree parent.\n */\nfunction advanceCutFrame(\n frame: CutFrame,\n adjacency: ReadonlyMap<string, readonly string[]>,\n state: CutState,\n): CutFrame | undefined {\n const neighbors = adjacency.get(frame.node)!;\n const neighbor = neighbors[frame.neighborIndex]!;\n frame.neighborIndex += 1;\n state.inspectedEdges += 1;\n if (neighbor === frame.parent) return undefined;\n if (state.discovery.has(neighbor)) {\n state.low.set(\n frame.node,\n Math.min(state.low.get(frame.node)!, state.discovery.get(neighbor)!),\n );\n return undefined;\n }\n frame.children += 1;\n state.discovery.set(neighbor, state.timer);\n state.low.set(neighbor, state.timer);\n state.timer += 1;\n return { node: neighbor, parent: frame.node, neighborIndex: 0, children: 0 };\n}\n\n/** Retreat from a finished frame: fold its low-link into its parent and flag cuts. */\nfunction retreatCutFrame(frame: CutFrame, root: string, state: CutState): void {\n if (frame.parent === null) {\n if (frame.children > 1) state.articulation.add(frame.node);\n return;\n }\n const parent = frame.parent;\n const childLow = state.low.get(frame.node)!;\n state.low.set(parent, Math.min(state.low.get(parent)!, childLow));\n if (parent !== root && childLow >= state.discovery.get(parent)!)\n state.articulation.add(parent);\n if (childLow > state.discovery.get(parent)!)\n state.bridges.push(orderedBridge(parent, frame.node));\n}\n\n/** Walk one connected component's depth-first tree, updating low-links and cuts. */\nfunction searchComponentCuts(\n root: string,\n adjacency: ReadonlyMap<string, readonly string[]>,\n state: CutState,\n signal: AbortSignal | undefined,\n): void {\n state.discovery.set(root, state.timer);\n state.low.set(root, state.timer);\n state.timer += 1;\n const stack: CutFrame[] = [\n { node: root, parent: null, neighborIndex: 0, children: 0 },\n ];\n while (stack.length > 0) {\n signal?.throwIfAborted();\n const frame = stack.at(-1)!;\n if (frame.neighborIndex < adjacency.get(frame.node)!.length) {\n const child = advanceCutFrame(frame, adjacency, state);\n if (child !== undefined) stack.push(child);\n } else {\n retreatCutFrame(frame, root, state);\n stack.pop();\n }\n }\n}\n\n/**\n * Find articulation points and bridges of the undirected knowledge graph with\n * an iterative Tarjan low-link search over the simple adjacency. An articulation\n * point is a node whose removal increases the connected-component count; a bridge\n * is an edge whose removal does the same — both are single points of failure in\n * the relationship graph. Results are deterministic and exact.\n */\nexport function findRelationshipCutStructure(\n graph: RelationshipGraph,\n options: GraphCutStructureOptions = {},\n): RelationshipQueryResult<RelationshipCutStructure> {\n const adjacency = buildSimpleUndirectedAdjacency(graph, options.kinds);\n const state: CutState = {\n discovery: new Map(),\n low: new Map(),\n timer: 0,\n articulation: new Set(),\n bridges: [],\n inspectedEdges: 0,\n };\n for (const root of graph.nodes()) {\n if (state.discovery.has(root)) continue;\n searchComponentCuts(root, adjacency, state, options.signal);\n }\n return {\n value: {\n articulationPoints: [...state.articulation].sort(),\n bridges: state.bridges.sort(\n (left, right) =>\n left.source.localeCompare(right.source) ||\n left.target.localeCompare(right.target),\n ),\n },\n meta: {\n visitedNodes: state.discovery.size,\n inspectedEdges: state.inspectedEdges,\n truncated: false,\n },\n };\n}\n","/**\n * @module sdk/graph/scheduling\n *\n * Critical Path Method (CPM) scheduling over the order-bearing relationship\n * DAG. The forward pass — topological order, earliest-start distances, the\n * longest deterministic path, and genuine-cycle isolation — is reused from the\n * exact execution analysis; this module adds the backward pass that derives\n * each task's latest start, latest finish, and total float (slack), then\n * classifies zero-slack tasks as critical. Durations are unit-weighted so the\n * schedule is deterministic and metadata-independent: slack counts how many\n * whole prerequisite hops a task can drift without extending the makespan.\n * Only tasks with a well-defined earliest start are scheduled: nodes with no\n * order-bearing edge, genuine ordering cycles, and any task transitively gated\n * by a cycle (whose earliest start is undefined) are all omitted from `rows`.\n * Genuine ordering cycles are additionally reported in `cycles`.\n */\nimport {\n analyzeRelationshipExecution,\n type RelationshipExecutionAnalysis,\n} from \"../relationship-analytics.js\";\nimport { RelationshipGraph } from \"../relationships.js\";\nimport { orientOrderingEdge } from \"./traversal.js\";\n\n/** One scheduled task row with its earliest/latest window and total float. */\nexport interface RelationshipScheduleRow {\n /** Scheduled task id. */\n id: string;\n /** Longest prerequisite distance from any source (earliest start). */\n earliestStart: number;\n /** Earliest start plus the unit task duration. */\n earliestFinish: number;\n /** Latest start that still preserves the makespan. */\n latestStart: number;\n /** Latest finish that still preserves the makespan. */\n latestFinish: number;\n /** Total float: latest start minus earliest start. */\n slack: number;\n /** Whether the task has zero slack and lies on a critical path. */\n critical: boolean;\n}\n\n/** Bounded schedule-analysis controls. */\nexport interface GraphScheduleOptions {\n /** Abort signal checked once at entry, before the forward pass. */\n signal?: AbortSignal;\n}\n\n/** Deterministic critical-path schedule of the order-bearing subgraph. */\nexport interface RelationshipScheduleAnalysis {\n /** Whether the result is exact rather than sampled or approximate. */\n exact: true;\n /** Whether the order-bearing graph is acyclic. */\n acyclic: boolean;\n /** Total makespan in unit task durations; zero when nothing is scheduled. */\n makespan: number;\n /** Number of tasks participating in the order-bearing DAG. */\n scheduledCount: number;\n /** Longest deterministic execution path — a canonical zero-slack chain. */\n criticalPath: string[];\n /** Edge count of the critical path. */\n criticalPathLength: number;\n /** Genuine ordering cycles, excluded from scheduling. */\n cycles: string[][];\n /** Scheduled rows sorted by ascending slack, then earliest start, then id. */\n rows: RelationshipScheduleRow[];\n /** Semantic provenance for the analysis. */\n provenance: {\n algorithm: \"critical-path-method\";\n edgeFamily: \"ordering\";\n weighting: \"unit\";\n };\n}\n\n/** Forward order-bearing adjacency restricted to tasks that carry an ordering edge. */\ninterface OrderingParticipation {\n /** Predecessor-to-successor adjacency in execution orientation. */\n forward: Map<string, Set<string>>;\n /** Ids that appear as an endpoint of at least one ordering edge. */\n participants: Set<string>;\n}\n\n/**\n * Collect the execution-oriented forward adjacency and the set of tasks that\n * carry any order-bearing edge. Each ordering edge is oriented through the\n * registry's declared precedence so inverse spellings agree, and self-loops\n * (which the execution cycle analysis reports) never enter the adjacency.\n */\nfunction collectOrderingParticipation(\n graph: RelationshipGraph,\n): OrderingParticipation {\n const registry = graph.registry();\n const forward = new Map<string, Set<string>>();\n const participants = new Set<string>();\n for (const edge of graph.edges()) {\n const definition = registry.require(edge.kind);\n if (!definition.ordering) continue;\n const { predecessor, successor } = orientOrderingEdge(edge, definition);\n participants.add(predecessor);\n participants.add(successor);\n if (predecessor === successor) continue;\n const targets = forward.get(predecessor);\n if (targets === undefined) forward.set(predecessor, new Set([successor]));\n else targets.add(successor);\n }\n return { forward, participants };\n}\n\n/** Resolve a task's latest finish from its acyclic successors, or the makespan when it has none. */\nfunction latestFinishFor(\n successors: Set<string> | undefined,\n acyclic: Set<string>,\n latestStart: Map<string, number>,\n makespan: number,\n): number {\n if (successors === undefined) return makespan;\n let bound = makespan;\n for (const successor of successors) {\n if (!acyclic.has(successor)) continue;\n bound = Math.min(bound, latestStart.get(successor)!);\n }\n return bound;\n}\n\n/** Build one scheduled row from the forward earliest-start depth and backward latest-start. */\nfunction scheduleRow(\n id: string,\n earliestStart: number,\n latestStart: number,\n): RelationshipScheduleRow {\n const slack = latestStart - earliestStart;\n return {\n id,\n earliestStart,\n earliestFinish: earliestStart + 1,\n latestStart,\n latestFinish: latestStart + 1,\n slack,\n critical: slack === 0,\n };\n}\n\n/** Run the backward CPM pass over the acyclic participants in reverse topological order. */\nfunction computeScheduleRows(\n topoParticipants: readonly string[],\n participation: OrderingParticipation,\n depth: Record<string, number>,\n acyclic: Set<string>,\n makespan: number,\n): RelationshipScheduleRow[] {\n const latestStart = new Map<string, number>();\n for (let index = topoParticipants.length - 1; index >= 0; index -= 1) {\n const id = topoParticipants[index]!;\n const finish = latestFinishFor(\n participation.forward.get(id),\n acyclic,\n latestStart,\n makespan,\n );\n latestStart.set(id, finish - 1);\n }\n return topoParticipants\n .map((id) => scheduleRow(id, depth[id]!, latestStart.get(id)!))\n .sort(\n (left, right) =>\n left.slack - right.slack ||\n left.earliestStart - right.earliestStart ||\n left.id.localeCompare(right.id),\n );\n}\n\n/**\n * Compute the deterministic critical-path schedule of the order-bearing\n * subgraph. Earliest-start distances and the critical path come from the exact\n * execution analysis; the backward pass then assigns each task the latest start\n * that preserves the makespan and reports total float as `slack`. Zero-slack\n * tasks are `critical`. Only tasks with a well-defined earliest start are\n * scheduled: tasks with no order-bearing edge, tasks on a genuine ordering\n * cycle, and tasks transitively gated by a cycle (excluded from Kahn's partial\n * order) are all omitted from `rows`; genuine cycles are reported in `cycles`.\n */\nexport function analyzeRelationshipSchedule(\n graph: RelationshipGraph,\n options: GraphScheduleOptions = {},\n): RelationshipScheduleAnalysis {\n options.signal?.throwIfAborted();\n const execution: RelationshipExecutionAnalysis = analyzeRelationshipExecution(\n graph,\n { registry: graph.registry() },\n );\n const participation = collectOrderingParticipation(graph);\n const acyclic = new Set(execution.order);\n const topoParticipants = execution.order.filter((id) =>\n participation.participants.has(id),\n );\n const makespan = topoParticipants.reduce(\n (peak, id) => Math.max(peak, execution.depth[id]! + 1),\n 0,\n );\n const rows = computeScheduleRows(\n topoParticipants,\n participation,\n execution.depth,\n acyclic,\n makespan,\n );\n const scheduled = rows.length > 0;\n return {\n exact: true,\n acyclic: execution.acyclic,\n makespan,\n scheduledCount: rows.length,\n // A single-node execution \"path\" over a workspace with no order-bearing\n // edge is not a real critical path, so report it only when work is scheduled.\n criticalPath: scheduled ? execution.criticalPath : [],\n criticalPathLength: scheduled ? execution.criticalPathLength : 0,\n cycles: execution.cycles,\n rows,\n provenance: {\n algorithm: \"critical-path-method\",\n edgeFamily: \"ordering\",\n weighting: \"unit\",\n },\n };\n}\n","/**\n * @module sdk/graph/durable-cache\n *\n * Durable, rebuildable graph query index persisted under the workspace\n * `runtime/` cache directory. One-shot CLI invocations lose the in-process\n * {@link WorkspaceGraphCache} memo between commands; this store persists the\n * fingerprint-keyed deterministic query results (and the audit census\n * baseline) across processes so repeated bounded queries on an unchanged\n * workspace are answered without re-running assembly-derived analysis. The\n * index is never authoritative: every entry is rebuildable from item storage,\n * a fingerprint mismatch invalidates the whole envelope, corrupt or\n * version-drifted files are ignored and rewritten, and writes are atomic\n * (temp-file rename) so a crash can never publish a torn index. Persistence\n * is optional for small projects: envelopes are written only above an item\n * threshold or after an explicit `pm graph index --rebuild` opt-in.\n */\nimport path from \"node:path\";\nimport {\n readFileIfExists,\n removeFileIfExists,\n writeFileAtomic,\n} from \"../../core/fs/fs-utils.js\";\nimport { acquireLock } from \"../../core/lock/lock.js\";\nimport type { RelationshipAuditSnapshot } from \"./governance.js\";\n\n/** Envelope format version; any change invalidates persisted entries. */\nexport const GRAPH_DURABLE_CACHE_VERSION = 1;\n\n/** Workspaces below this item count skip implicit persistence. */\nexport const GRAPH_DURABLE_CACHE_MIN_ITEMS = 500;\n\n/** Maximum memoized query results retained in one persisted envelope. */\nconst MAX_DURABLE_RESULTS = 64;\nconst DURABLE_GRAPH_CACHE_LOCK_ID = \"graph-durable-cache\";\n\n/** Serialize cache read-merge-write and clear operations across processes. */\nfunction acquireDurableGraphCacheLock(\n pmRoot: string,\n): Promise<() => Promise<void>> {\n return acquireLock(\n pmRoot,\n DURABLE_GRAPH_CACHE_LOCK_ID,\n 30,\n `graph-cache:${process.pid}`,\n false,\n false,\n 3_000,\n );\n}\n\n/** Persisted durable graph cache envelope keyed by one workspace fingerprint. */\nexport interface DurableGraphCacheEnvelope {\n /** Envelope format version guarding decode compatibility. */\n version: number;\n /** Full workspace graph fingerprint every entry answers for. */\n fingerprint: string;\n /** ISO timestamp of the last persisted write. */\n saved_at: string;\n /** Deterministic query results keyed by their canonical query key. */\n results: Record<string, unknown>;\n}\n\n/** Compact durable index status projection for observability surfaces. */\nexport interface DurableGraphCacheStatus {\n /** Whether an envelope file exists on disk. */\n exists: boolean;\n /** Whether the stored fingerprint matches the current workspace snapshot. */\n fresh: boolean;\n /** Stored entry count, 0 when absent. */\n entry_count: number;\n /** Truncated stored fingerprint, absent when no envelope exists. */\n fingerprint?: string;\n /** ISO timestamp of the last persisted write, absent when no envelope exists. */\n saved_at?: string;\n /** Envelope file size in bytes, absent when no envelope exists. */\n bytes?: number;\n}\n\n/** Resolve the durable graph cache file path for one workspace root. */\nexport function durableGraphCachePath(pmRoot: string): string {\n return path.join(pmRoot, \"runtime\", \"graph-cache.json\");\n}\n\n/** Resolve the persisted audit census baseline path for one workspace root. */\nexport function graphAuditBaselinePath(pmRoot: string): string {\n return path.join(pmRoot, \"runtime\", \"graph-audit-baseline.json\");\n}\n\n/** Decode one persisted JSON envelope, returning undefined on any defect. */\nfunction decodeEnvelope(\n raw: string | null,\n): DurableGraphCacheEnvelope | undefined {\n if (raw === null) return undefined;\n try {\n const parsed: unknown = JSON.parse(raw);\n if (\n typeof parsed !== \"object\" ||\n parsed === null ||\n (parsed as DurableGraphCacheEnvelope).version !==\n GRAPH_DURABLE_CACHE_VERSION ||\n typeof (parsed as DurableGraphCacheEnvelope).fingerprint !== \"string\" ||\n typeof (parsed as DurableGraphCacheEnvelope).saved_at !== \"string\" ||\n typeof (parsed as DurableGraphCacheEnvelope).results !== \"object\" ||\n (parsed as DurableGraphCacheEnvelope).results === null ||\n Array.isArray((parsed as DurableGraphCacheEnvelope).results)\n )\n return undefined;\n return parsed as DurableGraphCacheEnvelope;\n } catch {\n // Corrupt or torn writes must never break queries; the index rebuilds.\n return undefined;\n }\n}\n\n/** One opened durable index view bound to the current workspace fingerprint. */\nexport interface DurableGraphCacheView {\n /** Whether any envelope file exists on disk, fresh or not. */\n exists: boolean;\n /** Whether the stored envelope answers for the current fingerprint. */\n fresh: boolean;\n /** Fingerprint-fresh persisted query results; empty when absent or stale. */\n results: Record<string, unknown>;\n}\n\n/**\n * Open the persisted envelope against the current workspace fingerprint. A\n * missing, corrupt, version-drifted, or fingerprint-mismatched envelope reads\n * as empty so stale entries can never answer for a mutated workspace.\n */\nexport async function openDurableGraphCache(\n pmRoot: string,\n fingerprint: string,\n): Promise<DurableGraphCacheView> {\n const raw = await readFileIfExists(durableGraphCachePath(pmRoot));\n const envelope = decodeEnvelope(raw);\n const fresh = envelope?.fingerprint === fingerprint;\n return {\n exists: raw !== null,\n fresh,\n results: fresh ? envelope!.results : {},\n };\n}\n\n/**\n * Persist one query result into the durable envelope, replacing any envelope\n * recorded for a different fingerprint and trimming the oldest entries beyond\n * the retention bound. A cross-process lock protects the read-merge-write, and\n * the final write is atomic, so concurrent queries retain each other's entries.\n */\nexport async function persistDurableGraphResult(\n pmRoot: string,\n fingerprint: string,\n view: DurableGraphCacheView,\n queryKey: string,\n result: unknown,\n): Promise<void> {\n const release = await acquireDurableGraphCacheLock(pmRoot);\n try {\n const envelope = decodeEnvelope(\n await readFileIfExists(durableGraphCachePath(pmRoot)),\n );\n const results =\n envelope?.fingerprint === fingerprint ? envelope.results : {};\n delete results[queryKey];\n results[queryKey] = result;\n const keys = Object.keys(results);\n for (const stale of keys.slice(\n 0,\n Math.max(0, keys.length - MAX_DURABLE_RESULTS),\n ))\n delete results[stale];\n await writeFileAtomic(\n durableGraphCachePath(pmRoot),\n JSON.stringify({\n version: GRAPH_DURABLE_CACHE_VERSION,\n fingerprint,\n saved_at: new Date().toISOString(),\n results,\n }),\n );\n view.results = results;\n } finally {\n await release();\n }\n}\n\n/** Delete the persisted durable graph cache envelope when present. */\nexport async function clearDurableGraphCache(pmRoot: string): Promise<void> {\n const release = await acquireDurableGraphCacheLock(pmRoot);\n try {\n await removeFileIfExists(durableGraphCachePath(pmRoot));\n } finally {\n await release();\n }\n}\n\n/** Report the durable index status against the current workspace fingerprint. */\nexport async function durableGraphCacheStatus(\n pmRoot: string,\n fingerprint: string,\n): Promise<DurableGraphCacheStatus> {\n const cachePath = durableGraphCachePath(pmRoot);\n const raw = await readFileIfExists(cachePath);\n const envelope = decodeEnvelope(raw);\n if (envelope === undefined)\n return { exists: raw !== null, fresh: false, entry_count: 0 };\n return {\n exists: true,\n fresh: envelope.fingerprint === fingerprint,\n entry_count: Object.keys(envelope.results).length,\n fingerprint: envelope.fingerprint.slice(0, 12),\n saved_at: envelope.saved_at,\n bytes: Buffer.byteLength(raw!, \"utf8\"),\n };\n}\n\n/**\n * Decide whether implicit persistence applies to this invocation. Small\n * workspaces skip the index unless an envelope already exists — the explicit\n * `pm graph index --rebuild` opt-in creates it and thereby enables writes.\n */\nexport function shouldPersistDurableGraphCache(\n itemCount: number,\n envelopeExists: boolean,\n): boolean {\n return envelopeExists || itemCount >= GRAPH_DURABLE_CACHE_MIN_ITEMS;\n}\n\n/** Return whether a decoded value is a string-keyed non-negative integer count map. */\nfunction isNonnegativeCountRecord(\n value: unknown,\n): value is Record<string, number> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n Object.values(value).every((count) => Number.isInteger(count) && count >= 0)\n );\n}\n\n/** Return whether every decoded item-type coverage entry contains valid counts. */\nfunction isNonnegativeCoverageByTypeRecord(value: unknown): boolean {\n if (typeof value !== \"object\" || value === null || Array.isArray(value))\n return false;\n return Object.values(value).every(\n (entry) =>\n typeof entry === \"object\" &&\n entry !== null &&\n !Array.isArray(entry) &&\n [entry.active, entry.isolated, entry.degree_leq_one].every(\n (count) => Number.isInteger(count) && count >= 0,\n ),\n );\n}\n\n/** Decode one persisted audit census baseline, undefined on any defect. */\nfunction decodeBaseline(\n raw: string | null,\n): RelationshipAuditSnapshot | undefined {\n if (raw === null) return undefined;\n try {\n const parsed: unknown = JSON.parse(raw);\n if (typeof parsed !== \"object\" || parsed === null) return undefined;\n const snapshot = parsed as Partial<RelationshipAuditSnapshot>;\n const profile = snapshot.profile;\n if (\n typeof snapshot.saved_at !== \"string\" ||\n typeof snapshot.fingerprint !== \"string\" ||\n !isNonnegativeCountRecord(snapshot.affected_subjects_by_code) ||\n typeof profile !== \"object\" ||\n profile === null ||\n ![\n profile.nodes,\n profile.edges,\n profile.active_nodes,\n profile.missing_nodes,\n profile.isolated_active_nodes,\n profile.degree_leq_one_active_nodes,\n ].every((value) => Number.isInteger(value) && value >= 0) ||\n !isNonnegativeCountRecord(profile.edges_by_kind) ||\n (profile.coverage_by_type !== undefined &&\n !isNonnegativeCoverageByTypeRecord(profile.coverage_by_type))\n )\n return undefined;\n return {\n ...snapshot,\n profile: {\n ...profile,\n coverage_by_type: profile.coverage_by_type ?? {},\n },\n } as RelationshipAuditSnapshot;\n } catch {\n return undefined;\n }\n}\n\n/** Load the persisted audit census baseline when present and decodable. */\nexport async function loadGraphAuditBaseline(\n pmRoot: string,\n): Promise<RelationshipAuditSnapshot | undefined> {\n return decodeBaseline(await readFileIfExists(graphAuditBaselinePath(pmRoot)));\n}\n\n/** Atomically persist one audit census snapshot as the comparison baseline. */\nexport async function saveGraphAuditBaseline(\n pmRoot: string,\n snapshot: RelationshipAuditSnapshot,\n): Promise<void> {\n await writeFileAtomic(\n graphAuditBaselinePath(pmRoot),\n JSON.stringify(snapshot),\n );\n}\n","/**\n * @module sdk/graph/remediation\n *\n * Dry-run remediation planning over the relationship governance audit. The\n * planner turns bounded audit findings and transitive-redundancy evidence into\n * exact, machine-readable proposed operations — remove, retype, supersede,\n * waive, or investigate — each carrying its policy code, evidence, confidence,\n * and rationale. Planning never mutates the workspace and never invents an\n * edge: proposals with structural proof (duplicates, retired sentinels,\n * witnessed shortcuts) get actionable operations, while judgment calls stay\n * explicit `investigate` steps for a human or agent to resolve.\n */\nimport type { RelationshipEdge } from \"../relationships.js\";\nimport { findRedundantRelationshipEdges } from \"./analytics.js\";\nimport type { WorkspaceRelationshipAssembly } from \"./assembly.js\";\nimport {\n auditWorkspaceRelationshipGraph,\n collectDuplicateRelationshipEdgeGroups,\n formatDuplicateEdgeGroup,\n type DuplicateRelationshipEdgeGroup,\n type RelationshipAuditFinding,\n type RelationshipAuditFindingCode,\n type RelationshipAuditOptions,\n type RelationshipAuditReport,\n} from \"./governance.js\";\n\n/** Exact operation family a remediation step proposes; audits never auto-apply. */\nexport type RelationshipRemediationOperation =\n | \"add\"\n | \"remove\"\n | \"retype\"\n | \"supersede\"\n | \"waive\"\n | \"investigate\";\n\n/** Planner confidence that applying the proposed operation is safe and correct. */\nexport type RelationshipRemediationConfidence = \"high\" | \"medium\" | \"low\";\n\n/** Policy source a remediation step was derived from. */\nexport type RelationshipRemediationCode =\n | RelationshipAuditFindingCode\n | \"redundant_edge\";\n\n/** One exact dry-run remediation proposal with evidence and confidence. */\nexport interface RelationshipRemediationStep {\n /** Proposed operation family. */\n op: RelationshipRemediationOperation;\n /** Audit finding code or `redundant_edge` for witnessed transitive shortcuts. */\n code: RelationshipRemediationCode;\n /** Compact deterministic subject — the edge, reference, or node to act on. */\n subject: string;\n /** Why this operation is proposed and what applying it means. */\n rationale: string;\n /** Deterministic evidence strings backing the proposal. */\n evidence: string[];\n /** Planner confidence in the proposal. */\n confidence: RelationshipRemediationConfidence;\n}\n\n/** Tuning inputs accepted by dry-run remediation planning. */\nexport interface RelationshipRemediationPlanOptions\n extends RelationshipAuditOptions {\n /** Maximum witnessed redundant edges scanned into proposals; defaults to the audit sample bound. */\n redundancyLimit?: number;\n}\n\n/** Complete deterministic result of one dry-run remediation planning pass. */\nexport interface RelationshipRemediationPlan {\n /** Proposed steps in audit severity order, redundancy proposals last. */\n steps: RelationshipRemediationStep[];\n /** The governance-audit report the plan was derived from. */\n report: RelationshipAuditReport;\n /** Whether bounded samples or scan limits omitted derivable proposals. */\n truncated: boolean;\n /** Nodes visited and edges inspected by the redundancy witness scan. */\n cost: { visitedNodes: number; inspectedEdges: number };\n}\n\n/** Per-finding-code operation template applied to every sampled subject. */\nconst FINDING_STEP_TEMPLATES: Record<\n RelationshipAuditFindingCode,\n {\n op: RelationshipRemediationOperation;\n confidence: RelationshipRemediationConfidence;\n rationale: string;\n }\n> = {\n missing_reference_active: {\n op: \"investigate\",\n confidence: \"medium\",\n rationale:\n \"Restore or re-create the referenced item, or remove/retype the reference on the active holder; the correct fix depends on why the target is absent.\",\n },\n missing_reference_terminal: {\n op: \"waive\",\n confidence: \"high\",\n rationale:\n \"Terminal-holder reference to an absent item is historical debt; waive it or clean it up only in a dedicated changelog-safe closed-item batch.\",\n },\n legacy_no_blocker_sentinel: {\n op: \"remove\",\n confidence: \"high\",\n rationale:\n \"The pre-structured-dependency no-active-blocker sentinel is retired and carries no information; blocker state derives from blocked_by edges.\",\n },\n ordering_cycle: {\n op: \"investigate\",\n confidence: \"low\",\n rationale:\n \"Every cycle member is unschedulable until one ordering edge is removed or retyped; the planner never chooses which edge to cut.\",\n },\n legacy_ordering_cycle: {\n op: \"waive\",\n confidence: \"high\",\n rationale:\n \"Terminal-only ordering cycles have no scheduling effect; repairing them would mutate closed history (changelog drag).\",\n },\n // duplicate_edge findings are expanded into per-stored-edge remove steps by\n // the planner itself (see stepsFromDuplicateGroup); this template documents\n // the family for exhaustiveness and backs any future sample-only fallback.\n duplicate_edge: {\n op: \"remove\",\n confidence: \"high\",\n rationale:\n \"Parallel same-family spellings state one relationship twice; remove all but one stored spelling, keeping the holder's canonical direction.\",\n },\n legacy_duplicate_edge: {\n op: \"waive\",\n confidence: \"high\",\n rationale:\n \"Duplicated spellings between terminal items are historical noise; waive or batch changelog-safe cleanup.\",\n },\n duplicate_dependency_row: {\n op: \"remove\",\n confidence: \"high\",\n rationale:\n \"The identical dependency row is stored more than once on the holder; drop the repeats so the row exists exactly once — graph semantics are unchanged.\",\n },\n legacy_duplicate_dependency_row: {\n op: \"waive\",\n confidence: \"high\",\n rationale:\n \"Repeated identical rows on terminal holders are storage noise; waive or clean up only in a changelog-safe closed-item batch.\",\n },\n stale_lifecycle_block: {\n op: \"investigate\",\n confidence: \"medium\",\n rationale:\n \"Re-open the missing prerequisite as an ordering edge, or move the item back to an active status; only the holder's owner knows which is true.\",\n },\n isolated_active_node: {\n op: \"investigate\",\n confidence: \"medium\",\n rationale:\n \"Link the item to its parent, prerequisite, or origin — or register it as an explicitly exempt isolate; the audit never fabricates an edge.\",\n },\n sparse_active_node: {\n op: \"investigate\",\n confidence: \"low\",\n rationale:\n \"Investigate for an honest second edge (story-to-task, defect family, cross-epic complement); sparse is not automatically defective.\",\n },\n};\n\n/** Format one stored edge as a concrete removable identity. */\nfunction formatStoredEdge(edge: RelationshipEdge): string {\n return `${edge.source} -${edge.kind}-> ${edge.target}`;\n}\n\n/**\n * Expand one active duplicate group into concrete per-stored-edge removals.\n * The deterministic keeper is the group's first sorted edge; every other\n * stored spelling gets its own remove proposal naming the exact edge to drop,\n * so the plan stays machine-executable instead of pointing at a display\n * string that spans several stored rows.\n */\nfunction stepsFromDuplicateGroup(\n group: DuplicateRelationshipEdgeGroup,\n): RelationshipRemediationStep[] {\n const [keeper, ...extras] = group.edges;\n return extras.map((edge) => ({\n op: \"remove\" as const,\n code: \"duplicate_edge\" as const,\n subject: formatStoredEdge(edge),\n rationale:\n \"This stored spelling restates the kept canonical edge of the same semantic family; removing it leaves the relationship stated exactly once.\",\n evidence: [\n `keep: ${formatStoredEdge(keeper!)}`,\n `group: ${formatDuplicateEdgeGroup(group)}`,\n ],\n confidence: \"high\" as const,\n }));\n}\n\n/** Derive one proposal per bounded sample subject of an audit finding. */\nfunction stepsFromFinding(\n finding: RelationshipAuditFinding,\n duplicateGroups: Map<string, DuplicateRelationshipEdgeGroup>,\n): RelationshipRemediationStep[] {\n if (finding.code === \"duplicate_edge\") {\n // Sample subjects are the deterministic group format strings, so each one\n // resolves to its concrete stored-edge group for exact removal targeting.\n return finding.sample.flatMap((subject) =>\n stepsFromDuplicateGroup(duplicateGroups.get(subject)!),\n );\n }\n const template = FINDING_STEP_TEMPLATES[finding.code];\n return finding.sample.map((subject) => ({\n op: template.op,\n code: finding.code,\n subject,\n rationale: template.rationale,\n evidence: [finding.policy],\n confidence: template.confidence,\n }));\n}\n\n/**\n * Build one deterministic dry-run remediation plan over an assembled workspace\n * relationship graph. The plan runs the shared governance audit, derives one\n * exact proposal per bounded finding subject, then appends witnessed\n * transitive-shortcut removal proposals from the redundancy scan (medium\n * confidence, because shortcut edges are sometimes deliberate emphasis).\n * `truncated` reports whether sample or scan bounds omitted derivable steps;\n * nothing is ever applied automatically.\n */\nexport function planRelationshipRemediation(\n assembly: WorkspaceRelationshipAssembly,\n options: RelationshipRemediationPlanOptions = {},\n): RelationshipRemediationPlan {\n const { redundancyLimit, ...auditOptions } = options;\n const report = auditWorkspaceRelationshipGraph(assembly, auditOptions);\n const duplicateGroups = new Map(\n collectDuplicateRelationshipEdgeGroups(assembly).map((group) => [\n formatDuplicateEdgeGroup(group),\n group,\n ]),\n );\n const steps = report.findings.flatMap((finding) =>\n stepsFromFinding(finding, duplicateGroups),\n );\n let truncated = report.findings.some((finding) => finding.sample_truncated);\n options.signal?.throwIfAborted();\n const redundancy = findRedundantRelationshipEdges(assembly.graph, {\n limit: redundancyLimit ?? options.maxSampleSize ?? 25,\n ...(options.signal === undefined ? {} : { signal: options.signal }),\n });\n for (const row of redundancy.value) {\n steps.push({\n op: \"remove\",\n code: \"redundant_edge\",\n subject: `${row.edge.source} -> ${row.edge.target} (${row.edge.kind})`,\n rationale:\n \"The stored edge is implied by a longer same-family witness path; shortcut edges are sometimes deliberate emphasis, so confirm intent before removing.\",\n evidence: [`witness: ${row.witness.join(\" -> \")}`],\n confidence: \"medium\",\n });\n }\n truncated = truncated || redundancy.meta.truncated;\n return {\n steps,\n report,\n truncated,\n cost: {\n visitedNodes: redundancy.meta.visitedNodes,\n inspectedEdges: redundancy.meta.inspectedEdges,\n },\n };\n}\n","/**\n * @module sdk/graph/run\n *\n * Workspace-facing `pm graph` runner: one thin orchestrator that loads the\n * tracker once, resolves the fingerprint-keyed workspace assembly through the\n * shared graph cache, and dispatches bounded traversal, path, impact,\n * analytics, governance-audit, and remediation-planning queries through the\n * public graph toolkit. Every projection is counts-first, deterministic, and\n * carries explicit cost, truncation, and cache metadata so agents can budget\n * follow-up reads without re-scanning the workspace; identical repeated\n * queries in long-lived hosts are answered from the memoized snapshot.\n */\nimport { getActiveExtensionRegistrations } from \"../../core/extensions/index.js\";\nimport { pathExists } from \"../../core/fs/fs-utils.js\";\nimport { isTerminalStatus } from \"../../core/item/status.js\";\nimport { resolveItemTypeRegistry } from \"../../core/item/type-registry.js\";\nimport { resolveRuntimeStatusRegistry } from \"../../core/schema/runtime-schema.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { listAllItemMetadataLight } from \"../../core/store/item-store.js\";\nimport { getSettingsPath, resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport {\n parseDirection,\n parseKinds,\n parseMaxDepth,\n parsePositiveInteger,\n} from \"../dependencies.js\";\nimport {\n analyzeGraphImpact,\n analyzeKnowledgeGraph,\n analyzeRelationshipExecution,\n} from \"../relationship-analytics.js\";\nimport type { RelationshipQueryMeta } from \"../relationships.js\";\nimport {\n computeRelationshipDominators,\n detectRelationshipCommunities,\n findRedundantRelationshipEdges,\n} from \"./analytics.js\";\nimport {\n computeRelationshipCentrality,\n findRelationshipCutStructure,\n} from \"./centrality.js\";\nimport { analyzeRelationshipSchedule } from \"./scheduling.js\";\nimport {\n assembleWorkspaceRelationshipGraph,\n resolveWorkspaceRelationshipKindRegistry,\n type WorkspaceRelationshipAssembly,\n} from \"./assembly.js\";\nimport {\n computeWorkspaceGraphFingerprint,\n workspaceGraphCache,\n type GraphCacheMetadata,\n} from \"./cache.js\";\nimport {\n clearDurableGraphCache,\n durableGraphCacheStatus,\n loadGraphAuditBaseline,\n openDurableGraphCache,\n persistDurableGraphResult,\n saveGraphAuditBaseline,\n shouldPersistDurableGraphCache,\n GRAPH_DURABLE_CACHE_MIN_ITEMS,\n type DurableGraphCacheView,\n} from \"./durable-cache.js\";\nimport {\n auditWorkspaceRelationshipGraph,\n diffRelationshipAuditSnapshots,\n type RelationshipAuditDelta,\n type RelationshipAuditReport,\n type RelationshipAuditSnapshot,\n} from \"./governance.js\";\nimport {\n planRelationshipRemediation,\n type RelationshipRemediationStep,\n} from \"./remediation.js\";\nimport {\n enumerateRelationshipPaths,\n hierarchyAncestors,\n hierarchyDescendants,\n orderingPredecessors,\n orderingSuccessors,\n} from \"./traversal.js\";\n\nimport {\n GRAPH_SUBCOMMAND_VALUES,\n type GraphSubcommand,\n} from \"../cli-contracts/enum-contracts.js\";\n\nexport { GRAPH_SUBCOMMAND_VALUES, type GraphSubcommand };\n\n/** Graph subcommands that require a root item id. */\nconst ROOTED_SUBCOMMANDS = new Set<GraphSubcommand>([\n \"ancestors\",\n \"descendants\",\n \"predecessors\",\n \"successors\",\n \"paths\",\n \"impact\",\n \"dominators\",\n]);\n\n/** Default bounded sample rows returned by analyze/audit projections. */\nconst DEFAULT_SAMPLE_LIMIT = 10;\n\n/** Documents the graph command options payload exchanged by command, SDK, and package integrations. */\nexport interface GraphCommandOptions {\n /** Restricts traversal to registered relationship kinds (repeatable or comma-separated). */\n kind?: string | string[];\n /** Maximum traversal depth as a non-negative integer. */\n maxDepth?: string | number;\n /** Maximum returned rows per bounded collection. */\n limit?: string | number;\n /** Resume a traversal after this previously returned node id. */\n after?: string;\n /** Edge orientation for paths and impact queries (outgoing, incoming, or both). */\n direction?: string;\n /** Maximum enumerated paths for the paths subcommand. */\n maxPaths?: string | number;\n /** Maximum evidence sample entries per audit finding. */\n sample?: string | number;\n /** Item ids treated as explicitly valid isolates by the audit. */\n exemptIsolate?: string | string[];\n /** Item types whose active nodes are policy-valid isolates for the audit (repeatable or comma-separated). */\n exemptIsolateType?: string | string[];\n /** Persist the audit census as the change-since-baseline comparison point (audit only). */\n saveBaseline?: boolean;\n /** Rebuild and warm the durable graph index (index only). */\n rebuild?: boolean;\n /** Delete the durable graph index (index only). */\n clear?: boolean;\n /** Return counts-first envelopes without row collections. */\n summary?: boolean;\n}\n\n/** Cost metadata attached to every graph query projection. */\nexport interface GraphQueryCost {\n /** Nodes expanded while answering the query. */\n visited_nodes: number;\n /** Edges inspected while answering the query. */\n inspected_edges: number;\n}\n\n/** Result envelope for the transitive traversal subcommands. */\nexport interface GraphTraversalResult {\n /** Executed graph subcommand. */\n subcommand: \"ancestors\" | \"descendants\" | \"predecessors\" | \"successors\";\n /** Canonical root item id. */\n root: string;\n /** Total emitted node ids before summary suppression. */\n count: number;\n /** Whether configured bounds omitted reachable work. */\n truncated: boolean;\n /** Cursor resuming emission after the last returned node. */\n next_cursor?: string;\n /** Query cost metadata. */\n cost: GraphQueryCost;\n /** Emitted node ids in deterministic breadth-first order; absent with summary. */\n ids?: string[];\n /** Cache observability for this invocation. */\n cache?: GraphCacheMetadata;\n}\n\n/** One enumerated path projected with relationship kinds instead of raw edges. */\nexport interface GraphPathRow {\n /** Ordered node ids from source to target inclusive. */\n nodes: string[];\n /** Relationship kind of each traversed edge, in path order. */\n kinds: string[];\n /** Number of edges in the path. */\n length: number;\n}\n\n/** Result envelope for the paths subcommand. */\nexport interface GraphPathsResult {\n /** Executed graph subcommand. */\n subcommand: \"paths\";\n /** Canonical source item id. */\n root: string;\n /** Canonical target item id. */\n target: string;\n /** Traversal orientation used for the enumeration. */\n direction: string;\n /** Total enumerated paths before summary suppression. */\n count: number;\n /** Whether depth, path-count, or safety bounds stopped the search early. */\n truncated: boolean;\n /** Query cost metadata. */\n cost: GraphQueryCost;\n /** Enumerated paths, shortest first; absent with summary. */\n paths?: GraphPathRow[];\n /** Cache observability for this invocation. */\n cache?: GraphCacheMetadata;\n}\n\n/** One affected item row in an impact projection. */\nexport interface GraphImpactRow {\n /** Affected item id. */\n id: string;\n /** Shortest relationship distance from the root. */\n distance: number;\n /** Exact node path explaining why the item is affected. */\n path: string[];\n}\n\n/** Result envelope for the impact subcommand. */\nexport interface GraphImpactResult {\n /** Executed graph subcommand. */\n subcommand: \"impact\";\n /** Canonical impact-origin item id. */\n root: string;\n /** Traversal orientation used for the blast-radius walk. */\n direction: string;\n /** Total affected items before summary suppression. */\n count: number;\n /** Whether configured bounds omitted reachable work. */\n truncated: boolean;\n /** Query cost metadata. */\n cost: GraphQueryCost;\n /** Affected item rows ordered by discovery; absent with summary. */\n affected?: GraphImpactRow[];\n /** Cache observability for this invocation. */\n cache?: GraphCacheMetadata;\n}\n\n/** Bounded execution-graph projection inside an analyze result. */\nexport interface GraphExecutionSummary {\n /** Whether the order-bearing graph is acyclic. */\n acyclic: boolean;\n /** Nodes participating in the topological order. */\n ordered_node_count: number;\n /** Number of parallelizable topological layers. */\n layer_count: number;\n /** Total items with no open prerequisites. */\n frontier_count: number;\n /** Bounded prerequisite-free sample; absent with summary. */\n frontier?: string[];\n /** Edge count of the longest execution path. */\n critical_path_length: number;\n /** Longest deterministic execution path; absent with summary. */\n critical_path?: string[];\n /** Total genuine ordering cycles. */\n cycle_count: number;\n /** Bounded ordering-cycle sample; absent with summary. */\n cycles?: string[][];\n}\n\n/** Bounded knowledge-graph projection inside an analyze result. */\nexport interface GraphKnowledgeSummary {\n /** Total weakly connected components. */\n component_count: number;\n /** Node count of the largest component. */\n largest_component_size: number;\n /** Total nodes without any relationship edges. */\n orphan_count: number;\n /** Bounded orphan sample; absent with summary. */\n orphans?: string[];\n /** Bounded maximum-degree hubs; absent with summary. */\n hubs?: { id: string; degree: number }[];\n}\n\n/** Result envelope for the analyze subcommand. */\nexport interface GraphAnalyzeResult {\n /** Executed graph subcommand. */\n subcommand: \"analyze\";\n /** Total indexed graph nodes. */\n node_count: number;\n /** Total deduplicated graph edges. */\n edge_count: number;\n /** Bound applied to every sample collection. */\n sample_limit: number;\n /** Execution-order analytics over registered ordering kinds. */\n execution: GraphExecutionSummary;\n /** Structural analytics over every stored edge. */\n knowledge: GraphKnowledgeSummary;\n /** Cache observability for this invocation. */\n cache?: GraphCacheMetadata;\n}\n\n/** Result envelope for the audit subcommand. */\nexport interface GraphAuditResult {\n /** Executed graph subcommand. */\n subcommand: \"audit\";\n /** Total audit findings. */\n finding_count: number;\n /** Finding counts keyed by severity. */\n findings_by_severity: Record<string, number>;\n /** Finding-row counts keyed by finding code. Before 2026.7.19 this field incorrectly accumulated affected subjects; consumers of that unit must migrate to affected_subjects_by_code. */\n findings_by_code: Record<string, number>;\n /** Affected-subject counts keyed by severity. */\n affected_subjects_by_severity: Record<string, number>;\n /** Affected-subject counts keyed by finding code. */\n affected_subjects_by_code: Record<string, number>;\n /** Structural coverage metrics computed during the audit. */\n profile: RelationshipAuditReport[\"profile\"];\n /** Ordered findings with bounded evidence samples; absent with summary. */\n findings?: RelationshipAuditReport[\"findings\"];\n /** Signed change since the persisted census baseline; absent when no baseline exists. */\n baseline?: RelationshipAuditDelta;\n /** Cache observability for this invocation. */\n cache?: GraphCacheMetadata;\n}\n\n/** Result envelope for the durable-index maintenance subcommand. */\nexport interface GraphIndexResult {\n /** Executed graph subcommand. */\n subcommand: \"index\";\n /** Maintenance action performed by this invocation. */\n action: \"status\" | \"rebuilt\" | \"cleared\";\n /** Durable index disposition against the current workspace snapshot. */\n state: \"fresh\" | \"stale\" | \"absent\";\n /** Persisted deterministic query results in the envelope. */\n entry_count: number;\n /** Items in the current workspace snapshot. */\n item_count: number;\n /** Item threshold above which implicit persistence activates. */\n min_items_threshold: number;\n /** Whether queries on this workspace will persist results right now. */\n persist_enabled: boolean;\n /** Truncated fingerprint of the current workspace snapshot. */\n current_fingerprint: string;\n /** ISO timestamp of the last persisted write, absent without an envelope. */\n saved_at?: string;\n /** Envelope size in bytes, absent without an envelope. */\n bytes?: number;\n /** Cache observability; maintenance invocations never populate it. */\n cache?: GraphCacheMetadata;\n}\n\n/** One bounded community row projected by the communities subcommand. */\nexport interface GraphCommunityRow {\n /** Lexicographically smallest member id, naming the community. */\n representative: string;\n /** Total member count before sampling. */\n size: number;\n /** Bounded sorted member sample. */\n members: string[];\n}\n\n/** Result envelope for the communities subcommand. */\nexport interface GraphCommunitiesResult {\n /** Executed graph subcommand. */\n subcommand: \"communities\";\n /** Total detected communities meeting the size floor. */\n community_count: number;\n /** Member count of the largest community. */\n largest_community_size: number;\n /** Label-propagation sweeps executed. */\n iterations: number;\n /** Whether labels stabilized before the iteration bound. */\n converged: boolean;\n /** Whether the iteration bound stopped propagation early or the sample bound omitted rows. */\n truncated: boolean;\n /** Query cost metadata. */\n cost: GraphQueryCost;\n /** Bounded community rows, largest first; absent with summary. */\n communities?: GraphCommunityRow[];\n /** Cache observability for this invocation. */\n cache?: GraphCacheMetadata;\n}\n\n/** One redundant stored edge projected with its witness path. */\nexport interface GraphRedundancyRow {\n /** Stored edge source id. */\n source: string;\n /** Stored edge target id. */\n target: string;\n /** Stored relationship kind. */\n kind: string;\n /** Semantic-orientation node path proving the edge is implied. */\n witness: string[];\n}\n\n/** Result envelope for the redundancy subcommand. */\nexport interface GraphRedundancyResult {\n /** Executed graph subcommand. */\n subcommand: \"redundancy\";\n /** Total redundant edges found within configured bounds. */\n redundant_count: number;\n /** Whether the row limit omitted further redundant edges. */\n truncated: boolean;\n /** Query cost metadata. */\n cost: GraphQueryCost;\n /** Redundant edge rows in deterministic scan order; absent with summary. */\n redundant?: GraphRedundancyRow[];\n /** Cache observability for this invocation. */\n cache?: GraphCacheMetadata;\n}\n\n/** One structural bottleneck row projected by the dominators subcommand. */\nexport interface GraphDominatorRow {\n /** Bottleneck node id. */\n id: string;\n /** Immediate dominator appearing on every root-to-node path. */\n idom: string;\n /** Reachable nodes strictly gated by this node. */\n dominated_count: number;\n}\n\n/** Result envelope for the dominators subcommand. */\nexport interface GraphDominatorsResult {\n /** Executed graph subcommand. */\n subcommand: \"dominators\";\n /** Canonical analyzed root id. */\n root: string;\n /** Traversal orientation used for reachability. */\n direction: string;\n /** Reachable node count including the root. */\n reachable_count: number;\n /** Total nodes gating at least one other reachable node. */\n bottleneck_count: number;\n /** Whether the depth bound cut reachability or the row limit omitted bottleneck rows. */\n truncated: boolean;\n /** Query cost metadata. */\n cost: GraphQueryCost;\n /** Bounded bottleneck rows, most-gating first; absent with summary. */\n bottlenecks?: GraphDominatorRow[];\n /** Cache observability for this invocation. */\n cache?: GraphCacheMetadata;\n}\n\n/** One scheduled task row projected by the slack subcommand. */\nexport interface GraphScheduleRow {\n /** Scheduled task id. */\n id: string;\n /** Earliest start (longest prerequisite distance). */\n earliest_start: number;\n /** Latest start preserving the makespan. */\n latest_start: number;\n /** Total float: latest start minus earliest start. */\n slack: number;\n /** Whether the task lies on a critical path. */\n critical: boolean;\n}\n\n/** Result envelope for the critical-path slack subcommand. */\nexport interface GraphSlackResult {\n /** Executed graph subcommand. */\n subcommand: \"slack\";\n /** Whether the order-bearing graph is acyclic. */\n acyclic: boolean;\n /** Total makespan in unit task durations. */\n makespan: number;\n /** Tasks participating in the order-bearing DAG. */\n scheduled_count: number;\n /** Tasks with zero slack. */\n critical_count: number;\n /** Edge count of the longest execution path. */\n critical_path_length: number;\n /** Genuine ordering cycles excluded from scheduling. */\n cycle_count: number;\n /** Whether the row limit omitted scheduled tasks. */\n truncated: boolean;\n /** Longest deterministic execution path; absent with summary. */\n critical_path?: string[];\n /** Bounded scheduled rows, lowest slack first; absent with summary. */\n rows?: GraphScheduleRow[];\n /** Cache observability for this invocation. */\n cache?: GraphCacheMetadata;\n}\n\n/** One node ranked by structural centrality with directed fan-in/fan-out. */\nexport interface GraphCentralityRow {\n /** Node id. */\n id: string;\n /** Undirected unique-neighbor degree. */\n degree: number;\n /** Distinct ordering predecessors that gate this node (dependency fan-in). */\n in_degree: number;\n /** Distinct ordering successors this node gates (dependency fan-out). */\n out_degree: number;\n /** Shortest-path betweenness centrality. */\n betweenness: number;\n /** Wasserman–Faust closeness centrality. */\n closeness: number;\n}\n\n/** Result envelope for the centrality subcommand. */\nexport interface GraphCentralityResult {\n /** Executed graph subcommand. */\n subcommand: \"centrality\";\n /** Total indexed graph nodes. */\n node_count: number;\n /** Simple undirected edge count over selected kinds. */\n edge_count: number;\n /** Whether the row limit omitted ranked nodes. */\n truncated: boolean;\n /** Query cost metadata. */\n cost: GraphQueryCost;\n /** Bounded ranked node rows, highest betweenness first; absent with summary. */\n rows?: GraphCentralityRow[];\n /** Cache observability for this invocation. */\n cache?: GraphCacheMetadata;\n}\n\n/** One bridge edge projected by the articulation subcommand. */\nexport interface GraphBridgeRow {\n /** Lexicographically smaller endpoint. */\n source: string;\n /** Lexicographically larger endpoint. */\n target: string;\n}\n\n/** Result envelope for the articulation subcommand. */\nexport interface GraphArticulationResult {\n /** Executed graph subcommand. */\n subcommand: \"articulation\";\n /** Total articulation points (cut vertices). */\n articulation_count: number;\n /** Total bridge edges (cut edges). */\n bridge_count: number;\n /** Whether the row limit omitted articulation points or bridges. */\n truncated: boolean;\n /** Query cost metadata. */\n cost: GraphQueryCost;\n /** Bounded sorted articulation-point ids; absent with summary. */\n articulation_points?: string[];\n /** Bounded sorted bridge edges; absent with summary. */\n bridges?: GraphBridgeRow[];\n /** Cache observability for this invocation. */\n cache?: GraphCacheMetadata;\n}\n\n/** Result envelope for the dry-run remediation planning subcommand. */\nexport interface GraphPlanResult {\n /** Executed graph subcommand. */\n subcommand: \"plan\";\n /** Total derived remediation proposals before row bounding. */\n step_count: number;\n /** Proposal counts keyed by operation family. */\n steps_by_op: Record<string, number>;\n /** Proposal counts keyed by policy code. */\n steps_by_code: Record<string, number>;\n /** Total governance-audit findings the plan was derived from. */\n finding_count: number;\n /** Whether sample, scan, or row bounds omitted derivable proposals. */\n truncated: boolean;\n /** Query cost metadata. */\n cost: GraphQueryCost;\n /** Bounded proposal rows in audit severity order; absent with summary. */\n steps?: RelationshipRemediationStep[];\n /** Cache observability for this invocation. */\n cache?: GraphCacheMetadata;\n}\n\n/** Union of every graph subcommand result envelope. */\nexport type GraphResult =\n | GraphTraversalResult\n | GraphPathsResult\n | GraphImpactResult\n | GraphAnalyzeResult\n | GraphAuditResult\n | GraphCommunitiesResult\n | GraphRedundancyResult\n | GraphDominatorsResult\n | GraphSlackResult\n | GraphCentralityResult\n | GraphArticulationResult\n | GraphPlanResult\n | GraphIndexResult;\n\n/** Fully parsed graph invocation shared by the subcommand executors. */\ninterface GraphInvocation {\n /** Assembled workspace relationship graph and node details. */\n assembly: WorkspaceRelationshipAssembly;\n /** Canonical registered kind filters, when provided. */\n kinds?: string[];\n /** Parsed non-negative depth bound. */\n maxDepth?: number;\n /** Parsed positive row bound. */\n limit?: number;\n /** Traversal resume cursor. */\n after?: string;\n /** Validated traversal orientation. */\n direction: \"outgoing\" | \"incoming\" | \"both\";\n /** Parsed positive path-count bound. */\n maxPaths?: number;\n /** Parsed positive audit sample bound. */\n sample?: number;\n /** Normalized audit isolate exemptions. */\n exemptIsolates: string[];\n /** Normalized audit isolate-exempt item types. */\n exemptIsolateTypes: string[];\n /** Whether the audit census is persisted as the comparison baseline. */\n saveBaseline: boolean;\n /** Whether row collections are suppressed. */\n summary: boolean;\n}\n\n/** Normalize repeatable or comma-separated id options into a flat list. */\nfunction normalizeIdList(raw: string | string[] | undefined): string[] {\n if (raw === undefined) return [];\n return (Array.isArray(raw) ? raw : [raw])\n .flatMap((value) => value.split(\",\"))\n .map((value) => value.trim())\n .filter((value) => value.length > 0);\n}\n\n/** Validate the graph subcommand and its positional-id requirements. */\nexport function parseGraphSubcommand(\n raw: string,\n id: string | undefined,\n target: string | undefined,\n): GraphSubcommand {\n const candidate = raw.trim().toLowerCase();\n if (!(GRAPH_SUBCOMMAND_VALUES as readonly string[]).includes(candidate)) {\n throw new PmCliError(\n `Invalid graph subcommand \"${raw}\". Use one of: ${GRAPH_SUBCOMMAND_VALUES.join(\", \")}.`,\n EXIT_CODE.USAGE,\n );\n }\n const subcommand = candidate as GraphSubcommand;\n if (ROOTED_SUBCOMMANDS.has(subcommand) && !id?.trim()) {\n throw new PmCliError(\n `graph ${subcommand} requires an item id.`,\n EXIT_CODE.USAGE,\n );\n }\n if (subcommand === \"paths\" && !target?.trim()) {\n throw new PmCliError(\n \"graph paths requires a source and a target item id.\",\n EXIT_CODE.USAGE,\n );\n }\n return subcommand;\n}\n\n/**\n * Re-throw graph-kernel semantic option misuse (non-family kind, unknown\n * cursor, non-transitive redundancy kind) as a usage error carrying the\n * original explanation instead of an opaque crash.\n */\nfunction rethrowGraphUsage(error: unknown): never {\n if (error instanceof TypeError)\n throw new PmCliError(error.message, EXIT_CODE.USAGE);\n throw error;\n}\n\n/** Convert traversal metadata into the shared cost/truncation projection. */\nfunction projectQueryMeta(meta: RelationshipQueryMeta): {\n truncated: boolean;\n cost: GraphQueryCost;\n} {\n return {\n truncated: meta.truncated,\n cost: {\n visited_nodes: meta.visitedNodes,\n inspected_edges: meta.inspectedEdges,\n },\n };\n}\n\n/** Resolve one item id case-insensitively against the assembled graph. */\nfunction canonicalizeGraphId(\n assembly: WorkspaceRelationshipAssembly,\n raw: string,\n): string {\n const wanted = raw.trim().toLowerCase();\n for (const detail of assembly.details) {\n if (\n detail.id.trim().toLowerCase() === wanted &&\n !assembly.missingIdSet.has(detail.id.toLowerCase())\n ) {\n return detail.id;\n }\n }\n throw new PmCliError(`Item ${raw} not found`, EXIT_CODE.NOT_FOUND);\n}\n\n/** Execute one transitive traversal subcommand over the assembled graph. */\nfunction runGraphTraversal(\n subcommand: \"ancestors\" | \"descendants\" | \"predecessors\" | \"successors\",\n root: string,\n invocation: GraphInvocation,\n): GraphTraversalResult {\n const walk = {\n ancestors: hierarchyAncestors,\n descendants: hierarchyDescendants,\n predecessors: orderingPredecessors,\n successors: orderingSuccessors,\n }[subcommand];\n let result;\n try {\n result = walk(invocation.assembly.graph, root, {\n ...(invocation.kinds === undefined ? {} : { kinds: invocation.kinds }),\n ...(invocation.maxDepth === undefined\n ? {}\n : { maxDepth: invocation.maxDepth }),\n ...(invocation.limit === undefined ? {} : { limit: invocation.limit }),\n ...(invocation.after === undefined ? {} : { after: invocation.after }),\n });\n } catch (error) {\n rethrowGraphUsage(error);\n }\n const meta = projectQueryMeta(result.meta);\n return {\n subcommand,\n root,\n count: result.value.length,\n ...meta,\n ...(result.meta.nextCursor === undefined\n ? {}\n : { next_cursor: result.meta.nextCursor }),\n ...(invocation.summary ? {} : { ids: result.value }),\n };\n}\n\n/** Execute the bounded simple-path enumeration subcommand. */\nfunction runGraphPaths(\n root: string,\n target: string,\n invocation: GraphInvocation,\n): GraphPathsResult {\n const result = enumerateRelationshipPaths(\n invocation.assembly.graph,\n root,\n target,\n {\n direction: invocation.direction,\n ...(invocation.kinds === undefined ? {} : { kinds: invocation.kinds }),\n ...(invocation.maxDepth === undefined\n ? {}\n : { maxDepth: invocation.maxDepth }),\n ...(invocation.maxPaths === undefined\n ? {}\n : { maxPaths: invocation.maxPaths }),\n },\n );\n return {\n subcommand: \"paths\",\n root,\n target,\n direction: invocation.direction,\n count: result.value.length,\n ...projectQueryMeta(result.meta),\n ...(invocation.summary\n ? {}\n : {\n paths: result.value.map((path) => ({\n nodes: path.nodes,\n kinds: path.edges.map((edge) => edge.kind),\n length: path.length,\n })),\n }),\n };\n}\n\n/** Execute the bounded blast-radius impact subcommand. */\nfunction runGraphImpact(\n root: string,\n invocation: GraphInvocation,\n): GraphImpactResult {\n const analysis = analyzeGraphImpact(invocation.assembly.graph, root, {\n direction: invocation.direction,\n ...(invocation.kinds === undefined ? {} : { kinds: invocation.kinds }),\n ...(invocation.maxDepth === undefined\n ? {}\n : { maxDepth: invocation.maxDepth }),\n ...(invocation.limit === undefined ? {} : { limit: invocation.limit }),\n });\n return {\n subcommand: \"impact\",\n root,\n direction: invocation.direction,\n count: analysis.affected.length,\n truncated: analysis.truncated,\n cost: {\n visited_nodes: analysis.cost.visitedNodes,\n inspected_edges: analysis.cost.inspectedEdges,\n },\n ...(invocation.summary ? {} : { affected: analysis.affected }),\n };\n}\n\n/** Execute the workspace-wide execution and knowledge analytics subcommand. */\nfunction runGraphAnalyze(invocation: GraphInvocation): GraphAnalyzeResult {\n const graph = invocation.assembly.graph;\n const sampleLimit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;\n const execution = analyzeRelationshipExecution(graph, {\n registry: graph.registry(),\n });\n const knowledge = analyzeKnowledgeGraph(graph);\n return {\n subcommand: \"analyze\",\n node_count: graph.nodes().length,\n edge_count: graph.edges().length,\n sample_limit: sampleLimit,\n execution: {\n acyclic: execution.acyclic,\n ordered_node_count: execution.order.length,\n layer_count: execution.layers.length,\n frontier_count: execution.frontier.length,\n critical_path_length: execution.criticalPathLength,\n cycle_count: execution.cycles.length,\n ...(invocation.summary\n ? {}\n : {\n frontier: execution.frontier.slice(0, sampleLimit),\n critical_path: execution.criticalPath.slice(0, sampleLimit),\n cycles: execution.cycles.slice(0, sampleLimit),\n }),\n },\n knowledge: {\n component_count: knowledge.components.length,\n largest_component_size: knowledge.components[0]?.length ?? 0,\n orphan_count: knowledge.orphans.length,\n ...(invocation.summary\n ? {}\n : {\n orphans: knowledge.orphans.slice(0, sampleLimit),\n hubs: knowledge.hubs.slice(0, sampleLimit),\n }),\n },\n };\n}\n\n/** Execute the governance-audit subcommand over the assembled graph. */\nfunction runGraphAudit(\n invocation: GraphInvocation,\n isTerminal: (status: string) => boolean,\n): GraphAuditResult {\n const report = auditWorkspaceRelationshipGraph(invocation.assembly, {\n isTerminal,\n ...(invocation.sample === undefined\n ? {}\n : { maxSampleSize: invocation.sample }),\n ...(invocation.exemptIsolates.length === 0\n ? {}\n : { exemptIsolates: invocation.exemptIsolates }),\n ...(invocation.exemptIsolateTypes.length === 0\n ? {}\n : { isolateExemptTypes: invocation.exemptIsolateTypes }),\n });\n const bySeverity: Record<string, number> = {};\n const byCode: Record<string, number> = {};\n const affectedBySeverity: Record<string, number> = {};\n const affectedByCode: Record<string, number> = {};\n for (const finding of report.findings) {\n bySeverity[finding.severity] = (bySeverity[finding.severity] ?? 0) + 1;\n byCode[finding.code] = (byCode[finding.code] ?? 0) + 1;\n affectedBySeverity[finding.severity] =\n (affectedBySeverity[finding.severity] ?? 0) + finding.count;\n affectedByCode[finding.code] =\n (affectedByCode[finding.code] ?? 0) + finding.count;\n }\n return {\n subcommand: \"audit\",\n finding_count: report.findings.length,\n findings_by_severity: bySeverity,\n findings_by_code: byCode,\n affected_subjects_by_severity: affectedBySeverity,\n affected_subjects_by_code: affectedByCode,\n profile: report.profile,\n ...(invocation.summary ? {} : { findings: report.findings }),\n };\n}\n\n/** Execute the deterministic community-detection subcommand. */\nfunction runGraphCommunities(\n invocation: GraphInvocation,\n): GraphCommunitiesResult {\n const sampleLimit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;\n const options: Parameters<typeof detectRelationshipCommunities>[1] = {};\n if (invocation.kinds !== undefined) options.kinds = invocation.kinds;\n const result = detectRelationshipCommunities(\n invocation.assembly.graph,\n options,\n );\n const analysis = result.value;\n return {\n subcommand: \"communities\",\n community_count: analysis.communities.length,\n largest_community_size: analysis.communities[0]?.size ?? 0,\n iterations: analysis.iterations,\n converged: analysis.converged,\n truncated: !analysis.converged || analysis.communities.length > sampleLimit,\n cost: {\n visited_nodes: result.meta.visitedNodes,\n inspected_edges: result.meta.inspectedEdges,\n },\n ...(invocation.summary\n ? {}\n : {\n communities: analysis.communities\n .slice(0, sampleLimit)\n .map((community) => ({\n representative: community.representative,\n size: community.size,\n members: community.members.slice(0, sampleLimit),\n })),\n }),\n };\n}\n\n/** Execute the transitive-redundancy scan subcommand. */\nfunction runGraphRedundancy(\n invocation: GraphInvocation,\n): GraphRedundancyResult {\n let result;\n try {\n result = findRedundantRelationshipEdges(invocation.assembly.graph, {\n ...(invocation.kinds === undefined ? {} : { kinds: invocation.kinds }),\n ...(invocation.maxDepth === undefined\n ? {}\n : { maxDepth: invocation.maxDepth }),\n ...(invocation.limit === undefined ? {} : { limit: invocation.limit }),\n });\n } catch (error) {\n rethrowGraphUsage(error);\n }\n return {\n subcommand: \"redundancy\",\n redundant_count: result.value.length,\n ...projectQueryMeta(result.meta),\n ...(invocation.summary\n ? {}\n : {\n redundant: result.value.map((row) => ({\n source: row.edge.source,\n target: row.edge.target,\n kind: row.edge.kind,\n witness: row.witness,\n })),\n }),\n };\n}\n\n/** Execute the dominator/bottleneck analysis subcommand. */\nfunction runGraphDominators(\n root: string,\n invocation: GraphInvocation,\n): GraphDominatorsResult {\n const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;\n const result = computeRelationshipDominators(\n invocation.assembly.graph,\n root,\n {\n direction: invocation.direction,\n ...(invocation.kinds === undefined ? {} : { kinds: invocation.kinds }),\n ...(invocation.maxDepth === undefined\n ? {}\n : { maxDepth: invocation.maxDepth }),\n },\n );\n const bottlenecks = result.value.rows.filter((row) => row.dominatedCount > 0);\n return {\n subcommand: \"dominators\",\n root,\n direction: invocation.direction,\n reachable_count: result.value.reachableCount,\n bottleneck_count: bottlenecks.length,\n truncated: result.meta.truncated || bottlenecks.length > limit,\n cost: {\n visited_nodes: result.meta.visitedNodes,\n inspected_edges: result.meta.inspectedEdges,\n },\n ...(invocation.summary\n ? {}\n : {\n bottlenecks: bottlenecks.slice(0, limit).map((row) => ({\n id: row.id,\n idom: row.idom,\n dominated_count: row.dominatedCount,\n })),\n }),\n };\n}\n\n/** Execute the critical-path slack (float) analysis subcommand. */\nfunction runGraphSlack(invocation: GraphInvocation): GraphSlackResult {\n const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;\n // Scheduling spans every ordering kind; --kind is rejected upstream by\n // assertGraphFlagScope, so no kind filter reaches the analysis here.\n const analysis = analyzeRelationshipSchedule(invocation.assembly.graph);\n const criticalCount = analysis.rows.filter((row) => row.critical).length;\n return {\n subcommand: \"slack\",\n acyclic: analysis.acyclic,\n makespan: analysis.makespan,\n scheduled_count: analysis.scheduledCount,\n critical_count: criticalCount,\n critical_path_length: analysis.criticalPathLength,\n cycle_count: analysis.cycles.length,\n truncated: analysis.rows.length > limit,\n ...(invocation.summary\n ? {}\n : {\n critical_path: analysis.criticalPath,\n rows: analysis.rows.slice(0, limit).map((row) => ({\n id: row.id,\n earliest_start: row.earliestStart,\n latest_start: row.latestStart,\n slack: row.slack,\n critical: row.critical,\n })),\n }),\n };\n}\n\n/** Execute the structural-centrality ranking subcommand. */\nfunction runGraphCentrality(\n invocation: GraphInvocation,\n): GraphCentralityResult {\n const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;\n const result = computeRelationshipCentrality(invocation.assembly.graph, {\n ...(invocation.kinds === undefined ? {} : { kinds: invocation.kinds }),\n });\n const analysis = result.value;\n return {\n subcommand: \"centrality\",\n node_count: analysis.nodeCount,\n edge_count: analysis.edgeCount,\n truncated: analysis.rows.length > limit,\n cost: {\n visited_nodes: result.meta.visitedNodes,\n inspected_edges: result.meta.inspectedEdges,\n },\n ...(invocation.summary\n ? {}\n : {\n rows: analysis.rows.slice(0, limit).map((row) => ({\n id: row.id,\n degree: row.degree,\n in_degree: row.inDegree,\n out_degree: row.outDegree,\n betweenness: row.betweenness,\n closeness: row.closeness,\n })),\n }),\n };\n}\n\n/** Execute the articulation-point and bridge (cut-structure) subcommand. */\nfunction runGraphArticulation(\n invocation: GraphInvocation,\n): GraphArticulationResult {\n const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;\n const result = findRelationshipCutStructure(invocation.assembly.graph, {\n ...(invocation.kinds === undefined ? {} : { kinds: invocation.kinds }),\n });\n const { articulationPoints, bridges } = result.value;\n return {\n subcommand: \"articulation\",\n articulation_count: articulationPoints.length,\n bridge_count: bridges.length,\n truncated: articulationPoints.length > limit || bridges.length > limit,\n cost: {\n visited_nodes: result.meta.visitedNodes,\n inspected_edges: result.meta.inspectedEdges,\n },\n ...(invocation.summary\n ? {}\n : {\n articulation_points: articulationPoints.slice(0, limit),\n bridges: bridges.slice(0, limit),\n }),\n };\n}\n\n/** Execute the dry-run remediation planning subcommand. */\nfunction runGraphPlan(\n invocation: GraphInvocation,\n isTerminal: (status: string) => boolean,\n): GraphPlanResult {\n const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;\n const plan = planRelationshipRemediation(invocation.assembly, {\n isTerminal,\n redundancyLimit: limit,\n ...(invocation.sample === undefined\n ? {}\n : { maxSampleSize: invocation.sample }),\n ...(invocation.exemptIsolates.length === 0\n ? {}\n : { exemptIsolates: invocation.exemptIsolates }),\n ...(invocation.exemptIsolateTypes.length === 0\n ? {}\n : { isolateExemptTypes: invocation.exemptIsolateTypes }),\n });\n const byOp: Record<string, number> = {};\n const byCode: Record<string, number> = {};\n for (const step of plan.steps) {\n byOp[step.op] = (byOp[step.op] ?? 0) + 1;\n byCode[step.code] = (byCode[step.code] ?? 0) + 1;\n }\n return {\n subcommand: \"plan\",\n step_count: plan.steps.length,\n steps_by_op: byOp,\n steps_by_code: byCode,\n finding_count: plan.report.findings.length,\n truncated: plan.truncated || plan.steps.length > limit,\n cost: {\n visited_nodes: plan.cost.visitedNodes,\n inspected_edges: plan.cost.inspectedEdges,\n },\n ...(invocation.summary ? {} : { steps: plan.steps.slice(0, limit) }),\n };\n}\n\n/** Build the deterministic memoization key covering every query-shaping input. */\nfunction buildGraphQueryKey(\n subcommand: GraphSubcommand,\n root: string | undefined,\n pathsTarget: string | undefined,\n invocation: GraphInvocation,\n): string {\n return JSON.stringify({\n subcommand,\n root: root ?? null,\n target: pathsTarget ?? null,\n kinds: invocation.kinds ?? null,\n maxDepth: invocation.maxDepth ?? null,\n limit: invocation.limit ?? null,\n after: invocation.after ?? null,\n direction: invocation.direction,\n maxPaths: invocation.maxPaths ?? null,\n sample: invocation.sample ?? null,\n // The audit consumes exemptions as a case-insensitive set, so the key\n // must not distinguish logically identical spellings or orderings.\n exemptIsolates: [\n ...new Set(invocation.exemptIsolates.map((id) => id.toLowerCase())),\n ].sort(),\n exemptIsolateTypes: [\n ...new Set(\n invocation.exemptIsolateTypes.map((type) => type.toLowerCase()),\n ),\n ].sort(),\n summary: invocation.summary,\n });\n}\n\n/** Dispatch one parsed graph subcommand to its executor. */\nfunction executeGraphSubcommand(\n subcommand: Exclude<GraphSubcommand, \"index\">,\n root: string | undefined,\n pathsTarget: string | undefined,\n invocation: GraphInvocation,\n isTerminal: (status: string) => boolean,\n): GraphResult {\n if (subcommand === \"analyze\") return runGraphAnalyze(invocation);\n if (subcommand === \"audit\") return runGraphAudit(invocation, isTerminal);\n if (subcommand === \"plan\") return runGraphPlan(invocation, isTerminal);\n if (subcommand === \"communities\") return runGraphCommunities(invocation);\n if (subcommand === \"redundancy\") return runGraphRedundancy(invocation);\n if (subcommand === \"dominators\") return runGraphDominators(root!, invocation);\n if (subcommand === \"slack\") return runGraphSlack(invocation);\n if (subcommand === \"centrality\") return runGraphCentrality(invocation);\n if (subcommand === \"articulation\") return runGraphArticulation(invocation);\n if (subcommand === \"paths\")\n return runGraphPaths(root!, pathsTarget!, invocation);\n if (subcommand === \"impact\") return runGraphImpact(root!, invocation);\n return runGraphTraversal(subcommand, root!, invocation);\n}\n\n/** Reject maintenance or baseline flags outside their owning subcommand. */\nfunction assertGraphFlagScope(\n subcommand: GraphSubcommand,\n options: GraphCommandOptions,\n): void {\n if (\n subcommand !== \"index\" &&\n (options.rebuild === true || options.clear === true)\n )\n throw new PmCliError(\n \"--rebuild and --clear apply only to graph index.\",\n EXIT_CODE.USAGE,\n );\n if (subcommand !== \"audit\" && options.saveBaseline === true)\n throw new PmCliError(\n \"--save-baseline applies only to graph audit.\",\n EXIT_CODE.USAGE,\n );\n // Slack schedules the whole ordering DAG (reusing the exact execution\n // analysis, which has no kind filter), so reject --kind instead of silently\n // ignoring it and letting the cache key diverge on an inert option.\n if (subcommand === \"slack\" && options.kind !== undefined)\n throw new PmCliError(\n \"graph slack analyzes every ordering kind; --kind is not supported.\",\n EXIT_CODE.USAGE,\n );\n if (options.rebuild === true && options.clear === true)\n throw new PmCliError(\n \"graph index accepts either --rebuild or --clear, not both.\",\n EXIT_CODE.USAGE,\n );\n}\n\n/**\n * Execute the durable-index maintenance subcommand: report status, delete the\n * envelope, or rebuild it and warm the counts-first analyze and audit census\n * queries so follow-up summary invocations answer from the persisted index.\n * A rebuild is also the explicit opt-in that enables persistence on\n * workspaces below the implicit item threshold.\n */\nasync function runGraphIndex(\n pmRoot: string,\n fingerprint: string,\n invocation: GraphInvocation,\n itemCount: number,\n isTerminal: (status: string) => boolean,\n options: GraphCommandOptions,\n): Promise<GraphIndexResult> {\n let action: GraphIndexResult[\"action\"] = \"status\";\n if (options.clear === true) {\n await clearDurableGraphCache(pmRoot);\n action = \"cleared\";\n }\n if (options.rebuild === true) {\n await clearDurableGraphCache(pmRoot);\n const view = await openDurableGraphCache(pmRoot, fingerprint);\n const warmInvocation: GraphInvocation = {\n assembly: invocation.assembly,\n direction: \"both\",\n exemptIsolates: [],\n exemptIsolateTypes: [],\n saveBaseline: false,\n summary: true,\n };\n for (const warm of [\"analyze\", \"audit\"] as const) {\n await persistDurableGraphResult(\n pmRoot,\n fingerprint,\n view,\n buildGraphQueryKey(warm, undefined, undefined, warmInvocation),\n executeGraphSubcommand(\n warm,\n undefined,\n undefined,\n warmInvocation,\n isTerminal,\n ),\n );\n }\n action = \"rebuilt\";\n }\n const status = await durableGraphCacheStatus(pmRoot, fingerprint);\n return {\n subcommand: \"index\",\n action,\n state: status.exists ? (status.fresh ? \"fresh\" : \"stale\") : \"absent\",\n entry_count: status.entry_count,\n item_count: itemCount,\n min_items_threshold: GRAPH_DURABLE_CACHE_MIN_ITEMS,\n persist_enabled: shouldPersistDurableGraphCache(itemCount, status.exists),\n current_fingerprint: fingerprint.slice(0, 12),\n ...(status.saved_at === undefined ? {} : { saved_at: status.saved_at }),\n ...(status.bytes === undefined ? {} : { bytes: status.bytes }),\n };\n}\n\n/**\n * Attach the change-since-baseline census delta to one audit envelope and\n * persist the current census when the caller requested a new baseline. The\n * delta always compares against the baseline as it existed before this\n * invocation, so `--save-baseline` reports drift once and then resets it.\n */\nasync function applyAuditBaseline(\n pmRoot: string,\n fingerprint: string,\n audit: GraphAuditResult,\n saveBaseline: boolean,\n): Promise<GraphAuditResult> {\n const current: RelationshipAuditSnapshot = {\n saved_at: new Date().toISOString(),\n fingerprint,\n affected_subjects_by_code: audit.affected_subjects_by_code,\n profile: audit.profile,\n };\n const stored = await loadGraphAuditBaseline(pmRoot);\n if (saveBaseline) await saveGraphAuditBaseline(pmRoot, current);\n return stored === undefined\n ? audit\n : { ...audit, baseline: diffRelationshipAuditSnapshots(stored, current) };\n}\n\n/** Persist a rebuildable query result without allowing storage failure to reject the query. */\nasync function persistDurableGraphResultBestEffort(\n pmRoot: string,\n fingerprint: string,\n view: DurableGraphCacheView,\n queryKey: string,\n result: GraphResult,\n): Promise<void> {\n try {\n await persistDurableGraphResult(\n pmRoot,\n fingerprint,\n view,\n queryKey,\n result,\n );\n } catch {\n // The in-memory result remains authoritative; the next invocation can rebuild the cache.\n }\n}\n\n/** Implements run graph for the public runtime surface of this module. */\nexport async function runGraph(\n subcommandRaw: string,\n id: string | undefined,\n target: string | undefined,\n options: GraphCommandOptions,\n global: GlobalOptions,\n): Promise<GraphResult> {\n const subcommand = parseGraphSubcommand(subcommandRaw, id, target);\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(\n `Tracker is not initialized at ${pmRoot}. Run pm init first.`,\n EXIT_CODE.NOT_FOUND,\n );\n }\n const settings = await readSettings(pmRoot);\n const typeRegistry = resolveItemTypeRegistry(\n settings,\n getActiveExtensionRegistrations(),\n );\n const items = await listAllItemMetadataLight(\n pmRoot,\n settings.item_format,\n typeRegistry.type_to_folder,\n undefined,\n settings.schema,\n );\n const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);\n const isTerminal = (status: string): boolean =>\n isTerminalStatus(status, statusRegistry);\n assertGraphFlagScope(subcommand, options);\n const relationshipRegistry = resolveWorkspaceRelationshipKindRegistry();\n const kinds = parseKinds(options.kind, relationshipRegistry);\n const lookup = workspaceGraphCache().lookup(\n pmRoot,\n computeWorkspaceGraphFingerprint(items, isTerminal, relationshipRegistry),\n () =>\n assembleWorkspaceRelationshipGraph(\n items,\n isTerminal,\n relationshipRegistry,\n ),\n );\n const invocation: GraphInvocation = {\n assembly: lookup.assembly,\n ...(kinds === undefined ? {} : { kinds }),\n maxDepth: parseMaxDepth(options.maxDepth),\n limit: parsePositiveInteger(options.limit, \"limit\"),\n after: options.after?.trim() || undefined,\n direction: parseDirection(options.direction),\n maxPaths: parsePositiveInteger(options.maxPaths, \"max-paths\"),\n sample: parsePositiveInteger(options.sample, \"sample\"),\n exemptIsolates: normalizeIdList(options.exemptIsolate),\n exemptIsolateTypes: normalizeIdList(options.exemptIsolateType),\n saveBaseline: options.saveBaseline === true,\n summary: options.summary === true,\n };\n if (subcommand === \"index\") {\n return runGraphIndex(\n pmRoot,\n lookup.fingerprint,\n invocation,\n items.length,\n isTerminal,\n options,\n );\n }\n const root = ROOTED_SUBCOMMANDS.has(subcommand)\n ? canonicalizeGraphId(invocation.assembly, id!)\n : undefined;\n const pathsTarget =\n subcommand === \"paths\"\n ? canonicalizeGraphId(invocation.assembly, target!)\n : undefined;\n const queryKey = buildGraphQueryKey(\n subcommand,\n root,\n pathsTarget,\n invocation,\n );\n const durableView = await openDurableGraphCache(pmRoot, lookup.fingerprint);\n const durableValue = durableView.results[queryKey];\n const memo = lookup.memoize(queryKey, () =>\n durableValue !== undefined\n ? (structuredClone(durableValue) as GraphResult)\n : executeGraphSubcommand(\n subcommand,\n root,\n pathsTarget,\n invocation,\n isTerminal,\n ),\n );\n const persistEnabled = shouldPersistDurableGraphCache(\n items.length,\n durableView.exists,\n );\n if (!memo.reused && durableValue === undefined && persistEnabled) {\n await persistDurableGraphResultBestEffort(\n pmRoot,\n lookup.fingerprint,\n durableView,\n queryKey,\n memo.value,\n );\n }\n const value =\n memo.value.subcommand === \"audit\"\n ? await applyAuditBaseline(\n pmRoot,\n lookup.fingerprint,\n memo.value,\n invocation.saveBaseline,\n )\n : memo.value;\n value.cache = {\n fingerprint: lookup.fingerprint.slice(0, 12),\n assembly: lookup.assemblyReused ? \"hit\" : \"miss\",\n result: memo.reused ? \"hit\" : \"miss\",\n durable:\n durableValue !== undefined ? \"hit\" : persistEnabled ? \"miss\" : \"off\",\n };\n return value;\n}\n","/**\n * @module sdk/item-children\n *\n * Builds deterministic, bounded direct-child projections for every item type.\n * The primitive accepts metadata from either the persistent derived index or a\n * source scan, allowing CLI, MCP, packages, and custom hosts to share one graph\n * projection contract.\n */\nimport { isTerminalStatus } from \"../core/item/status.js\";\nimport type { RuntimeStatusRegistry } from \"../core/schema/runtime-schema.js\";\nimport { EXIT_CODE } from \"../core/shared/constants.js\";\nimport { PmCliError } from \"../core/shared/errors.js\";\nimport type { ItemMetadata } from \"../types/index.js\";\n\n/** Maximum corpus rows inspected by one child projection. */\nexport const MAX_CHILD_PROJECTION_ITEMS = 1_000_000;\n/** Default number of child summaries retained inline. */\nexport const DEFAULT_CHILD_SAMPLE_LIMIT = 20;\n\n/** Stable compact child row embedded in a parent read. */\nexport interface ChildRollupSample {\n /** Stable child identifier. */\n id: string;\n /** Human-readable child title. */\n title: string;\n /** Schema type of the child item. */\n type: string;\n /** Current lifecycle status of the child item. */\n status: string;\n /** Current priority of the child item. */\n priority: number;\n}\n\n/** Bounded direct-child summary shared across SDK and presentation surfaces. */\nexport interface ChildRollupContext {\n /** Total direct children discovered. */\n count: number;\n /** Direct children whose statuses are non-terminal. */\n active: number;\n /** Counts grouped by normalized lifecycle status. */\n by_status: Record<string, number>;\n /** Deterministic id-sorted inline sample. */\n sample: ChildRollupSample[];\n /** Configured maximum sample size. */\n sample_limit: number;\n /** Whether additional children exist beyond the inline sample. */\n truncated: boolean;\n /** Offset for the next page, or null when the sample is complete. */\n next_offset: number | null;\n /** Token-efficient CLI continuation command, or null when complete. */\n continuation: string | null;\n /** Number of corpus rows inspected to produce this projection. */\n scanned: number;\n}\n\n/**\n * Build a type-agnostic child rollup from indexed or source metadata. Input is\n * capped at one million rows to keep custom-host behavior explicitly bounded.\n */\nexport function buildItemChildrenRollup(\n parentId: string,\n corpus: Iterable<ItemMetadata>,\n statusRegistry: RuntimeStatusRegistry,\n sampleLimit = DEFAULT_CHILD_SAMPLE_LIMIT,\n): ChildRollupContext {\n if (!Number.isSafeInteger(sampleLimit) || sampleLimit < 0) {\n throw new PmCliError(\n \"Child projection sample limit must be a non-negative integer.\",\n EXIT_CODE.USAGE,\n );\n }\n const normalizedParentId = parentId.trim().toLowerCase();\n const byStatus: Record<string, number> = {};\n const children: ItemMetadata[] = [];\n let active = 0;\n let scanned = 0;\n for (const candidate of corpus) {\n scanned += 1;\n if (scanned > MAX_CHILD_PROJECTION_ITEMS) {\n throw new PmCliError(\n `Child projection exceeded the ${MAX_CHILD_PROJECTION_ITEMS.toLocaleString(\"en-US\")} item safety bound.`,\n EXIT_CODE.GENERIC_FAILURE,\n {\n code: \"child_projection_item_bound_exceeded\",\n required: \"Use an indexed or parent-filtered metadata source.\",\n why: \"Unbounded graph scans can exhaust memory in universal project stores.\",\n nextSteps: [\"Build the derived item index, then retry the parent read.\"],\n },\n );\n }\n if (candidate.parent?.trim().toLowerCase() !== normalizedParentId) {\n continue;\n }\n children.push(candidate);\n const status = candidate.status.trim().toLowerCase();\n byStatus[status] = (byStatus[status] ?? 0) + 1;\n if (!isTerminalStatus(status, statusRegistry)) {\n active += 1;\n }\n }\n children.sort((left, right) => left.id.localeCompare(right.id));\n const sample = children.slice(0, sampleLimit).map((child) => ({\n id: child.id,\n title: child.title,\n type: child.type,\n status: child.status,\n priority: child.priority,\n }));\n const truncated = children.length > sample.length;\n return {\n count: children.length,\n active,\n by_status: Object.fromEntries(\n Object.entries(byStatus).sort(([left], [right]) => left.localeCompare(right)),\n ),\n sample,\n sample_limit: sampleLimit,\n truncated,\n next_offset: truncated ? sample.length : null,\n continuation: truncated\n ? `pm list --status all --parent ${parentId} --offset ${sample.length} --limit ${sampleLimit}`\n : null,\n scanned,\n };\n}\n","/**\n * @module sdk/item-schedule\n *\n * Normalizes scheduling metadata into one stable read facet so scheduled item\n * types remain useful through generic SDK, CLI, MCP, JSON, and TOON reads.\n */\nimport type { CalendarEvent, ItemMetadata, Reminder } from \"../types/index.js\";\n\nconst BUILTIN_SCHEDULE_TYPES = new Set([\"event\", \"meeting\", \"reminder\"]);\n\n/** Schedule projection attached to standard and deep item reads. */\nexport interface ItemScheduleContext {\n /** Item deadline when present. */\n deadline: string | null;\n /** Earliest event start, convenient for single-event consumers. */\n start_at: string | null;\n /** End of the earliest event when present. */\n end_at: string | null;\n /** Location of the earliest event when present. */\n location: string | null;\n /** All configured reminders. */\n reminders: Reminder[];\n /** All configured events ordered by start timestamp. */\n events: CalendarEvent[];\n}\n\n/** Return whether an item carries or semantically represents schedule data. */\nexport function itemHasSchedule(item: ItemMetadata): boolean {\n return (\n BUILTIN_SCHEDULE_TYPES.has(item.type.trim().toLowerCase()) ||\n item.deadline !== undefined ||\n (item.reminders?.length ?? 0) > 0 ||\n (item.events?.length ?? 0) > 0\n );\n}\n\n/** Build a deterministic schedule facet, or undefined for unscheduled items. */\nexport function buildItemSchedule(\n item: ItemMetadata,\n): ItemScheduleContext | undefined {\n if (!itemHasSchedule(item)) {\n return undefined;\n }\n const events = [...(item.events ?? [])].sort((left, right) =>\n left.start_at.localeCompare(right.start_at),\n );\n const primary = events[0];\n return {\n deadline: item.deadline ?? null,\n start_at: primary?.start_at ?? null,\n end_at: primary?.end_at ?? null,\n location: primary?.location ?? null,\n reminders: [...(item.reminders ?? [])],\n events,\n };\n}\n","/**\n * @module cli/commands/get\n *\n * Implements the pm get command surface and its agent-facing runtime behavior.\n */\nimport { pathExists } from \"../../core/fs/fs-utils.js\";\nimport { getActiveExtensionRegistrations } from \"../../core/extensions/index.js\";\nimport { toItemRecord } from \"../../core/item/item-record.js\";\nimport { resolveItemTypeRegistry } from \"../../core/item/type-registry.js\";\nimport {\n resolveRuntimeFieldRegistry,\n resolveRuntimeStatusRegistry,\n} from \"../../core/schema/runtime-schema.js\";\nimport {\n EXIT_CODE,\n ITEM_METADATA_KEY_ORDER,\n TYPE_TO_FOLDER,\n} from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport {\n buildItemNotFoundError,\n listAllItemMetadataLight,\n locateItem,\n readLocatedItem,\n} from \"../../core/store/item-store.js\";\nimport {\n getHistoryPath,\n getSettingsPath,\n resolvePmRoot,\n} from \"../../core/store/paths.js\";\nimport { readHistoryEntries } from \"../../sdk/history-read.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport { recordContextUsageTouches } from \"../../sdk/context-usage.js\";\nimport {\n buildItemChildrenRollup,\n type ChildRollupContext,\n} from \"../../sdk/item-children.js\";\nimport {\n buildItemSchedule,\n type ItemScheduleContext,\n} from \"../../sdk/item-schedule.js\";\nimport { getItemAt, type GetItemAtResult } from \"../../sdk/history-read.js\";\nimport { parseIntegerLimit } from \"../shared-parsers.js\";\nimport type {\n ItemMetadata,\n LinkedDoc,\n LinkedFile,\n LinkedTest,\n} from \"../../types/index.js\";\nimport { runList } from \"./list.js\";\n\ninterface ClaimHistoryContext {\n ts: string;\n author: string;\n message: string | null;\n}\n\ninterface ClaimHistoryEntry {\n op: string;\n ts: string;\n author: string;\n message?: string;\n}\n\ninterface ClaimStateContext {\n claimed: boolean;\n assignee: string | null;\n last_claim: ClaimHistoryContext | null;\n last_release: ClaimHistoryContext | null;\n}\n\n/** Documents the get result payload exchanged by command, SDK, and package integrations. */\nexport interface GetResult {\n // `body` lives inside `item` (alongside `description`/`acceptance_criteria`)\n // for parity with `pm list --include-body`, so agents reliably find it at\n // `.item.body` in JSON output instead of a top-level sibling.\n /** Value that configures or reports item for this contract. */\n item: Partial<ItemMetadata> & { body?: string };\n /** Value that configures or reports linked for this contract. */\n linked?: {\n files: LinkedFile[];\n tests: LinkedTest[];\n docs: LinkedDoc[];\n };\n /** Value that configures or reports claim state for this contract. */\n claim_state?: ClaimStateContext;\n /** Value that configures or reports children for this contract. */\n children?: ChildRollupContext;\n /** Normalized scheduling data for scheduled item types and metadata. */\n schedule?: Partial<ItemScheduleContext>;\n /** True when the item was reconstructed from immutable history. */\n reconstructed?: true;\n /** One-based history version represented by a reconstructed read. */\n as_of_version?: number;\n /** Timestamp of the last history entry included in a reconstructed read. */\n as_of_timestamp?: string;\n /** Value that configures or reports tree for this contract. */\n tree?: {\n root_id: string;\n root_title: string | null;\n depth_limit: number | null;\n count: number;\n items: Record<string, unknown>[];\n };\n}\n\nconst GET_DEPTH_VALUES = [\"brief\", \"standard\", \"deep\"] as const;\n\nconst AUTOMATIC_CHILD_ROLLUP_TYPES = new Set([\n \"epic\",\n \"feature\",\n \"milestone\",\n \"plan\",\n]);\nconst BUILTIN_ITEM_TYPES = new Set(\n Object.keys(TYPE_TO_FOLDER).map((type) => type.toLowerCase()),\n);\n\ntype GetDepth = (typeof GET_DEPTH_VALUES)[number];\n\n/** Decide whether a normal read should pay for a workspace-wide child projection. */\nfunction shouldAutoIncludeGetChildren(itemType: string): boolean {\n const normalizedType = itemType.trim().toLowerCase();\n return (\n normalizedType.length > 0 &&\n (AUTOMATIC_CHILD_ROLLUP_TYPES.has(normalizedType) ||\n !BUILTIN_ITEM_TYPES.has(normalizedType))\n );\n}\n\n/** Documents the get options payload exchanged by command, SDK, and package integrations. */\nexport interface GetOptions {\n /** Value that configures or reports depth for this contract. */\n depth?: string;\n /** Value that configures or reports fields for this contract. */\n fields?: string;\n /** Value that configures or reports full for this contract. */\n full?: boolean;\n /** Value that configures or reports tree for this contract. */\n tree?: boolean;\n /** Value that configures or reports tree depth for this contract. */\n treeDepth?: string;\n /** One-based history version or ISO timestamp for a mutation-free read. */\n at?: string;\n}\n\nfunction toClaimHistoryContext(entry: ClaimHistoryEntry): ClaimHistoryContext {\n return {\n ts: entry.ts,\n author: entry.author,\n message: entry.message ?? null,\n };\n}\n\nfunction resolveClaimStateContext(\n assigneeValue: string | undefined,\n history: ClaimHistoryEntry[],\n): ClaimStateContext {\n const assignee = assigneeValue?.trim();\n const normalizedAssignee = assignee && assignee.length > 0 ? assignee : null;\n const lastClaim = [...history]\n .reverse()\n .find((entry) => entry.op === \"claim\");\n const lastRelease = [...history]\n .reverse()\n .find((entry) => entry.op === \"release\");\n return {\n claimed: normalizedAssignee !== null,\n assignee: normalizedAssignee,\n last_claim: lastClaim ? toClaimHistoryContext(lastClaim) : null,\n last_release: lastRelease ? toClaimHistoryContext(lastRelease) : null,\n };\n}\n\nfunction parseGetDepth(raw: string | undefined): GetDepth {\n if (raw === undefined || raw.trim().length === 0) {\n return \"standard\";\n }\n const normalized = raw.trim().toLowerCase();\n if (normalized === \"full\") {\n return \"deep\";\n }\n if (GET_DEPTH_VALUES.includes(normalized as GetDepth)) {\n return normalized as GetDepth;\n }\n throw new PmCliError(\n \"Get --depth must be one of brief|standard|deep|full\",\n EXIT_CODE.USAGE,\n );\n}\n\nfunction projectItemForDepth(\n item: ItemMetadata,\n depth: GetDepth,\n): Partial<ItemMetadata> {\n if (depth === \"deep\") {\n return item;\n }\n const {\n comments: _comments,\n notes: _notes,\n learnings: _learnings,\n files: _files,\n tests: _tests,\n docs: _docs,\n reminders: _reminders,\n events: _events,\n ...projected\n } = item;\n return projected;\n}\n\nfunction parseGetFields(raw: string | undefined): string[] | null {\n if (raw === undefined) {\n return null;\n }\n const fields = raw\n .split(\",\")\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0);\n if (fields.length === 0) {\n throw new PmCliError(\n \"Get --fields requires a comma-separated list of field names\",\n EXIT_CODE.USAGE,\n );\n }\n return fields;\n}\n\nfunction normalizeGetField(field: string): string {\n return field.startsWith(\"item.\") ? field.slice(\"item.\".length) : field;\n}\n\nfunction validateGetFields(\n fields: string[] | null,\n runtimeMetadataKeys: Iterable<string>,\n): void {\n if (fields === null) {\n return;\n }\n const itemFields = new Set([\n ...ITEM_METADATA_KEY_ORDER,\n ...runtimeMetadataKeys,\n ]);\n const allowedRootFields = new Set([\n \"body\",\n \"linked\",\n \"claim_state\",\n \"children\",\n \"schedule\",\n ]);\n const allowedLinkedFields = new Set([\n \"linked.files\",\n \"linked.tests\",\n \"linked.docs\",\n ]);\n const allowedClaimStateFields = new Set([\n \"claim_state.claimed\",\n \"claim_state.assignee\",\n \"claim_state.last_claim\",\n \"claim_state.last_release\",\n ]);\n const allowedScheduleFields = new Set([\n \"schedule.deadline\",\n \"schedule.start_at\",\n \"schedule.end_at\",\n \"schedule.location\",\n \"schedule.reminders\",\n \"schedule.events\",\n ]);\n const unknown = fields.filter((field) => {\n const normalized = normalizeGetField(field);\n return (\n !itemFields.has(normalized) &&\n !allowedRootFields.has(normalized) &&\n !allowedLinkedFields.has(normalized) &&\n !allowedClaimStateFields.has(normalized) &&\n !allowedScheduleFields.has(normalized)\n );\n });\n if (unknown.length > 0) {\n throw new PmCliError(\n `Unknown get --fields value(s): ${unknown.join(\", \")}`,\n EXIT_CODE.USAGE,\n {\n code: \"unknown_field_projection\",\n examples: [\n \"pm get <id> --fields id,title,status,type,updated_at\",\n \"pm get <id> --fields id,title,claim_state\",\n \"pm get <id> --fields id,title,body,linked.files\",\n ],\n },\n );\n }\n}\n\nfunction projectItemForFields(\n item: ItemMetadata,\n fields: string[],\n): Partial<ItemMetadata> {\n const source = toItemRecord(item);\n const projected: Record<string, unknown> = {};\n for (const field of fields) {\n const normalized = normalizeGetField(field);\n if (\n normalized === \"body\" ||\n normalized === \"linked\" ||\n normalized.startsWith(\"linked.\") ||\n normalized === \"claim_state\" ||\n normalized.startsWith(\"claim_state.\") ||\n normalized === \"children\" ||\n normalized.startsWith(\"children.\") ||\n normalized === \"schedule\" ||\n normalized.startsWith(\"schedule.\")\n ) {\n continue;\n }\n projected[normalized] = source[normalized];\n }\n return projected as Partial<ItemMetadata>;\n}\n\nfunction fieldsInclude(fields: string[] | null, name: string): boolean {\n return (\n fields?.some((field) => field === name || field === `item.${name}`) ?? false\n );\n}\n\nfunction fieldsIncludeRoot(fields: string[], name: string): boolean {\n return fields.some((field) => {\n const normalized = normalizeGetField(field);\n return normalized === name || normalized.startsWith(`${name}.`);\n });\n}\n\ninterface ResolvedGetProjection {\n depth: GetDepth;\n treeDepth: number | undefined;\n fields: string[] | null;\n fieldProjection: boolean;\n}\n\ninterface GetItemContext {\n pmRoot: string;\n settings: Awaited<ReturnType<typeof readSettings>>;\n typeToFolder: Record<string, string>;\n locatedId: string;\n metadata: ItemMetadata;\n body: string;\n historical?: GetItemAtResult;\n}\n\nfunction resolveGetProjection(options: GetOptions): ResolvedGetProjection {\n if (\n options.full &&\n (options.fields !== undefined || options.depth !== undefined)\n ) {\n throw new PmCliError(\n \"Get projection options are mutually exclusive; remove the extra projection flag and retry.\",\n EXIT_CODE.USAGE,\n );\n }\n if (options.tree !== true && options.treeDepth !== undefined) {\n throw new PmCliError(\"Get --tree-depth requires --tree\", EXIT_CODE.USAGE);\n }\n if (options.at !== undefined && options.tree === true) {\n throw new PmCliError(\n \"Get --at cannot be combined with --tree because workspace-level historical projections are not yet indexed.\",\n EXIT_CODE.USAGE,\n );\n }\n return {\n depth: options.full ? \"deep\" : parseGetDepth(options.depth),\n treeDepth:\n options.tree === true\n ? parseIntegerLimit(options.treeDepth, \"--tree-depth\")\n : undefined,\n fields: parseGetFields(options.fields),\n fieldProjection: options.fields !== undefined,\n };\n}\n\nasync function loadGetItemContext(\n id: string,\n global: GlobalOptions,\n at?: string,\n): Promise<GetItemContext> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(\n `Tracker is not initialized at ${pmRoot}. Run pm init first.`,\n EXIT_CODE.NOT_FOUND,\n );\n }\n const settings = await readSettings(pmRoot);\n const typeRegistry = resolveItemTypeRegistry(\n settings,\n getActiveExtensionRegistrations(),\n );\n if (at !== undefined) {\n const historical = await getItemAt(id, at, { pmRoot: global.path });\n return {\n pmRoot,\n settings,\n typeToFolder: typeRegistry.type_to_folder,\n locatedId: historical.document.metadata.id,\n metadata: historical.document.metadata,\n body: historical.document.body,\n historical,\n };\n }\n const located = await locateItem(\n pmRoot,\n id,\n settings.id_prefix,\n settings.item_format,\n typeRegistry.type_to_folder,\n );\n if (!located) {\n throw await buildItemNotFoundError(\n pmRoot,\n id,\n settings.id_prefix,\n typeRegistry.type_to_folder,\n );\n }\n const loaded = await readLocatedItem(located, { schema: settings.schema });\n return {\n pmRoot,\n settings,\n typeToFolder: typeRegistry.type_to_folder,\n locatedId: located.id,\n metadata: loaded.document.metadata,\n body: loaded.document.body,\n };\n}\n\nfunction validateGetProjectionFields(\n fields: string[] | null,\n settings: Awaited<ReturnType<typeof readSettings>>,\n historical: boolean,\n): void {\n const runtimeMetadataKeys = resolveRuntimeFieldRegistry(\n settings.schema,\n ).definitions.map((field) => field.metadata_key);\n validateGetFields(fields, runtimeMetadataKeys);\n if (historical && fieldsIncludeRoot(fields ?? [], \"children\")) {\n throw new PmCliError(\n \"Get --at cannot project children because workspace-level historical relationships are not yet indexed.\",\n EXIT_CODE.USAGE,\n );\n }\n}\n\nfunction shouldIncludeGetField(params: {\n fieldProjection: boolean;\n depth: GetDepth;\n fields: string[] | null;\n field: \"body\" | \"linked\" | \"claim_state\";\n}): boolean {\n const { fieldProjection, depth, fields, field } = params;\n if (fieldProjection) {\n if (field === \"body\" || field === \"linked\") {\n return fieldsInclude(fields, field);\n }\n return fieldsIncludeRoot(fields as string[], field);\n }\n return depth !== \"brief\";\n}\n\nasync function resolveGetClaimState(\n context: GetItemContext,\n includeClaimState: boolean,\n): Promise<ClaimStateContext | undefined> {\n if (!includeClaimState) {\n return undefined;\n }\n const historyPath = getHistoryPath(context.pmRoot, context.locatedId);\n const history = await readHistoryEntries(historyPath, context.locatedId);\n return resolveClaimStateContext(\n context.metadata.assignee,\n context.historical\n ? history.slice(0, context.historical.as_of_version)\n : history,\n );\n}\n\nfunction attachGetLinked(\n result: GetResult,\n context: GetItemContext,\n fields: string[] | null,\n includeLinked: boolean,\n): void {\n const includeLinkedFiles =\n includeLinked || fieldsInclude(fields, \"linked.files\");\n const includeLinkedTests =\n includeLinked || fieldsInclude(fields, \"linked.tests\");\n const includeLinkedDocs =\n includeLinked || fieldsInclude(fields, \"linked.docs\");\n if (\n !includeLinked &&\n !includeLinkedFiles &&\n !includeLinkedTests &&\n !includeLinkedDocs\n ) {\n return;\n }\n result.linked = {\n files: includeLinkedFiles ? (context.metadata.files ?? []) : [],\n tests: includeLinkedTests ? (context.metadata.tests ?? []) : [],\n docs: includeLinkedDocs ? (context.metadata.docs ?? []) : [],\n };\n}\n\nasync function buildGetChildrenRollup(\n context: GetItemContext,\n includeChildren: boolean,\n includeEmpty: boolean,\n): Promise<ChildRollupContext | undefined> {\n if (!includeChildren) {\n return undefined;\n }\n const statusRegistry = resolveRuntimeStatusRegistry(context.settings.schema);\n const corpus = await listAllItemMetadataLight(\n context.pmRoot,\n context.settings.item_format,\n context.typeToFolder,\n undefined,\n context.settings.schema,\n );\n const rollup = buildItemChildrenRollup(\n context.locatedId,\n corpus,\n statusRegistry,\n );\n return rollup.count > 0 || includeEmpty ? rollup : undefined;\n}\n\nfunction attachGetSchedule(\n result: GetResult,\n context: GetItemContext,\n fields: string[] | null,\n includeSchedule: boolean,\n): void {\n if (!includeSchedule) {\n return;\n }\n const schedule = buildItemSchedule(context.metadata);\n if (!schedule) {\n return;\n }\n if (fields === null || fieldsInclude(fields, \"schedule\")) {\n result.schedule = schedule;\n return;\n }\n result.schedule = Object.fromEntries(\n Object.entries(schedule).filter(([key]) =>\n fields.some(\n (field) => normalizeGetField(field) === `schedule.${key}`,\n ),\n ),\n ) as Partial<ItemScheduleContext>;\n}\n\nasync function buildGetTree(\n context: GetItemContext,\n options: GetOptions,\n treeDepth: number | undefined,\n global: GlobalOptions,\n): Promise<GetResult[\"tree\"] | undefined> {\n if (options.tree !== true) {\n return undefined;\n }\n const subtree = await runList(\n undefined,\n {\n parent: context.locatedId,\n tree: true,\n treeDepth: treeDepth === undefined ? undefined : String(treeDepth),\n full: true,\n },\n global,\n );\n return {\n root_id: context.locatedId,\n root_title: context.metadata.title,\n depth_limit: treeDepth ?? null,\n count: subtree.count,\n items: subtree.items.map((entry) => toItemRecord(entry)),\n };\n}\n\n/** Implements run get for the public runtime surface of this module. */\nexport async function runGet(\n id: string,\n global: GlobalOptions,\n options: GetOptions = {},\n): Promise<GetResult> {\n const projection = resolveGetProjection(options);\n const context = await loadGetItemContext(id, global, options.at);\n validateGetProjectionFields(\n projection.fields,\n context.settings,\n context.historical !== undefined,\n );\n const includeBody = shouldIncludeGetField({ ...projection, field: \"body\" });\n const includeLinked = shouldIncludeGetField({\n ...projection,\n field: \"linked\",\n });\n const includeClaimState = shouldIncludeGetField({\n ...projection,\n field: \"claim_state\",\n });\n const includeChildren =\n context.historical === undefined &&\n (projection.fieldProjection\n ? fieldsIncludeRoot(projection.fields as string[], \"children\")\n : projection.depth !== \"brief\" &&\n shouldAutoIncludeGetChildren(context.metadata.type));\n const includeSchedule = projection.fieldProjection\n ? fieldsIncludeRoot(projection.fields as string[], \"schedule\")\n : projection.depth !== \"brief\";\n const claimState = await resolveGetClaimState(context, includeClaimState);\n const result: GetResult = {\n item: projection.fieldProjection\n ? projectItemForFields(context.metadata, projection.fields as string[])\n : projectItemForDepth(context.metadata, projection.depth),\n };\n if (includeBody) {\n result.item.body = context.body;\n }\n attachGetLinked(result, context, projection.fields, includeLinked);\n if (claimState) {\n result.claim_state = claimState;\n }\n attachGetSchedule(result, context, projection.fields, includeSchedule);\n result.children = await buildGetChildrenRollup(\n context,\n includeChildren,\n projection.fieldProjection,\n );\n result.tree = await buildGetTree(\n context,\n options,\n projection.treeDepth,\n global,\n );\n if (context.historical) {\n result.reconstructed = true;\n result.as_of_version = context.historical.as_of_version;\n result.as_of_timestamp = context.historical.as_of_timestamp;\n }\n if (context.historical === undefined) {\n try {\n await recordContextUsageTouches({\n pmRoot: context.pmRoot,\n author:\n (process.env.PM_AUTHOR ?? context.settings.author_default).trim() ||\n \"unknown\",\n itemIds: [context.locatedId],\n intent: \"get\",\n });\n } catch {\n // Derived usage feedback must never make the source-of-truth read fail.\n }\n }\n return result;\n}\n\n/** Public contract for test-only get command policy helpers. */\nexport const _testOnlyGetCommand = {\n shouldAutoIncludeGetChildren,\n};\n","/**\n * @module sdk/query/search\n *\n * Implements the pm search command surface and its agent-facing runtime behavior.\n */\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n coerceNumberInRange,\n toNonEmptyStringOrUndefined,\n} from \"../../core/shared/primitives.js\";\nimport { isPathWithinDirectory } from \"../../core/fs/path-utils.js\";\nimport {\n getActiveExtensionRegistrations,\n runActiveOnReadHooks,\n} from \"../../core/extensions/index.js\";\nimport { collectRegisteredItemFieldNames } from \"../../core/extensions/item-fields.js\";\nimport {\n resolveRegisteredSearchProvider,\n resolveRegisteredVectorStoreAdapter,\n} from \"../../core/extensions/runtime-registrations.js\";\nimport {\n resolveItemTypeRegistry,\n type ItemTypeRegistry,\n} from \"../../core/item/type-registry.js\";\nimport { parseLimit, parsePriority, parseType } from \"./parsers.js\";\nimport {\n executeEmbeddingRequest,\n resolveEmbeddingProviders,\n type EmbeddingProviderConfig,\n type EmbeddingProviderResolution,\n} from \"../../core/search/providers.js\";\nimport {\n buildDeterministicQueryExpansions,\n mergeQueryExpansions,\n normalizeQueryExpansionOutput,\n normalizeRerankOutput,\n rerankCandidatesWithEmbeddings,\n resolveQueryExpansionConfig,\n resolveRerankConfig,\n type QueryExpansionConfig,\n type RerankCandidate,\n type RerankConfig,\n} from \"../../core/search/relevance.js\";\nimport { resolveSettingsWithSemanticRuntimeDefaults } from \"../../core/search/semantic-defaults.js\";\nimport {\n executeVectorQuery,\n resolveVectorStores,\n type VectorQueryHit,\n type VectorStoreConfig,\n type VectorStoreResolution,\n} from \"../../core/search/vector-stores.js\";\nimport { readVectorizationStatusLedger } from \"../../core/search/cache.js\";\nimport {\n buildEventCorpus,\n buildPlanFlatCorpus,\n buildReminderCorpus,\n buildSearchCorpus,\n resolveSearchCorpusFields,\n} from \"../../core/search/corpus.js\";\nimport {\n buildBm25Index,\n flattenSearchCorpusText,\n resolveBm25Params,\n scoreBm25Query,\n tokenizeBm25,\n type Bm25Params,\n} from \"../../core/search/bm25.js\";\nimport { collectStaleVectorizationIds } from \"../../core/search/staleness.js\";\nimport { pathExists } from \"../../core/fs/fs-utils.js\";\nimport { parseItemDocument } from \"../../core/item/item-format.js\";\nimport { toItemRecord } from \"../../core/item/item-record.js\";\nimport { isTerminalStatus } from \"../../core/item/status.js\";\nimport { parseStatusFilterCsv } from \"../../core/item/status-filter.js\";\nimport {\n collectRuntimeFilterValues,\n matchesRuntimeFilters,\n} from \"../../core/schema/runtime-field-filters.js\";\nimport {\n hasMissingMetadataFilter,\n itemMatchesMissingMetadata,\n lifecycleClassifierFromStatusRegistry,\n type LifecycleClassifier,\n} from \"../../core/governance/metadata-coverage.js\";\nimport {\n hasContentFieldFilter,\n itemMatchesContentFilters,\n} from \"../../core/governance/content-fields.js\";\nimport {\n resolveContentFieldFilters,\n resolveMissingMetadataFilters,\n} from \"./list.js\";\nimport {\n buildCompactSearchFilterSummary,\n buildVerboseSearchFilters,\n type SearchMode,\n} from \"./search-rendering.js\";\nimport {\n resolveRuntimeFieldRegistry,\n resolveRuntimeStatusRegistry,\n type RuntimeFieldRegistry,\n type RuntimeStatusRegistry,\n} from \"../../core/schema/runtime-schema.js\";\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { tokenizeAlphaNumeric } from \"../../core/shared/text-normalization.js\";\nimport {\n compareTimestampStrings,\n matchesTimestampFilters,\n nowIso,\n resolveIsoOrRelative,\n} from \"../../core/shared/time.js\";\nimport { listAllDocumentCandidatesCached } from \"../../core/store/item-metadata-cache.js\";\nimport { listAllItemMetadata } from \"../../core/store/item-store.js\";\nimport {\n getItemPath,\n getSettingsPath,\n resolveGlobalPmRoot,\n resolvePmRoot,\n} from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport type {\n ItemDocument,\n ItemFormat,\n ItemMetadata,\n ItemStatus,\n ItemType,\n PmSettings,\n} from \"../../types/index.js\";\nimport type { SharedItemFilterOptions } from \"./item-filter-options.js\";\nimport { resolveSearchPage } from \"./search-pagination.js\";\n\n/** Documents the search options payload exchanged by command, SDK, and package integrations. */\nexport interface SearchOptions extends SharedItemFilterOptions {\n /** Value that configures or reports mode for this contract. */\n mode?: string;\n /** Strategy used to control match behavior. */\n matchMode?: string;\n /** Value that configures or reports min score for this contract. */\n minScore?: string | number;\n /** Value that configures or reports count for this contract. */\n count?: boolean;\n /** Value that configures or reports semantic weight for this contract. */\n semanticWeight?: string | number;\n /** Value that configures or reports include linked for this contract. */\n includeLinked?: boolean;\n /** Value that configures or reports title exact for this contract. */\n titleExact?: boolean;\n /** Value that configures or reports phrase exact for this contract. */\n phraseExact?: boolean;\n /** Value that configures or reports limit for this contract. */\n limit?: string;\n /** Opaque cursor returned by a previous search page. */\n after?: string;\n /** Value that configures or reports compact for this contract. */\n compact?: boolean;\n /** Value that configures or reports full for this contract. */\n full?: boolean;\n /** Value that configures or reports fields for this contract. */\n fields?: string;\n // GH-157: emit per-field matched-text snippets on each hit (off by default for\n // token efficiency). Highlighted spans are wrapped with the «…» markers.\n /** Value that configures or reports highlight for this contract. */\n highlight?: boolean;\n}\n\n/** Restricts search match mode values accepted by command, SDK, and storage contracts. */\nexport type SearchMatchMode = \"and\" | \"or\" | \"exact\";\n\ntype SearchProjectionMode = \"compact\" | \"full\" | \"fields\";\n\ninterface SearchProjectionConfig {\n mode: SearchProjectionMode;\n fields: string[];\n}\n\nconst DEFAULT_COMPACT_SEARCH_FIELDS = [\n \"id\",\n \"title\",\n \"status\",\n \"type\",\n \"priority\",\n \"updated_at\",\n \"score\",\n \"matched_fields\",\n] as const;\n\nconst SEARCH_HIT_FIELD_KEYS = new Set([\n \"score\",\n \"matched_fields\",\n \"highlights\",\n]);\nconst SEARCH_ITEM_FIELD_KEYS = new Set([\n \"id\",\n \"title\",\n \"description\",\n \"type\",\n \"status\",\n \"priority\",\n \"tags\",\n \"created_at\",\n \"updated_at\",\n \"deadline\",\n \"assignee\",\n \"author\",\n \"estimated_minutes\",\n \"acceptance_criteria\",\n \"dependencies\",\n \"comments\",\n \"notes\",\n \"learnings\",\n \"reminders\",\n \"events\",\n \"files\",\n \"tests\",\n \"docs\",\n \"close_reason\",\n \"parent\",\n \"reviewer\",\n \"risk\",\n \"confidence\",\n \"sprint\",\n \"release\",\n \"blocked_by\",\n \"blocked_reason\",\n \"reporter\",\n \"severity\",\n \"environment\",\n \"repro_steps\",\n \"resolution\",\n \"expected_result\",\n \"actual_result\",\n \"affected_version\",\n \"fixed_version\",\n \"component\",\n \"regression\",\n \"customer_impact\",\n \"definition_of_ready\",\n \"order\",\n \"rank\",\n \"goal\",\n \"objective\",\n \"value\",\n \"impact\",\n \"outcome\",\n \"why_now\",\n \"plan\",\n]);\n\nconst LONG_QUERY_TOKEN_THRESHOLD = 2;\nconst LONG_QUERY_TITLE_EXACT_BONUS = 120;\nconst LONG_QUERY_PHRASE_MULTIPLIER = 6;\n// GH-181: in default (OR) match mode, multi-token queries that match EVERY\n// distinct query token in some searchable field get an additive ranking bonus so\n// items covering all terms outrank items matching only a subset. This is a\n// RANKING preference, not a hard filter (use --match-mode and for that).\nconst ALL_TERMS_COVERAGE_BONUS = 40;\nconst EXACT_ID_MATCH_SCORE = 1_000;\nconst SHORT_ID_MATCH_SCORE = 900;\n\n// GH-157 matched-text highlighting (--highlight): markers wrapping each matching\n// token run, and the number of characters of surrounding context retained on\n// each side of the first match in a field. The «…» guillemets are single\n// characters with negligible collision risk against item text, keeping the\n// snippet token-cheap while staying visually unambiguous for agents.\nconst HIGHLIGHT_OPEN = \"«\";\nconst HIGHLIGHT_CLOSE = \"»\";\nconst HIGHLIGHT_SNIPPET_RADIUS = 60;\n\n// GH-157 inline query syntax: bare `field:value` tokens parsed out of the query\n// string and applied as the equivalent filter. The value may itself contain\n// colons (e.g. `tag:area:search`), so only the FIRST colon delimits field from\n// value. Explicit --field flags take precedence over an inline token (see\n// resolveInlineQueryFilters).\nconst INLINE_QUERY_FILTER_FIELDS = [\n \"tag\",\n \"status\",\n \"type\",\n \"priority\",\n] as const;\ntype InlineQueryFilterField = (typeof INLINE_QUERY_FILTER_FIELDS)[number];\n\n/** Documents the search hit payload exchanged by command, SDK, and package integrations. */\nexport interface SearchHit {\n /** Value that configures or reports item for this contract. */\n item: ItemMetadata;\n /** Value that configures or reports score for this contract. */\n score: number;\n /** Value that configures or reports matched fields for this contract. */\n matched_fields: string[];\n // GH-181: whether every distinct query token matched some searchable field.\n // Used by --match-mode and (hard filter) and the default all-terms ranking\n // bonus. Not projected into output rows.\n /** Value that configures or reports matched all terms for this contract. */\n matched_all_terms?: boolean;\n // GH-281: marks the keyword hit produced by the exact full-ID / short-ID\n // early-return in scoreDocument(). The semantic & hybrid ranking paths use it\n // to guarantee the exact-ID target ALWAYS ranks #1 (and is exempt from the\n // score threshold / limit), so the keyword-mode exact-ID guarantee is never\n // lost once vector blending is active. SHORT_ID matches keep score=900 and\n // full-ID matches keep score=1000, so sortHits still orders full above short.\n // Not projected into output rows.\n /** Value that configures or reports exact id match for this contract. */\n exact_id_match?: boolean;\n // GH-157: per-field matched-text snippets, populated only when the caller\n // passes --highlight. Each entry pairs a matched field name with a snippet of\n // its text where the matching token runs are wrapped in the «…» markers.\n /** Value that configures or reports highlights for this contract. */\n highlights?: SearchHitHighlight[];\n}\n\n/**\n * Pairs a matched field name with a snippet of its text where every matching\n * token run is wrapped in the {@link HIGHLIGHT_OPEN}/{@link HIGHLIGHT_CLOSE}\n * markers. Emitted on {@link SearchHit.highlights} when `--highlight` is set.\n */\nexport interface SearchHitHighlight {\n /** Value that configures or reports field for this contract. */\n field: string;\n /** Value that configures or reports snippet for this contract. */\n snippet: string;\n}\n\n/** Restricts search result item values accepted by command, SDK, and storage contracts. */\nexport type SearchResultItem = SearchHit | Record<string, unknown>;\n\ninterface SearchResultBase {\n query: string;\n mode: SearchMode;\n items: SearchResultItem[];\n count: number;\n // GH-181: total matched hits after filters/threshold but BEFORE the limit\n // truncation. Lets callers see how many matched before the (now-default)\n // keyword limit dropped rows. Only emitted when it differs from count.\n total?: number;\n /** Whether additional ranked hits remain after this page. */\n has_more?: boolean;\n /** Opaque continuation cursor when additional hits remain. */\n next_cursor?: string;\n /** Effective page size for this response. */\n applied_limit?: number;\n /** Explicit marker that the response is a bounded page. */\n truncated?: true;\n // --count mode: count-only response carries the matched total and skips the\n // hit rows entirely (items is empty). `count` reflects the same total.\n count_only?: boolean;\n warnings?: string[];\n}\n\n/** Documents the search compact result payload exchanged by command, SDK, and package integrations. */\nexport interface SearchCompactResult extends SearchResultBase {\n /** Value that configures or reports filters for this contract. */\n filters: Record<string, unknown>;\n /** Value that configures or reports projection for this contract. */\n projection?: undefined;\n /** Value that configures or reports now for this contract. */\n now?: undefined;\n}\n\n/** Documents the search verbose result payload exchanged by command, SDK, and package integrations. */\nexport interface SearchVerboseResult extends SearchResultBase {\n /** Value that configures or reports filters for this contract. */\n filters: Record<string, unknown>;\n /** Value that configures or reports projection for this contract. */\n projection: {\n mode: SearchProjectionMode;\n fields: string[] | null;\n };\n /** Value that configures or reports now for this contract. */\n now: string;\n}\n\n/** Restricts search result values accepted by command, SDK, and storage contracts. */\nexport type SearchResult = SearchCompactResult | SearchVerboseResult;\n\ninterface ExtensionSearchProviderContext {\n query: string;\n mode: SearchMode;\n tokens: string[];\n options: SearchOptions;\n settings: PmSettings;\n documents: ItemDocument[];\n}\n\ninterface ExtensionSearchProviderHit {\n id: string;\n score: number;\n matched_fields?: string[];\n}\n\ntype ExtensionSearchProviderQuery = (\n context: ExtensionSearchProviderContext,\n) =>\n | Promise<\n ExtensionSearchProviderHit[] | { hits?: ExtensionSearchProviderHit[] }\n >\n | ExtensionSearchProviderHit[]\n | { hits?: ExtensionSearchProviderHit[] };\n\ninterface ExtensionSearchProviderQueryExpansionContext {\n query: string;\n mode: Exclude<SearchMode, \"keyword\">;\n settings: PmSettings;\n}\n\ntype ExtensionSearchProviderQueryExpansion = (\n context: ExtensionSearchProviderQueryExpansionContext,\n) =>\n | Promise<string[] | { queries?: string[] }>\n | string[]\n | { queries?: string[] };\n\ninterface ExtensionSearchProviderRerankCandidate {\n id: string;\n text: string;\n score: number;\n}\n\ninterface ExtensionSearchProviderRerankContext {\n query: string;\n mode: \"hybrid\";\n model: string;\n top_k: number;\n settings: PmSettings;\n candidates: ExtensionSearchProviderRerankCandidate[];\n}\n\ntype ExtensionSearchProviderRerank = (\n context: ExtensionSearchProviderRerankContext,\n) =>\n | Promise<\n | Array<{ id?: unknown; score?: unknown }>\n | { hits?: Array<{ id?: unknown; score?: unknown }> }\n >\n | Array<{ id?: unknown; score?: unknown }>\n | { hits?: Array<{ id?: unknown; score?: unknown }> };\n\ntype ExtensionVectorQuery = (context: {\n vector: number[];\n limit: number;\n settings: PmSettings;\n}) => Promise<VectorQueryHit[]> | VectorQueryHit[];\n\ntype ExtensionVectorUpsert = (context: {\n points: Array<{\n id: string;\n vector: number[];\n payload: Record<string, unknown>;\n }>;\n settings: PmSettings;\n}) => Promise<void> | void;\n\ntype ExtensionVectorAdapter = {\n adapterName: string;\n query?: ExtensionVectorQuery;\n upsert?: ExtensionVectorUpsert;\n};\n\ninterface SearchModeContext {\n hasProvider: boolean;\n hasVectorStore: boolean;\n}\n\ntype ImplicitSemanticFallbackReason = \"timeout\" | \"connection\" | \"error\";\n\n/**\n * Aggregate the `code` strings found along an error's `cause` chain.\n *\n * undici (Node's fetch) collapses connection errors to the generic message\n * \"fetch failed\" and stashes the real syscall code (e.g. `ECONNREFUSED`) on\n * `error.cause.code`. Walking the chain (bounded depth) lets the fallback\n * classifier label a downed/unreachable Ollama backend as \"connection\" rather\n * than the catch-all \"error\".\n */\nexport function collectErrorCauseCodes(error: unknown): string {\n const codes: string[] = [];\n let current: unknown = error;\n for (\n let depth = 0;\n depth < 5 && current && typeof current === \"object\";\n depth += 1\n ) {\n const code = (current as { code?: unknown }).code;\n if (typeof code === \"string\") {\n codes.push(code.toLowerCase());\n }\n current = (current as { cause?: unknown }).cause;\n }\n return codes.join(\" \");\n}\n\n/**\n * Classify why an implicit/explicit semantic search degraded to keyword mode,\n * inspecting both the error message and the {@link collectErrorCauseCodes} chain\n * so undici's generic \"fetch failed\" is recognised as a connection failure.\n */\nexport function classifyImplicitSemanticFallbackReason(\n error: unknown,\n): ImplicitSemanticFallbackReason {\n const message = (\n error instanceof Error ? error.message : String(error)\n ).toLowerCase();\n const causeCodes = collectErrorCauseCodes(error);\n const haystack = `${message} ${causeCodes}`;\n if (\n haystack.includes(\"timed out\") ||\n haystack.includes(\"timeout\") ||\n haystack.includes(\"etimedout\")\n ) {\n return \"timeout\";\n }\n if (\n haystack.includes(\"econnrefused\") ||\n haystack.includes(\"connection refused\") ||\n haystack.includes(\"connect \") ||\n haystack.includes(\"enotfound\") ||\n haystack.includes(\"eai_again\") ||\n haystack.includes(\"econnreset\") ||\n haystack.includes(\"fetch failed\")\n ) {\n return \"connection\";\n }\n return \"error\";\n}\n\n// Explicit --semantic/--hybrid searches must never hard-fail an agent when the\n// embedding/vector backend is unreachable or unconfigured: degrade to keyword\n// search and surface a machine-readable warning instead of an unknown_error.\nfunction buildExplicitSemanticFallbackWarning(\n requestedMode: SearchMode,\n error: unknown,\n): string {\n const reason = classifyImplicitSemanticFallbackReason(error);\n return `search_${requestedMode}_fallback:${reason}:using_keyword_mode`;\n}\n\n/** Compare the vectorization-status ledger against the filtered corpus and, when the vector index is behind, emit a one-line stderr warning plus a structured `vector_index_stale:N` entry in the JSON warnings array. Best-effort: ledger read failures fall through silently — the existing semantic/hybrid fallback paths cover backend errors. */\nasync function maybeEmitVectorIndexStaleWarning(\n pmRoot: string,\n filteredDocuments: ItemDocument[],\n warnings: string[],\n): Promise<void> {\n try {\n const ledger = await readVectorizationStatusLedger(pmRoot);\n if (ledger.warnings.length > 0) {\n warnings.push(...ledger.warnings);\n }\n const staleIds = collectStaleVectorizationIds(\n filteredDocuments.map((document) => ({\n id: document.metadata.id,\n updated_at: document.metadata.updated_at,\n })),\n ledger.entries,\n );\n if (staleIds.length === 0) {\n return;\n }\n warnings.push(`vector_index_stale:${staleIds.length}`);\n /* c8 ignore start -- singular/plural warning text branches are cosmetic and validated in integration UX tests */\n process.stderr.write(\n `[pm] warning: ${staleIds.length} item${staleIds.length === 1 ? \" is\" : \"s are\"} new or modified since the last reindex and ${staleIds.length === 1 ? \"is\" : \"are\"} NOT in the semantic index yet — they will be missing from semantic/hybrid results until you run 'pm reindex --mode hybrid'. (Write-time embedding is governed by search.mutation_refresh_policy; staleness means the embed was skipped, failed, or the backend was unreachable.)\\n`,\n );\n /* c8 ignore stop */\n } catch {\n // Best-effort: missing/unreadable ledger is not a query-blocking concern.\n }\n}\n\nfunction parseMode(\n raw: string | undefined,\n _context: SearchModeContext,\n): SearchMode {\n if (raw === undefined) {\n return \"keyword\";\n }\n const normalized = raw.trim().toLowerCase();\n if (\n normalized !== \"keyword\" &&\n normalized !== \"semantic\" &&\n normalized !== \"hybrid\"\n ) {\n throw new PmCliError(\n \"Search mode must be one of keyword|semantic|hybrid\",\n EXIT_CODE.USAGE,\n );\n }\n return normalized;\n}\n\nfunction parseIncludeLinked(raw: boolean | undefined): boolean {\n return raw === true;\n}\n\nfunction parseTitleExact(raw: boolean | undefined): boolean {\n return raw === true;\n}\n\nfunction parsePhraseExact(raw: boolean | undefined): boolean {\n return raw === true;\n}\n\nfunction parseSemanticWeightOverride(raw: unknown): number | undefined {\n return coerceNumberInRange(raw, 0, 1) ?? undefined;\n}\n\nfunction parseMatchMode(raw: string | undefined): SearchMatchMode {\n if (raw === undefined) {\n return \"or\";\n }\n const normalized = raw.trim().toLowerCase();\n if (normalized !== \"and\" && normalized !== \"or\" && normalized !== \"exact\") {\n throw new PmCliError(\n \"Search --match-mode must be one of and|or|exact\",\n EXIT_CODE.USAGE,\n );\n }\n return normalized;\n}\n\n// Per-query --min-score overrides the persistent search.score_threshold for this\n// query only. Accepts a finite number >= 0; anything else is a usage error.\nfunction parseMinScoreOverride(raw: unknown): number | undefined {\n if (raw === undefined || raw === null || raw === \"\") {\n return undefined;\n }\n /* c8 ignore start -- numeric-vs-string coercion branch is exercised via integration CLI parsing */\n const parsed = typeof raw === \"number\" ? raw : Number(String(raw).trim());\n /* c8 ignore stop */\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new PmCliError(\n \"Search --min-score must be a finite number >= 0\",\n EXIT_CODE.USAGE,\n );\n }\n return parsed;\n}\n\n// updated/created date-window filters share the deadline ISO+relative resolver\n// so `pm search` matches `pm list` semantics exactly: pass an ISO timestamp or a\n// SIGNED relative offset (\"-2h\"/\"-7d\" reach into the past, \"+1d\" the future;\n// units h/d/w/m, m = months — there is no minutes unit).\nfunction parseTimestampWindow(\n raw: unknown,\n fieldLabel: string,\n): string | undefined {\n if (raw == null) return undefined;\n const value = String(raw).trim();\n if (value.length === 0) return undefined;\n return resolveIsoOrRelative(value, new Date(), fieldLabel);\n}\n\nfunction normalizeSearchPhrase(value: string): string {\n return value.toLowerCase().replace(/\\s+/g, \" \").trim();\n}\n\nfunction parseDeadline(\n raw: string | undefined,\n fieldLabel: string,\n): string | undefined {\n if (raw === undefined) return undefined;\n return resolveIsoOrRelative(raw, new Date(), fieldLabel);\n}\n\nfunction parseFieldSelectors(raw: string | undefined): string[] | undefined {\n if (raw === undefined) {\n return undefined;\n }\n const selectors = raw\n .split(\",\")\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0);\n if (selectors.length === 0) {\n throw new PmCliError(\n \"Search --fields requires a comma-separated list of field names\",\n EXIT_CODE.USAGE,\n );\n }\n return [...new Set(selectors)];\n}\n\nfunction parseProjectionConfig(options: SearchOptions): SearchProjectionConfig {\n const compactRequested = options.compact === true;\n const fullRequested = options.full === true;\n const fieldSelectors = parseFieldSelectors(options.fields);\n const enabledModes =\n Number(compactRequested) +\n Number(fullRequested) +\n Number(fieldSelectors !== undefined);\n if (enabledModes > 1) {\n throw new PmCliError(\n \"Search projection options are mutually exclusive. Use one of --compact, --full, or --fields.\",\n EXIT_CODE.USAGE,\n );\n }\n if (compactRequested) {\n return {\n mode: \"compact\",\n fields: [...DEFAULT_COMPACT_SEARCH_FIELDS],\n };\n }\n if (fullRequested) {\n return {\n mode: \"full\",\n fields: [],\n };\n }\n if (fieldSelectors) {\n return {\n mode: \"fields\",\n fields: fieldSelectors,\n };\n }\n return {\n mode: \"full\",\n fields: [],\n };\n}\n\n/** Public contract for test only search command, shared by SDK and presentation-layer consumers. */\nexport const _testOnlySearchCommand = {\n applyFilters,\n applyExactQueryFilters,\n applyInlineQueryFilters,\n buildHitHighlights,\n buildVerboseSearchFilters,\n buildExplicitSemanticFallbackWarning,\n buildCompactSearchFilterSummary,\n buildHybridLexicalScore,\n buildRerankCorpus,\n buildSemanticHits,\n classifyImplicitSemanticFallbackReason,\n collectErrorCauseCodes,\n collectExactPhraseFields,\n collectLinkedPaths,\n combineHybridHits,\n computeBuiltInBm25Hits,\n computeSemanticOrHybridHits,\n resolveBuiltInBm25Mode,\n countOccurrences,\n dependencyEntries,\n documentContainsExactPhrase,\n emptySearchResult,\n highlightFieldSnippet,\n loadDocuments,\n markTokenRuns,\n parseInlineQueryFilters,\n maybeEmitVectorIndexStaleWarning,\n loadLinkedCorpus,\n mergeVectorHitsById,\n normalizeExtensionProviderHits,\n normalizeScoreMap,\n parseProjectionConfig,\n parseTimestampWindow,\n parseTokens,\n projectSearchHits,\n readSearchFieldValue,\n requireSemanticDependencies,\n resolveExtensionSearchProvider,\n resolveExtensionSearchProviderByName,\n resolveExtensionVectorAdapter,\n resolveLinkedCorpusRoots,\n scoreDocument,\n sortHits,\n stringArray,\n textEntries,\n validateSearchProjectionFields,\n};\n\n/* c8 ignore start -- projection/runtime-field validation edge permutations are covered by integration query-contract tests */\nfunction validateSearchProjectionFields(\n projection: SearchProjectionConfig,\n runtimeFieldRegistry: RuntimeFieldRegistry,\n): void {\n if (projection.mode !== \"fields\") {\n return;\n }\n const runtimeKeys = new Set(\n runtimeFieldRegistry.definitions.flatMap((field) => [\n field.key,\n field.metadata_key,\n ]),\n );\n const unknown = projection.fields.filter((field) => {\n const normalized = field.trim();\n const itemKey = normalized.startsWith(\"item.\")\n ? normalized.slice(\"item.\".length)\n : normalized;\n return (\n !SEARCH_HIT_FIELD_KEYS.has(normalized) &&\n !SEARCH_ITEM_FIELD_KEYS.has(itemKey) &&\n !runtimeKeys.has(itemKey)\n );\n });\n if (unknown.length > 0) {\n throw new PmCliError(\n `Unknown search --fields value(s): ${unknown.join(\", \")}`,\n EXIT_CODE.USAGE,\n {\n examples: [\n \"pm search <query> --fields id,title,status,score\",\n \"pm search <query> --fields id,title,item.description,matched_fields\",\n ],\n nextSteps: [\n \"Use item.<field> for explicit item metadata fields, or run pm search --help for projection examples.\",\n ],\n },\n );\n }\n}\n/* c8 ignore stop */\n\nfunction parseTokens(query: string): string[] {\n const normalized = normalizeSearchPhrase(query);\n if (!normalized) {\n throw new PmCliError(\"Search query must not be empty\", EXIT_CODE.USAGE);\n }\n return normalized.split(/\\s+/).filter(Boolean);\n}\n\n/** Result of extracting inline `field:value` tokens from a raw search query. */\ninterface InlineQueryParse {\n /** The query with all recognized inline filter tokens removed. */\n residualQuery: string;\n /** Recognized inline filters keyed by field name; first occurrence per field wins. */\n inlineFilters: Partial<Record<InlineQueryFilterField, string>>;\n}\n\n/**\n * Split a raw search query into its residual keyword text and any inline\n * `field:value` filter tokens (GH-157). Recognized fields are\n * {@link INLINE_QUERY_FILTER_FIELDS}; the value runs to the end of the token so\n * colon-bearing values like `tag:area:search` parse as `{ tag: \"area:search\" }`.\n * Only the first occurrence of each field is captured — later duplicates are left\n * in the residual query so they are never silently dropped. Tokens whose prefix\n * is not a recognized field (`foo:bar`) stay in the residual query verbatim.\n */\nfunction parseInlineQueryFilters(query: string): InlineQueryParse {\n const inlineFilters: Partial<Record<InlineQueryFilterField, string>> = {};\n const residualTokens: string[] = [];\n for (const token of query.split(/\\s+/).filter((entry) => entry.length > 0)) {\n const separatorIndex = token.indexOf(\":\");\n const field =\n separatorIndex > 0 ? token.slice(0, separatorIndex).toLowerCase() : \"\";\n const value = separatorIndex > 0 ? token.slice(separatorIndex + 1) : \"\";\n const matchedField = (\n INLINE_QUERY_FILTER_FIELDS as ReadonlyArray<string>\n ).includes(field)\n ? (field as InlineQueryFilterField)\n : undefined;\n if (\n matchedField &&\n value.length > 0 &&\n inlineFilters[matchedField] === undefined\n ) {\n inlineFilters[matchedField] = value;\n continue;\n }\n residualTokens.push(token);\n }\n return {\n residualQuery: residualTokens.join(\" \"),\n inlineFilters,\n };\n}\n\n/** Merge inline `field:value` filters into a search options object (GH-157). Explicit `--field` flags always win: an inline token is applied only when the corresponding option is not already set, and a conflicting inline token is recorded as a `search_inline_filter_ignored:<field>:flag_takes_precedence` warning so the override is observable rather than silent. Returns a fresh options object — the caller's input is never mutated. */\nfunction applyInlineQueryFilters(\n options: SearchOptions,\n inlineFilters: Partial<Record<InlineQueryFilterField, string>>,\n warnings: string[],\n): SearchOptions {\n const merged: SearchOptions = { ...options };\n for (const field of INLINE_QUERY_FILTER_FIELDS) {\n const inlineValue = inlineFilters[field];\n if (inlineValue === undefined) {\n continue;\n }\n if (toNonEmptyStringOrUndefined(merged[field]) !== undefined) {\n warnings.push(\n `search_inline_filter_ignored:${field}:flag_takes_precedence`,\n );\n continue;\n }\n merged[field] = inlineValue;\n }\n return merged;\n}\n\nfunction stringArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((entry): entry is string => typeof entry === \"string\")\n : [];\n}\n\nfunction textEntries(value: unknown): Array<{ text: string }> {\n return Array.isArray(value)\n ? value.filter(\n (entry): entry is { text: string } =>\n typeof entry === \"object\" &&\n entry !== null &&\n typeof (entry as { text?: unknown }).text === \"string\",\n )\n : [];\n}\n\nfunction dependencyEntries(\n value: unknown,\n): Array<{ id: string; kind: string }> {\n return Array.isArray(value)\n ? value.filter(\n (entry): entry is { id: string; kind: string } =>\n typeof entry === \"object\" &&\n entry !== null &&\n typeof (entry as { id?: unknown }).id === \"string\" &&\n typeof (entry as { kind?: unknown }).kind === \"string\",\n )\n : [];\n}\n\nfunction collectExactPhraseFields(document: ItemDocument): string[] {\n const item = document.metadata;\n return [\n item.title,\n item.description,\n item.status,\n stringArray(item.tags).join(\" \"),\n document.body,\n textEntries(item.comments)\n .map((entry) => entry.text)\n .join(\" \"),\n textEntries(item.notes)\n .map((entry) => entry.text)\n .join(\" \"),\n textEntries(item.learnings)\n .map((entry) => entry.text)\n .join(\" \"),\n buildReminderCorpus(item).join(\" \"),\n buildEventCorpus(item).join(\" \"),\n dependencyEntries(item.dependencies)\n .map((entry) => `${entry.id} ${entry.kind}`)\n .join(\" \"),\n buildPlanFlatCorpus(item),\n ];\n}\n\nfunction documentContainsExactPhrase(\n document: ItemDocument,\n normalizedQuery: string,\n): boolean {\n return collectExactPhraseFields(document).some((fieldValue) =>\n normalizeSearchPhrase(fieldValue).includes(normalizedQuery),\n );\n}\n\nfunction applyExactQueryFilters(\n items: ItemDocument[],\n normalizedQuery: string,\n options: { titleExact: boolean; phraseExact: boolean },\n): ItemDocument[] {\n if (!options.titleExact && !options.phraseExact) {\n return items;\n }\n return items.filter((document) => {\n if (\n options.titleExact &&\n normalizeSearchPhrase(document.metadata.title) !== normalizedQuery\n ) {\n return false;\n }\n if (\n options.phraseExact &&\n !documentContainsExactPhrase(document, normalizedQuery)\n ) {\n return false;\n }\n return true;\n });\n}\n\ntype SearchMissingMetadataFilters = ReturnType<\n typeof resolveMissingMetadataFilters\n>;\ntype SearchContentFieldFilters = ReturnType<typeof resolveContentFieldFilters>;\n\ninterface SearchMetadataFilterSet {\n typeFilter: ItemType | undefined;\n tagFilter: string | undefined;\n priorityFilter: number | undefined;\n deadlineBefore: string | undefined;\n deadlineAfter: string | undefined;\n updatedAfter: string | undefined;\n updatedBefore: string | undefined;\n createdAfter: string | undefined;\n createdBefore: string | undefined;\n assigneeFilter: string | undefined;\n sprintFilter: string | undefined;\n releaseFilter: string | undefined;\n parentFilter: string | undefined;\n statusSet: Set<ItemStatus> | undefined;\n missingMetadataFilters: SearchMissingMetadataFilters;\n missingMetadataActive: boolean;\n contentFieldFilters: SearchContentFieldFilters;\n contentFiltersActive: boolean;\n}\n\nfunction assertSearchAssigneeFilter(assigneeFilter: string | undefined): void {\n // Match pm list: --assignee no longer accepts none/null (unassigned filtering\n // belongs to a dedicated flag there; pm search has no presence flag so reject\n // the sentinel values explicitly rather than silently matching a literal).\n if (\n assigneeFilter &&\n (assigneeFilter.toLowerCase() === \"none\" ||\n assigneeFilter.toLowerCase() === \"null\")\n ) {\n throw new PmCliError(\n '--assignee no longer accepts \"none\" or \"null\".',\n EXIT_CODE.USAGE,\n );\n }\n}\n\nfunction resolveSearchMetadataFilterSet(\n options: SearchOptions,\n typeRegistry: ItemTypeRegistry,\n statusFilter: ItemStatus[] | undefined,\n): SearchMetadataFilterSet {\n const assigneeFilter = options.assignee?.trim();\n assertSearchAssigneeFilter(assigneeFilter);\n const missingMetadataFilters = resolveMissingMetadataFilters(options);\n const contentFieldFilters = resolveContentFieldFilters(\n options as Record<string, unknown>,\n );\n return {\n typeFilter: parseType(options.type, typeRegistry),\n tagFilter: options.tag?.trim().toLowerCase(),\n priorityFilter: parsePriority(options.priority),\n deadlineBefore: parseDeadline(options.deadlineBefore, \"deadline-before\"),\n deadlineAfter: parseDeadline(options.deadlineAfter, \"deadline-after\"),\n updatedAfter: parseTimestampWindow(options.updatedAfter, \"updated-after\"),\n updatedBefore: parseTimestampWindow(\n options.updatedBefore,\n \"updated-before\",\n ),\n createdAfter: parseTimestampWindow(options.createdAfter, \"created-after\"),\n createdBefore: parseTimestampWindow(\n options.createdBefore,\n \"created-before\",\n ),\n assigneeFilter,\n sprintFilter: options.sprint?.trim(),\n releaseFilter: options.release?.trim(),\n parentFilter: options.parent?.trim(),\n statusSet:\n statusFilter && statusFilter.length > 0\n ? new Set<ItemStatus>(statusFilter)\n : undefined,\n missingMetadataFilters,\n missingMetadataActive: hasMissingMetadataFilter(missingMetadataFilters),\n contentFieldFilters,\n contentFiltersActive: hasContentFieldFilter(contentFieldFilters),\n };\n}\n\nfunction matchesScalarSearchFilters(\n item: ItemMetadata,\n filters: SearchMetadataFilterSet,\n): boolean {\n return (\n matchesIdentitySearchFilters(item, filters) &&\n matchesTimestampSearchFilters(item, filters) &&\n matchesOwnerSearchFilters(item, filters)\n );\n}\n\nfunction matchesIdentitySearchFilters(\n item: ItemMetadata,\n filters: SearchMetadataFilterSet,\n): boolean {\n if (filters.statusSet && !filters.statusSet.has(item.status)) return false;\n if (filters.typeFilter && item.type !== filters.typeFilter) return false;\n if (filters.tagFilter && !stringArray(item.tags).includes(filters.tagFilter))\n return false;\n if (\n filters.priorityFilter !== undefined &&\n item.priority !== filters.priorityFilter\n )\n return false;\n return true;\n}\n\nfunction matchesTimestampSearchFilters(\n item: ItemMetadata,\n filters: SearchMetadataFilterSet,\n): boolean {\n return matchesTimestampFilters(item, filters);\n}\n\nfunction matchesOwnerSearchFilters(\n item: ItemMetadata,\n filters: SearchMetadataFilterSet,\n): boolean {\n if (\n filters.assigneeFilter !== undefined &&\n item.assignee !== filters.assigneeFilter\n )\n return false;\n if (\n filters.sprintFilter !== undefined &&\n item.sprint !== filters.sprintFilter\n )\n return false;\n /* c8 ignore start -- release/parent metadata filter combinations are covered by integration search fixtures */\n if (\n filters.releaseFilter !== undefined &&\n item.release !== filters.releaseFilter\n )\n return false;\n if (\n filters.parentFilter !== undefined &&\n item.parent !== filters.parentFilter\n )\n return false;\n /* c8 ignore stop */\n return true;\n}\n\nfunction matchesSearchMetadataFilters(\n document: ItemDocument,\n filters: SearchMetadataFilterSet,\n runtimeFieldFilters: Record<string, unknown>,\n lifecycleClassifier: LifecycleClassifier,\n): boolean {\n const item = document.metadata;\n if (!matchesScalarSearchFilters(item, filters)) {\n return false;\n }\n if (\n !matchesRuntimeFilters(item as Record<string, unknown>, runtimeFieldFilters)\n ) {\n return false;\n }\n if (\n filters.missingMetadataActive &&\n !itemMatchesMissingMetadata(\n item,\n filters.missingMetadataFilters,\n lifecycleClassifier,\n )\n ) {\n return false;\n }\n if (\n filters.contentFiltersActive &&\n !itemMatchesContentFilters(item, filters.contentFieldFilters)\n ) {\n return false;\n }\n return true;\n}\n\nfunction applyFilters(\n items: ItemDocument[],\n options: SearchOptions,\n typeRegistry: ItemTypeRegistry,\n runtimeFieldFilters: Record<string, unknown>,\n statusFilter: ItemStatus[] | undefined,\n lifecycleClassifier: LifecycleClassifier,\n): ItemDocument[] {\n const filters = resolveSearchMetadataFilterSet(\n options,\n typeRegistry,\n statusFilter,\n );\n return items.filter((document) =>\n matchesSearchMetadataFilters(\n document,\n filters,\n runtimeFieldFilters,\n lifecycleClassifier,\n ),\n );\n}\n\nfunction countOccurrences(haystack: string, needle: string): number {\n let count = 0;\n let index = 0;\n while (true) {\n const foundAt = haystack.indexOf(needle, index);\n if (foundAt < 0) {\n return count;\n }\n count += 1;\n index = foundAt + needle.length;\n }\n}\n\nfunction tokenizeForExactTokenMatch(value: string): string[] {\n return tokenizeAlphaNumeric(value);\n}\n\nfunction collectLinkedPaths(\n item: ItemMetadata,\n): Array<{ scope: \"project\" | \"global\"; path: string }> {\n const fromFiles = (item.files ?? []).map((entry) => ({\n scope: entry.scope,\n path: entry.path.trim(),\n }));\n const fromDocs = (item.docs ?? []).map((entry) => ({\n scope: entry.scope,\n path: entry.path.trim(),\n }));\n const fromTests = (item.tests ?? [])\n .filter(\n (entry): entry is typeof entry & { path: string } =>\n typeof entry.path === \"string\" && entry.path.trim().length > 0,\n )\n .map((entry) => ({\n scope: entry.scope,\n path: entry.path.trim(),\n }));\n const sorted = [...fromFiles, ...fromDocs, ...fromTests]\n .filter((entry) => entry.path.length > 0)\n .sort(\n (a, b) => a.scope.localeCompare(b.scope) || a.path.localeCompare(b.path),\n );\n const deduped = new Map<\n string,\n { scope: \"project\" | \"global\"; path: string }\n >();\n for (const entry of sorted) {\n deduped.set(`${entry.scope}:${entry.path}`, entry);\n }\n return [...deduped.values()];\n}\n\ninterface ContainmentRoot {\n resolved: string;\n realpath: string;\n}\n\ninterface LinkedCorpusRoots {\n projectContainmentRoot: ContainmentRoot | null;\n globalContainmentRoot: ContainmentRoot | null;\n}\n\nasync function resolveContainmentRoot(\n root: string,\n): Promise<ContainmentRoot | null> {\n const resolved = path.resolve(root);\n try {\n const realpathRoot = await fs.realpath(resolved);\n return {\n resolved,\n realpath: realpathRoot,\n };\n } catch {\n return null;\n }\n}\n\nasync function resolveLinkedCorpusRoots(\n projectRoot: string,\n globalRoot: string,\n): Promise<LinkedCorpusRoots> {\n const [projectContainmentRoot, globalContainmentRoot] = await Promise.all([\n resolveContainmentRoot(projectRoot),\n resolveContainmentRoot(globalRoot),\n ]);\n return {\n projectContainmentRoot,\n globalContainmentRoot,\n };\n}\n\nasync function loadLinkedCorpus(\n document: ItemDocument,\n roots: LinkedCorpusRoots,\n): Promise<string> {\n const linkedPaths = collectLinkedPaths(document.metadata);\n const chunks: string[] = [];\n for (const linkedPath of linkedPaths) {\n const containmentRoot =\n linkedPath.scope === \"global\"\n ? roots.globalContainmentRoot\n : roots.projectContainmentRoot;\n if (!containmentRoot) {\n continue;\n }\n const resolved = path.resolve(containmentRoot.resolved, linkedPath.path);\n if (!isPathWithinDirectory(containmentRoot.resolved, resolved)) {\n continue;\n }\n let linkedRealpath: string;\n try {\n linkedRealpath = await fs.realpath(resolved);\n } catch {\n continue;\n }\n if (!isPathWithinDirectory(containmentRoot.realpath, linkedRealpath)) {\n continue;\n }\n try {\n await runActiveOnReadHooks({\n path: resolved,\n scope: linkedPath.scope,\n });\n chunks.push(await fs.readFile(resolved, \"utf8\"));\n } catch {\n // Best-effort linked-content indexing: unreadable paths are ignored.\n }\n }\n return chunks.join(\"\\n\");\n}\n\n/** Documents the search tuning payload exchanged by command, SDK, and package integrations. */\nexport interface SearchTuning {\n /** Value that configures or reports title exact bonus for this contract. */\n title_exact_bonus: number;\n /** Value that configures or reports title weight for this contract. */\n title_weight: number;\n /** Value that configures or reports description weight for this contract. */\n description_weight: number;\n /** Value that configures or reports tags weight for this contract. */\n tags_weight: number;\n /** Value that configures or reports status weight for this contract. */\n status_weight: number;\n /** Value that configures or reports body weight for this contract. */\n body_weight: number;\n /** Value that configures or reports comments weight for this contract. */\n comments_weight: number;\n /** Value that configures or reports notes weight for this contract. */\n notes_weight: number;\n /** Value that configures or reports learnings weight for this contract. */\n learnings_weight: number;\n /** Value that configures or reports reminders weight for this contract. */\n reminders_weight: number;\n /** Value that configures or reports events weight for this contract. */\n events_weight: number;\n /** Value that configures or reports dependencies weight for this contract. */\n dependencies_weight: number;\n /** Value that configures or reports linked content weight for this contract. */\n linked_content_weight: number;\n}\n\n/**\n * Canonical definition of the document-derived searchable fields shared by the\n * lexical scorer ({@link scoreDocument}) and the matched-text highlighter\n * ({@link buildHitHighlights}). Keeping a single source of field name → text\n * extractor → tuning weight guarantees the highlighter can only ever produce\n * snippets for fields the scorer actually inspected. The `linked_content` field\n * is appended separately by the scorer because its text is supplied per-query\n * rather than derived from the document.\n */\nconst SEARCHABLE_FIELD_BUILDERS: ReadonlyArray<{\n name: string;\n weightKey: keyof SearchTuning;\n value: (document: ItemDocument) => string;\n}> = [\n {\n name: \"title\",\n weightKey: \"title_weight\",\n value: (document) => document.metadata.title,\n },\n {\n name: \"description\",\n weightKey: \"description_weight\",\n value: (document) => document.metadata.description,\n },\n {\n name: \"tags\",\n weightKey: \"tags_weight\",\n value: (document) => stringArray(document.metadata.tags).join(\" \"),\n },\n {\n name: \"status\",\n weightKey: \"status_weight\",\n value: (document) =>\n typeof document.metadata.status === \"string\"\n ? document.metadata.status\n : \"\",\n },\n {\n name: \"body\",\n weightKey: \"body_weight\",\n value: (document) => document.body,\n },\n {\n name: \"comments\",\n weightKey: \"comments_weight\",\n value: (document) =>\n textEntries(document.metadata.comments)\n .map((entry) => entry.text)\n .join(\" \"),\n },\n {\n name: \"notes\",\n weightKey: \"notes_weight\",\n value: (document) =>\n textEntries(document.metadata.notes)\n .map((entry) => entry.text)\n .join(\" \"),\n },\n {\n name: \"learnings\",\n weightKey: \"learnings_weight\",\n value: (document) =>\n textEntries(document.metadata.learnings)\n .map((entry) => entry.text)\n .join(\" \"),\n },\n {\n name: \"reminders\",\n weightKey: \"reminders_weight\",\n value: (document) => buildReminderCorpus(document.metadata).join(\" \"),\n },\n {\n name: \"events\",\n weightKey: \"events_weight\",\n value: (document) => buildEventCorpus(document.metadata).join(\" \"),\n },\n {\n name: \"dependencies\",\n weightKey: \"dependencies_weight\",\n value: (document) =>\n dependencyEntries(document.metadata.dependencies)\n .map((entry) => `${entry.id} ${entry.kind}`)\n .join(\" \"),\n },\n {\n name: \"plan\",\n weightKey: \"body_weight\",\n value: (document) => buildPlanFlatCorpus(document.metadata),\n },\n];\n\n// Name → builder index so the highlighter can resolve a matched field to its\n// text extractor in O(1) and evaluate ONLY the matched fields' values, instead\n// of materializing all twelve (several of which join/build corpora) per hit.\nconst SEARCHABLE_FIELD_BUILDER_BY_NAME = new Map(\n SEARCHABLE_FIELD_BUILDERS.map((builder) => [builder.name, builder]),\n);\n\nfunction escapeRegExpLiteral(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Wrap every case-insensitive occurrence of any query token in `text` with the\n * {@link HIGHLIGHT_OPEN}/{@link HIGHLIGHT_CLOSE} markers. Token boundaries follow\n * the same substring semantics as the lexical scorer (a token highlights inside\n * longer words, matching how it scored), and overlapping matches are coalesced\n * by the single combined alternation so markers never nest.\n */\nfunction markTokenRuns(text: string, tokens: string[]): string {\n // Sort by length descending before building the alternation so a longer token\n // wins over a shorter token that is its prefix (regex alternation is greedy\n // left-to-right, so `auth|authority` would mark «auth»ority instead of\n // «authority»). `.filter` already returns a fresh array, so the in-place sort\n // never mutates the caller's token list.\n const escaped = tokens\n .filter((token) => token.length > 0)\n .sort((left, right) => right.length - left.length)\n .map(escapeRegExpLiteral);\n if (escaped.length === 0) {\n return text;\n }\n const pattern = new RegExp(escaped.join(\"|\"), \"gi\");\n return text.replace(\n pattern,\n (match) => `${HIGHLIGHT_OPEN}${match}${HIGHLIGHT_CLOSE}`,\n );\n}\n\n/**\n * Build a single highlighted snippet for one field value (GH-157), or null when\n * no token matches. The snippet is a window of {@link HIGHLIGHT_SNIPPET_RADIUS}\n * characters on each side of the first match with the matching token runs\n * wrapped in markers, prefixed/suffixed with an ellipsis when the field text was\n * trimmed. Returning null lets the caller skip fields with no concrete textual\n * match (e.g. a field flagged purely by the phrase-coverage bonus).\n */\nfunction highlightFieldSnippet(text: string, tokens: string[]): string | null {\n if (text.length === 0) {\n return null;\n }\n const lowerText = text.toLowerCase();\n let firstMatchIndex = -1;\n let firstMatchLength = 0;\n for (const token of tokens) {\n if (token.length === 0) {\n continue;\n }\n const index = lowerText.indexOf(token);\n if (index >= 0 && (firstMatchIndex < 0 || index < firstMatchIndex)) {\n firstMatchIndex = index;\n firstMatchLength = token.length;\n }\n }\n if (firstMatchIndex < 0) {\n return null;\n }\n const windowStart = Math.max(0, firstMatchIndex - HIGHLIGHT_SNIPPET_RADIUS);\n const windowEnd = Math.min(\n text.length,\n firstMatchIndex + firstMatchLength + HIGHLIGHT_SNIPPET_RADIUS,\n );\n const marked = markTokenRuns(text.slice(windowStart, windowEnd), tokens);\n const prefix = windowStart > 0 ? \"…\" : \"\";\n const suffix = windowEnd < text.length ? \"…\" : \"\";\n return `${prefix}${marked}${suffix}`;\n}\n\n/** Produce per-field matched-text snippets for a hit (GH-157, `--highlight`). Iterates the hit's already-sorted `matched_fields`, retains only the document-derived searchable fields (skipping synthetic markers like `id`, `semantic`, `rerank`, and `linked_content`), and emits a snippet for each field that still contains a concrete token match. */\nfunction buildHitHighlights(\n document: ItemDocument,\n matchedFields: string[],\n tokens: string[],\n): SearchHitHighlight[] {\n const highlights: SearchHitHighlight[] = [];\n for (const field of matchedFields) {\n const builder = SEARCHABLE_FIELD_BUILDER_BY_NAME.get(field);\n if (builder === undefined) {\n continue;\n }\n const snippet = highlightFieldSnippet(builder.value(document), tokens);\n if (snippet !== null) {\n highlights.push({ field, snippet });\n }\n }\n return highlights;\n}\n\ninterface SearchableScoringField {\n name: string;\n value: string;\n weight: number;\n}\n\ninterface SearchScoreState {\n score: number;\n matched: Set<string>;\n matchedTokens: Set<string>;\n}\n\nfunction buildSearchableScoringFields(\n document: ItemDocument,\n linkedCorpus: string,\n tuning: SearchTuning,\n): SearchableScoringField[] {\n return [\n ...SEARCHABLE_FIELD_BUILDERS.map((builder) => ({\n name: builder.name,\n value: builder.value(document),\n weight: tuning[builder.weightKey],\n })),\n {\n name: \"linked_content\",\n value: linkedCorpus,\n weight: tuning.linked_content_weight,\n },\n ];\n}\n\nfunction buildExactIdSearchHit(\n item: ItemMetadata,\n normalizedQuery: string,\n idPrefix: string,\n): SearchHit | null {\n const normalizedId = normalizeSearchPhrase(item.id);\n const normalizedIdPrefix =\n typeof idPrefix === \"string\" ? idPrefix.trim().toLowerCase() : \"\";\n const normalizedIdPrefixPhrase = normalizeSearchPhrase(normalizedIdPrefix);\n const normalizedShortId =\n normalizedIdPrefixPhrase.length > 0 &&\n normalizedId.startsWith(normalizedIdPrefixPhrase)\n ? normalizedId.slice(normalizedIdPrefixPhrase.length).trim()\n : normalizedId;\n if (\n normalizedQuery !== normalizedId &&\n normalizedQuery !== normalizedShortId\n ) {\n return null;\n }\n return {\n item,\n score:\n normalizedQuery === normalizedId\n ? EXACT_ID_MATCH_SCORE\n : SHORT_ID_MATCH_SCORE,\n matched_fields: [\"id\"],\n matched_all_terms: true,\n exact_id_match: true,\n };\n}\n\nfunction scoreTokenMatches(\n tokens: string[],\n titleTokenCounts: Map<string, number>,\n searchableFields: SearchableScoringField[],\n tuning: SearchTuning,\n state: SearchScoreState,\n): void {\n for (const token of tokens) {\n const exactTitleMatches = titleTokenCounts.get(token) ?? 0;\n if (exactTitleMatches > 0) {\n state.score += exactTitleMatches * tuning.title_exact_bonus;\n state.matched.add(\"title\");\n state.matchedTokens.add(token);\n }\n for (const field of searchableFields) {\n const occurrences = countOccurrences(field.value.toLowerCase(), token);\n if (occurrences > 0) {\n state.score += occurrences * field.weight;\n state.matched.add(field.name);\n state.matchedTokens.add(token);\n }\n }\n }\n}\n\nfunction scorePhraseMatches(\n item: ItemMetadata,\n normalizedQuery: string,\n searchableFields: SearchableScoringField[],\n state: SearchScoreState,\n): void {\n const normalizedTitle = normalizeSearchPhrase(item.title);\n if (normalizedTitle === normalizedQuery) {\n state.score += LONG_QUERY_TITLE_EXACT_BONUS;\n state.matched.add(\"title\");\n }\n for (const field of searchableFields) {\n const phraseOccurrences = countOccurrences(\n normalizeSearchPhrase(field.value),\n normalizedQuery,\n );\n if (phraseOccurrences > 0) {\n state.score +=\n phraseOccurrences * field.weight * LONG_QUERY_PHRASE_MULTIPLIER;\n state.matched.add(field.name);\n }\n }\n}\n\nfunction scoreDocument(\n document: ItemDocument,\n tokens: string[],\n normalizedQuery: string,\n linkedCorpus: string,\n tuning: SearchTuning,\n idPrefix: string,\n applyCoverageBonus = false,\n): SearchHit | null {\n const item = document.metadata;\n const exactIdHit = buildExactIdSearchHit(item, normalizedQuery, idPrefix);\n if (exactIdHit) {\n return exactIdHit;\n }\n const titleTokenCounts = new Map<string, number>();\n for (const token of tokenizeForExactTokenMatch(item.title)) {\n titleTokenCounts.set(token, (titleTokenCounts.get(token) ?? 0) + 1);\n }\n const searchableFields = buildSearchableScoringFields(\n document,\n linkedCorpus,\n tuning,\n );\n const state: SearchScoreState = {\n score: 0,\n matched: new Set(),\n matchedTokens: new Set(),\n };\n scoreTokenMatches(tokens, titleTokenCounts, searchableFields, tuning, state);\n const distinctTokens = new Set(tokens);\n // matchedTokens only ever holds entries drawn from `tokens`, so it is always a\n // subset of distinctTokens — exact size equality means every distinct term matched.\n const matchedAllTerms =\n distinctTokens.size > 0 && state.matchedTokens.size === distinctTokens.size;\n // GH-181 default-mode all-terms ranking bonus: only meaningful for multi-token\n // queries where every distinct token matched somewhere.\n if (applyCoverageBonus && distinctTokens.size > 1 && matchedAllTerms) {\n state.score += ALL_TERMS_COVERAGE_BONUS;\n }\n\n const isLongPhraseQuery =\n tokens.length >= LONG_QUERY_TOKEN_THRESHOLD &&\n normalizedQuery.includes(\" \");\n if (isLongPhraseQuery) {\n scorePhraseMatches(item, normalizedQuery, searchableFields, state);\n }\n\n if (state.score <= 0) {\n return null;\n }\n\n return {\n item,\n score: state.score,\n matched_fields: [...state.matched].sort((a, b) => a.localeCompare(b)),\n matched_all_terms: matchedAllTerms,\n };\n}\n\nfunction sortHits(\n items: SearchHit[],\n statusRegistry: RuntimeStatusRegistry,\n): SearchHit[] {\n return [...items].sort((a, b) => {\n const byScore = b.score - a.score;\n if (byScore !== 0) return byScore;\n const aTerminal = isTerminalStatus(a.item.status, statusRegistry);\n const bTerminal = isTerminalStatus(b.item.status, statusRegistry);\n if (aTerminal !== bTerminal) {\n return aTerminal ? 1 : -1;\n }\n const byPriority = a.item.priority - b.item.priority;\n if (byPriority !== 0) return byPriority;\n const byUpdated = compareTimestampStrings(\n b.item.updated_at,\n a.item.updated_at,\n );\n if (byUpdated !== 0) return byUpdated;\n return a.item.id.localeCompare(b.item.id);\n });\n}\n\nfunction buildHybridLexicalScore(\n document: ItemDocument,\n tokens: string[],\n normalizedQuery: string,\n includeLinked: boolean,\n linkedCorpusById: Map<string, string>,\n tuning: SearchTuning,\n idPrefix: string,\n applyCoverageBonus = false,\n): SearchHit | null {\n /* c8 ignore start -- linked corpus presence branch is covered by keyword/hybrid integration query tests */\n return scoreDocument(\n document,\n tokens,\n normalizedQuery,\n includeLinked ? (linkedCorpusById.get(document.metadata.id) ?? \"\") : \"\",\n tuning,\n idPrefix,\n applyCoverageBonus,\n );\n /* c8 ignore stop */\n}\n\nfunction normalizeScoreMap(\n scoreById: Map<string, number>,\n): Map<string, number> {\n if (scoreById.size === 0) {\n return new Map();\n }\n const values = [...scoreById.values()];\n const minScore = Math.min(...values);\n const maxScore = Math.max(...values);\n if (maxScore === minScore) {\n return new Map([...scoreById.keys()].map((id) => [id, 1]));\n }\n const normalized = new Map<string, number>();\n for (const [id, score] of scoreById) {\n normalized.set(id, (score - minScore) / (maxScore - minScore));\n }\n return normalized;\n}\n\n/** Implements resolve search max results for the public runtime surface of this module. */\nexport function resolveSearchMaxResults(settings: unknown): number {\n const candidate = (settings as { search?: { max_results?: unknown } }).search\n ?.max_results;\n if (\n typeof candidate === \"number\" &&\n Number.isFinite(candidate) &&\n candidate > 0\n ) {\n return Math.floor(candidate);\n }\n return 50;\n}\n\n/** Implements resolve search score threshold for the public runtime surface of this module. */\nexport function resolveSearchScoreThreshold(settings: unknown): number {\n const candidate = (settings as { search?: { score_threshold?: unknown } })\n .search?.score_threshold;\n if (typeof candidate === \"number\" && Number.isFinite(candidate)) {\n return candidate;\n }\n return 0;\n}\n\n/** Implements resolve hybrid semantic weight for the public runtime surface of this module. */\nexport function resolveHybridSemanticWeight(settings: unknown): number {\n const candidate = (\n settings as { search?: { hybrid_semantic_weight?: unknown } }\n ).search?.hybrid_semantic_weight;\n if (\n typeof candidate === \"number\" &&\n Number.isFinite(candidate) &&\n candidate >= 0 &&\n candidate <= 1\n ) {\n return candidate;\n }\n return 0.7;\n}\n\n/** Implements resolve search tuning for the public runtime surface of this module. */\nexport function resolveSearchTuning(settings: unknown): SearchTuning {\n const defaults: SearchTuning = {\n title_exact_bonus: 10,\n title_weight: 8,\n description_weight: 5,\n tags_weight: 6,\n status_weight: 2,\n body_weight: 1,\n comments_weight: 1,\n notes_weight: 1,\n learnings_weight: 1,\n reminders_weight: 2,\n events_weight: 2,\n dependencies_weight: 3,\n linked_content_weight: 1,\n };\n const tuning = (settings as { search?: { tuning?: Partial<SearchTuning> } })\n .search?.tuning;\n if (!tuning) return defaults;\n\n const resolveWeight = (candidate: unknown, fallback: number) => {\n if (\n typeof candidate === \"number\" &&\n Number.isFinite(candidate) &&\n candidate >= 0\n ) {\n return candidate;\n }\n return fallback;\n };\n\n return {\n title_exact_bonus: resolveWeight(\n tuning.title_exact_bonus,\n defaults.title_exact_bonus,\n ),\n title_weight: resolveWeight(tuning.title_weight, defaults.title_weight),\n description_weight: resolveWeight(\n tuning.description_weight,\n defaults.description_weight,\n ),\n tags_weight: resolveWeight(tuning.tags_weight, defaults.tags_weight),\n status_weight: resolveWeight(tuning.status_weight, defaults.status_weight),\n body_weight: resolveWeight(tuning.body_weight, defaults.body_weight),\n comments_weight: resolveWeight(\n tuning.comments_weight,\n defaults.comments_weight,\n ),\n notes_weight: resolveWeight(tuning.notes_weight, defaults.notes_weight),\n learnings_weight: resolveWeight(\n tuning.learnings_weight,\n defaults.learnings_weight,\n ),\n reminders_weight: resolveWeight(\n tuning.reminders_weight,\n defaults.reminders_weight,\n ),\n events_weight: resolveWeight(tuning.events_weight, defaults.events_weight),\n dependencies_weight: resolveWeight(\n tuning.dependencies_weight,\n defaults.dependencies_weight,\n ),\n linked_content_weight: resolveWeight(\n tuning.linked_content_weight,\n defaults.linked_content_weight,\n ),\n };\n}\n\n/* c8 ignore start -- empty-result projection/count/warnings shape matrix is validated by integration response-contract tests */\nfunction emptySearchResult(\n query: string,\n mode: SearchMode,\n matchMode: SearchMatchMode,\n options: SearchOptions,\n includeLinked: boolean,\n scoreThreshold: number,\n hybridSemanticWeight: number,\n queryExpansion: QueryExpansionConfig,\n rerank: RerankConfig,\n projection: SearchProjectionConfig,\n warnings: string[],\n runtimeFieldFilters?: Record<string, unknown>,\n countOnly = false,\n): SearchResult {\n // --count consistency: a count-only query that matches nothing must still\n // carry the same { count_only: true, total } shape as the non-empty path.\n const countExtras = countOnly ? { total: 0, count_only: true } : {};\n const compactSummaryMode =\n projection.mode === \"compact\" && options.compact === true;\n if (compactSummaryMode) {\n const compactFilters = buildCompactSearchFilterSummary({\n mode,\n matchMode,\n options,\n includeLinked,\n titleExact: options.titleExact === true,\n phraseExact: options.phraseExact === true,\n scoreThreshold,\n hybridSemanticWeight,\n runtimeFieldFilters,\n });\n return {\n query: query.trim(),\n mode,\n items: [],\n count: 0,\n ...countExtras,\n filters: compactFilters,\n ...(warnings.length > 0 ? { warnings } : {}),\n };\n }\n const projectionFields =\n projection.mode === \"full\" ? null : [...projection.fields];\n return {\n query: query.trim(),\n mode,\n items: [],\n count: 0,\n ...countExtras,\n filters: buildVerboseSearchFilters({\n effectiveMode: mode,\n matchMode,\n options,\n includeLinked,\n titleExact: options.titleExact === true,\n phraseExact: options.phraseExact === true,\n scoreThreshold,\n hybridSemanticWeight,\n queryExpansion,\n rerank,\n runtimeFieldFilters: runtimeFieldFilters ?? {},\n }),\n projection: {\n mode: projection.mode,\n fields: projectionFields,\n },\n now: nowIso(),\n ...(warnings.length > 0 ? { warnings } : {}),\n };\n}\n/* c8 ignore stop */\n\nfunction requireSemanticDependencies(\n requestedMode: Exclude<SearchMode, \"keyword\">,\n providerResolution: EmbeddingProviderResolution,\n vectorResolution: VectorStoreResolution,\n hasExtensionVectorQuery: boolean,\n): {\n provider: EmbeddingProviderConfig;\n vectorStore: VectorStoreConfig | null;\n} {\n if (!providerResolution.active) {\n throw new PmCliError(\n `Search mode '${requestedMode}' requires a configured embedding provider in settings.providers.openai or settings.providers.ollama`,\n EXIT_CODE.USAGE,\n );\n }\n if (!vectorResolution.active && !hasExtensionVectorQuery) {\n throw new PmCliError(\n `Search mode '${requestedMode}' requires a configured vector store in settings.vector_store.qdrant/settings.vector_store.lancedb or an extension adapter selected by settings.vector_store.adapter`,\n EXIT_CODE.USAGE,\n );\n }\n return {\n provider: providerResolution.active,\n vectorStore: vectorResolution.active ?? null,\n };\n}\n\nconst toOptionalNonEmptyString = toNonEmptyStringOrUndefined;\n\ninterface ExtensionSearchProviderHooks {\n providerName: string;\n query?: ExtensionSearchProviderQuery;\n queryExpansion?: ExtensionSearchProviderQueryExpansion;\n rerank?: ExtensionSearchProviderRerank;\n}\n\n/* c8 ignore start -- extension search-provider registration permutations are covered by extension integration suites */\nfunction resolveExtensionSearchProviderByName(\n providerName: string | undefined,\n): ExtensionSearchProviderHooks | null {\n const registrations = getActiveExtensionRegistrations();\n const resolved = resolveRegisteredSearchProvider(registrations, providerName);\n if (!resolved) {\n return null;\n }\n const runtimeDefinition = resolved.runtime_definition ?? resolved.definition;\n const query = (runtimeDefinition as { query?: unknown }).query;\n const queryExpansion =\n (\n runtimeDefinition as {\n queryExpansion?: unknown;\n query_expansion?: unknown;\n }\n ).queryExpansion ??\n (\n runtimeDefinition as {\n queryExpansion?: unknown;\n query_expansion?: unknown;\n }\n ).query_expansion;\n const rerank = (runtimeDefinition as { rerank?: unknown }).rerank;\n const registeredName =\n toOptionalNonEmptyString((runtimeDefinition as { name?: unknown }).name) ??\n toOptionalNonEmptyString(\n (resolved.definition as { name?: unknown }).name,\n ) ??\n providerName;\n /* c8 ignore next 2 -- providerName is required for lookup and remains a non-empty fallback */\n if (!registeredName) {\n return null;\n }\n const hooks: ExtensionSearchProviderHooks = {\n providerName: registeredName,\n ...(typeof query === \"function\"\n ? { query: query as ExtensionSearchProviderQuery }\n : {}),\n ...(typeof queryExpansion === \"function\"\n ? {\n queryExpansion:\n queryExpansion as ExtensionSearchProviderQueryExpansion,\n }\n : {}),\n ...(typeof rerank === \"function\"\n ? { rerank: rerank as ExtensionSearchProviderRerank }\n : {}),\n };\n if (!hooks.query && !hooks.queryExpansion && !hooks.rerank) {\n return null;\n }\n return hooks;\n}\n/* c8 ignore stop */\n\nfunction resolveExtensionSearchProvider(\n settings: PmSettings,\n): { providerName: string; query: ExtensionSearchProviderQuery } | null {\n const providerName = toOptionalNonEmptyString(\n (settings.search as { provider?: unknown } | undefined)?.provider,\n );\n const resolved = resolveExtensionSearchProviderByName(providerName);\n if (!resolved?.query) {\n return null;\n }\n return {\n providerName: resolved.providerName,\n query: resolved.query,\n };\n}\n\n/* c8 ignore start -- vector adapter runtime definition permutations are covered by extension integration suites */\nfunction resolveExtensionVectorAdapter(\n settings: PmSettings,\n): ExtensionVectorAdapter | null {\n const registrations = getActiveExtensionRegistrations();\n const adapterName = toOptionalNonEmptyString(\n (settings.vector_store as { adapter?: unknown } | undefined)?.adapter,\n );\n const resolved = resolveRegisteredVectorStoreAdapter(\n registrations,\n adapterName,\n );\n if (!resolved) {\n return null;\n }\n const runtimeDefinition = resolved.runtime_definition ?? resolved.definition;\n const query = (runtimeDefinition as { query?: unknown }).query;\n if (typeof query !== \"function\") {\n return null;\n }\n const upsert = (runtimeDefinition as { upsert?: unknown }).upsert;\n const runtimeAdapterName =\n toOptionalNonEmptyString((runtimeDefinition as { name?: unknown }).name) ??\n toOptionalNonEmptyString(\n (resolved.definition as { name?: unknown }).name,\n ) ??\n adapterName ??\n \"extension\";\n return {\n adapterName: runtimeAdapterName,\n query: query as ExtensionVectorQuery,\n ...(typeof upsert === \"function\"\n ? { upsert: upsert as ExtensionVectorUpsert }\n : {}),\n };\n}\n/* c8 ignore stop */\n\nfunction normalizeExtensionProviderHits(\n providerName: string,\n raw: unknown,\n filteredById: Map<string, ItemDocument>,\n): SearchHit[] {\n const rawHits = Array.isArray(raw)\n ? raw\n : (raw as { hits?: unknown } | null | undefined)?.hits;\n if (!Array.isArray(rawHits)) {\n throw new PmCliError(\n `Extension search provider \"${providerName}\" must return an array of hits or { hits: [...] }`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n\n const seen = new Set<string>();\n const hits: SearchHit[] = [];\n for (const rawHit of rawHits) {\n if (typeof rawHit !== \"object\" || rawHit === null) {\n continue;\n }\n const id = toOptionalNonEmptyString((rawHit as { id?: unknown }).id);\n const score = (rawHit as { score?: unknown }).score;\n if (\n !id ||\n typeof score !== \"number\" ||\n !Number.isFinite(score) ||\n seen.has(id)\n ) {\n continue;\n }\n const document = filteredById.get(id);\n if (!document) {\n continue;\n }\n const matchedFieldsRaw = (rawHit as { matched_fields?: unknown })\n .matched_fields;\n const matchedFields =\n Array.isArray(matchedFieldsRaw) &&\n matchedFieldsRaw.every((entry) => typeof entry === \"string\")\n ? [\n ...new Set(\n (matchedFieldsRaw as string[])\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0),\n ),\n ].sort((a, b) => a.localeCompare(b))\n : [`provider:${providerName}`];\n seen.add(id);\n hits.push({\n item: document.metadata,\n score,\n matched_fields: matchedFields,\n });\n }\n return hits;\n}\n\nfunction buildSemanticHits(\n vectorHits: VectorQueryHit[],\n filteredById: Map<string, ItemDocument>,\n): { semanticHits: SearchHit[]; semanticScores: Map<string, number> } {\n const semanticHits: SearchHit[] = [];\n const semanticScores = new Map<string, number>();\n for (const vectorHit of vectorHits) {\n if (semanticScores.has(vectorHit.id)) {\n continue;\n }\n const document = filteredById.get(vectorHit.id);\n if (!document) {\n continue;\n }\n semanticScores.set(vectorHit.id, vectorHit.score);\n semanticHits.push({\n item: document.metadata,\n score: vectorHit.score,\n matched_fields: [\"semantic\"],\n });\n }\n return {\n semanticHits,\n semanticScores,\n };\n}\n\n// GH-281: in semantic & hybrid mode the blended/vector scores live on an\n// arbitrary scale (blended hybrid scores are [0,1]; raw vector similarities are\n// provider-defined), so an exact full-ID or short-ID keyword match can be\n// out-ranked by a high-semantic body mention. This reattaches the exact-ID\n// keyword hit(s) to the top of the ranked set in a reserved band ABOVE every\n// other hit, preserving matched_fields:[\"id\"] and keeping full-ID above\n// short-ID. The reserved scores are derived from the current max so the\n// guarantee holds no matter what scale the backend returns, and the hit is\n// re-inserted even if it was dropped from `rankedHits` (e.g. it had no semantic\n// vector match) so it is never lost to the threshold or the result-limit slice.\nfunction forceExactIdHitsToTop(\n rankedHits: SearchHit[],\n keywordHits: SearchHit[],\n): SearchHit[] {\n const exactIdHits = keywordHits.filter((hit) => hit.exact_id_match === true);\n if (exactIdHits.length === 0) {\n return rankedHits;\n }\n const exactIdIds = new Set(exactIdHits.map((hit) => hit.item.id));\n const remaining = rankedHits.filter((hit) => !exactIdIds.has(hit.item.id));\n // reduce (not Math.max(...spread)) so a very large pre-truncation candidate\n // set can never overflow the call stack.\n const maxRemainingScore = remaining.reduce(\n (max, hit) => Math.max(max, hit.score),\n 0,\n );\n // Full-ID hits (score 1000) must rank above short-ID hits (score 900): rank\n // within the exact-ID band by the original keyword score (descending) so a\n // full-ID match always precedes a short-ID match for the same query, then\n // offset the whole band above every remaining hit. ids are unique, so two\n // exact-ID hits can never tie on score — sorting on score alone is total.\n // exactIdHits is already a fresh array from keywordHits.filter(...), so sort\n // it in place — no defensive copy needed.\n const orderedExactHits = exactIdHits.sort(\n (left, right) => right.score - left.score,\n );\n const bandBase = maxRemainingScore + orderedExactHits.length + 1;\n const promoted = orderedExactHits.map((hit, index) => ({\n // Spread the original keyword hit so flags like matched_all_terms /\n // exact_id_match are preserved; only the band-slot score and the id-only\n // matched_fields are overridden.\n ...hit,\n // Higher band slot for earlier (higher original keyword score) hits.\n score: bandBase - index,\n matched_fields: [\"id\"],\n }));\n return [...promoted, ...remaining];\n}\n\nfunction combineHybridHits(\n filteredById: Map<string, ItemDocument>,\n semanticScores: Map<string, number>,\n keywordHits: SearchHit[],\n hybridSemanticWeight: number,\n // Matched-field label for the dense-ranking component. Defaults to \"semantic\"\n // (vector retrieval); the offline BM25 hybrid path passes \"bm25\" so hits carry\n // an honest provenance marker instead of implying a vector match (pm-75k9).\n semanticFieldLabel = \"semantic\",\n): SearchHit[] {\n const keywordScores = new Map(\n keywordHits.map((entry) => [entry.item.id, entry.score]),\n );\n const keywordMatches = new Map(\n keywordHits.map((entry) => [entry.item.id, entry.matched_fields]),\n );\n const normalizedSemantic = normalizeScoreMap(semanticScores);\n const normalizedKeyword = normalizeScoreMap(keywordScores);\n const candidateIds = new Set<string>([\n ...semanticScores.keys(),\n ...keywordScores.keys(),\n ]);\n const keywordWeight = 1 - hybridSemanticWeight;\n return [...candidateIds]\n .map((id) => {\n const document = filteredById.get(id)!;\n const semanticScore = normalizedSemantic.get(id) ?? 0;\n const keywordScore = normalizedKeyword.get(id) ?? 0;\n const combinedScore =\n semanticScore * hybridSemanticWeight + keywordScore * keywordWeight;\n if (combinedScore <= 0) {\n return null;\n }\n const matchedFields = new Set<string>();\n if (semanticScores.has(id)) {\n matchedFields.add(semanticFieldLabel);\n }\n for (const field of keywordMatches.get(id) ?? []) {\n matchedFields.add(field);\n }\n return {\n item: document.metadata,\n score: combinedScore,\n matched_fields: [...matchedFields].sort((a, b) => a.localeCompare(b)),\n };\n })\n .filter((entry): entry is SearchHit => entry !== null);\n}\n\n/** Built-in BM25 activation outcome for semantic/hybrid search (pm-75k9): - `\"explicit\"`: `search.provider` is `bm25` — the user opted into offline lexical ranking, so it is used even if an embedding provider is configured. - `\"auto-fallback\"`: `search.provider` is `auto` and neither an embedding provider nor an extension search provider is available — BM25 is used in place of degrading to the naive field-weighted keyword scorer. - `null`: BM25 does not apply; the existing embedding/extension path runs. */\ntype BuiltInBm25Mode = \"explicit\" | \"auto-fallback\";\n\nfunction resolveBuiltInBm25Mode(params: {\n configuredProvider: string | undefined;\n hasEmbeddingProvider: boolean;\n hasExtensionSearchProvider: boolean;\n}): BuiltInBm25Mode | null {\n const normalized = params.configuredProvider?.trim().toLowerCase();\n if (normalized === \"bm25\") {\n return \"explicit\";\n }\n if (\n normalized === \"auto\" &&\n !params.hasEmbeddingProvider &&\n !params.hasExtensionSearchProvider\n ) {\n return \"auto-fallback\";\n }\n return null;\n}\n\n/**\n * Rank the filtered corpus with the offline BM25 provider (pm-75k9). Builds a\n * BM25 index over each document's resolved search corpus (honoring\n * `search.corpus_fields`), scores the query, and shapes hits for the requested\n * mode: semantic mode returns pure BM25-ranked hits tagged\n * `matched_fields: [\"bm25\"]`, while hybrid mode blends the BM25 scores with the\n * locally computed keyword scores via {@link combineHybridHits}. The exact\n * full-ID / short-ID guarantee is preserved in both modes via\n * {@link forceExactIdHitsToTop}. No network, embedding service, or vector store\n * is involved, so this path cannot fail on a backend error.\n */\nfunction computeBuiltInBm25Hits(params: {\n requestedMode: Exclude<SearchMode, \"keyword\">;\n query: string;\n filteredDocuments: ItemDocument[];\n keywordHits: SearchHit[];\n corpusFields: string[];\n bm25Params: Bm25Params;\n hybridSemanticWeight: number;\n}): SearchHit[] {\n const bm25Documents = params.filteredDocuments.map((document) => ({\n id: document.metadata.id,\n text: flattenSearchCorpusText(\n buildSearchCorpus(document, { fields: params.corpusFields }),\n ),\n }));\n const index = buildBm25Index(bm25Documents);\n const bm25Scores = scoreBm25Query(\n index,\n tokenizeBm25(params.query),\n params.bm25Params,\n );\n const filteredById = new Map(\n params.filteredDocuments.map((document) => [\n document.metadata.id,\n document,\n ]),\n );\n if (params.requestedMode === \"semantic\") {\n const semanticHits: SearchHit[] = [...bm25Scores].map(([id, score]) => ({\n item: filteredById.get(id)!.metadata,\n score,\n matched_fields: [\"bm25\"],\n }));\n return forceExactIdHitsToTop(semanticHits, params.keywordHits);\n }\n const hybridHits = combineHybridHits(\n filteredById,\n bm25Scores,\n params.keywordHits,\n params.hybridSemanticWeight,\n \"bm25\",\n );\n return forceExactIdHitsToTop(hybridHits, params.keywordHits);\n}\n\ninterface SemanticQueryContext {\n requestedMode: Exclude<SearchMode, \"keyword\">;\n query: string;\n filteredDocuments: ItemDocument[];\n keywordHits: SearchHit[];\n hybridSemanticWeight: number;\n limit: number | undefined;\n maxResults: number;\n provider: EmbeddingProviderConfig;\n vectorStore: VectorStoreConfig | null;\n extensionVectorAdapter: ExtensionVectorAdapter | null;\n queryExpansion: QueryExpansionConfig;\n queryExpansionExtension: {\n providerName: string;\n expand: ExtensionSearchProviderQueryExpansion;\n } | null;\n rerank: RerankConfig;\n rerankExtension: {\n providerName: string;\n rerank: ExtensionSearchProviderRerank;\n } | null;\n warnings: string[];\n settings: PmSettings;\n embeddingTimeoutMs?: number;\n vectorQueryTimeoutMs?: number;\n}\n\ninterface SemanticQueryResult {\n hits: SearchHit[];\n // Number of documents returned by the vector stage for this query after the\n // current metadata filters. When this is 0 the semantic/hybrid query ran\n // successfully, but vector ranking contributed nothing to the returned hits.\n vectorMatchCount: number;\n}\n\nfunction mergeVectorHitsById(\n vectorHitGroups: VectorQueryHit[][],\n): VectorQueryHit[] {\n const bestById = new Map<string, VectorQueryHit>();\n for (const group of vectorHitGroups) {\n for (const hit of group) {\n const existing = bestById.get(hit.id);\n if (!existing || hit.score > existing.score) {\n bestById.set(hit.id, hit);\n }\n }\n }\n const merged = [...bestById.values()];\n merged.sort((left, right) => {\n if (left.score !== right.score) {\n return right.score - left.score;\n }\n return left.id.localeCompare(right.id);\n });\n return merged;\n}\n\n/* c8 ignore start -- rerank corpus metadata-shape permutations are covered by semantic integration tests */\nfunction buildRerankCorpus(document: ItemDocument): string {\n const metadata = (document as { metadata?: ItemDocument[\"metadata\"] | null })\n .metadata;\n const tags = Array.isArray(metadata?.tags) ? metadata.tags.join(\" \") : \"\";\n return [\n metadata?.title,\n metadata?.description,\n metadata?.type,\n metadata?.status,\n tags,\n document.body,\n ]\n .map((entry) => (typeof entry === \"string\" ? entry.trim() : \"\"))\n .filter((entry) => entry.length > 0)\n .join(\"\\n\");\n}\n/* c8 ignore stop */\n\n/* c8 ignore start -- semantic expansion/rerank fallback matrices are covered by end-to-end semantic search tests */\nasync function resolveExpandedSemanticQueries(\n context: SemanticQueryContext,\n queryTrimmed: string,\n): Promise<string[]> {\n const baseExpandedQueries = context.queryExpansion.enabled\n ? buildDeterministicQueryExpansions(\n queryTrimmed,\n context.queryExpansion.max_queries,\n )\n : [queryTrimmed];\n const expandedQueries =\n baseExpandedQueries.length > 0 ? baseExpandedQueries : [queryTrimmed];\n if (!context.queryExpansion.enabled) {\n return expandedQueries;\n }\n if (context.queryExpansionExtension?.expand) {\n try {\n const rawExpansion = await Promise.resolve(\n context.queryExpansionExtension.expand({\n query: queryTrimmed,\n mode: context.requestedMode,\n settings: context.settings,\n }),\n );\n return mergeQueryExpansions(\n expandedQueries,\n normalizeQueryExpansionOutput(rawExpansion),\n context.queryExpansion.max_queries,\n );\n } catch {\n context.warnings.push(\n `search_query_expansion_provider_failed:${context.queryExpansionExtension.providerName}:using_builtin`,\n );\n return expandedQueries;\n }\n }\n if (\n context.queryExpansion.provider &&\n context.queryExpansion.provider !== \"openai\" &&\n context.queryExpansion.provider !== \"ollama\"\n ) {\n context.warnings.push(\n `search_query_expansion_provider_unavailable:${context.queryExpansion.provider}:using_builtin`,\n );\n }\n return expandedQueries;\n}\n\nasync function executeSemanticVectorQuery(\n context: SemanticQueryContext,\n semanticVector: number[],\n semanticLimit: number,\n vectorQueryOptions: { timeout_ms?: number },\n): Promise<VectorQueryHit[]> {\n if (context.extensionVectorAdapter?.query) {\n try {\n return await Promise.resolve(\n context.extensionVectorAdapter.query({\n vector: semanticVector,\n limit: semanticLimit,\n settings: context.settings,\n }),\n );\n } catch (error: unknown) {\n if (!context.vectorStore) {\n throw new PmCliError(\n `Extension vector adapter query failed and no built-in fallback store is configured (${error instanceof Error ? error.message : String(error)})`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n context.warnings.push(\n `search_vector_adapter_failed:${context.extensionVectorAdapter.adapterName}:using_builtin`,\n );\n return await executeVectorQuery(\n context.vectorStore,\n semanticVector,\n semanticLimit,\n vectorQueryOptions,\n );\n }\n }\n if (context.vectorStore) {\n return await executeVectorQuery(\n context.vectorStore,\n semanticVector,\n semanticLimit,\n vectorQueryOptions,\n );\n }\n throw new PmCliError(\n \"Semantic search requires either a configured vector store or an extension vector adapter query handler\",\n EXIT_CODE.USAGE,\n );\n}\n\nfunction buildRerankCandidateContexts(\n hybridHits: SearchHit[],\n filteredById: Map<string, ItemDocument>,\n topK: number,\n): Array<{ hit: SearchHit; text: string }> {\n const sortedForCandidates = [...hybridHits].sort((left, right) => {\n if (left.score !== right.score) {\n return right.score - left.score;\n }\n return left.item.id.localeCompare(right.item.id);\n });\n return sortedForCandidates\n .slice(0, topK)\n .map((hit) => {\n const document = filteredById.get(hit.item.id);\n return document ? { hit, text: buildRerankCorpus(document) } : null;\n })\n .filter(\n (entry): entry is { hit: SearchHit; text: string } => entry !== null,\n );\n}\n\nasync function resolveExtensionRerankScores(\n context: SemanticQueryContext,\n queryTrimmed: string,\n candidateContexts: Array<{ hit: SearchHit; text: string }>,\n): Promise<Map<string, number> | null> {\n if (!context.rerankExtension?.rerank) {\n return null;\n }\n try {\n const rawRerank = await Promise.resolve(\n context.rerankExtension.rerank({\n query: queryTrimmed,\n mode: \"hybrid\",\n model: context.rerank.model,\n top_k: context.rerank.top_k,\n settings: context.settings,\n candidates: candidateContexts.map((entry) => ({\n id: entry.hit.item.id,\n text: entry.text,\n score: entry.hit.score,\n })),\n }),\n );\n const normalizedRerank = normalizeRerankOutput(rawRerank);\n if (normalizedRerank.length > 0) {\n return new Map(normalizedRerank.map((entry) => [entry.id, entry.score]));\n }\n context.warnings.push(\n `search_rerank_provider_invalid_response:${context.rerankExtension.providerName}:using_builtin`,\n );\n return null;\n } catch {\n context.warnings.push(\n `search_rerank_provider_failed:${context.rerankExtension.providerName}:using_builtin`,\n );\n return null;\n }\n}\n\nasync function resolveRerankScores(\n context: SemanticQueryContext,\n queryTrimmed: string,\n candidateContexts: Array<{ hit: SearchHit; text: string }>,\n): Promise<Map<string, number> | null> {\n const extensionScores = await resolveExtensionRerankScores(\n context,\n queryTrimmed,\n candidateContexts,\n );\n if (extensionScores) {\n return extensionScores;\n }\n const rerankCandidates: RerankCandidate[] = candidateContexts.map(\n (entry) => ({\n id: entry.hit.item.id,\n text: entry.text,\n }),\n );\n try {\n return await rerankCandidatesWithEmbeddings(\n context.provider,\n context.rerank.model,\n queryTrimmed,\n rerankCandidates,\n context.embeddingTimeoutMs,\n );\n } catch {\n context.warnings.push(\"search_rerank_failed:using_hybrid_scores\");\n return null;\n }\n}\n\nfunction applyRerankScores(\n hybridHits: SearchHit[],\n rerankScores: Map<string, number>,\n): SearchHit[] {\n const rerankedIds = new Set(rerankScores.keys());\n const rerankedHits = hybridHits.map((hit) => {\n const rerankScore = rerankScores.get(hit.item.id);\n if (rerankScore === undefined) {\n return hit;\n }\n const matchedFields = new Set(hit.matched_fields);\n matchedFields.add(\"rerank\");\n return {\n ...hit,\n score: rerankScore,\n matched_fields: [...matchedFields].sort((left, right) =>\n left.localeCompare(right),\n ),\n };\n });\n rerankedHits.sort((left, right) => {\n const leftWasReranked = rerankedIds.has(left.item.id);\n const rightWasReranked = rerankedIds.has(right.item.id);\n if (leftWasReranked !== rightWasReranked) {\n return leftWasReranked ? -1 : 1;\n }\n if (left.score !== right.score) {\n return right.score - left.score;\n }\n return left.item.id.localeCompare(right.item.id);\n });\n return rerankedHits;\n}\n\nasync function applyHybridRerank(\n context: SemanticQueryContext,\n queryTrimmed: string,\n hybridHits: SearchHit[],\n filteredById: Map<string, ItemDocument>,\n): Promise<SearchHit[]> {\n if (!context.rerank.enabled || hybridHits.length <= 1) {\n return hybridHits;\n }\n const candidateContexts = buildRerankCandidateContexts(\n hybridHits,\n filteredById,\n context.rerank.top_k,\n );\n const rerankScores = await resolveRerankScores(\n context,\n queryTrimmed,\n candidateContexts,\n );\n return rerankScores && rerankScores.size > 0\n ? applyRerankScores(hybridHits, rerankScores)\n : hybridHits;\n}\n\nasync function computeSemanticOrHybridHits(\n context: SemanticQueryContext,\n): Promise<SemanticQueryResult> {\n const semanticLimit = Math.max(\n context.limit ?? context.maxResults,\n context.maxResults,\n );\n const embeddingOptions =\n context.embeddingTimeoutMs !== undefined\n ? { timeout_ms: context.embeddingTimeoutMs }\n : {};\n const vectorQueryOptions =\n context.vectorQueryTimeoutMs !== undefined\n ? { timeout_ms: context.vectorQueryTimeoutMs }\n : {};\n const queryTrimmed = context.query.trim();\n const expandedQueries = await resolveExpandedSemanticQueries(\n context,\n queryTrimmed,\n );\n const queryVectors = await executeEmbeddingRequest(\n context.provider,\n expandedQueries,\n embeddingOptions,\n );\n const queryVectorGroups = await Promise.all(\n queryVectors.map(\n async (semanticVector) =>\n await executeSemanticVectorQuery(\n context,\n semanticVector,\n semanticLimit,\n vectorQueryOptions,\n ),\n ),\n );\n const vectorHits = mergeVectorHitsById(queryVectorGroups);\n const filteredById = new Map(\n context.filteredDocuments.map((document) => [\n document.metadata.id,\n document,\n ]),\n );\n const { semanticHits, semanticScores } = buildSemanticHits(\n vectorHits,\n filteredById,\n );\n const vectorMatchCount = semanticScores.size;\n if (context.requestedMode === \"semantic\") {\n // GH-281: guarantee an exact full-ID / short-ID match ranks #1 even in pure\n // semantic mode, where it otherwise carries no vector hit at all.\n return {\n hits: forceExactIdHitsToTop(semanticHits, context.keywordHits),\n vectorMatchCount,\n };\n }\n const hybridHits = await applyHybridRerank(\n context,\n queryTrimmed,\n combineHybridHits(\n filteredById,\n semanticScores,\n context.keywordHits,\n context.hybridSemanticWeight,\n ),\n filteredById,\n );\n return {\n // GH-281: applied LAST (after any rerank reordering) so an exact full-ID /\n // short-ID keyword match always ranks #1 in hybrid mode regardless of the\n // semantic blend weight or rerank scores.\n hits: forceExactIdHitsToTop(hybridHits, context.keywordHits),\n vectorMatchCount,\n };\n}\n/* c8 ignore stop */\n\n/* c8 ignore start -- item body fallback read-path combinations are covered by document-cache integration tests */\nasync function loadDocuments(\n pmRoot: string,\n itemFormat: ItemFormat,\n typeToFolder: Record<string, string>,\n schema: PmSettings[\"schema\"],\n): Promise<{ documents: ItemDocument[]; warnings: string[] }> {\n const extensionFieldNames = collectRegisteredItemFieldNames(\n getActiveExtensionRegistrations(),\n );\n const readDocumentBody = async (\n metadata: ItemMetadata,\n preferredPath: string,\n preferredFormat: ItemFormat,\n ): Promise<string> => {\n const tryRead = async (\n targetPath: string,\n format: ItemFormat,\n ): Promise<string> => {\n await runActiveOnReadHooks({ path: targetPath, scope: \"project\" });\n const raw = await fs.readFile(targetPath, \"utf8\");\n const parsed = parseItemDocument(raw, {\n format,\n schema,\n extensionFieldNames,\n onWarning: (warning) => listWarnings.push(warning),\n });\n return parsed.body;\n };\n\n try {\n return await tryRead(preferredPath, preferredFormat);\n } catch {\n const alternateFormat: ItemFormat =\n preferredFormat === \"toon\" ? \"json_markdown\" : \"toon\";\n const alternatePath = getItemPath(\n pmRoot,\n metadata.type as ItemType,\n metadata.id,\n alternateFormat,\n typeToFolder,\n );\n try {\n return await tryRead(alternatePath, alternateFormat);\n } catch {\n listWarnings.push(\n `item_list_item_read_failed:${path.relative(pmRoot, alternatePath)}`,\n );\n return \"\";\n }\n }\n };\n\n const listWarnings: string[] = [];\n const cachedDocuments = await listAllDocumentCandidatesCached(\n pmRoot,\n itemFormat,\n typeToFolder,\n listWarnings,\n schema,\n );\n const documents: ItemDocument[] = [];\n if (cachedDocuments.length === 0) {\n const itemMetadataDocuments = await listAllItemMetadata(\n pmRoot,\n itemFormat,\n typeToFolder,\n listWarnings,\n schema,\n );\n for (const metadata of itemMetadataDocuments) {\n const preferredPath = getItemPath(\n pmRoot,\n metadata.type as ItemType,\n metadata.id,\n itemFormat,\n typeToFolder,\n );\n const body = await readDocumentBody(metadata, preferredPath, itemFormat);\n documents.push({ metadata, body });\n }\n return {\n documents,\n warnings: [...new Set(listWarnings)].sort((left, right) =>\n left.localeCompare(right),\n ),\n };\n }\n\n for (const cachedDocument of cachedDocuments) {\n if (typeof cachedDocument.body === \"string\") {\n documents.push({\n metadata: cachedDocument.metadata,\n body: cachedDocument.body,\n });\n continue;\n }\n const body = await readDocumentBody(\n cachedDocument.metadata,\n cachedDocument.item_path,\n cachedDocument.item_format,\n );\n documents.push({\n metadata: cachedDocument.metadata,\n body,\n });\n }\n return {\n documents,\n warnings: [...new Set(listWarnings)].sort((left, right) =>\n left.localeCompare(right),\n ),\n };\n}\n/* c8 ignore stop */\n\n/* c8 ignore start -- field projection lookup precedence is validated by output-shaping integration tests */\nfunction readSearchFieldValue(hit: SearchHit, field: string): unknown {\n const normalized = field.trim();\n if (normalized.length === 0) {\n return null;\n }\n if (normalized === \"score\") {\n return hit.score;\n }\n if (normalized === \"matched_fields\") {\n return hit.matched_fields;\n }\n if (normalized.startsWith(\"item.\")) {\n const itemKey = normalized.slice(\"item.\".length);\n if (itemKey.length === 0) {\n return null;\n }\n const itemRecord = toItemRecord(hit.item);\n return itemRecord[itemKey] ?? null;\n }\n const hitRecord = hit as unknown as Record<string, unknown>;\n const itemRecord = toItemRecord(hit.item);\n if (Object.prototype.hasOwnProperty.call(itemRecord, normalized)) {\n return itemRecord[normalized] ?? null;\n }\n if (Object.prototype.hasOwnProperty.call(hitRecord, normalized)) {\n return hitRecord[normalized] ?? null;\n }\n return null;\n}\n/* c8 ignore stop */\n\nfunction projectSearchHits(\n hits: SearchHit[],\n projection: SearchProjectionConfig,\n): SearchResultItem[] {\n if (projection.mode === \"full\") {\n // matched_all_terms is an internal ranking signal (GH-181); strip it from\n // full-mode output rows so the public hit shape stays { item, score, matched_fields }.\n return hits.map(\n ({\n matched_all_terms: _matchedAllTerms,\n exact_id_match: _exactIdMatch,\n ...hit\n }) => hit,\n );\n }\n return hits.map((hit) => {\n const projected: Record<string, unknown> = {};\n for (const field of projection.fields) {\n projected[field] = readSearchFieldValue(hit, field);\n }\n return projected;\n });\n}\n\ninterface PreparedSearchInput {\n query: string;\n options: SearchOptions;\n inlineWarnings: string[];\n highlight: boolean;\n includeLinked: boolean;\n titleExact: boolean;\n phraseExact: boolean;\n matchMode: SearchMatchMode;\n minScoreOverride: number | undefined;\n countOnly: boolean;\n tokens: string[];\n normalizedQuery: string;\n limit: number | undefined;\n projection: SearchProjectionConfig;\n modeWasExplicit: boolean;\n}\n\ninterface SearchRuntimeContext {\n pmRoot: string;\n settings: PmSettings;\n statusRegistry: RuntimeStatusRegistry;\n runtimeFieldRegistry: RuntimeFieldRegistry;\n runtimeFieldFilters: Record<string, unknown>;\n typeRegistry: ItemTypeRegistry;\n maxResults: number;\n scoreThreshold: number;\n semanticWeightProvided: boolean;\n semanticWeightOverride: number | undefined;\n hybridSemanticWeight: number;\n tuning: SearchTuning;\n providerResolution: EmbeddingProviderResolution;\n vectorResolution: VectorStoreResolution;\n extensionSearchProvider: ReturnType<typeof resolveExtensionSearchProvider>;\n extensionVectorAdapter: ReturnType<typeof resolveExtensionVectorAdapter>;\n bm25Mode: BuiltInBm25Mode | null;\n queryExpansion: QueryExpansionConfig;\n queryExpansionExtension: {\n providerName: string;\n expand: ExtensionSearchProviderQueryExpansion;\n } | null;\n rerank: RerankConfig;\n rerankExtension: {\n providerName: string;\n rerank: ExtensionSearchProviderRerank;\n } | null;\n effectiveMode: SearchMode;\n}\n\ninterface FilteredSearchCorpus {\n warnings: string[];\n allDocuments: ItemDocument[];\n filteredDocuments: ItemDocument[];\n}\n\ninterface SearchResponseContext {\n query: string;\n effectiveMode: SearchMode;\n matchMode: SearchMatchMode;\n options: SearchOptions;\n includeLinked: boolean;\n titleExact: boolean;\n phraseExact: boolean;\n scoreThreshold: number;\n hybridSemanticWeight: number;\n queryExpansion: QueryExpansionConfig;\n rerank: RerankConfig;\n projection: SearchProjectionConfig;\n warnings: string[];\n runtimeFieldFilters: Record<string, unknown>;\n}\n\ninterface SearchModeExecutionInput {\n prepared: PreparedSearchInput;\n runtime: SearchRuntimeContext;\n filteredDocuments: ItemDocument[];\n keywordHits: SearchHit[];\n warnings: string[];\n modeWasExplicit: boolean;\n}\n\ninterface SearchModeExecutionResult {\n effectiveMode: SearchMode;\n hits: SearchHit[];\n}\n\nfunction resolveQueryExpansionExtension(queryExpansion: QueryExpansionConfig): {\n providerName: string;\n expand: ExtensionSearchProviderQueryExpansion;\n} | null {\n const provider = resolveExtensionSearchProviderByName(\n queryExpansion.provider ?? undefined,\n );\n return provider?.queryExpansion\n ? { providerName: provider.providerName, expand: provider.queryExpansion }\n : null;\n}\n\nfunction resolveRerankExtension(\n settings: PmSettings,\n): { providerName: string; rerank: ExtensionSearchProviderRerank } | null {\n const provider = resolveExtensionSearchProviderByName(\n toOptionalNonEmptyString(settings.search?.provider),\n );\n return provider?.rerank\n ? { providerName: provider.providerName, rerank: provider.rerank }\n : null;\n}\n\nfunction prepareSearchInput(\n rawQuery: string,\n rawOptions: SearchOptions,\n): PreparedSearchInput {\n const inlineWarnings: string[] = [];\n const inlineParse = parseInlineQueryFilters(rawQuery);\n const hasInlineFilters = Object.keys(inlineParse.inlineFilters).length > 0;\n if (hasInlineFilters && inlineParse.residualQuery.trim().length === 0) {\n throw new PmCliError(\n \"Inline field:value tokens consumed the entire query, leaving no search terms.\",\n EXIT_CODE.USAGE,\n {\n examples: [\n \"pm search auth tag:area:search\",\n \"pm list --tag area:search --status open\",\n ],\n nextSteps: [\n \"Add keyword terms alongside the inline filters, or use pm list for pure tag/status/type/priority filtering.\",\n ],\n },\n );\n }\n const query = hasInlineFilters ? inlineParse.residualQuery : rawQuery;\n const options = applyInlineQueryFilters(\n rawOptions,\n inlineParse.inlineFilters,\n inlineWarnings,\n );\n return {\n query,\n options,\n inlineWarnings,\n highlight: options.highlight === true,\n includeLinked: parseIncludeLinked(options.includeLinked),\n titleExact: parseTitleExact(options.titleExact),\n phraseExact: parsePhraseExact(options.phraseExact),\n matchMode: parseMatchMode(\n typeof options.matchMode === \"string\" ? options.matchMode : undefined,\n ),\n minScoreOverride: parseMinScoreOverride(options.minScore),\n countOnly: options.count === true,\n tokens: parseTokens(query),\n normalizedQuery: normalizeSearchPhrase(query),\n limit: parseLimit(options.limit),\n projection: parseProjectionConfig(options),\n modeWasExplicit:\n typeof options.mode === \"string\" && options.mode.trim().length > 0,\n };\n}\n\nasync function resolveSearchRuntimeContext(\n prepared: PreparedSearchInput,\n global: GlobalOptions,\n): Promise<SearchRuntimeContext> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(\n `Tracker is not initialized at ${pmRoot}. Run pm init first.`,\n EXIT_CODE.NOT_FOUND,\n );\n }\n const storedSettings = await readSettings(pmRoot);\n const settings =\n resolveSettingsWithSemanticRuntimeDefaults(storedSettings).settings;\n const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);\n const runtimeFieldRegistry = resolveRuntimeFieldRegistry(settings.schema);\n validateSearchProjectionFields(prepared.projection, runtimeFieldRegistry);\n const runtimeFieldFilters = collectRuntimeFilterValues(\n prepared.options as Record<string, unknown>,\n runtimeFieldRegistry,\n \"search\",\n );\n const typeRegistry = resolveItemTypeRegistry(\n settings,\n getActiveExtensionRegistrations(),\n );\n const providerResolution = resolveEmbeddingProviders(settings);\n const vectorResolution = resolveVectorStores(settings, pmRoot);\n const extensionSearchProvider = resolveExtensionSearchProvider(settings);\n const extensionVectorAdapter = resolveExtensionVectorAdapter(settings);\n const semanticWeightOverride = parseSemanticWeightOverride(\n prepared.options.semanticWeight,\n );\n const queryExpansion = resolveQueryExpansionConfig(\n settings,\n providerResolution.active?.name ?? null,\n );\n const rerank = resolveRerankConfig(\n settings,\n providerResolution.active?.model ??\n toOptionalNonEmptyString(settings.search?.embedding_model) ??\n \"text-embedding-3-small\",\n );\n return {\n pmRoot,\n settings,\n statusRegistry,\n runtimeFieldRegistry,\n runtimeFieldFilters,\n typeRegistry,\n maxResults: resolveSearchMaxResults(settings),\n scoreThreshold:\n prepared.minScoreOverride ?? resolveSearchScoreThreshold(settings),\n semanticWeightProvided: prepared.options.semanticWeight !== undefined,\n semanticWeightOverride,\n hybridSemanticWeight:\n semanticWeightOverride ?? resolveHybridSemanticWeight(settings),\n tuning: resolveSearchTuning(settings),\n providerResolution,\n vectorResolution,\n extensionSearchProvider,\n extensionVectorAdapter,\n bm25Mode: resolveBuiltInBm25Mode({\n configuredProvider: toOptionalNonEmptyString(settings.search?.provider),\n hasEmbeddingProvider: providerResolution.active !== null,\n hasExtensionSearchProvider: extensionSearchProvider !== null,\n }),\n queryExpansion,\n queryExpansionExtension: resolveQueryExpansionExtension(queryExpansion),\n rerank,\n rerankExtension: resolveRerankExtension(settings),\n effectiveMode: parseMode(prepared.options.mode, {\n hasProvider:\n providerResolution.active !== null || extensionSearchProvider !== null,\n hasVectorStore:\n vectorResolution.active !== null || extensionVectorAdapter !== null,\n }),\n };\n}\n\nasync function loadFilteredSearchCorpus(\n prepared: PreparedSearchInput,\n runtime: SearchRuntimeContext,\n): Promise<FilteredSearchCorpus> {\n const loadedDocuments = await loadDocuments(\n runtime.pmRoot,\n runtime.settings.item_format ?? \"toon\",\n runtime.typeRegistry.type_to_folder,\n runtime.settings.schema,\n );\n const statusFilter = parseStatusFilterCsv(\n typeof prepared.options.status === \"string\"\n ? prepared.options.status\n : undefined,\n runtime.statusRegistry,\n { strict: true },\n );\n const lifecycleClassifier = lifecycleClassifierFromStatusRegistry(\n runtime.statusRegistry,\n );\n const metadataFilteredDocuments = applyFilters(\n loadedDocuments.documents,\n prepared.options,\n runtime.typeRegistry,\n runtime.runtimeFieldFilters,\n statusFilter,\n lifecycleClassifier,\n );\n return {\n warnings: loadedDocuments.warnings,\n allDocuments: loadedDocuments.documents,\n filteredDocuments: applyExactQueryFilters(\n metadataFilteredDocuments,\n prepared.normalizedQuery,\n {\n titleExact: prepared.titleExact,\n phraseExact: prepared.phraseExact || prepared.matchMode === \"exact\",\n },\n ),\n };\n}\n\nasync function collectLinkedCorpusById(\n includeLinked: boolean,\n effectiveMode: SearchMode,\n filteredDocuments: ItemDocument[],\n): Promise<Map<string, string>> {\n const linkedCorpusById = new Map<string, string>();\n if (\n !includeLinked ||\n (effectiveMode !== \"keyword\" && effectiveMode !== \"hybrid\")\n ) {\n return linkedCorpusById;\n }\n const projectRoot = process.cwd();\n const linkedCorpusRoots = await resolveLinkedCorpusRoots(\n projectRoot,\n resolveGlobalPmRoot(projectRoot),\n );\n const linkedCorpusEntries = await Promise.all(\n filteredDocuments.map(\n async (document) =>\n [\n document.metadata.id,\n await loadLinkedCorpus(document, linkedCorpusRoots),\n ] as const,\n ),\n );\n for (const [id, corpus] of linkedCorpusEntries) {\n linkedCorpusById.set(id, corpus);\n }\n return linkedCorpusById;\n}\n\nasync function computeKeywordSearchHits(\n prepared: PreparedSearchInput,\n runtime: SearchRuntimeContext,\n filteredDocuments: ItemDocument[],\n): Promise<SearchHit[]> {\n const linkedCorpusById = await collectLinkedCorpusById(\n prepared.includeLinked,\n runtime.effectiveMode,\n filteredDocuments,\n );\n const applyCoverageBonus = prepared.matchMode === \"or\";\n return filteredDocuments\n .map((document) =>\n buildHybridLexicalScore(\n document,\n prepared.tokens,\n prepared.normalizedQuery,\n prepared.includeLinked,\n linkedCorpusById,\n runtime.tuning,\n runtime.settings.id_prefix,\n applyCoverageBonus,\n ),\n )\n .filter((entry): entry is SearchHit => entry !== null)\n .filter(\n (entry) =>\n prepared.matchMode !== \"and\" || entry.matched_all_terms === true,\n );\n}\n\nfunction buildEmptySearchResultFromContext(\n response: SearchResponseContext,\n countOnly: boolean,\n): SearchResult {\n return emptySearchResult(\n response.query,\n response.effectiveMode,\n response.matchMode,\n response.options,\n response.includeLinked,\n response.scoreThreshold,\n response.hybridSemanticWeight,\n response.queryExpansion,\n response.rerank,\n response.projection,\n response.warnings,\n response.runtimeFieldFilters,\n countOnly,\n );\n}\n\nasync function executeBuiltInBm25Search(\n prepared: PreparedSearchInput,\n runtime: SearchRuntimeContext,\n filteredDocuments: ItemDocument[],\n keywordHits: SearchHit[],\n warnings: string[],\n): Promise<SearchHit[] | null> {\n if (runtime.bm25Mode === null || runtime.effectiveMode === \"keyword\") {\n return null;\n }\n const hits = computeBuiltInBm25Hits({\n requestedMode: runtime.effectiveMode,\n query: prepared.query,\n filteredDocuments,\n keywordHits,\n corpusFields: resolveSearchCorpusFields(runtime.settings),\n bm25Params: resolveBm25Params(runtime.settings),\n hybridSemanticWeight: runtime.hybridSemanticWeight,\n });\n if (runtime.bm25Mode === \"auto-fallback\") {\n warnings.push(\n `search_${runtime.effectiveMode}_offline_bm25:no_embedding_provider:using_lexical_bm25`,\n );\n }\n return hits;\n}\n\nasync function executeExtensionSearchProvider(\n prepared: PreparedSearchInput,\n runtime: SearchRuntimeContext,\n filteredDocuments: ItemDocument[],\n filteredById: Map<string, ItemDocument>,\n): Promise<SearchHit[] | null> {\n if (!runtime.extensionSearchProvider) {\n return null;\n }\n const canUseBuiltInSemantic =\n runtime.providerResolution.active !== null &&\n (runtime.vectorResolution.active !== null ||\n runtime.extensionVectorAdapter !== null);\n try {\n const providerResponse = await Promise.resolve(\n runtime.extensionSearchProvider.query({\n query: prepared.query,\n mode: runtime.effectiveMode,\n tokens: prepared.tokens,\n options: prepared.options,\n settings: runtime.settings,\n documents: filteredDocuments,\n }),\n );\n return normalizeExtensionProviderHits(\n runtime.extensionSearchProvider.providerName,\n providerResponse,\n filteredById,\n );\n } catch (error: unknown) {\n if (!canUseBuiltInSemantic) {\n throw new PmCliError(\n `Extension search provider \"${runtime.extensionSearchProvider.providerName}\" failed: ${error instanceof Error ? error.message : String(error)}`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n return null;\n }\n}\n\nfunction maybeApplyNoVectorFallback(\n effectiveMode: Exclude<SearchMode, \"keyword\">,\n semanticResult: Awaited<ReturnType<typeof computeSemanticOrHybridHits>>,\n keywordHits: SearchHit[],\n warnings: string[],\n): SearchHit[] {\n if (semanticResult.vectorMatchCount > 0) {\n return semanticResult.hits;\n }\n warnings.push(\n `search_${effectiveMode}_degraded:no_vector_matches:results_are_lexical`,\n );\n return effectiveMode === \"semantic\" ? keywordHits : semanticResult.hits;\n}\n\nasync function prepareBuiltInSemanticSearch(\n runtime: SearchRuntimeContext,\n effectiveMode: Exclude<SearchMode, \"keyword\">,\n filteredDocuments: ItemDocument[],\n warnings: string[],\n modeWasExplicit: boolean,\n): Promise<void> {\n const builtInSemanticWillRun =\n !runtime.extensionSearchProvider &&\n runtime.providerResolution.active !== null &&\n (runtime.vectorResolution.active !== null ||\n runtime.extensionVectorAdapter !== null);\n if (modeWasExplicit && builtInSemanticWillRun) {\n await maybeEmitVectorIndexStaleWarning(\n runtime.pmRoot,\n filteredDocuments,\n warnings,\n );\n }\n if (!runtime.extensionSearchProvider) {\n requireSemanticDependencies(\n effectiveMode,\n runtime.providerResolution,\n runtime.vectorResolution,\n runtime.extensionVectorAdapter !== null,\n );\n }\n}\n\nasync function executeSemanticSearch(\n input: SearchModeExecutionInput,\n): Promise<SearchModeExecutionResult> {\n const {\n prepared,\n runtime,\n filteredDocuments,\n keywordHits,\n warnings,\n modeWasExplicit,\n } = input;\n let hits = keywordHits;\n const bm25Hits = await executeBuiltInBm25Search(\n prepared,\n runtime,\n filteredDocuments,\n keywordHits,\n warnings,\n );\n const semanticMode = runtime.effectiveMode;\n if (bm25Hits !== null || semanticMode === \"keyword\") {\n return { effectiveMode: runtime.effectiveMode, hits: bm25Hits ?? hits };\n }\n try {\n await prepareBuiltInSemanticSearch(\n runtime,\n semanticMode,\n filteredDocuments,\n warnings,\n modeWasExplicit,\n );\n if (filteredDocuments.length === 0 || prepared.limit === 0) {\n return { effectiveMode: runtime.effectiveMode, hits: [] };\n }\n const filteredById = new Map(\n filteredDocuments.map((document) => [document.metadata.id, document]),\n );\n hits =\n (await executeExtensionSearchProvider(\n prepared,\n runtime,\n filteredDocuments,\n filteredById,\n )) ?? hits;\n if (hits === keywordHits) {\n const { provider, vectorStore } = requireSemanticDependencies(\n semanticMode,\n runtime.providerResolution,\n runtime.vectorResolution,\n runtime.extensionVectorAdapter !== null,\n );\n const semanticResult = await computeSemanticOrHybridHits({\n requestedMode: semanticMode,\n query: prepared.query,\n filteredDocuments,\n keywordHits,\n hybridSemanticWeight: runtime.hybridSemanticWeight,\n limit: prepared.limit,\n maxResults: runtime.maxResults,\n provider,\n vectorStore,\n extensionVectorAdapter: runtime.extensionVectorAdapter,\n queryExpansion: runtime.queryExpansion,\n queryExpansionExtension: runtime.queryExpansionExtension,\n rerank: runtime.rerank,\n rerankExtension: runtime.rerankExtension,\n warnings,\n settings: runtime.settings,\n });\n hits = maybeApplyNoVectorFallback(\n semanticMode,\n semanticResult,\n keywordHits,\n warnings,\n );\n }\n return { effectiveMode: runtime.effectiveMode, hits };\n } catch (error: unknown) {\n warnings.push(\n buildExplicitSemanticFallbackWarning(runtime.effectiveMode, error),\n );\n return { effectiveMode: \"keyword\", hits: keywordHits };\n }\n}\n\nfunction buildCountOnlySearchResult(\n response: SearchResponseContext,\n total: number,\n): SearchResult {\n if (\n response.projection.mode === \"compact\" &&\n response.options.compact === true\n ) {\n return withSearchWarnings(\n {\n query: response.query.trim(),\n mode: response.effectiveMode,\n items: [],\n count: total,\n total,\n count_only: true,\n filters: buildCompactSearchFilterSummary({\n mode: response.effectiveMode,\n matchMode: response.matchMode,\n options: response.options,\n includeLinked: response.includeLinked,\n titleExact: response.titleExact,\n phraseExact: response.phraseExact,\n scoreThreshold: response.scoreThreshold,\n hybridSemanticWeight: response.hybridSemanticWeight,\n runtimeFieldFilters: response.runtimeFieldFilters,\n }),\n },\n response.warnings,\n );\n }\n const projectionFields =\n response.projection.mode === \"full\"\n ? null\n : [...response.projection.fields];\n return withSearchWarnings(\n {\n query: response.query.trim(),\n mode: response.effectiveMode,\n items: [],\n count: total,\n total,\n count_only: true,\n filters: buildVerboseSearchFilters({\n effectiveMode: response.effectiveMode,\n matchMode: response.matchMode,\n options: response.options,\n includeLinked: response.includeLinked,\n titleExact: response.titleExact,\n phraseExact: response.phraseExact,\n scoreThreshold: response.scoreThreshold,\n hybridSemanticWeight: response.hybridSemanticWeight,\n queryExpansion: response.queryExpansion,\n rerank: response.rerank,\n runtimeFieldFilters: response.runtimeFieldFilters,\n }),\n projection: {\n mode: response.projection.mode,\n fields: projectionFields,\n },\n now: nowIso(),\n },\n response.warnings,\n );\n}\n\nfunction withSearchWarnings(\n result: SearchResult,\n warnings: string[],\n): SearchResult {\n if (warnings.length === 0) {\n return result;\n }\n return { ...result, warnings };\n}\n\nfunction attachSearchHighlights(\n prepared: PreparedSearchInput,\n filteredDocuments: ItemDocument[],\n limited: SearchHit[],\n): { hits: SearchHit[]; projection: SearchProjectionConfig } {\n if (!prepared.highlight) {\n return { hits: limited, projection: prepared.projection };\n }\n const documentById = new Map(\n filteredDocuments.map((document) => [document.metadata.id, document]),\n );\n const hits = limited.map((hit) => ({\n ...hit,\n highlights: buildHitHighlights(\n documentById.get(hit.item.id)!,\n hit.matched_fields,\n prepared.tokens,\n ),\n }));\n if (\n prepared.projection.mode === \"full\" ||\n prepared.projection.fields.includes(\"highlights\")\n ) {\n return { hits, projection: prepared.projection };\n }\n return {\n hits,\n projection: {\n mode: prepared.projection.mode,\n fields: [...prepared.projection.fields, \"highlights\"],\n },\n };\n}\n\nfunction buildSearchResultForHits(\n response: SearchResponseContext,\n projectedItems: SearchResultItem[],\n total: number,\n limitedCount: number,\n effectiveProjection: SearchProjectionConfig,\n pageExtras: {\n has_more?: boolean;\n next_cursor?: string;\n applied_limit: number;\n truncated?: true;\n },\n): SearchResult {\n const truncationExtras = limitedCount < total ? { total } : {};\n if (\n response.projection.mode === \"compact\" &&\n response.options.compact === true\n ) {\n return withSearchWarnings(\n {\n query: response.query.trim(),\n mode: response.effectiveMode,\n items: projectedItems,\n count: projectedItems.length,\n ...truncationExtras,\n ...pageExtras,\n filters: buildCompactSearchFilterSummary({\n mode: response.effectiveMode,\n matchMode: response.matchMode,\n options: response.options,\n includeLinked: response.includeLinked,\n titleExact: response.titleExact,\n phraseExact: response.phraseExact,\n scoreThreshold: response.scoreThreshold,\n hybridSemanticWeight: response.hybridSemanticWeight,\n runtimeFieldFilters: response.runtimeFieldFilters,\n }),\n },\n response.warnings,\n );\n }\n const finalProjectionFields =\n effectiveProjection.mode === \"full\"\n ? null\n : [...effectiveProjection.fields];\n return {\n query: response.query.trim(),\n mode: response.effectiveMode,\n items: projectedItems,\n count: projectedItems.length,\n ...truncationExtras,\n ...pageExtras,\n filters: buildVerboseSearchFilters({\n effectiveMode: response.effectiveMode,\n matchMode: response.matchMode,\n options: response.options,\n includeLinked: response.includeLinked,\n titleExact: response.titleExact,\n phraseExact: response.phraseExact,\n scoreThreshold: response.scoreThreshold,\n hybridSemanticWeight: response.hybridSemanticWeight,\n queryExpansion: response.queryExpansion,\n rerank: response.rerank,\n runtimeFieldFilters: response.runtimeFieldFilters,\n }),\n projection: {\n mode: effectiveProjection.mode,\n fields: finalProjectionFields,\n },\n now: nowIso(),\n ...(response.warnings.length > 0 ? { warnings: response.warnings } : {}),\n };\n}\n\nfunction assertSearchPagingOptions(options: SearchOptions): void {\n if (options.after !== undefined && options.count === true) {\n throw new PmCliError(\n \"Search --after cannot be combined with --count.\",\n EXIT_CODE.USAGE,\n );\n }\n}\n\n/** Implements run search for the public runtime surface of this module. */\nexport async function runSearch(\n rawQuery: string,\n rawOptions: SearchOptions,\n global: GlobalOptions,\n): Promise<SearchResult> {\n assertSearchPagingOptions(rawOptions);\n const prepared = prepareSearchInput(rawQuery, rawOptions);\n const runtime = await resolveSearchRuntimeContext(prepared, global);\n const corpus = await loadFilteredSearchCorpus(prepared, runtime);\n const warnings = corpus.warnings;\n warnings.push(...prepared.inlineWarnings);\n if (\n runtime.effectiveMode === \"hybrid\" &&\n runtime.semanticWeightProvided &&\n runtime.semanticWeightOverride === undefined\n ) {\n warnings.push(\n \"search_hybrid_semantic_weight_override_invalid:using_settings_default\",\n );\n }\n const responseBase = {\n query: prepared.query,\n matchMode: prepared.matchMode,\n options: prepared.options,\n includeLinked: prepared.includeLinked,\n titleExact: prepared.titleExact,\n phraseExact: prepared.phraseExact,\n scoreThreshold: runtime.scoreThreshold,\n hybridSemanticWeight: runtime.hybridSemanticWeight,\n queryExpansion: runtime.queryExpansion,\n rerank: runtime.rerank,\n projection: prepared.projection,\n warnings,\n runtimeFieldFilters: runtime.runtimeFieldFilters,\n };\n if (\n runtime.effectiveMode === \"keyword\" &&\n (corpus.filteredDocuments.length === 0 ||\n (prepared.limit === 0 && !prepared.countOnly))\n ) {\n return buildEmptySearchResultFromContext(\n { ...responseBase, effectiveMode: runtime.effectiveMode },\n prepared.countOnly,\n );\n }\n const keywordHits = await computeKeywordSearchHits(\n prepared,\n runtime,\n corpus.filteredDocuments,\n );\n const modeResult = await executeSemanticSearch({\n prepared,\n runtime,\n filteredDocuments: corpus.filteredDocuments,\n keywordHits,\n warnings,\n modeWasExplicit: prepared.modeWasExplicit,\n });\n if (\n modeResult.effectiveMode !== \"keyword\" &&\n modeResult.hits.length === 0 &&\n (corpus.filteredDocuments.length === 0 ||\n (prepared.limit === 0 && !prepared.countOnly))\n ) {\n return buildEmptySearchResultFromContext(\n { ...responseBase, effectiveMode: modeResult.effectiveMode },\n prepared.countOnly,\n );\n }\n const thresholded = modeResult.hits.filter(\n (entry) =>\n entry.exact_id_match === true || entry.score >= runtime.scoreThreshold,\n );\n const sorted = sortHits(thresholded, runtime.statusRegistry);\n const total = sorted.length;\n const page = resolveSearchPage({\n sorted,\n query: prepared.query,\n mode: modeResult.effectiveMode,\n searchOptions: prepared.options,\n limit: prepared.limit ?? runtime.maxResults,\n });\n const response = { ...responseBase, effectiveMode: modeResult.effectiveMode };\n if (prepared.countOnly) {\n return buildCountOnlySearchResult(response, total);\n }\n const { hits: projectedHits, projection: effectiveProjection } =\n attachSearchHighlights(prepared, corpus.filteredDocuments, page.limited);\n const projectedItems = projectSearchHits(projectedHits, effectiveProjection);\n return buildSearchResultForHits(\n response,\n projectedItems,\n total,\n page.limited.length,\n effectiveProjection,\n page.pageExtras,\n );\n}\n","/**\n * @module core/shared/text-normalization\n *\n * Provides shared primitives and utilities for Text Normalization.\n */\n/** Normalizes text to lowercase whitespace-collapsed form for stable matching and comparison. */\nexport function normalizeLowercaseWhitespace(value: string): string {\n return value.trim().toLowerCase().replace(/\\s+/g, \" \");\n}\n\n/** Implements tokenize alpha numeric for the public runtime surface of this module. */\nexport function tokenizeAlphaNumeric(value: string): string[] {\n return normalizeLowercaseWhitespace(value)\n .split(/[^a-z0-9]+/)\n .filter((token) => token.length > 0);\n}\n\n/** Implements jaccard similarity for the public runtime surface of this module. */\nexport function jaccardSimilarity(\n leftTokens: string[],\n rightTokens: string[],\n): number {\n if (leftTokens.length === 0 && rightTokens.length === 0) {\n return 1;\n }\n if (leftTokens.length === 0 || rightTokens.length === 0) {\n return 0;\n }\n const leftSet = new Set(leftTokens);\n const rightSet = new Set(rightTokens);\n let intersection = 0;\n for (const token of leftSet) {\n if (rightSet.has(token)) {\n intersection += 1;\n }\n }\n // Both token sets are non-empty here (guarded above), so union is always >= 1.\n const union = new Set([...leftSet, ...rightSet]).size;\n return intersection / union;\n}\n","/**\n * @module core/search/relevance\n *\n * Powers search, embeddings, and semantic retrieval behavior for Relevance.\n */\nimport type { PmSettings } from \"../../types.js\";\nimport {\n coercePositiveInteger,\n toNonEmptyString,\n} from \"../shared/primitives.js\";\nimport { tokenizeAlphaNumeric } from \"../shared/text-normalization.js\";\nimport {\n executeEmbeddingRequest,\n type EmbeddingProviderConfig,\n} from \"./providers.js\";\n\n/** Fallback query expansion max queries used when callers do not provide an override. */\nexport const DEFAULT_QUERY_EXPANSION_MAX_QUERIES = 4;\n/** Fallback rerank top k used when callers do not provide an override. */\nexport const DEFAULT_RERANK_TOP_K = 20;\nconst MAX_RERANK_TOP_K = 200;\n\nconst QUERY_EXPANSION_STOP_WORDS = new Set([\n \"a\",\n \"an\",\n \"and\",\n \"for\",\n \"from\",\n \"in\",\n \"into\",\n \"of\",\n \"on\",\n \"or\",\n \"the\",\n \"to\",\n \"with\",\n]);\n\n/** Documents the query expansion config payload exchanged by command, SDK, and package integrations. */\nexport interface QueryExpansionConfig {\n /** Whether enabled applies to this operation. */\n enabled: boolean;\n /** Value that configures or reports provider for this contract. */\n provider: string | null;\n /** Value that configures or reports max queries for this contract. */\n max_queries: number;\n}\n\n/** Documents the rerank config payload exchanged by command, SDK, and package integrations. */\nexport interface RerankConfig {\n /** Whether enabled applies to this operation. */\n enabled: boolean;\n /** Value that configures or reports model for this contract. */\n model: string;\n /** Value that configures or reports top k for this contract. */\n top_k: number;\n}\n\n/** Documents the rerank candidate payload exchanged by command, SDK, and package integrations. */\nexport interface RerankCandidate {\n /** Stable identifier used to reference this record across commands and storage. */\n id: string;\n /** Value that configures or reports text for this contract. */\n text: string;\n}\n\n/** Documents the rerank scored hit payload exchanged by command, SDK, and package integrations. */\nexport interface RerankScoredHit {\n /** Stable identifier used to reference this record across commands and storage. */\n id: string;\n /** Value that configures or reports score for this contract. */\n score: number;\n}\n\nfunction dedupeQueries(values: string[], limit: number): string[] {\n const deduped: string[] = [];\n const seen = new Set<string>();\n for (const entry of values) {\n const normalized = entry.trim().replaceAll(/\\s+/g, \" \");\n if (normalized.length === 0) {\n continue;\n }\n const dedupeKey = normalized.toLowerCase();\n if (seen.has(dedupeKey)) {\n continue;\n }\n seen.add(dedupeKey);\n deduped.push(normalized);\n if (deduped.length >= limit) {\n break;\n }\n }\n return deduped;\n}\n\nfunction singularizeSimple(token: string): string {\n const normalizedToken = token.toLowerCase();\n if (normalizedToken.length > 4 && normalizedToken.endsWith(\"ies\")) {\n return `${normalizedToken.slice(0, -3)}y`;\n }\n if (\n normalizedToken.length > 4 &&\n (normalizedToken.endsWith(\"ches\") ||\n normalizedToken.endsWith(\"shes\") ||\n normalizedToken.endsWith(\"xes\") ||\n normalizedToken.endsWith(\"zes\") ||\n normalizedToken.endsWith(\"sses\"))\n ) {\n return normalizedToken.slice(0, -2);\n }\n if (\n normalizedToken.length > 3 &&\n normalizedToken.endsWith(\"s\") &&\n !normalizedToken.endsWith(\"ss\") &&\n !normalizedToken.endsWith(\"us\") &&\n !normalizedToken.endsWith(\"is\") &&\n !normalizedToken.endsWith(\"as\")\n ) {\n return normalizedToken.slice(0, -1);\n }\n return normalizedToken;\n}\n\nfunction pluralizeSimple(token: string): string {\n const normalizedToken = token.toLowerCase();\n if (\n normalizedToken.length > 2 &&\n (!normalizedToken.endsWith(\"s\") || normalizedToken.endsWith(\"ss\"))\n ) {\n if (normalizedToken.endsWith(\"y\") && !/[aeiou]y$/u.test(normalizedToken)) {\n return `${normalizedToken.slice(0, -1)}ies`;\n }\n if (\n normalizedToken.endsWith(\"ch\") ||\n normalizedToken.endsWith(\"sh\") ||\n normalizedToken.endsWith(\"x\") ||\n normalizedToken.endsWith(\"z\") ||\n normalizedToken.endsWith(\"ss\")\n ) {\n return `${normalizedToken}es`;\n }\n return `${normalizedToken}s`;\n }\n return normalizedToken;\n}\n\n/** Implements build deterministic query expansions for the public runtime surface of this module. */\nexport function buildDeterministicQueryExpansions(\n query: string,\n maxQueries = DEFAULT_QUERY_EXPANSION_MAX_QUERIES,\n): string[] {\n const normalizedQuery = query.trim().replaceAll(/\\s+/g, \" \");\n if (normalizedQuery.length === 0) {\n return [];\n }\n const tokens = tokenizeAlphaNumeric(normalizedQuery);\n if (tokens.length === 0) {\n return [normalizedQuery];\n }\n const contentTokens = tokens.filter(\n (token) => !QUERY_EXPANSION_STOP_WORDS.has(token.toLowerCase()),\n );\n const singularized = tokens.map((token) => singularizeSimple(token));\n const pluralized = contentTokens.map((token) => pluralizeSimple(token));\n return dedupeQueries(\n [\n normalizedQuery,\n tokens.join(\" \"),\n contentTokens.join(\" \"),\n singularized.join(\" \"),\n pluralized.join(\" \"),\n ],\n Math.max(1, maxQueries),\n );\n}\n\n/** Implements normalize query expansion output for the public runtime surface of this module. */\nexport function normalizeQueryExpansionOutput(raw: unknown): string[] {\n const rawQueries = Array.isArray(raw)\n ? raw\n : (raw as { queries?: unknown } | null | undefined)?.queries;\n if (!Array.isArray(rawQueries)) {\n return [];\n }\n return dedupeQueries(\n rawQueries.filter((entry): entry is string => typeof entry === \"string\"),\n DEFAULT_QUERY_EXPANSION_MAX_QUERIES,\n );\n}\n\n/** Implements merge query expansions for the public runtime surface of this module. */\nexport function mergeQueryExpansions(\n base: string[],\n extra: string[],\n maxQueries: number,\n): string[] {\n return dedupeQueries([...base, ...extra], Math.max(1, maxQueries));\n}\n\n/** Implements resolve query expansion config for the public runtime surface of this module. */\nexport function resolveQueryExpansionConfig(\n settings: PmSettings,\n fallbackProviderName: string | null,\n): QueryExpansionConfig {\n const search = (\n settings as {\n search?: { query_expansion?: { enabled?: unknown; provider?: unknown } };\n }\n ).search;\n const queryExpansion = search?.query_expansion;\n const configuredProvider = toNonEmptyString(queryExpansion?.provider);\n return {\n enabled: queryExpansion?.enabled === true,\n provider: configuredProvider ?? fallbackProviderName,\n max_queries: DEFAULT_QUERY_EXPANSION_MAX_QUERIES,\n };\n}\n\n/** Implements resolve rerank config for the public runtime surface of this module. */\nexport function resolveRerankConfig(\n settings: PmSettings,\n fallbackModel: string,\n): RerankConfig {\n const search = (\n settings as {\n search?: {\n rerank?: { enabled?: unknown; model?: unknown; top_k?: unknown };\n };\n }\n ).search;\n const rerank = search?.rerank;\n const configuredModel = toNonEmptyString(rerank?.model);\n const configuredTopK = coercePositiveInteger(rerank?.top_k);\n const normalizedTopK = configuredTopK ?? DEFAULT_RERANK_TOP_K;\n return {\n enabled: rerank?.enabled === true,\n model: configuredModel ?? fallbackModel,\n top_k: Math.min(MAX_RERANK_TOP_K, normalizedTopK),\n };\n}\n\n/** Implements normalize rerank output for the public runtime surface of this module. */\nexport function normalizeRerankOutput(raw: unknown): RerankScoredHit[] {\n const rawHits = Array.isArray(raw)\n ? raw\n : (raw as { hits?: unknown } | null | undefined)?.hits;\n if (!Array.isArray(rawHits)) {\n return [];\n }\n const bestById = new Map<string, number>();\n for (const entry of rawHits) {\n if (typeof entry !== \"object\" || entry === null) {\n continue;\n }\n const id = toNonEmptyString((entry as { id?: unknown }).id);\n const score = (entry as { score?: unknown }).score;\n if (!id || typeof score !== \"number\" || !Number.isFinite(score)) {\n continue;\n }\n const existing = bestById.get(id);\n if (existing === undefined || score > existing) {\n bestById.set(id, score);\n }\n }\n const normalized = [...bestById.entries()].map(([id, score]) => ({\n id,\n score,\n }));\n normalized.sort((left, right) => {\n if (left.score !== right.score) {\n return right.score - left.score;\n }\n return left.id.localeCompare(right.id);\n });\n return normalized;\n}\n\nfunction dotProduct(left: number[], right: number[]): number {\n const size = left.length;\n let result = 0;\n for (let index = 0; index < size; index += 1) {\n result += left[index] * right[index];\n }\n return result;\n}\n\nfunction l2Norm(vector: number[]): number {\n let sumSquares = 0;\n for (let index = 0; index < vector.length; index += 1) {\n sumSquares += vector[index] * vector[index];\n }\n return Math.sqrt(sumSquares);\n}\n\nfunction cosineSimilarityWithKnownLeftNorm(\n left: number[] | null | undefined,\n right: number[] | null | undefined,\n leftNorm: number,\n): number {\n if (\n !left ||\n !right ||\n left.length === 0 ||\n right.length === 0 ||\n left.length !== right.length\n ) {\n return 0;\n }\n const numerator = dotProduct(left, right);\n const rightNorm = l2Norm(right);\n const denominator = leftNorm * rightNorm;\n if (\n !Number.isFinite(numerator) ||\n !Number.isFinite(leftNorm) ||\n !Number.isFinite(rightNorm) ||\n !Number.isFinite(denominator) ||\n denominator === 0\n ) {\n return 0;\n }\n return Math.max(-1, Math.min(1, numerator / denominator));\n}\n\n/** Implements rerank candidates with embeddings for the public runtime surface of this module. */\nexport async function rerankCandidatesWithEmbeddings(\n provider: EmbeddingProviderConfig,\n model: string,\n query: string,\n candidates: RerankCandidate[],\n timeoutMs?: number,\n): Promise<Map<string, number>> {\n if (candidates.length === 0) {\n return new Map();\n }\n const effectiveModel = toNonEmptyString(model) ?? provider.model;\n const rerankProvider: EmbeddingProviderConfig =\n effectiveModel === provider.model\n ? provider\n : { ...provider, model: effectiveModel };\n const payload = [query.trim(), ...candidates.map((entry) => entry.text)];\n const vectors = await executeEmbeddingRequest(\n rerankProvider,\n payload,\n timeoutMs ? { timeout_ms: timeoutMs } : {},\n );\n const queryVector = vectors[0];\n if (!queryVector) {\n return new Map();\n }\n const queryNorm = l2Norm(queryVector);\n const scoreById = new Map<string, number>();\n for (let index = 0; index < candidates.length; index += 1) {\n const candidate = candidates[index];\n const candidateVector = vectors[index + 1];\n if (!candidateVector) {\n continue;\n }\n const similarity = cosineSimilarityWithKnownLeftNorm(\n queryVector,\n candidateVector,\n queryNorm,\n );\n scoreById.set(candidate.id, Math.max(0, Math.min(1, (similarity + 1) / 2)));\n }\n return scoreById;\n}\n","/**\n * @module core/search/bm25\n *\n * Offline BM25 lexical retrieval (pm-75k9). Provides an Okapi BM25 ranker that\n * scores the in-memory item corpus with no embedding service, vector store, or\n * network dependency, so semantic/hybrid search degrades to a dense-quality\n * lexical ranker — rather than the naive field-weighted scorer — in air-gapped,\n * CI, and zero-setup environments.\n *\n * BM25 improves on raw term-frequency counting in three ways the legacy keyword\n * scorer cannot: inverse document frequency down-weights terms common across the\n * whole corpus, term-frequency saturation (`k1`) caps the contribution of a term\n * repeated many times in one document, and length normalization (`b`) prevents\n * long documents from dominating purely by size.\n */\nimport type { PmSettings } from \"../../types/index.js\";\nimport { tokenizeAlphaNumeric } from \"../shared/text-normalization.js\";\n\n/** Default Okapi BM25 term-frequency saturation parameter. `1.2` is the widely used Lucene/Elasticsearch default: higher values reduce the diminishing returns of repeated terms more slowly (terms keep accruing weight), lower values saturate sooner. */\nexport const DEFAULT_BM25_K1 = 1.2;\n\n/** Default Okapi BM25 length-normalization parameter. `0.75` is the Lucene default: `0` disables length normalization entirely, `1` fully normalizes a document's score by its length relative to the corpus average. */\nexport const DEFAULT_BM25_B = 0.75;\n\n/**\n * Resolved BM25 tuning parameters. Both are clamped to sane ranges by\n * {@link resolveBm25Params} before scoring.\n */\nexport interface Bm25Params {\n /** Term-frequency saturation (`k1`); finite and `>= 0`. */\n k1: number;\n /** Length normalization (`b`); finite and within `[0, 1]`. */\n b: number;\n}\n\n/**\n * One corpus document supplied to {@link buildBm25Index}: a stable id and the\n * already-concatenated searchable text. Callers build the text from whichever\n * fields they want indexed (typically the resolved `search.corpus_fields`).\n */\nexport interface Bm25Document {\n /** Stable identifier used to reference this record across commands and storage. */\n id: string;\n /** Value that configures or reports text for this contract. */\n text: string;\n}\n\n/**\n * Per-document statistics retained in a {@link Bm25Index}: the term-frequency\n * map and the document length (total token count) used for length\n * normalization.\n */\ninterface Bm25DocumentStats {\n id: string;\n termFrequencies: Map<string, number>;\n length: number;\n}\n\n/**\n * An immutable BM25 index built from a document set. Carries the per-document\n * term frequencies, per-term document frequencies, corpus size, and average\n * document length needed to score any query. Build once per query batch with\n * {@link buildBm25Index}, then score with {@link scoreBm25Query}.\n */\nexport interface Bm25Index {\n /** Value that configures or reports documents for this contract. */\n documents: Bm25DocumentStats[];\n /** Value that configures or reports document frequency for this contract. */\n documentFrequency: Map<string, number>;\n /** Number of document entries represented by this result. */\n documentCount: number;\n /** Value that configures or reports average document length for this contract. */\n averageDocumentLength: number;\n}\n\n/**\n * Tokenize a document/query string into BM25 terms. Shares\n * {@link tokenizeAlphaNumeric} with the lexical scorer so the BM25 vocabulary is\n * identical to the rest of search: lowercase, alphanumeric runs, no stop-word\n * removal or stemming (kept deliberately simple and language-agnostic).\n */\nexport function tokenizeBm25(text: string): string[] {\n return tokenizeAlphaNumeric(text);\n}\n\n/** Count occurrences of each token in a token list. */\nfunction buildTermFrequencies(tokens: string[]): Map<string, number> {\n const frequencies = new Map<string, number>();\n for (const token of tokens) {\n frequencies.set(token, (frequencies.get(token) ?? 0) + 1);\n }\n return frequencies;\n}\n\n/**\n * Build a BM25 index from a corpus. Computes each document's term frequencies\n * and length, the per-term document frequency, the corpus size, and the average\n * document length. Empty documents (no tokens) are retained with length `0` so\n * they can still be scored (they simply never match a query term). An empty\n * corpus yields an index with `averageDocumentLength` `0`, which\n * {@link scoreBm25Query} handles without dividing by zero.\n */\nexport function buildBm25Index(documents: Bm25Document[]): Bm25Index {\n const stats: Bm25DocumentStats[] = [];\n const documentFrequency = new Map<string, number>();\n let totalLength = 0;\n for (const document of documents) {\n const tokens = tokenizeBm25(document.text);\n const termFrequencies = buildTermFrequencies(tokens);\n totalLength += tokens.length;\n for (const term of termFrequencies.keys()) {\n documentFrequency.set(term, (documentFrequency.get(term) ?? 0) + 1);\n }\n stats.push({ id: document.id, termFrequencies, length: tokens.length });\n }\n const documentCount = stats.length;\n return {\n documents: stats,\n documentFrequency,\n documentCount,\n averageDocumentLength: documentCount > 0 ? totalLength / documentCount : 0,\n };\n}\n\n/** Inverse document frequency for one term using the BM25 \"plus-one\" variant (`ln(1 + (N - n + 0.5) / (n + 0.5))`) used by Lucene. The `1 +` inside the logarithm keeps the IDF strictly non-negative even for a term that appears in every document, so a common term can never subtract from a document's score. */\nfunction inverseDocumentFrequency(\n documentCount: number,\n termDocumentFrequency: number,\n): number {\n return Math.log(\n 1 +\n (documentCount - termDocumentFrequency + 0.5) /\n (termDocumentFrequency + 0.5),\n );\n}\n\n/** Score every document in the index against a query and return an id → score map containing only documents with a strictly positive score (a document that matches no query term is omitted, mirroring the lexical scorer's \"no match → no hit\" contract). Query tokens are de-duplicated so a token repeated in the query does not multiply its own contribution. Returns an empty map for an empty index, an empty query, or a query whose terms appear in no document. */\nexport function scoreBm25Query(\n index: Bm25Index,\n queryTokens: string[],\n params: Bm25Params,\n): Map<string, number> {\n const scores = new Map<string, number>();\n // Empty corpus, or a corpus where every document is empty (avgdl 0): no term\n // can match, so return early. Guarding here also guarantees a non-zero\n // average document length below, keeping the length-normalization division\n // safe without an unreachable fallback branch.\n if (index.documentCount === 0 || index.averageDocumentLength === 0) {\n return scores;\n }\n const distinctQueryTerms = [\n ...new Set(queryTokens.filter((token) => token.length > 0)),\n ];\n if (distinctQueryTerms.length === 0) {\n return scores;\n }\n // Precompute the IDF for each query term once rather than per document.\n const idfByTerm = new Map<string, number>();\n for (const term of distinctQueryTerms) {\n const termDocumentFrequency = index.documentFrequency.get(term);\n if (termDocumentFrequency === undefined) {\n continue;\n }\n idfByTerm.set(\n term,\n inverseDocumentFrequency(index.documentCount, termDocumentFrequency),\n );\n }\n if (idfByTerm.size === 0) {\n return scores;\n }\n for (const document of index.documents) {\n let score = 0;\n for (const [term, idf] of idfByTerm) {\n const termFrequency = document.termFrequencies.get(term);\n if (termFrequency === undefined) {\n continue;\n }\n const lengthNormalization =\n 1 -\n params.b +\n (params.b * document.length) / index.averageDocumentLength;\n const denominator = termFrequency + params.k1 * lengthNormalization;\n score += idf * ((termFrequency * (params.k1 + 1)) / denominator);\n }\n if (score > 0) {\n scores.set(document.id, score);\n }\n }\n return scores;\n}\n\n/** Coerce one persisted BM25 parameter to a finite number within `[min, max]`. A finite number is clamped to the range (preserving user intent — e.g. `k1=5000` becomes `1000` rather than being silently ignored); any non-number or non-finite value (string, `NaN`, `Infinity`, missing) falls back to `fallback` so a malformed `settings.json` can never crash or skew scoring. */\nfunction resolveClampedParam(\n candidate: unknown,\n fallback: number,\n min: number,\n max: number,\n): number {\n if (typeof candidate !== \"number\" || !Number.isFinite(candidate)) {\n return fallback;\n }\n return Math.min(max, Math.max(min, candidate));\n}\n\n/** Flatten a structured search-corpus record (the shape produced by `buildSearchCorpus`) into a single whitespace-joined string of its *values* only — field names/object keys are deliberately excluded so corpus-wide keys (`title`, `description`, …) never enter the BM25 vocabulary and skew IDF. Strings and numbers contribute their text; arrays and nested objects (tags, dependencies, the plan corpus) are walked recursively; everything else is dropped. */\nexport function flattenSearchCorpusText(\n corpus: Record<string, unknown>,\n): string {\n const collectValueText = (value: unknown): string[] => {\n if (typeof value === \"string\") {\n return [value];\n }\n if (typeof value === \"number\") {\n return [String(value)];\n }\n if (Array.isArray(value)) {\n return value.flatMap(collectValueText);\n }\n if (typeof value === \"object\" && value !== null) {\n return Object.values(value).flatMap(collectValueText);\n }\n return [];\n };\n return collectValueText(Object.values(corpus)).join(\" \");\n}\n\n/**\n * Resolve the effective BM25 parameters from `settings.search.bm25`, applying\n * {@link DEFAULT_BM25_K1}/{@link DEFAULT_BM25_B} when unset and clamping `k1` to\n * `[0, 1000]` and `b` to `[0, 1]`. Tolerant of partial/invalid config: each\n * knob is resolved independently so one bad value does not discard the other.\n */\nexport function resolveBm25Params(\n settings: Pick<PmSettings, \"search\"> | undefined,\n): Bm25Params {\n const bm25 = (\n settings?.search as { bm25?: { k1?: unknown; b?: unknown } } | undefined\n )?.bm25;\n return {\n k1: resolveClampedParam(bm25?.k1, DEFAULT_BM25_K1, 0, 1_000),\n b: resolveClampedParam(bm25?.b, DEFAULT_BM25_B, 0, 1),\n };\n}\n","/**\n * @module sdk/query/search-rendering\n *\n * Builds stable compact and verbose filter projections for search responses.\n */\nimport {\n applyFilterValueEcho,\n buildContentFilterEcho,\n buildGovernanceMissingFilterEcho,\n} from \"./list.js\";\nimport type { SearchMatchMode, SearchOptions } from \"./search.js\";\n\n/** Search execution modes represented in response metadata. */\nexport type SearchMode = \"keyword\" | \"semantic\" | \"hybrid\";\n\ninterface SearchRenderingQueryExpansion {\n enabled: boolean;\n provider: string | null;\n}\n\ninterface SearchRenderingRerank {\n enabled: boolean;\n model: string;\n top_k: number;\n}\n\nfunction isAllStatuses(value: unknown): boolean {\n if (typeof value !== \"string\") return false;\n const tokens = value\n .split(\",\")\n .map((entry) => entry.trim().toLowerCase())\n .filter(Boolean);\n return tokens.length === 1 && tokens[0] === \"all\";\n}\n\nconst COMPACT_SEARCH_VALUE_FILTER_ECHO_ENTRIES = [\n {\n optionKey: \"status\",\n summaryKey: \"status\",\n normalize: (value: unknown) => (isAllStatuses(value) ? \"all\" : value),\n },\n { optionKey: \"type\", summaryKey: \"type\" },\n { optionKey: \"tag\", summaryKey: \"tag\" },\n { optionKey: \"priority\", summaryKey: \"priority\" },\n { optionKey: \"deadlineBefore\", summaryKey: \"deadline_before\" },\n { optionKey: \"deadlineAfter\", summaryKey: \"deadline_after\" },\n { optionKey: \"updatedAfter\", summaryKey: \"updated_after\" },\n { optionKey: \"updatedBefore\", summaryKey: \"updated_before\" },\n { optionKey: \"createdAfter\", summaryKey: \"created_after\" },\n { optionKey: \"createdBefore\", summaryKey: \"created_before\" },\n { optionKey: \"assignee\", summaryKey: \"assignee\" },\n { optionKey: \"sprint\", summaryKey: \"sprint\" },\n { optionKey: \"release\", summaryKey: \"release\" },\n { optionKey: \"parent\", summaryKey: \"parent\" },\n] as const;\n\n/** Builds the token-efficient filter echo used by compact search results. */\nexport function buildCompactSearchFilterSummary(params: {\n mode: SearchMode;\n matchMode: SearchMatchMode;\n options: SearchOptions;\n includeLinked: boolean;\n titleExact: boolean;\n phraseExact: boolean;\n scoreThreshold: number;\n hybridSemanticWeight: number;\n runtimeFieldFilters?: Record<string, unknown>;\n}): Record<string, unknown> {\n const { mode, matchMode, options, includeLinked, titleExact, phraseExact, scoreThreshold, hybridSemanticWeight, runtimeFieldFilters } = params;\n const filters: Record<string, unknown> = {};\n applyFilterValueEcho(filters, options, COMPACT_SEARCH_VALUE_FILTER_ECHO_ENTRIES);\n Object.assign(filters, buildGovernanceMissingFilterEcho(options as Record<string, unknown>));\n Object.assign(filters, buildContentFilterEcho(options as Record<string, unknown>));\n if (matchMode !== \"or\") filters.match_mode = matchMode;\n if (includeLinked) filters.include_linked = true;\n if (titleExact) filters.title_exact = true;\n if (phraseExact) filters.phrase_exact = true;\n if (scoreThreshold > 0) filters.score_threshold = scoreThreshold;\n if (mode === \"hybrid\" && options.semanticWeight !== undefined) {\n filters.hybrid_semantic_weight = hybridSemanticWeight;\n }\n if (options.limit !== undefined) filters.limit = options.limit;\n if (runtimeFieldFilters && Object.keys(runtimeFieldFilters).length > 0) {\n filters.runtime_filters = runtimeFieldFilters;\n }\n return filters;\n}\n\n/** Builds the complete filter echo shared by verbose search response paths. */\nexport function buildVerboseSearchFilters(params: {\n effectiveMode: SearchMode;\n matchMode: SearchMatchMode;\n options: SearchOptions;\n includeLinked: boolean;\n titleExact: boolean;\n phraseExact: boolean;\n scoreThreshold: number;\n hybridSemanticWeight: number;\n queryExpansion: SearchRenderingQueryExpansion;\n rerank: SearchRenderingRerank;\n runtimeFieldFilters: Record<string, unknown>;\n}): Record<string, unknown> {\n const { effectiveMode, matchMode, options, includeLinked, titleExact, phraseExact, scoreThreshold, hybridSemanticWeight, queryExpansion, rerank, runtimeFieldFilters } = params;\n const valueOrNull = (value: unknown): unknown => value ?? null;\n return {\n mode: effectiveMode,\n match_mode: matchMode,\n status: isAllStatuses(options.status) ? \"all\" : valueOrNull(options.status),\n type: valueOrNull(options.type),\n tag: valueOrNull(options.tag),\n priority: valueOrNull(options.priority),\n deadline_before: valueOrNull(options.deadlineBefore),\n deadline_after: valueOrNull(options.deadlineAfter),\n updated_after: valueOrNull(options.updatedAfter),\n updated_before: valueOrNull(options.updatedBefore),\n created_after: valueOrNull(options.createdAfter),\n created_before: valueOrNull(options.createdBefore),\n assignee: valueOrNull(options.assignee),\n sprint: valueOrNull(options.sprint),\n release: valueOrNull(options.release),\n parent: valueOrNull(options.parent),\n ...buildGovernanceMissingFilterEcho(options as Record<string, unknown>),\n ...buildContentFilterEcho(options as Record<string, unknown>),\n include_linked: includeLinked,\n title_exact: titleExact,\n phrase_exact: phraseExact,\n score_threshold: scoreThreshold,\n hybrid_semantic_weight: effectiveMode === \"hybrid\" ? hybridSemanticWeight : null,\n query_expansion_enabled: queryExpansion.enabled,\n query_expansion_provider: queryExpansion.provider,\n rerank_enabled: rerank.enabled,\n rerank_model: rerank.model,\n rerank_top_k: rerank.top_k,\n limit: valueOrNull(options.limit),\n runtime_filters: runtimeFieldFilters,\n };\n}\n","/**\n * @module sdk/query/search-pagination\n *\n * Applies the shared SDK cursor contract to ranked search results.\n */\nimport {\n createQueryFingerprint,\n paginateQueryRows,\n} from \"../pagination.js\";\nimport type { SearchHit, SearchOptions } from \"./search.js\";\nimport type { SearchMode } from \"./search-rendering.js\";\n\n/** Build the query-only fingerprint shared by search retrieval and paging. */\nexport function createSearchCursorFingerprint(options: {\n query: string;\n mode: SearchMode;\n searchOptions: SearchOptions;\n}): string {\n const normalizedOptions: Record<string, unknown> = {\n ...options.searchOptions,\n };\n delete normalizedOptions.after;\n delete normalizedOptions.limit;\n delete normalizedOptions.compact;\n delete normalizedOptions.full;\n delete normalizedOptions.fields;\n delete normalizedOptions.highlight;\n delete normalizedOptions.format;\n return createQueryFingerprint(\"search\", {\n query: options.query.trim(),\n mode: options.mode,\n options: normalizedOptions,\n });\n}\n\n/** Page ranked search hits without coupling cursor mechanics to search scoring. */\nexport function resolveSearchPage(options: {\n sorted: SearchHit[];\n query: string;\n mode: SearchMode;\n searchOptions: SearchOptions;\n limit: number;\n}): {\n limited: SearchHit[];\n pageExtras: {\n has_more?: boolean;\n next_cursor?: string;\n applied_limit: number;\n truncated?: true;\n };\n} {\n const page = paginateQueryRows(options.sorted, {\n cursor: options.searchOptions.after,\n fingerprint: createSearchCursorFingerprint(options),\n limit: options.limit,\n readId: (hit) => hit.item.id,\n });\n return {\n limited: page.rows,\n pageExtras: {\n applied_limit: options.limit,\n ...(page.has_more ? { has_more: true, truncated: true } : {}),\n ...(page.next_cursor ? { next_cursor: page.next_cursor } : {}),\n },\n };\n}\n","/**\n * @module sdk/eval\n *\n * Implements the `pm eval` command surface (pm-u8n5): a search-relevance\n * evaluation runner that scores a human-curated golden-query set against the\n * live retrieval path and reports nDCG@k, MRR@k, precision@k, and recall@k per\n * query plus the macro average. With `--fail-under` it doubles as a CI gate so\n * relevance regressions — from corpus changes, hybrid-weight changes, or\n * provider swaps (including the offline BM25 provider, pm-75k9) — fail the build\n * instead of silently degrading retrieval quality.\n */\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n aggregateEvalMetrics,\n DEFAULT_EVAL_K,\n evaluateRanking,\n parseEvalQuerySet,\n type EvalSearchMode,\n type QueryEvalMetrics,\n} from \"../core/search/eval.js\";\nimport { EXIT_CODE } from \"../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../core/shared/command-types.js\";\nimport { PmCliError } from \"../core/shared/errors.js\";\nimport { coercePositiveInteger } from \"../core/shared/primitives.js\";\nimport { pathExists } from \"../core/fs/fs-utils.js\";\nimport { getSettingsPath, resolvePmRoot } from \"../core/store/paths.js\";\nimport { runSearch } from \"./query/search.js\";\n\n/** Relative location (under the pm root) of the default golden-query set. A git-tracked, human-curated file so relevance ground truth lives alongside the tracker it evaluates. */\nexport const DEFAULT_EVAL_QUERIES_RELATIVE_PATH = path.join(\n \"search\",\n \"eval-queries.json\",\n);\n\n/** Documents the eval command options payload exchanged by command, SDK, and package integrations. */\nexport interface EvalOptions {\n /** Default retrieval mode for queries that do not set their own (keyword|semantic|hybrid). */\n mode?: string;\n /** Metric cutoff (`@k`); positive integer, defaults to {@link DEFAULT_EVAL_K}. */\n k?: string | number;\n /** Gate threshold: exit non-zero when the aggregate nDCG@k falls below this `[0,1]` value. */\n failUnder?: string | number;\n /** Override path to the golden-query JSON file (defaults to `<pmRoot>/search/eval-queries.json`). */\n queries?: string;\n /** Output format override: json|toon. */\n format?: string;\n}\n\n/** Per-query relevance report row emitted by {@link runEval}. */\nexport interface EvalQueryReport {\n /** Value that configures or reports query for this contract. */\n query: string;\n /** Value that configures or reports mode for this contract. */\n mode: EvalSearchMode;\n /** Value that configures or reports relevant total for this contract. */\n relevant_total: number;\n /** Value that configures or reports retrieved relevant for this contract. */\n retrieved_relevant: number;\n /** Value that configures or reports ndcg for this contract. */\n ndcg: number;\n /** Value that configures or reports mrr for this contract. */\n mrr: number;\n /** Value that configures or reports precision for this contract. */\n precision: number;\n /** Value that configures or reports recall for this contract. */\n recall: number;\n}\n\n/** Documents the eval result payload exchanged by command, SDK, and package integrations. */\nexport interface EvalResult {\n /** Value that configures or reports k for this contract. */\n k: number;\n /** Number of query entries represented by this result. */\n query_count: number;\n /** Value that configures or reports aggregate for this contract. */\n aggregate: {\n ndcg: number;\n mrr: number;\n precision: number;\n recall: number;\n };\n /** Value that configures or reports queries for this contract. */\n queries: EvalQueryReport[];\n /** Present only when `--fail-under` was supplied. */\n fail_under?: number;\n /** Whether the aggregate nDCG met the gate (always true when no gate is set). */\n passed: boolean;\n}\n\nconst VALID_EVAL_MODES: ReadonlySet<string> = new Set<EvalSearchMode>([\n \"keyword\",\n \"semantic\",\n \"hybrid\",\n]);\n\ntype EvalQuery = ReturnType<typeof parseEvalQuerySet>[\"queries\"][number];\n\n/** Resolves and validates the default retrieval mode for an evaluation run. */\nconst parseEvalMode = (raw: string | undefined): EvalSearchMode => {\n if (raw === undefined) {\n return \"keyword\";\n }\n const normalized = raw.trim().toLowerCase();\n if (!VALID_EVAL_MODES.has(normalized)) {\n throw new PmCliError(\n \"Eval --mode must be one of keyword|semantic|hybrid\",\n EXIT_CODE.USAGE,\n );\n }\n return normalized as EvalSearchMode;\n};\n\n/** Resolves and validates the positive ranking cutoff for an evaluation run. */\nconst parseEvalK = (raw: string | number | undefined): number => {\n if (raw === undefined || raw === \"\") {\n return DEFAULT_EVAL_K;\n }\n const parsed = coercePositiveInteger(raw);\n if (parsed === null) {\n throw new PmCliError(\n \"Eval --k must be a positive integer\",\n EXIT_CODE.USAGE,\n );\n }\n return parsed;\n};\n\n/** Resolves and validates an optional normalized nDCG gate threshold. */\nconst parseFailUnder = (\n raw: string | number | undefined,\n): number | undefined => {\n if (raw === undefined || raw === \"\") {\n return undefined;\n }\n const normalized = String(raw).trim();\n const parsed = Number(normalized);\n if (\n [\n normalized.length === 0,\n !Number.isFinite(parsed),\n parsed < 0,\n parsed > 1,\n ].includes(true)\n ) {\n throw new PmCliError(\n \"Eval --fail-under must be a number in the range [0, 1]\",\n EXIT_CODE.USAGE,\n );\n }\n return parsed;\n};\n\n/** Round a metric to four decimals to keep the JSON output compact and stable. */\nconst roundMetric = (value: number): number =>\n Math.round(value * 10_000) / 10_000;\n\n/** Reads a golden-query file and translates missing-file failures to CLI guidance. */\nconst readEvalQuerySetFile = async (queriesPath: string): Promise<string> => {\n try {\n return await fs.readFile(queriesPath, \"utf8\");\n } catch {\n throw new PmCliError(\n `Eval query set not found at ${queriesPath}`,\n EXIT_CODE.NOT_FOUND,\n {\n examples: [\n `echo '[{\"query\":\"offline search\",\"relevant_ids\":[\"pm-75k9\"]}]' > ${queriesPath}`,\n \"pm eval --queries ./my-eval.json\",\n ],\n nextSteps: [\n \"Create a git-tracked golden-query JSON file (an array of {query, relevant_ids, mode?} objects), then re-run pm eval.\",\n ],\n },\n );\n }\n};\n\n/** Parses golden-query JSON while preserving a path-specific usage diagnostic. */\nconst parseEvalQuerySetJson = (raw: string, queriesPath: string): unknown => {\n try {\n return JSON.parse(raw);\n } catch (error: unknown) {\n throw new PmCliError(\n /* c8 ignore next -- JSON.parse throws Error instances; String fallback protects nonstandard hosts. */\n `Eval query set at ${queriesPath} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,\n EXIT_CODE.USAGE,\n );\n }\n};\n\n/** Applies the structured golden-query contract and preserves its diagnostics. */\nconst validateEvalQuerySet = (\n parsed: unknown,\n): ReturnType<typeof parseEvalQuerySet> => {\n try {\n return parseEvalQuerySet(parsed);\n } catch (error: unknown) {\n throw new PmCliError(\n /* c8 ignore next -- parseEvalQuerySet throws Error instances; String fallback protects nonstandard hosts. */\n error instanceof Error ? error.message : String(error),\n EXIT_CODE.USAGE,\n );\n }\n};\n\n/** Loads and validates a golden-query set from one resolved filesystem path. */\nconst loadEvalQuerySet = async (\n queriesPath: string,\n): Promise<ReturnType<typeof parseEvalQuerySet>> =>\n validateEvalQuerySet(\n parseEvalQuerySetJson(await readEvalQuerySetFile(queriesPath), queriesPath),\n );\n\n/** Resolves the caller override or tracker-owned default golden-query path. */\nconst resolveEvalQueriesPath = (\n pmRoot: string,\n queries: string | undefined,\n): string =>\n queries\n ? path.resolve(process.cwd(), queries)\n : path.join(pmRoot, DEFAULT_EVAL_QUERIES_RELATIVE_PATH);\n\n/** Executes and scores one golden query without rounding its aggregate input. */\nconst evaluateEvalQuery = async (\n evalQuery: EvalQuery,\n defaultMode: EvalSearchMode,\n k: number,\n global: GlobalOptions,\n): Promise<{ report: EvalQueryReport; metrics: QueryEvalMetrics }> => {\n const mode = evalQuery.mode ?? defaultMode;\n const searchResult = await runSearch(\n evalQuery.query,\n { mode, limit: String(k), fields: \"id\" },\n global,\n );\n const rankedIds = searchResult.items\n .map((item) => (item as { id?: unknown }).id)\n .filter((id): id is string => typeof id === \"string\");\n const metrics = evaluateRanking(\n rankedIds,\n new Set(evalQuery.relevant_ids),\n k,\n );\n return {\n metrics,\n report: {\n query: evalQuery.query,\n mode,\n relevant_total: metrics.relevant_total,\n retrieved_relevant: metrics.retrieved_relevant,\n ndcg: roundMetric(metrics.ndcg),\n mrr: roundMetric(metrics.mrr),\n precision: roundMetric(metrics.precision),\n recall: roundMetric(metrics.recall),\n },\n };\n};\n\n/** Shapes rounded aggregate metrics and the optional gate result. */\nconst buildEvalResult = (\n k: number,\n reports: EvalQueryReport[],\n rawMetrics: QueryEvalMetrics[],\n failUnder: number | undefined,\n): EvalResult => {\n const aggregate = aggregateEvalMetrics(rawMetrics);\n return {\n k,\n query_count: reports.length,\n aggregate: {\n ndcg: roundMetric(aggregate.ndcg),\n mrr: roundMetric(aggregate.mrr),\n precision: roundMetric(aggregate.precision),\n recall: roundMetric(aggregate.recall),\n },\n queries: reports,\n ...(failUnder !== undefined ? { fail_under: failUnder } : {}),\n passed: failUnder === undefined || aggregate.ndcg >= failUnder,\n };\n};\n\n/**\n * Run the search-relevance evaluation (pm-u8n5). Loads the golden-query set\n * (default `<pmRoot>/search/eval-queries.json`, overridable via `--queries`),\n * runs each query through {@link runSearch} at the resolved mode, scores the\n * returned ranking with the nDCG/MRR/precision/recall metrics, and macro-averages\n * across queries. When `--fail-under` is supplied, `passed` reflects whether the\n * aggregate nDCG@k cleared the threshold; the CLI layer maps a failed gate to a\n * non-zero exit code.\n */\nexport const runEval = async (\n options: EvalOptions,\n global: GlobalOptions,\n): Promise<EvalResult> => {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(\n `Tracker is not initialized at ${pmRoot}. Run pm init first.`,\n EXIT_CODE.NOT_FOUND,\n );\n }\n const k = parseEvalK(options.k);\n const defaultMode = parseEvalMode(options.mode);\n const failUnder = parseFailUnder(options.failUnder);\n const queriesPath = resolveEvalQueriesPath(pmRoot, options.queries);\n const querySet = await loadEvalQuerySet(queriesPath);\n\n const reports: EvalQueryReport[] = [];\n // Aggregate and gate on the UNROUNDED metrics; rounding is applied only to the\n // emitted report values so display precision never flips a --fail-under decision.\n const rawMetrics: QueryEvalMetrics[] = [];\n for (const evalQuery of querySet.queries) {\n const { report, metrics } = await evaluateEvalQuery(\n evalQuery,\n defaultMode,\n k,\n global,\n );\n rawMetrics.push(metrics);\n reports.push(report);\n }\n return buildEvalResult(k, reports, rawMetrics, failUnder);\n};\n","/**\n * @module core/search/eval\n *\n * Search relevance evaluation primitives (pm-u8n5). Implements the standard\n * offline ranking metrics — nDCG@k, MRR@k, precision@k, recall@k — over a\n * human-curated golden-query set, plus the loader/validator for that set. The\n * `pm eval` command (src/cli/commands/eval.ts) runs each golden query through\n * the live retrieval path and feeds the ranked ids here, so relevance\n * regressions from corpus changes, hybrid-weight changes, or provider swaps are\n * measurable and gateable in CI.\n *\n * Relevance is binary: an id is either in a query's `relevant_ids` set or it is\n * not. This keeps the golden set cheap to curate while still supporting the\n * graded-discount behavior of DCG (earlier hits are worth more).\n */\n\n/** Retrieval mode a golden query is evaluated under. Mirrors the `pm search` mode surface; omitting it on a query defers to the eval run's default mode. */\nexport type EvalSearchMode = \"keyword\" | \"semantic\" | \"hybrid\";\n\n/** Default cutoff (`@k`) used for every metric when the caller does not override it. */\nexport const DEFAULT_EVAL_K = 10;\n\n/** One curated golden query: the query text, the set of item ids considered relevant, an optional per-query retrieval mode override, and an optional human-readable description of the relevance intent. */\nexport interface EvalQuery {\n /** Value that configures or reports query for this contract. */\n query: string;\n /** Value that configures or reports relevant ids for this contract. */\n relevant_ids: string[];\n /** Value that configures or reports mode for this contract. */\n mode?: EvalSearchMode;\n /** Value that configures or reports description for this contract. */\n description?: string;\n}\n\n/** A parsed, validated golden-query set. */\nexport interface EvalQuerySet {\n /** Value that configures or reports queries for this contract. */\n queries: EvalQuery[];\n}\n\n/**\n * Thrown by {@link parseEvalQuerySet} when the raw golden-query payload is\n * structurally invalid. Carries a precise, human-actionable message naming the\n * offending query index/field so an author can fix the JSON directly.\n */\nexport class EvalQuerySetError extends Error {\n /** Construct an error describing why a golden-query set failed validation. */\n constructor(message: string) {\n super(message);\n this.name = \"EvalQuerySetError\";\n }\n}\n\nconst VALID_EVAL_MODES: ReadonlySet<string> = new Set<EvalSearchMode>([\n \"keyword\",\n \"semantic\",\n \"hybrid\",\n]);\n\n/** Compute Discounted Cumulative Gain at cutoff `k` for an ordered list of binary relevance gains (`1` relevant, `0` not). Position `i` (1-based) contributes `gain / log2(i + 1)`, so a relevant hit ranked first is worth `1` and later hits are progressively discounted. Gains beyond `k` are ignored. */\nexport function dcgAtK(relevanceGains: number[], k: number): number {\n let dcg = 0;\n const limit = Math.min(k, relevanceGains.length);\n for (let index = 0; index < limit; index += 1) {\n dcg += relevanceGains[index] / Math.log2(index + 2);\n }\n return dcg;\n}\n\n/** Normalized DCG at cutoff `k`: the ranking's DCG divided by the DCG of the ideal ranking (all relevant ids first). Returns `0` when the query has no relevant ids (the ideal DCG is `0` and the score is undefined), giving a stable lower bound for aggregation. Result is in `[0, 1]`. */\nexport function ndcgAtK(\n rankedIds: string[],\n relevantIds: ReadonlySet<string>,\n k: number,\n): number {\n if (relevantIds.size === 0) {\n return 0;\n }\n const gains = rankedIds.map((id) => (relevantIds.has(id) ? 1 : 0));\n const dcg = dcgAtK(gains, k);\n const idealGains = Array.from({ length: relevantIds.size }, () => 1);\n const idealDcg = dcgAtK(idealGains, k);\n return idealDcg === 0 ? 0 : dcg / idealDcg;\n}\n\n/**\n * Reciprocal rank of the first relevant id within the top `k` results: `1/rank`\n * (rank is 1-based), or `0` when no relevant id appears in the cutoff. Averaged\n * across queries this is Mean Reciprocal Rank (MRR@k).\n */\nexport function reciprocalRankAtK(\n rankedIds: string[],\n relevantIds: ReadonlySet<string>,\n k: number,\n): number {\n const limit = Math.min(k, rankedIds.length);\n for (let index = 0; index < limit; index += 1) {\n if (relevantIds.has(rankedIds[index])) {\n return 1 / (index + 1);\n }\n }\n return 0;\n}\n\n/** Count relevant ids within the top `k` results (shared by precision and recall). */\nfunction countRelevantInTopK(\n rankedIds: string[],\n relevantIds: ReadonlySet<string>,\n k: number,\n): number {\n const limit = Math.min(k, rankedIds.length);\n let hits = 0;\n for (let index = 0; index < limit; index += 1) {\n if (relevantIds.has(rankedIds[index])) {\n hits += 1;\n }\n }\n return hits;\n}\n\n/** Precision at cutoff `k`: relevant ids retrieved in the top `k` divided by `k`. Returns `0` for a non-positive `k`. */\nexport function precisionAtK(\n rankedIds: string[],\n relevantIds: ReadonlySet<string>,\n k: number,\n): number {\n if (k <= 0) {\n return 0;\n }\n return countRelevantInTopK(rankedIds, relevantIds, k) / k;\n}\n\n/** Recall at cutoff `k`: relevant ids retrieved in the top `k` divided by the total number of relevant ids. Returns `0` when the query has no relevant ids. */\nexport function recallAtK(\n rankedIds: string[],\n relevantIds: ReadonlySet<string>,\n k: number,\n): number {\n if (relevantIds.size === 0) {\n return 0;\n }\n return countRelevantInTopK(rankedIds, relevantIds, k) / relevantIds.size;\n}\n\n/** The four ranking metrics computed for a single query, plus match counts. */\nexport interface QueryEvalMetrics {\n /** Value that configures or reports ndcg for this contract. */\n ndcg: number;\n /** Value that configures or reports mrr for this contract. */\n mrr: number;\n /** Value that configures or reports precision for this contract. */\n precision: number;\n /** Value that configures or reports recall for this contract. */\n recall: number;\n /** Value that configures or reports relevant total for this contract. */\n relevant_total: number;\n /** Value that configures or reports retrieved relevant for this contract. */\n retrieved_relevant: number;\n}\n\n/** Evaluate one ranking against its relevant-id set at cutoff `k`, returning all four metrics together so callers compute the document ranking once and read every score off the result. */\nexport function evaluateRanking(\n rankedIds: string[],\n relevantIds: ReadonlySet<string>,\n k: number,\n): QueryEvalMetrics {\n return {\n ndcg: ndcgAtK(rankedIds, relevantIds, k),\n mrr: reciprocalRankAtK(rankedIds, relevantIds, k),\n precision: precisionAtK(rankedIds, relevantIds, k),\n recall: recallAtK(rankedIds, relevantIds, k),\n relevant_total: relevantIds.size,\n retrieved_relevant: countRelevantInTopK(rankedIds, relevantIds, k),\n };\n}\n\n/** Macro-averaged metrics across all evaluated queries. */\nexport interface AggregateEvalMetrics {\n /** Value that configures or reports ndcg for this contract. */\n ndcg: number;\n /** Value that configures or reports mrr for this contract. */\n mrr: number;\n /** Value that configures or reports precision for this contract. */\n precision: number;\n /** Value that configures or reports recall for this contract. */\n recall: number;\n /** Number of query entries represented by this result. */\n query_count: number;\n}\n\n/** Macro-average per-query metrics (each query weighted equally). Returns all zeros with `query_count: 0` for an empty input so the gate path has a stable shape to compare against. */\nexport function aggregateEvalMetrics(\n perQuery: QueryEvalMetrics[],\n): AggregateEvalMetrics {\n const queryCount = perQuery.length;\n if (queryCount === 0) {\n return { ndcg: 0, mrr: 0, precision: 0, recall: 0, query_count: 0 };\n }\n const sum = perQuery.reduce(\n (accumulator, metrics) => ({\n ndcg: accumulator.ndcg + metrics.ndcg,\n mrr: accumulator.mrr + metrics.mrr,\n precision: accumulator.precision + metrics.precision,\n recall: accumulator.recall + metrics.recall,\n }),\n { ndcg: 0, mrr: 0, precision: 0, recall: 0 },\n );\n return {\n ndcg: sum.ndcg / queryCount,\n mrr: sum.mrr / queryCount,\n precision: sum.precision / queryCount,\n recall: sum.recall / queryCount,\n query_count: queryCount,\n };\n}\n\n/**\n * Validate one raw golden-query entry, returning a typed {@link EvalQuery}.\n * Throws {@link EvalQuerySetError} (with the entry index) for a missing/empty\n * `query`, a `relevant_ids` that is not a non-empty string array, or an invalid\n * `mode`. `relevant_ids` are trimmed and de-duplicated; `description` is kept\n * only when it is a non-empty string.\n */\nfunction parseEvalQueryEntry(raw: unknown, index: number): EvalQuery {\n if (typeof raw !== \"object\" || raw === null) {\n throw new EvalQuerySetError(\n `Eval query at index ${index} must be an object`,\n );\n }\n const entry = raw as {\n query?: unknown;\n relevant_ids?: unknown;\n mode?: unknown;\n description?: unknown;\n };\n const query = typeof entry.query === \"string\" ? entry.query.trim() : \"\";\n if (query.length === 0) {\n throw new EvalQuerySetError(\n `Eval query at index ${index} must have a non-empty \"query\" string`,\n );\n }\n if (!Array.isArray(entry.relevant_ids)) {\n throw new EvalQuerySetError(\n `Eval query at index ${index} must have a \"relevant_ids\" array`,\n );\n }\n if (entry.relevant_ids.some((value) => typeof value !== \"string\")) {\n // Reject (rather than silently drop) non-string members: malformed golden\n // data must fail loudly so it can never quietly change relevance judgments.\n throw new EvalQuerySetError(\n `Eval query at index ${index} must have a \"relevant_ids\" array of strings`,\n );\n }\n const relevantIds = [\n ...new Set(\n (entry.relevant_ids as string[])\n .map((value) => value.trim())\n .filter((value) => value.length > 0),\n ),\n ];\n if (relevantIds.length === 0) {\n throw new EvalQuerySetError(\n `Eval query at index ${index} must list at least one relevant id`,\n );\n }\n if (\n entry.mode !== undefined &&\n (typeof entry.mode !== \"string\" || !VALID_EVAL_MODES.has(entry.mode))\n ) {\n throw new EvalQuerySetError(\n `Eval query at index ${index} has an invalid mode (expected keyword|semantic|hybrid)`,\n );\n }\n return {\n query,\n relevant_ids: relevantIds,\n ...(entry.mode !== undefined ? { mode: entry.mode as EvalSearchMode } : {}),\n ...(typeof entry.description === \"string\" &&\n entry.description.trim().length > 0\n ? { description: entry.description.trim() }\n : {}),\n };\n}\n\n/**\n * Parse and validate a raw golden-query payload (typically `JSON.parse` of\n * `.agents/pm/search/eval-queries.json`). Accepts either a bare array of query\n * entries or an object with a `queries` array. Throws {@link EvalQuerySetError}\n * with a precise message when the payload is not an array/object, when\n * `queries` is missing/not an array, when the set is empty, or when any entry\n * fails {@link parseEvalQueryEntry}.\n */\nexport function parseEvalQuerySet(raw: unknown): EvalQuerySet {\n const rawQueries = Array.isArray(raw)\n ? raw\n : typeof raw === \"object\" && raw !== null\n ? (raw as { queries?: unknown }).queries\n : undefined;\n if (!Array.isArray(rawQueries)) {\n throw new EvalQuerySetError(\n 'Eval query set must be an array of queries or an object with a \"queries\" array',\n );\n }\n if (rawQueries.length === 0) {\n throw new EvalQuerySetError(\n \"Eval query set must contain at least one query\",\n );\n }\n return {\n queries: rawQueries.map((entry, index) =>\n parseEvalQueryEntry(entry, index),\n ),\n };\n}\n"],"names":["path","path","path","path","itemRecord","fs","path","path","VALID_EVAL_MODES","fs"],"mappings":"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","debugId":"407ff97b-d1b6-5af5-861a-080b97f250be"}