@unbrained/pm-cli 2026.7.14 → 2026.7.16

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 (708) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +54 -0
  3. package/README.md +14 -11
  4. package/dist/cli/argv-utils.d.ts +1 -4
  5. package/dist/cli/argv-utils.js +3 -13
  6. package/dist/cli/argv-utils.js.map +1 -1
  7. package/dist/cli/bootstrap-args.d.ts +6 -4
  8. package/dist/cli/bootstrap-args.js +51 -16
  9. package/dist/cli/bootstrap-args.js.map +1 -1
  10. package/dist/cli/bundle-integrity.d.ts +49 -0
  11. package/dist/cli/bundle-integrity.js +111 -0
  12. package/dist/cli/bundle-integrity.js.map +1 -0
  13. package/dist/cli/commands/completion.js +7 -2
  14. package/dist/cli/commands/completion.js.map +1 -1
  15. package/dist/cli/commands/config.d.ts +6 -163
  16. package/dist/cli/commands/config.js +4 -1133
  17. package/dist/cli/commands/config.js.map +1 -1
  18. package/dist/cli/commands/context.d.ts +2 -4
  19. package/dist/cli/commands/context.js +10 -85
  20. package/dist/cli/commands/context.js.map +1 -1
  21. package/dist/cli/commands/create.d.ts +1 -0
  22. package/dist/cli/commands/create.js +3 -2
  23. package/dist/cli/commands/create.js.map +1 -1
  24. package/dist/cli/commands/extension/describe.d.ts +2 -91
  25. package/dist/cli/commands/extension/describe.js +4 -142
  26. package/dist/cli/commands/extension/describe.js.map +1 -1
  27. package/dist/cli/commands/extension/scaffold.d.ts +2 -36
  28. package/dist/cli/commands/extension/scaffold.js +4 -2435
  29. package/dist/cli/commands/extension/scaffold.js.map +1 -1
  30. package/dist/cli/commands/extension/shared.d.ts +2 -28
  31. package/dist/cli/commands/extension/shared.js +4 -130
  32. package/dist/cli/commands/extension/shared.js.map +1 -1
  33. package/dist/cli/commands/extension.d.ts +3 -400
  34. package/dist/cli/commands/extension.js +4 -2183
  35. package/dist/cli/commands/extension.js.map +1 -1
  36. package/dist/cli/commands/gc.d.ts +6 -56
  37. package/dist/cli/commands/gc.js +4 -270
  38. package/dist/cli/commands/gc.js.map +1 -1
  39. package/dist/cli/commands/get.d.ts +18 -5
  40. package/dist/cli/commands/get.js +117 -58
  41. package/dist/cli/commands/get.js.map +1 -1
  42. package/dist/cli/commands/health.d.ts +6 -184
  43. package/dist/cli/commands/health.js +4 -1747
  44. package/dist/cli/commands/health.js.map +1 -1
  45. package/dist/cli/commands/history-compact.d.ts +4 -139
  46. package/dist/cli/commands/history-compact.js +5 -510
  47. package/dist/cli/commands/history-compact.js.map +1 -1
  48. package/dist/cli/commands/history-redact.d.ts +8 -120
  49. package/dist/cli/commands/history-redact.js +6 -581
  50. package/dist/cli/commands/history-redact.js.map +1 -1
  51. package/dist/cli/commands/history-repair.d.ts +7 -89
  52. package/dist/cli/commands/history-repair.js +5 -257
  53. package/dist/cli/commands/history-repair.js.map +1 -1
  54. package/dist/cli/commands/history.d.ts +1 -2
  55. package/dist/cli/commands/history.js +6 -48
  56. package/dist/cli/commands/history.js.map +1 -1
  57. package/dist/cli/commands/index.d.ts +1 -0
  58. package/dist/cli/commands/index.js +3 -2
  59. package/dist/cli/commands/index.js.map +1 -1
  60. package/dist/cli/commands/init-agent-guidance.d.ts +6 -113
  61. package/dist/cli/commands/init-agent-guidance.js +4 -431
  62. package/dist/cli/commands/init-agent-guidance.js.map +1 -1
  63. package/dist/cli/commands/init.d.ts +6 -181
  64. package/dist/cli/commands/init.js +4 -690
  65. package/dist/cli/commands/init.js.map +1 -1
  66. package/dist/cli/commands/next.js +3 -3
  67. package/dist/cli/commands/next.js.map +1 -1
  68. package/dist/cli/commands/profile.d.ts +4 -174
  69. package/dist/cli/commands/profile.js +4 -425
  70. package/dist/cli/commands/profile.js.map +1 -1
  71. package/dist/cli/commands/restore.d.ts +4 -19
  72. package/dist/cli/commands/restore.js +9 -158
  73. package/dist/cli/commands/restore.js.map +1 -1
  74. package/dist/cli/commands/schema.d.ts +7 -507
  75. package/dist/cli/commands/schema.js +5 -1254
  76. package/dist/cli/commands/schema.js.map +1 -1
  77. package/dist/cli/commands/test.d.ts +2 -4
  78. package/dist/cli/commands/test.js +7 -97
  79. package/dist/cli/commands/test.js.map +1 -1
  80. package/dist/cli/commands/validate.d.ts +9 -249
  81. package/dist/cli/commands/validate.js +9 -2150
  82. package/dist/cli/commands/validate.js.map +1 -1
  83. package/dist/cli/extension-command-help.js +18 -4
  84. package/dist/cli/extension-command-help.js.map +1 -1
  85. package/dist/cli/extension-command-options.js +3 -3
  86. package/dist/cli/extension-command-options.js.map +1 -1
  87. package/dist/cli/help-content.js +7 -3
  88. package/dist/cli/help-content.js.map +1 -1
  89. package/dist/cli/main.js +20 -30
  90. package/dist/cli/main.js.map +1 -1
  91. package/dist/cli/register-list-query.js +4 -2
  92. package/dist/cli/register-list-query.js.map +1 -1
  93. package/dist/cli/register-mutation.js +11 -3
  94. package/dist/cli/register-mutation.js.map +1 -1
  95. package/dist/cli/register-setup.js +4 -2
  96. package/dist/cli/register-setup.js.map +1 -1
  97. package/dist/cli/registration-helpers.js +3 -2
  98. package/dist/cli/registration-helpers.js.map +1 -1
  99. package/dist/cli-bundle/bundle-manifest.json +782 -0
  100. package/dist/cli-bundle/chunks/{append-PVZJDM6J.js → append-OJQFUQ4T.js} +5 -5
  101. package/dist/cli-bundle/chunks/append-UZVHUO74.js +11 -0
  102. package/dist/cli-bundle/chunks/{chunk-MQZ3PLCF.js → chunk-2IFFUZLC.js} +2 -2
  103. package/dist/cli-bundle/chunks/{chunk-P6MYFH6K.js → chunk-2JKGO6QX.js} +4 -4
  104. package/dist/cli-bundle/chunks/{chunk-X3GYR4P2.js → chunk-2NCIPMQP.js} +2 -2
  105. package/dist/cli-bundle/chunks/{chunk-Q7E6OYZK.js → chunk-2VPAVL7O.js} +2 -2
  106. package/dist/cli-bundle/chunks/{chunk-DRNJPEPQ.js → chunk-2WSE6PO2.js} +4 -4
  107. package/dist/cli-bundle/chunks/{chunk-FDSBDNYE.js → chunk-34L5OT3Y.js} +2 -2
  108. package/dist/cli-bundle/chunks/{chunk-TH7U4KLY.js → chunk-3AUGG2DP.js} +3 -3
  109. package/dist/cli-bundle/chunks/{chunk-NKW36AMT.js → chunk-3CLU2XZO.js} +4 -4
  110. package/dist/cli-bundle/chunks/{chunk-N3CMP4NI.js → chunk-3S5QVM5H.js} +43 -7
  111. package/dist/cli-bundle/chunks/chunk-3S5QVM5H.js.map +1 -0
  112. package/dist/cli-bundle/chunks/chunk-3U7ZR6M4.js +64 -0
  113. package/dist/cli-bundle/chunks/chunk-3U7ZR6M4.js.map +7 -0
  114. package/dist/cli-bundle/chunks/{chunk-ABRCOSDC.js → chunk-3WM75PWC.js} +3 -3
  115. package/dist/cli-bundle/chunks/chunk-4223PVZT.js +121 -0
  116. package/dist/cli-bundle/chunks/chunk-4223PVZT.js.map +7 -0
  117. package/dist/cli-bundle/chunks/{chunk-5URI7TPJ.js → chunk-4XQ3BDV4.js} +281 -164
  118. package/dist/cli-bundle/chunks/chunk-4XQ3BDV4.js.map +7 -0
  119. package/dist/cli-bundle/chunks/{chunk-X6BVXQ52.js → chunk-5JLUII3O.js} +13 -13
  120. package/dist/cli-bundle/chunks/{chunk-MKL4CP2I.js → chunk-5ZSLZLDN.js} +631 -246
  121. package/dist/cli-bundle/chunks/chunk-5ZSLZLDN.js.map +1 -0
  122. package/dist/cli-bundle/chunks/{chunk-Q37E63AM.js → chunk-6CFNAVTF.js} +21 -141
  123. package/dist/cli-bundle/chunks/chunk-6CFNAVTF.js.map +7 -0
  124. package/dist/cli-bundle/chunks/{chunk-3TL7WOEF.js → chunk-6N2VXVTQ.js} +2 -2
  125. package/dist/cli-bundle/chunks/{chunk-ERL2YFJ2.js → chunk-6S3YSUYG.js} +3 -3
  126. package/dist/cli-bundle/chunks/{chunk-ZUKSZVBW.js → chunk-7B67ZL4N.js} +8 -7
  127. package/dist/cli-bundle/chunks/chunk-7B67ZL4N.js.map +7 -0
  128. package/dist/cli-bundle/chunks/{chunk-IA3YFTXT.js → chunk-7PIWCHTW.js} +11 -13
  129. package/dist/cli-bundle/chunks/chunk-7PIWCHTW.js.map +1 -0
  130. package/dist/cli-bundle/chunks/{chunk-BPD26E3P.js → chunk-7Z4LKRS4.js} +291 -81
  131. package/dist/cli-bundle/chunks/chunk-7Z4LKRS4.js.map +1 -0
  132. package/dist/cli-bundle/chunks/{chunk-IFZA4VB5.js → chunk-AHVTB5I5.js} +4 -4
  133. package/dist/cli-bundle/chunks/{chunk-DO5RGJXT.js → chunk-APRVSW2O.js} +3 -3
  134. package/dist/cli-bundle/chunks/{chunk-NAQYVWSQ.js → chunk-B7PE22W6.js} +4 -4
  135. package/dist/cli-bundle/chunks/{chunk-MD6ULIPJ.js → chunk-BCOFWYW4.js} +3 -3
  136. package/dist/cli-bundle/chunks/{chunk-KADLSPIU.js → chunk-BEP7WJA2.js} +4 -4
  137. package/dist/cli-bundle/chunks/chunk-BKVG6XOA.js +1114 -0
  138. package/dist/cli-bundle/chunks/chunk-BKVG6XOA.js.map +7 -0
  139. package/dist/cli-bundle/chunks/{chunk-AFWZRL7M.js → chunk-BSEQUTQP.js} +2 -2
  140. package/dist/cli-bundle/chunks/{chunk-AFWZRL7M.js.map → chunk-BSEQUTQP.js.map} +2 -2
  141. package/dist/cli-bundle/chunks/{chunk-OBDLEQG5.js → chunk-CRVF2JDM.js} +10 -10
  142. package/dist/cli-bundle/chunks/{chunk-FJZDA6MS.js → chunk-DM4H7FP4.js} +3 -3
  143. package/dist/cli-bundle/chunks/chunk-DUT67M43.js +5 -0
  144. package/dist/cli-bundle/chunks/{chunk-44LNIULG.js → chunk-DYH63FX7.js} +4 -4
  145. package/dist/cli-bundle/chunks/{chunk-LWTIRS3Y.js → chunk-E2OJMKML.js} +306 -82
  146. package/dist/cli-bundle/chunks/chunk-E2OJMKML.js.map +7 -0
  147. package/dist/cli-bundle/chunks/{chunk-HAMLIWAF.js → chunk-EAB64KLB.js} +4 -4
  148. package/dist/cli-bundle/chunks/{chunk-CIOZ376P.js → chunk-EACOH7AU.js} +10 -10
  149. package/dist/cli-bundle/chunks/{chunk-HL7V2PHX.js → chunk-EH2OPHBI.js} +10 -10
  150. package/dist/cli-bundle/chunks/{chunk-HL7V2PHX.js.map → chunk-EH2OPHBI.js.map} +1 -1
  151. package/dist/cli-bundle/chunks/{chunk-QK2ZN6UL.js → chunk-EJEXHTY5.js} +2 -2
  152. package/dist/cli-bundle/chunks/{chunk-WQUEHPZB.js → chunk-EYLCSJAI.js} +2 -2
  153. package/dist/cli-bundle/chunks/{chunk-655STMGA.js → chunk-FMBNM2EN.js} +2 -2
  154. package/dist/cli-bundle/chunks/{chunk-RMF3IOYQ.js → chunk-FNSPG7MU.js} +12 -12
  155. package/dist/cli-bundle/chunks/{chunk-5CT5BW6E.js → chunk-GM5QHQU6.js} +46 -40
  156. package/dist/cli-bundle/chunks/chunk-GM5QHQU6.js.map +7 -0
  157. package/dist/cli-bundle/chunks/{chunk-FTQLW4JD.js → chunk-GOSLKLFE.js} +418 -24
  158. package/dist/cli-bundle/chunks/chunk-GOSLKLFE.js.map +1 -0
  159. package/dist/cli-bundle/chunks/{chunk-KB726FMH.js → chunk-H2Z3FYXQ.js} +4 -4
  160. package/dist/cli-bundle/chunks/chunk-H3EIEWGR.js +162 -0
  161. package/dist/cli-bundle/chunks/chunk-H3EIEWGR.js.map +1 -0
  162. package/dist/cli-bundle/chunks/{chunk-2QIQGYPW.js → chunk-H5APFTHZ.js} +53 -10
  163. package/dist/cli-bundle/chunks/chunk-H5APFTHZ.js.map +7 -0
  164. package/dist/cli-bundle/chunks/chunk-HDH3JUGG.js +118 -0
  165. package/dist/cli-bundle/chunks/chunk-HDH3JUGG.js.map +1 -0
  166. package/dist/cli-bundle/chunks/{chunk-ZAYYDNB3.js → chunk-HO4KXD6I.js} +22 -142
  167. package/dist/cli-bundle/chunks/chunk-HO4KXD6I.js.map +1 -0
  168. package/dist/cli-bundle/chunks/{chunk-ILLUE5DI.js → chunk-HYB5AZ63.js} +203 -62
  169. package/dist/cli-bundle/chunks/{chunk-ILLUE5DI.js.map → chunk-HYB5AZ63.js.map} +3 -3
  170. package/dist/cli-bundle/chunks/{chunk-BN62TO2S.js → chunk-IA5FKNII.js} +2 -2
  171. package/dist/cli-bundle/chunks/{chunk-JL7WZ4O2.js → chunk-IG3SWA4A.js} +33 -9
  172. package/dist/cli-bundle/chunks/chunk-IG3SWA4A.js.map +7 -0
  173. package/dist/cli-bundle/chunks/{chunk-W6HZ55JO.js → chunk-IJIICKVW.js} +2 -2
  174. package/dist/cli-bundle/chunks/{chunk-IGED7NH2.js → chunk-ILX33QXL.js} +668 -251
  175. package/dist/cli-bundle/chunks/chunk-ILX33QXL.js.map +7 -0
  176. package/dist/cli-bundle/chunks/{chunk-UGTVWL3E.js → chunk-INU6DKT5.js} +47 -41
  177. package/dist/cli-bundle/chunks/chunk-INU6DKT5.js.map +1 -0
  178. package/dist/cli-bundle/chunks/{chunk-UB2QYSTO.js → chunk-J5AOEGDC.js} +26 -18
  179. package/dist/cli-bundle/chunks/chunk-J5AOEGDC.js.map +1 -0
  180. package/dist/cli-bundle/chunks/{chunk-4DY4KPQI.js → chunk-J6364LFM.js} +1330 -937
  181. package/dist/cli-bundle/chunks/chunk-J6364LFM.js.map +7 -0
  182. package/dist/cli-bundle/chunks/{chunk-DVOLZJ3C.js → chunk-J6EY5V4N.js} +1295 -939
  183. package/dist/cli-bundle/chunks/chunk-J6EY5V4N.js.map +1 -0
  184. package/dist/cli-bundle/chunks/chunk-JFTKLTEF.js +1097 -0
  185. package/dist/cli-bundle/chunks/chunk-JFTKLTEF.js.map +1 -0
  186. package/dist/cli-bundle/chunks/{chunk-M7EWN4TF.js → chunk-JOUQZENX.js} +3 -3
  187. package/dist/cli-bundle/chunks/{chunk-J4NZOP3I.js → chunk-JXQUXVMI.js} +9 -8
  188. package/dist/cli-bundle/chunks/chunk-JXQUXVMI.js.map +1 -0
  189. package/dist/cli-bundle/chunks/{chunk-2FNWQXZ2.js → chunk-JYFOV7FC.js} +4 -4
  190. package/dist/cli-bundle/chunks/{chunk-HLHSQ5CA.js → chunk-K2X6U4UA.js} +4 -4
  191. package/dist/cli-bundle/chunks/{chunk-6OTZMORS.js → chunk-K3WII2ME.js} +27 -27
  192. package/dist/cli-bundle/chunks/chunk-K3WII2ME.js.map +7 -0
  193. package/dist/cli-bundle/chunks/{chunk-M6ASXYCU.js → chunk-KG44YSKD.js} +4 -4
  194. package/dist/cli-bundle/chunks/{chunk-YVKE5ZDM.js → chunk-KPMKHGEA.js} +4 -4
  195. package/dist/cli-bundle/chunks/{chunk-QASRVKUQ.js → chunk-LPYWLWDS.js} +257 -163
  196. package/dist/cli-bundle/chunks/chunk-LPYWLWDS.js.map +1 -0
  197. package/dist/cli-bundle/chunks/{chunk-RGXD5JJR.js → chunk-LSG2U345.js} +19 -12
  198. package/dist/cli-bundle/chunks/chunk-LSG2U345.js.map +7 -0
  199. package/dist/cli-bundle/chunks/chunk-MIQDDLB5.js +5 -0
  200. package/dist/cli-bundle/chunks/{chunk-UJ4HJYWL.js → chunk-NLDFBC6J.js} +2 -2
  201. package/dist/cli-bundle/chunks/{chunk-WRKB56FC.js → chunk-NP22ERDF.js} +3 -3
  202. package/dist/cli-bundle/chunks/{chunk-YQYG2V23.js → chunk-NU3IMIEA.js} +2 -2
  203. package/dist/cli-bundle/chunks/{chunk-3I3LRT2G.js → chunk-NVPZIJVR.js} +2 -2
  204. package/dist/cli-bundle/chunks/{chunk-JAF4TUQ7.js → chunk-ODALILG3.js} +2 -2
  205. package/dist/cli-bundle/chunks/{chunk-CDJYP7OQ.js → chunk-ONG5V5CI.js} +190 -63
  206. package/dist/cli-bundle/chunks/chunk-ONG5V5CI.js.map +1 -0
  207. package/dist/cli-bundle/chunks/{chunk-QZ7LT3XE.js → chunk-ONREO4ST.js} +3 -3
  208. package/dist/cli-bundle/chunks/chunk-OW4JWD5M.js +61 -0
  209. package/dist/cli-bundle/chunks/chunk-OW4JWD5M.js.map +1 -0
  210. package/dist/cli-bundle/chunks/{chunk-3CMRNVTO.js → chunk-P74IZQ7A.js} +12 -12
  211. package/dist/cli-bundle/chunks/chunk-PENXZX3U.js +172 -0
  212. package/dist/cli-bundle/chunks/chunk-PENXZX3U.js.map +7 -0
  213. package/dist/cli-bundle/chunks/{chunk-ZTRBSABY.js → chunk-PGY23YTC.js} +3 -3
  214. package/dist/cli-bundle/chunks/{chunk-H2QBAKLQ.js → chunk-PMOSXADO.js} +3 -3
  215. package/dist/cli-bundle/chunks/chunk-PNTULOGU.js +9 -0
  216. package/dist/cli-bundle/chunks/{chunk-GSEADLRH.js → chunk-Q7A43DS4.js} +2 -2
  217. package/dist/cli-bundle/chunks/{chunk-QSPARJWF.js → chunk-QEHQ2GVG.js} +2 -2
  218. package/dist/cli-bundle/chunks/{chunk-VJTAEIPC.js → chunk-QIPLHNP7.js} +7 -7
  219. package/dist/cli-bundle/chunks/{chunk-GXXC7QSK.js → chunk-QKECXBBG.js} +3 -3
  220. package/dist/cli-bundle/chunks/{chunk-GXXC7QSK.js.map → chunk-QKECXBBG.js.map} +1 -1
  221. package/dist/cli-bundle/chunks/{chunk-K7WNZ7KD.js → chunk-QKJGPFAF.js} +3 -3
  222. package/dist/cli-bundle/chunks/{chunk-F7PSHRNO.js → chunk-QKXHFPYM.js} +27 -10
  223. package/dist/cli-bundle/chunks/chunk-QKXHFPYM.js.map +1 -0
  224. package/dist/cli-bundle/chunks/{chunk-ZNP64HOW.js → chunk-RLCHOOHC.js} +2 -2
  225. package/dist/cli-bundle/chunks/{chunk-IAPHYPRL.js → chunk-RMLWNPH2.js} +2 -2
  226. package/dist/cli-bundle/chunks/{chunk-UVBA6F5A.js → chunk-RRM5JYJC.js} +2 -2
  227. package/dist/cli-bundle/chunks/{chunk-6IIVBC56.js → chunk-S6MQESFR.js} +4 -4
  228. package/dist/cli-bundle/chunks/{chunk-QABYZYLU.js → chunk-SDQLJWBO.js} +4 -4
  229. package/dist/cli-bundle/chunks/{chunk-ANSJHDOZ.js → chunk-SELVXEZK.js} +2 -2
  230. package/dist/cli-bundle/chunks/{chunk-DYEX6NFH.js → chunk-TD3LVC7D.js} +438 -23
  231. package/dist/cli-bundle/chunks/chunk-TD3LVC7D.js.map +7 -0
  232. package/dist/cli-bundle/chunks/{chunk-WD6MSYMP.js → chunk-TKOVBP6C.js} +2 -2
  233. package/dist/cli-bundle/chunks/{chunk-TZ2PSLLT.js → chunk-TQSZFPIS.js} +4 -4
  234. package/dist/cli-bundle/chunks/{chunk-WPAWZW7S.js → chunk-TSMHDIW4.js} +2 -2
  235. package/dist/cli-bundle/chunks/{chunk-TZRTLMWM.js → chunk-UFXU44HV.js} +4 -4
  236. package/dist/cli-bundle/chunks/{chunk-TWLDBKQU.js → chunk-ULTHRDBP.js} +3 -3
  237. package/dist/cli-bundle/chunks/{chunk-OI4S4KCI.js → chunk-UMOPHQSU.js} +9 -9
  238. package/dist/cli-bundle/chunks/{chunk-OI4S4KCI.js.map → chunk-UMOPHQSU.js.map} +2 -2
  239. package/dist/cli-bundle/chunks/{chunk-RA5AIAMP.js → chunk-UOHFKBUV.js} +3 -3
  240. package/dist/cli-bundle/chunks/{chunk-PHKP3AGR.js → chunk-UWQHLMEB.js} +35 -18
  241. package/dist/cli-bundle/chunks/chunk-UWQHLMEB.js.map +7 -0
  242. package/dist/cli-bundle/chunks/{chunk-6TTOHMTB.js → chunk-UXONS674.js} +45 -112
  243. package/dist/cli-bundle/chunks/chunk-UXONS674.js.map +1 -0
  244. package/dist/cli-bundle/chunks/{chunk-4RXTMU57.js → chunk-UY2ACEMF.js} +7 -7
  245. package/dist/cli-bundle/chunks/{chunk-6PKA3SJQ.js → chunk-WQPUU7XD.js} +19 -28
  246. package/dist/cli-bundle/chunks/chunk-WQPUU7XD.js.map +1 -0
  247. package/dist/cli-bundle/chunks/{chunk-7TQMR6LK.js → chunk-WT3ZEOGH.js} +70 -20
  248. package/dist/cli-bundle/chunks/chunk-WT3ZEOGH.js.map +7 -0
  249. package/dist/cli-bundle/chunks/{chunk-FIGXOCEQ.js → chunk-WUJQK4YV.js} +4 -4
  250. package/dist/cli-bundle/chunks/{chunk-T4BRCB6Z.js → chunk-XSJUSQAE.js} +2 -2
  251. package/dist/cli-bundle/chunks/{chunk-6MHSBDGD.js → chunk-XXXF6PAQ.js} +50 -117
  252. package/dist/cli-bundle/chunks/chunk-XXXF6PAQ.js.map +7 -0
  253. package/dist/cli-bundle/chunks/{chunk-UKUIIBDW.js → chunk-YAQEBNY7.js} +4 -4
  254. package/dist/cli-bundle/chunks/{chunk-7QDSYUMF.js → chunk-YAROI3PD.js} +44 -21
  255. package/dist/cli-bundle/chunks/chunk-YAROI3PD.js.map +1 -0
  256. package/dist/cli-bundle/chunks/{chunk-E2WC6S4P.js → chunk-YBLZ2VE7.js} +13 -13
  257. package/dist/cli-bundle/chunks/{chunk-Y72FV7RM.js → chunk-YCQET3OT.js} +2 -2
  258. package/dist/cli-bundle/chunks/chunk-YUSOJDWM.js +9 -0
  259. package/dist/cli-bundle/chunks/chunk-YXSHIAUJ.js +58 -0
  260. package/dist/cli-bundle/chunks/chunk-YXSHIAUJ.js.map +1 -0
  261. package/dist/cli-bundle/chunks/{chunk-FS6UM5WH.js → chunk-ZI6VQWQ7.js} +4 -4
  262. package/dist/cli-bundle/chunks/chunk-ZKRZY773.js +68 -0
  263. package/dist/cli-bundle/chunks/chunk-ZKRZY773.js.map +7 -0
  264. package/dist/cli-bundle/chunks/{close-LZECOMHO.js → close-CWODTPKG.js} +5 -5
  265. package/dist/cli-bundle/chunks/close-W6LI2PKM.js +12 -0
  266. package/dist/cli-bundle/chunks/{close-many-ZHI6A5TN.js → close-many-CQFUY7MR.js} +15 -13
  267. package/dist/cli-bundle/chunks/close-many-DLDDVSH5.js +23 -0
  268. package/dist/cli-bundle/chunks/comments-E3TNTK24.js +13 -0
  269. package/dist/cli-bundle/chunks/{comments-AJWRTFZ5.js → comments-WGLHR7LB.js} +7 -7
  270. package/dist/cli-bundle/chunks/{copy-GMXYKBXT.js → copy-LXVDXH7B.js} +4 -4
  271. package/dist/cli-bundle/chunks/copy-Q5ZJPUKR.js +9 -0
  272. package/dist/cli-bundle/chunks/{create-F53OBTOU.js → create-J5U6ND4K.js} +9 -9
  273. package/dist/cli-bundle/chunks/{create-HU4Q7RJX.js → create-LBVCYMEG.js} +9 -9
  274. package/dist/cli-bundle/chunks/{delete-GSDZLTRC.js → delete-PMJBNY5G.js} +4 -4
  275. package/dist/cli-bundle/chunks/delete-WNHB3LYW.js +10 -0
  276. package/dist/cli-bundle/chunks/{deps-WWB7P2GT.js → deps-JZ7TMVCB.js} +7 -4
  277. package/dist/cli-bundle/chunks/{deps-U57I7EAK.js → deps-OA26IS25.js} +7 -4
  278. package/dist/cli-bundle/chunks/{docs-MQIY2ZQS.js → docs-FEWB2DQB.js} +6 -6
  279. package/dist/cli-bundle/chunks/docs-HA2AIDBB.js +14 -0
  280. package/dist/cli-bundle/chunks/{files-TBZD7V6H.js → files-6YFBJRBG.js} +6 -6
  281. package/dist/cli-bundle/chunks/{files-TTY6N2AV.js → files-EFIWKFTM.js} +6 -6
  282. package/dist/cli-bundle/chunks/{focus-XT6YVFFX.js → focus-4QJR7FOQ.js} +5 -5
  283. package/dist/cli-bundle/chunks/focus-POIW5LTJ.js +10 -0
  284. package/dist/cli-bundle/chunks/{history-compact-KKVUWB4V.js → history-compact-CKRPDTJN.js} +6 -10
  285. package/dist/cli-bundle/chunks/history-compact-FWG2C7FZ.js +16 -0
  286. package/dist/cli-bundle/chunks/history-redact-BB3TGDAE.js +15 -0
  287. package/dist/cli-bundle/chunks/{history-redact-3DVZOILD.js → history-redact-D225BHOZ.js} +5 -6
  288. package/dist/cli-bundle/chunks/history-repair-6GEAM7HE.js +16 -0
  289. package/dist/cli-bundle/chunks/{history-repair-ITDUMK4N.js → history-repair-RQXKQHL4.js} +6 -8
  290. package/dist/cli-bundle/chunks/{learnings-FGO3NSFW.js → learnings-JLNLCOL5.js} +7 -7
  291. package/dist/cli-bundle/chunks/learnings-RSNLSWDC.js +13 -0
  292. package/dist/cli-bundle/chunks/notes-2WDH6DXU.js +13 -0
  293. package/dist/cli-bundle/chunks/{notes-NQ6RXVW6.js → notes-GB47XXQQ.js} +7 -7
  294. package/dist/cli-bundle/chunks/plan-DOVI2VMW.js +24 -0
  295. package/dist/cli-bundle/chunks/{plan-2NNEO46V.js → plan-VDCJ2PCN.js} +10 -10
  296. package/dist/cli-bundle/chunks/{profile-AAQUU6T3.js → profile-FAU7NZML.js} +10 -10
  297. package/dist/cli-bundle/chunks/{profile-U725ATWZ.js → profile-IVXQEL3D.js} +10 -10
  298. package/dist/cli-bundle/chunks/{register-list-query-BUWCYHBT.js → register-list-query-DKA3EH5D.js} +22 -19
  299. package/dist/cli-bundle/chunks/register-list-query-DKA3EH5D.js.map +7 -0
  300. package/dist/cli-bundle/chunks/{register-list-query-KTZ6AGE7.js → register-list-query-UL4UKBBN.js} +23 -20
  301. package/dist/cli-bundle/chunks/register-list-query-UL4UKBBN.js.map +1 -0
  302. package/dist/cli-bundle/chunks/{register-mutation-UELYYOR7.js → register-mutation-ARFHRW55.js} +36 -32
  303. package/dist/cli-bundle/chunks/{register-mutation-UELYYOR7.js.map → register-mutation-ARFHRW55.js.map} +2 -2
  304. package/dist/cli-bundle/chunks/{register-mutation-4FMGJJF7.js → register-mutation-RBBJ52DK.js} +37 -33
  305. package/dist/cli-bundle/chunks/register-mutation-RBBJ52DK.js.map +1 -0
  306. package/dist/cli-bundle/chunks/{register-operations-JVW24J2Y.js → register-operations-ZIBBRSED.js} +41 -39
  307. package/dist/cli-bundle/chunks/{register-operations-JVW24J2Y.js.map → register-operations-ZIBBRSED.js.map} +1 -1
  308. package/dist/cli-bundle/chunks/{register-operations-ISUX6LY5.js → register-operations-ZUJ5JWPE.js} +39 -37
  309. package/dist/cli-bundle/chunks/{register-operations-ISUX6LY5.js.map → register-operations-ZUJ5JWPE.js.map} +1 -1
  310. package/dist/cli-bundle/chunks/{register-setup-5XNGKJ22.js → register-setup-BCVLFEYS.js} +29 -17
  311. package/dist/cli-bundle/chunks/{register-setup-5XNGKJ22.js.map → register-setup-BCVLFEYS.js.map} +2 -2
  312. package/dist/cli-bundle/chunks/{register-setup-ZTNY6S7R.js → register-setup-TDCGWIOS.js} +19 -18
  313. package/dist/cli-bundle/chunks/{register-setup-ZTNY6S7R.js.map → register-setup-TDCGWIOS.js.map} +1 -1
  314. package/dist/cli-bundle/chunks/{restore-B3BAB6X2.js → restore-25DLT2Q2.js} +6 -6
  315. package/dist/cli-bundle/chunks/restore-YPMVUUEX.js +14 -0
  316. package/dist/cli-bundle/chunks/{schema-U7IM2DXV.js → schema-FNU3WE4O.js} +7 -6
  317. package/dist/cli-bundle/chunks/{schema-LZNUYHDB.js → schema-NBCM3RAD.js} +7 -6
  318. package/dist/cli-bundle/chunks/update-WWBYOPXO.js +21 -0
  319. package/dist/cli-bundle/chunks/update-WWBYOPXO.js.map +7 -0
  320. package/dist/cli-bundle/chunks/{update-Q3UCILNR.js → update-XHSIAIXE.js} +12 -12
  321. package/dist/cli-bundle/chunks/update-XHSIAIXE.js.map +1 -0
  322. package/dist/cli-bundle/chunks/update-many-OUGIU5SF.js +32 -0
  323. package/dist/cli-bundle/chunks/update-many-OUGIU5SF.js.map +7 -0
  324. package/dist/cli-bundle/chunks/update-many-TA7NGQBO.js +36 -0
  325. package/dist/cli-bundle/chunks/update-many-TA7NGQBO.js.map +1 -0
  326. package/dist/cli-bundle/main.js +826 -43
  327. package/dist/cli-bundle/main.js.map +4 -4
  328. package/dist/cli-bundle/sdk-runtime.js +70 -57
  329. package/dist/cli-bundle/sdk-testing.js +6 -6
  330. package/dist/cli-bundle/sdk.js +876 -74
  331. package/dist/cli-bundle/sdk.js.map +4 -4
  332. package/dist/cli.js +5 -4
  333. package/dist/cli.js.map +1 -1
  334. package/dist/core/diagnostics/remediation.js +12 -2
  335. package/dist/core/diagnostics/remediation.js.map +1 -1
  336. package/dist/core/history/projection.d.ts +39 -0
  337. package/dist/core/history/projection.js +164 -0
  338. package/dist/core/history/projection.js.map +1 -0
  339. package/dist/core/history/read.d.ts +3 -0
  340. package/dist/core/history/read.js +55 -0
  341. package/dist/core/history/read.js.map +1 -0
  342. package/dist/core/output/output-control.d.ts +18 -0
  343. package/dist/core/output/output-control.js +26 -0
  344. package/dist/core/output/output-control.js.map +1 -0
  345. package/dist/core/output/output.js +20 -8
  346. package/dist/core/output/output.js.map +1 -1
  347. package/dist/core/sentry/helpers.js +10 -2
  348. package/dist/core/sentry/helpers.js.map +1 -1
  349. package/dist/core/shared/command-types.d.ts +2 -0
  350. package/dist/core/shared/command-types.js +2 -2
  351. package/dist/core/shared/command-types.js.map +1 -1
  352. package/dist/core/shared/errors.d.ts +11 -0
  353. package/dist/core/shared/errors.js +2 -2
  354. package/dist/core/shared/errors.js.map +1 -1
  355. package/dist/mcp/server.d.ts +2 -2
  356. package/dist/mcp/tool-definitions.js +5 -5
  357. package/dist/mcp/tool-definitions.js.map +1 -1
  358. package/dist/sdk/author-attribution.d.ts +35 -0
  359. package/dist/sdk/author-attribution.js +118 -0
  360. package/dist/sdk/author-attribution.js.map +1 -0
  361. package/dist/sdk/cli-contracts/command-aliases.d.ts +7 -0
  362. package/dist/sdk/cli-contracts/command-aliases.js +17 -0
  363. package/dist/sdk/cli-contracts/command-aliases.js.map +1 -0
  364. package/dist/sdk/cli-contracts/flag-contracts.js +5 -2
  365. package/dist/sdk/cli-contracts/flag-contracts.js.map +1 -1
  366. package/dist/sdk/cli-contracts/tool-option-contracts.js +6 -2
  367. package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -1
  368. package/dist/sdk/cli-contracts/tool-parameter-tables.js +21 -2
  369. package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
  370. package/dist/sdk/cli-contracts/tool-schema.js +3 -3
  371. package/dist/sdk/cli-contracts/tool-schema.js.map +1 -1
  372. package/dist/sdk/cli-contracts.d.ts +1 -0
  373. package/dist/sdk/cli-contracts.js +3 -2
  374. package/dist/sdk/cli-contracts.js.map +1 -1
  375. package/dist/sdk/cli-program.d.ts +8 -0
  376. package/dist/sdk/cli-program.js +39 -0
  377. package/dist/sdk/cli-program.js.map +1 -0
  378. package/dist/sdk/command-line.d.ts +11 -0
  379. package/dist/sdk/command-line.js +40 -0
  380. package/dist/sdk/command-line.js.map +1 -0
  381. package/dist/sdk/config.d.ts +163 -0
  382. package/dist/sdk/config.js +1087 -0
  383. package/dist/sdk/config.js.map +1 -0
  384. package/dist/sdk/context-relevance.d.ts +21 -0
  385. package/dist/sdk/context-relevance.js +70 -2
  386. package/dist/sdk/context-relevance.js.map +1 -1
  387. package/dist/sdk/dependencies.d.ts +15 -2
  388. package/dist/sdk/dependencies.js +97 -8
  389. package/dist/sdk/dependencies.js.map +1 -1
  390. package/dist/{cli/commands → sdk}/extension/bundled-catalog.d.ts +1 -1
  391. package/dist/{cli/commands → sdk}/extension/bundled-catalog.js +12 -12
  392. package/dist/sdk/extension/bundled-catalog.js.map +1 -0
  393. package/dist/sdk/extension/concurrency.d.ts +7 -0
  394. package/dist/sdk/extension/concurrency.js +26 -0
  395. package/dist/sdk/extension/concurrency.js.map +1 -0
  396. package/dist/sdk/extension/describe.d.ts +91 -0
  397. package/dist/sdk/extension/describe.js +144 -0
  398. package/dist/sdk/extension/describe.js.map +1 -0
  399. package/dist/{cli/commands → sdk}/extension/doctor.d.ts +3 -3
  400. package/dist/{cli/commands → sdk}/extension/doctor.js +7 -7
  401. package/dist/sdk/extension/doctor.js.map +1 -0
  402. package/dist/sdk/extension/install-runtime.d.ts +26 -0
  403. package/dist/sdk/extension/install-runtime.js +269 -0
  404. package/dist/sdk/extension/install-runtime.js.map +1 -0
  405. package/dist/sdk/extension/install-snapshot.d.ts +23 -0
  406. package/dist/sdk/extension/install-snapshot.js +66 -0
  407. package/dist/sdk/extension/install-snapshot.js.map +1 -0
  408. package/dist/{cli/commands → sdk}/extension/install-sources.d.ts +3 -3
  409. package/dist/{cli/commands → sdk}/extension/install-sources.js +15 -12
  410. package/dist/sdk/extension/install-sources.js.map +1 -0
  411. package/dist/{cli/commands → sdk}/extension/managed-state.js +6 -6
  412. package/dist/sdk/extension/managed-state.js.map +1 -0
  413. package/dist/sdk/extension/scaffold.d.ts +36 -0
  414. package/dist/sdk/extension/scaffold.js +2436 -0
  415. package/dist/sdk/extension/scaffold.js.map +1 -0
  416. package/dist/sdk/extension/shared.d.ts +28 -0
  417. package/dist/sdk/extension/shared.js +140 -0
  418. package/dist/sdk/extension/shared.js.map +1 -0
  419. package/dist/sdk/extension/update-check.d.ts +15 -0
  420. package/dist/sdk/extension/update-check.js +68 -0
  421. package/dist/sdk/extension/update-check.js.map +1 -0
  422. package/dist/sdk/extension.d.ts +367 -0
  423. package/dist/sdk/extension.js +2174 -0
  424. package/dist/sdk/extension.js.map +1 -0
  425. package/dist/sdk/governance/gc.d.ts +56 -0
  426. package/dist/sdk/governance/gc.js +276 -0
  427. package/dist/sdk/governance/gc.js.map +1 -0
  428. package/dist/sdk/governance/health.d.ts +187 -0
  429. package/dist/sdk/governance/health.js +1796 -0
  430. package/dist/sdk/governance/health.js.map +1 -0
  431. package/dist/sdk/governance/validate.d.ts +255 -0
  432. package/dist/sdk/governance/validate.js +2175 -0
  433. package/dist/sdk/governance/validate.js.map +1 -0
  434. package/dist/sdk/history-compact.d.ts +142 -0
  435. package/dist/sdk/history-compact.js +508 -0
  436. package/dist/sdk/history-compact.js.map +1 -0
  437. package/dist/sdk/history-mcp.d.ts +17 -0
  438. package/dist/sdk/history-mcp.js +68 -0
  439. package/dist/sdk/history-mcp.js.map +1 -0
  440. package/dist/sdk/history-read.d.ts +31 -0
  441. package/dist/sdk/history-read.js +58 -0
  442. package/dist/sdk/history-read.js.map +1 -0
  443. package/dist/sdk/history-redact.d.ts +120 -0
  444. package/dist/sdk/history-redact.js +577 -0
  445. package/dist/sdk/history-redact.js.map +1 -0
  446. package/dist/sdk/history-repair.d.ts +89 -0
  447. package/dist/sdk/history-repair.js +263 -0
  448. package/dist/sdk/history-repair.js.map +1 -0
  449. package/dist/sdk/index.d.ts +25 -1
  450. package/dist/sdk/index.js +27 -3
  451. package/dist/sdk/index.js.map +1 -1
  452. package/dist/sdk/init-agent-guidance.d.ts +113 -0
  453. package/dist/sdk/init-agent-guidance.js +437 -0
  454. package/dist/sdk/init-agent-guidance.js.map +1 -0
  455. package/dist/sdk/init.d.ts +186 -0
  456. package/dist/sdk/init.js +733 -0
  457. package/dist/sdk/init.js.map +1 -0
  458. package/dist/sdk/invocation-author.d.ts +2 -0
  459. package/dist/sdk/invocation-author.js +39 -0
  460. package/dist/sdk/invocation-author.js.map +1 -0
  461. package/dist/sdk/item-children.d.ts +45 -0
  462. package/dist/sdk/item-children.js +75 -0
  463. package/dist/sdk/item-children.js.map +1 -0
  464. package/dist/sdk/item-schedule.d.ts +26 -0
  465. package/dist/sdk/item-schedule.js +28 -0
  466. package/dist/sdk/item-schedule.js.map +1 -0
  467. package/dist/sdk/output.d.ts +7 -0
  468. package/dist/sdk/output.js +11 -0
  469. package/dist/sdk/output.js.map +1 -0
  470. package/dist/sdk/pagination.d.ts +4 -1
  471. package/dist/sdk/pagination.js +13 -5
  472. package/dist/sdk/pagination.js.map +1 -1
  473. package/dist/sdk/profile.d.ts +176 -0
  474. package/dist/sdk/profile.js +431 -0
  475. package/dist/sdk/profile.js.map +1 -0
  476. package/dist/sdk/relationship-analytics.d.ts +108 -0
  477. package/dist/sdk/relationship-analytics.js +292 -0
  478. package/dist/sdk/relationship-analytics.js.map +1 -0
  479. package/dist/sdk/relationship-context.d.ts +67 -0
  480. package/dist/sdk/relationship-context.js +207 -0
  481. package/dist/sdk/relationship-context.js.map +1 -0
  482. package/dist/sdk/relationship-history.d.ts +109 -0
  483. package/dist/sdk/relationship-history.js +401 -0
  484. package/dist/sdk/relationship-history.js.map +1 -0
  485. package/dist/sdk/relationships.d.ts +145 -0
  486. package/dist/sdk/relationships.js +551 -0
  487. package/dist/sdk/relationships.js.map +1 -0
  488. package/dist/sdk/runtime-input.d.ts +10 -0
  489. package/dist/sdk/runtime-input.js +60 -0
  490. package/dist/sdk/runtime-input.js.map +1 -0
  491. package/dist/sdk/runtime.d.ts +31 -8
  492. package/dist/sdk/runtime.js +61 -57
  493. package/dist/sdk/runtime.js.map +1 -1
  494. package/dist/sdk/schema.d.ts +507 -0
  495. package/dist/sdk/schema.js +1269 -0
  496. package/dist/sdk/schema.js.map +1 -0
  497. package/dist/{cli/commands → sdk}/templates.d.ts +1 -1
  498. package/dist/{cli/commands → sdk}/templates.js +9 -9
  499. package/dist/sdk/templates.js.map +1 -0
  500. package/dist/{cli/commands → sdk}/test/linked-command-detection.d.ts +10 -2
  501. package/dist/sdk/test/linked-command-detection.js +525 -0
  502. package/dist/sdk/test/linked-command-detection.js.map +1 -0
  503. package/docs/COMMANDS.md +58 -40
  504. package/docs/EXTENSIONS.md +10 -1
  505. package/docs/RELATIONSHIP_GRAPH.md +113 -0
  506. package/docs/RELEASING.md +2 -0
  507. package/docs/SDK.md +156 -9
  508. package/docs/SDK_CUSTOMIZATION_PRIMITIVES.md +79 -0
  509. package/marketplace.json +2 -2
  510. package/package.json +3 -2
  511. package/packages/pm-beads/package.json +1 -1
  512. package/packages/pm-calendar/package.json +1 -1
  513. package/packages/pm-command-kit/package.json +1 -1
  514. package/packages/pm-governance-audit/extensions/governance-audit/runtime-utils.ts +76 -16
  515. package/packages/pm-governance-audit/extensions/governance-audit/sdk.ts +8 -0
  516. package/packages/pm-governance-audit/package.json +1 -1
  517. package/packages/pm-guide-shell/package.json +1 -1
  518. package/packages/pm-kanban/package.json +1 -1
  519. package/packages/pm-lifecycle-hooks/package.json +1 -1
  520. package/packages/pm-linked-test-adapters/package.json +1 -1
  521. package/packages/pm-search-advanced/package.json +1 -1
  522. package/packages/pm-templates/package.json +1 -1
  523. package/packages/pm-todos/package.json +1 -1
  524. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  525. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  526. package/scripts/bundle-cli.mjs +66 -23
  527. package/dist/cli/commands/extension/bundled-catalog.js.map +0 -1
  528. package/dist/cli/commands/extension/doctor.js.map +0 -1
  529. package/dist/cli/commands/extension/install-sources.js.map +0 -1
  530. package/dist/cli/commands/extension/managed-state.js.map +0 -1
  531. package/dist/cli/commands/templates.js.map +0 -1
  532. package/dist/cli/commands/test/linked-command-detection.js +0 -248
  533. package/dist/cli/commands/test/linked-command-detection.js.map +0 -1
  534. package/dist/cli-bundle/chunks/append-DYQWQK2J.js +0 -11
  535. package/dist/cli-bundle/chunks/chunk-2GA3NK35.js +0 -530
  536. package/dist/cli-bundle/chunks/chunk-2GA3NK35.js.map +0 -1
  537. package/dist/cli-bundle/chunks/chunk-2QIQGYPW.js.map +0 -7
  538. package/dist/cli-bundle/chunks/chunk-4DY4KPQI.js.map +0 -7
  539. package/dist/cli-bundle/chunks/chunk-4WREH7RT.js +0 -554
  540. package/dist/cli-bundle/chunks/chunk-4WREH7RT.js.map +0 -7
  541. package/dist/cli-bundle/chunks/chunk-5CT5BW6E.js.map +0 -7
  542. package/dist/cli-bundle/chunks/chunk-5URI7TPJ.js.map +0 -7
  543. package/dist/cli-bundle/chunks/chunk-6MHSBDGD.js.map +0 -7
  544. package/dist/cli-bundle/chunks/chunk-6OTZMORS.js.map +0 -7
  545. package/dist/cli-bundle/chunks/chunk-6PKA3SJQ.js.map +0 -1
  546. package/dist/cli-bundle/chunks/chunk-6TTOHMTB.js.map +0 -1
  547. package/dist/cli-bundle/chunks/chunk-7QDSYUMF.js.map +0 -1
  548. package/dist/cli-bundle/chunks/chunk-7TQMR6LK.js.map +0 -7
  549. package/dist/cli-bundle/chunks/chunk-B5DZYTT3.js +0 -312
  550. package/dist/cli-bundle/chunks/chunk-B5DZYTT3.js.map +0 -7
  551. package/dist/cli-bundle/chunks/chunk-BPD26E3P.js.map +0 -1
  552. package/dist/cli-bundle/chunks/chunk-CDJYP7OQ.js.map +0 -1
  553. package/dist/cli-bundle/chunks/chunk-DBZVUJTK.js +0 -858
  554. package/dist/cli-bundle/chunks/chunk-DBZVUJTK.js.map +0 -1
  555. package/dist/cli-bundle/chunks/chunk-DVOLZJ3C.js.map +0 -1
  556. package/dist/cli-bundle/chunks/chunk-DYEX6NFH.js.map +0 -7
  557. package/dist/cli-bundle/chunks/chunk-F7PSHRNO.js.map +0 -1
  558. package/dist/cli-bundle/chunks/chunk-FO7GMJKG.js +0 -875
  559. package/dist/cli-bundle/chunks/chunk-FO7GMJKG.js.map +0 -7
  560. package/dist/cli-bundle/chunks/chunk-FTQLW4JD.js.map +0 -1
  561. package/dist/cli-bundle/chunks/chunk-IA3YFTXT.js.map +0 -1
  562. package/dist/cli-bundle/chunks/chunk-IGED7NH2.js.map +0 -7
  563. package/dist/cli-bundle/chunks/chunk-J4NZOP3I.js.map +0 -1
  564. package/dist/cli-bundle/chunks/chunk-JL7WZ4O2.js.map +0 -7
  565. package/dist/cli-bundle/chunks/chunk-L24HCJFC.js +0 -309
  566. package/dist/cli-bundle/chunks/chunk-L24HCJFC.js.map +0 -1
  567. package/dist/cli-bundle/chunks/chunk-LWTIRS3Y.js.map +0 -7
  568. package/dist/cli-bundle/chunks/chunk-MKL4CP2I.js.map +0 -1
  569. package/dist/cli-bundle/chunks/chunk-N3CMP4NI.js.map +0 -1
  570. package/dist/cli-bundle/chunks/chunk-PHKP3AGR.js.map +0 -7
  571. package/dist/cli-bundle/chunks/chunk-Q37E63AM.js.map +0 -7
  572. package/dist/cli-bundle/chunks/chunk-QASRVKUQ.js.map +0 -1
  573. package/dist/cli-bundle/chunks/chunk-RGXD5JJR.js.map +0 -7
  574. package/dist/cli-bundle/chunks/chunk-UB2QYSTO.js.map +0 -1
  575. package/dist/cli-bundle/chunks/chunk-UGTVWL3E.js.map +0 -1
  576. package/dist/cli-bundle/chunks/chunk-ZAYYDNB3.js.map +0 -1
  577. package/dist/cli-bundle/chunks/chunk-ZUKSZVBW.js.map +0 -7
  578. package/dist/cli-bundle/chunks/close-RI4JQQHU.js +0 -12
  579. package/dist/cli-bundle/chunks/close-many-LY2XJ52M.js +0 -21
  580. package/dist/cli-bundle/chunks/comments-35M273DN.js +0 -13
  581. package/dist/cli-bundle/chunks/copy-NPYM7M7U.js +0 -9
  582. package/dist/cli-bundle/chunks/delete-ODRWJWAM.js +0 -10
  583. package/dist/cli-bundle/chunks/docs-G7N4E2JO.js +0 -14
  584. package/dist/cli-bundle/chunks/focus-U5TRVCRS.js +0 -10
  585. package/dist/cli-bundle/chunks/history-compact-M7GHYVFN.js +0 -20
  586. package/dist/cli-bundle/chunks/history-redact-JIHZLHDP.js +0 -16
  587. package/dist/cli-bundle/chunks/history-repair-NAFCHLH7.js +0 -18
  588. package/dist/cli-bundle/chunks/learnings-SONGPSHI.js +0 -13
  589. package/dist/cli-bundle/chunks/notes-BSD53H2W.js +0 -13
  590. package/dist/cli-bundle/chunks/plan-AWLYGBNV.js +0 -24
  591. package/dist/cli-bundle/chunks/register-list-query-BUWCYHBT.js.map +0 -7
  592. package/dist/cli-bundle/chunks/register-list-query-KTZ6AGE7.js.map +0 -1
  593. package/dist/cli-bundle/chunks/register-mutation-4FMGJJF7.js.map +0 -1
  594. package/dist/cli-bundle/chunks/restore-66GLMHIX.js +0 -14
  595. package/dist/cli-bundle/chunks/update-2XGHIVQ2.js +0 -21
  596. package/dist/cli-bundle/chunks/update-many-75K57FS3.js +0 -34
  597. package/dist/cli-bundle/chunks/update-many-U42YA445.js +0 -30
  598. /package/dist/cli-bundle/chunks/{append-PVZJDM6J.js.map → append-OJQFUQ4T.js.map} +0 -0
  599. /package/dist/cli-bundle/chunks/{append-DYQWQK2J.js.map → append-UZVHUO74.js.map} +0 -0
  600. /package/dist/cli-bundle/chunks/{chunk-MQZ3PLCF.js.map → chunk-2IFFUZLC.js.map} +0 -0
  601. /package/dist/cli-bundle/chunks/{chunk-P6MYFH6K.js.map → chunk-2JKGO6QX.js.map} +0 -0
  602. /package/dist/cli-bundle/chunks/{chunk-X3GYR4P2.js.map → chunk-2NCIPMQP.js.map} +0 -0
  603. /package/dist/cli-bundle/chunks/{chunk-Q7E6OYZK.js.map → chunk-2VPAVL7O.js.map} +0 -0
  604. /package/dist/cli-bundle/chunks/{chunk-DRNJPEPQ.js.map → chunk-2WSE6PO2.js.map} +0 -0
  605. /package/dist/cli-bundle/chunks/{chunk-FDSBDNYE.js.map → chunk-34L5OT3Y.js.map} +0 -0
  606. /package/dist/cli-bundle/chunks/{chunk-TH7U4KLY.js.map → chunk-3AUGG2DP.js.map} +0 -0
  607. /package/dist/cli-bundle/chunks/{chunk-NKW36AMT.js.map → chunk-3CLU2XZO.js.map} +0 -0
  608. /package/dist/cli-bundle/chunks/{chunk-ABRCOSDC.js.map → chunk-3WM75PWC.js.map} +0 -0
  609. /package/dist/cli-bundle/chunks/{chunk-X6BVXQ52.js.map → chunk-5JLUII3O.js.map} +0 -0
  610. /package/dist/cli-bundle/chunks/{chunk-3TL7WOEF.js.map → chunk-6N2VXVTQ.js.map} +0 -0
  611. /package/dist/cli-bundle/chunks/{chunk-ERL2YFJ2.js.map → chunk-6S3YSUYG.js.map} +0 -0
  612. /package/dist/cli-bundle/chunks/{chunk-IFZA4VB5.js.map → chunk-AHVTB5I5.js.map} +0 -0
  613. /package/dist/cli-bundle/chunks/{chunk-DO5RGJXT.js.map → chunk-APRVSW2O.js.map} +0 -0
  614. /package/dist/cli-bundle/chunks/{chunk-NAQYVWSQ.js.map → chunk-B7PE22W6.js.map} +0 -0
  615. /package/dist/cli-bundle/chunks/{chunk-MD6ULIPJ.js.map → chunk-BCOFWYW4.js.map} +0 -0
  616. /package/dist/cli-bundle/chunks/{chunk-KADLSPIU.js.map → chunk-BEP7WJA2.js.map} +0 -0
  617. /package/dist/cli-bundle/chunks/{chunk-OBDLEQG5.js.map → chunk-CRVF2JDM.js.map} +0 -0
  618. /package/dist/cli-bundle/chunks/{chunk-FJZDA6MS.js.map → chunk-DM4H7FP4.js.map} +0 -0
  619. /package/dist/cli-bundle/chunks/{close-LZECOMHO.js.map → chunk-DUT67M43.js.map} +0 -0
  620. /package/dist/cli-bundle/chunks/{chunk-44LNIULG.js.map → chunk-DYH63FX7.js.map} +0 -0
  621. /package/dist/cli-bundle/chunks/{chunk-HAMLIWAF.js.map → chunk-EAB64KLB.js.map} +0 -0
  622. /package/dist/cli-bundle/chunks/{chunk-CIOZ376P.js.map → chunk-EACOH7AU.js.map} +0 -0
  623. /package/dist/cli-bundle/chunks/{chunk-QK2ZN6UL.js.map → chunk-EJEXHTY5.js.map} +0 -0
  624. /package/dist/cli-bundle/chunks/{chunk-WQUEHPZB.js.map → chunk-EYLCSJAI.js.map} +0 -0
  625. /package/dist/cli-bundle/chunks/{chunk-655STMGA.js.map → chunk-FMBNM2EN.js.map} +0 -0
  626. /package/dist/cli-bundle/chunks/{chunk-RMF3IOYQ.js.map → chunk-FNSPG7MU.js.map} +0 -0
  627. /package/dist/cli-bundle/chunks/{chunk-KB726FMH.js.map → chunk-H2Z3FYXQ.js.map} +0 -0
  628. /package/dist/cli-bundle/chunks/{chunk-BN62TO2S.js.map → chunk-IA5FKNII.js.map} +0 -0
  629. /package/dist/cli-bundle/chunks/{chunk-W6HZ55JO.js.map → chunk-IJIICKVW.js.map} +0 -0
  630. /package/dist/cli-bundle/chunks/{chunk-M7EWN4TF.js.map → chunk-JOUQZENX.js.map} +0 -0
  631. /package/dist/cli-bundle/chunks/{chunk-2FNWQXZ2.js.map → chunk-JYFOV7FC.js.map} +0 -0
  632. /package/dist/cli-bundle/chunks/{chunk-HLHSQ5CA.js.map → chunk-K2X6U4UA.js.map} +0 -0
  633. /package/dist/cli-bundle/chunks/{chunk-M6ASXYCU.js.map → chunk-KG44YSKD.js.map} +0 -0
  634. /package/dist/cli-bundle/chunks/{chunk-YVKE5ZDM.js.map → chunk-KPMKHGEA.js.map} +0 -0
  635. /package/dist/cli-bundle/chunks/{close-many-ZHI6A5TN.js.map → chunk-MIQDDLB5.js.map} +0 -0
  636. /package/dist/cli-bundle/chunks/{chunk-UJ4HJYWL.js.map → chunk-NLDFBC6J.js.map} +0 -0
  637. /package/dist/cli-bundle/chunks/{chunk-WRKB56FC.js.map → chunk-NP22ERDF.js.map} +0 -0
  638. /package/dist/cli-bundle/chunks/{chunk-YQYG2V23.js.map → chunk-NU3IMIEA.js.map} +0 -0
  639. /package/dist/cli-bundle/chunks/{chunk-3I3LRT2G.js.map → chunk-NVPZIJVR.js.map} +0 -0
  640. /package/dist/cli-bundle/chunks/{chunk-JAF4TUQ7.js.map → chunk-ODALILG3.js.map} +0 -0
  641. /package/dist/cli-bundle/chunks/{chunk-QZ7LT3XE.js.map → chunk-ONREO4ST.js.map} +0 -0
  642. /package/dist/cli-bundle/chunks/{chunk-3CMRNVTO.js.map → chunk-P74IZQ7A.js.map} +0 -0
  643. /package/dist/cli-bundle/chunks/{chunk-ZTRBSABY.js.map → chunk-PGY23YTC.js.map} +0 -0
  644. /package/dist/cli-bundle/chunks/{chunk-H2QBAKLQ.js.map → chunk-PMOSXADO.js.map} +0 -0
  645. /package/dist/cli-bundle/chunks/{close-RI4JQQHU.js.map → chunk-PNTULOGU.js.map} +0 -0
  646. /package/dist/cli-bundle/chunks/{chunk-GSEADLRH.js.map → chunk-Q7A43DS4.js.map} +0 -0
  647. /package/dist/cli-bundle/chunks/{chunk-QSPARJWF.js.map → chunk-QEHQ2GVG.js.map} +0 -0
  648. /package/dist/cli-bundle/chunks/{chunk-VJTAEIPC.js.map → chunk-QIPLHNP7.js.map} +0 -0
  649. /package/dist/cli-bundle/chunks/{chunk-K7WNZ7KD.js.map → chunk-QKJGPFAF.js.map} +0 -0
  650. /package/dist/cli-bundle/chunks/{chunk-ZNP64HOW.js.map → chunk-RLCHOOHC.js.map} +0 -0
  651. /package/dist/cli-bundle/chunks/{chunk-IAPHYPRL.js.map → chunk-RMLWNPH2.js.map} +0 -0
  652. /package/dist/cli-bundle/chunks/{chunk-UVBA6F5A.js.map → chunk-RRM5JYJC.js.map} +0 -0
  653. /package/dist/cli-bundle/chunks/{chunk-6IIVBC56.js.map → chunk-S6MQESFR.js.map} +0 -0
  654. /package/dist/cli-bundle/chunks/{chunk-QABYZYLU.js.map → chunk-SDQLJWBO.js.map} +0 -0
  655. /package/dist/cli-bundle/chunks/{chunk-ANSJHDOZ.js.map → chunk-SELVXEZK.js.map} +0 -0
  656. /package/dist/cli-bundle/chunks/{chunk-WD6MSYMP.js.map → chunk-TKOVBP6C.js.map} +0 -0
  657. /package/dist/cli-bundle/chunks/{chunk-TZ2PSLLT.js.map → chunk-TQSZFPIS.js.map} +0 -0
  658. /package/dist/cli-bundle/chunks/{chunk-WPAWZW7S.js.map → chunk-TSMHDIW4.js.map} +0 -0
  659. /package/dist/cli-bundle/chunks/{chunk-TZRTLMWM.js.map → chunk-UFXU44HV.js.map} +0 -0
  660. /package/dist/cli-bundle/chunks/{chunk-TWLDBKQU.js.map → chunk-ULTHRDBP.js.map} +0 -0
  661. /package/dist/cli-bundle/chunks/{chunk-RA5AIAMP.js.map → chunk-UOHFKBUV.js.map} +0 -0
  662. /package/dist/cli-bundle/chunks/{chunk-4RXTMU57.js.map → chunk-UY2ACEMF.js.map} +0 -0
  663. /package/dist/cli-bundle/chunks/{chunk-FIGXOCEQ.js.map → chunk-WUJQK4YV.js.map} +0 -0
  664. /package/dist/cli-bundle/chunks/{chunk-T4BRCB6Z.js.map → chunk-XSJUSQAE.js.map} +0 -0
  665. /package/dist/cli-bundle/chunks/{chunk-UKUIIBDW.js.map → chunk-YAQEBNY7.js.map} +0 -0
  666. /package/dist/cli-bundle/chunks/{chunk-E2WC6S4P.js.map → chunk-YBLZ2VE7.js.map} +0 -0
  667. /package/dist/cli-bundle/chunks/{chunk-Y72FV7RM.js.map → chunk-YCQET3OT.js.map} +0 -0
  668. /package/dist/cli-bundle/chunks/{close-many-LY2XJ52M.js.map → chunk-YUSOJDWM.js.map} +0 -0
  669. /package/dist/cli-bundle/chunks/{chunk-FS6UM5WH.js.map → chunk-ZI6VQWQ7.js.map} +0 -0
  670. /package/dist/cli-bundle/chunks/{comments-AJWRTFZ5.js.map → close-CWODTPKG.js.map} +0 -0
  671. /package/dist/cli-bundle/chunks/{comments-35M273DN.js.map → close-W6LI2PKM.js.map} +0 -0
  672. /package/dist/cli-bundle/chunks/{copy-GMXYKBXT.js.map → close-many-CQFUY7MR.js.map} +0 -0
  673. /package/dist/cli-bundle/chunks/{copy-NPYM7M7U.js.map → close-many-DLDDVSH5.js.map} +0 -0
  674. /package/dist/cli-bundle/chunks/{create-F53OBTOU.js.map → comments-E3TNTK24.js.map} +0 -0
  675. /package/dist/cli-bundle/chunks/{create-HU4Q7RJX.js.map → comments-WGLHR7LB.js.map} +0 -0
  676. /package/dist/cli-bundle/chunks/{delete-GSDZLTRC.js.map → copy-LXVDXH7B.js.map} +0 -0
  677. /package/dist/cli-bundle/chunks/{delete-ODRWJWAM.js.map → copy-Q5ZJPUKR.js.map} +0 -0
  678. /package/dist/cli-bundle/chunks/{deps-U57I7EAK.js.map → create-J5U6ND4K.js.map} +0 -0
  679. /package/dist/cli-bundle/chunks/{deps-WWB7P2GT.js.map → create-LBVCYMEG.js.map} +0 -0
  680. /package/dist/cli-bundle/chunks/{docs-MQIY2ZQS.js.map → delete-PMJBNY5G.js.map} +0 -0
  681. /package/dist/cli-bundle/chunks/{docs-G7N4E2JO.js.map → delete-WNHB3LYW.js.map} +0 -0
  682. /package/dist/cli-bundle/chunks/{files-TTY6N2AV.js.map → deps-JZ7TMVCB.js.map} +0 -0
  683. /package/dist/cli-bundle/chunks/{files-TBZD7V6H.js.map → deps-OA26IS25.js.map} +0 -0
  684. /package/dist/cli-bundle/chunks/{focus-XT6YVFFX.js.map → docs-FEWB2DQB.js.map} +0 -0
  685. /package/dist/cli-bundle/chunks/{focus-U5TRVCRS.js.map → docs-HA2AIDBB.js.map} +0 -0
  686. /package/dist/cli-bundle/chunks/{history-compact-M7GHYVFN.js.map → files-6YFBJRBG.js.map} +0 -0
  687. /package/dist/cli-bundle/chunks/{history-compact-KKVUWB4V.js.map → files-EFIWKFTM.js.map} +0 -0
  688. /package/dist/cli-bundle/chunks/{history-redact-3DVZOILD.js.map → focus-4QJR7FOQ.js.map} +0 -0
  689. /package/dist/cli-bundle/chunks/{history-redact-JIHZLHDP.js.map → focus-POIW5LTJ.js.map} +0 -0
  690. /package/dist/cli-bundle/chunks/{history-repair-ITDUMK4N.js.map → history-compact-CKRPDTJN.js.map} +0 -0
  691. /package/dist/cli-bundle/chunks/{history-repair-NAFCHLH7.js.map → history-compact-FWG2C7FZ.js.map} +0 -0
  692. /package/dist/cli-bundle/chunks/{learnings-SONGPSHI.js.map → history-redact-BB3TGDAE.js.map} +0 -0
  693. /package/dist/cli-bundle/chunks/{learnings-FGO3NSFW.js.map → history-redact-D225BHOZ.js.map} +0 -0
  694. /package/dist/cli-bundle/chunks/{notes-BSD53H2W.js.map → history-repair-6GEAM7HE.js.map} +0 -0
  695. /package/dist/cli-bundle/chunks/{notes-NQ6RXVW6.js.map → history-repair-RQXKQHL4.js.map} +0 -0
  696. /package/dist/cli-bundle/chunks/{plan-2NNEO46V.js.map → learnings-JLNLCOL5.js.map} +0 -0
  697. /package/dist/cli-bundle/chunks/{plan-AWLYGBNV.js.map → learnings-RSNLSWDC.js.map} +0 -0
  698. /package/dist/cli-bundle/chunks/{profile-U725ATWZ.js.map → notes-2WDH6DXU.js.map} +0 -0
  699. /package/dist/cli-bundle/chunks/{profile-AAQUU6T3.js.map → notes-GB47XXQQ.js.map} +0 -0
  700. /package/dist/cli-bundle/chunks/{restore-66GLMHIX.js.map → plan-DOVI2VMW.js.map} +0 -0
  701. /package/dist/cli-bundle/chunks/{restore-B3BAB6X2.js.map → plan-VDCJ2PCN.js.map} +0 -0
  702. /package/dist/cli-bundle/chunks/{schema-U7IM2DXV.js.map → profile-FAU7NZML.js.map} +0 -0
  703. /package/dist/cli-bundle/chunks/{schema-LZNUYHDB.js.map → profile-IVXQEL3D.js.map} +0 -0
  704. /package/dist/cli-bundle/chunks/{update-Q3UCILNR.js.map → restore-25DLT2Q2.js.map} +0 -0
  705. /package/dist/cli-bundle/chunks/{update-2XGHIVQ2.js.map → restore-YPMVUUEX.js.map} +0 -0
  706. /package/dist/cli-bundle/chunks/{update-many-75K57FS3.js.map → schema-FNU3WE4O.js.map} +0 -0
  707. /package/dist/cli-bundle/chunks/{update-many-U42YA445.js.map → schema-NBCM3RAD.js.map} +0 -0
  708. /package/dist/{cli/commands → sdk}/extension/managed-state.d.ts +0 -0
