@unbrained/pm-cli 2026.8.4 → 2026.8.6

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 (253) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +53 -13
  3. package/dist/cli/error-guidance.js +4 -4
  4. package/dist/cli/main.js +12 -37
  5. package/dist/cli/register-setup.d.ts +1 -1
  6. package/dist/cli/register-setup.js +46 -20
  7. package/dist/cli/register-structured-mutation.d.ts +2 -0
  8. package/dist/cli/register-structured-mutation.js +124 -12
  9. package/dist/cli-bundle/bundle-manifest.json +397 -397
  10. package/dist/cli-bundle/chunks/append-XAJ5Z4XS.js +2 -0
  11. package/dist/cli-bundle/chunks/{chunk-QVO3VTA4.js → chunk-343QETLI.js} +2 -2
  12. package/dist/cli-bundle/chunks/{chunk-Q5F6OI7C.js → chunk-3KFVGGRE.js} +2 -2
  13. package/dist/cli-bundle/chunks/{chunk-6S7I3UKV.js → chunk-3ZJRFYY2.js} +19 -19
  14. package/dist/cli-bundle/chunks/{chunk-NFF3JAQR.js → chunk-4AVFKHHC.js} +2 -2
  15. package/dist/cli-bundle/chunks/{chunk-5H47J5FG.js → chunk-4OVGQW22.js} +2 -2
  16. package/dist/cli-bundle/chunks/{chunk-D2MBVMVE.js → chunk-5PBP2ZP3.js} +2 -2
  17. package/dist/cli-bundle/chunks/chunk-5ZKQPA44.js +2 -0
  18. package/dist/cli-bundle/chunks/chunk-A3XQ7VPU.js +2 -0
  19. package/dist/cli-bundle/chunks/chunk-AJE3AHPD.js +8 -0
  20. package/dist/cli-bundle/chunks/{chunk-2POYGY53.js → chunk-AOBDLU4T.js} +2 -2
  21. package/dist/cli-bundle/chunks/{chunk-PYYPQLHC.js → chunk-AYRUGRNS.js} +2 -2
  22. package/dist/cli-bundle/chunks/{chunk-QMWUL66F.js → chunk-BP6EMEDP.js} +5 -5
  23. package/dist/cli-bundle/chunks/{chunk-UVZREFZU.js → chunk-C3YABSJK.js} +2 -2
  24. package/dist/cli-bundle/chunks/{chunk-RB65T4RX.js → chunk-CA3BURYF.js} +2 -2
  25. package/dist/cli-bundle/chunks/{chunk-KIKLF2W4.js → chunk-D7I3TUGV.js} +2 -2
  26. package/dist/cli-bundle/chunks/{chunk-PQXEB7W4.js → chunk-DQGJ2RWT.js} +2 -2
  27. package/dist/cli-bundle/chunks/{chunk-OB7TRZ2G.js → chunk-DWOAOZHZ.js} +2 -2
  28. package/dist/cli-bundle/chunks/{chunk-SVDH5CHC.js → chunk-E7BFPLUZ.js} +4 -4
  29. package/dist/cli-bundle/chunks/{chunk-CGY5I2GO.js → chunk-F4NREH3G.js} +2 -2
  30. package/dist/cli-bundle/chunks/{chunk-DCJ6CM6F.js → chunk-FDBRXV25.js} +2 -2
  31. package/dist/cli-bundle/chunks/{chunk-NM5G7RLU.js → chunk-GU3TSEHD.js} +2 -2
  32. package/dist/cli-bundle/chunks/chunk-HS7OVAUN.js +164 -0
  33. package/dist/cli-bundle/chunks/{chunk-CU5ENFNP.js → chunk-JFZIS6JF.js} +2 -2
  34. package/dist/cli-bundle/chunks/{chunk-GOICHIX4.js → chunk-JQ4NZ5EB.js} +2 -2
  35. package/dist/cli-bundle/chunks/{chunk-HE3DZFN4.js → chunk-L6LGKJX3.js} +2 -2
  36. package/dist/cli-bundle/chunks/{chunk-BLINBTMX.js → chunk-M357ZCOR.js} +2 -2
  37. package/dist/cli-bundle/chunks/{chunk-NRDKVOUE.js → chunk-M4VEE3FK.js} +2 -2
  38. package/dist/cli-bundle/chunks/{chunk-HTYC76A4.js → chunk-MCS73BKB.js} +2 -2
  39. package/dist/cli-bundle/chunks/{chunk-BKMZTZYL.js → chunk-MDTH7SAE.js} +2 -2
  40. package/dist/cli-bundle/chunks/{chunk-H6FITE7D.js → chunk-NE5VRDAI.js} +2 -2
  41. package/dist/cli-bundle/chunks/{chunk-NPUJ7OLK.js → chunk-OXY3SJ3N.js} +2 -2
  42. package/dist/cli-bundle/chunks/chunk-PECV7L5T.js +2 -0
  43. package/dist/cli-bundle/chunks/{chunk-KH4GVBMC.js → chunk-Q3VOP62W.js} +2 -2
  44. package/dist/cli-bundle/chunks/{chunk-FQ4EFFDU.js → chunk-QJ7C3JIW.js} +2 -2
  45. package/dist/cli-bundle/chunks/{chunk-VH2EAGUG.js → chunk-R6LSRGPS.js} +2 -2
  46. package/dist/cli-bundle/chunks/{chunk-HQ2WU7OY.js → chunk-R6RKEYYW.js} +2 -2
  47. package/dist/cli-bundle/chunks/{chunk-PA5XRN2A.js → chunk-RAFUN7IX.js} +4 -4
  48. package/dist/cli-bundle/chunks/chunk-RUAU5OSH.js +2 -0
  49. package/dist/cli-bundle/chunks/chunk-SD3YXU2U.js +56 -0
  50. package/dist/cli-bundle/chunks/{chunk-JMKVCQSE.js → chunk-SV3YQ4RY.js} +2 -2
  51. package/dist/cli-bundle/chunks/{chunk-B5ZLCD5Z.js → chunk-SVV3DQES.js} +2 -2
  52. package/dist/cli-bundle/chunks/{chunk-J4EPW4GT.js → chunk-SXECIECW.js} +2 -2
  53. package/dist/cli-bundle/chunks/chunk-T45OHXDW.js +8 -0
  54. package/dist/cli-bundle/chunks/{chunk-NH35JNK5.js → chunk-TPKDJ5WL.js} +2 -2
  55. package/dist/cli-bundle/chunks/{chunk-ZSH4GNBH.js → chunk-UVVXHGYS.js} +2 -2
  56. package/dist/cli-bundle/chunks/chunk-V663653R.js +20 -0
  57. package/dist/cli-bundle/chunks/{chunk-5PZGZMPG.js → chunk-WSI5KZQJ.js} +2 -2
  58. package/dist/cli-bundle/chunks/{chunk-3XZYTRPC.js → chunk-XPOQQJTX.js} +2 -2
  59. package/dist/cli-bundle/chunks/{chunk-UJHUR3LZ.js → chunk-YCCDXBNU.js} +2 -2
  60. package/dist/cli-bundle/chunks/chunk-ZFBWCKYF.js +2 -0
  61. package/dist/cli-bundle/chunks/close-DI66JMSB.js +2 -0
  62. package/dist/cli-bundle/chunks/close-many-VFKT6U3O.js +2 -0
  63. package/dist/cli-bundle/chunks/comments-E73HIEZJ.js +2 -0
  64. package/dist/cli-bundle/chunks/copy-WBYVLCPC.js +2 -0
  65. package/dist/cli-bundle/chunks/{create-RLLCBCXM.js → create-TG67IVFI.js} +2 -2
  66. package/dist/cli-bundle/chunks/delete-6XKUVVQN.js +2 -0
  67. package/dist/cli-bundle/chunks/{deps-J4ONTF4X.js → deps-AJUGP2OH.js} +2 -2
  68. package/dist/cli-bundle/chunks/{docs-YL2DJ4WD.js → docs-QOCLDRKJ.js} +2 -2
  69. package/dist/cli-bundle/chunks/{files-NGNAIYKK.js → files-3ST5TY64.js} +2 -2
  70. package/dist/cli-bundle/chunks/focus-R2AWS63Y.js +2 -0
  71. package/dist/cli-bundle/chunks/{history-compact-HW62K5XP.js → history-compact-7BJFML4S.js} +2 -2
  72. package/dist/cli-bundle/chunks/{history-redact-HVBKUJOW.js → history-redact-WJN3HYXR.js} +2 -2
  73. package/dist/cli-bundle/chunks/{history-repair-OPNBH5JJ.js → history-repair-XDNZUB7F.js} +2 -2
  74. package/dist/cli-bundle/chunks/{learnings-F36PZXT6.js → learnings-SZMUPVNA.js} +2 -2
  75. package/dist/cli-bundle/chunks/{profile-N3XMWBM7.js → profile-KL53JIAC.js} +2 -2
  76. package/dist/cli-bundle/chunks/{register-list-query-BKGHBI7Y.js → register-list-query-QH7ONPKU.js} +2 -2
  77. package/dist/cli-bundle/chunks/register-mutation-OCRQNZK4.js +20 -0
  78. package/dist/cli-bundle/chunks/register-operations-HIBJXRGB.js +2 -0
  79. package/dist/cli-bundle/chunks/register-setup-QWBQ6HBS.js +2 -0
  80. package/dist/cli-bundle/chunks/restore-FXA5QPM7.js +2 -0
  81. package/dist/cli-bundle/chunks/{schema-4PJQMGUY.js → schema-QJ27OTRV.js} +2 -2
  82. package/dist/cli-bundle/chunks/update-7GBO4SXG.js +2 -0
  83. package/dist/cli-bundle/chunks/update-many-VF6ZKQUO.js +2 -0
  84. package/dist/cli-bundle/focused-chunks/chunk-27DK4A5O.js +2 -0
  85. package/dist/cli-bundle/focused-chunks/chunk-4JC3AOGS.js +8 -0
  86. package/dist/cli-bundle/focused-chunks/chunk-6KDHXURF.js +2 -0
  87. package/dist/cli-bundle/focused-chunks/chunk-74CWP3A4.js +2 -0
  88. package/dist/cli-bundle/focused-chunks/chunk-7AZDTGPA.js +2 -0
  89. package/dist/cli-bundle/focused-chunks/chunk-7YTZ7A4E.js +2 -0
  90. package/dist/cli-bundle/focused-chunks/{chunk-ONIX2KKW.js → chunk-CL3NB7VW.js} +2 -2
  91. package/dist/cli-bundle/focused-chunks/chunk-EAXXF2HW.js +4 -0
  92. package/dist/cli-bundle/focused-chunks/{chunk-L6A4NVQC.js → chunk-EYO4F74Z.js} +2 -2
  93. package/dist/cli-bundle/focused-chunks/chunk-GEYU23YS.js +153 -0
  94. package/dist/cli-bundle/focused-chunks/{chunk-DQ4PLKEE.js → chunk-GIERI4YU.js} +2 -2
  95. package/dist/cli-bundle/focused-chunks/chunk-GSW2Y7VZ.js +5 -0
  96. package/dist/cli-bundle/focused-chunks/{chunk-WVGJAD7L.js → chunk-LKQXXO62.js} +2 -2
  97. package/dist/cli-bundle/focused-chunks/{chunk-UFCPSWIL.js → chunk-MBBMTDD3.js} +2 -2
  98. package/dist/cli-bundle/focused-chunks/{chunk-OYTK4VNH.js → chunk-ME4XVOBJ.js} +2 -2
  99. package/dist/cli-bundle/focused-chunks/{chunk-RO5BQFG3.js → chunk-N7QN3NE6.js} +2 -2
  100. package/dist/cli-bundle/focused-chunks/chunk-QL5H3AQH.js +2 -0
  101. package/dist/cli-bundle/focused-chunks/chunk-TQMFQYXR.js +29 -0
  102. package/dist/cli-bundle/focused-chunks/{chunk-SQXVGHMH.js → chunk-XNVXIQ4B.js} +2 -2
  103. package/dist/cli-bundle/focused-chunks/{chunk-BOGRY7M6.js → chunk-YHDCGUIW.js} +10 -10
  104. package/dist/cli-bundle/focused-chunks/{chunk-K37BB4JL.js → chunk-YLPZHWX7.js} +2 -2
  105. package/dist/cli-bundle/main.js +13 -13
  106. package/dist/cli-bundle/sdk-authoring.js +1 -1
  107. package/dist/cli-bundle/sdk-contracts.js +1 -1
  108. package/dist/cli-bundle/sdk-core.js +28 -28
  109. package/dist/cli-bundle/sdk-governance.js +1 -1
  110. package/dist/cli-bundle/sdk-graph.js +1 -1
  111. package/dist/cli-bundle/sdk-merge.js +1 -1
  112. package/dist/cli-bundle/sdk-query.js +1 -1
  113. package/dist/cli-bundle/sdk-runtime.js +1 -1
  114. package/dist/cli-bundle/sdk-testing.js +1 -1
  115. package/dist/cli-bundle/sdk.js +1 -1
  116. package/dist/core/extensions/activation-summary.d.ts +4 -0
  117. package/dist/core/extensions/activation-summary.js +5 -2
  118. package/dist/core/extensions/contribution-inventory.d.ts +1 -0
  119. package/dist/core/extensions/contribution-inventory.js +35 -2
  120. package/dist/core/extensions/extension-hook-runtime.js +5 -3
  121. package/dist/core/extensions/extension-types.d.ts +18 -1
  122. package/dist/core/extensions/extension-types.js +2 -2
  123. package/dist/core/extensions/loader.js +8 -13
  124. package/dist/core/extensions/preflight-ownership.d.ts +5 -0
  125. package/dist/core/extensions/preflight-ownership.js +42 -0
  126. package/dist/core/item/item-format.js +14 -20
  127. package/dist/core/shared/constants.js +3 -2
  128. package/dist/core/store/item-store.js +2 -2
  129. package/dist/core/store/settings.js +2 -2
  130. package/dist/mcp/server.js +12 -6
  131. package/dist/mcp/tool-definitions.js +14 -7
  132. package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +18 -18
  133. package/dist/sdk/cli-contracts/agent-output-contracts.js +51 -23
  134. package/dist/sdk/cli-contracts/commander-mutation-options.js +26 -2
  135. package/dist/sdk/cli-contracts/flag-contracts.d.ts +4 -0
  136. package/dist/sdk/cli-contracts/flag-contracts.js +34 -2
  137. package/dist/sdk/cli-contracts/registration-helpers.js +4 -2
  138. package/dist/sdk/cli-contracts/runtime-contracts.d.ts +10 -2
  139. package/dist/sdk/cli-contracts/runtime-contracts.js +21 -5
  140. package/dist/sdk/cli-contracts/tool-schema.js +4 -2
  141. package/dist/sdk/cli-contracts.d.ts +2 -2
  142. package/dist/sdk/cli-contracts.js +4 -4
  143. package/dist/sdk/cli-program.js +3 -3
  144. package/dist/sdk/compose.d.ts +2 -2
  145. package/dist/sdk/compose.js +7 -2
  146. package/dist/sdk/contracts.d.ts +1 -0
  147. package/dist/sdk/contracts.js +3 -2
  148. package/dist/sdk/define.d.ts +3 -1
  149. package/dist/sdk/define.js +3 -8
  150. package/dist/sdk/dependency-provenance.d.ts +2 -0
  151. package/dist/sdk/dependency-provenance.js +7 -3
  152. package/dist/sdk/error-code-catalog.d.ts +23 -0
  153. package/dist/sdk/error-code-catalog.js +25 -5
  154. package/dist/sdk/extension/install-sources.d.ts +43 -5
  155. package/dist/sdk/extension/install-sources.js +36 -2
  156. package/dist/sdk/extension/migrations.d.ts +114 -0
  157. package/dist/sdk/extension/migrations.js +175 -0
  158. package/dist/sdk/extension/scaffold.js +14 -9
  159. package/dist/sdk/extension/source-resolution.d.ts +50 -0
  160. package/dist/sdk/extension/source-resolution.js +66 -0
  161. package/dist/sdk/extension.d.ts +5 -1
  162. package/dist/sdk/extension.js +24 -26
  163. package/dist/sdk/generated-error-code-catalog.js +499 -3
  164. package/dist/sdk/governance/health.js +11 -2
  165. package/dist/sdk/graph/governance.js +3 -3
  166. package/dist/sdk/graph/remediation.js +3 -3
  167. package/dist/sdk/graph/run.js +4 -8
  168. package/dist/sdk/index.d.ts +7 -2
  169. package/dist/sdk/index.js +9 -4
  170. package/dist/sdk/item-transaction.d.ts +51 -6
  171. package/dist/sdk/item-transaction.js +132 -22
  172. package/dist/sdk/lifecycle/create.d.ts +4 -0
  173. package/dist/sdk/lifecycle/create.js +26 -10
  174. package/dist/sdk/lifecycle-policy.d.ts +9 -0
  175. package/dist/sdk/lifecycle-policy.js +22 -9
  176. package/dist/sdk/merge/driver.js +6 -3
  177. package/dist/sdk/output-contracts.d.ts +67 -0
  178. package/dist/sdk/output-contracts.js +173 -0
  179. package/dist/sdk/package-import-adapters.js +2 -2
  180. package/dist/sdk/package-migrations.d.ts +10 -0
  181. package/dist/sdk/package-migrations.js +21 -0
  182. package/dist/sdk/runtime.d.ts +2 -0
  183. package/dist/sdk/runtime.js +6 -2
  184. package/dist/sdk/structured-mutations.d.ts +23 -0
  185. package/dist/sdk/structured-mutations.js +219 -10
  186. package/dist/sdk/workspace-snapshot.js +58 -12
  187. package/dist/sdk/workspace.js +30 -4
  188. package/docs/COMMANDS.md +49 -10
  189. package/docs/EXTENSIONS.md +3 -3
  190. package/docs/EXTENSION_LIFECYCLE.md +46 -0
  191. package/docs/MERGE_SAFETY.md +2 -0
  192. package/docs/PR_REVIEW_LOOP.md +10 -4
  193. package/docs/README.md +23 -22
  194. package/docs/RELEASING.md +36 -23
  195. package/docs/SCRIPTING.md +32 -9
  196. package/docs/SDK.md +122 -14
  197. package/docs/SELF_DESCRIBING_CONTEXT_CONTRACTS.md +13 -0
  198. package/docs/TESTING.md +25 -0
  199. package/docs/examples/sdk-contract-consumer/README.md +11 -1
  200. package/docs/examples/sdk-contract-consumer/package.json +2 -1
  201. package/docs/examples/sdk-contract-consumer/parse-receipt.mjs +22 -0
  202. package/marketplace.json +2 -2
  203. package/package.json +5 -4
  204. package/packages/pm-beads/package.json +1 -1
  205. package/packages/pm-calendar/package.json +1 -1
  206. package/packages/pm-command-kit/package.json +1 -1
  207. package/packages/pm-digital-twin/package.json +1 -1
  208. package/packages/pm-governance-audit/package.json +1 -1
  209. package/packages/pm-guide-shell/package.json +1 -1
  210. package/packages/pm-kanban/package.json +1 -1
  211. package/packages/pm-lifecycle-hooks/package.json +1 -1
  212. package/packages/pm-linked-test-adapters/package.json +1 -1
  213. package/packages/pm-search-advanced/package.json +1 -1
  214. package/packages/pm-templates/package.json +1 -1
  215. package/packages/pm-todos/package.json +1 -1
  216. package/packages/pm-vcs/package.json +1 -1
  217. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  218. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  219. package/sdk/public-surface.json +508 -32
  220. package/dist/cli-bundle/chunks/append-DHBRLHHS.js +0 -2
  221. package/dist/cli-bundle/chunks/chunk-2INN52SU.js +0 -8
  222. package/dist/cli-bundle/chunks/chunk-377OOXUF.js +0 -55
  223. package/dist/cli-bundle/chunks/chunk-6RSK4IFN.js +0 -20
  224. package/dist/cli-bundle/chunks/chunk-ASJJKA57.js +0 -2
  225. package/dist/cli-bundle/chunks/chunk-IYAVULRN.js +0 -2
  226. package/dist/cli-bundle/chunks/chunk-JDPKBV5P.js +0 -2
  227. package/dist/cli-bundle/chunks/chunk-RRQBHQOV.js +0 -2
  228. package/dist/cli-bundle/chunks/chunk-SULWTPQO.js +0 -8
  229. package/dist/cli-bundle/chunks/chunk-V5K52PYW.js +0 -164
  230. package/dist/cli-bundle/chunks/chunk-XBLOD5TZ.js +0 -2
  231. package/dist/cli-bundle/chunks/close-VLHNN6YB.js +0 -2
  232. package/dist/cli-bundle/chunks/close-many-LSJNZKU6.js +0 -2
  233. package/dist/cli-bundle/chunks/comments-AAIA6A6X.js +0 -2
  234. package/dist/cli-bundle/chunks/copy-Z7YMLEHN.js +0 -2
  235. package/dist/cli-bundle/chunks/delete-KNOHHQJM.js +0 -2
  236. package/dist/cli-bundle/chunks/focus-LFRCGALV.js +0 -2
  237. package/dist/cli-bundle/chunks/register-mutation-GU3DCECN.js +0 -20
  238. package/dist/cli-bundle/chunks/register-operations-PTWH727R.js +0 -2
  239. package/dist/cli-bundle/chunks/register-setup-KWV6UD77.js +0 -2
  240. package/dist/cli-bundle/chunks/restore-4HZSLILR.js +0 -2
  241. package/dist/cli-bundle/chunks/update-E6LPS5IV.js +0 -2
  242. package/dist/cli-bundle/chunks/update-many-OSIC6KRO.js +0 -2
  243. package/dist/cli-bundle/focused-chunks/chunk-2VIIXOAD.js +0 -2
  244. package/dist/cli-bundle/focused-chunks/chunk-5MTKO7TV.js +0 -153
  245. package/dist/cli-bundle/focused-chunks/chunk-6GIZK7VQ.js +0 -2
  246. package/dist/cli-bundle/focused-chunks/chunk-AOP2WIZZ.js +0 -2
  247. package/dist/cli-bundle/focused-chunks/chunk-C2QSL62X.js +0 -28
  248. package/dist/cli-bundle/focused-chunks/chunk-CL75YW32.js +0 -2
  249. package/dist/cli-bundle/focused-chunks/chunk-E7OFMWGT.js +0 -8
  250. package/dist/cli-bundle/focused-chunks/chunk-I5F5UK3Q.js +0 -2
  251. package/dist/cli-bundle/focused-chunks/chunk-QM2BIVK7.js +0 -4
  252. package/dist/cli-bundle/focused-chunks/chunk-T5TSY36R.js +0 -5
  253. package/dist/cli-bundle/focused-chunks/chunk-VT6BF2IX.js +0 -2
