@unbrained/pm-cli 2026.6.24 → 2026.7.1

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 (744) hide show
  1. package/AGENTS.md +2 -0
  2. package/CHANGELOG.md +113 -1
  3. package/CONTRIBUTING.md +30 -0
  4. package/README.md +16 -3
  5. package/dist/cli/bootstrap-args.js +89 -79
  6. package/dist/cli/bootstrap-args.js.map +1 -1
  7. package/dist/cli/commander-usage.js +3 -3
  8. package/dist/cli/commander-usage.js.map +1 -1
  9. package/dist/cli/commands/aggregate.js +8 -7
  10. package/dist/cli/commands/aggregate.js.map +1 -1
  11. package/dist/cli/commands/calendar.js +63 -62
  12. package/dist/cli/commands/calendar.js.map +1 -1
  13. package/dist/cli/commands/close.d.ts +2 -4
  14. package/dist/cli/commands/close.js +5 -17
  15. package/dist/cli/commands/close.js.map +1 -1
  16. package/dist/cli/commands/completion.js +158 -9
  17. package/dist/cli/commands/completion.js.map +1 -1
  18. package/dist/cli/commands/config.d.ts +1 -1
  19. package/dist/cli/commands/config.js +2 -2
  20. package/dist/cli/commands/config.js.map +1 -1
  21. package/dist/cli/commands/context.d.ts +31 -4
  22. package/dist/cli/commands/context.js +33 -10
  23. package/dist/cli/commands/context.js.map +1 -1
  24. package/dist/cli/commands/contracts.js +48 -8
  25. package/dist/cli/commands/contracts.js.map +1 -1
  26. package/dist/cli/commands/create.d.ts +1 -6
  27. package/dist/cli/commands/create.js +491 -587
  28. package/dist/cli/commands/create.js.map +1 -1
  29. package/dist/cli/commands/extension/bundled-catalog.js +59 -46
  30. package/dist/cli/commands/extension/bundled-catalog.js.map +1 -1
  31. package/dist/cli/commands/extension/describe.d.ts +15 -0
  32. package/dist/cli/commands/extension/describe.js +48 -2
  33. package/dist/cli/commands/extension/describe.js.map +1 -1
  34. package/dist/cli/commands/extension/doctor.js +129 -75
  35. package/dist/cli/commands/extension/doctor.js.map +1 -1
  36. package/dist/cli/commands/extension/install-sources.js +37 -7
  37. package/dist/cli/commands/extension/install-sources.js.map +1 -1
  38. package/dist/cli/commands/extension/managed-state.js +101 -57
  39. package/dist/cli/commands/extension/managed-state.js.map +1 -1
  40. package/dist/cli/commands/extension/scaffold.d.ts +38 -8
  41. package/dist/cli/commands/extension/scaffold.js +1956 -242
  42. package/dist/cli/commands/extension/scaffold.js.map +1 -1
  43. package/dist/cli/commands/extension.d.ts +28 -3
  44. package/dist/cli/commands/extension.js +1181 -880
  45. package/dist/cli/commands/extension.js.map +1 -1
  46. package/dist/cli/commands/index.d.ts +3 -1
  47. package/dist/cli/commands/index.js +5 -3
  48. package/dist/cli/commands/index.js.map +1 -1
  49. package/dist/cli/commands/item-filter-options.d.ts +63 -0
  50. package/dist/cli/commands/item-filter-options.js +10 -0
  51. package/dist/cli/commands/item-filter-options.js.map +1 -0
  52. package/dist/cli/commands/legacy-none-tokens.d.ts +14 -0
  53. package/dist/cli/commands/legacy-none-tokens.js +31 -2
  54. package/dist/cli/commands/legacy-none-tokens.js.map +1 -1
  55. package/dist/cli/commands/linked-artifacts.d.ts +7 -0
  56. package/dist/cli/commands/linked-artifacts.js +12 -2
  57. package/dist/cli/commands/linked-artifacts.js.map +1 -1
  58. package/dist/cli/commands/list-filter-shared.js +55 -48
  59. package/dist/cli/commands/list-filter-shared.js.map +1 -1
  60. package/dist/cli/commands/list.d.ts +16 -39
  61. package/dist/cli/commands/list.js +127 -118
  62. package/dist/cli/commands/list.js.map +1 -1
  63. package/dist/cli/commands/next.d.ts +98 -0
  64. package/dist/cli/commands/next.js +304 -0
  65. package/dist/cli/commands/next.js.map +1 -0
  66. package/dist/cli/commands/profile.d.ts +208 -0
  67. package/dist/cli/commands/profile.js +418 -0
  68. package/dist/cli/commands/profile.js.map +1 -0
  69. package/dist/cli/commands/repeatable-metadata-parsers.js +12 -13
  70. package/dist/cli/commands/repeatable-metadata-parsers.js.map +1 -1
  71. package/dist/cli/commands/schema.d.ts +7 -0
  72. package/dist/cli/commands/schema.js +9 -3
  73. package/dist/cli/commands/schema.js.map +1 -1
  74. package/dist/cli/commands/search.d.ts +2 -39
  75. package/dist/cli/commands/search.js +196 -172
  76. package/dist/cli/commands/search.js.map +1 -1
  77. package/dist/cli/commands/shared-unset-fields.d.ts +30 -0
  78. package/dist/cli/commands/shared-unset-fields.js +161 -0
  79. package/dist/cli/commands/shared-unset-fields.js.map +1 -0
  80. package/dist/cli/commands/stats.js +15 -3
  81. package/dist/cli/commands/stats.js.map +1 -1
  82. package/dist/cli/commands/test.js +115 -125
  83. package/dist/cli/commands/test.js.map +1 -1
  84. package/dist/cli/commands/update.d.ts +1 -6
  85. package/dist/cli/commands/update.js +37 -232
  86. package/dist/cli/commands/update.js.map +1 -1
  87. package/dist/cli/commands/validate.js +20 -5
  88. package/dist/cli/commands/validate.js.map +1 -1
  89. package/dist/cli/extension-command-options.js +48 -21
  90. package/dist/cli/extension-command-options.js.map +1 -1
  91. package/dist/cli/help-content.js +26 -2
  92. package/dist/cli/help-content.js.map +1 -1
  93. package/dist/cli/help-json-payload.js +3 -3
  94. package/dist/cli/help-json-payload.js.map +1 -1
  95. package/dist/cli/main.js +27 -12
  96. package/dist/cli/main.js.map +1 -1
  97. package/dist/cli/register-list-query.js +42 -3
  98. package/dist/cli/register-list-query.js.map +1 -1
  99. package/dist/cli/register-mutation.js +86 -2
  100. package/dist/cli/register-mutation.js.map +1 -1
  101. package/dist/cli/register-setup.js +67 -6
  102. package/dist/cli/register-setup.js.map +1 -1
  103. package/dist/cli/registration-helpers.d.ts +9 -1
  104. package/dist/cli/registration-helpers.js +149 -123
  105. package/dist/cli/registration-helpers.js.map +1 -1
  106. package/dist/cli-bundle/chunks/activity-AW6XVFH6.js +16 -0
  107. package/dist/cli-bundle/chunks/{activity-N7RVTLBQ.js → activity-DBLQVIP6.js} +9 -11
  108. package/dist/cli-bundle/chunks/{aggregate-63NWNIBR.js → aggregate-JTEF4BP7.js} +17 -18
  109. package/dist/cli-bundle/chunks/aggregate-JTEF4BP7.js.map +1 -0
  110. package/dist/cli-bundle/chunks/{aggregate-YHCYX2EV.js → aggregate-SDF7DUOD.js} +16 -17
  111. package/dist/cli-bundle/chunks/aggregate-SDF7DUOD.js.map +7 -0
  112. package/dist/cli-bundle/chunks/{append-VLQQDHMJ.js → append-LOVPGVPT.js} +8 -10
  113. package/dist/cli-bundle/chunks/{append-VLQQDHMJ.js.map → append-LOVPGVPT.js.map} +1 -1
  114. package/dist/cli-bundle/chunks/{append-PUKREFV5.js → append-QCFJSDFL.js} +10 -12
  115. package/dist/cli-bundle/chunks/{append-PUKREFV5.js.map → append-QCFJSDFL.js.map} +1 -1
  116. package/dist/cli-bundle/chunks/{chunk-ABYCA5VX.js → chunk-22WKIL3H.js} +9 -11
  117. package/dist/cli-bundle/chunks/{chunk-ABYCA5VX.js.map → chunk-22WKIL3H.js.map} +1 -1
  118. package/dist/cli-bundle/chunks/{chunk-A66VYUOV.js → chunk-2466X6E4.js} +9 -11
  119. package/dist/cli-bundle/chunks/{chunk-A66VYUOV.js.map → chunk-2466X6E4.js.map} +1 -1
  120. package/dist/cli-bundle/chunks/{chunk-F32L4HR6.js → chunk-27BXPBAY.js} +3 -3
  121. package/dist/cli-bundle/chunks/{schema-QO5I4FBL.js → chunk-2D4HATP2.js} +136 -66
  122. package/dist/cli-bundle/chunks/chunk-2D4HATP2.js.map +1 -0
  123. package/dist/cli-bundle/chunks/{chunk-J7I4C5ZB.js → chunk-3J6JRJ3I.js} +153 -125
  124. package/dist/cli-bundle/chunks/chunk-3J6JRJ3I.js.map +7 -0
  125. package/dist/cli-bundle/chunks/{chunk-OHDQNKJB.js → chunk-3K2M5OYU.js} +106 -34
  126. package/dist/cli-bundle/chunks/chunk-3K2M5OYU.js.map +7 -0
  127. package/dist/cli-bundle/chunks/{chunk-XVYKWZNL.js → chunk-3S2KT7NG.js} +127 -127
  128. package/dist/cli-bundle/chunks/chunk-3S2KT7NG.js.map +7 -0
  129. package/dist/cli-bundle/chunks/{chunk-5BBEWX6C.js → chunk-3VGN2UWE.js} +2 -2
  130. package/dist/cli-bundle/chunks/{chunk-N5B6WZC5.js → chunk-3XZCOZ5J.js} +115 -123
  131. package/dist/cli-bundle/chunks/chunk-3XZCOZ5J.js.map +1 -0
  132. package/dist/cli-bundle/chunks/chunk-4A3BJ675.js +799 -0
  133. package/dist/cli-bundle/chunks/chunk-4A3BJ675.js.map +1 -0
  134. package/dist/cli-bundle/chunks/chunk-4BU75MF4.js +87 -0
  135. package/dist/cli-bundle/chunks/chunk-4BU75MF4.js.map +7 -0
  136. package/dist/cli-bundle/chunks/{chunk-HZF5RLKX.js → chunk-4DSGXSBL.js} +5 -7
  137. package/dist/cli-bundle/chunks/{chunk-HZF5RLKX.js.map → chunk-4DSGXSBL.js.map} +1 -1
  138. package/dist/cli-bundle/chunks/{chunk-JV27C7OZ.js → chunk-4DUVCVLZ.js} +4 -6
  139. package/dist/cli-bundle/chunks/{chunk-JV27C7OZ.js.map → chunk-4DUVCVLZ.js.map} +1 -1
  140. package/dist/cli-bundle/chunks/{chunk-IAP5KYBQ.js → chunk-4XOIEKSD.js} +563 -506
  141. package/dist/cli-bundle/chunks/chunk-4XOIEKSD.js.map +1 -0
  142. package/dist/cli-bundle/chunks/{context-5LB7UGKE.js → chunk-55SNVXRQ.js} +79 -82
  143. package/dist/cli-bundle/chunks/chunk-55SNVXRQ.js.map +7 -0
  144. package/dist/cli-bundle/chunks/{chunk-BFFO3AIB.js → chunk-5CGRF3L5.js} +128 -128
  145. package/dist/cli-bundle/chunks/chunk-5CGRF3L5.js.map +1 -0
  146. package/dist/cli-bundle/chunks/{chunk-JKL6HRMV.js → chunk-5QFDBI4F.js} +1260 -1046
  147. package/dist/cli-bundle/chunks/chunk-5QFDBI4F.js.map +7 -0
  148. package/dist/cli-bundle/chunks/{chunk-LU36E6GU.js → chunk-64HNBBFQ.js} +8 -12
  149. package/dist/cli-bundle/chunks/{chunk-LU36E6GU.js.map → chunk-64HNBBFQ.js.map} +1 -1
  150. package/dist/cli-bundle/chunks/chunk-6AQZPVHQ.js +2444 -0
  151. package/dist/cli-bundle/chunks/chunk-6AQZPVHQ.js.map +1 -0
  152. package/dist/cli-bundle/chunks/chunk-7M2HAZEB.js +17 -0
  153. package/dist/cli-bundle/chunks/chunk-7M2HAZEB.js.map +7 -0
  154. package/dist/cli-bundle/chunks/{chunk-VSAABFGQ.js → chunk-7R4QEMZZ.js} +1490 -734
  155. package/dist/cli-bundle/chunks/chunk-7R4QEMZZ.js.map +1 -0
  156. package/dist/cli-bundle/chunks/{chunk-M6TUBOGW.js → chunk-A7FPBAQS.js} +19 -12
  157. package/dist/cli-bundle/chunks/chunk-A7FPBAQS.js.map +1 -0
  158. package/dist/cli-bundle/chunks/{chunk-GQYJEEFX.js → chunk-AVEE5EHK.js} +53 -54
  159. package/dist/cli-bundle/chunks/chunk-AVEE5EHK.js.map +1 -0
  160. package/dist/cli-bundle/chunks/{chunk-FMWW2JDU.js → chunk-AXIDKKAT.js} +2 -2
  161. package/dist/cli-bundle/chunks/{chunk-TIM4OD74.js → chunk-BDTISOSD.js} +2 -2
  162. package/dist/cli-bundle/chunks/{chunk-C4C3EJCJ.js → chunk-BHO33VBQ.js} +509 -363
  163. package/dist/cli-bundle/chunks/chunk-BHO33VBQ.js.map +7 -0
  164. package/dist/cli-bundle/chunks/{chunk-6W3Y65PL.js → chunk-BZCEN4JA.js} +198 -177
  165. package/dist/cli-bundle/chunks/chunk-BZCEN4JA.js.map +7 -0
  166. package/dist/cli-bundle/chunks/{chunk-RRP6D345.js → chunk-CF7RL6FR.js} +12 -16
  167. package/dist/cli-bundle/chunks/{chunk-RRP6D345.js.map → chunk-CF7RL6FR.js.map} +1 -1
  168. package/dist/cli-bundle/chunks/{chunk-HC2S36NB.js → chunk-CWFNTKQJ.js} +154 -126
  169. package/dist/cli-bundle/chunks/chunk-CWFNTKQJ.js.map +1 -0
  170. package/dist/cli-bundle/chunks/chunk-CZVISY5A.js +87 -0
  171. package/dist/cli-bundle/chunks/chunk-CZVISY5A.js.map +7 -0
  172. package/dist/cli-bundle/chunks/{chunk-CZIFFMZI.js → chunk-DDPTYJIM.js} +2 -2
  173. package/dist/cli-bundle/chunks/{chunk-AYPQUFCX.js → chunk-EJUDVUYZ.js} +3 -3
  174. package/dist/cli-bundle/chunks/{chunk-EOGBMLCE.js → chunk-EVMTBV6V.js} +3 -3
  175. package/dist/cli-bundle/chunks/{chunk-RAWA3Y7O.js → chunk-FFMQB7WR.js} +199 -178
  176. package/dist/cli-bundle/chunks/chunk-FFMQB7WR.js.map +1 -0
  177. package/dist/cli-bundle/chunks/{chunk-CG3KP6I5.js → chunk-G7I7DEZA.js} +4 -4
  178. package/dist/cli-bundle/chunks/{chunk-MEXZ5XUM.js → chunk-GJ326ZKX.js} +53 -54
  179. package/dist/cli-bundle/chunks/chunk-GJ326ZKX.js.map +7 -0
  180. package/dist/cli-bundle/chunks/chunk-HPPFYYOV.js +119 -0
  181. package/dist/cli-bundle/chunks/chunk-HPPFYYOV.js.map +7 -0
  182. package/dist/cli-bundle/chunks/{chunk-OF7V47P3.js → chunk-HXTQJXWT.js} +2172 -2146
  183. package/dist/cli-bundle/chunks/chunk-HXTQJXWT.js.map +1 -0
  184. package/dist/cli-bundle/chunks/{chunk-F4BNR2IN.js → chunk-HYTGA6GI.js} +3 -3
  185. package/dist/cli-bundle/chunks/{chunk-2WCYE3IF.js → chunk-HZZEHPRG.js} +2 -2
  186. package/dist/cli-bundle/chunks/chunk-IBMFIKVS.js +14 -0
  187. package/dist/cli-bundle/chunks/chunk-IBMFIKVS.js.map +1 -0
  188. package/dist/cli-bundle/chunks/{chunk-YV2OSAMS.js → chunk-IJYK2T43.js} +2 -2
  189. package/dist/cli-bundle/chunks/{chunk-4XDGYFHL.js → chunk-IPYBJWTE.js} +10 -14
  190. package/dist/cli-bundle/chunks/{chunk-4XDGYFHL.js.map → chunk-IPYBJWTE.js.map} +1 -1
  191. package/dist/cli-bundle/chunks/{chunk-6EBNFQOR.js → chunk-IZBR4NRW.js} +10 -14
  192. package/dist/cli-bundle/chunks/{chunk-6EBNFQOR.js.map → chunk-IZBR4NRW.js.map} +1 -1
  193. package/dist/cli-bundle/chunks/{chunk-VFJYVXHL.js → chunk-JLM7BHI7.js} +7 -9
  194. package/dist/cli-bundle/chunks/{chunk-VFJYVXHL.js.map → chunk-JLM7BHI7.js.map} +1 -1
  195. package/dist/cli-bundle/chunks/{chunk-6EL7SW5C.js → chunk-JMP4E6D7.js} +114 -122
  196. package/dist/cli-bundle/chunks/chunk-JMP4E6D7.js.map +7 -0
  197. package/dist/cli-bundle/chunks/{chunk-QOUOMPHO.js → chunk-JPECA746.js} +2 -2
  198. package/dist/cli-bundle/chunks/{chunk-KJZOSF7J.js → chunk-JSU5P7VS.js} +100 -35
  199. package/dist/cli-bundle/chunks/chunk-JSU5P7VS.js.map +1 -0
  200. package/dist/cli-bundle/chunks/{context-55VEOYI3.js → chunk-JWXRETDF.js} +79 -82
  201. package/dist/cli-bundle/chunks/chunk-JWXRETDF.js.map +1 -0
  202. package/dist/cli-bundle/chunks/{chunk-OQ2E64FH.js → chunk-KNPEF7QG.js} +4 -4
  203. package/dist/cli-bundle/chunks/{chunk-3BKH2CL3.js → chunk-L5OEFZQG.js} +3 -3
  204. package/dist/cli-bundle/chunks/{chunk-DTABLLVE.js → chunk-LB6TP6MC.js} +5 -7
  205. package/dist/cli-bundle/chunks/{chunk-DTABLLVE.js.map → chunk-LB6TP6MC.js.map} +2 -2
  206. package/dist/cli-bundle/chunks/{chunk-TSI32UEL.js → chunk-MAUKX7JC.js} +6 -8
  207. package/dist/cli-bundle/chunks/{chunk-TSI32UEL.js.map → chunk-MAUKX7JC.js.map} +1 -1
  208. package/dist/cli-bundle/chunks/{chunk-SMXSDY7J.js → chunk-MDPEOIGN.js} +2221 -2172
  209. package/dist/cli-bundle/chunks/chunk-MDPEOIGN.js.map +7 -0
  210. package/dist/cli-bundle/chunks/{chunk-5S4ZGDB2.js → chunk-N74UMG5H.js} +2 -2
  211. package/dist/cli-bundle/chunks/{chunk-IXAZI443.js → chunk-NFDPYAIP.js} +2 -2
  212. package/dist/cli-bundle/chunks/{chunk-SKC4UTRP.js → chunk-NKZAN7BD.js} +3 -3
  213. package/dist/cli-bundle/chunks/chunk-NOLPZMSV.js +116 -0
  214. package/dist/cli-bundle/chunks/chunk-NOLPZMSV.js.map +1 -0
  215. package/dist/cli-bundle/chunks/{chunk-L7UXKP2I.js → chunk-NU2UEROZ.js} +1257 -1029
  216. package/dist/cli-bundle/chunks/chunk-NU2UEROZ.js.map +1 -0
  217. package/dist/cli-bundle/chunks/{chunk-HBAEFWX3.js → chunk-NUHHPVVS.js} +65 -335
  218. package/dist/cli-bundle/chunks/chunk-NUHHPVVS.js.map +7 -0
  219. package/dist/cli-bundle/chunks/{chunk-JPJDP4VU.js → chunk-NWMZWYYB.js} +2 -2
  220. package/dist/cli-bundle/chunks/{chunk-MWMHZOZZ.js → chunk-OGXLACHC.js} +10 -14
  221. package/dist/cli-bundle/chunks/{chunk-MWMHZOZZ.js.map → chunk-OGXLACHC.js.map} +1 -1
  222. package/dist/cli-bundle/chunks/chunk-OKQ22KTH.js +379 -0
  223. package/dist/cli-bundle/chunks/chunk-OKQ22KTH.js.map +1 -0
  224. package/dist/cli-bundle/chunks/{chunk-KKX4Z2SE.js → chunk-OTUHB4HS.js} +4 -4
  225. package/dist/cli-bundle/chunks/{chunk-ZLWRPBOW.js → chunk-QCWF6IYD.js} +510 -364
  226. package/dist/cli-bundle/chunks/chunk-QCWF6IYD.js.map +1 -0
  227. package/dist/cli-bundle/chunks/{chunk-PRVTGX64.js → chunk-RGEMWD6Q.js} +11 -23
  228. package/dist/cli-bundle/chunks/chunk-RGEMWD6Q.js.map +7 -0
  229. package/dist/cli-bundle/chunks/chunk-RH5ZBYFD.js +809 -0
  230. package/dist/cli-bundle/chunks/chunk-RH5ZBYFD.js.map +7 -0
  231. package/dist/cli-bundle/chunks/{chunk-ALQKV6U7.js → chunk-RLDHZHQS.js} +12 -16
  232. package/dist/cli-bundle/chunks/{chunk-ALQKV6U7.js.map → chunk-RLDHZHQS.js.map} +1 -1
  233. package/dist/cli-bundle/chunks/{schema-C6QA367T.js → chunk-RMMQ74TG.js} +144 -67
  234. package/dist/cli-bundle/chunks/chunk-RMMQ74TG.js.map +7 -0
  235. package/dist/cli-bundle/chunks/{chunk-EYPINTFR.js → chunk-RVUALSJF.js} +1516 -753
  236. package/dist/cli-bundle/chunks/chunk-RVUALSJF.js.map +7 -0
  237. package/dist/cli-bundle/chunks/chunk-SDR5J34Q.js +2468 -0
  238. package/dist/cli-bundle/chunks/chunk-SDR5J34Q.js.map +7 -0
  239. package/dist/cli-bundle/chunks/{chunk-WB5BYQMF.js → chunk-SLMUGTK3.js} +4 -4
  240. package/dist/cli-bundle/chunks/{chunk-SUREE24M.js → chunk-TP5Q5ZD3.js} +12 -24
  241. package/dist/cli-bundle/chunks/chunk-TP5Q5ZD3.js.map +1 -0
  242. package/dist/cli-bundle/chunks/{chunk-UACWNBL2.js → chunk-UYUYDGIB.js} +7 -9
  243. package/dist/cli-bundle/chunks/{chunk-UACWNBL2.js.map → chunk-UYUYDGIB.js.map} +1 -1
  244. package/dist/cli-bundle/chunks/{chunk-V4UYNSEM.js → chunk-UZIWVBE6.js} +6 -8
  245. package/dist/cli-bundle/chunks/{chunk-V4UYNSEM.js.map → chunk-UZIWVBE6.js.map} +1 -1
  246. package/dist/cli-bundle/chunks/{chunk-EWRSXOIZ.js → chunk-V3NOKJF2.js} +11 -13
  247. package/dist/cli-bundle/chunks/{chunk-EWRSXOIZ.js.map → chunk-V3NOKJF2.js.map} +1 -1
  248. package/dist/cli-bundle/chunks/{chunk-XXKV4UWE.js → chunk-VARHOHYV.js} +571 -507
  249. package/dist/cli-bundle/chunks/chunk-VARHOHYV.js.map +7 -0
  250. package/dist/cli-bundle/chunks/{chunk-AEACLRVH.js → chunk-VICZWYGZ.js} +18 -11
  251. package/dist/cli-bundle/chunks/chunk-VICZWYGZ.js.map +7 -0
  252. package/dist/cli-bundle/chunks/chunk-VY3VQ22F.js +84 -0
  253. package/dist/cli-bundle/chunks/chunk-VY3VQ22F.js.map +1 -0
  254. package/dist/cli-bundle/chunks/chunk-VZDBVEZR.js +382 -0
  255. package/dist/cli-bundle/chunks/chunk-VZDBVEZR.js.map +7 -0
  256. package/dist/cli-bundle/chunks/{chunk-GDUMGZK3.js → chunk-W4ULYO7Z.js} +11 -13
  257. package/dist/cli-bundle/chunks/{chunk-GDUMGZK3.js.map → chunk-W4ULYO7Z.js.map} +1 -1
  258. package/dist/cli-bundle/chunks/{chunk-I6QMJ2XT.js → chunk-WYDHYJPO.js} +2 -2
  259. package/dist/cli-bundle/chunks/{chunk-ALKFCIIB.js → chunk-YITK2PJ6.js} +9 -11
  260. package/dist/cli-bundle/chunks/{chunk-ALKFCIIB.js.map → chunk-YITK2PJ6.js.map} +1 -1
  261. package/dist/cli-bundle/chunks/chunk-YJIEJRZB.js +84 -0
  262. package/dist/cli-bundle/chunks/chunk-YJIEJRZB.js.map +1 -0
  263. package/dist/cli-bundle/chunks/{chunk-LNEDHJNQ.js → chunk-ZETXE4SE.js} +66 -329
  264. package/dist/cli-bundle/chunks/chunk-ZETXE4SE.js.map +1 -0
  265. package/dist/cli-bundle/chunks/{chunk-KIEAK7YE.js → chunk-ZRP4VG5U.js} +2 -2
  266. package/dist/cli-bundle/chunks/{claim-FZZZCAY6.js → claim-EMQLYPRW.js} +10 -12
  267. package/dist/cli-bundle/chunks/{claim-FZZZCAY6.js.map → claim-EMQLYPRW.js.map} +1 -1
  268. package/dist/cli-bundle/chunks/{claim-XK5QBZE3.js → claim-T3GCKV7C.js} +8 -10
  269. package/dist/cli-bundle/chunks/{claim-XK5QBZE3.js.map → claim-T3GCKV7C.js.map} +1 -1
  270. package/dist/cli-bundle/chunks/close-E6ZZGCJY.js +14 -0
  271. package/dist/cli-bundle/chunks/{close-QHMVWM7M.js → close-TQYAAFJP.js} +7 -8
  272. package/dist/cli-bundle/chunks/{close-many-OIXJE2JZ.js → close-many-BG5QQIDQ.js} +16 -18
  273. package/dist/cli-bundle/chunks/{close-many-OIXJE2JZ.js.map → close-many-BG5QQIDQ.js.map} +1 -1
  274. package/dist/cli-bundle/chunks/{close-many-SUU5BS2C.js → close-many-LDRVEQY2.js} +18 -20
  275. package/dist/cli-bundle/chunks/{close-many-SUU5BS2C.js.map → close-many-LDRVEQY2.js.map} +1 -1
  276. package/dist/cli-bundle/chunks/{comments-5YM62D75.js → comments-QCKR2YY2.js} +11 -13
  277. package/dist/cli-bundle/chunks/{comments-5YM62D75.js.map → comments-QCKR2YY2.js.map} +1 -1
  278. package/dist/cli-bundle/chunks/{comments-RH3IBIRH.js → comments-YUXJRZPQ.js} +9 -11
  279. package/dist/cli-bundle/chunks/{comments-RH3IBIRH.js.map → comments-YUXJRZPQ.js.map} +1 -1
  280. package/dist/cli-bundle/chunks/{config-NCNNWF6R.js → config-DMSU64QO.js} +18 -387
  281. package/dist/cli-bundle/chunks/config-DMSU64QO.js.map +7 -0
  282. package/dist/cli-bundle/chunks/{config-SW3U7XP2.js → config-QH2DICD6.js} +18 -380
  283. package/dist/cli-bundle/chunks/config-QH2DICD6.js.map +1 -0
  284. package/dist/cli-bundle/chunks/context-B6275WPX.js +46 -0
  285. package/dist/cli-bundle/chunks/context-OCZ3FJ4Z.js +42 -0
  286. package/dist/cli-bundle/chunks/{contracts-SY6PDFIK.js → contracts-HN7ABKLP.js} +72 -15
  287. package/dist/cli-bundle/chunks/contracts-HN7ABKLP.js.map +7 -0
  288. package/dist/cli-bundle/chunks/{contracts-JXFGBOYT.js → contracts-W4FZVVD6.js} +72 -15
  289. package/dist/cli-bundle/chunks/contracts-W4FZVVD6.js.map +1 -0
  290. package/dist/cli-bundle/chunks/{copy-N3GE6FYS.js → copy-BTJOSKKT.js} +7 -11
  291. package/dist/cli-bundle/chunks/{copy-N3GE6FYS.js.map → copy-BTJOSKKT.js.map} +1 -1
  292. package/dist/cli-bundle/chunks/{copy-IEDBJOOX.js → copy-DEM4DATS.js} +9 -13
  293. package/dist/cli-bundle/chunks/{copy-IEDBJOOX.js.map → copy-DEM4DATS.js.map} +1 -1
  294. package/dist/cli-bundle/chunks/create-OH3BDGBB.js +28 -0
  295. package/dist/cli-bundle/chunks/{create-O4VONGPG.js → create-RLRJMRTM.js} +12 -14
  296. package/dist/cli-bundle/chunks/{delete-LPEIF7RU.js → delete-BHK7VB2Z.js} +5 -7
  297. package/dist/cli-bundle/chunks/{delete-LPEIF7RU.js.map → delete-BHK7VB2Z.js.map} +1 -1
  298. package/dist/cli-bundle/chunks/{delete-724EQ6OS.js → delete-LSVHAB4Y.js} +7 -9
  299. package/dist/cli-bundle/chunks/{delete-724EQ6OS.js.map → delete-LSVHAB4Y.js.map} +1 -1
  300. package/dist/cli-bundle/chunks/{deps-RSBU4SIU.js → deps-4UDFJRUA.js} +8 -11
  301. package/dist/cli-bundle/chunks/{deps-RSBU4SIU.js.map → deps-4UDFJRUA.js.map} +1 -1
  302. package/dist/cli-bundle/chunks/{deps-T3Y6Y7RT.js → deps-XHYXWEPT.js} +6 -9
  303. package/dist/cli-bundle/chunks/{deps-T3Y6Y7RT.js.map → deps-XHYXWEPT.js.map} +1 -1
  304. package/dist/cli-bundle/chunks/{docs-IFS7HZPP.js → docs-26S44RXU.js} +8 -9
  305. package/dist/cli-bundle/chunks/{docs-IFS7HZPP.js.map → docs-26S44RXU.js.map} +1 -1
  306. package/dist/cli-bundle/chunks/{docs-75ZLCO3G.js → docs-GYZNVS26.js} +10 -11
  307. package/dist/cli-bundle/chunks/{docs-75ZLCO3G.js.map → docs-GYZNVS26.js.map} +1 -1
  308. package/dist/cli-bundle/chunks/{eval-L2KD7W3M.js → eval-PGRVIJQU.js} +12 -14
  309. package/dist/cli-bundle/chunks/{eval-L2KD7W3M.js.map → eval-PGRVIJQU.js.map} +1 -1
  310. package/dist/cli-bundle/chunks/{eval-QGR7JCQO.js → eval-UYF3ZPVO.js} +10 -12
  311. package/dist/cli-bundle/chunks/{eval-QGR7JCQO.js.map → eval-UYF3ZPVO.js.map} +1 -1
  312. package/dist/cli-bundle/chunks/{extension-YQF4CPIR.js → extension-CPSLJQVE.js} +12 -7
  313. package/dist/cli-bundle/chunks/{extension-3JYWJ5K2.js → extension-CXJ6RELI.js} +12 -7
  314. package/dist/cli-bundle/chunks/{files-EPEJMJHQ.js → files-MBNICQFM.js} +9 -11
  315. package/dist/cli-bundle/chunks/{files-EPEJMJHQ.js.map → files-MBNICQFM.js.map} +1 -1
  316. package/dist/cli-bundle/chunks/{files-5BQWDRDT.js → files-NQHEXUZD.js} +11 -13
  317. package/dist/cli-bundle/chunks/{files-5BQWDRDT.js.map → files-NQHEXUZD.js.map} +1 -1
  318. package/dist/cli-bundle/chunks/{focus-RWGKD76E.js → focus-DWYIG7GU.js} +10 -14
  319. package/dist/cli-bundle/chunks/{focus-RWGKD76E.js.map → focus-DWYIG7GU.js.map} +1 -1
  320. package/dist/cli-bundle/chunks/{focus-DQVJAPOE.js → focus-XZW5423D.js} +8 -12
  321. package/dist/cli-bundle/chunks/{focus-DQVJAPOE.js.map → focus-XZW5423D.js.map} +1 -1
  322. package/dist/cli-bundle/chunks/{gc-BEJMQT64.js → gc-7GQYOS2G.js} +3 -3
  323. package/dist/cli-bundle/chunks/{gc-JEFQDJPA.js → gc-LPVMKJQJ.js} +3 -3
  324. package/dist/cli-bundle/chunks/{get-LQG6PEVG.js → get-A7MAOHCU.js} +10 -13
  325. package/dist/cli-bundle/chunks/{get-LQG6PEVG.js.map → get-A7MAOHCU.js.map} +1 -1
  326. package/dist/cli-bundle/chunks/{get-WVN75H42.js → get-DSDEKJ3L.js} +12 -15
  327. package/dist/cli-bundle/chunks/{get-WVN75H42.js.map → get-DSDEKJ3L.js.map} +1 -1
  328. package/dist/cli-bundle/chunks/{health-JJJOY7DJ.js → health-3IPFLKXB.js} +17 -17
  329. package/dist/cli-bundle/chunks/{health-P67NZ6TT.js → health-GZXGBZ36.js} +17 -17
  330. package/dist/cli-bundle/chunks/{history-RUKPKNY7.js → history-NERDJNUB.js} +8 -10
  331. package/dist/cli-bundle/chunks/history-WSZHY3PN.js +18 -0
  332. package/dist/cli-bundle/chunks/{history-compact-NQ7VPRVT.js → history-compact-2WRZ2WK4.js} +11 -14
  333. package/dist/cli-bundle/chunks/{history-compact-NQ7VPRVT.js.map → history-compact-2WRZ2WK4.js.map} +1 -1
  334. package/dist/cli-bundle/chunks/{history-compact-ZAOWR7GD.js → history-compact-HR7BB4LR.js} +13 -16
  335. package/dist/cli-bundle/chunks/{history-compact-ZAOWR7GD.js.map → history-compact-HR7BB4LR.js.map} +1 -1
  336. package/dist/cli-bundle/chunks/history-redact-MP6CH7U5.js +19 -0
  337. package/dist/cli-bundle/chunks/{history-redact-YY4XYVEP.js → history-redact-O3NBCNWC.js} +9 -11
  338. package/dist/cli-bundle/chunks/{history-repair-EHL4ODQY.js → history-repair-LCMOS45X.js} +11 -14
  339. package/dist/cli-bundle/chunks/{history-repair-EHL4ODQY.js.map → history-repair-LCMOS45X.js.map} +1 -1
  340. package/dist/cli-bundle/chunks/{history-repair-YSQH6SY6.js → history-repair-XA3LC4GA.js} +13 -16
  341. package/dist/cli-bundle/chunks/{history-repair-YSQH6SY6.js.map → history-repair-XA3LC4GA.js.map} +1 -1
  342. package/dist/cli-bundle/chunks/{init-HBFGYS66.js → init-64XDLQJB.js} +12 -11
  343. package/dist/cli-bundle/chunks/init-PAX32BJA.js +22 -0
  344. package/dist/cli-bundle/chunks/{learnings-KFQO7GEZ.js → learnings-JR6MA5TI.js} +9 -11
  345. package/dist/cli-bundle/chunks/{learnings-KFQO7GEZ.js.map → learnings-JR6MA5TI.js.map} +1 -1
  346. package/dist/cli-bundle/chunks/{learnings-J555ZFPD.js → learnings-LPKCSJX7.js} +11 -13
  347. package/dist/cli-bundle/chunks/{learnings-J555ZFPD.js.map → learnings-LPKCSJX7.js.map} +1 -1
  348. package/dist/cli-bundle/chunks/{list-C7R33MD5.js → list-DNBJVO3E.js} +10 -10
  349. package/dist/cli-bundle/chunks/{list-DSN6UNFB.js → list-G5Y65VF6.js} +10 -10
  350. package/dist/cli-bundle/chunks/next-BCERKDUR.js +277 -0
  351. package/dist/cli-bundle/chunks/next-BCERKDUR.js.map +7 -0
  352. package/dist/cli-bundle/chunks/next-FYTQF6HG.js +274 -0
  353. package/dist/cli-bundle/chunks/next-FYTQF6HG.js.map +1 -0
  354. package/dist/cli-bundle/chunks/{notes-V4VNIQL4.js → notes-2BMU3VVQ.js} +9 -11
  355. package/dist/cli-bundle/chunks/{notes-V4VNIQL4.js.map → notes-2BMU3VVQ.js.map} +1 -1
  356. package/dist/cli-bundle/chunks/{notes-VYJFN2A3.js → notes-6KTGO2OJ.js} +11 -13
  357. package/dist/cli-bundle/chunks/{notes-VYJFN2A3.js.map → notes-6KTGO2OJ.js.map} +1 -1
  358. package/dist/cli-bundle/chunks/{plan-RBHQ5PO7.js → plan-4WXEQCTN.js} +15 -18
  359. package/dist/cli-bundle/chunks/{plan-RBHQ5PO7.js.map → plan-4WXEQCTN.js.map} +1 -1
  360. package/dist/cli-bundle/chunks/{plan-DHRSVSHR.js → plan-RKZHQVXR.js} +17 -20
  361. package/dist/cli-bundle/chunks/{plan-DHRSVSHR.js.map → plan-RKZHQVXR.js.map} +1 -1
  362. package/dist/cli-bundle/chunks/profile-4OMM32CD.js +1235 -0
  363. package/dist/cli-bundle/chunks/profile-4OMM32CD.js.map +7 -0
  364. package/dist/cli-bundle/chunks/profile-QLER5ENE.js +1197 -0
  365. package/dist/cli-bundle/chunks/profile-QLER5ENE.js.map +1 -0
  366. package/dist/cli-bundle/chunks/{register-list-query-OM3E2KMY.js → register-list-query-7LV46VAU.js} +45 -21
  367. package/dist/cli-bundle/chunks/register-list-query-7LV46VAU.js.map +1 -0
  368. package/dist/cli-bundle/chunks/{register-list-query-CCMHGZTF.js → register-list-query-SNG5PGA4.js} +44 -20
  369. package/dist/cli-bundle/chunks/register-list-query-SNG5PGA4.js.map +7 -0
  370. package/dist/cli-bundle/chunks/{register-mutation-N3CDEGZU.js → register-mutation-ENNDUAZG.js} +106 -40
  371. package/dist/cli-bundle/chunks/register-mutation-ENNDUAZG.js.map +1 -0
  372. package/dist/cli-bundle/chunks/{register-mutation-UXTTWL6N.js → register-mutation-KK7PHYYU.js} +105 -39
  373. package/dist/cli-bundle/chunks/register-mutation-KK7PHYYU.js.map +7 -0
  374. package/dist/cli-bundle/chunks/{register-operations-UDIFMQKD.js → register-operations-C6OWLDSH.js} +32 -34
  375. package/dist/cli-bundle/chunks/{register-operations-UDIFMQKD.js.map → register-operations-C6OWLDSH.js.map} +1 -1
  376. package/dist/cli-bundle/chunks/{register-operations-R2FLOCRI.js → register-operations-HZ6XERQG.js} +30 -32
  377. package/dist/cli-bundle/chunks/{register-operations-R2FLOCRI.js.map → register-operations-HZ6XERQG.js.map} +1 -1
  378. package/dist/cli-bundle/chunks/{register-setup-G5LTSFYK.js → register-setup-P67EMBDJ.js} +68 -25
  379. package/dist/cli-bundle/chunks/register-setup-P67EMBDJ.js.map +1 -0
  380. package/dist/cli-bundle/chunks/{register-setup-TWHKICM2.js → register-setup-ZKJ53RS7.js} +67 -24
  381. package/dist/cli-bundle/chunks/register-setup-ZKJ53RS7.js.map +7 -0
  382. package/dist/cli-bundle/chunks/{restore-LL2WLEDG.js → restore-4MHZFJ2E.js} +9 -11
  383. package/dist/cli-bundle/chunks/restore-YALDGTQR.js +17 -0
  384. package/dist/cli-bundle/chunks/{scheduling-shortcuts-M4H2ZI64.js → scheduling-shortcuts-LB6DOLRL.js} +14 -16
  385. package/dist/cli-bundle/chunks/{scheduling-shortcuts-M4H2ZI64.js.map → scheduling-shortcuts-LB6DOLRL.js.map} +1 -1
  386. package/dist/cli-bundle/chunks/{scheduling-shortcuts-255GI3BU.js → scheduling-shortcuts-UTOYKLXQ.js} +12 -14
  387. package/dist/cli-bundle/chunks/{scheduling-shortcuts-255GI3BU.js.map → scheduling-shortcuts-UTOYKLXQ.js.map} +1 -1
  388. package/dist/cli-bundle/chunks/schema-73HR2OJW.js +75 -0
  389. package/dist/cli-bundle/chunks/schema-U6LJKSIR.js +71 -0
  390. package/dist/cli-bundle/chunks/{search-2EI6EAXH.js → search-AXPXKZER.js} +10 -12
  391. package/dist/cli-bundle/chunks/{search-QBFBLQRO.js → search-KILGT37L.js} +10 -12
  392. package/dist/cli-bundle/chunks/{stats-TKC6CAKB.js → stats-PSYVVTNZ.js} +21 -13
  393. package/dist/cli-bundle/chunks/stats-PSYVVTNZ.js.map +1 -0
  394. package/dist/cli-bundle/chunks/{stats-TCW2SZQG.js → stats-W5KNVJWQ.js} +20 -12
  395. package/dist/cli-bundle/chunks/stats-W5KNVJWQ.js.map +7 -0
  396. package/dist/cli-bundle/chunks/{telemetry-BT2VSWU2.js → telemetry-BZUF6H7G.js} +4 -4
  397. package/dist/cli-bundle/chunks/{telemetry-LQ6FRTUT.js → telemetry-GAHHQTOS.js} +4 -4
  398. package/dist/cli-bundle/chunks/test-ACD52Z3S.js +35 -0
  399. package/dist/cli-bundle/chunks/test-ACD52Z3S.js.map +7 -0
  400. package/dist/cli-bundle/chunks/{test-NV2DRPUS.js → test-PWDIZ255.js} +15 -16
  401. package/dist/cli-bundle/chunks/test-PWDIZ255.js.map +1 -0
  402. package/dist/cli-bundle/chunks/{test-all-DZ76VTPQ.js → test-all-L2MDDUCA.js} +20 -22
  403. package/dist/cli-bundle/chunks/{test-all-DZ76VTPQ.js.map → test-all-L2MDDUCA.js.map} +1 -1
  404. package/dist/cli-bundle/chunks/{test-all-REW67LXT.js → test-all-RBZ6DLU2.js} +18 -20
  405. package/dist/cli-bundle/chunks/{test-all-REW67LXT.js.map → test-all-RBZ6DLU2.js.map} +1 -1
  406. package/dist/cli-bundle/chunks/{test-runs-PX73DMMI.js → test-runs-PLRAZEFW.js} +5 -6
  407. package/dist/cli-bundle/chunks/test-runs-PLRAZEFW.js.map +7 -0
  408. package/dist/cli-bundle/chunks/{test-runs-FQ5WNQLP.js → test-runs-UXIXPDKU.js} +6 -7
  409. package/dist/cli-bundle/chunks/test-runs-UXIXPDKU.js.map +1 -0
  410. package/dist/cli-bundle/chunks/update-AMRSOIWP.js +24 -0
  411. package/dist/cli-bundle/chunks/update-AMRSOIWP.js.map +7 -0
  412. package/dist/cli-bundle/chunks/update-KFX2SIAC.js +28 -0
  413. package/dist/cli-bundle/chunks/update-KFX2SIAC.js.map +1 -0
  414. package/dist/cli-bundle/chunks/{update-many-Q5ZEI64S.js → update-many-RNSBX2TA.js} +35 -36
  415. package/dist/cli-bundle/chunks/{update-many-Q5ZEI64S.js.map → update-many-RNSBX2TA.js.map} +1 -1
  416. package/dist/cli-bundle/chunks/{update-many-2ILP6E4Y.js → update-many-Z5GJS5LC.js} +33 -34
  417. package/dist/cli-bundle/chunks/{update-many-2ILP6E4Y.js.map → update-many-Z5GJS5LC.js.map} +1 -1
  418. package/dist/cli-bundle/chunks/{upgrade-FOZKQTQF.js → upgrade-BRL6KCOJ.js} +13 -8
  419. package/dist/cli-bundle/chunks/{upgrade-FOZKQTQF.js.map → upgrade-BRL6KCOJ.js.map} +1 -1
  420. package/dist/cli-bundle/chunks/{upgrade-DHL74PQH.js → upgrade-HAK6JG2O.js} +11 -6
  421. package/dist/cli-bundle/chunks/{upgrade-DHL74PQH.js.map → upgrade-HAK6JG2O.js.map} +1 -1
  422. package/dist/cli-bundle/chunks/{validate-HYZNIB6W.js → validate-MTUVL5VC.js} +38 -28
  423. package/dist/cli-bundle/chunks/validate-MTUVL5VC.js.map +7 -0
  424. package/dist/cli-bundle/chunks/{validate-54SYJ7QW.js → validate-X5W76YJL.js} +39 -29
  425. package/dist/cli-bundle/chunks/validate-X5W76YJL.js.map +1 -0
  426. package/dist/cli-bundle/main.js +95 -724
  427. package/dist/cli-bundle/main.js.map +4 -4
  428. package/dist/core/config/positional-value.d.ts +2 -0
  429. package/dist/core/config/positional-value.js +2 -2
  430. package/dist/core/config/positional-value.js.map +1 -1
  431. package/dist/core/extensions/activation-summary-markdown.d.ts +71 -0
  432. package/dist/core/extensions/activation-summary-markdown.js +151 -0
  433. package/dist/core/extensions/activation-summary-markdown.js.map +1 -0
  434. package/dist/core/extensions/activation-summary.d.ts +2 -0
  435. package/dist/core/extensions/activation-summary.js +3 -2
  436. package/dist/core/extensions/activation-summary.js.map +1 -1
  437. package/dist/core/extensions/capability-usage.d.ts +1 -1
  438. package/dist/core/extensions/capability-usage.js +4 -3
  439. package/dist/core/extensions/capability-usage.js.map +1 -1
  440. package/dist/core/extensions/extension-policy.d.ts +18 -3
  441. package/dist/core/extensions/extension-policy.js +116 -106
  442. package/dist/core/extensions/extension-policy.js.map +1 -1
  443. package/dist/core/extensions/extension-registries.js +3 -2
  444. package/dist/core/extensions/extension-registries.js.map +1 -1
  445. package/dist/core/extensions/extension-types.d.ts +21 -1
  446. package/dist/core/extensions/extension-types.js +3 -2
  447. package/dist/core/extensions/extension-types.js.map +1 -1
  448. package/dist/core/extensions/loader.js +439 -232
  449. package/dist/core/extensions/loader.js.map +1 -1
  450. package/dist/core/fs/fs-utils.js +27 -2
  451. package/dist/core/fs/fs-utils.js.map +1 -1
  452. package/dist/core/item/actionability.d.ts +57 -0
  453. package/dist/core/item/actionability.js +178 -0
  454. package/dist/core/item/actionability.js.map +1 -0
  455. package/dist/core/item/item-format.js +523 -410
  456. package/dist/core/item/item-format.js.map +1 -1
  457. package/dist/core/item/type-registry.js +18 -45
  458. package/dist/core/item/type-registry.js.map +1 -1
  459. package/dist/core/profile/profile-describe.d.ts +64 -0
  460. package/dist/core/profile/profile-describe.js +83 -0
  461. package/dist/core/profile/profile-describe.js.map +1 -0
  462. package/dist/core/profile/profile-lint.d.ts +53 -0
  463. package/dist/core/profile/profile-lint.js +422 -0
  464. package/dist/core/profile/profile-lint.js.map +1 -0
  465. package/dist/core/profile/profile-plan.d.ts +145 -0
  466. package/dist/core/profile/profile-plan.js +0 -0
  467. package/dist/core/profile/profile-plan.js.map +1 -0
  468. package/dist/core/profile/profile-presets.d.ts +218 -0
  469. package/dist/core/profile/profile-presets.js +325 -0
  470. package/dist/core/profile/profile-presets.js.map +1 -0
  471. package/dist/core/schema/fields-file.js +25 -25
  472. package/dist/core/schema/fields-file.js.map +1 -1
  473. package/dist/core/schema/item-types-file.js +3 -3
  474. package/dist/core/schema/item-types-file.js.map +1 -1
  475. package/dist/core/schema/runtime-schema.js +4 -4
  476. package/dist/core/schema/runtime-schema.js.map +1 -1
  477. package/dist/core/schema/status-defs-file.js +3 -3
  478. package/dist/core/schema/status-defs-file.js.map +1 -1
  479. package/dist/core/shared/serialization.js +83 -62
  480. package/dist/core/shared/serialization.js.map +1 -1
  481. package/dist/core/store/item-store.d.ts +1 -0
  482. package/dist/core/store/item-store.js +16 -8
  483. package/dist/core/store/item-store.js.map +1 -1
  484. package/dist/core/store/paths.js +4 -32
  485. package/dist/core/store/paths.js.map +1 -1
  486. package/dist/core/store/settings.js +14 -14
  487. package/dist/core/store/settings.js.map +1 -1
  488. package/dist/core/telemetry/observability.js +50 -54
  489. package/dist/core/telemetry/observability.js.map +1 -1
  490. package/dist/core/telemetry/runtime.js +11 -2
  491. package/dist/core/telemetry/runtime.js.map +1 -1
  492. package/dist/core/test/background-runs.js +3 -2
  493. package/dist/core/test/background-runs.js.map +1 -1
  494. package/dist/core/validate/linked-artifact-reference.d.ts +24 -0
  495. package/dist/core/validate/linked-artifact-reference.js +41 -0
  496. package/dist/core/validate/linked-artifact-reference.js.map +1 -0
  497. package/dist/mcp/server.js +540 -420
  498. package/dist/mcp/server.js.map +1 -1
  499. package/dist/mcp/tool-definitions.js +33 -2
  500. package/dist/mcp/tool-definitions.js.map +1 -1
  501. package/dist/sdk/cli-contracts/commander-types.d.ts +1 -0
  502. package/dist/sdk/cli-contracts/commander-types.js +15 -2
  503. package/dist/sdk/cli-contracts/commander-types.js.map +1 -1
  504. package/dist/sdk/cli-contracts/enum-contracts.d.ts +3 -3
  505. package/dist/sdk/cli-contracts/enum-contracts.js +6 -2
  506. package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -1
  507. package/dist/sdk/cli-contracts/flag-contracts.d.ts +149 -0
  508. package/dist/sdk/cli-contracts/flag-contracts.js +1514 -0
  509. package/dist/sdk/cli-contracts/flag-contracts.js.map +1 -0
  510. package/dist/sdk/cli-contracts/string-lists.d.ts +14 -0
  511. package/dist/sdk/cli-contracts/string-lists.js +20 -0
  512. package/dist/sdk/cli-contracts/string-lists.js.map +1 -0
  513. package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +1 -1
  514. package/dist/sdk/cli-contracts/tool-option-contracts.js +51 -109
  515. package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -1
  516. package/dist/sdk/cli-contracts/tool-parameter-tables.d.ts +17 -0
  517. package/dist/sdk/cli-contracts/tool-parameter-tables.js +54 -5
  518. package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
  519. package/dist/sdk/cli-contracts/tool-schema.d.ts +74 -0
  520. package/dist/sdk/cli-contracts/tool-schema.js +871 -0
  521. package/dist/sdk/cli-contracts/tool-schema.js.map +1 -0
  522. package/dist/sdk/cli-contracts.d.ts +13 -193
  523. package/dist/sdk/cli-contracts.js +5 -2277
  524. package/dist/sdk/cli-contracts.js.map +1 -1
  525. package/dist/sdk/compose.d.ts +11 -5
  526. package/dist/sdk/compose.js +240 -124
  527. package/dist/sdk/compose.js.map +1 -1
  528. package/dist/sdk/define.d.ts +14 -0
  529. package/dist/sdk/define.js +17 -2
  530. package/dist/sdk/define.js.map +1 -1
  531. package/dist/sdk/index.d.ts +14 -3
  532. package/dist/sdk/index.js +14 -3
  533. package/dist/sdk/index.js.map +1 -1
  534. package/dist/sdk/testing.d.ts +82 -2
  535. package/dist/sdk/testing.js +74 -3
  536. package/dist/sdk/testing.js.map +1 -1
  537. package/docs/AGENT_GUIDE.md +2 -0
  538. package/docs/CLAUDE_CODE_PLUGIN.md +2 -2
  539. package/docs/COMMANDS.md +37 -0
  540. package/docs/EXTENSIONS.md +12 -13
  541. package/docs/RELEASING.md +8 -4
  542. package/docs/SDK.md +184 -17
  543. package/docs/TESTING.md +12 -0
  544. package/docs/examples/policy-restricted-extension/README.md +6 -0
  545. package/docs/examples/policy-restricted-extension/index.ts +40 -0
  546. package/docs/examples/policy-restricted-extension/manifest.json +2 -2
  547. package/docs/examples/starter-extension/README.md +14 -2
  548. package/docs/examples/starter-extension/{index.js → index.ts} +51 -6
  549. package/docs/examples/starter-extension/manifest.json +2 -2
  550. package/package.json +20 -7
  551. package/packages/pm-beads/extensions/beads/index.ts +3 -3
  552. package/packages/pm-beads/extensions/beads/manifest.json +2 -2
  553. package/packages/pm-beads/extensions/beads/runtime-loader.ts +19 -7
  554. package/packages/pm-beads/extensions/beads/runtime.ts +155 -37
  555. package/packages/pm-calendar/extensions/calendar/index.ts +3 -3
  556. package/packages/pm-calendar/extensions/calendar/manifest.json +2 -2
  557. package/packages/pm-calendar/extensions/calendar/runtime.ts +2 -2
  558. package/packages/pm-command-kit/extensions/command-kit/index.ts +1 -1
  559. package/packages/pm-command-kit/extensions/command-kit/manifest.json +2 -2
  560. package/packages/pm-governance-audit/extensions/governance-audit/index.ts +2 -2
  561. package/packages/pm-governance-audit/extensions/governance-audit/manifest.json +2 -2
  562. package/packages/pm-governance-audit/extensions/governance-audit/runtime.ts +1 -1
  563. package/packages/pm-guide-shell/extensions/guide-shell/index.ts +2 -2
  564. package/packages/pm-guide-shell/extensions/guide-shell/manifest.json +2 -2
  565. package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +1 -1
  566. package/packages/pm-kanban/README.md +97 -0
  567. package/packages/pm-kanban/extensions/kanban/index.ts +191 -0
  568. package/packages/pm-kanban/extensions/kanban/manifest.json +19 -0
  569. package/packages/pm-kanban/package.json +57 -0
  570. package/packages/pm-lifecycle-hooks/extensions/lifecycle-hooks/index.ts +1 -1
  571. package/packages/pm-lifecycle-hooks/extensions/lifecycle-hooks/manifest.json +2 -2
  572. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/index.ts +2 -2
  573. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/manifest.json +2 -2
  574. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.ts +1 -1
  575. package/packages/pm-search-advanced/extensions/search-advanced/index.ts +2 -2
  576. package/packages/pm-search-advanced/extensions/search-advanced/manifest.json +2 -2
  577. package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +1 -1
  578. package/packages/pm-templates/extensions/templates/index.ts +2 -2
  579. package/packages/pm-templates/extensions/templates/manifest.json +2 -2
  580. package/packages/pm-templates/extensions/templates/runtime.ts +1 -1
  581. package/packages/pm-todos/extensions/todos/index.ts +3 -3
  582. package/packages/pm-todos/extensions/todos/manifest.json +2 -2
  583. package/packages/pm-todos/extensions/todos/runtime-loader.ts +19 -7
  584. package/packages/pm-todos/extensions/todos/runtime.ts +177 -43
  585. package/plugins/pm-claude/scripts/pm-mcp-server.mjs +2 -2
  586. package/plugins/pm-codex/scripts/pm-mcp-server.mjs +2 -2
  587. package/scripts/bundle-cli.mjs +1 -1
  588. package/dist/cli-bundle/chunks/activity-54TXGJ2T.js +0 -18
  589. package/dist/cli-bundle/chunks/aggregate-63NWNIBR.js.map +0 -1
  590. package/dist/cli-bundle/chunks/aggregate-YHCYX2EV.js.map +0 -7
  591. package/dist/cli-bundle/chunks/chunk-6EL7SW5C.js.map +0 -7
  592. package/dist/cli-bundle/chunks/chunk-6W3Y65PL.js.map +0 -7
  593. package/dist/cli-bundle/chunks/chunk-AEACLRVH.js.map +0 -7
  594. package/dist/cli-bundle/chunks/chunk-B74BP6IS.js +0 -78
  595. package/dist/cli-bundle/chunks/chunk-B74BP6IS.js.map +0 -7
  596. package/dist/cli-bundle/chunks/chunk-BFFO3AIB.js.map +0 -1
  597. package/dist/cli-bundle/chunks/chunk-C4C3EJCJ.js.map +0 -7
  598. package/dist/cli-bundle/chunks/chunk-EYPINTFR.js.map +0 -7
  599. package/dist/cli-bundle/chunks/chunk-FBLT6WGK.js +0 -75
  600. package/dist/cli-bundle/chunks/chunk-FBLT6WGK.js.map +0 -1
  601. package/dist/cli-bundle/chunks/chunk-GQYJEEFX.js.map +0 -1
  602. package/dist/cli-bundle/chunks/chunk-HBAEFWX3.js.map +0 -7
  603. package/dist/cli-bundle/chunks/chunk-HC2S36NB.js.map +0 -1
  604. package/dist/cli-bundle/chunks/chunk-IAP5KYBQ.js.map +0 -1
  605. package/dist/cli-bundle/chunks/chunk-INPHFO33.js +0 -764
  606. package/dist/cli-bundle/chunks/chunk-INPHFO33.js.map +0 -7
  607. package/dist/cli-bundle/chunks/chunk-IOT6WRL5.js +0 -86
  608. package/dist/cli-bundle/chunks/chunk-IOT6WRL5.js.map +0 -7
  609. package/dist/cli-bundle/chunks/chunk-ISEKN64V.js +0 -35
  610. package/dist/cli-bundle/chunks/chunk-ISEKN64V.js.map +0 -7
  611. package/dist/cli-bundle/chunks/chunk-J3NMWFIN.js +0 -115
  612. package/dist/cli-bundle/chunks/chunk-J3NMWFIN.js.map +0 -1
  613. package/dist/cli-bundle/chunks/chunk-J7I4C5ZB.js.map +0 -7
  614. package/dist/cli-bundle/chunks/chunk-JKL6HRMV.js.map +0 -7
  615. package/dist/cli-bundle/chunks/chunk-KJZOSF7J.js.map +0 -1
  616. package/dist/cli-bundle/chunks/chunk-L7UXKP2I.js.map +0 -1
  617. package/dist/cli-bundle/chunks/chunk-LNEDHJNQ.js.map +0 -1
  618. package/dist/cli-bundle/chunks/chunk-M6TUBOGW.js.map +0 -1
  619. package/dist/cli-bundle/chunks/chunk-MEXZ5XUM.js.map +0 -7
  620. package/dist/cli-bundle/chunks/chunk-N5B6WZC5.js.map +0 -1
  621. package/dist/cli-bundle/chunks/chunk-NJ73ALW2.js +0 -761
  622. package/dist/cli-bundle/chunks/chunk-NJ73ALW2.js.map +0 -1
  623. package/dist/cli-bundle/chunks/chunk-NVXGVEFD.js +0 -83
  624. package/dist/cli-bundle/chunks/chunk-NVXGVEFD.js.map +0 -1
  625. package/dist/cli-bundle/chunks/chunk-OF7V47P3.js.map +0 -1
  626. package/dist/cli-bundle/chunks/chunk-OHDQNKJB.js.map +0 -7
  627. package/dist/cli-bundle/chunks/chunk-PEL2NLQE.js +0 -118
  628. package/dist/cli-bundle/chunks/chunk-PEL2NLQE.js.map +0 -7
  629. package/dist/cli-bundle/chunks/chunk-PRVTGX64.js.map +0 -7
  630. package/dist/cli-bundle/chunks/chunk-RAWA3Y7O.js.map +0 -1
  631. package/dist/cli-bundle/chunks/chunk-SMXSDY7J.js.map +0 -7
  632. package/dist/cli-bundle/chunks/chunk-SUREE24M.js.map +0 -1
  633. package/dist/cli-bundle/chunks/chunk-TKPP4GOO.js +0 -654
  634. package/dist/cli-bundle/chunks/chunk-TKPP4GOO.js.map +0 -1
  635. package/dist/cli-bundle/chunks/chunk-VSAABFGQ.js.map +0 -1
  636. package/dist/cli-bundle/chunks/chunk-W2VMLL5S.js +0 -32
  637. package/dist/cli-bundle/chunks/chunk-W2VMLL5S.js.map +0 -1
  638. package/dist/cli-bundle/chunks/chunk-XVYKWZNL.js.map +0 -7
  639. package/dist/cli-bundle/chunks/chunk-XXKV4UWE.js.map +0 -7
  640. package/dist/cli-bundle/chunks/chunk-ZLWRPBOW.js.map +0 -1
  641. package/dist/cli-bundle/chunks/chunk-ZV7IQ23N.js +0 -657
  642. package/dist/cli-bundle/chunks/chunk-ZV7IQ23N.js.map +0 -7
  643. package/dist/cli-bundle/chunks/close-JEBZXONN.js +0 -15
  644. package/dist/cli-bundle/chunks/config-NCNNWF6R.js.map +0 -7
  645. package/dist/cli-bundle/chunks/config-SW3U7XP2.js.map +0 -1
  646. package/dist/cli-bundle/chunks/context-55VEOYI3.js.map +0 -1
  647. package/dist/cli-bundle/chunks/context-5LB7UGKE.js.map +0 -7
  648. package/dist/cli-bundle/chunks/contracts-JXFGBOYT.js.map +0 -1
  649. package/dist/cli-bundle/chunks/contracts-SY6PDFIK.js.map +0 -7
  650. package/dist/cli-bundle/chunks/create-CLSCHGJJ.js +0 -30
  651. package/dist/cli-bundle/chunks/history-ALTM2RRP.js +0 -20
  652. package/dist/cli-bundle/chunks/history-redact-5YGLWUDH.js +0 -21
  653. package/dist/cli-bundle/chunks/init-C4CRHW22.js +0 -21
  654. package/dist/cli-bundle/chunks/register-list-query-CCMHGZTF.js.map +0 -7
  655. package/dist/cli-bundle/chunks/register-list-query-OM3E2KMY.js.map +0 -1
  656. package/dist/cli-bundle/chunks/register-mutation-N3CDEGZU.js.map +0 -1
  657. package/dist/cli-bundle/chunks/register-mutation-UXTTWL6N.js.map +0 -7
  658. package/dist/cli-bundle/chunks/register-setup-G5LTSFYK.js.map +0 -1
  659. package/dist/cli-bundle/chunks/register-setup-TWHKICM2.js.map +0 -7
  660. package/dist/cli-bundle/chunks/restore-LQHXBAY5.js +0 -19
  661. package/dist/cli-bundle/chunks/schema-C6QA367T.js.map +0 -7
  662. package/dist/cli-bundle/chunks/schema-QO5I4FBL.js.map +0 -1
  663. package/dist/cli-bundle/chunks/stats-TCW2SZQG.js.map +0 -7
  664. package/dist/cli-bundle/chunks/stats-TKC6CAKB.js.map +0 -1
  665. package/dist/cli-bundle/chunks/test-WA6RZGM2.js +0 -36
  666. package/dist/cli-bundle/chunks/test-runs-FQ5WNQLP.js.map +0 -1
  667. package/dist/cli-bundle/chunks/test-runs-PX73DMMI.js.map +0 -7
  668. package/dist/cli-bundle/chunks/update-BSKMQOYH.js +0 -28
  669. package/dist/cli-bundle/chunks/update-FIGYNQ2I.js +0 -24
  670. package/dist/cli-bundle/chunks/validate-54SYJ7QW.js.map +0 -1
  671. package/dist/cli-bundle/chunks/validate-HYZNIB6W.js.map +0 -7
  672. package/docs/examples/policy-restricted-extension/index.js +0 -21
  673. package/packages/pm-beads/extensions/beads/index.js +0 -64
  674. package/packages/pm-beads/extensions/beads/runtime-loader.js +0 -86
  675. package/packages/pm-beads/extensions/beads/runtime.js +0 -482
  676. package/packages/pm-calendar/extensions/calendar/index.js +0 -150
  677. package/packages/pm-calendar/extensions/calendar/runtime.js +0 -126
  678. package/packages/pm-command-kit/extensions/command-kit/index.js +0 -181
  679. package/packages/pm-governance-audit/extensions/governance-audit/index.js +0 -177
  680. package/packages/pm-governance-audit/extensions/governance-audit/runtime.js +0 -153
  681. package/packages/pm-guide-shell/extensions/guide-shell/index.js +0 -98
  682. package/packages/pm-guide-shell/extensions/guide-shell/runtime.js +0 -294
  683. package/packages/pm-lifecycle-hooks/extensions/lifecycle-hooks/index.js +0 -18
  684. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/index.js +0 -124
  685. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.js +0 -110
  686. package/packages/pm-search-advanced/extensions/search-advanced/index.js +0 -258
  687. package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +0 -361
  688. package/packages/pm-templates/extensions/templates/index.js +0 -132
  689. package/packages/pm-templates/extensions/templates/runtime.js +0 -35
  690. package/packages/pm-todos/extensions/todos/index.js +0 -81
  691. package/packages/pm-todos/extensions/todos/runtime-loader.js +0 -86
  692. package/packages/pm-todos/extensions/todos/runtime.js +0 -545
  693. /package/dist/cli-bundle/chunks/{activity-54TXGJ2T.js.map → activity-AW6XVFH6.js.map} +0 -0
  694. /package/dist/cli-bundle/chunks/{activity-N7RVTLBQ.js.map → activity-DBLQVIP6.js.map} +0 -0
  695. /package/dist/cli-bundle/chunks/{chunk-F32L4HR6.js.map → chunk-27BXPBAY.js.map} +0 -0
  696. /package/dist/cli-bundle/chunks/{chunk-5BBEWX6C.js.map → chunk-3VGN2UWE.js.map} +0 -0
  697. /package/dist/cli-bundle/chunks/{chunk-FMWW2JDU.js.map → chunk-AXIDKKAT.js.map} +0 -0
  698. /package/dist/cli-bundle/chunks/{chunk-TIM4OD74.js.map → chunk-BDTISOSD.js.map} +0 -0
  699. /package/dist/cli-bundle/chunks/{chunk-CZIFFMZI.js.map → chunk-DDPTYJIM.js.map} +0 -0
  700. /package/dist/cli-bundle/chunks/{chunk-AYPQUFCX.js.map → chunk-EJUDVUYZ.js.map} +0 -0
  701. /package/dist/cli-bundle/chunks/{chunk-EOGBMLCE.js.map → chunk-EVMTBV6V.js.map} +0 -0
  702. /package/dist/cli-bundle/chunks/{chunk-CG3KP6I5.js.map → chunk-G7I7DEZA.js.map} +0 -0
  703. /package/dist/cli-bundle/chunks/{chunk-F4BNR2IN.js.map → chunk-HYTGA6GI.js.map} +0 -0
  704. /package/dist/cli-bundle/chunks/{chunk-2WCYE3IF.js.map → chunk-HZZEHPRG.js.map} +0 -0
  705. /package/dist/cli-bundle/chunks/{chunk-YV2OSAMS.js.map → chunk-IJYK2T43.js.map} +0 -0
  706. /package/dist/cli-bundle/chunks/{chunk-QOUOMPHO.js.map → chunk-JPECA746.js.map} +0 -0
  707. /package/dist/cli-bundle/chunks/{chunk-OQ2E64FH.js.map → chunk-KNPEF7QG.js.map} +0 -0
  708. /package/dist/cli-bundle/chunks/{chunk-3BKH2CL3.js.map → chunk-L5OEFZQG.js.map} +0 -0
  709. /package/dist/cli-bundle/chunks/{chunk-5S4ZGDB2.js.map → chunk-N74UMG5H.js.map} +0 -0
  710. /package/dist/cli-bundle/chunks/{chunk-IXAZI443.js.map → chunk-NFDPYAIP.js.map} +0 -0
  711. /package/dist/cli-bundle/chunks/{chunk-SKC4UTRP.js.map → chunk-NKZAN7BD.js.map} +0 -0
  712. /package/dist/cli-bundle/chunks/{chunk-JPJDP4VU.js.map → chunk-NWMZWYYB.js.map} +0 -0
  713. /package/dist/cli-bundle/chunks/{chunk-KKX4Z2SE.js.map → chunk-OTUHB4HS.js.map} +0 -0
  714. /package/dist/cli-bundle/chunks/{chunk-WB5BYQMF.js.map → chunk-SLMUGTK3.js.map} +0 -0
  715. /package/dist/cli-bundle/chunks/{chunk-I6QMJ2XT.js.map → chunk-WYDHYJPO.js.map} +0 -0
  716. /package/dist/cli-bundle/chunks/{chunk-KIEAK7YE.js.map → chunk-ZRP4VG5U.js.map} +0 -0
  717. /package/dist/cli-bundle/chunks/{close-JEBZXONN.js.map → close-E6ZZGCJY.js.map} +0 -0
  718. /package/dist/cli-bundle/chunks/{close-QHMVWM7M.js.map → close-TQYAAFJP.js.map} +0 -0
  719. /package/dist/cli-bundle/chunks/{create-O4VONGPG.js.map → context-B6275WPX.js.map} +0 -0
  720. /package/dist/cli-bundle/chunks/{create-CLSCHGJJ.js.map → context-OCZ3FJ4Z.js.map} +0 -0
  721. /package/dist/cli-bundle/chunks/{extension-YQF4CPIR.js.map → create-OH3BDGBB.js.map} +0 -0
  722. /package/dist/cli-bundle/chunks/{extension-3JYWJ5K2.js.map → create-RLRJMRTM.js.map} +0 -0
  723. /package/dist/cli-bundle/chunks/{history-ALTM2RRP.js.map → extension-CPSLJQVE.js.map} +0 -0
  724. /package/dist/cli-bundle/chunks/{history-RUKPKNY7.js.map → extension-CXJ6RELI.js.map} +0 -0
  725. /package/dist/cli-bundle/chunks/{gc-BEJMQT64.js.map → gc-7GQYOS2G.js.map} +0 -0
  726. /package/dist/cli-bundle/chunks/{gc-JEFQDJPA.js.map → gc-LPVMKJQJ.js.map} +0 -0
  727. /package/dist/cli-bundle/chunks/{health-JJJOY7DJ.js.map → health-3IPFLKXB.js.map} +0 -0
  728. /package/dist/cli-bundle/chunks/{health-P67NZ6TT.js.map → health-GZXGBZ36.js.map} +0 -0
  729. /package/dist/cli-bundle/chunks/{history-redact-YY4XYVEP.js.map → history-NERDJNUB.js.map} +0 -0
  730. /package/dist/cli-bundle/chunks/{history-redact-5YGLWUDH.js.map → history-WSZHY3PN.js.map} +0 -0
  731. /package/dist/cli-bundle/chunks/{init-C4CRHW22.js.map → history-redact-MP6CH7U5.js.map} +0 -0
  732. /package/dist/cli-bundle/chunks/{init-HBFGYS66.js.map → history-redact-O3NBCNWC.js.map} +0 -0
  733. /package/dist/cli-bundle/chunks/{list-C7R33MD5.js.map → init-64XDLQJB.js.map} +0 -0
  734. /package/dist/cli-bundle/chunks/{list-DSN6UNFB.js.map → init-PAX32BJA.js.map} +0 -0
  735. /package/dist/cli-bundle/chunks/{restore-LL2WLEDG.js.map → list-DNBJVO3E.js.map} +0 -0
  736. /package/dist/cli-bundle/chunks/{restore-LQHXBAY5.js.map → list-G5Y65VF6.js.map} +0 -0
  737. /package/dist/cli-bundle/chunks/{search-2EI6EAXH.js.map → restore-4MHZFJ2E.js.map} +0 -0
  738. /package/dist/cli-bundle/chunks/{search-QBFBLQRO.js.map → restore-YALDGTQR.js.map} +0 -0
  739. /package/dist/cli-bundle/chunks/{test-NV2DRPUS.js.map → schema-73HR2OJW.js.map} +0 -0
  740. /package/dist/cli-bundle/chunks/{test-WA6RZGM2.js.map → schema-U6LJKSIR.js.map} +0 -0
  741. /package/dist/cli-bundle/chunks/{update-BSKMQOYH.js.map → search-AXPXKZER.js.map} +0 -0
  742. /package/dist/cli-bundle/chunks/{update-FIGYNQ2I.js.map → search-KILGT37L.js.map} +0 -0
  743. /package/dist/cli-bundle/chunks/{telemetry-BT2VSWU2.js.map → telemetry-BZUF6H7G.js.map} +0 -0
  744. /package/dist/cli-bundle/chunks/{telemetry-LQ6FRTUT.js.map → telemetry-GAHHQTOS.js.map} +0 -0