@@ -1,2189 +1,10 @@
1
1
  /**
2
2
  * @module cli/commands/extension
3
3
  *
4
- * Implements the pm extension command surface and its agent-facing runtime behavior.
4
+ * Compatibility exports for the SDK-owned extension and package engine.
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]="17d000c7-b19f-540c-9600-65416d2ca11b")}catch(e){}}();
8
- import { execFile } from "node:child_process";
9
- import fs from "node:fs/promises";
10
- import os from "node:os";
11
- import path from "node:path";
12
- import { fileURLToPath } from "node:url";
13
- import { promisify } from "node:util";
14
- import { activateExtensions, createSerialQueue, loadExtensions, nextExtensionReloadToken, } from "../../core/extensions/index.js";
15
- import { resolveExtensionRoots } from "../../core/extensions/loader.js";
16
- import { pathExists } from "../../core/fs/fs-utils.js";
17
- import { isPathWithinDirectory } from "../../core/fs/path-utils.js";
18
- import { EXIT_CODE } from "../../core/shared/constants.js";
19
- import { PmCliError } from "../../core/shared/errors.js";
20
- import { levenshteinDistanceWithinLimit } from "../../core/shared/levenshtein.js";
21
- import { nowIso } from "../../core/shared/time.js";
22
- import { resolveGlobalPmRoot, resolvePmRoot } from "../../core/store/paths.js";
23
- import { readSettings, writeSettings } from "../../core/store/settings.js";
24
- import { ensureTypeFolderScaffold } from "./schema.js";
25
- // Cohesive helper groups now live in ./extension/* sibling modules. They are
26
- // imported for the command wiring that stays here and re-exported below so
27
- // existing import sites (sdk barrels, upgrade.ts, tests) keep importing the
28
- // public surface (runExtension, managed-state read/write, install-source
29
- // parsing, …) from "./extension.js" unchanged.
30
- import { normalizeStringList, normalizeExtensionNameForMatch, normalizeManagedDirectoryName, parseExtensionManifest, validateExtensionDirectory, } from "./extension/shared.js";
31
- import { sortManagedEntries, managedExtensionSourcesEquivalent, readManagedExtensionState, writeManagedExtensionState, upsertManagedEntry, resolveManagedExtensionStatePath, } from "./extension/managed-state.js";
32
- import { parseExtensionInstallSource, resolveInstallSource, areDirectoriesEquivalent, runGitCommand, } from "./extension/install-sources.js";
33
- import { resolveBundledExtensionAliasSource, resolveBundledPackageNpmName, isBundledPackageInstallAllTarget, listBundledPackageAliases, resolveBundledAliasManifestName, buildBundledPackageCatalog, } from "./extension/bundled-catalog.js";
34
- import { scaffoldExtensionProject } from "./extension/scaffold.js";
35
- import { buildExtensionDescribeResult } from "./extension/describe.js";
36
- import { applyDoctorRuntimeActivationState, classifyDoctorLoadFailureWarnings, classifyDoctorActivationFailureWarnings, classifyUnusedCapabilityWarnings, buildExtensionTriageSummary, parseDoctorDetailMode, collectUnknownCapabilityGuidance, buildCapabilityContractMetadata, buildDoctorConsistencySummary, } from "./extension/doctor.js";
37
- // Re-export the public surface that lives in sibling modules but was previously
38
- // exported from this file (used by sdk barrels, upgrade.ts, and tests).
39
- export { parseExtensionManifest, validateExtensionDirectory, readManagedExtensionState, writeManagedExtensionState, resolveManagedExtensionStatePath, parseExtensionInstallSource, };
40
- const execFileAsync = promisify(execFile);
41
- const EXTENSION_INSTALL_COPY_ATTEMPTS = 3;
42
- const EXTENSION_INSTALL_LOCK_ATTEMPTS = 120;
43
- const EXTENSION_INSTALL_LOCK_DELAY_MS = 250;
44
- const EXTENSION_INSTALL_LOCK_STALE_MS = 120_000;
45
- const LIFECYCLE_ACTION_TARGETS = [
46
- ["install", "install", "--install"],
47
- ["uninstall", "uninstall", "--uninstall"],
48
- ["explore", "explore", "--explore"],
49
- ["list", "explore", "--explore"],
50
- ["manage", "manage", "--manage"],
51
- ["describe", "describe", "--describe"],
52
- ["reload", "reload", "--reload"],
53
- ["doctor", "doctor", "--doctor"],
54
- ["catalog", "catalog", "--catalog"],
55
- ["init", "init", "--init"],
56
- ["scaffold", "init", "--scaffold"],
57
- ["adopt", "adopt", "--adopt"],
58
- ["adopt-all", "adopt-all", "--adopt-all"],
59
- ["activate", "activate", "--activate"],
60
- ["deactivate", "deactivate", "--deactivate"],
61
- ];
62
- const LIFECYCLE_ACTION_FLAG_HINT = LIFECYCLE_ACTION_TARGETS.map(([, , flag]) => flag)
63
- .filter((flag, index, flags) => flags.indexOf(flag) === index)
64
- .join(", ");
65
- const LIFECYCLE_ACTION_FLAGS = {
66
- install: "--install",
67
- uninstall: "--uninstall",
68
- explore: "--explore",
69
- manage: "--manage",
70
- describe: "--describe",
71
- reload: "--reload",
72
- doctor: "--doctor",
73
- catalog: "--catalog",
74
- adopt: "--adopt",
75
- "adopt-all": "--adopt-all",
76
- activate: "--activate",
77
- deactivate: "--deactivate",
78
- init: "--init",
79
- };
80
- const NATIVE_OUTPUT_MARKER = "__pm_native_output";
81
- const EXTENSION_POLICY_ROOT_LIST_FIELDS = [
82
- "trusted_extensions",
83
- "allowed_extensions",
84
- "blocked_extensions",
85
- "allowed_capabilities",
86
- "blocked_capabilities",
87
- "allowed_surfaces",
88
- "blocked_surfaces",
89
- "allowed_commands",
90
- "blocked_commands",
91
- "allowed_actions",
92
- "blocked_actions",
93
- "allowed_services",
94
- "blocked_services",
95
- ];
96
- const EXTENSION_POLICY_OVERRIDE_LIST_FIELDS = [
97
- "allowed_capabilities",
98
- "blocked_capabilities",
99
- "allowed_surfaces",
100
- "blocked_surfaces",
101
- "allowed_commands",
102
- "blocked_commands",
103
- "allowed_actions",
104
- "blocked_actions",
105
- "allowed_services",
106
- "blocked_services",
107
- ];
108
- const DEFAULT_EXTENSION_POLICY_DETAILS = {
109
- mode: "off",
110
- trust_mode: "off",
111
- require_provenance: false,
112
- trusted_extensions: [],
113
- default_sandbox_profile: "none",
114
- allowed_extensions: [],
115
- blocked_extensions: [],
116
- allowed_capabilities: [],
117
- blocked_capabilities: [],
118
- allowed_surfaces: [],
119
- blocked_surfaces: [],
120
- allowed_commands: [],
121
- blocked_commands: [],
122
- allowed_actions: [],
123
- blocked_actions: [],
124
- allowed_services: [],
125
- blocked_services: [],
126
- extension_overrides: [],
127
- };
128
- function normalizePolicyRootLists(policy) {
129
- const safePolicy = policy ?? DEFAULT_EXTENSION_POLICY_DETAILS;
130
- const lists = {};
131
- for (const field of EXTENSION_POLICY_ROOT_LIST_FIELDS) {
132
- lists[field] = normalizeStringList(safePolicy[field] ?? []);
133
- }
134
- return lists;
135
- }
136
- function appendNonEmptyPolicyLists(target, lists) {
137
- for (const field of EXTENSION_POLICY_OVERRIDE_LIST_FIELDS) {
138
- if (lists[field].length > 0) {
139
- target[field] = lists[field];
140
- }
141
- }
142
- return target;
143
- }
144
- function buildExtensionPolicyOverrideDetails(override) {
145
- const name = typeof override.name === "string" ? override.name.trim() : "";
146
- if (name.length === 0) {
147
- return null;
148
- }
149
- const details = { name };
150
- if (override.disabled === true) {
151
- details.disabled = true;
152
- }
153
- if (override.require_trusted === true) {
154
- details.require_trusted = true;
155
- }
156
- if (override.require_provenance === true) {
157
- details.require_provenance = true;
158
- }
159
- if (override.sandbox_profile) {
160
- details.sandbox_profile = override.sandbox_profile;
161
- }
162
- const lists = {};
163
- for (const field of EXTENSION_POLICY_OVERRIDE_LIST_FIELDS) {
164
- lists[field] = normalizeStringList(override[field] ?? []);
165
- }
166
- return appendNonEmptyPolicyLists(details, lists);
167
- }
168
- function buildExtensionPolicyDetails(policy) {
169
- const safePolicy = policy ?? DEFAULT_EXTENSION_POLICY_DETAILS;
170
- const rootLists = normalizePolicyRootLists(policy);
171
- const overrides = (safePolicy.extension_overrides ?? [])
172
- .map((override) => buildExtensionPolicyOverrideDetails(override))
173
- .filter((override) => override !== null)
174
- .sort((left, right) => left.name.localeCompare(right.name));
175
- return {
176
- mode: safePolicy.mode ?? DEFAULT_EXTENSION_POLICY_DETAILS.mode,
177
- trust_mode: safePolicy.trust_mode ?? DEFAULT_EXTENSION_POLICY_DETAILS.trust_mode,
178
- require_provenance: safePolicy.require_provenance === true,
179
- trusted_extensions: rootLists.trusted_extensions,
180
- default_sandbox_profile: safePolicy.default_sandbox_profile ?? "none",
181
- allowed_extensions: rootLists.allowed_extensions,
182
- blocked_extensions: rootLists.blocked_extensions,
183
- allowed_capabilities: rootLists.allowed_capabilities,
184
- blocked_capabilities: rootLists.blocked_capabilities,
185
- allowed_surfaces: rootLists.allowed_surfaces,
186
- blocked_surfaces: rootLists.blocked_surfaces,
187
- allowed_commands: rootLists.allowed_commands,
188
- blocked_commands: rootLists.blocked_commands,
189
- allowed_actions: rootLists.allowed_actions,
190
- blocked_actions: rootLists.blocked_actions,
191
- allowed_services: rootLists.allowed_services,
192
- blocked_services: rootLists.blocked_services,
193
- extension_overrides: overrides,
194
- };
195
- }
196
- function isRetriableExtensionInstallCopyError(error) {
197
- if (typeof error !== "object" || error === null || !("code" in error)) {
198
- return false;
199
- }
200
- const code = error.code;
201
- return code === "EEXIST" || code === "ENOTEMPTY" || code === "ENOENT";
202
- }
203
- function isErrnoCode(error, code) {
204
- return (typeof error === "object" &&
205
- error !== null &&
206
- "code" in error &&
207
- error.code === code);
208
- }
209
- function sleep(ms) {
210
- return new Promise((resolve) => {
211
- setTimeout(resolve, ms);
212
- });
213
- }
214
- /** Ensure the installed extension directory carries a `package.json` with `"type": "module"`. Extension entrypoints are ESM TypeScript; without a nearby package.json Node resolves the module type from the HOST project's package.json, so installs into `"type": "commonjs"` projects fail activation with `extension_load_failed` (pm-r0m4). Extensions that ship their own package.json are left untouched. */
215
- async function ensureExtensionModuleTypeMarker(destinationDirectory) {
216
- const markerPath = path.join(destinationDirectory, "package.json");
217
- if (await pathExists(markerPath)) {
218
- return;
219
- }
220
- await fs.writeFile(markerPath, `${JSON.stringify({ type: "module" }, null, 2)}\n`, "utf8");
221
- }
222
- /** Implements copy extension directory for install for the public runtime surface of this module. */
223
- export async function copyExtensionDirectoryForInstall(sourceDirectory, destinationDirectory, copyDirectory = fs.cp) {
224
- for (let attempt = 1; attempt <= EXTENSION_INSTALL_COPY_ATTEMPTS; attempt += 1) {
225
- try {
226
- if (await pathExists(destinationDirectory)) {
227
- await fs.rm(destinationDirectory, { recursive: true, force: true });
228
- }
229
- await copyExtensionDirectoryWithoutSelfNesting(sourceDirectory, destinationDirectory, copyDirectory);
230
- return;
231
- }
232
- catch (error) {
233
- if (!isRetriableExtensionInstallCopyError(error) ||
234
- attempt === EXTENSION_INSTALL_COPY_ATTEMPTS) {
235
- throw error;
236
- }
237
- await sleep(EXTENSION_INSTALL_LOCK_DELAY_MS);
238
- }
239
- }
240
- }
241
- async function copyExtensionDirectoryWithoutSelfNesting(sourceDirectory, destinationDirectory, copyDirectory) {
242
- const resolvedSource = path.resolve(sourceDirectory);
243
- const resolvedDestination = path.resolve(destinationDirectory);
244
- if (resolvedSource === resolvedDestination) {
245
- return;
246
- }
247
- if (!isPathWithinDirectory(resolvedSource, resolvedDestination)) {
248
- await copyDirectory(sourceDirectory, destinationDirectory, {
249
- recursive: true,
250
- force: true,
251
- });
252
- return;
253
- }
254
- const stagingRoot = await fs.mkdtemp(path.join(os.tmpdir(), "pm-extension-copy-"));
255
- const stagedDirectory = path.join(stagingRoot, "extension");
256
- try {
257
- await copyDirectory(sourceDirectory, stagedDirectory, {
258
- recursive: true,
259
- force: true,
260
- });
261
- await copyDirectory(stagedDirectory, destinationDirectory, {
262
- recursive: true,
263
- force: true,
264
- });
265
- }
266
- finally {
267
- await fs.rm(stagingRoot, { recursive: true, force: true });
268
- }
269
- }
270
- async function withExtensionInstallLock(settingsRoot, destinationDirectoryName, run, options) {
271
- const lockRoot = path.join(settingsRoot, "runtime", "extension-install-locks");
272
- const lockPath = path.join(lockRoot, `${destinationDirectoryName}.lock`);
273
- await fs.mkdir(lockRoot, { recursive: true });
274
- const attempts = Math.max(1, Math.floor(options?.attempts ?? EXTENSION_INSTALL_LOCK_ATTEMPTS));
275
- const delayMs = Math.max(0, Math.floor(options?.delay_ms ?? EXTENSION_INSTALL_LOCK_DELAY_MS));
276
- const staleMs = Math.max(0, Math.floor(options?.stale_ms ?? EXTENSION_INSTALL_LOCK_STALE_MS));
277
- let acquired = false;
278
- for (let attempt = 1; attempt <= attempts; attempt += 1) {
279
- try {
280
- await fs.mkdir(lockPath);
281
- acquired = true;
282
- await fs.writeFile(path.join(lockPath, "owner.json"), `${JSON.stringify({ pid: process.pid, created_at: nowIso(), destination: destinationDirectoryName }, null, 2)}\n`, "utf8");
283
- break;
284
- }
285
- catch (error) {
286
- if (!isErrnoCode(error, "EEXIST")) {
287
- throw error;
288
- }
289
- let stat = null;
290
- try {
291
- stat = await fs.stat(lockPath);
292
- }
293
- catch {
294
- stat = null;
295
- }
296
- if (stat && Date.now() - stat.mtimeMs > staleMs) {
297
- await fs.rm(lockPath, { recursive: true, force: true });
298
- continue;
299
- }
300
- await sleep(delayMs);
301
- }
302
- }
303
- if (!acquired) {
304
- throw new PmCliError(`Timed out waiting for extension install lock for "${destinationDirectoryName}".`, EXIT_CODE.CONFLICT);
305
- }
306
- try {
307
- return await run();
308
- }
309
- finally {
310
- await fs
311
- .rm(lockPath, { recursive: true, force: true })
312
- .catch(() => undefined);
313
- }
314
- }
315
- async function resolveInstalledExtensionCandidate(installed, extensionTarget) {
316
- const lookupValues = [extensionTarget];
317
- const bundledAliasManifestName = await resolveBundledAliasManifestName(extensionTarget);
318
- if (bundledAliasManifestName) {
319
- lookupValues.push(bundledAliasManifestName);
320
- }
321
- const normalizedLookups = [
322
- ...new Set(lookupValues
323
- .map((value) => normalizeExtensionNameForMatch(value))
324
- .filter((value) => value.length > 0)),
325
- ];
326
- for (const lookup of normalizedLookups) {
327
- const byName = installed.find((entry) => normalizeExtensionNameForMatch(entry.name) === lookup);
328
- if (byName) {
329
- return byName;
330
- }
331
- const byDirectory = installed.find((entry) => normalizeExtensionNameForMatch(entry.directory) === lookup);
332
- if (byDirectory) {
333
- return byDirectory;
334
- }
335
- }
336
- return undefined;
337
- }
338
- function isExtensionEnabled(settings, name) {
339
- const normalizedName = name.trim();
340
- const enabled = new Set(normalizeStringList(settings.extensions.enabled));
341
- const disabled = new Set(normalizeStringList(settings.extensions.disabled));
342
- if (disabled.has(normalizedName)) {
343
- return false;
344
- }
345
- if (enabled.size === 0) {
346
- return true;
347
- }
348
- return enabled.has(normalizedName);
349
- }
350
- function ensureActivated(settings, name) {
351
- const normalizedName = name.trim();
352
- const enabled = new Set(normalizeStringList(settings.extensions.enabled));
353
- const disabled = new Set(normalizeStringList(settings.extensions.disabled));
354
- const previousEnabled = [...enabled];
355
- const previousDisabled = [...disabled];
356
- disabled.delete(normalizedName);
357
- if (enabled.size > 0) {
358
- enabled.add(normalizedName);
359
- }
360
- settings.extensions.enabled = [...enabled].sort((left, right) => left.localeCompare(right));
361
- settings.extensions.disabled = [...disabled].sort((left, right) => left.localeCompare(right));
362
- return (settings.extensions.enabled.join("\u0000") !==
363
- previousEnabled.join("\u0000") ||
364
- settings.extensions.disabled.join("\u0000") !==
365
- previousDisabled.join("\u0000"));
366
- }
367
- function ensureDeactivated(settings, name) {
368
- const normalizedName = name.trim();
369
- const enabled = new Set(normalizeStringList(settings.extensions.enabled));
370
- const disabled = new Set(normalizeStringList(settings.extensions.disabled));
371
- const previousEnabled = [...enabled];
372
- const previousDisabled = [...disabled];
373
- enabled.delete(normalizedName);
374
- disabled.add(normalizedName);
375
- settings.extensions.enabled = [...enabled].sort((left, right) => left.localeCompare(right));
376
- settings.extensions.disabled = [...disabled].sort((left, right) => left.localeCompare(right));
377
- return (settings.extensions.enabled.join("\u0000") !==
378
- previousEnabled.join("\u0000") ||
379
- settings.extensions.disabled.join("\u0000") !==
380
- previousDisabled.join("\u0000"));
381
- }
382
- function clearExtensionState(settings, name) {
383
- const normalizedName = name.trim();
384
- const enabled = new Set(normalizeStringList(settings.extensions.enabled));
385
- const disabled = new Set(normalizeStringList(settings.extensions.disabled));
386
- const previousEnabled = [...enabled];
387
- const previousDisabled = [...disabled];
388
- enabled.delete(normalizedName);
389
- disabled.delete(normalizedName);
390
- settings.extensions.enabled = [...enabled].sort((left, right) => left.localeCompare(right));
391
- settings.extensions.disabled = [...disabled].sort((left, right) => left.localeCompare(right));
392
- return (settings.extensions.enabled.join("\u0000") !==
393
- previousEnabled.join("\u0000") ||
394
- settings.extensions.disabled.join("\u0000") !==
395
- previousDisabled.join("\u0000"));
396
- }
397
- function suggestLifecycleActionTarget(target) {
398
- const normalizedTarget = target.trim().toLowerCase();
399
- const exactMatch = LIFECYCLE_ACTION_TARGETS.find(([candidate]) => candidate === normalizedTarget);
400
- if (exactMatch) {
401
- return { action: exactMatch[1], flag: exactMatch[2] };
402
- }
403
- const maxDistance = normalizedTarget.length <= 4 ? 1 : 2;
404
- let nearest = null;
405
- for (const [candidate, action, flag] of LIFECYCLE_ACTION_TARGETS) {
406
- const distance = levenshteinDistanceWithinLimit(normalizedTarget, candidate, maxDistance);
407
- if (distance === null) {
408
- continue;
409
- }
410
- if (nearest === null) {
411
- nearest = { action, flag, distance };
412
- continue;
413
- }
414
- if (distance < nearest.distance) {
415
- nearest = { action, flag, distance };
416
- }
417
- }
418
- return nearest === null
419
- ? null
420
- : { action: nearest.action, flag: nearest.flag };
421
- }
422
- function buildUnknownLifecycleActionError(target, options) {
423
- const noun = options.vocabulary === "package" ? "package" : "extension";
424
- const suggestion = suggestLifecycleActionTarget(target);
425
- if (!suggestion) {
426
- 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);
427
- }
428
- const command = `pm ${noun} ${suggestion.flag}`;
429
- return new PmCliError(`Unknown ${noun} lifecycle action "${target}". Did you mean "${suggestion.flag}"?`, EXIT_CODE.USAGE, {
430
- code: "unknown_lifecycle_action",
431
- required: `Use one of: ${LIFECYCLE_ACTION_FLAG_HINT}.`,
432
- examples: [command, `pm ${noun} --help`],
433
- recovery: {
434
- attempted_command: `pm ${noun} ${target}`,
435
- suggested_retry: command,
436
- fallback_candidates: [
437
- {
438
- source: "lifecycle_action",
439
- command,
440
- reason: `nearest lifecycle action for "${target}"`,
441
- },
442
- ],
443
- },
444
- });
445
- }
446
- // Maps each boolean action flag to the lifecycle action it selects. `scaffold`
447
- // aliases `init` and `adoptAll` selects `adopt-all`; every other flag maps to its
448
- // like-named action. Dispatching through the table keeps `resolveAction` flat.
449
- const EXTENSION_ACTION_FLAG_SELECTORS = [
450
- ["install", "install"],
451
- ["uninstall", "uninstall"],
452
- ["explore", "explore"],
453
- ["manage", "manage"],
454
- ["describe", "describe"],
455
- ["reload", "reload"],
456
- ["doctor", "doctor"],
457
- ["catalog", "catalog"],
458
- ["init", "init"],
459
- ["scaffold", "init"],
460
- ["adopt", "adopt"],
461
- ["adoptAll", "adopt-all"],
462
- ["activate", "activate"],
463
- ["deactivate", "deactivate"],
464
- ];
465
- /** Map a bare positional token (already trimmed and lower-cased) to the lifecycle action it implies for `pm extension <token>` / `pm package <token>`: the `doctor`/`reload`/`catalog`/`init`/`scaffold`/`explore`/`manage` keywords, with `list` and the empty string both meaning `explore`. Returns `null` for anything else so the caller can raise a did-you-mean error. */
466
- function resolveImplicitActionFromTarget(normalizedTarget) {
467
- if (normalizedTarget === "doctor") {
468
- return "doctor";
469
- }
470
- if (normalizedTarget === "reload") {
471
- return "reload";
472
- }
473
- if (normalizedTarget === "catalog") {
474
- return "catalog";
475
- }
476
- if (normalizedTarget === "init" || normalizedTarget === "scaffold") {
477
- return "init";
478
- }
479
- if (normalizedTarget === "explore") {
480
- return "explore";
481
- }
482
- if (normalizedTarget === "manage") {
483
- return "manage";
484
- }
485
- if (normalizedTarget === "list" || normalizedTarget === "") {
486
- return "explore";
487
- }
488
- return null;
489
- }
490
- function resolveAction(target, options) {
491
- const selected = [
492
- ...new Set(EXTENSION_ACTION_FLAG_SELECTORS.filter(([flag]) => options[flag] === true).map(([, mappedAction]) => mappedAction)),
493
- ];
494
- if (selected.length === 0) {
495
- if (target === undefined) {
496
- return "explore";
497
- }
498
- const implicitAction = resolveImplicitActionFromTarget(target.trim().toLowerCase());
499
- if (implicitAction) {
500
- return implicitAction;
501
- }
502
- throw buildUnknownLifecycleActionError(target, options);
503
- }
504
- if (selected.length > 1) {
505
- throw new PmCliError("Extension action flags are mutually exclusive.", EXIT_CODE.USAGE);
506
- }
507
- return selected[0];
508
- }
509
- function resolveScope(options) {
510
- const projectLike = options.project === true || options.local === true;
511
- const global = options.global === true;
512
- if (projectLike && global) {
513
- throw new PmCliError('Options "--project/--local" and "--global" are mutually exclusive.', EXIT_CODE.USAGE);
514
- }
515
- return global ? "global" : "project";
516
- }
517
- function resolveUpdateCheckResolution(managedEntry) {
518
- if (!managedEntry) {
519
- return {
520
- status: "skipped_unmanaged",
521
- reason: "extension_not_managed",
522
- };
523
- }
524
- if (managedEntry.source.kind !== "github") {
525
- return {
526
- status: "skipped_non_github",
527
- reason: `managed_source_kind_${managedEntry.source.kind}`,
528
- };
529
- }
530
- const updateError = typeof managedEntry.update_error === "string"
531
- ? managedEntry.update_error.trim()
532
- : "";
533
- if (updateError.length > 0) {
534
- return {
535
- status: "failed",
536
- reason: updateError,
537
- };
538
- }
539
- if (typeof managedEntry.last_update_check_at === "string" &&
540
- managedEntry.last_update_check_at.trim().length > 0) {
541
- if (managedEntry.update_available === true) {
542
- return {
543
- status: "checked",
544
- reason: "update_available",
545
- };
546
- }
547
- if (managedEntry.update_available === false) {
548
- return {
549
- status: "checked",
550
- reason: "up_to_date",
551
- };
552
- }
553
- return {
554
- status: "checked",
555
- reason: "checked_without_commit_baseline",
556
- };
557
- }
558
- return {
559
- status: "not_checked",
560
- reason: "no_update_check_recorded",
561
- };
562
- }
563
- /**
564
- * Assemble a {@link ManagedExtensionSummary} from a directory's resolved identity
565
- * (name/version/entry/enabled state) and its managed-state record, projecting the
566
- * managed-source provenance and the resolved update-check status. Runtime
567
- * activation fields default to "not yet probed" (`runtime_active: null`,
568
- * `activation_status: "unknown"`) so a later runtime probe can overlay live state.
569
- */
570
- function buildInstalledExtensionSummary(identity, scope, managedEntry, updateCheck) {
571
- return {
572
- name: identity.name,
573
- directory: identity.directory,
574
- version: identity.version,
575
- entry: identity.entry,
576
- scope,
577
- active: identity.enabled,
578
- enabled: identity.enabled,
579
- runtime_active: null,
580
- activation_status: "unknown",
581
- managed: Boolean(managedEntry),
582
- source: managedEntry?.source,
583
- update_available: managedEntry?.update_available,
584
- last_update_check_at: managedEntry?.last_update_check_at,
585
- last_update_remote_commit: managedEntry?.last_update_remote_commit,
586
- update_error: managedEntry?.update_error,
587
- update_check_status: updateCheck.status,
588
- update_check_reason: updateCheck.reason,
589
- };
590
- }
591
- async function listInstalledExtensions(extensionsRoot, scope, settings, state) {
592
- if (!(await pathExists(extensionsRoot))) {
593
- return {
594
- extensions: [],
595
- warnings: [],
596
- };
597
- }
598
- const entries = await fs.readdir(extensionsRoot, { withFileTypes: true });
599
- const directories = entries
600
- .filter((entry) => entry.isDirectory())
601
- .map((entry) => entry.name)
602
- .sort((left, right) => left.localeCompare(right));
603
- const managedByName = new Map();
604
- const managedByDirectory = new Map();
605
- for (const managedEntry of state.entries) {
606
- managedByName.set(normalizeExtensionNameForMatch(managedEntry.name), managedEntry);
607
- managedByDirectory.set(normalizeExtensionNameForMatch(managedEntry.directory), managedEntry);
608
- }
609
- const warnings = [];
610
- const summaries = [];
611
- for (const directoryName of directories) {
612
- const extensionDirectory = path.join(extensionsRoot, directoryName);
613
- const manifestPath = path.join(extensionDirectory, "manifest.json");
614
- if (!(await pathExists(manifestPath))) {
615
- warnings.push(`extension_manifest_missing:${scope}:${directoryName}`);
616
- const managedEntry = managedByDirectory.get(normalizeExtensionNameForMatch(directoryName));
617
- summaries.push(buildInstalledExtensionSummary({
618
- name: managedEntry?.name ?? directoryName,
619
- directory: directoryName,
620
- version: managedEntry?.manifest_version ?? "unknown",
621
- entry: managedEntry?.manifest_entry ?? "unknown",
622
- enabled: managedEntry
623
- ? isExtensionEnabled(settings, managedEntry.name)
624
- : false,
625
- }, scope, managedEntry, resolveUpdateCheckResolution(managedEntry)));
626
- continue;
627
- }
628
- let rawManifest;
629
- try {
630
- rawManifest = JSON.parse(await fs.readFile(manifestPath, "utf8"));
631
- }
632
- catch {
633
- warnings.push(`extension_manifest_invalid_json:${scope}:${directoryName}`);
634
- continue;
635
- }
636
- const manifest = parseExtensionManifest(rawManifest);
637
- if (!manifest) {
638
- warnings.push(`extension_manifest_invalid:${scope}:${directoryName}`);
639
- continue;
640
- }
641
- const managedEntry = managedByName.get(normalizeExtensionNameForMatch(manifest.name)) ??
642
- managedByDirectory.get(normalizeExtensionNameForMatch(directoryName));
643
- summaries.push(buildInstalledExtensionSummary({
644
- name: manifest.name,
645
- directory: directoryName,
646
- version: manifest.version,
647
- entry: manifest.entry,
648
- enabled: isExtensionEnabled(settings, manifest.name),
649
- }, scope, managedEntry, resolveUpdateCheckResolution(managedEntry)));
650
- }
651
- return {
652
- extensions: summaries.sort((left, right) => left.name.localeCompare(right.name)),
653
- warnings: warnings.sort((left, right) => left.localeCompare(right)),
654
- };
655
- }
656
- const extensionRuntimeProbeQueue = createSerialQueue();
657
- function summarizeRuntimeCommandPathsForExtension(extensionName, installed) {
658
- const normalizedName = normalizeExtensionNameForMatch(extensionName);
659
- const entry = installed.find((candidate) => normalizeExtensionNameForMatch(candidate.name) === normalizedName);
660
- return {
661
- command_paths: [...(entry?.command_paths ?? [])].sort((left, right) => left.localeCompare(right)),
662
- action_paths: [...(entry?.action_paths ?? [])].sort((left, right) => left.localeCompare(right)),
663
- };
664
- }
665
- function resolveCommandDiscoveryPackageName(extensionName, source) {
666
- if (typeof source.package === "string" && source.package.trim().length > 0) {
667
- return source.package.trim();
668
- }
669
- if (source.kind === "builtin" &&
670
- typeof source.name === "string" &&
671
- source.name.trim().length > 0) {
672
- return source.name.trim();
673
- }
674
- return extensionName;
675
- }
676
- function buildInstallCommandDiscovery(extensionName, source, commandSummary, activationFailure) {
677
- const helpCommands = commandSummary.command_paths.map((commandPath) => `pm ${commandPath} --help`);
678
- const sdkDependencyMissing = activationFailure?.error.toLowerCase().includes("@unbrained/pm-cli") ===
679
- true;
680
- const nextSteps = commandSummary.command_paths.length > 0
681
- ? [...helpCommands]
682
- : [
683
- "Run pm package doctor --project --detail deep if expected package commands are missing.",
684
- ];
685
- if (sdkDependencyMissing) {
686
- nextSteps.unshift("Install @unbrained/pm-cli in the target workspace so declarative package runtime imports resolve, then reinstall the package.");
687
- }
688
- return {
689
- package_name: resolveCommandDiscoveryPackageName(extensionName, source),
690
- extension_name: extensionName,
691
- command_paths: commandSummary.command_paths,
692
- action_paths: commandSummary.action_paths,
693
- help_commands: helpCommands,
694
- next_steps: nextSteps,
695
- ...(sdkDependencyMissing ? { sdk_dependency_status: "missing" } : {}),
696
- };
697
- }
698
- function summarizeActivationFailureForDiagnostics(failure) {
699
- const trace = failure.trace
700
- ? {
701
- method: failure.trace.method,
702
- registration_index: failure.trace.registration_index,
703
- expected_schema: failure.trace.expected_schema,
704
- ...(failure.trace.command ? { command: failure.trace.command } : {}),
705
- ...(failure.trace.capability
706
- ? { capability: failure.trace.capability }
707
- : {}),
708
- ...(failure.trace.missing_capability
709
- ? { missing_capability: failure.trace.missing_capability }
710
- : {}),
711
- ...(failure.trace.hint ? { hint: failure.trace.hint } : {}),
712
- }
713
- : undefined;
714
- return {
715
- layer: failure.layer,
716
- name: failure.name,
717
- entry_path: failure.entry_path,
718
- error: failure.error,
719
- ...(failure.trace?.missing_capability
720
- ? { missing_capability: failure.trace.missing_capability }
721
- : {}),
722
- ...(failure.trace?.hint ? { hint: failure.trace.hint } : {}),
723
- ...(trace ? { trace } : {}),
724
- };
725
- }
726
- function collectActivationFailureDiagnostics(failures) {
727
- return failures
728
- .map((failure) => summarizeActivationFailureForDiagnostics(failure))
729
- .sort((left, right) => `${left.layer}:${left.name}`.localeCompare(`${right.layer}:${right.name}`));
730
- }
731
- function findActivationFailureByName(extensionName, failures, layer) {
732
- const normalizedName = normalizeExtensionNameForMatch(extensionName);
733
- return failures.find((failure) => (layer === undefined || failure.layer === layer) &&
734
- normalizeExtensionNameForMatch(failure.name) === normalizedName);
735
- }
736
- function resolveInstallRuntimeActivationStatus(extensionName, scope, runtimeInstalled, installActivationFailure) {
737
- const runtimeInstalledExtension = runtimeInstalled.find((entry) => entry.scope === scope &&
738
- normalizeExtensionNameForMatch(entry.name) ===
739
- normalizeExtensionNameForMatch(extensionName));
740
- return (runtimeInstalledExtension?.activation_status ??
741
- (installActivationFailure ? "failed" : "unknown"));
742
- }
743
- async function probeRuntimeCommandPathsForInstall(pmRoot, settings, refreshedInstalled, global) {
744
- return extensionRuntimeProbeQueue.enqueue(async () => {
745
- const originalPackageRoot = process.env.PM_CLI_PACKAGE_ROOT;
746
- process.env.PM_CLI_PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../..");
747
- try {
748
- const loadResult = await loadExtensions({
749
- pmRoot,
750
- settings,
751
- cwd: process.cwd(),
752
- noExtensions: global.noExtensions === true,
753
- reload_token: nextExtensionReloadToken(),
754
- cache_bust: true,
755
- });
756
- const activationResult = await activateExtensions({
757
- ...loadResult,
758
- loaded: loadResult.loaded,
759
- });
760
- const runtimeFailures = [
761
- ...loadResult.failed.map((failure) => ({
762
- layer: failure.layer,
763
- name: failure.name,
764
- entry_path: failure.entry_path,
765
- error: failure.error,
766
- })),
767
- ...collectActivationFailureDiagnostics(activationResult.failed),
768
- ];
769
- return {
770
- installed: applyDoctorRuntimeActivationState(refreshedInstalled, loadResult, activationResult),
771
- warnings: [...loadResult.warnings, ...activationResult.warnings],
772
- activation_failures: runtimeFailures,
773
- extensions_disabled: loadResult.disabled_by_flag,
774
- item_type_registrations: activationResult.registrations.item_types,
775
- };
776
- }
777
- finally {
778
- if (originalPackageRoot === undefined) {
779
- delete process.env.PM_CLI_PACKAGE_ROOT;
780
- }
781
- else {
782
- process.env.PM_CLI_PACKAGE_ROOT = originalPackageRoot;
783
- }
784
- }
785
- });
786
- }
787
- async function checkGithubUpdate(source, gitCommandRunner = runGitCommand) {
788
- const checkedAt = nowIso();
789
- if (source.kind !== "github" || !source.repository) {
790
- return {
791
- checked_at: checkedAt,
792
- available: null,
793
- error: "not_a_github_managed_source",
794
- };
795
- }
796
- try {
797
- const ref = source.ref && source.ref.trim().length > 0 ? source.ref.trim() : "HEAD";
798
- const output = await gitCommandRunner([
799
- "ls-remote",
800
- source.repository,
801
- ref,
802
- ]);
803
- const firstLine = output
804
- .split(/\r?\n/)
805
- .map((line) => line.trim())
806
- .find((line) => line.length > 0);
807
- if (!firstLine) {
808
- return {
809
- checked_at: checkedAt,
810
- available: null,
811
- error: "no_remote_reference_found",
812
- };
813
- }
814
- const [remoteCommit] = firstLine.split(/\s+/);
815
- /* c8 ignore start -- firstLine is trimmed non-empty, so split always yields a non-empty first token */
816
- if (typeof remoteCommit !== "string" || remoteCommit.length === 0) {
817
- return {
818
- checked_at: checkedAt,
819
- available: null,
820
- error: "invalid_remote_reference",
821
- };
822
- }
823
- /* c8 ignore stop */
824
- if (typeof source.commit === "string" && source.commit.trim().length > 0) {
825
- return {
826
- checked_at: checkedAt,
827
- remote_commit: remoteCommit,
828
- available: remoteCommit !== source.commit.trim(),
829
- };
830
- }
831
- return {
832
- checked_at: checkedAt,
833
- remote_commit: remoteCommit,
834
- available: null,
835
- error: "missing_installed_commit",
836
- };
837
- }
838
- catch (error) {
839
- return {
840
- checked_at: checkedAt,
841
- available: null,
842
- error: error instanceof Error ? error.message : String(error),
843
- };
844
- }
845
- }
846
- async function adoptUnmanagedExtensions(extensionsRoot, scope, installedExtensions, state) {
847
- const unmanagedCandidates = installedExtensions.filter((entry) => !entry.managed);
848
- const sortedCandidates = [...unmanagedCandidates].sort((left, right) => {
849
- const byName = left.name.localeCompare(right.name);
850
- if (byName !== 0) {
851
- return byName;
852
- }
853
- return left.directory.localeCompare(right.directory);
854
- });
855
- let nextState = state;
856
- const adoptedEntries = [];
857
- for (const candidate of sortedCandidates) {
858
- const extensionDirectory = path.join(extensionsRoot, candidate.directory);
859
- const validated = await validateExtensionDirectory(extensionDirectory);
860
- const now = nowIso();
861
- const sourceRecord = {
862
- kind: "local",
863
- input: candidate.name,
864
- location: extensionDirectory,
865
- };
866
- nextState = upsertManagedEntry(nextState, {
867
- name: validated.manifest.name,
868
- directory: candidate.directory,
869
- scope,
870
- manifest_version: validated.manifest.version,
871
- manifest_entry: validated.manifest.entry,
872
- capabilities: [...validated.manifest.capabilities],
873
- installed_at: now,
874
- updated_at: now,
875
- source: sourceRecord,
876
- });
877
- adoptedEntries.push({
878
- name: validated.manifest.name,
879
- directory: candidate.directory,
880
- version: validated.manifest.version,
881
- entry: validated.manifest.entry,
882
- source: sourceRecord,
883
- });
884
- }
885
- if (adoptedEntries.length > 0) {
886
- await writeManagedExtensionState(extensionsRoot, nextState);
887
- }
888
- return {
889
- state: nextState,
890
- adopted_entries: adoptedEntries,
891
- unmanaged_candidates: sortedCandidates,
892
- already_managed_count: installedExtensions.length - unmanagedCandidates.length,
893
- };
894
- }
895
- function resolveExtensionRootsForScope(scope, global) {
896
- const pmRoot = resolvePmRoot(process.cwd(), global.path);
897
- const roots = resolveExtensionRoots(pmRoot, process.cwd());
898
- const settingsRoot = scope === "global" ? resolveGlobalPmRoot(process.cwd()) : pmRoot;
899
- const selectedRoot = scope === "global" ? roots.global : roots.project;
900
- return {
901
- pm_root: pmRoot,
902
- scope,
903
- settings_root: settingsRoot,
904
- selected_root: selectedRoot,
905
- roots,
906
- };
907
- }
908
- function resolveGithubOption(options) {
909
- if (typeof options.gh === "string" &&
910
- typeof options.github === "string" &&
911
- options.gh.trim() !== options.github.trim()) {
912
- throw new PmCliError('Options "--gh" and "--github" must match when both are provided.', EXIT_CODE.USAGE);
913
- }
914
- if (typeof options.gh === "string" && options.gh.trim().length > 0) {
915
- return options.gh.trim();
916
- }
917
- if (typeof options.github === "string" && options.github.trim().length > 0) {
918
- return options.github.trim();
919
- }
920
- return undefined;
921
- }
922
- function getLifecycleActionFlag(action) {
923
- return LIFECYCLE_ACTION_FLAGS[action];
924
- }
925
- function requireTarget(target, action, options = {}) {
926
- const normalized = target?.trim();
927
- if (!normalized) {
928
- if (action === "init") {
929
- 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);
930
- }
931
- const noun = options.vocabulary === "package" ? "package" : "extension";
932
- const targetName = action === "install" ? "source" : "name";
933
- const targetLabel = `${noun} ${targetName}`;
934
- const actionFlag = getLifecycleActionFlag(action);
935
- const commandTarget = `<${targetName}>`;
936
- const command = `pm ${noun} ${actionFlag} ${commandTarget}`;
937
- throw new PmCliError(`Action "${action}" requires ${targetLabel} input.`, EXIT_CODE.USAGE, {
938
- code: "missing_lifecycle_target",
939
- required: `Provide a ${targetName} target for ${action}.`,
940
- examples: [
941
- `pm ${noun} ${action} ${commandTarget}`,
942
- command,
943
- `pm ${noun} --help`,
944
- ],
945
- recovery: {
946
- attempted_command: `pm ${noun} ${action}`,
947
- suggested_retry: command,
948
- fallback_candidates: [
949
- {
950
- source: "lifecycle_action",
951
- command,
952
- reason: `flag-form ${action} command with required ${targetName} target`,
953
- },
954
- ],
955
- },
956
- });
957
- }
958
- return normalized;
959
- }
960
- function collectGlobalOutputOverrideDoctorWarnings(activationResult) {
961
- const warnings = [];
962
- for (const entry of activationResult.services.overrides) {
963
- if (entry.service !== "output_format") {
964
- continue;
965
- }
966
- warnings.push(`extension_output_service_override_global:${entry.service}:${entry.layer}:${entry.name}`);
967
- }
968
- for (const entry of activationResult.renderers.overrides) {
969
- warnings.push(`extension_output_renderer_override_global:${entry.format}:${entry.layer}:${entry.name}`);
970
- }
971
- return [...new Set(warnings)].sort((left, right) => left.localeCompare(right));
972
- }
973
- /**
974
- * Doctor advisory: flag loaded extensions that contribute GLOBAL schema (custom
975
- * item types or fields) yet also declare narrow `activation.commands`.
976
- *
977
- * Custom item types and fields must be present for the built-in commands the
978
- * extension does not own and cannot enumerate (`pm create <type>`,
979
- * `pm list --type <type>`, `pm validate`). Declaring `activation.commands` gates
980
- * lazy activation to only the listed command paths, so the package never
981
- * activates for those built-ins and its custom type silently fails to register —
982
- * a quiet footgun (decision pm-halx). The `schema` scaffold deliberately omits
983
- * the field; this advisory catches hand-authored packages that do not. It is
984
- * doctor-only and non-blocking — `pm health` does not surface it — so the author
985
- * can either drop `activation.commands` or, when the schema is intentionally
986
- * command-scoped, knowingly ignore the hint.
987
- */
988
- function collectSchemaNarrowActivationDoctorWarnings(loadResult, activationResult) {
989
- const schemaContributors = new Set();
990
- for (const entry of activationResult.registrations.item_types) {
991
- if (entry.types.length > 0) {
992
- schemaContributors.add(`${entry.layer}:${normalizeExtensionNameForMatch(entry.name)}`);
993
- }
994
- }
995
- for (const entry of activationResult.registrations.item_fields) {
996
- if (entry.fields.length > 0) {
997
- schemaContributors.add(`${entry.layer}:${normalizeExtensionNameForMatch(entry.name)}`);
998
- }
999
- }
1000
- const warnings = [];
1001
- for (const extension of loadResult.loaded) {
1002
- if ((extension.activation?.commands ?? []).length === 0) {
1003
- continue;
1004
- }
1005
- if (schemaContributors.has(`${extension.layer}:${normalizeExtensionNameForMatch(extension.name)}`)) {
1006
- warnings.push(`extension_schema_narrow_activation:${extension.layer}:${extension.name}`);
1007
- }
1008
- }
1009
- return [...new Set(warnings)].sort((left, right) => left.localeCompare(right));
1010
- }
1011
- /** Reject option/action combinations that are only meaningful for a specific lifecycle action — `--trace`/`--strict-exit`/`--fail-on-warn` require `--doctor`, `--watch` requires `--reload`, `--runtime-probe` requires `--manage`, `--fix-managed-state` requires `--manage`/`--doctor`, and `--capability`/`--declarative` require `--init`/`--scaffold`. Each guard pairs a "flag is set" predicate with the action(s) that permit it and throws a USAGE error on the first mismatch. */
1012
- function assertExtensionActionOptionScope(action, options) {
1013
- const guards = [
1014
- {
1015
- triggered: options.strictExit === true || options.failOnWarn === true,
1016
- allowed: action === "doctor",
1017
- message: "--strict-exit and --fail-on-warn are only valid with --doctor.",
1018
- },
1019
- {
1020
- triggered: options.trace === true,
1021
- allowed: action === "doctor",
1022
- message: "--trace is only valid with --doctor.",
1023
- },
1024
- {
1025
- triggered: options.watch === true,
1026
- allowed: action === "reload",
1027
- message: "--watch is only valid with --reload.",
1028
- },
1029
- {
1030
- triggered: options.runtimeProbe === true,
1031
- allowed: action === "manage",
1032
- message: "--runtime-probe is only valid with --manage.",
1033
- },
1034
- {
1035
- triggered: options.fixManagedState === true,
1036
- allowed: action === "manage" || action === "doctor",
1037
- message: "--fix-managed-state is only valid with --manage or --doctor.",
1038
- },
1039
- {
1040
- triggered: options.isolated === true || options.ignoreGlobal === true,
1041
- allowed: action === "doctor",
1042
- message: "--isolated and --ignore-global are only valid with --doctor.",
1043
- },
1044
- {
1045
- triggered: options.capability !== undefined,
1046
- allowed: action === "init",
1047
- message: "--capability is only valid with --init/--scaffold.",
1048
- },
1049
- {
1050
- triggered: options.declarative === true,
1051
- allowed: action === "init",
1052
- message: "--declarative is only valid with --init/--scaffold.",
1053
- },
1054
- ];
1055
- for (const guard of guards) {
1056
- if (guard.triggered && !guard.allowed) {
1057
- throw new PmCliError(guard.message, EXIT_CODE.USAGE);
1058
- }
1059
- }
1060
- }
1061
- /* c8 ignore start -- alias-normalization matrix is covered by resolveAction tests; this only rewrites positional aliases */
1062
- /** Collapse a positional target that merely repeats the action keyword (`pm extension doctor`, `reload`, `catalog`, or `init`/`scaffold`) to `undefined` so the action handlers treat it as "no target" rather than an extension name; otherwise the original target is returned unchanged. */
1063
- function resolveNormalizedExtensionTarget(target, action, options) {
1064
- const normalizedInput = target?.trim().toLowerCase();
1065
- if (action === "doctor" && normalizedInput === "doctor") {
1066
- return undefined;
1067
- }
1068
- if (action === "reload" && normalizedInput === "reload") {
1069
- return undefined;
1070
- }
1071
- if (action === "catalog" && normalizedInput === "catalog") {
1072
- return undefined;
1073
- }
1074
- const inferredInitAlias = action === "init" &&
1075
- options.init !== true &&
1076
- options.scaffold !== true &&
1077
- (normalizedInput === "init" || normalizedInput === "scaffold");
1078
- if (inferredInitAlias) {
1079
- return undefined;
1080
- }
1081
- return target;
1082
- }
1083
- /* c8 ignore stop */
1084
- /**
1085
- * Entry point for the `pm extension` / `pm package` command surface. Resolves the
1086
- * requested lifecycle action and scope, rejects out-of-scope option usage,
1087
- * normalizes positional aliases, then dispatches to the matching action handler —
1088
- * each of which reads and writes managed-extension state, runtime-probes, and
1089
- * returns the canonical {@link ExtensionCommandResult}. `--doctor` results are
1090
- * flagged for native (non-JSON-wrapped) output.
1091
- */
1092
- export async function runExtension(target, options, global) {
1093
- const action = resolveAction(target, options);
1094
- assertExtensionActionOptionScope(action, options);
1095
- const normalizedTarget = resolveNormalizedExtensionTarget(target, action, options);
1096
- const scope = resolveScope(options);
1097
- const resolvedRoots = resolveExtensionRootsForScope(scope, global);
1098
- const warnings = [];
1099
- const withResult = (details, ok = true) => {
1100
- const result = {
1101
- ok,
1102
- action,
1103
- scope,
1104
- roots: action === "catalog" &&
1105
- typeof options.fields === "string" &&
1106
- options.fields.trim().length > 0
1107
- ? {
1108
- project: "project",
1109
- global: "global",
1110
- selected: scope,
1111
- settings_root: "project",
1112
- }
1113
- : {
1114
- project: resolvedRoots.roots.project,
1115
- global: resolvedRoots.roots.global,
1116
- selected: resolvedRoots.selected_root,
1117
- settings_root: resolvedRoots.settings_root,
1118
- },
1119
- warnings: [...new Set(warnings)].sort((left, right) => left.localeCompare(right)),
1120
- details,
1121
- };
1122
- if (action === "doctor") {
1123
- Object.defineProperty(result, NATIVE_OUTPUT_MARKER, {
1124
- value: true,
1125
- enumerable: false,
1126
- configurable: false,
1127
- });
1128
- }
1129
- return result;
1130
- };
1131
- const ctx = {
1132
- action,
1133
- normalizedTarget,
1134
- scope,
1135
- resolvedRoots,
1136
- warnings,
1137
- options,
1138
- global,
1139
- withResult,
1140
- };
1141
- return EXTENSION_ACTION_HANDLERS[action](ctx);
1142
- }
1143
- async function runExtensionInitAction(ctx) {
1144
- const { action, normalizedTarget, options, withResult } = ctx;
1145
- const githubOption = resolveGithubOption(options);
1146
- if (githubOption !== undefined ||
1147
- (typeof options.ref === "string" && options.ref.trim().length > 0)) {
1148
- throw new PmCliError('Action "init" does not accept --gh/--github/--ref options.', EXIT_CODE.USAGE);
1149
- }
1150
- const scaffoldTarget = requireTarget(normalizedTarget, action, options);
1151
- const scaffold = await scaffoldExtensionProject(scaffoldTarget, options.vocabulary ?? "extension", options.capability, options.declarative === true);
1152
- const quotedTargetPath = JSON.stringify(scaffold.target_path);
1153
- // Forward-slash the path for the copy-pasteable `cd` hint: Windows cmd.exe /
1154
- // PowerShell reject the doubled backslashes JSON.stringify emits, while both
1155
- // shells (and POSIX) accept forward slashes.
1156
- const quotedShellTargetPath = JSON.stringify(scaffold.target_path.replace(/\\/g, "/"));
1157
- return withResult({
1158
- scaffolded: scaffold.created_directory ||
1159
- scaffold.files.some((entry) => entry.status === "created"),
1160
- extension: {
1161
- name: scaffold.extension_name,
1162
- command: scaffold.command_name,
1163
- },
1164
- capability: scaffold.capability,
1165
- style: scaffold.style,
1166
- target_path: scaffold.target_path,
1167
- created_directory: scaffold.created_directory,
1168
- files: scaffold.files,
1169
- next_steps: [
1170
- // Extensions are authored AND loaded as TypeScript (ADR pm-2c28 / pm-m1uz):
1171
- // the manifest entry is ./index.ts and pm strips types on load (Node
1172
- // >=22.18), so there is no compile/build step — install dependencies, then
1173
- // install the scaffold directly.
1174
- ...(options.vocabulary === "package"
1175
- ? [
1176
- `Install dependencies: cd ${quotedShellTargetPath}, then run "npm install"`,
1177
- ]
1178
- : [
1179
- `Install type-check dependencies: cd ${quotedShellTargetPath}, then run "npm install -D typescript @types/node @unbrained/pm-cli"`,
1180
- ]),
1181
- ...(options.vocabulary === "package" && options.declarative === true
1182
- ? [
1183
- "Ensure the target workspace can resolve @unbrained/pm-cli before installing this declarative package.",
1184
- ]
1185
- : []),
1186
- `Install the scaffold: ${options.vocabulary === "package" ? "pm install --project" : "pm extension --install --project"} ${quotedTargetPath}`,
1187
- `Smoke-test command path: pm ${scaffold.command_name}`,
1188
- ...(options.vocabulary === "package"
1189
- ? [
1190
- `Validate the package: cd ${quotedShellTargetPath}, then run "npm run typecheck" and "npm test"`,
1191
- ]
1192
- : [
1193
- `Type-check the source (optional): cd ${quotedShellTargetPath}, then run "npx tsc --noEmit"`,
1194
- ]),
1195
- `Run diagnostics: ${options.vocabulary === "package" ? "pm package doctor" : "pm extension --doctor"} --project --detail summary`,
1196
- ],
1197
- });
1198
- }
1199
- async function runExtensionReloadAction(ctx) {
1200
- const { normalizedTarget, resolvedRoots, warnings, options, global, withResult, } = ctx;
1201
- if (normalizedTarget !== undefined) {
1202
- throw new PmCliError('Action "reload" does not accept a target argument.', EXIT_CODE.USAGE);
1203
- }
1204
- const settings = await readSettings(resolvedRoots.settings_root);
1205
- const reloadToken = nextExtensionReloadToken();
1206
- const reloaded = await loadExtensions({
1207
- pmRoot: resolvedRoots.settings_root,
1208
- settings,
1209
- cwd: process.cwd(),
1210
- noExtensions: global.noExtensions,
1211
- reload_token: reloadToken,
1212
- cache_bust: true,
1213
- });
1214
- warnings.push(...reloaded.warnings);
1215
- const activation = await activateExtensions(reloaded);
1216
- warnings.push(...activation.warnings);
1217
- const details = {
1218
- reload: {
1219
- token: reloadToken,
1220
- cache_bust: true,
1221
- watch: options.watch === true,
1222
- },
1223
- loaded_count: reloaded.loaded.length,
1224
- failed_count: reloaded.failed.length,
1225
- activated_count: Math.max(0, reloaded.loaded.length - activation.failed.length),
1226
- activation_failed_count: activation.failed.length,
1227
- loaded_extensions: reloaded.loaded.map((entry) => ({
1228
- name: entry.name,
1229
- layer: entry.layer,
1230
- version: entry.version,
1231
- })),
1232
- failed_extensions: reloaded.failed.map((entry) => ({
1233
- name: entry.name,
1234
- layer: entry.layer,
1235
- error: entry.error,
1236
- })),
1237
- activation_failures: activation.failed.map((entry) => ({
1238
- name: entry.name,
1239
- layer: entry.layer,
1240
- error: entry.error,
1241
- })),
1242
- };
1243
- if (options.watch === true) {
1244
- warnings.push("extension_reload_watch_hint:watch_mode_requested_non_interactive_single_pass_only");
1245
- }
1246
- return withResult(details);
1247
- }
1248
- async function runExtensionCatalogAction(ctx) {
1249
- const { normalizedTarget, scope, options, global, withResult } = ctx;
1250
- if (typeof normalizedTarget === "string" &&
1251
- normalizedTarget.length > 0 &&
1252
- normalizedTarget !== "catalog") {
1253
- throw new PmCliError('Action "catalog" does not accept a package target.', EXIT_CODE.USAGE);
1254
- }
1255
- return withResult(await buildBundledPackageCatalog(scope, global, options));
1256
- }
1257
- /* c8 ignore start -- source-shape branch combinations are exercised in install-source focused tests */
1258
- /** Build the persisted managed-source record for an install from its resolved shape: a bundled builtin alias, a local path, an npm package, or (the default) a GitHub repository, capturing the location/commit/subpath provenance the manage and upgrade flows later read back. */
1259
- function buildInstallManagedSource(bundledAliasName, bundledPackageName, installSource, resolvedSource) {
1260
- if (bundledAliasName) {
1261
- return {
1262
- kind: "builtin",
1263
- input: bundledAliasName,
1264
- location: bundledAliasName,
1265
- name: bundledAliasName,
1266
- ...(bundledPackageName === null ? {} : { package: bundledPackageName }),
1267
- };
1268
- }
1269
- if (installSource.kind === "local") {
1270
- return {
1271
- kind: "local",
1272
- input: installSource.input,
1273
- location: installSource.absolute_path,
1274
- };
1275
- }
1276
- if (installSource.kind === "npm") {
1277
- return {
1278
- kind: "npm",
1279
- input: installSource.input,
1280
- location: resolvedSource.resolved_subpath ?? ".",
1281
- package: resolvedSource.npm_package,
1282
- version: resolvedSource.npm_version,
1283
- };
1284
- }
1285
- return {
1286
- kind: "github",
1287
- input: installSource.input,
1288
- location: resolvedSource.resolved_subpath ?? installSource.subpath ?? ".",
1289
- repository: installSource.repository,
1290
- owner: installSource.owner,
1291
- repo: installSource.repo,
1292
- ref: installSource.ref,
1293
- subpath: resolvedSource.resolved_subpath ?? installSource.subpath,
1294
- commit: resolvedSource.commit,
1295
- };
1296
- }
1297
- /* c8 ignore stop */
1298
- /** Run the install body while holding the per-destination install lock: read settings and managed state, copy the validated extension into the scope root unless it is already installed in place, upsert the managed entry and activation state, scaffold any contributed item-type folders, runtime-probe the freshly installed command paths, and return the install result envelope. */
1299
- async function performExtensionInstallUnderLock(ctx, input) {
1300
- const { scope, resolvedRoots, warnings, global, withResult } = ctx;
1301
- const { validated, destinationDirectoryName, bundledAliasName, bundledPackageName, installSource, resolvedSource, } = input;
1302
- const settings = await readSettings(resolvedRoots.settings_root);
1303
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1304
- warnings.push(...managedStateRead.warnings);
1305
- const destinationDirectory = path.join(resolvedRoots.selected_root, destinationDirectoryName);
1306
- const destinationExists = await pathExists(destinationDirectory);
1307
- const installInPlace = await areDirectoriesEquivalent(validated.directory, destinationDirectory);
1308
- await fs.mkdir(resolvedRoots.selected_root, { recursive: true });
1309
- if (!installInPlace) {
1310
- await copyExtensionDirectoryForInstall(validated.directory, destinationDirectory);
1311
- }
1312
- await ensureExtensionModuleTypeMarker(destinationDirectory);
1313
- const sourceRecord = buildInstallManagedSource(bundledAliasName, bundledPackageName, installSource, resolvedSource);
1314
- const now = nowIso();
1315
- const existingManagedEntry = managedStateRead.state.entries.find((entry) => normalizeExtensionNameForMatch(entry.name) ===
1316
- normalizeExtensionNameForMatch(validated.manifest.name));
1317
- const sourceUnchanged = existingManagedEntry !== undefined &&
1318
- existingManagedEntry.manifest_version === validated.manifest.version &&
1319
- managedExtensionSourcesEquivalent(existingManagedEntry.source, sourceRecord);
1320
- const managedState = upsertManagedEntry(managedStateRead.state, {
1321
- name: validated.manifest.name,
1322
- directory: destinationDirectoryName,
1323
- scope,
1324
- manifest_version: validated.manifest.version,
1325
- manifest_entry: validated.manifest.entry,
1326
- capabilities: [...validated.manifest.capabilities],
1327
- installed_at: existingManagedEntry?.installed_at ?? now,
1328
- updated_at: sourceUnchanged ? existingManagedEntry.updated_at : now,
1329
- source: sourceRecord,
1330
- });
1331
- await writeManagedExtensionState(resolvedRoots.selected_root, managedState);
1332
- const activationChanged = ensureActivated(settings, validated.manifest.name);
1333
- if (activationChanged) {
1334
- await writeSettings(resolvedRoots.settings_root, settings, "settings:write");
1335
- }
1336
- const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedState);
1337
- warnings.push(...refreshedInstalled.warnings);
1338
- const runtimeProbe = await probeRuntimeCommandPathsForInstall(resolvedRoots.pm_root, settings, refreshedInstalled.extensions, global);
1339
- warnings.push(...runtimeProbe.warnings);
1340
- // Scaffold the folders for any item types the installed package contributes
1341
- // so the tracker is immediately healthy — matching `pm schema add-type` and
1342
- // `pm profile apply`, the other paths that register a type. Without this a
1343
- // freshly-installed schema package leaves a `missing_directory` health
1344
- // warning until the first item of its type is created. Scoped to project
1345
- // installs, where `pm_root` is unambiguously the tracker the type folders
1346
- // belong to; a global install is not tied to one tracker, so its folders are
1347
- // created lazily on first use in each project.
1348
- const installedItemTypeDefinitions = runtimeProbe.item_type_registrations
1349
- .filter((entry) => normalizeExtensionNameForMatch(entry.name) ===
1350
- normalizeExtensionNameForMatch(validated.manifest.name))
1351
- .flatMap((entry) => entry.types.map((type) => ({ name: type.name, folder: type.folder })));
1352
- if (scope === "project" && installedItemTypeDefinitions.length > 0) {
1353
- await ensureTypeFolderScaffold(resolvedRoots.pm_root, installedItemTypeDefinitions, warnings, "install:type-folder");
1354
- }
1355
- const commandSummary = summarizeRuntimeCommandPathsForExtension(validated.manifest.name, runtimeProbe.installed);
1356
- const installActivationFailure = findActivationFailureByName(validated.manifest.name, runtimeProbe.activation_failures, scope);
1357
- const runtimeActivationStatus = resolveInstallRuntimeActivationStatus(validated.manifest.name, scope, runtimeProbe.installed, installActivationFailure);
1358
- const activated = !runtimeProbe.extensions_disabled && runtimeActivationStatus !== "failed";
1359
- if (!activated) {
1360
- warnings.push(`extension_install_activation_failed:${scope}:${validated.manifest.name}:${runtimeActivationStatus}`);
1361
- }
1362
- const verification = {
1363
- status: activated ? "ok" : "degraded",
1364
- target_pm_root: resolvedRoots.pm_root,
1365
- activation_status: runtimeActivationStatus,
1366
- activated,
1367
- registered_commands: commandSummary.command_paths,
1368
- registered_actions: commandSummary.action_paths,
1369
- registered_item_types: installedItemTypeDefinitions,
1370
- health: {
1371
- status: activated ? "ok" : "degraded",
1372
- blocking_failure_count: activated ? 0 : 1,
1373
- },
1374
- };
1375
- return withResult({
1376
- extension: {
1377
- name: validated.manifest.name,
1378
- version: validated.manifest.version,
1379
- entry: validated.manifest.entry,
1380
- capabilities: validated.manifest.capabilities,
1381
- directory: destinationDirectoryName,
1382
- },
1383
- source: sourceRecord,
1384
- destination_path: destinationDirectory,
1385
- overwritten: destinationExists && !installInPlace,
1386
- installed_in_place: installInPlace,
1387
- activated,
1388
- settings_changed: activationChanged,
1389
- runtime_activation_status: runtimeActivationStatus,
1390
- command_paths: commandSummary.command_paths,
1391
- action_paths: commandSummary.action_paths,
1392
- command_discovery: buildInstallCommandDiscovery(validated.manifest.name, sourceRecord, commandSummary, installActivationFailure),
1393
- verification,
1394
- activation_diagnostics: {
1395
- failed_count: runtimeProbe.activation_failures.length,
1396
- failed: runtimeProbe.activation_failures,
1397
- installed_extension_failed: installActivationFailure ?? null,
1398
- },
1399
- }, activated);
1400
- }
1401
- async function runExtensionInstallAction(ctx) {
1402
- const { action, normalizedTarget, resolvedRoots, warnings, options, global, withResult, } = ctx;
1403
- const githubOption = resolveGithubOption(options);
1404
- const explicitSourceInput = githubOption ?? requireTarget(normalizedTarget, action, options);
1405
- if (typeof githubOption !== "string" &&
1406
- isBundledPackageInstallAllTarget(explicitSourceInput)) {
1407
- if (typeof options.ref === "string" && options.ref.trim().length > 0) {
1408
- throw new PmCliError('Action "install all" does not accept --ref.', EXIT_CODE.USAGE);
1409
- }
1410
- const aliases = await listBundledPackageAliases();
1411
- const packages = [];
1412
- for (const alias of aliases) {
1413
- packages.push({
1414
- alias,
1415
- result: await runExtension(alias, { ...options, install: true }, global),
1416
- });
1417
- }
1418
- for (const entry of packages) {
1419
- warnings.push(...entry.result.warnings);
1420
- }
1421
- const installedAll = packages.every((entry) => entry.result.ok);
1422
- return withResult({
1423
- installed_all: installedAll,
1424
- installed_count: packages.filter((entry) => entry.result.ok).length,
1425
- failed_count: packages.filter((entry) => !entry.result.ok).length,
1426
- packages: packages.map((entry) => ({
1427
- alias: entry.alias,
1428
- ok: entry.result.ok,
1429
- extension: entry.result.details
1430
- .extension,
1431
- source: entry.result.details.source,
1432
- destination_path: entry.result.details.destination_path,
1433
- activated: entry.result.details
1434
- .activated,
1435
- settings_changed: entry.result.details.settings_changed,
1436
- command_paths: entry.result.details
1437
- .command_paths,
1438
- action_paths: entry.result.details
1439
- .action_paths,
1440
- command_discovery: entry.result.details.command_discovery,
1441
- verification: entry.result.details
1442
- .verification,
1443
- runtime_activation_status: entry.result.details.runtime_activation_status,
1444
- activation_diagnostics: entry.result.details.activation_diagnostics,
1445
- warnings: entry.result.warnings,
1446
- })),
1447
- }, installedAll);
1448
- }
1449
- /* c8 ignore start -- github/local alias-source split is exercised in install-action integration tests */
1450
- const bundledAliasSource = typeof githubOption === "string"
1451
- ? null
1452
- : await resolveBundledExtensionAliasSource(explicitSourceInput);
1453
- /* c8 ignore stop */
1454
- const bundledAliasName = bundledAliasSource === null
1455
- ? null
1456
- : explicitSourceInput.trim().toLowerCase();
1457
- const bundledPackageName = bundledAliasName === null
1458
- ? null
1459
- : await resolveBundledPackageNpmName(bundledAliasName);
1460
- const sourceInput = bundledAliasSource ?? explicitSourceInput;
1461
- /* c8 ignore start -- install-source branch combinations are covered in install-sources focused tests */
1462
- const installSource = parseExtensionInstallSource(sourceInput, {
1463
- forceGithub: typeof githubOption === "string",
1464
- ref: options.ref,
1465
- });
1466
- /* c8 ignore stop */
1467
- const resolvedSource = await resolveInstallSource(installSource);
1468
- try {
1469
- const validated = await validateExtensionDirectory(resolvedSource.directory);
1470
- const destinationDirectoryName = normalizeManagedDirectoryName(validated.manifest.name);
1471
- return await withExtensionInstallLock(resolvedRoots.settings_root, destinationDirectoryName, () => performExtensionInstallUnderLock(ctx, {
1472
- validated,
1473
- destinationDirectoryName,
1474
- bundledAliasName,
1475
- bundledPackageName,
1476
- installSource,
1477
- resolvedSource,
1478
- }));
1479
- }
1480
- finally {
1481
- /* c8 ignore start -- cleanup hooks are only present for transient install sources */
1482
- if (resolvedSource.cleanup) {
1483
- await resolvedSource.cleanup();
1484
- }
1485
- /* c8 ignore stop */
1486
- }
1487
- }
1488
- async function runExtensionAdoptAllAction(ctx) {
1489
- const { normalizedTarget, scope, resolvedRoots, warnings, options, withResult, } = ctx;
1490
- if (normalizedTarget !== undefined) {
1491
- throw new PmCliError('Action "adopt-all" does not accept a target argument.', EXIT_CODE.USAGE);
1492
- }
1493
- const githubOption = resolveGithubOption(options);
1494
- if (githubOption !== undefined ||
1495
- (typeof options.ref === "string" && options.ref.trim().length > 0)) {
1496
- throw new PmCliError('Action "adopt-all" does not accept --gh/--github/--ref options.', EXIT_CODE.USAGE);
1497
- }
1498
- const settings = await readSettings(resolvedRoots.settings_root);
1499
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1500
- warnings.push(...managedStateRead.warnings);
1501
- const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1502
- warnings.push(...installed.warnings);
1503
- const adoption = await adoptUnmanagedExtensions(resolvedRoots.selected_root, scope, installed.extensions, managedStateRead.state);
1504
- const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, adoption.state);
1505
- warnings.push(...refreshedInstalled.warnings);
1506
- const triage = buildExtensionTriageSummary(scope, warnings, refreshedInstalled.extensions, options);
1507
- warnings.push(...triage.warnings);
1508
- /* c8 ignore start -- refresh-entry optional metadata is display-only and exercised indirectly */
1509
- const adoptedDetails = adoption.adopted_entries.map((entry) => {
1510
- const refreshedEntry = refreshedInstalled.extensions.find((candidate) => normalizeExtensionNameForMatch(candidate.name) ===
1511
- normalizeExtensionNameForMatch(entry.name) &&
1512
- normalizeExtensionNameForMatch(candidate.directory) ===
1513
- normalizeExtensionNameForMatch(entry.directory)) ??
1514
- /* c8 ignore next 3 -- fallback only matters if a manifest renames between adopt and refresh */
1515
- refreshedInstalled.extensions.find((candidate) => normalizeExtensionNameForMatch(candidate.directory) ===
1516
- normalizeExtensionNameForMatch(entry.directory));
1517
- return {
1518
- ...entry,
1519
- update_check_status: refreshedEntry?.update_check_status ?? null,
1520
- update_check_reason: refreshedEntry?.update_check_reason ?? null,
1521
- };
1522
- });
1523
- /* c8 ignore stop */
1524
- /* c8 ignore start -- adopt-all summary booleans are deterministic mirrors of adoptedDetails length */
1525
- return withResult({
1526
- adopted_all: adoptedDetails.length > 0,
1527
- adopted_count: adoptedDetails.length,
1528
- already_managed_count: adoption.already_managed_count,
1529
- extensions: adoptedDetails,
1530
- triage,
1531
- warning_codes: triage.warning_codes,
1532
- update_health_partial: triage.update_health_partial,
1533
- update_health_coverage: triage.update_health_coverage,
1534
- });
1535
- /* c8 ignore stop */
1536
- }
1537
- async function runExtensionAdoptAction(ctx) {
1538
- const { action, normalizedTarget, scope, resolvedRoots, warnings, options, withResult, } = ctx;
1539
- const extensionTarget = requireTarget(normalizedTarget, action, options);
1540
- const githubOption = resolveGithubOption(options);
1541
- const settings = await readSettings(resolvedRoots.settings_root);
1542
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1543
- warnings.push(...managedStateRead.warnings);
1544
- const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1545
- warnings.push(...installed.warnings);
1546
- const candidate = await resolveInstalledExtensionCandidate(installed.extensions, extensionTarget);
1547
- if (!candidate) {
1548
- throw new PmCliError(`Installed extension "${extensionTarget}" was not found in ${scope} scope.`, EXIT_CODE.NOT_FOUND);
1549
- }
1550
- if (candidate.managed) {
1551
- return withResult({
1552
- adopted: false,
1553
- already_managed: true,
1554
- extension: {
1555
- name: candidate.name,
1556
- directory: candidate.directory,
1557
- },
1558
- });
1559
- }
1560
- const extensionDirectory = path.join(resolvedRoots.selected_root, candidate.directory);
1561
- const validated = await validateExtensionDirectory(extensionDirectory);
1562
- const now = nowIso();
1563
- const sourceRecord = githubOption === undefined
1564
- ? {
1565
- kind: "local",
1566
- input: extensionTarget,
1567
- location: extensionDirectory,
1568
- }
1569
- : (() => {
1570
- const parsed = parseExtensionInstallSource(githubOption, {
1571
- forceGithub: true,
1572
- ref: options.ref,
1573
- });
1574
- /* c8 ignore start -- forceGithub guarantees a github-kind install source */
1575
- if (parsed.kind !== "github") {
1576
- throw new PmCliError(`Invalid GitHub shorthand "${githubOption}".`, EXIT_CODE.USAGE);
1577
- }
1578
- /* c8 ignore stop */
1579
- /* c8 ignore start -- github subpath defaults are validated in install-source parser tests */
1580
- return {
1581
- kind: "github",
1582
- input: parsed.input,
1583
- location: parsed.subpath ?? ".",
1584
- repository: parsed.repository,
1585
- owner: parsed.owner,
1586
- repo: parsed.repo,
1587
- ref: parsed.ref,
1588
- subpath: parsed.subpath,
1589
- };
1590
- /* c8 ignore stop */
1591
- })();
1592
- const managedState = upsertManagedEntry(managedStateRead.state, {
1593
- name: validated.manifest.name,
1594
- directory: candidate.directory,
1595
- scope,
1596
- manifest_version: validated.manifest.version,
1597
- manifest_entry: validated.manifest.entry,
1598
- capabilities: [...validated.manifest.capabilities],
1599
- installed_at: now,
1600
- updated_at: now,
1601
- source: sourceRecord,
1602
- });
1603
- await writeManagedExtensionState(resolvedRoots.selected_root, managedState);
1604
- const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedState);
1605
- warnings.push(...refreshedInstalled.warnings);
1606
- /* c8 ignore start -- fallback only matters if a manifest renames between adopt and refresh */
1607
- const refreshedEntry = refreshedInstalled.extensions.find((entry) => normalizeExtensionNameForMatch(entry.name) ===
1608
- normalizeExtensionNameForMatch(validated.manifest.name)) ??
1609
- refreshedInstalled.extensions.find((entry) => normalizeExtensionNameForMatch(entry.directory) ===
1610
- normalizeExtensionNameForMatch(candidate.directory));
1611
- /* c8 ignore stop */
1612
- /* c8 ignore start -- adopt result mirrors refreshedEntry optionals for display only */
1613
- return withResult({
1614
- adopted: true,
1615
- extension: {
1616
- name: validated.manifest.name,
1617
- directory: candidate.directory,
1618
- version: validated.manifest.version,
1619
- entry: validated.manifest.entry,
1620
- },
1621
- source: sourceRecord,
1622
- update_check_status: refreshedEntry?.update_check_status ?? null,
1623
- update_check_reason: refreshedEntry?.update_check_reason ?? null,
1624
- });
1625
- /* c8 ignore stop */
1626
- }
1627
- async function resolveRequiredInstalledExtension(ctx) {
1628
- const { action, normalizedTarget, scope, resolvedRoots, warnings, options } = ctx;
1629
- const extensionTarget = requireTarget(normalizedTarget, action, options);
1630
- const settings = await readSettings(resolvedRoots.settings_root);
1631
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1632
- warnings.push(...managedStateRead.warnings);
1633
- const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1634
- warnings.push(...installed.warnings);
1635
- const candidate = await resolveInstalledExtensionCandidate(installed.extensions, extensionTarget);
1636
- if (!candidate) {
1637
- throw new PmCliError(`Installed extension "${extensionTarget}" was not found in ${scope} scope.`, EXIT_CODE.NOT_FOUND);
1638
- }
1639
- return { settings, managedStateRead, candidate };
1640
- }
1641
- async function runExtensionUninstallAction(ctx) {
1642
- const { resolvedRoots, withResult } = ctx;
1643
- const { settings, managedStateRead, candidate } = await resolveRequiredInstalledExtension(ctx);
1644
- const destinationDirectory = path.join(resolvedRoots.selected_root, candidate.directory);
1645
- await fs.rm(destinationDirectory, { recursive: true, force: true });
1646
- const updatedState = {
1647
- ...managedStateRead.state,
1648
- updated_at: nowIso(),
1649
- /* c8 ignore start -- uninstall filter keeps both name+directory guards for legacy managed-state migrations */
1650
- entries: managedStateRead.state.entries.filter((entry) => normalizeExtensionNameForMatch(entry.name) !==
1651
- normalizeExtensionNameForMatch(candidate.name) &&
1652
- normalizeExtensionNameForMatch(entry.directory) !==
1653
- normalizeExtensionNameForMatch(candidate.directory)),
1654
- /* c8 ignore stop */
1655
- };
1656
- await writeManagedExtensionState(resolvedRoots.selected_root, updatedState);
1657
- const stateChanged = clearExtensionState(settings, candidate.name);
1658
- if (stateChanged) {
1659
- await writeSettings(resolvedRoots.settings_root, settings, "settings:write");
1660
- }
1661
- return withResult({
1662
- removed: true,
1663
- extension: {
1664
- name: candidate.name,
1665
- directory: candidate.directory,
1666
- },
1667
- destination_path: destinationDirectory,
1668
- settings_changed: stateChanged,
1669
- });
1670
- }
1671
- async function runExtensionActivateDeactivateAction(ctx) {
1672
- const { action, resolvedRoots, withResult } = ctx;
1673
- const { settings, candidate } = await resolveRequiredInstalledExtension(ctx);
1674
- const settingsChanged = action === "activate"
1675
- ? ensureActivated(settings, candidate.name)
1676
- : ensureDeactivated(settings, candidate.name);
1677
- if (settingsChanged) {
1678
- await writeSettings(resolvedRoots.settings_root, settings, "settings:write");
1679
- }
1680
- return withResult({
1681
- extension: {
1682
- name: candidate.name,
1683
- directory: candidate.directory,
1684
- },
1685
- active: action === "activate",
1686
- settings_changed: settingsChanged,
1687
- settings: {
1688
- enabled: [...settings.extensions.enabled],
1689
- disabled: [...settings.extensions.disabled],
1690
- },
1691
- });
1692
- }
1693
- /** Assemble the doctor remediation hints: the triage remediations, vocabulary-aware advice to inspect load failures and activation failures, and a note when a managed-state fix adopted entries. Blank entries are trimmed and the list is de-duplicated. */
1694
- function buildDoctorRemediation(baseRemediation, loadFailureCount, activationFailureCount, vocabulary, managedStateFix, isolationHint) {
1695
- return [
1696
- ...new Set([
1697
- ...baseRemediation,
1698
- ...(isolationHint === null ? [] : [isolationHint]),
1699
- /* c8 ignore start -- vocabulary-specific remediation branches are copy-only variants */
1700
- ...(loadFailureCount > 0
1701
- ? [
1702
- vocabulary === "package"
1703
- ? "Run pm package explore --project and pm package explore --global to inspect load failures."
1704
- : "Run pm extension --explore --project and pm extension --explore --global to inspect load failures.",
1705
- ]
1706
- : []),
1707
- ...(activationFailureCount > 0
1708
- ? [
1709
- vocabulary === "package"
1710
- ? "Review activation failures in pm package doctor --detail deep output."
1711
- : "Review activation failures in pm extension --doctor --detail deep output.",
1712
- ]
1713
- : []),
1714
- /* c8 ignore stop */
1715
- ...(managedStateFix && managedStateFix.adopted_entries.length > 0
1716
- ? [
1717
- `Managed-state fix adopted ${managedStateFix.adopted_entries.length} extension(s).`,
1718
- ]
1719
- : []),
1720
- ]
1721
- .map((entry) => entry.trim())
1722
- .filter((entry) => entry.length > 0)),
1723
- ];
1724
- }
1725
- function hasGlobalLayerDiagnostics(loadResult) {
1726
- return (loadResult.loaded.some((entry) => entry.layer === "global") ||
1727
- loadResult.failed.some((entry) => entry.layer === "global") ||
1728
- loadResult.warnings.some((warning) => warning.includes(":global:")));
1729
- }
1730
- function buildDoctorIsolationHint(scope, isolated, vocabulary, loadResult) {
1731
- if (scope !== "project" ||
1732
- isolated ||
1733
- !hasGlobalLayerDiagnostics(loadResult)) {
1734
- return null;
1735
- }
1736
- const noun = vocabulary === "package" ? "package" : "extension";
1737
- return (`Global ${noun} registrations are included in project diagnostics. ` +
1738
- `For hermetic ${noun} smoke tests, rerun pm ${noun} doctor --project --isolated --detail deep --trace, ` +
1739
- "or set PM_GLOBAL_PATH to a temporary directory for the whole test process.");
1740
- }
1741
- /** Build the doctor isolation block shared by summary and details output so the over-the-wire payload stays identical for extension and package vocabulary. */
1742
- function buildDoctorIsolationMetadata(scope, isolated, vocabulary, loadResult) {
1743
- const noun = vocabulary === "package" ? "package" : "extension";
1744
- if (scope !== "project") {
1745
- return {
1746
- isolated,
1747
- global_extensions_included: false,
1748
- global_diagnostics_present: hasGlobalLayerDiagnostics(loadResult),
1749
- rerun_command: null,
1750
- pm_global_path_recipe: null,
1751
- };
1752
- }
1753
- const isolatedCommand = `pm ${noun} doctor --project --isolated --detail deep --trace`;
1754
- return {
1755
- isolated,
1756
- global_extensions_included: !isolated,
1757
- global_diagnostics_present: hasGlobalLayerDiagnostics(loadResult),
1758
- rerun_command: isolated ? null : isolatedCommand,
1759
- pm_global_path_recipe: `PM_GLOBAL_PATH=$(mktemp -d) pm ${noun} doctor --project --detail deep --trace`,
1760
- };
1761
- }
1762
- async function runExtensionDoctorAction(ctx) {
1763
- const { normalizedTarget, scope, resolvedRoots, warnings, options, global, withResult, } = ctx;
1764
- if (normalizedTarget && normalizedTarget.trim().length > 0) {
1765
- throw new PmCliError('Action "doctor" does not accept a target argument.', EXIT_CODE.USAGE);
1766
- }
1767
- const isolated = options.isolated === true || options.ignoreGlobal === true;
1768
- if (isolated && scope === "global") {
1769
- throw new PmCliError("--isolated and --ignore-global are only valid with project-scope doctor diagnostics.", EXIT_CODE.USAGE);
1770
- }
1771
- const detailMode = parseDoctorDetailMode(options.detail);
1772
- const includeTrace = options.trace === true;
1773
- if (includeTrace && detailMode !== "deep") {
1774
- throw new PmCliError("--trace requires --detail deep with --doctor.", EXIT_CODE.USAGE);
1775
- }
1776
- const settings = await readSettings(resolvedRoots.settings_root);
1777
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
1778
- warnings.push(...managedStateRead.warnings);
1779
- const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
1780
- warnings.push(...installed.warnings);
1781
- let managedState = managedStateRead.state;
1782
- const managedStateFix = options.fixManagedState === true
1783
- ? await adoptUnmanagedExtensions(resolvedRoots.selected_root, scope, installed.extensions, managedStateRead.state)
1784
- : null;
1785
- if (managedStateFix) {
1786
- managedState = managedStateFix.state;
1787
- }
1788
- const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedState);
1789
- warnings.push(...refreshedInstalled.warnings);
1790
- const loadResult = await loadExtensions({
1791
- pmRoot: resolvedRoots.pm_root,
1792
- settings,
1793
- cwd: process.cwd(),
1794
- noExtensions: global.noExtensions === true,
1795
- ignoreGlobalExtensions: isolated,
1796
- });
1797
- const activationResult = await activateExtensions({
1798
- ...loadResult,
1799
- loaded: loadResult.loaded,
1800
- });
1801
- warnings.push(...loadResult.warnings);
1802
- warnings.push(...classifyDoctorLoadFailureWarnings(loadResult.failed));
1803
- warnings.push(...activationResult.warnings);
1804
- warnings.push(...classifyDoctorActivationFailureWarnings(activationResult.failed));
1805
- warnings.push(...classifyUnusedCapabilityWarnings(loadResult, activationResult));
1806
- warnings.push(...collectGlobalOutputOverrideDoctorWarnings(activationResult));
1807
- warnings.push(...collectSchemaNarrowActivationDoctorWarnings(loadResult, activationResult));
1808
- const runtimeInstalledExtensions = applyDoctorRuntimeActivationState(refreshedInstalled.extensions, loadResult, activationResult);
1809
- const doctorConsistency = buildDoctorConsistencySummary(scope, runtimeInstalledExtensions, loadResult.loaded.map((entry) => ({
1810
- layer: entry.layer,
1811
- name: entry.name,
1812
- })), loadResult.failed.map((entry) => ({ name: entry.name })), loadResult.disabled_by_flag);
1813
- warnings.push(...doctorConsistency.warnings);
1814
- const updateCheckWarnings = runtimeInstalledExtensions
1815
- .filter((entry) => entry.update_check_status === "failed")
1816
- .map((entry) => `extension_update_check_failed:${entry.name}`);
1817
- warnings.push(...updateCheckWarnings);
1818
- const triage = buildExtensionTriageSummary(scope, warnings, runtimeInstalledExtensions, options);
1819
- warnings.push(...triage.warnings);
1820
- const normalizedWarnings = [...triage.warnings];
1821
- const policySummary = {
1822
- mode: loadResult.policy.mode,
1823
- trust_mode: loadResult.policy.trust_mode,
1824
- require_provenance: loadResult.policy.require_provenance,
1825
- default_sandbox_profile: loadResult.policy.default_sandbox_profile,
1826
- // Honest trust model (ADR pm-6ef3): keep this caveat to one concise line.
1827
- sandbox_enforcement: "advisory: sandbox_profile/permissions are declaration-based load gates, not runtime isolation (ADR pm-6ef3)",
1828
- trusted_extensions_count: loadResult.policy.trusted_extensions.length,
1829
- allowed_extensions_count: loadResult.policy.allowed_extensions.length,
1830
- blocked_extensions_count: loadResult.policy.blocked_extensions.length,
1831
- allowed_capabilities_count: loadResult.policy.allowed_capabilities.length,
1832
- blocked_capabilities_count: loadResult.policy.blocked_capabilities.length,
1833
- allowed_surfaces_count: loadResult.policy.allowed_surfaces.length,
1834
- blocked_surfaces_count: loadResult.policy.blocked_surfaces.length,
1835
- allowed_commands_count: loadResult.policy.allowed_commands.length,
1836
- blocked_commands_count: loadResult.policy.blocked_commands.length,
1837
- allowed_actions_count: loadResult.policy.allowed_actions.length,
1838
- blocked_actions_count: loadResult.policy.blocked_actions.length,
1839
- allowed_services_count: loadResult.policy.allowed_services.length,
1840
- blocked_services_count: loadResult.policy.blocked_services.length,
1841
- extension_override_count: loadResult.policy.extension_overrides.length,
1842
- };
1843
- const capabilityGuidance = collectUnknownCapabilityGuidance(normalizedWarnings);
1844
- const capabilityContract = buildCapabilityContractMetadata();
1845
- const warningCodes = triage.warning_codes;
1846
- const isolationHint = buildDoctorIsolationHint(scope, isolated, options.vocabulary, loadResult);
1847
- const remediation = buildDoctorRemediation(triage.remediation, loadResult.failed.length, activationResult.failed.length, options.vocabulary, managedStateFix, isolationHint);
1848
- const isolation = buildDoctorIsolationMetadata(scope, isolated, options.vocabulary, loadResult);
1849
- const summary = {
1850
- status: triage.status,
1851
- scope,
1852
- warning_count: triage.warning_count,
1853
- warning_codes: warningCodes,
1854
- total_extensions: runtimeInstalledExtensions.length,
1855
- managed_total: runtimeInstalledExtensions.filter((entry) => entry.managed)
1856
- .length,
1857
- enabled_total: runtimeInstalledExtensions.filter((entry) => entry.enabled)
1858
- .length,
1859
- active_total: runtimeInstalledExtensions.filter((entry) => entry.active)
1860
- .length,
1861
- unmanaged_loaded_extension_count: triage.unmanaged_loaded_extension_count,
1862
- unmanaged_action_required_extension_count: triage.unmanaged_action_required_extension_count,
1863
- unmanaged_expected_extension_count: triage.unmanaged_expected_extension_count,
1864
- runtime_active_total: runtimeInstalledExtensions.filter((entry) => entry.runtime_active === true).length,
1865
- activation_status_totals: {
1866
- ok: runtimeInstalledExtensions.filter((entry) => entry.activation_status === "ok").length,
1867
- failed: runtimeInstalledExtensions.filter((entry) => entry.activation_status === "failed").length,
1868
- not_loaded: runtimeInstalledExtensions.filter((entry) => entry.activation_status === "not_loaded").length,
1869
- unknown: runtimeInstalledExtensions.filter((entry) => entry.activation_status === "unknown").length,
1870
- },
1871
- unknown_capability_count: capabilityGuidance.length,
1872
- capability_contract_version: capabilityContract.version,
1873
- update_available_total: runtimeInstalledExtensions.filter((entry) => entry.update_available === true).length,
1874
- update_health_coverage: triage.update_health_coverage,
1875
- update_health_partial: triage.update_health_partial,
1876
- update_check_failed_total: runtimeInstalledExtensions.filter((entry) => entry.update_check_status === "failed").length,
1877
- load_failure_count: loadResult.failed.length,
1878
- activation_failure_count: activationResult.failed.length,
1879
- blocking_failure_count: loadResult.failed.length + activationResult.failed.length,
1880
- has_blocking_failures: loadResult.failed.length + activationResult.failed.length > 0,
1881
- consistency_warning_count: doctorConsistency.warnings.length,
1882
- trace_enabled: includeTrace,
1883
- isolation,
1884
- policy: policySummary,
1885
- remediation,
1886
- };
1887
- const managedStateFixSummary = managedStateFix
1888
- ? {
1889
- requested: true,
1890
- applied: managedStateFix.adopted_entries.length > 0,
1891
- adopted_count: managedStateFix.adopted_entries.length,
1892
- already_managed_count: managedStateFix.already_managed_count,
1893
- adopted_extensions: managedStateFix.adopted_entries.map((entry) => entry.name),
1894
- }
1895
- : {
1896
- requested: false,
1897
- applied: false,
1898
- adopted_count: 0,
1899
- already_managed_count: refreshedInstalled.extensions.filter((entry) => entry.managed).length,
1900
- adopted_extensions: [],
1901
- };
1902
- const details = {
1903
- mode: detailMode,
1904
- summary,
1905
- triage,
1906
- trace_enabled: includeTrace,
1907
- capability_contract: capabilityContract,
1908
- capability_guidance: capabilityGuidance,
1909
- managed_state_fix: managedStateFixSummary,
1910
- isolation,
1911
- policy: loadResult.policy,
1912
- };
1913
- if (detailMode === "deep") {
1914
- const activationFailedDetails = includeTrace
1915
- ? activationResult.failed
1916
- : activationResult.failed.map((entry) => {
1917
- const { trace: _trace, ...rest } = entry;
1918
- return rest;
1919
- });
1920
- details.deep = {
1921
- warnings: normalizedWarnings,
1922
- warning_codes: warningCodes,
1923
- capability_contract: capabilityContract,
1924
- capability_guidance: capabilityGuidance,
1925
- trace_enabled: includeTrace,
1926
- managed_state: {
1927
- path: managedStateRead.path,
1928
- count: managedState.entries.length,
1929
- entries: managedState.entries,
1930
- },
1931
- installed_extensions: runtimeInstalledExtensions,
1932
- load: {
1933
- roots: loadResult.roots,
1934
- policy: loadResult.policy,
1935
- warnings: loadResult.warnings,
1936
- failed: loadResult.failed,
1937
- loaded: loadResult.loaded.map((entry) => ({
1938
- layer: entry.layer,
1939
- directory: entry.directory,
1940
- name: entry.name,
1941
- version: entry.version,
1942
- entry: entry.entry,
1943
- priority: entry.priority,
1944
- })),
1945
- },
1946
- activation: {
1947
- failed: activationFailedDetails,
1948
- warnings: activationResult.warnings,
1949
- hook_counts: activationResult.hook_counts,
1950
- registration_counts: activationResult.registration_counts,
1951
- parser_override_count: activationResult.parser_override_count,
1952
- preflight_override_count: activationResult.preflight_override_count,
1953
- service_override_count: activationResult.service_override_count,
1954
- renderer_override_count: activationResult.renderer_override_count,
1955
- },
1956
- consistency: doctorConsistency.summary,
1957
- };
1958
- if (includeTrace) {
1959
- details.deep.trace = {
1960
- activation_failures: activationResult.failed
1961
- .filter((entry) => entry.trace !== undefined)
1962
- .map((entry) => ({
1963
- layer: entry.layer,
1964
- name: entry.name,
1965
- entry_path: entry.entry_path,
1966
- error: entry.error,
1967
- method: entry.trace?.method,
1968
- command: entry.trace?.command,
1969
- capability: entry.trace?.capability,
1970
- missing_capability: entry.trace?.missing_capability,
1971
- registration_index: entry.trace?.registration_index,
1972
- expected_schema: entry.trace?.expected_schema,
1973
- hint: entry.trace?.hint,
1974
- received: entry.trace?.received,
1975
- })),
1976
- };
1977
- }
1978
- }
1979
- return withResult(details);
1980
- }
1981
- async function runExtensionDescribeAction(ctx) {
1982
- const { normalizedTarget, scope, resolvedRoots, warnings, options, global, withResult, } = ctx;
1983
- const settings = await readSettings(resolvedRoots.settings_root);
1984
- const loadResult = await loadExtensions({
1985
- pmRoot: resolvedRoots.pm_root,
1986
- settings,
1987
- cwd: process.cwd(),
1988
- noExtensions: global.noExtensions === true,
1989
- });
1990
- const activationResult = await activateExtensions(loadResult);
1991
- warnings.push(...loadResult.warnings);
1992
- warnings.push(...activationResult.warnings);
1993
- const describeResult = buildExtensionDescribeResult(normalizedTarget, loadResult, activationResult);
1994
- if (normalizedTarget !== undefined &&
1995
- describeResult.extensions.length === 0) {
1996
- const noun = options.vocabulary === "package" ? "package" : "extension";
1997
- const loadedNames = [
1998
- ...new Set(loadResult.loaded.map((entry) => options.vocabulary === "package" &&
1999
- typeof entry.source_package === "string" &&
2000
- entry.source_package.trim().length > 0
2001
- ? entry.source_package.trim()
2002
- : entry.name)),
2003
- ].sort((left, right) => left.localeCompare(right));
2004
- const loadedHint = loadedNames.length > 0
2005
- ? ` Loaded ${noun} names: ${loadedNames.join(", ")}.`
2006
- : "";
2007
- throw new PmCliError(`No loaded ${noun} named "${normalizedTarget}" was found in ${scope} scope.${loadedHint} Run pm ${noun} explore to list discovered ${noun}s.`, EXIT_CODE.NOT_FOUND);
2008
- }
2009
- return withResult({
2010
- target: describeResult.target,
2011
- total: describeResult.total,
2012
- extensions: describeResult.extensions,
2013
- union: describeResult.union,
2014
- });
2015
- }
2016
- /* c8 ignore start -- explore/manage action split is validated by dedicated command-action tests */
2017
- async function runExtensionExploreManageAction(ctx) {
2018
- const { action, scope, resolvedRoots, warnings, options, global, withResult, } = ctx;
2019
- const settings = await readSettings(resolvedRoots.settings_root);
2020
- const configuredPolicy = buildExtensionPolicyDetails(settings.extensions.policy);
2021
- const managedStateRead = await readManagedExtensionState(resolvedRoots.selected_root);
2022
- warnings.push(...managedStateRead.warnings);
2023
- const installed = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedStateRead.state);
2024
- warnings.push(...installed.warnings);
2025
- let managedState = managedStateRead.state;
2026
- const managedStateFix = action === "manage" && options.fixManagedState === true
2027
- ? await adoptUnmanagedExtensions(resolvedRoots.selected_root, scope, installed.extensions, managedStateRead.state)
2028
- : null;
2029
- if (managedStateFix) {
2030
- managedState = managedStateFix.state;
2031
- }
2032
- if (action === "manage") {
2033
- const updates = await Promise.all(managedState.entries.map(async (entry) => {
2034
- if (entry.source.kind !== "github") {
2035
- return entry;
2036
- }
2037
- const updateStatus = await checkGithubUpdate(entry.source);
2038
- return {
2039
- ...entry,
2040
- last_update_check_at: updateStatus.checked_at,
2041
- last_update_remote_commit: updateStatus.remote_commit,
2042
- update_available: updateStatus.available,
2043
- update_error: updateStatus.error,
2044
- };
2045
- }));
2046
- managedState = {
2047
- ...managedState,
2048
- updated_at: nowIso(),
2049
- entries: sortManagedEntries(updates),
2050
- };
2051
- await writeManagedExtensionState(resolvedRoots.selected_root, managedState);
2052
- }
2053
- const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, managedState);
2054
- warnings.push(...refreshedInstalled.warnings);
2055
- if (action === "manage") {
2056
- const updateWarnings = refreshedInstalled.extensions
2057
- .filter((entry) => entry.update_check_status === "failed")
2058
- .map((entry) => `extension_update_check_failed:${entry.name}`);
2059
- warnings.push(...updateWarnings);
2060
- }
2061
- let runtimeProbeSummary;
2062
- let runtimeInstalledExtensions = refreshedInstalled.extensions;
2063
- let runtimeActivationFailures;
2064
- if (action === "explore" || options.runtimeProbe === true) {
2065
- const loadResult = await loadExtensions({
2066
- pmRoot: resolvedRoots.pm_root,
2067
- settings,
2068
- cwd: process.cwd(),
2069
- noExtensions: global.noExtensions === true,
2070
- });
2071
- const activationResult = await activateExtensions({
2072
- ...loadResult,
2073
- loaded: loadResult.loaded,
2074
- });
2075
- warnings.push(...loadResult.warnings);
2076
- warnings.push(...activationResult.warnings);
2077
- runtimeInstalledExtensions = applyDoctorRuntimeActivationState(refreshedInstalled.extensions, loadResult, activationResult);
2078
- runtimeActivationFailures = collectActivationFailureDiagnostics(activationResult.failed);
2079
- runtimeProbeSummary = {
2080
- requested: true,
2081
- executed: true,
2082
- reason: action === "explore"
2083
- ? "explore_defaults_to_runtime_probe"
2084
- : "runtime_probe_requested",
2085
- load_failure_count: loadResult.failed.length,
2086
- activation_failure_count: activationResult.failed.length,
2087
- warning_count: [
2088
- ...new Set([...loadResult.warnings, ...activationResult.warnings]),
2089
- ].length,
2090
- policy: loadResult.policy,
2091
- };
2092
- }
2093
- else if (action === "manage") {
2094
- runtimeProbeSummary = {
2095
- requested: false,
2096
- executed: false,
2097
- };
2098
- }
2099
- const triage = buildExtensionTriageSummary(scope, warnings, runtimeInstalledExtensions, options);
2100
- warnings.push(...triage.warnings);
2101
- const details = {
2102
- total: runtimeInstalledExtensions.length,
2103
- managed_total: runtimeInstalledExtensions.filter((entry) => entry.managed)
2104
- .length,
2105
- enabled_total: runtimeInstalledExtensions.filter((entry) => entry.enabled)
2106
- .length,
2107
- active_total: runtimeInstalledExtensions.filter((entry) => entry.active)
2108
- .length,
2109
- extensions: runtimeInstalledExtensions,
2110
- triage,
2111
- policy: configuredPolicy,
2112
- };
2113
- if (runtimeActivationFailures !== undefined) {
2114
- details.activation_diagnostics = {
2115
- failed_count: runtimeActivationFailures.length,
2116
- failed: runtimeActivationFailures,
2117
- };
2118
- }
2119
- if (action === "explore") {
2120
- details.runtime_probe = runtimeProbeSummary;
2121
- }
2122
- if (action === "manage") {
2123
- details.runtime_probe = runtimeProbeSummary;
2124
- details.managed_state_fix =
2125
- managedStateFix !== null
2126
- ? {
2127
- requested: true,
2128
- applied: managedStateFix.adopted_entries.length > 0,
2129
- adopted_count: managedStateFix.adopted_entries.length,
2130
- adopted_extensions: managedStateFix.adopted_entries.map((entry) => entry.name),
2131
- already_managed_count: managedStateFix.already_managed_count,
2132
- }
2133
- : {
2134
- requested: false,
2135
- applied: false,
2136
- adopted_count: 0,
2137
- adopted_extensions: [],
2138
- already_managed_count: runtimeInstalledExtensions.filter((entry) => entry.managed).length,
2139
- };
2140
- }
2141
- return withResult(details);
2142
- }
2143
- /* c8 ignore stop */
2144
- // Dispatch table from lifecycle action to its handler. `explore`/`manage` and
2145
- // `activate`/`deactivate` share a handler that branches on `ctx.action`; the
2146
- // closed ExtensionCommandAction union guarantees every action has an entry, so
2147
- // runExtension needs no unsupported-action fallthrough.
2148
- const EXTENSION_ACTION_HANDLERS = {
2149
- init: runExtensionInitAction,
2150
- install: runExtensionInstallAction,
2151
- uninstall: runExtensionUninstallAction,
2152
- explore: runExtensionExploreManageAction,
2153
- manage: runExtensionExploreManageAction,
2154
- describe: runExtensionDescribeAction,
2155
- reload: runExtensionReloadAction,
2156
- doctor: runExtensionDoctorAction,
2157
- catalog: runExtensionCatalogAction,
2158
- adopt: runExtensionAdoptAction,
2159
- "adopt-all": runExtensionAdoptAllAction,
2160
- activate: runExtensionActivateDeactivateAction,
2161
- deactivate: runExtensionActivateDeactivateAction,
2162
- };
2163
- /** Public contract for test only, shared by SDK and presentation-layer consumers. */
2164
- export const _testOnly = {
2165
- adoptUnmanagedExtensions,
2166
- buildExtensionPolicyDetails,
2167
- buildInstallCommandDiscovery,
2168
- checkGithubUpdate,
2169
- clearExtensionState,
2170
- collectActivationFailureDiagnostics,
2171
- findActivationFailureByName,
2172
- resolveInstallRuntimeActivationStatus,
2173
- collectGlobalOutputOverrideDoctorWarnings,
2174
- collectSchemaNarrowActivationDoctorWarnings,
2175
- copyExtensionDirectoryWithoutSelfNesting,
2176
- isErrnoCode,
2177
- isRetriableExtensionInstallCopyError,
2178
- listInstalledExtensions,
2179
- requireTarget,
2180
- resolveAction,
2181
- resolveCommandDiscoveryPackageName,
2182
- resolveGithubOption,
2183
- resolveInstalledExtensionCandidate,
2184
- resolveScope,
2185
- resolveUpdateCheckResolution,
2186
- withExtensionInstallLock,
2187
- };
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]="3594d81d-d502-5f4e-bdf0-ef81a6a3cf91")}catch(e){}}();
8
+ export * from "../../sdk/extension.js";
2188
9
  //# sourceMappingURL=extension.js.map
2189
- //# debugId=17d000c7-b19f-540c-9600-65416d2ca11b
10
+ //# debugId=3594d81d-d502-5f4e-bdf0-ef81a6a3cf91