@@ -32,7 +32,7 @@
32
32
  * non-generic signature lets TypeScript type the handler parameter from the
33
33
  * declared function type.
34
34
  */
35
- import type { AfterCommandHook, BeforeCommandHook, BeforeMutationHook, CommandDefinition, CommandOverride, Exporter, ExtensionManifest, FlagDefinition, Importer, OnIndexHook, OnReadHook, OnWriteHook, ParserOverride, PreflightOverride, RendererOverride, ScopedRendererOverrideDefinition, SchemaFieldDefinition, SchemaItemTypeDefinition, SchemaMigrationDefinition, SearchProviderDefinition, ServiceOverride, ServiceOverrideDecision, VectorStoreAdapterDefinition } from "../core/extensions/loader.js";
35
+ import type { AfterCommandHook, BeforeCommandHook, BeforeMutationHook, CommandDefinition, CommandOverride, Exporter, ExtensionManifest, FlagDefinition, Importer, OnIndexHook, OnReadHook, OnWriteHook, ParserOverride, PreflightOverride, ScopedPreflightOverrideDefinition, RendererOverride, ScopedRendererOverrideDefinition, SchemaFieldDefinition, SchemaItemTypeDefinition, SchemaMigrationDefinition, SearchProviderDefinition, ServiceOverride, ServiceOverrideDecision, VectorStoreAdapterDefinition } from "../core/extensions/loader.js";
36
36
  import type { ProjectProfileDefinition } from "../core/profile/profile-presets.js";