@@ -4,7 +4,7 @@
4
4
  * Implements the pm extension command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="68131f37-e747-546c-ab4d-f986cdd37b76")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0e9a5528-9595-5a89-89b7-5a5acce477a8")}catch(e){}}();
8
8
  import { execFile } from "node:child_process";
9
9
  import fs from "node:fs/promises";
10
10
  import os from "node:os";
@@ -16,9 +16,11 @@ import { pathExists } from "../../core/fs/fs-utils.js";
16
16
  import { isPathWithinDirectory } from "../../core/fs/path-utils.js";
17
17
  import { EXIT_CODE } from "../../core/shared/constants.js";
18
18
  import { PmCliError } from "../../core/shared/errors.js";
19
+ import { levenshteinDistanceWithinLimit } from "../../core/shared/levenshtein.js";
19
20
  import { nowIso } from "../../core/shared/time.js";
20
21
  import { resolveGlobalPmRoot, resolvePmRoot } from "../../core/store/paths.js";
21
22
  import { readSettings, writeSettings } from "../../core/store/settings.js";
23
+ import { ensureTypeFolderScaffold } from "./schema.js";
22
24
  // Cohesive helper groups now live in ./extension/* sibling modules. They are
23
25
  // imported for the command wiring that stays here and re-exported below so
24
26
  // existing import sites (sdk barrels, upgrade.ts, tests) keep importing the
@@ -39,6 +41,41 @@ const EXTENSION_INSTALL_COPY_ATTEMPTS = 3;
39
41
  const EXTENSION_INSTALL_LOCK_ATTEMPTS = 120;
40
42
  const EXTENSION_INSTALL_LOCK_DELAY_MS = 250;
41
43
  const EXTENSION_INSTALL_LOCK_STALE_MS = 120_000;
44
+ const LIFECYCLE_ACTION_TARGETS = [
45
+ ["install", "install", "--install"],
46
+ ["uninstall", "uninstall", "--uninstall"],
47
+ ["explore", "explore", "--explore"],
48
+ ["list", "explore", "--explore"],
49
+ ["manage", "manage", "--manage"],
50
+ ["describe", "describe", "--describe"],
51
+ ["reload", "reload", "--reload"],
52
+ ["doctor", "doctor", "--doctor"],
53
+ ["catalog", "catalog", "--catalog"],
54
+ ["init", "init", "--init"],
55
+ ["scaffold", "init", "--scaffold"],
56
+ ["adopt", "adopt", "--adopt"],
57
+ ["adopt-all", "adopt-all", "--adopt-all"],
58
+ ["activate", "activate", "--activate"],
59
+ ["deactivate", "deactivate", "--deactivate"],
60
+ ];
61
+ const LIFECYCLE_ACTION_FLAG_HINT = LIFECYCLE_ACTION_TARGETS.map(([, , flag]) => flag)
62
+ .filter((flag, index, flags) => flags.indexOf(flag) === index)
63
+ .join(", ");
64
+ const LIFECYCLE_ACTION_FLAGS = {
65
+ install: "--install",
66
+ uninstall: "--uninstall",
67
+ explore: "--explore",
68
+ manage: "--manage",
69
+ describe: "--describe",
70
+ reload: "--reload",
71
+ doctor: "--doctor",
72
+ catalog: "--catalog",
73
+ adopt: "--adopt",
74
+ "adopt-all": "--adopt-all",
75
+ activate: "--activate",
76
+ deactivate: "--deactivate",
77
+ init: "--init",
78
+ };
42
79
  const NATIVE_OUTPUT_MARKER = "__pm_native_output";