37
37
  type ExactDefinition<TDefinition, TContract> = TDefinition & Record<Exclude<keyof TDefinition, keyof TContract>, never>;
38
38
  type FlagAuthoringDefinition = Pick<FlagDefinition, "long" | "short" | "value_name" | "description" | "required" | "enabled" | "visible" | "value_type" | "type" | "list" | "default">;
@@ -145,6 +145,8 @@ export declare function defineParserOverride(override: ParserOverride): ParserOv
145
145
  * package's pre-run validation override is checked at the definition site.
146
146
  */
147
147
  export declare function definePreflightOverride(override: PreflightOverride): PreflightOverride;
148
+ /** Type a scoped preflight definition while preserving literal command ownership. */
149
+ export declare function definePreflightOverride<TDefinition extends ScopedPreflightOverrideDefinition>(override: ExactDefinition<TDefinition, ScopedPreflightOverrideDefinition>): TDefinition;
148
150
  /**
149
151
  * Type a service-override handler for `api.registerService(service, override)`.
150
152
  *
@@ -9,7 +9,7 @@
9
9
  * to keep `capabilities` matched to the surfaces the extension actually registers.
10
10
  */
11
11
 
12
- !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]="9212673f-1a9f-50b8-92a2-4fd30ce54351")}catch(e){}}();
12
+ !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]="7fc669d4-1db2-5636-8304-2c111a684726")}catch(e){}}();
13
13
  export function defineExtensionManifest(manifest) {
14
14
  return manifest;
15
15
  }