43
80
  function buildExtensionPolicyDetails(policy) {
44
81
  const overrides = (policy.extension_overrides ?? [])
@@ -268,49 +305,116 @@ function clearExtensionState(settings, name) {
268
305
  return (settings.extensions.enabled.join("\u0000") !== previousEnabled.join("\u0000") ||
269
306
  settings.extensions.disabled.join("\u0000") !== previousDisabled.join("\u0000"));
270
307
  }
271
- function resolveAction(target, options) {
272
- const selected = [...new Set([
273
- options.install ? "install" : null,
274
- options.uninstall ? "uninstall" : null,
275
- options.explore ? "explore" : null,
276
- options.manage ? "manage" : null,
277
- options.describe ? "describe" : null,
278
- options.reload ? "reload" : null,
279
- options.doctor ? "doctor" : null,
280
- options.catalog ? "catalog" : null,
281
- options.init ? "init" : null,
282
- options.scaffold ? "init" : null,
283
- options.adopt ? "adopt" : null,
284
- options.adoptAll ? "adopt-all" : null,
285
- options.activate ? "activate" : null,
286
- options.deactivate ? "deactivate" : null,
287
- ].filter((value) => value !== null))];
288
- if (selected.length === 0) {
289
- if (typeof target === "string" && target.trim().toLowerCase() === "doctor") {
290
- return "doctor";
291
- }
292
- if (typeof target === "string" && target.trim().toLowerCase() === "reload") {
293
- return "reload";
294
- }
295
- if (typeof target === "string" && target.trim().toLowerCase() === "catalog") {
296
- return "catalog";
297
- }
298
- if (typeof target === "string" && (target.trim().toLowerCase() === "init" || target.trim().toLowerCase() === "scaffold")) {
299
- return "init";
300
- }
301
- if (typeof target === "string" && target.trim().toLowerCase() === "explore") {
302
- return "explore";
308
+ function suggestLifecycleActionTarget(target) {
309
+ const normalizedTarget = target.trim().toLowerCase();
310
+ const exactMatch = LIFECYCLE_ACTION_TARGETS.find(([candidate]) => candidate === normalizedTarget);
311
+ if (exactMatch) {
312
+ return { action: exactMatch[1], flag: exactMatch[2] };
313
+ }
314
+ const maxDistance = normalizedTarget.length <= 4 ? 1 : 2;
315
+ let nearest = null;
316
+ for (const [candidate, action, flag] of LIFECYCLE_ACTION_TARGETS) {
317
+ const distance = levenshteinDistanceWithinLimit(normalizedTarget, candidate, maxDistance);
318
+ if (distance === null) {
319
+ continue;
303
320
  }
304
- if (typeof target === "string" && target.trim().toLowerCase() === "manage") {
305
- return "manage";
321
+ if (nearest === null) {
322
+ nearest = { action, flag, distance };
323
+ continue;
306
324
  }
307
- if (typeof target === "string" && (target.trim().toLowerCase() === "list" || target.trim() === "")) {
308
- return "explore";
325
+ if (distance < nearest.distance) {
326
+ nearest = { action, flag, distance };
309
327
  }
328
+ }
329
+ return nearest === null ? null : { action: nearest.action, flag: nearest.flag };
330
+ }
331
+ function buildUnknownLifecycleActionError(target, options) {
332
+ const noun = options.vocabulary === "package" ? "package" : "extension";
333
+ const suggestion = suggestLifecycleActionTarget(target);
334
+ if (!suggestion) {
335
+ return new PmCliError(`One action flag is required. Use one of: ${LIFECYCLE_ACTION_FLAG_HINT}. Bare \`pm package\` and \`pm extension\` default to --explore.`, EXIT_CODE.USAGE);
336
+ }
337
+ const command = `pm ${noun} ${suggestion.flag}`;
338
+ return new PmCliError(`Unknown ${noun} lifecycle action "${target}". Did you mean "${suggestion.flag}"?`, EXIT_CODE.USAGE, {
339
+ code: "unknown_lifecycle_action",
340
+ required: `Use one of: ${LIFECYCLE_ACTION_FLAG_HINT}.`,
341
+ examples: [command, `pm ${noun} --help`],
342
+ recovery: {
343
+ attempted_command: `pm ${noun} ${target}`,
344
+ suggested_retry: command,
345
+ fallback_candidates: [
346
+ {
347
+ source: "lifecycle_action",
348
+ command,
349
+ reason: `nearest lifecycle action for "${target}"`,
350
+ },
351
+ ],
352
+ },
353
+ });
354
+ }
355
+ // Maps each boolean action flag to the lifecycle action it selects. `scaffold`
356
+ // aliases `init` and `adoptAll` selects `adopt-all`; every other flag maps to its
357
+ // like-named action. Dispatching through the table keeps `resolveAction` flat.
358
+ const EXTENSION_ACTION_FLAG_SELECTORS = [
359
+ ["install", "install"],
360
+ ["uninstall", "uninstall"],
361
+ ["explore", "explore"],
362
+ ["manage", "manage"],
363
+ ["describe", "describe"],
364
+ ["reload", "reload"],
365
+ ["doctor", "doctor"],
366
+ ["catalog", "catalog"],
367
+ ["init", "init"],
368
+ ["scaffold", "init"],
369
+ ["adopt", "adopt"],
370
+ ["adoptAll", "adopt-all"],
371
+ ["activate", "activate"],
372
+ ["deactivate", "deactivate"],
373
+ ];
374
+ /**
375
+ * Map a bare positional token (already trimmed and lower-cased) to the lifecycle
376
+ * action it implies for `pm extension <token>` / `pm package <token>`: the
377
+ * `doctor`/`reload`/`catalog`/`init`/`scaffold`/`explore`/`manage` keywords, with
378
+ * `list` and the empty string both meaning `explore`. Returns `null` for anything
379
+ * else so the caller can raise a did-you-mean error.
380
+ */
381
+ function resolveImplicitActionFromTarget(normalizedTarget) {
382
+ if (normalizedTarget === "doctor") {
383
+ return "doctor";
384
+ }
385
+ if (normalizedTarget === "reload") {
386
+ return "reload";
387
+ }
388
+ if (normalizedTarget === "catalog") {
389
+ return "catalog";
390
+ }
391
+ if (normalizedTarget === "init" || normalizedTarget === "scaffold") {
392
+ return "init";
393
+ }
394
+ if (normalizedTarget === "explore") {
395
+ return "explore";
396
+ }
397
+ if (normalizedTarget === "manage") {
398
+ return "manage";
399
+ }
400
+ if (normalizedTarget === "list" || normalizedTarget === "") {
401
+ return "explore";
402
+ }
403
+ return null;
404
+ }
405
+ function resolveAction(target, options) {
406
+ const selected = [
407
+ ...new Set(EXTENSION_ACTION_FLAG_SELECTORS.filter(([flag]) => options[flag] === true).map(([, mappedAction]) => mappedAction)),
408
+ ];
409
+ if (selected.length === 0) {
310
410
  if (target === undefined) {
311
411
  return "explore";
312
412
  }
313
- throw new PmCliError("One action flag is required. Use one of: --install, --uninstall, --explore, --manage, --describe, --reload, --doctor, --catalog, --init/--scaffold, --adopt, --adopt-all, --activate, --deactivate. Bare `pm package` and `pm extension` default to --explore.", EXIT_CODE.USAGE);
413
+ const implicitAction = resolveImplicitActionFromTarget(target.trim().toLowerCase());
414
+ if (implicitAction) {
415
+ return implicitAction;
416
+ }
417
+ throw buildUnknownLifecycleActionError(target, options);
314
418
  }
315
419
  if (selected.length > 1) {
316
420
  throw new PmCliError("Extension action flags are mutually exclusive.", EXIT_CODE.USAGE);
@@ -368,6 +472,34 @@ function resolveUpdateCheckResolution(managedEntry) {
368
472
  reason: "no_update_check_recorded",
369
473
  };
370
474
  }
475
+ /**
476
+ * Assemble a {@link ManagedExtensionSummary} from a directory's resolved identity
477
+ * (name/version/entry/enabled state) and its managed-state record, projecting the
478
+ * managed-source provenance and the resolved update-check status. Runtime
479
+ * activation fields default to "not yet probed" (`runtime_active: null`,
480
+ * `activation_status: "unknown"`) so a later runtime probe can overlay live state.
481
+ */
482
+ function buildInstalledExtensionSummary(identity, scope, managedEntry, updateCheck) {
483
+ return {
484
+ name: identity.name,
485
+ directory: identity.directory,
486
+ version: identity.version,
487
+ entry: identity.entry,
488
+ scope,
489
+ active: identity.enabled,
490
+ enabled: identity.enabled,
491
+ runtime_active: null,
492
+ activation_status: "unknown",
493
+ managed: Boolean(managedEntry),
494
+ source: managedEntry?.source,
495
+ update_available: managedEntry?.update_available,
496
+ last_update_check_at: managedEntry?.last_update_check_at,
497
+ last_update_remote_commit: managedEntry?.last_update_remote_commit,
498
+ update_error: managedEntry?.update_error,
499
+ update_check_status: updateCheck.status,
500
+ update_check_reason: updateCheck.reason,
501
+ };
502
+ }
371
503
  async function listInstalledExtensions(extensionsRoot, scope, settings, state) {
372
504
  if (!(await pathExists(extensionsRoot))) {
373
505
  return {
@@ -394,27 +526,13 @@ async function listInstalledExtensions(extensionsRoot, scope, settings, state) {
394
526
  if (!(await pathExists(manifestPath))) {
395
527
  warnings.push(`extension_manifest_missing:${scope}:${directoryName}`);
396
528
  const managedEntry = managedByDirectory.get(normalizeExtensionNameForMatch(directoryName));
397
- const updateCheck = resolveUpdateCheckResolution(managedEntry);
398
- const enabled = managedEntry ? isExtensionEnabled(settings, managedEntry.name) : false;
399
- summaries.push({
529
+ summaries.push(buildInstalledExtensionSummary({
400
530
  name: managedEntry?.name ?? directoryName,
401
531
  directory: directoryName,
402
532
  version: managedEntry?.manifest_version ?? "unknown",
403
533
  entry: managedEntry?.manifest_entry ?? "unknown",
404
- scope,
405
- active: enabled,
406
- enabled,
407
- runtime_active: null,
408
- activation_status: "unknown",
409
- managed: Boolean(managedEntry),
410
- source: managedEntry?.source,
411
- update_available: managedEntry?.update_available,
412
- last_update_check_at: managedEntry?.last_update_check_at,
413
- last_update_remote_commit: managedEntry?.last_update_remote_commit,
414
- update_error: managedEntry?.update_error,
415
- update_check_status: updateCheck.status,
416
- update_check_reason: updateCheck.reason,
417
- });
534
+ enabled: managedEntry ? isExtensionEnabled(settings, managedEntry.name) : false,
535
+ }, scope, managedEntry, resolveUpdateCheckResolution(managedEntry)));
418
536
  continue;
419
537
  }
420
538
  let rawManifest;
@@ -432,27 +550,13 @@ async function listInstalledExtensions(extensionsRoot, scope, settings, state) {
432
550
  }
433
551
  const managedEntry = managedByName.get(normalizeExtensionNameForMatch(manifest.name)) ??
434
552
  managedByDirectory.get(normalizeExtensionNameForMatch(directoryName));
435
- const updateCheck = resolveUpdateCheckResolution(managedEntry);
436
- const enabled = isExtensionEnabled(settings, manifest.name);
437
- summaries.push({
553
+ summaries.push(buildInstalledExtensionSummary({
438
554
  name: manifest.name,
439
555
  directory: directoryName,
440
556
  version: manifest.version,
441
557
  entry: manifest.entry,
442
- scope,
443
- active: enabled,
444
- enabled,
445
- runtime_active: null,
446
- activation_status: "unknown",
447
- managed: Boolean(managedEntry),
448
- source: managedEntry?.source,
449
- update_available: managedEntry?.update_available,
450
- last_update_check_at: managedEntry?.last_update_check_at,
451
- last_update_remote_commit: managedEntry?.last_update_remote_commit,
452
- update_error: managedEntry?.update_error,
453
- update_check_status: updateCheck.status,
454
- update_check_reason: updateCheck.reason,
455
- });
558
+ enabled: isExtensionEnabled(settings, manifest.name),
559
+ }, scope, managedEntry, resolveUpdateCheckResolution(managedEntry)));
456
560
  }
457
561
  return {
458
562
  extensions: summaries.sort((left, right) => left.name.localeCompare(right.name)),
@@ -542,6 +646,7 @@ async function probeRuntimeCommandPathsForInstall(pmRoot, settings, refreshedIns
542
646
  installed: applyDoctorRuntimeActivationState(refreshedInstalled, loadResult, activationResult),
543
647
  warnings: [...loadResult.warnings, ...activationResult.warnings],
544
648
  activation_failures: collectActivationFailureDiagnostics(activationResult.failed),
649
+ item_type_registrations: activationResult.registrations.item_types,
545
650
  };
546
651
  }
547
652
  async function checkGithubUpdate(source, gitCommandRunner = runGitCommand) {
@@ -673,13 +778,37 @@ function resolveGithubOption(options) {
673
778
  }
674
779
  return undefined;
675
780
  }
676
- function requireTarget(target, action) {
781
+ function getLifecycleActionFlag(action) {
782
+ return LIFECYCLE_ACTION_FLAGS[action];
783
+ }
784
+ function requireTarget(target, action, options = {}) {
677
785
  const normalized = target?.trim();
678
786
  if (!normalized) {
679
787
  if (action === "init") {
680
788
  throw new PmCliError('Action "init" requires a scaffold target path (for example: pm package init ./my-package or pm extension init ./my-extension).', EXIT_CODE.USAGE);
681
789
  }
682
- throw new PmCliError(`Action "${action}" requires an extension name or source target argument.`, EXIT_CODE.USAGE);
790
+ const noun = options.vocabulary === "package" ? "package" : "extension";
791
+ const targetName = action === "install" ? "source" : "name";
792
+ const targetLabel = `${noun} ${targetName}`;
793
+ const actionFlag = getLifecycleActionFlag(action);
794
+ const commandTarget = `<${targetName}>`;
795
+ const command = `pm ${noun} ${actionFlag} ${commandTarget}`;
796
+ throw new PmCliError(`Action "${action}" requires ${targetLabel} input.`, EXIT_CODE.USAGE, {
797
+ code: "missing_lifecycle_target",
798
+ required: `Provide a ${targetName} target for ${action}.`,
799
+ examples: [`pm ${noun} ${action} ${commandTarget}`, command, `pm ${noun} --help`],
800
+ recovery: {
801
+ attempted_command: `pm ${noun} ${action}`,
802
+ suggested_retry: command,
803
+ fallback_candidates: [
804
+ {
805
+ source: "lifecycle_action",
806
+ command,
807
+ reason: `flag-form ${action} command with required ${targetName} target`,
808
+ },
809
+ ],
810
+ },
811
+ });
683
812
  }
684
813
  return normalized;
685
814
  }
@@ -697,50 +826,128 @@ function collectGlobalOutputOverrideDoctorWarnings(activationResult) {
697
826
  return [...new Set(warnings)].sort((left, right) => left.localeCompare(right));
698
827
  }
699
828
  /**
700
- * Implements run extension for the public runtime surface of this module.
829
+ * Doctor advisory: flag loaded extensions that contribute GLOBAL schema (custom
830
+ * item types or fields) yet also declare narrow `activation.commands`.
831
+ *
832
+ * Custom item types and fields must be present for the built-in commands the
833
+ * extension does not own and cannot enumerate (`pm create <type>`,
834
+ * `pm list --type <type>`, `pm validate`). Declaring `activation.commands` gates
835
+ * lazy activation to only the listed command paths, so the package never
836
+ * activates for those built-ins and its custom type silently fails to register —
837
+ * a quiet footgun (decision pm-halx). The `schema` scaffold deliberately omits
838
+ * the field; this advisory catches hand-authored packages that do not. It is
839
+ * doctor-only and non-blocking — `pm health` does not surface it — so the author
840
+ * can either drop `activation.commands` or, when the schema is intentionally
841
+ * command-scoped, knowingly ignore the hint.
701
842
  */
702
- export async function runExtension(target, options, global) {
703
- const action = resolveAction(target, options);
704
- if ((options.strictExit === true || options.failOnWarn === true) && action !== "doctor") {
705
- throw new PmCliError("--strict-exit and --fail-on-warn are only valid with --doctor.", EXIT_CODE.USAGE);
843
+ function collectSchemaNarrowActivationDoctorWarnings(loadResult, activationResult) {
844
+ const schemaContributors = new Set();
845
+ for (const entry of activationResult.registrations.item_types) {
846
+ if (entry.types.length > 0) {
847
+ schemaContributors.add(`${entry.layer}:${normalizeExtensionNameForMatch(entry.name)}`);
848
+ }
706
849
  }
707
- if (options.trace === true && action !== "doctor") {
708
- throw new PmCliError("--trace is only valid with --doctor.", EXIT_CODE.USAGE);
850
+ for (const entry of activationResult.registrations.item_fields) {
851
+ if (entry.fields.length > 0) {
852
+ schemaContributors.add(`${entry.layer}:${normalizeExtensionNameForMatch(entry.name)}`);
853
+ }
709
854
  }
710
- if (options.watch === true && action !== "reload") {
711
- throw new PmCliError("--watch is only valid with --reload.", EXIT_CODE.USAGE);
855
+ const warnings = [];
856
+ for (const extension of loadResult.loaded) {
857
+ if ((extension.activation?.commands ?? []).length === 0) {
858
+ continue;
859
+ }
860
+ if (schemaContributors.has(`${extension.layer}:${normalizeExtensionNameForMatch(extension.name)}`)) {
861
+ warnings.push(`extension_schema_narrow_activation:${extension.layer}:${extension.name}`);
862
+ }
712
863
  }
713
- if (options.runtimeProbe === true && action !== "manage") {
714
- throw new PmCliError("--runtime-probe is only valid with --manage.", EXIT_CODE.USAGE);
864
+ return [...new Set(warnings)].sort((left, right) => left.localeCompare(right));
865
+ }
866
+ /**
867
+ * Reject option/action combinations that are only meaningful for a specific
868
+ * lifecycle action — `--trace`/`--strict-exit`/`--fail-on-warn` require `--doctor`,
869
+ * `--watch` requires `--reload`, `--runtime-probe` requires `--manage`,
870
+ * `--fix-managed-state` requires `--manage`/`--doctor`, and
871
+ * `--capability`/`--declarative` require `--init`/`--scaffold`. Each guard pairs a
872
+ * "flag is set" predicate with the action(s) that permit it and throws a USAGE
873
+ * error on the first mismatch.
874
+ */
875
+ function assertExtensionActionOptionScope(action, options) {
876
+ const guards = [
877
+ {
878
+ triggered: options.strictExit === true || options.failOnWarn === true,
879
+ allowed: action === "doctor",
880
+ message: "--strict-exit and --fail-on-warn are only valid with --doctor.",
881
+ },
882
+ { triggered: options.trace === true, allowed: action === "doctor", message: "--trace is only valid with --doctor." },
883
+ { triggered: options.watch === true, allowed: action === "reload", message: "--watch is only valid with --reload." },
884
+ {
885
+ triggered: options.runtimeProbe === true,
886
+ allowed: action === "manage",
887
+ message: "--runtime-probe is only valid with --manage.",
888
+ },
889
+ {
890
+ triggered: options.fixManagedState === true,
891
+ allowed: action === "manage" || action === "doctor",
892
+ message: "--fix-managed-state is only valid with --manage or --doctor.",
893
+ },
894
+ {
895
+ triggered: options.capability !== undefined,
896
+ allowed: action === "init",
897
+ message: "--capability is only valid with --init/--scaffold.",
898
+ },
899
+ {
900
+ triggered: options.declarative === true,
901
+ allowed: action === "init",
902
+ message: "--declarative is only valid with --init/--scaffold.",
903
+ },
904
+ ];
905
+ for (const guard of guards) {
906
+ if (guard.triggered && !guard.allowed) {
907
+ throw new PmCliError(guard.message, EXIT_CODE.USAGE);
908
+ }
715
909
  }
716
- if (options.fixManagedState === true && action !== "manage" && action !== "doctor") {
717
- throw new PmCliError("--fix-managed-state is only valid with --manage or --doctor.", EXIT_CODE.USAGE);
910
+ }
911
+ /* c8 ignore start -- alias-normalization matrix is covered by resolveAction tests; this only rewrites positional aliases */
912
+ /**
913
+ * Collapse a positional target that merely repeats the action keyword
914
+ * (`pm extension doctor`, `reload`, `catalog`, or `init`/`scaffold`) to
915
+ * `undefined` so the action handlers treat it as "no target" rather than an
916
+ * extension name; otherwise the original target is returned unchanged.
917
+ */
918
+ function resolveNormalizedExtensionTarget(target, action, options) {
919
+ const normalizedInput = target?.trim().toLowerCase();
920
+ if (action === "doctor" && normalizedInput === "doctor") {
921
+ return undefined;
718
922
  }
719
- if (options.capability !== undefined && action !== "init") {
720
- throw new PmCliError("--capability is only valid with --init/--scaffold.", EXIT_CODE.USAGE);
923
+ if (action === "reload" && normalizedInput === "reload") {
924
+ return undefined;
721
925
  }
722
- /* c8 ignore start -- alias-normalization matrix is covered by resolveAction tests; this IIFE only rewrites positional aliases */
723
- const normalizedTarget = (() => {
724
- const normalizedInput = target?.trim().toLowerCase();
725
- if (action === "doctor" && normalizedInput === "doctor") {
726
- return undefined;
727
- }
728
- if (action === "reload" && normalizedInput === "reload") {
729
- return undefined;
730
- }
731
- if (action === "catalog" && normalizedInput === "catalog") {
732
- return undefined;
733
- }
734
- const inferredInitAlias = action === "init" &&
735
- options.init !== true &&
736
- options.scaffold !== true &&
737
- (normalizedInput === "init" || normalizedInput === "scaffold");
738
- if (inferredInitAlias) {
739
- return undefined;
740
- }
741
- return target;
742
- })();
743
- /* c8 ignore stop */
926
+ if (action === "catalog" && normalizedInput === "catalog") {
927
+ return undefined;
928
+ }
929
+ const inferredInitAlias = action === "init" &&
930
+ options.init !== true &&
931
+ options.scaffold !== true &&
932
+ (normalizedInput === "init" || normalizedInput === "scaffold");
933
+ if (inferredInitAlias) {
934
+ return undefined;
935
+ }
936
+ return target;
937
+ }
938
+ /* c8 ignore stop */
939
+ /**
940
+ * Entry point for the `pm extension` / `pm package` command surface. Resolves the
941
+ * requested lifecycle action and scope, rejects out-of-scope option usage,
942
+ * normalizes positional aliases, then dispatches to the matching action handler —
943
+ * each of which reads and writes managed-extension state, runtime-probes, and
944
+ * returns the canonical {@link ExtensionCommandResult}. `--doctor` results are
945
+ * flagged for native (non-JSON-wrapped) output.
946
+ */
947
+ export async function runExtension(target, options, global) {
948
+ const action = resolveAction(target, options);
949
+ assertExtensionActionOptionScope(action, options);
950
+ const normalizedTarget = resolveNormalizedExtensionTarget(target, action, options);
744
951
  const scope = resolveScope(options);
745
952
  const resolvedRoots = resolveExtensionRootsForScope(scope, global);
746
953
  const warnings = [];
@@ -774,475 +981,826 @@ export async function runExtension(target, options, global) {
774
981
  }
775
982
  return result;
776
983
  };
777
- if (action === "init") {
778
- const githubOption = resolveGithubOption(options);
779
- if (githubOption !== undefined || (typeof options.ref === "string" && options.ref.trim().length > 0)) {
780
- throw new PmCliError('Action "init" does not accept --gh/--github/--ref options.', EXIT_CODE.USAGE);
781
- }
782
- const scaffoldTarget = requireTarget(normalizedTarget, action);
783
- const scaffold = await scaffoldExtensionProject(scaffoldTarget, options.vocabulary ?? "extension", options.capability);
784
- const quotedTargetPath = JSON.stringify(scaffold.target_path);
785
- // Forward-slash the path for the copy-pasteable `cd` hint: Windows cmd.exe /
786
- // PowerShell reject the doubled backslashes JSON.stringify emits, while both
787
- // shells (and POSIX) accept forward slashes.
788
- const quotedShellTargetPath = JSON.stringify(scaffold.target_path.replace(/\\/g, "/"));
789
- return withResult({
790
- scaffolded: scaffold.created_directory || scaffold.files.some((entry) => entry.status === "created"),
791
- extension: {
792
- name: scaffold.extension_name,
793
- command: scaffold.command_name,
794
- },
795
- capability: scaffold.capability,
796
- target_path: scaffold.target_path,
797
- created_directory: scaffold.created_directory,
798
- files: scaffold.files,
799
- next_steps: [
800
- // The scaffold is authored in TypeScript (ADR pm-2c28); the manifest's
801
- // ./index.js entry only exists after a compile, so building comes first.
802
- ...(options.vocabulary === "package"
803
- ? [`Build the package: cd ${quotedShellTargetPath}, then run "npm install" and "npm run build"`]
804
- : [
805
- `Build the extension: cd ${quotedShellTargetPath}, then run "npm install -D typescript @types/node @unbrained/pm-cli" and "npx tsc"`,
806
- ]),
807
- `Install the scaffold: ${options.vocabulary === "package" ? "pm install --project" : "pm extension --install --project"} ${quotedTargetPath}`,
808
- `Smoke-test command path: pm ${scaffold.command_name}`,
809
- ...(options.vocabulary === "package"
810
- ? [`Validate the sample test: cd ${quotedShellTargetPath}, then run "npm test"`]
811
- : []),
812
- `Run diagnostics: ${options.vocabulary === "package" ? "pm package doctor" : "pm extension --doctor"} --project --detail summary`,
813
- ],
814
- });
984
+ const ctx = {
985
+ action,
986
+ normalizedTarget,
987
+ scope,
988
+ resolvedRoots,
989
+ warnings,
990
+ options,
991
+ global,
992
+ withResult,
993
+ };
994
+ return EXTENSION_ACTION_HANDLERS[action](ctx);
995
+ }
996
+ async function runExtensionInitAction(ctx) {
997
+ const { action, normalizedTarget, options, withResult } = ctx;
998
+ const githubOption = resolveGithubOption(options);
999
+ if (githubOption !== undefined || (typeof options.ref === "string" && options.ref.trim().length > 0)) {
1000
+ throw new PmCliError('Action "init" does not accept --gh/--github/--ref options.', EXIT_CODE.USAGE);
815
1001
  }
816
- if (action === "reload") {
817
- if (normalizedTarget !== undefined) {
818
- throw new PmCliError('Action "reload" does not accept a target argument.', EXIT_CODE.USAGE);
819
- }
820
- const settings = await readSettings(resolvedRoots.settings_root);
821
- const reloadToken = nextExtensionReloadToken();
822
- const reloaded = await loadExtensions({
823
- pmRoot: resolvedRoots.settings_root,
824
- settings,
825
- cwd: process.cwd(),
826
- noExtensions: global.noExtensions,
827
- reload_token: reloadToken,
1002
+ const scaffoldTarget = requireTarget(normalizedTarget, action, options);
1003
+ const scaffold = await scaffoldExtensionProject(scaffoldTarget, options.vocabulary ?? "extension", options.capability, options.declarative === true);
1004
+ const quotedTargetPath = JSON.stringify(scaffold.target_path);
1005
+ // Forward-slash the path for the copy-pasteable `cd` hint: Windows cmd.exe /
1006
+ // PowerShell reject the doubled backslashes JSON.stringify emits, while both
1007
+ // shells (and POSIX) accept forward slashes.
1008
+ const quotedShellTargetPath = JSON.stringify(scaffold.target_path.replace(/\\/g, "/"));
1009
+ return withResult({
1010
+ scaffolded: scaffold.created_directory || scaffold.files.some((entry) => entry.status === "created"),
1011
+ extension: {
1012
+ name: scaffold.extension_name,
1013
+ command: scaffold.command_name,
1014
+ },
1015
+ capability: scaffold.capability,
1016
+ style: scaffold.style,
1017
+ target_path: scaffold.target_path,
1018
+ created_directory: scaffold.created_directory,
1019
+ files: scaffold.files,
1020
+ next_steps: [
1021
+ // Extensions are authored AND loaded as TypeScript (ADR pm-2c28 / pm-m1uz):
1022
+ // the manifest entry is ./index.ts and pm strips types on load (Node
1023
+ // >=22.18), so there is no compile/build step — install dependencies, then
1024
+ // install the scaffold directly.
1025
+ ...(options.vocabulary === "package"
1026
+ ? [`Install dependencies: cd ${quotedShellTargetPath}, then run "npm install"`]
1027
+ : [
1028
+ `Install type-check dependencies: cd ${quotedShellTargetPath}, then run "npm install -D typescript @types/node @unbrained/pm-cli"`,
1029
+ ]),
1030
+ `Install the scaffold: ${options.vocabulary === "package" ? "pm install --project" : "pm extension --install --project"} ${quotedTargetPath}`,
1031
+ `Smoke-test command path: pm ${scaffold.command_name}`,
1032
+ ...(options.vocabulary === "package"
1033
+ ? [`Validate the package: cd ${quotedShellTargetPath}, then run "npm run typecheck" and "npm test"`]
1034
+ : [`Type-check the source (optional): cd ${quotedShellTargetPath}, then run "npx tsc --noEmit"`]),
1035
+ `Run diagnostics: ${options.vocabulary === "package" ? "pm package doctor" : "pm extension --doctor"} --project --detail summary`,
1036
+ ],
1037
+ });
1038
+ }
1039
+ async function runExtensionReloadAction(ctx) {
1040
+ const { normalizedTarget, resolvedRoots, warnings, options, global, withResult } = ctx;
1041
+ if (normalizedTarget !== undefined) {
1042
+ throw new PmCliError('Action "reload" does not accept a target argument.', EXIT_CODE.USAGE);
1043
+ }
1044
+ const settings = await readSettings(resolvedRoots.settings_root);
1045
+ const reloadToken = nextExtensionReloadToken();
1046
+ const reloaded = await loadExtensions({
1047
+ pmRoot: resolvedRoots.settings_root,
1048
+ settings,
1049
+ cwd: process.cwd(),
1050
+ noExtensions: global.noExtensions,
1051
+ reload_token: reloadToken,
1052
+ cache_bust: true,
1053
+ });
1054
+ warnings.push(...reloaded.warnings);
1055
+ const activation = await activateExtensions(reloaded);
1056
+ warnings.push(...activation.warnings);
1057
+ const details = {
1058
+ reload: {
1059
+ token: reloadToken,
828
1060
  cache_bust: true,
829
- });
830
- warnings.push(...reloaded.warnings);
831
- const activation = await activateExtensions(reloaded);
832
- warnings.push(...activation.warnings);
833
- const details = {
834
- reload: {
835
- token: reloadToken,
836
- cache_bust: true,
837
- watch: options.watch === true,
838
- },
839
- loaded_count: reloaded.loaded.length,
840
- failed_count: reloaded.failed.length,
841
- activated_count: Math.max(0, reloaded.loaded.length - activation.failed.length),
842
- activation_failed_count: activation.failed.length,
843
- loaded_extensions: reloaded.loaded.map((entry) => ({
844
- name: entry.name,
845
- layer: entry.layer,
846
- version: entry.version,
847
- })),
848
- failed_extensions: reloaded.failed.map((entry) => ({
849
- name: entry.name,
850
- layer: entry.layer,
851
- error: entry.error,
852
- })),
853
- activation_failures: activation.failed.map((entry) => ({
854
- name: entry.name,
855
- layer: entry.layer,
856
- error: entry.error,
857
- })),
1061
+ watch: options.watch === true,
1062
+ },
1063
+ loaded_count: reloaded.loaded.length,
1064
+ failed_count: reloaded.failed.length,
1065
+ activated_count: Math.max(0, reloaded.loaded.length - activation.failed.length),
1066
+ activation_failed_count: activation.failed.length,
1067
+ loaded_extensions: reloaded.loaded.map((entry) => ({
1068
+ name: entry.name,
1069
+ layer: entry.layer,
1070
+ version: entry.version,
1071
+ })),
1072
+ failed_extensions: reloaded.failed.map((entry) => ({
1073
+ name: entry.name,
1074
+ layer: entry.layer,
1075
+ error: entry.error,
1076
+ })),
1077
+ activation_failures: activation.failed.map((entry) => ({
1078
+ name: entry.name,
1079
+ layer: entry.layer,
1080
+ error: entry.error,
1081
+ })),
1082
+ };
1083
+ if (options.watch === true) {
1084
+ warnings.push("extension_reload_watch_hint:watch_mode_requested_non_interactive_single_pass_only");
1085
+ }
1086
+ return withResult(details);
1087
+ }
1088
+ async function runExtensionCatalogAction(ctx) {
1089
+ const { normalizedTarget, scope, options, global, withResult } = ctx;
1090
+ if (typeof normalizedTarget === "string" && normalizedTarget.length > 0 && normalizedTarget !== "catalog") {
1091
+ throw new PmCliError('Action "catalog" does not accept a package target.', EXIT_CODE.USAGE);
1092
+ }
1093
+ return withResult(await buildBundledPackageCatalog(scope, global, options));
1094
+ }
1095
+ /* c8 ignore start -- source-shape branch combinations are exercised in install-source focused tests */
1096
+ /**
1097
+ * Build the persisted managed-source record for an install from its resolved
1098
+ * shape: a bundled builtin alias, a local path, an npm package, or (the default) a
1099
+ * GitHub repository, capturing the location/commit/subpath provenance the manage
1100
+ * and upgrade flows later read back.
1101
+ */
1102
+ function buildInstallManagedSource(bundledAliasName, installSource, resolvedSource) {
1103
+ if (bundledAliasName) {
1104
+ return {
1105
+ kind: "builtin",
1106
+ input: bundledAliasName,
1107
+ location: bundledAliasName,
1108
+ name: bundledAliasName,
858
1109
  };
859
- if (options.watch === true) {
860
- warnings.push("extension_reload_watch_hint:watch_mode_requested_non_interactive_single_pass_only");
861
- }
862
- return withResult(details);
863
1110
  }
864
- if (action === "catalog") {
865
- if (typeof normalizedTarget === "string" && normalizedTarget.length > 0 && normalizedTarget !== "catalog") {
866
- throw new PmCliError('Action "catalog" does not accept a package target.', EXIT_CODE.USAGE);
867
- }
868
- return withResult(await buildBundledPackageCatalog(scope, global, options));
869
- }
870
- if (action === "install") {
871
- const githubOption = resolveGithubOption(options);
872
- const explicitSourceInput = githubOption ?? requireTarget(normalizedTarget, action);
873
- if (typeof githubOption !== "string" && isBundledPackageInstallAllTarget(explicitSourceInput)) {
874
- if (typeof options.ref === "string" && options.ref.trim().length > 0) {
875
- throw new PmCliError('Action "install all" does not accept --ref.', EXIT_CODE.USAGE);
876
- }
877
- const aliases = await listBundledPackageAliases();
878
- const packages = [];
879
- for (const alias of aliases) {
880
- packages.push({
881
- alias,
882
- result: await runExtension(alias, { ...options, install: true }, global),
883
- });
884
- }
885
- for (const entry of packages) {
886
- warnings.push(...entry.result.warnings);
887
- }
888
- return withResult({
889
- installed_all: true,
890
- installed_count: packages.length,
891
- packages: packages.map((entry) => ({
892
- alias: entry.alias,
893
- ok: entry.result.ok,
894
- extension: entry.result.details.extension,
895
- source: entry.result.details.source,
896
- destination_path: entry.result.details.destination_path,
897
- activated: entry.result.details.activated,
898
- settings_changed: entry.result.details.settings_changed,
899
- command_paths: entry.result.details.command_paths,
900
- action_paths: entry.result.details.action_paths,
901
- command_discovery: entry.result.details.command_discovery,
902
- warnings: entry.result.warnings,
903
- })),
904
- });
1111
+ if (installSource.kind === "local") {
1112
+ return {
1113
+ kind: "local",
1114
+ input: installSource.input,
1115
+ location: installSource.absolute_path,
1116
+ };
1117
+ }
1118
+ if (installSource.kind === "npm") {
1119
+ return {
1120
+ kind: "npm",
1121
+ input: installSource.input,
1122
+ location: resolvedSource.resolved_subpath ?? ".",
1123
+ package: resolvedSource.npm_package,
1124
+ version: resolvedSource.npm_version,
1125
+ };
1126
+ }
1127
+ return {
1128
+ kind: "github",
1129
+ input: installSource.input,
1130
+ location: resolvedSource.resolved_subpath ?? installSource.subpath ?? ".",
1131
+ repository: installSource.repository,
1132
+ owner: installSource.owner,
1133
+ repo: installSource.repo,
1134
+ ref: installSource.ref,
1135
+ subpath: resolvedSource.resolved_subpath ?? installSource.subpath,
1136
+ commit: resolvedSource.commit,
1137
+ };
1138
+ }
1139
+ /* c8 ignore stop */
1140
+ /**
1141
+ * Run the install body while holding the per-destination install lock: read
1142
+ * settings and managed state, copy the validated extension into the scope root
1143
+ * unless it is already installed in place, upsert the managed entry and activation
1144
+ * state, scaffold any contributed item-type folders, runtime-probe the freshly
1145
+ * installed command paths, and return the install result envelope.
1146
+ */
1147
+ async function performExtensionInstallUnderLock(ctx, input) {
1148
+ const { scope, resolvedRoots, warnings, global, withResult } = ctx;
1149
+ const { validated, destinationDirectoryName, bundledAliasName, installSource, resolvedSource } = input;
1150
+ const settings = await readSettings(resolvedRoots.settings_root);
1151
+ const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1152
+ warnings.push(...managedStateRead.warnings);
1153
+ const destinationDirectory = path.join(resolvedRoots.selected_root, destinationDirectoryName);
1154
+ const destinationExists = await pathExists(destinationDirectory);
1155
+ const installInPlace = await areDirectoriesEquivalent(validated.directory, destinationDirectory);
1156
+ await fs.mkdir(resolvedRoots.selected_root, { recursive: true });
1157
+ if (!installInPlace) {
1158
+ await copyExtensionDirectoryForInstall(validated.directory, destinationDirectory);
1159
+ }
1160
+ const sourceRecord = buildInstallManagedSource(bundledAliasName, installSource, resolvedSource);
1161
+ const now = nowIso();
1162
+ const existingManagedEntry = managedStateRead.state.entries.find((entry) => normalizeExtensionNameForMatch(entry.name) === normalizeExtensionNameForMatch(validated.manifest.name));
1163
+ const sourceUnchanged = existingManagedEntry !== undefined &&
1164
+ existingManagedEntry.manifest_version === validated.manifest.version &&
1165
+ managedExtensionSourcesEquivalent(existingManagedEntry.source, sourceRecord);
1166
+ const managedState = upsertManagedEntry(managedStateRead.state, {
1167
+ name: validated.manifest.name,
1168
+ directory: destinationDirectoryName,
1169
+ scope,
1170
+ manifest_version: validated.manifest.version,
1171
+ manifest_entry: validated.manifest.entry,
1172
+ capabilities: [...validated.manifest.capabilities],
1173
+ installed_at: existingManagedEntry?.installed_at ?? now,
1174
+ updated_at: sourceUnchanged ? existingManagedEntry.updated_at : now,
1175
+ source: sourceRecord,
1176
+ });
1177
+ await writeManagedExtensionState(resolvedRoots.selected_root, managedState);
1178
+ const activationChanged = ensureActivated(settings, validated.manifest.name);
1179
+ if (activationChanged) {
1180
+ await writeSettings(resolvedRoots.settings_root, settings, "settings:write");
1181
+ }
1182
+ const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedState);
1183
+ warnings.push(...refreshedInstalled.warnings);
1184
+ const runtimeProbe = await probeRuntimeCommandPathsForInstall(resolvedRoots.pm_root, settings, refreshedInstalled.extensions, global);
1185
+ warnings.push(...runtimeProbe.warnings);
1186
+ // Scaffold the folders for any item types the installed package contributes
1187
+ // so the tracker is immediately healthy — matching `pm schema add-type` and
1188
+ // `pm profile apply`, the other paths that register a type. Without this a
1189
+ // freshly-installed schema package leaves a `missing_directory` health
1190
+ // warning until the first item of its type is created. Scoped to project
1191
+ // installs, where `pm_root` is unambiguously the tracker the type folders
1192
+ // belong to; a global install is not tied to one tracker, so its folders are
1193
+ // created lazily on first use in each project.
1194
+ const installedItemTypeDefinitions = runtimeProbe.item_type_registrations
1195
+ .filter((entry) => normalizeExtensionNameForMatch(entry.name) === normalizeExtensionNameForMatch(validated.manifest.name))
1196
+ .flatMap((entry) => entry.types.map((type) => ({ name: type.name, folder: type.folder })));
1197
+ if (scope === "project" && installedItemTypeDefinitions.length > 0) {
1198
+ await ensureTypeFolderScaffold(resolvedRoots.pm_root, installedItemTypeDefinitions, warnings, "install:type-folder");
1199
+ }
1200
+ const commandSummary = summarizeRuntimeCommandPathsForExtension(validated.manifest.name, runtimeProbe.installed);
1201
+ const installActivationFailure = findActivationFailureByName(validated.manifest.name, runtimeProbe.activation_failures, scope);
1202
+ const runtimeActivationStatus = resolveInstallRuntimeActivationStatus(validated.manifest.name, scope, runtimeProbe.installed, installActivationFailure);
1203
+ return withResult({
1204
+ extension: {
1205
+ name: validated.manifest.name,
1206
+ version: validated.manifest.version,
1207
+ entry: validated.manifest.entry,
1208
+ capabilities: validated.manifest.capabilities,
1209
+ directory: destinationDirectoryName,
1210
+ },
1211
+ source: sourceRecord,
1212
+ destination_path: destinationDirectory,
1213
+ overwritten: destinationExists && !installInPlace,
1214
+ installed_in_place: installInPlace,
1215
+ activated: true,
1216
+ settings_changed: activationChanged,
1217
+ runtime_activation_status: runtimeActivationStatus,
1218
+ command_paths: commandSummary.command_paths,
1219
+ action_paths: commandSummary.action_paths,
1220
+ command_discovery: buildInstallCommandDiscovery(validated.manifest.name, sourceRecord, commandSummary),
1221
+ activation_diagnostics: {
1222
+ failed_count: runtimeProbe.activation_failures.length,
1223
+ failed: runtimeProbe.activation_failures,
1224
+ installed_extension_failed: installActivationFailure ?? null,
1225
+ },
1226
+ });
1227
+ }
1228
+ async function runExtensionInstallAction(ctx) {
1229
+ const { action, normalizedTarget, resolvedRoots, warnings, options, global, withResult } = ctx;
1230
+ const githubOption = resolveGithubOption(options);
1231
+ const explicitSourceInput = githubOption ?? requireTarget(normalizedTarget, action, options);
1232
+ if (typeof githubOption !== "string" && isBundledPackageInstallAllTarget(explicitSourceInput)) {
1233
+ if (typeof options.ref === "string" && options.ref.trim().length > 0) {
1234
+ throw new PmCliError('Action "install all" does not accept --ref.', EXIT_CODE.USAGE);
905
1235
  }
906
- /* c8 ignore start -- github/local alias-source split is exercised in install-action integration tests */
907
- const bundledAliasSource = typeof githubOption === "string" ? null : await resolveBundledExtensionAliasSource(explicitSourceInput);
908
- /* c8 ignore stop */
909
- const bundledAliasName = bundledAliasSource === null ? null : explicitSourceInput.trim().toLowerCase();
910
- const sourceInput = bundledAliasSource ?? explicitSourceInput;
911
- /* c8 ignore start -- install-source branch combinations are covered in install-sources focused tests */
912
- const installSource = parseExtensionInstallSource(sourceInput, {
913
- forceGithub: typeof githubOption === "string",
914
- ref: options.ref,
915
- });
916
- /* c8 ignore stop */
917
- const resolvedSource = await resolveInstallSource(installSource);
918
- try {
919
- const validated = await validateExtensionDirectory(resolvedSource.directory);
920
- const destinationDirectoryName = normalizeManagedDirectoryName(validated.manifest.name);
921
- return await withExtensionInstallLock(resolvedRoots.settings_root, destinationDirectoryName, async () => {
922
- const settings = await readSettings(resolvedRoots.settings_root);
923
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
924
- warnings.push(...managedStateRead.warnings);
925
- const destinationDirectory = path.join(resolvedRoots.selected_root, destinationDirectoryName);
926
- const destinationExists = await pathExists(destinationDirectory);
927
- const installInPlace = await areDirectoriesEquivalent(validated.directory, destinationDirectory);
928
- await fs.mkdir(resolvedRoots.selected_root, { recursive: true });
929
- if (!installInPlace) {
930
- await copyExtensionDirectoryForInstall(validated.directory, destinationDirectory);
931
- }
932
- /* c8 ignore start -- source-shape branch combinations are exercised in install-source focused tests */
933
- const sourceRecord = bundledAliasName
934
- ? {
935
- kind: "builtin",
936
- input: bundledAliasName,
937
- location: bundledAliasName,
938
- name: bundledAliasName,
939
- }
940
- : installSource.kind === "local"
941
- ? {
942
- kind: "local",
943
- input: installSource.input,
944
- location: installSource.absolute_path,
945
- }
946
- : installSource.kind === "npm"
947
- ? {
948
- kind: "npm",
949
- input: installSource.input,
950
- location: resolvedSource.resolved_subpath ?? ".",
951
- package: resolvedSource.npm_package,
952
- version: resolvedSource.npm_version,
953
- }
954
- : {
955
- kind: "github",
956
- input: installSource.input,
957
- location: resolvedSource.resolved_subpath ?? installSource.subpath ?? ".",
958
- repository: installSource.repository,
959
- owner: installSource.owner,
960
- repo: installSource.repo,
961
- ref: installSource.ref,
962
- subpath: resolvedSource.resolved_subpath ?? installSource.subpath,
963
- commit: resolvedSource.commit,
964
- };
965
- /* c8 ignore stop */
966
- const now = nowIso();
967
- const existingManagedEntry = managedStateRead.state.entries.find((entry) => normalizeExtensionNameForMatch(entry.name) === normalizeExtensionNameForMatch(validated.manifest.name));
968
- const sourceUnchanged = existingManagedEntry !== undefined &&
969
- existingManagedEntry.manifest_version === validated.manifest.version &&
970
- managedExtensionSourcesEquivalent(existingManagedEntry.source, sourceRecord);
971
- const managedState = upsertManagedEntry(managedStateRead.state, {
972
- name: validated.manifest.name,
973
- directory: destinationDirectoryName,
974
- scope,
975
- manifest_version: validated.manifest.version,
976
- manifest_entry: validated.manifest.entry,
977
- capabilities: [...validated.manifest.capabilities],
978
- installed_at: existingManagedEntry?.installed_at ?? now,
979
- updated_at: sourceUnchanged ? existingManagedEntry.updated_at : now,
980
- source: sourceRecord,
981
- });
982
- await writeManagedExtensionState(resolvedRoots.selected_root, managedState);
983
- const activationChanged = ensureActivated(settings, validated.manifest.name);
984
- if (activationChanged) {
985
- await writeSettings(resolvedRoots.settings_root, settings, "settings:write");
986
- }
987
- const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedState);
988
- warnings.push(...refreshedInstalled.warnings);
989
- const runtimeProbe = await probeRuntimeCommandPathsForInstall(resolvedRoots.pm_root, settings, refreshedInstalled.extensions, global);
990
- warnings.push(...runtimeProbe.warnings);
991
- const commandSummary = summarizeRuntimeCommandPathsForExtension(validated.manifest.name, runtimeProbe.installed);
992
- const installActivationFailure = findActivationFailureByName(validated.manifest.name, runtimeProbe.activation_failures, scope);
993
- const runtimeActivationStatus = resolveInstallRuntimeActivationStatus(validated.manifest.name, scope, runtimeProbe.installed, installActivationFailure);
994
- return withResult({
995
- extension: {
996
- name: validated.manifest.name,
997
- version: validated.manifest.version,
998
- entry: validated.manifest.entry,
999
- capabilities: validated.manifest.capabilities,
1000
- directory: destinationDirectoryName,
1001
- },
1002
- source: sourceRecord,
1003
- destination_path: destinationDirectory,
1004
- overwritten: destinationExists && !installInPlace,
1005
- installed_in_place: installInPlace,
1006
- activated: true,
1007
- settings_changed: activationChanged,
1008
- runtime_activation_status: runtimeActivationStatus,
1009
- command_paths: commandSummary.command_paths,
1010
- action_paths: commandSummary.action_paths,
1011
- command_discovery: buildInstallCommandDiscovery(validated.manifest.name, sourceRecord, commandSummary),
1012
- activation_diagnostics: {
1013
- failed_count: runtimeProbe.activation_failures.length,
1014
- failed: runtimeProbe.activation_failures,
1015
- installed_extension_failed: installActivationFailure ?? null,
1016
- },
1017
- });
1236
+ const aliases = await listBundledPackageAliases();
1237
+ const packages = [];
1238
+ for (const alias of aliases) {
1239
+ packages.push({
1240
+ alias,
1241
+ result: await runExtension(alias, { ...options, install: true }, global),
1018
1242
  });
1019
1243
  }
1020
- finally {
1021
- /* c8 ignore start -- cleanup hooks are only present for transient install sources */
1022
- if (resolvedSource.cleanup) {
1023
- await resolvedSource.cleanup();
1024
- }
1025
- /* c8 ignore stop */
1026
- }
1027
- }
1028
- if (action === "adopt-all") {
1029
- if (normalizedTarget !== undefined) {
1030
- throw new PmCliError('Action "adopt-all" does not accept a target argument.', EXIT_CODE.USAGE);
1031
- }
1032
- const githubOption = resolveGithubOption(options);
1033
- if (githubOption !== undefined || (typeof options.ref === "string" && options.ref.trim().length > 0)) {
1034
- throw new PmCliError('Action "adopt-all" does not accept --gh/--github/--ref options.', EXIT_CODE.USAGE);
1244
+ for (const entry of packages) {
1245
+ warnings.push(...entry.result.warnings);
1035
1246
  }
1036
- const settings = await readSettings(resolvedRoots.settings_root);
1037
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1038
- warnings.push(...managedStateRead.warnings);
1039
- const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1040
- warnings.push(...installed.warnings);
1041
- const adoption = await adoptUnmanagedExtensions(resolvedRoots.selected_root, scope, installed.extensions, managedStateRead.state);
1042
- const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, adoption.state);
1043
- warnings.push(...refreshedInstalled.warnings);
1044
- const triage = buildExtensionTriageSummary(scope, warnings, refreshedInstalled.extensions, options);
1045
- warnings.push(...triage.warnings);
1046
- /* c8 ignore start -- refresh-entry optional metadata is display-only and exercised indirectly */
1047
- const adoptedDetails = adoption.adopted_entries.map((entry) => {
1048
- const refreshedEntry = refreshedInstalled.extensions.find((candidate) => normalizeExtensionNameForMatch(candidate.name) === normalizeExtensionNameForMatch(entry.name) &&
1049
- normalizeExtensionNameForMatch(candidate.directory) === normalizeExtensionNameForMatch(entry.directory)) ??
1050
- /* c8 ignore next 3 -- fallback only matters if a manifest renames between adopt and refresh */
1051
- refreshedInstalled.extensions.find((candidate) => normalizeExtensionNameForMatch(candidate.directory) === normalizeExtensionNameForMatch(entry.directory));
1052
- return {
1053
- ...entry,
1054
- update_check_status: refreshedEntry?.update_check_status ?? null,
1055
- update_check_reason: refreshedEntry?.update_check_reason ?? null,
1056
- };
1057
- });
1058
- /* c8 ignore stop */
1059
- /* c8 ignore start -- adopt-all summary booleans are deterministic mirrors of adoptedDetails length */
1060
1247
  return withResult({
1061
- adopted_all: adoptedDetails.length > 0,
1062
- adopted_count: adoptedDetails.length,
1063
- already_managed_count: adoption.already_managed_count,
1064
- extensions: adoptedDetails,
1065
- triage,
1066
- warning_codes: triage.warning_codes,
1067
- update_health_partial: triage.update_health_partial,
1068
- update_health_coverage: triage.update_health_coverage,
1248
+ installed_all: true,
1249
+ installed_count: packages.length,
1250
+ packages: packages.map((entry) => ({
1251
+ alias: entry.alias,
1252
+ ok: entry.result.ok,
1253
+ extension: entry.result.details.extension,
1254
+ source: entry.result.details.source,
1255
+ destination_path: entry.result.details.destination_path,
1256
+ activated: entry.result.details.activated,
1257
+ settings_changed: entry.result.details.settings_changed,
1258
+ command_paths: entry.result.details.command_paths,
1259
+ action_paths: entry.result.details.action_paths,
1260
+ command_discovery: entry.result.details.command_discovery,
1261
+ warnings: entry.result.warnings,
1262
+ })),
1069
1263
  });
1070
- /* c8 ignore stop */
1071
1264
  }
1072
- if (action === "adopt") {
1073
- const extensionTarget = requireTarget(normalizedTarget, action);
1074
- const githubOption = resolveGithubOption(options);
1075
- const settings = await readSettings(resolvedRoots.settings_root);
1076
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1077
- warnings.push(...managedStateRead.warnings);
1078
- const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1079
- warnings.push(...installed.warnings);
1080
- const candidate = await resolveInstalledExtensionCandidate(installed.extensions, extensionTarget);
1081
- if (!candidate) {
1082
- throw new PmCliError(`Installed extension "${extensionTarget}" was not found in ${scope} scope.`, EXIT_CODE.NOT_FOUND);
1083
- }
1084
- if (candidate.managed) {
1085
- return withResult({
1086
- adopted: false,
1087
- already_managed: true,
1088
- extension: {
1089
- name: candidate.name,
1090
- directory: candidate.directory,
1091
- },
1092
- });
1265
+ /* c8 ignore start -- github/local alias-source split is exercised in install-action integration tests */
1266
+ const bundledAliasSource = typeof githubOption === "string" ? null : await resolveBundledExtensionAliasSource(explicitSourceInput);
1267
+ /* c8 ignore stop */
1268
+ const bundledAliasName = bundledAliasSource === null ? null : explicitSourceInput.trim().toLowerCase();
1269
+ const sourceInput = bundledAliasSource ?? explicitSourceInput;
1270
+ /* c8 ignore start -- install-source branch combinations are covered in install-sources focused tests */
1271
+ const installSource = parseExtensionInstallSource(sourceInput, {
1272
+ forceGithub: typeof githubOption === "string",
1273
+ ref: options.ref,
1274
+ });
1275
+ /* c8 ignore stop */
1276
+ const resolvedSource = await resolveInstallSource(installSource);
1277
+ try {
1278
+ const validated = await validateExtensionDirectory(resolvedSource.directory);
1279
+ const destinationDirectoryName = normalizeManagedDirectoryName(validated.manifest.name);
1280
+ return await withExtensionInstallLock(resolvedRoots.settings_root, destinationDirectoryName, () => performExtensionInstallUnderLock(ctx, {
1281
+ validated,
1282
+ destinationDirectoryName,
1283
+ bundledAliasName,
1284
+ installSource,
1285
+ resolvedSource,
1286
+ }));
1287
+ }
1288
+ finally {
1289
+ /* c8 ignore start -- cleanup hooks are only present for transient install sources */
1290
+ if (resolvedSource.cleanup) {
1291
+ await resolvedSource.cleanup();
1093
1292
  }
1094
- const extensionDirectory = path.join(resolvedRoots.selected_root, candidate.directory);
1095
- const validated = await validateExtensionDirectory(extensionDirectory);
1096
- const now = nowIso();
1097
- const sourceRecord = githubOption === undefined
1098
- ? {
1099
- kind: "local",
1100
- input: extensionTarget,
1101
- location: extensionDirectory,
1102
- }
1103
- : (() => {
1104
- const parsed = parseExtensionInstallSource(githubOption, {
1105
- forceGithub: true,
1106
- ref: options.ref,
1107
- });
1108
- /* c8 ignore start -- forceGithub guarantees a github-kind install source */
1109
- if (parsed.kind !== "github") {
1110
- throw new PmCliError(`Invalid GitHub shorthand "${githubOption}".`, EXIT_CODE.USAGE);
1111
- }
1112
- /* c8 ignore stop */
1113
- /* c8 ignore start -- github subpath defaults are validated in install-source parser tests */
1114
- return {
1115
- kind: "github",
1116
- input: parsed.input,
1117
- location: parsed.subpath ?? ".",
1118
- repository: parsed.repository,
1119
- owner: parsed.owner,
1120
- repo: parsed.repo,
1121
- ref: parsed.ref,
1122
- subpath: parsed.subpath,
1123
- };
1124
- /* c8 ignore stop */
1125
- })();
1126
- const managedState = upsertManagedEntry(managedStateRead.state, {
1127
- name: validated.manifest.name,
1128
- directory: candidate.directory,
1129
- scope,
1130
- manifest_version: validated.manifest.version,
1131
- manifest_entry: validated.manifest.entry,
1132
- capabilities: [...validated.manifest.capabilities],
1133
- installed_at: now,
1134
- updated_at: now,
1135
- source: sourceRecord,
1136
- });
1137
- await writeManagedExtensionState(resolvedRoots.selected_root, managedState);
1138
- const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedState);
1139
- warnings.push(...refreshedInstalled.warnings);
1140
- /* c8 ignore start -- fallback only matters if a manifest renames between adopt and refresh */
1141
- const refreshedEntry = refreshedInstalled.extensions.find((entry) => normalizeExtensionNameForMatch(entry.name) === normalizeExtensionNameForMatch(validated.manifest.name)) ??
1142
- refreshedInstalled.extensions.find((entry) => normalizeExtensionNameForMatch(entry.directory) === normalizeExtensionNameForMatch(candidate.directory));
1143
1293
  /* c8 ignore stop */
1144
- /* c8 ignore start -- adopt result mirrors refreshedEntry optionals for display only */
1145
- return withResult({
1146
- adopted: true,
1147
- extension: {
1148
- name: validated.manifest.name,
1149
- directory: candidate.directory,
1150
- version: validated.manifest.version,
1151
- entry: validated.manifest.entry,
1152
- },
1153
- source: sourceRecord,
1294
+ }
1295
+ }
1296
+ async function runExtensionAdoptAllAction(ctx) {
1297
+ const { normalizedTarget, scope, resolvedRoots, warnings, options, withResult } = ctx;
1298
+ if (normalizedTarget !== undefined) {
1299
+ throw new PmCliError('Action "adopt-all" does not accept a target argument.', EXIT_CODE.USAGE);
1300
+ }
1301
+ const githubOption = resolveGithubOption(options);
1302
+ if (githubOption !== undefined || (typeof options.ref === "string" && options.ref.trim().length > 0)) {
1303
+ throw new PmCliError('Action "adopt-all" does not accept --gh/--github/--ref options.', EXIT_CODE.USAGE);
1304
+ }
1305
+ const settings = await readSettings(resolvedRoots.settings_root);
1306
+ const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1307
+ warnings.push(...managedStateRead.warnings);
1308
+ const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1309
+ warnings.push(...installed.warnings);
1310
+ const adoption = await adoptUnmanagedExtensions(resolvedRoots.selected_root, scope, installed.extensions, managedStateRead.state);
1311
+ const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, adoption.state);
1312
+ warnings.push(...refreshedInstalled.warnings);
1313
+ const triage = buildExtensionTriageSummary(scope, warnings, refreshedInstalled.extensions, options);
1314
+ warnings.push(...triage.warnings);
1315
+ /* c8 ignore start -- refresh-entry optional metadata is display-only and exercised indirectly */
1316
+ const adoptedDetails = adoption.adopted_entries.map((entry) => {
1317
+ const refreshedEntry = refreshedInstalled.extensions.find((candidate) => normalizeExtensionNameForMatch(candidate.name) === normalizeExtensionNameForMatch(entry.name) &&
1318
+ normalizeExtensionNameForMatch(candidate.directory) === normalizeExtensionNameForMatch(entry.directory)) ??
1319
+ /* c8 ignore next 3 -- fallback only matters if a manifest renames between adopt and refresh */
1320
+ refreshedInstalled.extensions.find((candidate) => normalizeExtensionNameForMatch(candidate.directory) === normalizeExtensionNameForMatch(entry.directory));
1321
+ return {
1322
+ ...entry,
1154
1323
  update_check_status: refreshedEntry?.update_check_status ?? null,
1155
1324
  update_check_reason: refreshedEntry?.update_check_reason ?? null,
1156
- });
1157
- /* c8 ignore stop */
1158
- }
1159
- if (action === "uninstall") {
1160
- const extensionTarget = requireTarget(normalizedTarget, action);
1161
- const settings = await readSettings(resolvedRoots.settings_root);
1162
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1163
- warnings.push(...managedStateRead.warnings);
1164
- const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1165
- warnings.push(...installed.warnings);
1166
- const candidate = await resolveInstalledExtensionCandidate(installed.extensions, extensionTarget);
1167
- if (!candidate) {
1168
- throw new PmCliError(`Installed extension "${extensionTarget}" was not found in ${scope} scope.`, EXIT_CODE.NOT_FOUND);
1169
- }
1170
- const destinationDirectory = path.join(resolvedRoots.selected_root, candidate.directory);
1171
- await fs.rm(destinationDirectory, { recursive: true, force: true });
1172
- const updatedState = {
1173
- ...managedStateRead.state,
1174
- updated_at: nowIso(),
1175
- /* c8 ignore start -- uninstall filter keeps both name+directory guards for legacy managed-state migrations */
1176
- entries: managedStateRead.state.entries.filter((entry) => normalizeExtensionNameForMatch(entry.name) !== normalizeExtensionNameForMatch(candidate.name) &&
1177
- normalizeExtensionNameForMatch(entry.directory) !== normalizeExtensionNameForMatch(candidate.directory)),
1178
- /* c8 ignore stop */
1179
1325
  };
1180
- await writeManagedExtensionState(resolvedRoots.selected_root, updatedState);
1181
- const stateChanged = clearExtensionState(settings, candidate.name);
1182
- if (stateChanged) {
1183
- await writeSettings(resolvedRoots.settings_root, settings, "settings:write");
1184
- }
1326
+ });
1327
+ /* c8 ignore stop */
1328
+ /* c8 ignore start -- adopt-all summary booleans are deterministic mirrors of adoptedDetails length */
1329
+ return withResult({
1330
+ adopted_all: adoptedDetails.length > 0,
1331
+ adopted_count: adoptedDetails.length,
1332
+ already_managed_count: adoption.already_managed_count,
1333
+ extensions: adoptedDetails,
1334
+ triage,
1335
+ warning_codes: triage.warning_codes,
1336
+ update_health_partial: triage.update_health_partial,
1337
+ update_health_coverage: triage.update_health_coverage,
1338
+ });
1339
+ /* c8 ignore stop */
1340
+ }
1341
+ async function runExtensionAdoptAction(ctx) {
1342
+ const { action, normalizedTarget, scope, resolvedRoots, warnings, options, withResult } = ctx;
1343
+ const extensionTarget = requireTarget(normalizedTarget, action, options);
1344
+ const githubOption = resolveGithubOption(options);
1345
+ const settings = await readSettings(resolvedRoots.settings_root);
1346
+ const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1347
+ warnings.push(...managedStateRead.warnings);
1348
+ const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1349
+ warnings.push(...installed.warnings);
1350
+ const candidate = await resolveInstalledExtensionCandidate(installed.extensions, extensionTarget);
1351
+ if (!candidate) {
1352
+ throw new PmCliError(`Installed extension "${extensionTarget}" was not found in ${scope} scope.`, EXIT_CODE.NOT_FOUND);
1353
+ }
1354
+ if (candidate.managed) {
1185
1355
  return withResult({
1186
- removed: true,
1356
+ adopted: false,
1357
+ already_managed: true,
1187
1358
  extension: {
1188
1359
  name: candidate.name,
1189
1360
  directory: candidate.directory,
1190
1361
  },
1191
- destination_path: destinationDirectory,
1192
- settings_changed: stateChanged,
1193
1362
  });
1194
1363
  }
1195
- if (action === "activate" || action === "deactivate") {
1196
- const extensionTarget = requireTarget(normalizedTarget, action);
1197
- const settings = await readSettings(resolvedRoots.settings_root);
1198
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1199
- warnings.push(...managedStateRead.warnings);
1200
- const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1201
- warnings.push(...installed.warnings);
1202
- const candidate = await resolveInstalledExtensionCandidate(installed.extensions, extensionTarget);
1203
- if (!candidate) {
1204
- throw new PmCliError(`Installed extension "${extensionTarget}" was not found in ${scope} scope.`, EXIT_CODE.NOT_FOUND);
1364
+ const extensionDirectory = path.join(resolvedRoots.selected_root, candidate.directory);
1365
+ const validated = await validateExtensionDirectory(extensionDirectory);
1366
+ const now = nowIso();
1367
+ const sourceRecord = githubOption === undefined
1368
+ ? {
1369
+ kind: "local",
1370
+ input: extensionTarget,
1371
+ location: extensionDirectory,
1205
1372
  }
1206
- const settingsChanged = action === "activate" ? ensureActivated(settings, candidate.name) : ensureDeactivated(settings, candidate.name);
1207
- if (settingsChanged) {
1208
- await writeSettings(resolvedRoots.settings_root, settings, "settings:write");
1373
+ : (() => {
1374
+ const parsed = parseExtensionInstallSource(githubOption, {
1375
+ forceGithub: true,
1376
+ ref: options.ref,
1377
+ });
1378
+ /* c8 ignore start -- forceGithub guarantees a github-kind install source */
1379
+ if (parsed.kind !== "github") {
1380
+ throw new PmCliError(`Invalid GitHub shorthand "${githubOption}".`, EXIT_CODE.USAGE);
1381
+ }
1382
+ /* c8 ignore stop */
1383
+ /* c8 ignore start -- github subpath defaults are validated in install-source parser tests */
1384
+ return {
1385
+ kind: "github",
1386
+ input: parsed.input,
1387
+ location: parsed.subpath ?? ".",
1388
+ repository: parsed.repository,
1389
+ owner: parsed.owner,
1390
+ repo: parsed.repo,
1391
+ ref: parsed.ref,
1392
+ subpath: parsed.subpath,
1393
+ };
1394
+ /* c8 ignore stop */
1395
+ })();
1396
+ const managedState = upsertManagedEntry(managedStateRead.state, {
1397
+ name: validated.manifest.name,
1398
+ directory: candidate.directory,
1399
+ scope,
1400
+ manifest_version: validated.manifest.version,
1401
+ manifest_entry: validated.manifest.entry,
1402
+ capabilities: [...validated.manifest.capabilities],
1403
+ installed_at: now,
1404
+ updated_at: now,
1405
+ source: sourceRecord,
1406
+ });
1407
+ await writeManagedExtensionState(resolvedRoots.selected_root, managedState);
1408
+ const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedState);
1409
+ warnings.push(...refreshedInstalled.warnings);
1410
+ /* c8 ignore start -- fallback only matters if a manifest renames between adopt and refresh */
1411
+ const refreshedEntry = refreshedInstalled.extensions.find((entry) => normalizeExtensionNameForMatch(entry.name) === normalizeExtensionNameForMatch(validated.manifest.name)) ??
1412
+ refreshedInstalled.extensions.find((entry) => normalizeExtensionNameForMatch(entry.directory) === normalizeExtensionNameForMatch(candidate.directory));
1413
+ /* c8 ignore stop */
1414
+ /* c8 ignore start -- adopt result mirrors refreshedEntry optionals for display only */
1415
+ return withResult({
1416
+ adopted: true,
1417
+ extension: {
1418
+ name: validated.manifest.name,
1419
+ directory: candidate.directory,
1420
+ version: validated.manifest.version,
1421
+ entry: validated.manifest.entry,
1422
+ },
1423
+ source: sourceRecord,
1424
+ update_check_status: refreshedEntry?.update_check_status ?? null,
1425
+ update_check_reason: refreshedEntry?.update_check_reason ?? null,
1426
+ });
1427
+ /* c8 ignore stop */
1428
+ }
1429
+ async function runExtensionUninstallAction(ctx) {
1430
+ const { action, normalizedTarget, scope, resolvedRoots, warnings, options, withResult } = ctx;
1431
+ const extensionTarget = requireTarget(normalizedTarget, action, options);
1432
+ const settings = await readSettings(resolvedRoots.settings_root);
1433
+ const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1434
+ warnings.push(...managedStateRead.warnings);
1435
+ const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1436
+ warnings.push(...installed.warnings);
1437
+ const candidate = await resolveInstalledExtensionCandidate(installed.extensions, extensionTarget);
1438
+ if (!candidate) {
1439
+ throw new PmCliError(`Installed extension "${extensionTarget}" was not found in ${scope} scope.`, EXIT_CODE.NOT_FOUND);
1440
+ }
1441
+ const destinationDirectory = path.join(resolvedRoots.selected_root, candidate.directory);
1442
+ await fs.rm(destinationDirectory, { recursive: true, force: true });
1443
+ const updatedState = {
1444
+ ...managedStateRead.state,
1445
+ updated_at: nowIso(),
1446
+ /* c8 ignore start -- uninstall filter keeps both name+directory guards for legacy managed-state migrations */
1447
+ entries: managedStateRead.state.entries.filter((entry) => normalizeExtensionNameForMatch(entry.name) !== normalizeExtensionNameForMatch(candidate.name) &&
1448
+ normalizeExtensionNameForMatch(entry.directory) !== normalizeExtensionNameForMatch(candidate.directory)),
1449
+ /* c8 ignore stop */
1450
+ };
1451
+ await writeManagedExtensionState(resolvedRoots.selected_root, updatedState);
1452
+ const stateChanged = clearExtensionState(settings, candidate.name);
1453
+ if (stateChanged) {
1454
+ await writeSettings(resolvedRoots.settings_root, settings, "settings:write");
1455
+ }
1456
+ return withResult({
1457
+ removed: true,
1458
+ extension: {
1459
+ name: candidate.name,
1460
+ directory: candidate.directory,
1461
+ },
1462
+ destination_path: destinationDirectory,
1463
+ settings_changed: stateChanged,
1464
+ });
1465
+ }
1466
+ async function runExtensionActivateDeactivateAction(ctx) {
1467
+ const { action, normalizedTarget, scope, resolvedRoots, warnings, options, withResult } = ctx;
1468
+ const extensionTarget = requireTarget(normalizedTarget, action, options);
1469
+ const settings = await readSettings(resolvedRoots.settings_root);
1470
+ const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1471
+ warnings.push(...managedStateRead.warnings);
1472
+ const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1473
+ warnings.push(...installed.warnings);
1474
+ const candidate = await resolveInstalledExtensionCandidate(installed.extensions, extensionTarget);
1475
+ if (!candidate) {
1476
+ throw new PmCliError(`Installed extension "${extensionTarget}" was not found in ${scope} scope.`, EXIT_CODE.NOT_FOUND);
1477
+ }
1478
+ const settingsChanged = action === "activate" ? ensureActivated(settings, candidate.name) : ensureDeactivated(settings, candidate.name);
1479
+ if (settingsChanged) {
1480
+ await writeSettings(resolvedRoots.settings_root, settings, "settings:write");
1481
+ }
1482
+ return withResult({
1483
+ extension: {
1484
+ name: candidate.name,
1485
+ directory: candidate.directory,
1486
+ },
1487
+ active: action === "activate",
1488
+ settings_changed: settingsChanged,
1489
+ settings: {
1490
+ enabled: [...settings.extensions.enabled],
1491
+ disabled: [...settings.extensions.disabled],
1492
+ },
1493
+ });
1494
+ }
1495
+ /**
1496
+ * Assemble the doctor remediation hints: the triage remediations, vocabulary-aware
1497
+ * advice to inspect load failures and activation failures, and a note when a
1498
+ * managed-state fix adopted entries. Blank entries are trimmed and the list is
1499
+ * de-duplicated.
1500
+ */
1501
+ function buildDoctorRemediation(baseRemediation, loadFailureCount, activationFailureCount, vocabulary, managedStateFix) {
1502
+ return [
1503
+ ...new Set([
1504
+ ...baseRemediation,
1505
+ /* c8 ignore start -- vocabulary-specific remediation branches are copy-only variants */
1506
+ ...(loadFailureCount > 0
1507
+ ? [
1508
+ vocabulary === "package"
1509
+ ? "Run pm package explore --project and pm package explore --global to inspect load failures."
1510
+ : "Run pm extension --explore --project and pm extension --explore --global to inspect load failures.",
1511
+ ]
1512
+ : []),
1513
+ ...(activationFailureCount > 0
1514
+ ? [
1515
+ vocabulary === "package"
1516
+ ? "Review activation failures in pm package doctor --detail deep output."
1517
+ : "Review activation failures in pm extension --doctor --detail deep output.",
1518
+ ]
1519
+ : []),
1520
+ /* c8 ignore stop */
1521
+ ...(managedStateFix && managedStateFix.adopted_entries.length > 0
1522
+ ? [`Managed-state fix adopted ${managedStateFix.adopted_entries.length} extension(s).`]
1523
+ : []),
1524
+ ].map((entry) => entry.trim()).filter((entry) => entry.length > 0)),
1525
+ ];
1526
+ }
1527
+ async function runExtensionDoctorAction(ctx) {
1528
+ const { normalizedTarget, scope, resolvedRoots, warnings, options, global, withResult } = ctx;
1529
+ if (normalizedTarget && normalizedTarget.trim().length > 0) {
1530
+ throw new PmCliError('Action "doctor" does not accept a target argument.', EXIT_CODE.USAGE);
1531
+ }
1532
+ const detailMode = parseDoctorDetailMode(options.detail);
1533
+ const includeTrace = options.trace === true;
1534
+ if (includeTrace && detailMode !== "deep") {
1535
+ throw new PmCliError("--trace requires --detail deep with --doctor.", EXIT_CODE.USAGE);
1536
+ }
1537
+ const settings = await readSettings(resolvedRoots.settings_root);
1538
+ const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1539
+ warnings.push(...managedStateRead.warnings);
1540
+ const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1541
+ warnings.push(...installed.warnings);
1542
+ let managedState = managedStateRead.state;
1543
+ const managedStateFix = options.fixManagedState === true
1544
+ ? await adoptUnmanagedExtensions(resolvedRoots.selected_root, scope, installed.extensions, managedStateRead.state)
1545
+ : null;
1546
+ if (managedStateFix) {
1547
+ managedState = managedStateFix.state;
1548
+ }
1549
+ const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedState);
1550
+ warnings.push(...refreshedInstalled.warnings);
1551
+ const loadResult = await loadExtensions({
1552
+ pmRoot: resolvedRoots.pm_root,
1553
+ settings,
1554
+ cwd: process.cwd(),
1555
+ noExtensions: global.noExtensions === true,
1556
+ });
1557
+ const activationResult = await activateExtensions({
1558
+ ...loadResult,
1559
+ loaded: loadResult.loaded,
1560
+ });
1561
+ warnings.push(...loadResult.warnings);
1562
+ warnings.push(...classifyDoctorLoadFailureWarnings(loadResult.failed));
1563
+ warnings.push(...activationResult.warnings);
1564
+ warnings.push(...classifyDoctorActivationFailureWarnings(activationResult.failed));
1565
+ warnings.push(...classifyUnusedCapabilityWarnings(loadResult, activationResult));
1566
+ warnings.push(...collectGlobalOutputOverrideDoctorWarnings(activationResult));
1567
+ warnings.push(...collectSchemaNarrowActivationDoctorWarnings(loadResult, activationResult));
1568
+ const runtimeInstalledExtensions = applyDoctorRuntimeActivationState(refreshedInstalled.extensions, loadResult, activationResult);
1569
+ const doctorConsistency = buildDoctorConsistencySummary(scope, runtimeInstalledExtensions, loadResult.loaded.map((entry) => ({ layer: entry.layer, name: entry.name })), loadResult.failed.map((entry) => ({ name: entry.name })), loadResult.disabled_by_flag);
1570
+ warnings.push(...doctorConsistency.warnings);
1571
+ const updateCheckWarnings = runtimeInstalledExtensions
1572
+ .filter((entry) => entry.update_check_status === "failed")
1573
+ .map((entry) => `extension_update_check_failed:${entry.name}`);
1574
+ warnings.push(...updateCheckWarnings);
1575
+ const triage = buildExtensionTriageSummary(scope, warnings, runtimeInstalledExtensions, options);
1576
+ warnings.push(...triage.warnings);
1577
+ const normalizedWarnings = [...triage.warnings];
1578
+ const policySummary = {
1579
+ mode: loadResult.policy.mode,
1580
+ trust_mode: loadResult.policy.trust_mode,
1581
+ require_provenance: loadResult.policy.require_provenance,
1582
+ default_sandbox_profile: loadResult.policy.default_sandbox_profile,
1583
+ // Honest trust model (ADR pm-6ef3): keep this caveat to one concise line.
1584
+ sandbox_enforcement: "advisory: sandbox_profile/permissions are declaration-based load gates, not runtime isolation (ADR pm-6ef3)",
1585
+ trusted_extensions_count: loadResult.policy.trusted_extensions.length,
1586
+ allowed_extensions_count: loadResult.policy.allowed_extensions.length,
1587
+ blocked_extensions_count: loadResult.policy.blocked_extensions.length,
1588
+ allowed_capabilities_count: loadResult.policy.allowed_capabilities.length,
1589
+ blocked_capabilities_count: loadResult.policy.blocked_capabilities.length,
1590
+ allowed_surfaces_count: loadResult.policy.allowed_surfaces.length,
1591
+ blocked_surfaces_count: loadResult.policy.blocked_surfaces.length,
1592
+ allowed_commands_count: loadResult.policy.allowed_commands.length,
1593
+ blocked_commands_count: loadResult.policy.blocked_commands.length,
1594
+ allowed_actions_count: loadResult.policy.allowed_actions.length,
1595
+ blocked_actions_count: loadResult.policy.blocked_actions.length,
1596
+ allowed_services_count: loadResult.policy.allowed_services.length,
1597
+ blocked_services_count: loadResult.policy.blocked_services.length,
1598
+ extension_override_count: loadResult.policy.extension_overrides.length,
1599
+ };
1600
+ const capabilityGuidance = collectUnknownCapabilityGuidance(normalizedWarnings);
1601
+ const capabilityContract = buildCapabilityContractMetadata();
1602
+ const warningCodes = triage.warning_codes;
1603
+ const remediation = buildDoctorRemediation(triage.remediation, loadResult.failed.length, activationResult.failed.length, options.vocabulary, managedStateFix);
1604
+ const summary = {
1605
+ status: triage.status,
1606
+ scope,
1607
+ warning_count: triage.warning_count,
1608
+ warning_codes: warningCodes,
1609
+ total_extensions: runtimeInstalledExtensions.length,
1610
+ managed_total: runtimeInstalledExtensions.filter((entry) => entry.managed).length,
1611
+ enabled_total: runtimeInstalledExtensions.filter((entry) => entry.enabled).length,
1612
+ active_total: runtimeInstalledExtensions.filter((entry) => entry.active).length,
1613
+ unmanaged_loaded_extension_count: triage.unmanaged_loaded_extension_count,
1614
+ unmanaged_action_required_extension_count: triage.unmanaged_action_required_extension_count,
1615
+ unmanaged_expected_extension_count: triage.unmanaged_expected_extension_count,
1616
+ runtime_active_total: runtimeInstalledExtensions.filter((entry) => entry.runtime_active === true).length,
1617
+ activation_status_totals: {
1618
+ ok: runtimeInstalledExtensions.filter((entry) => entry.activation_status === "ok").length,
1619
+ failed: runtimeInstalledExtensions.filter((entry) => entry.activation_status === "failed").length,
1620
+ not_loaded: runtimeInstalledExtensions.filter((entry) => entry.activation_status === "not_loaded").length,
1621
+ unknown: runtimeInstalledExtensions.filter((entry) => entry.activation_status === "unknown").length,
1622
+ },
1623
+ unknown_capability_count: capabilityGuidance.length,
1624
+ capability_contract_version: capabilityContract.version,
1625
+ update_available_total: runtimeInstalledExtensions.filter((entry) => entry.update_available === true).length,
1626
+ update_health_coverage: triage.update_health_coverage,
1627
+ update_health_partial: triage.update_health_partial,
1628
+ update_check_failed_total: runtimeInstalledExtensions.filter((entry) => entry.update_check_status === "failed").length,
1629
+ load_failure_count: loadResult.failed.length,
1630
+ activation_failure_count: activationResult.failed.length,
1631
+ blocking_failure_count: loadResult.failed.length + activationResult.failed.length,
1632
+ has_blocking_failures: loadResult.failed.length + activationResult.failed.length > 0,
1633
+ consistency_warning_count: doctorConsistency.warnings.length,
1634
+ trace_enabled: includeTrace,
1635
+ policy: policySummary,
1636
+ remediation,
1637
+ };
1638
+ const managedStateFixSummary = managedStateFix
1639
+ ? {
1640
+ requested: true,
1641
+ applied: managedStateFix.adopted_entries.length > 0,
1642
+ adopted_count: managedStateFix.adopted_entries.length,
1643
+ already_managed_count: managedStateFix.already_managed_count,
1644
+ adopted_extensions: managedStateFix.adopted_entries.map((entry) => entry.name),
1209
1645
  }
1210
- return withResult({
1211
- extension: {
1212
- name: candidate.name,
1213
- directory: candidate.directory,
1646
+ : {
1647
+ requested: false,
1648
+ applied: false,
1649
+ adopted_count: 0,
1650
+ already_managed_count: refreshedInstalled.extensions.filter((entry) => entry.managed).length,
1651
+ adopted_extensions: [],
1652
+ };
1653
+ const details = {
1654
+ mode: detailMode,
1655
+ summary,
1656
+ triage,
1657
+ trace_enabled: includeTrace,
1658
+ capability_contract: capabilityContract,
1659
+ capability_guidance: capabilityGuidance,
1660
+ managed_state_fix: managedStateFixSummary,
1661
+ policy: loadResult.policy,
1662
+ };
1663
+ if (detailMode === "deep") {
1664
+ const activationFailedDetails = includeTrace
1665
+ ? activationResult.failed
1666
+ : activationResult.failed.map((entry) => {
1667
+ const { trace: _trace, ...rest } = entry;
1668
+ return rest;
1669
+ });
1670
+ details.deep = {
1671
+ warnings: normalizedWarnings,
1672
+ warning_codes: warningCodes,
1673
+ capability_contract: capabilityContract,
1674
+ capability_guidance: capabilityGuidance,
1675
+ trace_enabled: includeTrace,
1676
+ managed_state: {
1677
+ path: managedStateRead.path,
1678
+ count: managedState.entries.length,
1679
+ entries: managedState.entries,
1214
1680
  },
1215
- active: action === "activate",
1216
- settings_changed: settingsChanged,
1217
- settings: {
1218
- enabled: [...settings.extensions.enabled],
1219
- disabled: [...settings.extensions.disabled],
1681
+ installed_extensions: runtimeInstalledExtensions,
1682
+ load: {
1683
+ roots: loadResult.roots,
1684
+ policy: loadResult.policy,
1685
+ warnings: loadResult.warnings,
1686
+ failed: loadResult.failed,
1687
+ loaded: loadResult.loaded.map((entry) => ({
1688
+ layer: entry.layer,
1689
+ directory: entry.directory,
1690
+ name: entry.name,
1691
+ version: entry.version,
1692
+ entry: entry.entry,
1693
+ priority: entry.priority,
1694
+ })),
1220
1695
  },
1221
- });
1222
- }
1223
- if (action === "doctor") {
1224
- if (normalizedTarget && normalizedTarget.trim().length > 0) {
1225
- throw new PmCliError('Action "doctor" does not accept a target argument.', EXIT_CODE.USAGE);
1226
- }
1227
- const detailMode = parseDoctorDetailMode(options.detail);
1228
- const includeTrace = options.trace === true;
1229
- if (includeTrace && detailMode !== "deep") {
1230
- throw new PmCliError("--trace requires --detail deep with --doctor.", EXIT_CODE.USAGE);
1231
- }
1232
- const settings = await readSettings(resolvedRoots.settings_root);
1233
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1234
- warnings.push(...managedStateRead.warnings);
1235
- const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1236
- warnings.push(...installed.warnings);
1237
- let managedState = managedStateRead.state;
1238
- const managedStateFix = options.fixManagedState === true
1239
- ? await adoptUnmanagedExtensions(resolvedRoots.selected_root, scope, installed.extensions, managedStateRead.state)
1240
- : null;
1241
- if (managedStateFix) {
1242
- managedState = managedStateFix.state;
1696
+ activation: {
1697
+ failed: activationFailedDetails,
1698
+ warnings: activationResult.warnings,
1699
+ hook_counts: activationResult.hook_counts,
1700
+ registration_counts: activationResult.registration_counts,
1701
+ parser_override_count: activationResult.parser_override_count,
1702
+ preflight_override_count: activationResult.preflight_override_count,
1703
+ service_override_count: activationResult.service_override_count,
1704
+ renderer_override_count: activationResult.renderer_override_count,
1705
+ },
1706
+ consistency: doctorConsistency.summary,
1707
+ };
1708
+ if (includeTrace) {
1709
+ details.deep.trace = {
1710
+ activation_failures: activationResult.failed
1711
+ .filter((entry) => entry.trace !== undefined)
1712
+ .map((entry) => ({
1713
+ layer: entry.layer,
1714
+ name: entry.name,
1715
+ entry_path: entry.entry_path,
1716
+ error: entry.error,
1717
+ method: entry.trace?.method,
1718
+ command: entry.trace?.command,
1719
+ capability: entry.trace?.capability,
1720
+ missing_capability: entry.trace?.missing_capability,
1721
+ registration_index: entry.trace?.registration_index,
1722
+ expected_schema: entry.trace?.expected_schema,
1723
+ hint: entry.trace?.hint,
1724
+ received: entry.trace?.received,
1725
+ })),
1726
+ };
1243
1727
  }
1244
- const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedState);
1245
- warnings.push(...refreshedInstalled.warnings);
1728
+ }
1729
+ return withResult(details);
1730
+ }
1731
+ async function runExtensionDescribeAction(ctx) {
1732
+ const { normalizedTarget, scope, resolvedRoots, warnings, options, global, withResult } = ctx;
1733
+ const settings = await readSettings(resolvedRoots.settings_root);
1734
+ const loadResult = await loadExtensions({
1735
+ pmRoot: resolvedRoots.pm_root,
1736
+ settings,
1737
+ cwd: process.cwd(),
1738
+ noExtensions: global.noExtensions === true,
1739
+ });
1740
+ const activationResult = await activateExtensions(loadResult);
1741
+ warnings.push(...loadResult.warnings);
1742
+ warnings.push(...activationResult.warnings);
1743
+ const describeResult = buildExtensionDescribeResult(normalizedTarget, loadResult, activationResult);
1744
+ if (normalizedTarget !== undefined && describeResult.extensions.length === 0) {
1745
+ const noun = options.vocabulary === "package" ? "package" : "extension";
1746
+ throw new PmCliError(`No loaded ${noun} named "${normalizedTarget}" was found in ${scope} scope. Run pm ${noun} explore to list discovered ${noun}s.`, EXIT_CODE.NOT_FOUND);
1747
+ }
1748
+ return withResult({
1749
+ target: describeResult.target,
1750
+ total: describeResult.total,
1751
+ extensions: describeResult.extensions,
1752
+ union: describeResult.union,
1753
+ });
1754
+ }
1755
+ /* c8 ignore start -- explore/manage action split is validated by dedicated command-action tests */
1756
+ async function runExtensionExploreManageAction(ctx) {
1757
+ const { action, scope, resolvedRoots, warnings, options, global, withResult } = ctx;
1758
+ const settings = await readSettings(resolvedRoots.settings_root);
1759
+ const configuredPolicy = buildExtensionPolicyDetails(settings.extensions.policy);
1760
+ const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1761
+ warnings.push(...managedStateRead.warnings);
1762
+ const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1763
+ warnings.push(...installed.warnings);
1764
+ let managedState = managedStateRead.state;
1765
+ const managedStateFix = action === "manage" && options.fixManagedState === true
1766
+ ? await adoptUnmanagedExtensions(resolvedRoots.selected_root, scope, installed.extensions, managedStateRead.state)
1767
+ : null;
1768
+ if (managedStateFix) {
1769
+ managedState = managedStateFix.state;
1770
+ }
1771
+ if (action === "manage") {
1772
+ const updates = await Promise.all(managedState.entries.map(async (entry) => {
1773
+ if (entry.source.kind !== "github") {
1774
+ return entry;
1775
+ }
1776
+ const updateStatus = await checkGithubUpdate(entry.source);
1777
+ return {
1778
+ ...entry,
1779
+ last_update_check_at: updateStatus.checked_at,
1780
+ last_update_remote_commit: updateStatus.remote_commit,
1781
+ update_available: updateStatus.available,
1782
+ update_error: updateStatus.error,
1783
+ };
1784
+ }));
1785
+ managedState = {
1786
+ ...managedState,
1787
+ updated_at: nowIso(),
1788
+ entries: sortManagedEntries(updates),
1789
+ };
1790
+ await writeManagedExtensionState(resolvedRoots.selected_root, managedState);
1791
+ }
1792
+ const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedState);
1793
+ warnings.push(...refreshedInstalled.warnings);
1794
+ if (action === "manage") {
1795
+ const updateWarnings = refreshedInstalled.extensions
1796
+ .filter((entry) => entry.update_check_status === "failed")
1797
+ .map((entry) => `extension_update_check_failed:${entry.name}`);
1798
+ warnings.push(...updateWarnings);
1799
+ }
1800
+ let runtimeProbeSummary;
1801
+ let runtimeInstalledExtensions = refreshedInstalled.extensions;
1802
+ let runtimeActivationFailures;
1803
+ if (action === "explore" || options.runtimeProbe === true) {
1246
1804
  const loadResult = await loadExtensions({
1247
1805
  pmRoot: resolvedRoots.pm_root,
1248
1806
  settings,
@@ -1254,344 +1812,86 @@ export async function runExtension(target, options, global) {
1254
1812
  loaded: loadResult.loaded,
1255
1813
  });
1256
1814
  warnings.push(...loadResult.warnings);
1257
- warnings.push(...classifyDoctorLoadFailureWarnings(loadResult.failed));
1258
1815
  warnings.push(...activationResult.warnings);
1259
- warnings.push(...classifyDoctorActivationFailureWarnings(activationResult.failed));
1260
- warnings.push(...classifyUnusedCapabilityWarnings(loadResult, activationResult));
1261
- warnings.push(...collectGlobalOutputOverrideDoctorWarnings(activationResult));
1262
- const runtimeInstalledExtensions = applyDoctorRuntimeActivationState(refreshedInstalled.extensions, loadResult, activationResult);
1263
- const doctorConsistency = buildDoctorConsistencySummary(scope, runtimeInstalledExtensions, loadResult.loaded.map((entry) => ({ layer: entry.layer, name: entry.name })), loadResult.failed.map((entry) => ({ name: entry.name })), loadResult.disabled_by_flag);
1264
- warnings.push(...doctorConsistency.warnings);
1265
- const updateCheckWarnings = runtimeInstalledExtensions
1266
- .filter((entry) => entry.update_check_status === "failed")
1267
- .map((entry) => `extension_update_check_failed:${entry.name}`);
1268
- warnings.push(...updateCheckWarnings);
1269
- const triage = buildExtensionTriageSummary(scope, warnings, runtimeInstalledExtensions, options);
1270
- warnings.push(...triage.warnings);
1271
- const normalizedWarnings = [...triage.warnings];
1272
- const policySummary = {
1273
- mode: loadResult.policy.mode,
1274
- trust_mode: loadResult.policy.trust_mode,
1275
- require_provenance: loadResult.policy.require_provenance,
1276
- default_sandbox_profile: loadResult.policy.default_sandbox_profile,
1277
- // Honest trust model (ADR pm-6ef3): keep this caveat to one concise line.
1278
- sandbox_enforcement: "advisory: sandbox_profile/permissions are declaration-based load gates, not runtime isolation (ADR pm-6ef3)",
1279
- trusted_extensions_count: loadResult.policy.trusted_extensions.length,
1280
- allowed_extensions_count: loadResult.policy.allowed_extensions.length,
1281
- blocked_extensions_count: loadResult.policy.blocked_extensions.length,
1282
- allowed_capabilities_count: loadResult.policy.allowed_capabilities.length,
1283
- blocked_capabilities_count: loadResult.policy.blocked_capabilities.length,
1284
- allowed_surfaces_count: loadResult.policy.allowed_surfaces.length,
1285
- blocked_surfaces_count: loadResult.policy.blocked_surfaces.length,
1286
- allowed_commands_count: loadResult.policy.allowed_commands.length,
1287
- blocked_commands_count: loadResult.policy.blocked_commands.length,
1288
- allowed_actions_count: loadResult.policy.allowed_actions.length,
1289
- blocked_actions_count: loadResult.policy.blocked_actions.length,
1290
- allowed_services_count: loadResult.policy.allowed_services.length,
1291
- blocked_services_count: loadResult.policy.blocked_services.length,
1292
- extension_override_count: loadResult.policy.extension_overrides.length,
1293
- };
1294
- const capabilityGuidance = collectUnknownCapabilityGuidance(normalizedWarnings);
1295
- const capabilityContract = buildCapabilityContractMetadata();
1296
- const warningCodes = triage.warning_codes;
1297
- const remediation = [
1298
- ...new Set([
1299
- ...triage.remediation,
1300
- /* c8 ignore start -- vocabulary-specific remediation branches are copy-only variants */
1301
- ...(loadResult.failed.length > 0
1302
- ? [
1303
- options.vocabulary === "package"
1304
- ? "Run pm package explore --project and pm package explore --global to inspect load failures."
1305
- : "Run pm extension --explore --project and pm extension --explore --global to inspect load failures.",
1306
- ]
1307
- : []),
1308
- ...(activationResult.failed.length > 0
1309
- ? [
1310
- options.vocabulary === "package"
1311
- ? "Review activation failures in pm package doctor --detail deep output."
1312
- : "Review activation failures in pm extension --doctor --detail deep output.",
1313
- ]
1314
- : []),
1315
- /* c8 ignore stop */
1316
- ...(managedStateFix && managedStateFix.adopted_entries.length > 0
1317
- ? [`Managed-state fix adopted ${managedStateFix.adopted_entries.length} extension(s).`]
1318
- : []),
1319
- ].map((entry) => entry.trim()).filter((entry) => entry.length > 0)),
1320
- ];
1321
- const summary = {
1322
- status: triage.status,
1323
- scope,
1324
- warning_count: triage.warning_count,
1325
- warning_codes: warningCodes,
1326
- total_extensions: runtimeInstalledExtensions.length,
1327
- managed_total: runtimeInstalledExtensions.filter((entry) => entry.managed).length,
1328
- enabled_total: runtimeInstalledExtensions.filter((entry) => entry.enabled).length,
1329
- active_total: runtimeInstalledExtensions.filter((entry) => entry.active).length,
1330
- unmanaged_loaded_extension_count: triage.unmanaged_loaded_extension_count,
1331
- unmanaged_action_required_extension_count: triage.unmanaged_action_required_extension_count,
1332
- unmanaged_expected_extension_count: triage.unmanaged_expected_extension_count,
1333
- runtime_active_total: runtimeInstalledExtensions.filter((entry) => entry.runtime_active === true).length,
1334
- activation_status_totals: {
1335
- ok: runtimeInstalledExtensions.filter((entry) => entry.activation_status === "ok").length,
1336
- failed: runtimeInstalledExtensions.filter((entry) => entry.activation_status === "failed").length,
1337
- not_loaded: runtimeInstalledExtensions.filter((entry) => entry.activation_status === "not_loaded").length,
1338
- unknown: runtimeInstalledExtensions.filter((entry) => entry.activation_status === "unknown").length,
1339
- },
1340
- unknown_capability_count: capabilityGuidance.length,
1341
- capability_contract_version: capabilityContract.version,
1342
- update_available_total: runtimeInstalledExtensions.filter((entry) => entry.update_available === true).length,
1343
- update_health_coverage: triage.update_health_coverage,
1344
- update_health_partial: triage.update_health_partial,
1345
- update_check_failed_total: runtimeInstalledExtensions.filter((entry) => entry.update_check_status === "failed").length,
1816
+ runtimeInstalledExtensions = applyDoctorRuntimeActivationState(refreshedInstalled.extensions, loadResult, activationResult);
1817
+ runtimeActivationFailures = collectActivationFailureDiagnostics(activationResult.failed);
1818
+ runtimeProbeSummary = {
1819
+ requested: true,
1820
+ executed: true,
1821
+ reason: action === "explore" ? "explore_defaults_to_runtime_probe" : "runtime_probe_requested",
1346
1822
  load_failure_count: loadResult.failed.length,
1347
1823
  activation_failure_count: activationResult.failed.length,
1348
- blocking_failure_count: loadResult.failed.length + activationResult.failed.length,
1349
- has_blocking_failures: loadResult.failed.length + activationResult.failed.length > 0,
1350
- consistency_warning_count: doctorConsistency.warnings.length,
1351
- trace_enabled: includeTrace,
1352
- policy: policySummary,
1353
- remediation,
1354
- };
1355
- const managedStateFixSummary = managedStateFix
1356
- ? {
1357
- requested: true,
1358
- applied: managedStateFix.adopted_entries.length > 0,
1359
- adopted_count: managedStateFix.adopted_entries.length,
1360
- already_managed_count: managedStateFix.already_managed_count,
1361
- adopted_extensions: managedStateFix.adopted_entries.map((entry) => entry.name),
1362
- }
1363
- : {
1364
- requested: false,
1365
- applied: false,
1366
- adopted_count: 0,
1367
- already_managed_count: refreshedInstalled.extensions.filter((entry) => entry.managed).length,
1368
- adopted_extensions: [],
1369
- };
1370
- const details = {
1371
- mode: detailMode,
1372
- summary,
1373
- triage,
1374
- trace_enabled: includeTrace,
1375
- capability_contract: capabilityContract,
1376
- capability_guidance: capabilityGuidance,
1377
- managed_state_fix: managedStateFixSummary,
1824
+ warning_count: [...new Set([...loadResult.warnings, ...activationResult.warnings])].length,
1378
1825
  policy: loadResult.policy,
1379
1826
  };
1380
- if (detailMode === "deep") {
1381
- const activationFailedDetails = includeTrace
1382
- ? activationResult.failed
1383
- : activationResult.failed.map((entry) => {
1384
- const { trace: _trace, ...rest } = entry;
1385
- return rest;
1386
- });
1387
- details.deep = {
1388
- warnings: normalizedWarnings,
1389
- warning_codes: warningCodes,
1390
- capability_contract: capabilityContract,
1391
- capability_guidance: capabilityGuidance,
1392
- trace_enabled: includeTrace,
1393
- managed_state: {
1394
- path: managedStateRead.path,
1395
- count: managedState.entries.length,
1396
- entries: managedState.entries,
1397
- },
1398
- installed_extensions: runtimeInstalledExtensions,
1399
- load: {
1400
- roots: loadResult.roots,
1401
- policy: loadResult.policy,
1402
- warnings: loadResult.warnings,
1403
- failed: loadResult.failed,
1404
- loaded: loadResult.loaded.map((entry) => ({
1405
- layer: entry.layer,
1406
- directory: entry.directory,
1407
- name: entry.name,
1408
- version: entry.version,
1409
- entry: entry.entry,
1410
- priority: entry.priority,
1411
- })),
1412
- },
1413
- activation: {
1414
- failed: activationFailedDetails,
1415
- warnings: activationResult.warnings,
1416
- hook_counts: activationResult.hook_counts,
1417
- registration_counts: activationResult.registration_counts,
1418
- parser_override_count: activationResult.parser_override_count,
1419
- preflight_override_count: activationResult.preflight_override_count,
1420
- service_override_count: activationResult.service_override_count,
1421
- renderer_override_count: activationResult.renderer_override_count,
1422
- },
1423
- consistency: doctorConsistency.summary,
1424
- };
1425
- if (includeTrace) {
1426
- details.deep.trace = {
1427
- activation_failures: activationResult.failed
1428
- .filter((entry) => entry.trace !== undefined)
1429
- .map((entry) => ({
1430
- layer: entry.layer,
1431
- name: entry.name,
1432
- entry_path: entry.entry_path,
1433
- error: entry.error,
1434
- method: entry.trace?.method,
1435
- command: entry.trace?.command,
1436
- capability: entry.trace?.capability,
1437
- missing_capability: entry.trace?.missing_capability,
1438
- registration_index: entry.trace?.registration_index,
1439
- expected_schema: entry.trace?.expected_schema,
1440
- hint: entry.trace?.hint,
1441
- received: entry.trace?.received,
1442
- })),
1443
- };
1444
- }
1445
- }
1446
- return withResult(details);
1447
1827
  }
1448
- if (action === "describe") {
1449
- const settings = await readSettings(resolvedRoots.settings_root);
1450
- const loadResult = await loadExtensions({
1451
- pmRoot: resolvedRoots.pm_root,
1452
- settings,
1453
- cwd: process.cwd(),
1454
- noExtensions: global.noExtensions === true,
1455
- });
1456
- const activationResult = await activateExtensions(loadResult);
1457
- warnings.push(...loadResult.warnings);
1458
- warnings.push(...activationResult.warnings);
1459
- const describeResult = buildExtensionDescribeResult(normalizedTarget, loadResult, activationResult);
1460
- if (normalizedTarget !== undefined && describeResult.extensions.length === 0) {
1461
- const noun = options.vocabulary === "package" ? "package" : "extension";
1462
- throw new PmCliError(`No loaded ${noun} named "${normalizedTarget}" was found in ${scope} scope. Run pm ${noun} explore to list discovered ${noun}s.`, EXIT_CODE.NOT_FOUND);
1463
- }
1464
- return withResult({
1465
- target: describeResult.target,
1466
- total: describeResult.total,
1467
- extensions: describeResult.extensions,
1468
- union: describeResult.union,
1469
- });
1828
+ else if (action === "manage") {
1829
+ runtimeProbeSummary = {
1830
+ requested: false,
1831
+ executed: false,
1832
+ };
1470
1833
  }
1471
- /* c8 ignore start -- explore/manage action split is validated by dedicated command-action tests */
1472
- if (action === "explore" || action === "manage") {
1473
- const settings = await readSettings(resolvedRoots.settings_root);
1474
- const configuredPolicy = buildExtensionPolicyDetails(settings.extensions.policy);
1475
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1476
- warnings.push(...managedStateRead.warnings);
1477
- const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1478
- warnings.push(...installed.warnings);
1479
- let managedState = managedStateRead.state;
1480
- const managedStateFix = action === "manage" && options.fixManagedState === true
1481
- ? await adoptUnmanagedExtensions(resolvedRoots.selected_root, scope, installed.extensions, managedStateRead.state)
1482
- : null;
1483
- if (managedStateFix) {
1484
- managedState = managedStateFix.state;
1485
- }
1486
- if (action === "manage") {
1487
- const updates = await Promise.all(managedState.entries.map(async (entry) => {
1488
- if (entry.source.kind !== "github") {
1489
- return entry;
1834
+ const triage = buildExtensionTriageSummary(scope, warnings, runtimeInstalledExtensions, options);
1835
+ warnings.push(...triage.warnings);
1836
+ const details = {
1837
+ total: runtimeInstalledExtensions.length,
1838
+ managed_total: runtimeInstalledExtensions.filter((entry) => entry.managed).length,
1839
+ enabled_total: runtimeInstalledExtensions.filter((entry) => entry.enabled).length,
1840
+ active_total: runtimeInstalledExtensions.filter((entry) => entry.active).length,
1841
+ extensions: runtimeInstalledExtensions,
1842
+ triage,
1843
+ policy: configuredPolicy,
1844
+ };
1845
+ if (runtimeActivationFailures !== undefined) {
1846
+ details.activation_diagnostics = {
1847
+ failed_count: runtimeActivationFailures.length,
1848
+ failed: runtimeActivationFailures,
1849
+ };
1850
+ }
1851
+ if (action === "explore") {
1852
+ details.runtime_probe = runtimeProbeSummary;
1853
+ }
1854
+ if (action === "manage") {
1855
+ details.runtime_probe = runtimeProbeSummary;
1856
+ details.managed_state_fix =
1857
+ managedStateFix !== null
1858
+ ? {
1859
+ requested: true,
1860
+ applied: managedStateFix.adopted_entries.length > 0,
1861
+ adopted_count: managedStateFix.adopted_entries.length,
1862
+ adopted_extensions: managedStateFix.adopted_entries.map((entry) => entry.name),
1863
+ already_managed_count: managedStateFix.already_managed_count,
1490
1864
  }
1491
- const updateStatus = await checkGithubUpdate(entry.source);
1492
- return {
1493
- ...entry,
1494
- last_update_check_at: updateStatus.checked_at,
1495
- last_update_remote_commit: updateStatus.remote_commit,
1496
- update_available: updateStatus.available,
1497
- update_error: updateStatus.error,
1865
+ : {
1866
+ requested: false,
1867
+ applied: false,
1868
+ adopted_count: 0,
1869
+ adopted_extensions: [],
1870
+ already_managed_count: runtimeInstalledExtensions.filter((entry) => entry.managed).length,
1498
1871
  };
1499
- }));
1500
- managedState = {
1501
- ...managedState,
1502
- updated_at: nowIso(),
1503
- entries: sortManagedEntries(updates),
1504
- };
1505
- await writeManagedExtensionState(resolvedRoots.selected_root, managedState);
1506
- }
1507
- const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedState);
1508
- warnings.push(...refreshedInstalled.warnings);
1509
- if (action === "manage") {
1510
- const updateWarnings = refreshedInstalled.extensions
1511
- .filter((entry) => entry.update_check_status === "failed")
1512
- .map((entry) => `extension_update_check_failed:${entry.name}`);
1513
- warnings.push(...updateWarnings);
1514
- }
1515
- let runtimeProbeSummary;
1516
- let runtimeInstalledExtensions = refreshedInstalled.extensions;
1517
- let runtimeActivationFailures;
1518
- if (action === "explore" || options.runtimeProbe === true) {
1519
- const loadResult = await loadExtensions({
1520
- pmRoot: resolvedRoots.pm_root,
1521
- settings,
1522
- cwd: process.cwd(),
1523
- noExtensions: global.noExtensions === true,
1524
- });
1525
- const activationResult = await activateExtensions({
1526
- ...loadResult,
1527
- loaded: loadResult.loaded,
1528
- });
1529
- warnings.push(...loadResult.warnings);
1530
- warnings.push(...activationResult.warnings);
1531
- runtimeInstalledExtensions = applyDoctorRuntimeActivationState(refreshedInstalled.extensions, loadResult, activationResult);
1532
- runtimeActivationFailures = collectActivationFailureDiagnostics(activationResult.failed);
1533
- runtimeProbeSummary = {
1534
- requested: true,
1535
- executed: true,
1536
- reason: action === "explore" ? "explore_defaults_to_runtime_probe" : "runtime_probe_requested",
1537
- load_failure_count: loadResult.failed.length,
1538
- activation_failure_count: activationResult.failed.length,
1539
- warning_count: [...new Set([...loadResult.warnings, ...activationResult.warnings])].length,
1540
- policy: loadResult.policy,
1541
- };
1542
- }
1543
- else if (action === "manage") {
1544
- runtimeProbeSummary = {
1545
- requested: false,
1546
- executed: false,
1547
- };
1548
- }
1549
- const triage = buildExtensionTriageSummary(scope, warnings, runtimeInstalledExtensions, options);
1550
- warnings.push(...triage.warnings);
1551
- const details = {
1552
- total: runtimeInstalledExtensions.length,
1553
- managed_total: runtimeInstalledExtensions.filter((entry) => entry.managed).length,
1554
- enabled_total: runtimeInstalledExtensions.filter((entry) => entry.enabled).length,
1555
- active_total: runtimeInstalledExtensions.filter((entry) => entry.active).length,
1556
- extensions: runtimeInstalledExtensions,
1557
- triage,
1558
- policy: configuredPolicy,
1559
- };
1560
- if (runtimeActivationFailures !== undefined) {
1561
- details.activation_diagnostics = {
1562
- failed_count: runtimeActivationFailures.length,
1563
- failed: runtimeActivationFailures,
1564
- };
1565
- }
1566
- if (action === "explore") {
1567
- details.runtime_probe = runtimeProbeSummary;
1568
- }
1569
- if (action === "manage") {
1570
- details.runtime_probe = runtimeProbeSummary;
1571
- details.managed_state_fix =
1572
- managedStateFix !== null
1573
- ? {
1574
- requested: true,
1575
- applied: managedStateFix.adopted_entries.length > 0,
1576
- adopted_count: managedStateFix.adopted_entries.length,
1577
- adopted_extensions: managedStateFix.adopted_entries.map((entry) => entry.name),
1578
- already_managed_count: managedStateFix.already_managed_count,
1579
- }
1580
- : {
1581
- requested: false,
1582
- applied: false,
1583
- adopted_count: 0,
1584
- adopted_extensions: [],
1585
- already_managed_count: runtimeInstalledExtensions.filter((entry) => entry.managed).length,
1586
- };
1587
- }
1588
- return withResult(details);
1589
1872
  }
1590
- /* c8 ignore stop */
1591
- /* c8 ignore start -- resolveAction returns a closed ExtensionCommandAction union */
1592
- throw new PmCliError(`Unsupported extension action "${action}".`, EXIT_CODE.USAGE);
1593
- /* c8 ignore stop */
1873
+ return withResult(details);
1594
1874
  }
1875
+ /* c8 ignore stop */
1876
+ // Dispatch table from lifecycle action to its handler. `explore`/`manage` and
1877
+ // `activate`/`deactivate` share a handler that branches on `ctx.action`; the
1878
+ // closed ExtensionCommandAction union guarantees every action has an entry, so
1879
+ // runExtension needs no unsupported-action fallthrough.
1880
+ const EXTENSION_ACTION_HANDLERS = {
1881
+ init: runExtensionInitAction,
1882
+ install: runExtensionInstallAction,
1883
+ uninstall: runExtensionUninstallAction,
1884
+ explore: runExtensionExploreManageAction,
1885
+ manage: runExtensionExploreManageAction,
1886
+ describe: runExtensionDescribeAction,
1887
+ reload: runExtensionReloadAction,
1888
+ doctor: runExtensionDoctorAction,
1889
+ catalog: runExtensionCatalogAction,
1890
+ adopt: runExtensionAdoptAction,
1891
+ "adopt-all": runExtensionAdoptAllAction,
1892
+ activate: runExtensionActivateDeactivateAction,
1893
+ deactivate: runExtensionActivateDeactivateAction,
1894
+ };
1595
1895
  export const _testOnly = {
1596
1896
  adoptUnmanagedExtensions,
1597
1897
  buildExtensionPolicyDetails,
@@ -1602,6 +1902,7 @@ export const _testOnly = {
1602
1902
  findActivationFailureByName,
1603
1903
  resolveInstallRuntimeActivationStatus,
1604
1904
  collectGlobalOutputOverrideDoctorWarnings,
1905
+ collectSchemaNarrowActivationDoctorWarnings,
1605
1906
  copyExtensionDirectoryWithoutSelfNesting,
1606
1907
  isErrnoCode,
1607
1908
  isRetriableExtensionInstallCopyError,
@@ -1616,4 +1917,4 @@ export const _testOnly = {
1616
1917
  withExtensionInstallLock,
1617
1918
  };
1618
1919
  //# sourceMappingURL=extension.js.map
1619
- //# debugId=68131f37-e747-546c-ab4d-f986cdd37b76
1920
+ //# debugId=0e9a5528-9595-5a89-89b7-5a5acce477a8