@@ -119,12 +119,7 @@ export function defineCommandOverride(override) {
119
119
  export function defineParserOverride(override) {
120
120
  return override;
121
121
  }
122
- /**
123
- * Type a preflight-override handler for `api.registerPreflight(override)`.
124
- *
125
- * Contextually types the `context` parameter and the returned gate decision so a
126
- * package's pre-run validation override is checked at the definition site.
127
- */
122
+ /** Implement the preflight authoring identity for callbacks and scoped definitions. */
128
123
  export function definePreflightOverride(override) {
129
124
  return override;
130
125
  }
@@ -223,4 +218,4 @@ export function defineOnIndexHook(hook) {
223
218
  return hook;
224
219
  }
225
220
  //# sourceMappingURL=define.js.map
226
- //# debugId=9212673f-1a9f-50b8-92a2-4fd30ce54351
221
+ //# debugId=7fc669d4-1db2-5636-8304-2c111a684726
@@ -1,5 +1,7 @@
1
1
  /** Provenance value declaring that a dependency id belongs to another workspace. */
2
2
  export declare const EXTERNAL_DEPENDENCY_SOURCE_KIND = "global";
3
+ /** Human-facing alias accepted wherever external dependency provenance is parsed. */
4
+ export declare const EXTERNAL_DEPENDENCY_SOURCE_KIND_ALIAS = "external";
3
5
  /** Return whether a dependency provenance value identifies an external workspace target. */
4
6
  export declare function isExternalDependencySourceKind(sourceKind: string | undefined): boolean;
5
7
  /** Canonicalize external provenance while preserving other named source kinds. */
@@ -5,13 +5,17 @@
5
5
  * items outside the current workspace.
6
6
  */
7
7
 
8
- !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]="187a7342-71fc-5432-9f30-c40e444d4611")}catch(e){}}();
8
+ !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]="1b2f1ac3-82b3-58a2-9f40-2dd95ab1b2bc")}catch(e){}}();
9
9
  import { normalizeItemId } from "../core/item/id.js";
10
10
  /** Provenance value declaring that a dependency id belongs to another workspace. */
11
11
  export const EXTERNAL_DEPENDENCY_SOURCE_KIND = "global";
12
+ /** Human-facing alias accepted wherever external dependency provenance is parsed. */
13
+ export const EXTERNAL_DEPENDENCY_SOURCE_KIND_ALIAS = "external";
12
14
  /** Return whether a dependency provenance value identifies an external workspace target. */
13
15
  export function isExternalDependencySourceKind(sourceKind) {
14
- return sourceKind?.trim().toLowerCase() === EXTERNAL_DEPENDENCY_SOURCE_KIND;
16
+ const normalized = sourceKind?.trim().toLowerCase();
17
+ return (normalized === EXTERNAL_DEPENDENCY_SOURCE_KIND ||
18
+ normalized === EXTERNAL_DEPENDENCY_SOURCE_KIND_ALIAS);
15
19
  }
16
20
  /** Canonicalize external provenance while preserving other named source kinds. */
17
21
  export function normalizeDependencySourceKind(sourceKind) {
@@ -35,4 +39,4 @@ export function normalizeDependencySeedId(id, prefix, sourceKind) {
35
39
  : normalizeItemId(trimmed, prefix);
36
40
  }
37
41
  //# sourceMappingURL=dependency-provenance.js.map
38
- //# debugId=187a7342-71fc-5432-9f30-c40e444d4611
42
+ //# debugId=1b2f1ac3-82b3-58a2-9f40-2dd95ab1b2bc
@@ -6,6 +6,25 @@
6
6
  */
7
7
  /** Compatibility promise attached to a machine-readable error code. */
8
8
  export type PmErrorCodeStability = "provisional" | "stable";
9
+ /** Semantic process-exit class shared by shell and SDK consumers. */
10
+ export type PmErrorCodeClass = "generic_failure" | "usage" | "not_found" | "conflict" | "dependency_failed";
11
+ /** Stable shell exit-code taxonomy shared by every structured error. */
12
+ export declare const PM_ERROR_CODE_EXIT_CLASS_CONTRACTS: readonly [{
13
+ readonly exit_code: 1;
14
+ readonly class: "generic_failure";
15
+ }, {
16
+ readonly exit_code: 2;
17
+ readonly class: "usage";
18
+ }, {
19
+ readonly exit_code: 3;
20
+ readonly class: "not_found";
21
+ }, {
22
+ readonly exit_code: 4;
23
+ readonly class: "conflict";
24
+ }, {
25
+ readonly exit_code: 5;
26
+ readonly class: "dependency_failed";
27
+ }];
9
28
  /** One machine-readable error and its portable recovery contract. */
10
29
  export interface PmErrorCodeContract {
11
30
  /** Stable snake_case identifier. */
@@ -16,10 +35,14 @@ export interface PmErrorCodeContract {
16
35
  stability: PmErrorCodeStability;
17
36
  /** Process exit code emitted by the CLI transport. */
18
37
  exit_code: 1 | 2 | 3 | 4 | 5;
38
+ /** Semantic class represented by the process exit code. */
39
+ class: PmErrorCodeClass;
19
40
  /** Actionable caller recovery guidance. */
20
41
  recovery: string;
21
42
  /** Subsystems that can emit the code. */
22
43
  sources: string[];
44
+ /** CLI command roots inferred from executable declaration ownership. */
45
+ emitting_commands: string[];
23
46
  }
24
47
  /** Validate, normalize, sort, and freeze an error-code catalog. */
25
48
  export declare function definePmErrorCodeCatalog(declarations: readonly PmErrorCodeContract[]): readonly PmErrorCodeContract[];
@@ -4,9 +4,24 @@
4
4
  * Defines the stable, discoverable error vocabulary used across CLI, SDK, MCP,
5
5
  * packages, and generated contract surfaces.
6
6
  */
7
- /** Validate, normalize, sort, and freeze an error-code catalog. */
7
+ /** Stable shell exit-code taxonomy shared by every structured error. */
8
8
 
9
- !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]="804df95b-c2fc-5ea7-bfb5-aea890a65abc")}catch(e){}}();
9
+ !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]="479dd590-7f54-54ae-bbaf-8f183fd6b6b4")}catch(e){}}();
10
+ export const PM_ERROR_CODE_EXIT_CLASS_CONTRACTS = [
11
+ { exit_code: 1, class: "generic_failure" },
12
+ { exit_code: 2, class: "usage" },
13
+ { exit_code: 3, class: "not_found" },
14
+ { exit_code: 4, class: "conflict" },
15
+ { exit_code: 5, class: "dependency_failed" },
16
+ ];
17
+ const ERROR_CLASS_BY_EXIT_CODE = new Map(PM_ERROR_CODE_EXIT_CLASS_CONTRACTS.map((contract) => [contract.exit_code, contract.class]));
18
+ /** Normalize a declared non-empty string set into stable contract order. */
19
+ function normalizeContractList(values) {
20
+ return [
21
+ ...new Set(values.map((value) => value.trim()).filter(Boolean)),
22
+ ].sort();
23
+ }
24
+ /** Validate, normalize, sort, and freeze an error-code catalog. */
10
25
  export function definePmErrorCodeCatalog(declarations) {
11
26
  const seen = new Set();
12
27
  const normalized = declarations.map((declaration) => {
@@ -18,10 +33,14 @@ export function definePmErrorCodeCatalog(declarations) {
18
33
  throw new TypeError(`Duplicate pm error code: ${code}`);
19
34
  }
20
35
  seen.add(code);
36
+ const sources = normalizeContractList(declaration.sources);
37
+ const emittingCommands = normalizeContractList(declaration.emitting_commands);
21
38
  if (![1, 2, 3, 4, 5].includes(declaration.exit_code) ||
22
39
  declaration.meaning.trim().length === 0 ||
23
40
  declaration.recovery.trim().length === 0 ||
24
- declaration.sources.length === 0) {
41
+ sources.length === 0 ||
42
+ emittingCommands.length === 0 ||
43
+ ERROR_CLASS_BY_EXIT_CODE.get(declaration.exit_code) !== declaration.class) {
25
44
  throw new TypeError(`Invalid pm error code contract: ${code}`);
26
45
  }
27
46
  return Object.freeze({
@@ -29,7 +48,8 @@ export function definePmErrorCodeCatalog(declarations) {
29
48
  code,
30
49
  meaning: declaration.meaning.trim(),
31
50
  recovery: declaration.recovery.trim(),
32
- sources: [...new Set(declaration.sources.map((source) => source.trim()).filter(Boolean))].sort(),
51
+ sources,
52
+ emitting_commands: emittingCommands,
33
53
  });
34
54
  });
35
55
  return Object.freeze(normalized.sort((left, right) => left.code.localeCompare(right.code)));
@@ -44,4 +64,4 @@ export function resolvePmErrorCodeContract(code, catalog) {
44
64
  return contract;
45
65
  }
46
66
  //# sourceMappingURL=error-code-catalog.js.map
47
- //# debugId=804df95b-c2fc-5ea7-bfb5-aea890a65abc
67
+ //# debugId=479dd590-7f54-54ae-bbaf-8f183fd6b6b4
@@ -13,36 +13,73 @@ interface LocalPackageArchiveLimits {
13
13
  maxExpandedBytes: number;
14
14
  maxEntryBytes: number;
15
15
  }
16
- interface LocalInstallSource {
16
+ /** Parsed filesystem install source. */
17
+ export interface LocalInstallSource {
18
+ /** Discriminator for a filesystem source. */
17
19
  kind: "local";
20
+ /** Exact caller-provided source text. */
18
21
  input: string;
22
+ /** Absolute normalized source path. */
19
23
  absolute_path: string;
20
24
  }
21
- interface GithubInstallSource {
25
+ /** Parsed GitHub repository install source. */
26
+ export interface GithubInstallSource {
27
+ /** Discriminator for a GitHub repository source. */
22
28
  kind: "github";
29
+ /** Exact caller-provided source text. */
23
30
  input: string;
31
+ /** Repository owner. */
24
32
  owner: string;
33
+ /** Repository name without a `.git` suffix. */
25
34
  repo: string;
35
+ /** Cloneable HTTPS repository URL. */
26
36
  repository: string;
37
+ /** Optional Git ref selected by the caller or URL. */
27
38
  ref?: string;
39
+ /** Optional repository-relative package directory. */
28
40
  subpath?: string;
29
41
  }
30
- interface NpmInstallSource {
42
+ /** Parsed npm registry or package-spec install source. */
43
+ export interface NpmInstallSource {
44
+ /** Discriminator for an npm package source. */
31
45
  kind: "npm";
46
+ /** Exact caller-provided source text. */
32
47
  input: string;
48
+ /** Validated npm package specification. */
33
49
  spec: string;
34
50
  }
35
- type InstallSource = LocalInstallSource | GithubInstallSource | NpmInstallSource;
36
- interface ResolvedInstallSource {
51
+ /** Parsed extension install source accepted by the resolver. */
52
+ export type InstallSource = LocalInstallSource | GithubInstallSource | NpmInstallSource;
53
+ /** Materialized install source ready for extension validation. */
54
+ export interface ResolvedInstallSource {
55
+ /** Parsed source that produced this directory. */
37
56
  source: InstallSource;
57
+ /** Absolute extension or package directory ready for validation. */
38
58
  directory: string;
59
+ /** Root unpacked or cloned source directory when different from `directory`. */
39
60
  source_root?: string;
61
+ /** Repository subpath selected after clone. */
40
62
  resolved_subpath?: string;
63
+ /** Resolved Git commit when the source is a repository. */
41
64
  commit?: string;
65
+ /** Canonical npm package name when the source is a registry package. */
42
66
  npm_package?: string;
67
+ /** Resolved npm package version. */
43
68
  npm_version?: string;
69
+ /** Releases temporary source material created during resolution. */
44
70
  cleanup?: () => Promise<void>;
45
71
  }
72
+ /** Installed npm package that competes with a bare bundled install target. */
73
+ export interface InstalledNpmPackageCandidate {
74
+ /** Package identity read from its package.json. */
75
+ package: string;
76
+ /** Installed package version when declared. */
77
+ version?: string;
78
+ /** Absolute package root selected by Node-style ancestor lookup. */
79
+ directory: string;
80
+ }
81
+ /** Resolve an already-installed npm package without executing package code. */
82
+ export declare function findInstalledNpmPackageCandidate(packageName: string, cwd?: string): Promise<InstalledNpmPackageCandidate | null>;
46
83
  /** Implements parse extension install source for the public runtime surface of this module. */
47
84
  export declare function parseExtensionInstallSource(input: string, options?: {
48
85
  forceGithub?: boolean;
@@ -128,6 +165,7 @@ export declare const _testOnlyInstallSources: {
128
165
  resolveNpmSourceDirectoryWithRunner: typeof resolveNpmSourceDirectoryWithRunner;
129
166
  resolveNpmSourceDirectory: typeof resolveNpmSourceDirectory;
130
167
  resolveNpmPackSpec: typeof resolveNpmPackSpec;
168
+ findInstalledNpmPackageCandidate: typeof findInstalledNpmPackageCandidate;
131
169
  resolvePackageExtensionDirectory: typeof resolvePackageExtensionDirectory;
132
170
  runtimeDependencyInstallSpecs: typeof runtimeDependencyInstallSpecs;
133
171
  hasHostedPmCliDependency: typeof hasHostedPmCliDependency;
@@ -4,7 +4,7 @@
4
4
  * Implements extension package-management support for Install Sources.
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]="0c87e77d-e7c5-5f0c-aad6-b047e33ccb25")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8994c8e2-8e3a-5e00-a3ca-7bd553c045d7")}catch(e){}}();
8
8
  import { execFile } from "node:child_process";
9
9
  import fs from "node:fs/promises";
10
10
  import os from "node:os";
@@ -29,6 +29,39 @@ const LOCAL_PACKAGE_ARCHIVE_LIMITS = {
29
29
  maxEntryBytes: 64 * 1024 * 1024,
30
30
  };
31
31
  let bundledPackageAliasesCache;
32
+ /** Resolve an already-installed npm package without executing package code. */
33
+ export async function findInstalledNpmPackageCandidate(packageName, cwd = process.cwd()) {
34
+ const normalized = packageName.trim();
35
+ if (!/^(@[^/\\\s]+\/[^/\\\s]+|[^@/\\\s][^/\\\s]*)$/u.test(normalized)) {
36
+ return null;
37
+ }
38
+ let current = path.resolve(cwd);
39
+ while (true) {
40
+ const directory = path.join(current, "node_modules", ...normalized.split("/"));
41
+ const manifestPath = path.join(directory, "package.json");
42
+ if (await pathExists(manifestPath)) {
43
+ try {
44
+ const manifest = JSON.parse(await fs.readFile(manifestPath, "utf8"));
45
+ if (manifest.name === normalized) {
46
+ return {
47
+ package: normalized,
48
+ ...(typeof manifest.version === "string"
49
+ ? { version: manifest.version }
50
+ : {}),
51
+ directory,
52
+ };
53
+ }
54
+ }
55
+ catch {
56
+ return null;
57
+ }
58
+ }
59
+ const parent = path.dirname(current);
60
+ if (parent === current)
61
+ return null;
62
+ current = parent;
63
+ }
64
+ }
32
65
  function parseGithubPathSpec(pathSpec, input, refOverride) {
33
66
  const segments = pathSpec
34
67
  .split("/")
@@ -916,6 +949,7 @@ export const _testOnlyInstallSources = {
916
949
  resolveNpmSourceDirectoryWithRunner,
917
950
  resolveNpmSourceDirectory,
918
951
  resolveNpmPackSpec,
952
+ findInstalledNpmPackageCandidate,
919
953
  resolvePackageExtensionDirectory,
920
954
  runtimeDependencyInstallSpecs,
921
955
  hasHostedPmCliDependency,
@@ -925,4 +959,4 @@ export const _testOnlyInstallSources = {
925
959
  runNpmCommand,
926
960
  };
927
961
  //# sourceMappingURL=install-sources.js.map
928
- //# debugId=0c87e77d-e7c5-5f0c-aad6-b047e33ccb25
962
+ //# debugId=8994c8e2-8e3a-5e00-a3ca-7bd553c045d7
@@ -0,0 +1,114 @@
1
+ import type { RegisteredExtensionSchemaMigrationDefinition } from "../../core/extensions/extension-types.js";
2
+ import type { ExtensionCommandResult, ExtensionScope } from "../extension.js";
3
+ /** Durable lifecycle state of one extension migration in one workspace. */
4
+ export type ExtensionMigrationOutcomeStatus = "applied" | "failed";
5
+ /** One durable extension-migration outcome. */
6
+ export interface ExtensionMigrationStateEntry {
7
+ /** Stable layer/name/id identity. */
8
+ key: string;
9
+ /** Extension installation layer. */
10
+ layer: "global" | "project";
11
+ /** Owning extension name. */
12
+ extension: string;
13
+ /** Migration identifier declared by the extension. */
14
+ id: string;
15
+ /** Last durable outcome. */
16
+ status: ExtensionMigrationOutcomeStatus;
17
+ /** ISO timestamp for the last attempt. */
18
+ attempted_at: string;
19
+ /** Failure text retained only for failed outcomes. */
20
+ error?: string;
21
+ }
22
+ /** Versioned workspace state for extension migrations. */
23
+ export interface ExtensionMigrationState {
24
+ /** Storage schema version. */
25
+ version: 1;
26
+ /** Last state change timestamp. */
27
+ updated_at: string;
28
+ /** Deterministically sorted outcomes. */
29
+ entries: ExtensionMigrationStateEntry[];
30
+ }
31
+ /** Planned or executed row returned for one registered migration. */
32
+ export interface ExtensionMigrationReceipt {
33
+ /** Stable layer/name/id identity. */
34
+ key: string;
35
+ /** Extension installation layer. */
36
+ layer: "global" | "project";
37
+ /** Owning extension name. */
38
+ extension: string;
39
+ /** Migration identifier. */
40
+ id: string;
41
+ /** State observed before this invocation. */
42
+ before: "pending" | ExtensionMigrationOutcomeStatus;
43
+ /** Invocation outcome. */
44
+ outcome: "pending" | "applied" | "skipped" | "failed";
45
+ /** Failure text for failed execution. */
46
+ error?: string;
47
+ }
48
+ /** Structured plan/application envelope for extension migrations. */
49
+ export interface ExtensionMigrationRunResult {
50
+ /** Whether the invocation executed no failing migration. */
51
+ ok: boolean;
52
+ /** Whether execution was suppressed. */
53
+ dry_run: boolean;
54
+ /** Durable state path. */
55
+ state_path: string;
56
+ /** Total registered migrations in scope. */
57
+ total: number;
58
+ /** Pending rows in the returned receipt. */
59
+ pending_count: number;
60
+ /** Applied rows in the returned receipt. */
61
+ applied_count: number;
62
+ /** Already-applied rows skipped idempotently. */
63
+ skipped_count: number;
64
+ /** Failed rows in the returned receipt. */
65
+ failed_count: number;
66
+ /** Deterministically ordered per-migration receipts. */
67
+ migrations: ExtensionMigrationReceipt[];
68
+ }
69
+ /** Options for planning or applying active extension migrations. */
70
+ export interface RunExtensionMigrationsOptions {
71
+ /** Tracker root that owns durable migration state. */
72
+ pmRoot: string;
73
+ /** Active runtime registrations. */
74
+ migrations: RegisteredExtensionSchemaMigrationDefinition[];
75
+ /** Audit author written to workspace history. */
76
+ author: string;
77
+ /** Report pending work without invoking extension code. */
78
+ dryRun?: boolean;
79
+ /** Limit execution and receipts to one installation layer. */
80
+ scope?: "global" | "project";
81
+ }
82
+ /** Minimal lifecycle context required by the migration action dispatcher. */
83
+ export interface ExtensionMigrationActionContext {
84
+ /** Selected package scope. */
85
+ scope: ExtensionScope;
86
+ /** Tracker and settings roots for the invocation. */
87
+ resolvedRoots: {
88
+ pm_root: string;
89
+ settings_root: string;
90
+ };
91
+ /** Mutable warning collection shared with the lifecycle result. */
92
+ warnings: string[];
93
+ /** Migration-specific command options. */
94
+ options: {
95
+ dryRun?: boolean;
96
+ };
97
+ /** Relevant global runtime options. */
98
+ global: {
99
+ noExtensions?: boolean;
100
+ author?: string;
101
+ };
102
+ /** Construct the standard extension lifecycle result envelope. */
103
+ withResult: (details: Record<string, unknown>, ok?: boolean) => ExtensionCommandResult;
104
+ }
105
+ /** Return the durable workspace path for extension migration state. */
106
+ export declare function resolveExtensionMigrationStatePath(pmRoot: string): string;
107
+ /** Read durable extension migration outcomes, degrading absent state to empty. */
108
+ export declare function readExtensionMigrationState(pmRoot: string): Promise<ExtensionMigrationState>;
109
+ /** Overlay durable outcomes onto freshly activated migration definitions. */
110
+ export declare function applyStoredExtensionMigrationState(pmRoot: string, migrations: RegisteredExtensionSchemaMigrationDefinition[]): Promise<ExtensionMigrationState>;
111
+ /** Plan or apply active extension migrations with durable idempotency receipts. */
112
+ export declare function runExtensionMigrations(options: RunExtensionMigrationsOptions): Promise<ExtensionMigrationRunResult>;
113
+ /** Load active registrations and execute the extension lifecycle migrate action. */
114
+ export declare function runExtensionMigrateAction(context: ExtensionMigrationActionContext): Promise<ExtensionCommandResult>;
@@ -0,0 +1,175 @@
1
+ /**
2
+ * @module sdk/extension/migrations
3
+ *
4
+ * Provides durable planning and execution for extension-owned schema migrations.
5
+ */
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]="56290db9-933c-590d-8b9f-df62ff45e515")}catch(e){}}();
8
+ import fs from "node:fs/promises";
9
+ import path from "node:path";
10
+ import { pathExists } from "../../core/fs/fs-utils.js";
11
+ import { activateExtensions, loadExtensions } from "../../core/extensions/index.js";
12
+ import { writeWorkspaceJsonWithHistory } from "../../core/history/workspace-history.js";
13
+ import { readSettings } from "../../core/store/settings.js";
14
+ /** Return the durable workspace path for extension migration state. */
15
+ export function resolveExtensionMigrationStatePath(pmRoot) {
16
+ return path.join(pmRoot, "extension-migrations.json");
17
+ }
18
+ function migrationId(migration, index) {
19
+ const id = migration.definition.id;
20
+ return typeof id === "string" && id.trim().length > 0
21
+ ? id.trim()
22
+ : `migration-${String(index + 1).padStart(3, "0")}`;
23
+ }
24
+ function migrationKey(migration, id) {
25
+ return `${migration.layer}:${migration.name}:${id}`;
26
+ }
27
+ /** Read durable extension migration outcomes, degrading absent state to empty. */
28
+ export async function readExtensionMigrationState(pmRoot) {
29
+ const statePath = resolveExtensionMigrationStatePath(pmRoot);
30
+ if (!(await pathExists(statePath))) {
31
+ return { version: 1, updated_at: "", entries: [] };
32
+ }
33
+ const parsed = JSON.parse(await fs.readFile(statePath, "utf8"));
34
+ return {
35
+ version: 1,
36
+ updated_at: typeof parsed.updated_at === "string" ? parsed.updated_at : "",
37
+ entries: Array.isArray(parsed.entries)
38
+ ? parsed.entries.filter((entry) => typeof entry?.key === "string" &&
39
+ (entry.status === "applied" || entry.status === "failed"))
40
+ : [],
41
+ };
42
+ }
43
+ /** Overlay durable outcomes onto freshly activated migration definitions. */
44
+ export async function applyStoredExtensionMigrationState(pmRoot, migrations) {
45
+ const state = await readExtensionMigrationState(pmRoot);
46
+ const byKey = new Map(state.entries.map((entry) => [entry.key, entry]));
47
+ migrations.forEach((migration, index) => {
48
+ const id = migrationId(migration, index);
49
+ const entry = byKey.get(migrationKey(migration, id));
50
+ if (!entry)
51
+ return;
52
+ migration.definition.status = entry.status;
53
+ if (entry.status === "failed") {
54
+ migration.definition.reason = entry.error;
55
+ }
56
+ else {
57
+ delete migration.definition.reason;
58
+ delete migration.definition.error;
59
+ delete migration.definition.message;
60
+ }
61
+ });
62
+ return state;
63
+ }
64
+ /** Plan or apply active extension migrations with durable idempotency receipts. */
65
+ export async function runExtensionMigrations(options) {
66
+ const state = await applyStoredExtensionMigrationState(options.pmRoot, options.migrations);
67
+ const stateByKey = new Map(state.entries.map((entry) => [entry.key, entry]));
68
+ const receipts = [];
69
+ let changed = false;
70
+ const scopedMigrations = options.migrations
71
+ .map((migration, index) => ({ migration, index }))
72
+ .filter(({ migration }) => options.scope === undefined || migration.layer === options.scope);
73
+ for (const { migration, index } of scopedMigrations) {
74
+ const id = migrationId(migration, index);
75
+ const key = migrationKey(migration, id);
76
+ const stored = stateByKey.get(key);
77
+ const declaredStatus = String(migration.definition.status ?? "pending").toLowerCase();
78
+ const before = stored?.status ?? (declaredStatus === "applied" || declaredStatus === "failed" ? declaredStatus : "pending");
79
+ if (before === "applied") {
80
+ receipts.push({ key, layer: migration.layer, extension: migration.name, id, before, outcome: "skipped" });
81
+ continue;
82
+ }
83
+ if (options.dryRun === true) {
84
+ receipts.push({ key, layer: migration.layer, extension: migration.name, id, before, outcome: "pending" });
85
+ continue;
86
+ }
87
+ const run = migration.runtime_definition?.run ?? migration.definition.run;
88
+ if (typeof run !== "function") {
89
+ receipts.push({ key, layer: migration.layer, extension: migration.name, id, before, outcome: "pending" });
90
+ continue;
91
+ }
92
+ const attemptedAt = new Date().toISOString();
93
+ try {
94
+ await Promise.resolve(run({ id, command: "migration", layer: migration.layer, extension: migration.name, pm_root: options.pmRoot, status: before }));
95
+ const entry = { key, layer: migration.layer, extension: migration.name, id, status: "applied", attempted_at: attemptedAt };
96
+ stateByKey.set(key, entry);
97
+ migration.definition.status = "applied";
98
+ delete migration.definition.reason;
99
+ delete migration.definition.error;
100
+ delete migration.definition.message;
101
+ receipts.push({ key, layer: migration.layer, extension: migration.name, id, before, outcome: "applied" });
102
+ changed = true;
103
+ }
104
+ catch (error) {
105
+ const message = error instanceof Error ? error.message : String(error);
106
+ const entry = { key, layer: migration.layer, extension: migration.name, id, status: "failed", attempted_at: attemptedAt, error: message };
107
+ stateByKey.set(key, entry);
108
+ migration.definition.status = "failed";
109
+ migration.definition.reason = message;
110
+ receipts.push({ key, layer: migration.layer, extension: migration.name, id, before, outcome: "failed", error: message });
111
+ changed = true;
112
+ }
113
+ }
114
+ if (changed) {
115
+ const settings = await readSettings(options.pmRoot);
116
+ const nextState = {
117
+ version: 1,
118
+ updated_at: new Date().toISOString(),
119
+ entries: [...stateByKey.values()].sort((left, right) => left.key.localeCompare(right.key)),
120
+ };
121
+ await writeWorkspaceJsonWithHistory({
122
+ pmRoot: options.pmRoot,
123
+ filePath: resolveExtensionMigrationStatePath(options.pmRoot),
124
+ raw: `${JSON.stringify(nextState, null, 2)}\n`,
125
+ op: "extension_migrations_apply",
126
+ author: options.author,
127
+ lockTtlSeconds: settings.locks.ttl_seconds,
128
+ lockWaitMs: settings.locks.wait_ms,
129
+ });
130
+ }
131
+ const pendingCount = receipts.filter((receipt) => receipt.outcome === "pending").length;
132
+ const appliedCount = receipts.filter((receipt) => receipt.outcome === "applied").length;
133
+ const skippedCount = receipts.filter((receipt) => receipt.outcome === "skipped").length;
134
+ const failedCount = receipts.filter((receipt) => receipt.outcome === "failed").length;
135
+ return {
136
+ ok: failedCount === 0,
137
+ dry_run: options.dryRun === true,
138
+ state_path: resolveExtensionMigrationStatePath(options.pmRoot),
139
+ total: receipts.length,
140
+ pending_count: pendingCount,
141
+ applied_count: appliedCount,
142
+ skipped_count: skippedCount,
143
+ failed_count: failedCount,
144
+ migrations: receipts,
145
+ };
146
+ }
147
+ /** Load active registrations and execute the extension lifecycle migrate action. */
148
+ export async function runExtensionMigrateAction(context) {
149
+ const settings = await readSettings(context.resolvedRoots.settings_root);
150
+ const loaded = await loadExtensions({
151
+ pmRoot: context.resolvedRoots.pm_root,
152
+ settings,
153
+ cwd: process.cwd(),
154
+ noExtensions: context.global.noExtensions === true,
155
+ });
156
+ const activated = await activateExtensions(loaded);
157
+ context.warnings.push(...loaded.warnings, ...activated.warnings);
158
+ const migration = await runExtensionMigrations({
159
+ pmRoot: context.resolvedRoots.pm_root,
160
+ migrations: activated.registrations.migrations,
161
+ author: typeof context.global.author === "string" &&
162
+ context.global.author.trim().length > 0
163
+ ? context.global.author.trim()
164
+ : "pm-extension-migration",
165
+ dryRun: context.options.dryRun === true,
166
+ ...(context.scope === "global" ? { scope: "global" } : {}),
167
+ });
168
+ return context.withResult({
169
+ migration,
170
+ load_failure_count: loaded.failed.length,
171
+ activation_failure_count: activated.failed.length,
172
+ }, migration.ok);
173
+ }
174
+ //# sourceMappingURL=migrations.js.map
175
+ //# debugId=56290db9-933c-590d-8b9f-df62ff45e515