@lesliechan721/aw 0.1.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (429) hide show
  1. package/dist/authoring/assets/aw-config.d.mts +2 -0
  2. package/dist/authoring/assets/aw-config.mjs +556 -0
  3. package/dist/authoring/assets/aw-config.mjs.map +1 -0
  4. package/dist/authoring/scripts/add-skill.d.mts +2 -0
  5. package/dist/authoring/scripts/add-skill.mjs +355 -0
  6. package/dist/authoring/scripts/add-skill.mjs.map +1 -0
  7. package/dist/authoring/scripts/check-plugin-versions.d.mts +2 -0
  8. package/dist/authoring/scripts/check-plugin-versions.mjs +5 -0
  9. package/dist/authoring/scripts/check-plugin-versions.mjs.map +1 -0
  10. package/dist/authoring/scripts/init-plugin.d.mts +2 -0
  11. package/dist/authoring/scripts/init-plugin.mjs +512 -0
  12. package/dist/authoring/scripts/init-plugin.mjs.map +1 -0
  13. package/dist/authoring/scripts/lib/javascript-import-scanner.d.mts +4 -0
  14. package/dist/authoring/scripts/lib/javascript-import-scanner.mjs +261 -0
  15. package/dist/authoring/scripts/lib/javascript-import-scanner.mjs.map +1 -0
  16. package/dist/authoring/scripts/lib/plugin-root.d.mts +26 -0
  17. package/dist/authoring/scripts/lib/plugin-root.mjs +125 -0
  18. package/dist/authoring/scripts/lib/plugin-root.mjs.map +1 -0
  19. package/dist/authoring/scripts/lib/plugin-version-check.d.mts +55 -0
  20. package/dist/authoring/scripts/lib/plugin-version-check.mjs +777 -0
  21. package/dist/authoring/scripts/lib/plugin-version-check.mjs.map +1 -0
  22. package/dist/authoring/scripts/lib/semver.d.mts +9 -0
  23. package/dist/authoring/scripts/lib/semver.mjs +63 -0
  24. package/dist/authoring/scripts/lib/semver.mjs.map +1 -0
  25. package/dist/authoring/scripts/lib/skill-scaffold.d.mts +124 -0
  26. package/dist/authoring/scripts/lib/skill-scaffold.mjs +374 -0
  27. package/dist/authoring/scripts/lib/skill-scaffold.mjs.map +1 -0
  28. package/dist/authoring/scripts/plugin-status.d.mts +2 -0
  29. package/dist/authoring/scripts/plugin-status.mjs +96 -0
  30. package/dist/authoring/scripts/plugin-status.mjs.map +1 -0
  31. package/dist/authoring/scripts/validate-plugin.d.mts +2 -0
  32. package/dist/authoring/scripts/validate-plugin.mjs +4442 -0
  33. package/dist/authoring/scripts/validate-plugin.mjs.map +1 -0
  34. package/dist/authoring/scripts/validate-skill.d.mts +2 -0
  35. package/dist/authoring/scripts/validate-skill.mjs +126 -0
  36. package/dist/authoring/scripts/validate-skill.mjs.map +1 -0
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.js +8 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/scripts/aw-skill-eval-engine.d.ts +13 -0
  41. package/dist/scripts/aw-skill-eval-engine.js +31 -0
  42. package/dist/scripts/aw-skill-eval-engine.js.map +1 -0
  43. package/dist/scripts/bundle-plugins.d.ts +18 -0
  44. package/dist/scripts/bundle-plugins.js +123 -0
  45. package/dist/scripts/bundle-plugins.js.map +1 -0
  46. package/dist/scripts/codex-eval-app-server.d.ts +89 -0
  47. package/dist/scripts/codex-eval-app-server.js +1228 -0
  48. package/dist/scripts/codex-eval-app-server.js.map +1 -0
  49. package/dist/scripts/codex-eval-isolation.d.ts +61 -0
  50. package/dist/scripts/codex-eval-isolation.js +318 -0
  51. package/dist/scripts/codex-eval-isolation.js.map +1 -0
  52. package/dist/scripts/codex-eval-process-management.d.ts +8 -0
  53. package/dist/scripts/codex-eval-process-management.js +69 -0
  54. package/dist/scripts/codex-eval-process-management.js.map +1 -0
  55. package/dist/scripts/codex-eval-process-tree.d.ts +38 -0
  56. package/dist/scripts/codex-eval-process-tree.js +803 -0
  57. package/dist/scripts/codex-eval-process-tree.js.map +1 -0
  58. package/dist/scripts/codex-eval-runtime-config.d.ts +62 -0
  59. package/dist/scripts/codex-eval-runtime-config.js +843 -0
  60. package/dist/scripts/codex-eval-runtime-config.js.map +1 -0
  61. package/dist/scripts/codex-trigger-eval.d.ts +84 -0
  62. package/dist/scripts/codex-trigger-eval.js +968 -0
  63. package/dist/scripts/codex-trigger-eval.js.map +1 -0
  64. package/dist/scripts/eval-plugin-skills-audited.d.ts +6 -0
  65. package/dist/scripts/eval-plugin-skills-audited.js +261 -0
  66. package/dist/scripts/eval-plugin-skills-audited.js.map +1 -0
  67. package/dist/scripts/eval-plugin-skills.d.ts +45 -0
  68. package/dist/scripts/eval-plugin-skills.js +1586 -0
  69. package/dist/scripts/eval-plugin-skills.js.map +1 -0
  70. package/dist/scripts/eval-run-layout.d.ts +17 -0
  71. package/dist/scripts/eval-run-layout.js +26 -0
  72. package/dist/scripts/eval-run-layout.js.map +1 -0
  73. package/dist/scripts/plugin-eval-contract.d.ts +185 -0
  74. package/dist/scripts/plugin-eval-contract.js +695 -0
  75. package/dist/scripts/plugin-eval-contract.js.map +1 -0
  76. package/dist/scripts/plugin-eval-materializer.d.ts +13 -0
  77. package/dist/scripts/plugin-eval-materializer.js +421 -0
  78. package/dist/scripts/plugin-eval-materializer.js.map +1 -0
  79. package/dist/scripts/plugin-staging.d.ts +43 -0
  80. package/dist/scripts/plugin-staging.js +196 -0
  81. package/dist/scripts/plugin-staging.js.map +1 -0
  82. package/dist/scripts/skill-reporting.d.ts +212 -0
  83. package/dist/scripts/skill-reporting.js +922 -0
  84. package/dist/scripts/skill-reporting.js.map +1 -0
  85. package/dist/scripts/test-plugin-scripts.d.ts +7 -0
  86. package/dist/scripts/test-plugin-scripts.js +674 -0
  87. package/dist/scripts/test-plugin-scripts.js.map +1 -0
  88. package/dist/src/adapters/helpers.d.ts +44 -0
  89. package/dist/src/adapters/helpers.js +95 -0
  90. package/dist/src/adapters/helpers.js.map +1 -0
  91. package/dist/src/authoring/workspace-commands.d.ts +46 -0
  92. package/dist/src/authoring/workspace-commands.js +133 -0
  93. package/dist/src/authoring/workspace-commands.js.map +1 -0
  94. package/dist/src/commands/catalog-publish.d.ts +33 -0
  95. package/dist/src/commands/catalog-publish.js +374 -0
  96. package/dist/src/commands/catalog-publish.js.map +1 -0
  97. package/dist/src/commands/catalog-source.d.ts +111 -0
  98. package/dist/src/commands/catalog-source.js +266 -0
  99. package/dist/src/commands/catalog-source.js.map +1 -0
  100. package/dist/src/commands/console.d.ts +3 -0
  101. package/dist/src/commands/console.js +44 -0
  102. package/dist/src/commands/console.js.map +1 -0
  103. package/dist/src/commands/dependency-operation-plan.d.ts +28 -0
  104. package/dist/src/commands/dependency-operation-plan.js +15 -0
  105. package/dist/src/commands/dependency-operation-plan.js.map +1 -0
  106. package/dist/src/commands/init.d.ts +31 -0
  107. package/dist/src/commands/init.js +63 -0
  108. package/dist/src/commands/init.js.map +1 -0
  109. package/dist/src/commands/options.d.ts +68 -0
  110. package/dist/src/commands/options.js +146 -0
  111. package/dist/src/commands/options.js.map +1 -0
  112. package/dist/src/commands/rebuild-command.d.ts +77 -0
  113. package/dist/src/commands/rebuild-command.js +1681 -0
  114. package/dist/src/commands/rebuild-command.js.map +1 -0
  115. package/dist/src/commands/rebuild-integration.d.ts +94 -0
  116. package/dist/src/commands/rebuild-integration.js +3289 -0
  117. package/dist/src/commands/rebuild-integration.js.map +1 -0
  118. package/dist/src/commands/rebuild-operations.d.ts +110 -0
  119. package/dist/src/commands/rebuild-operations.js +791 -0
  120. package/dist/src/commands/rebuild-operations.js.map +1 -0
  121. package/dist/src/commands/review-publication.d.ts +99 -0
  122. package/dist/src/commands/review-publication.js +904 -0
  123. package/dist/src/commands/review-publication.js.map +1 -0
  124. package/dist/src/commands/runtime.d.ts +176 -0
  125. package/dist/src/commands/runtime.js +746 -0
  126. package/dist/src/commands/runtime.js.map +1 -0
  127. package/dist/src/commands/status-v4.d.ts +102 -0
  128. package/dist/src/commands/status-v4.js +844 -0
  129. package/dist/src/commands/status-v4.js.map +1 -0
  130. package/dist/src/commands/status.d.ts +93 -0
  131. package/dist/src/commands/status.js +442 -0
  132. package/dist/src/commands/status.js.map +1 -0
  133. package/dist/src/commands/wizard.d.ts +57 -0
  134. package/dist/src/commands/wizard.js +58 -0
  135. package/dist/src/commands/wizard.js.map +1 -0
  136. package/dist/src/commands/write-commands.d.ts +7 -0
  137. package/dist/src/commands/write-commands.js +167 -0
  138. package/dist/src/commands/write-commands.js.map +1 -0
  139. package/dist/src/constants.d.ts +25 -0
  140. package/dist/src/constants.js +26 -0
  141. package/dist/src/constants.js.map +1 -0
  142. package/dist/src/generators/agents.d.ts +3 -0
  143. package/dist/src/generators/agents.js +46 -0
  144. package/dist/src/generators/agents.js.map +1 -0
  145. package/dist/src/generators/hooks.d.ts +15 -0
  146. package/dist/src/generators/hooks.js +76 -0
  147. package/dist/src/generators/hooks.js.map +1 -0
  148. package/dist/src/generators/instructions.d.ts +13 -0
  149. package/dist/src/generators/instructions.js +66 -0
  150. package/dist/src/generators/instructions.js.map +1 -0
  151. package/dist/src/generators/local-plugin.d.ts +53 -0
  152. package/dist/src/generators/local-plugin.js +1268 -0
  153. package/dist/src/generators/local-plugin.js.map +1 -0
  154. package/dist/src/generators/permissions.d.ts +10 -0
  155. package/dist/src/generators/permissions.js +37 -0
  156. package/dist/src/generators/permissions.js.map +1 -0
  157. package/dist/src/generators/shared.d.ts +2 -0
  158. package/dist/src/generators/shared.js +15 -0
  159. package/dist/src/generators/shared.js.map +1 -0
  160. package/dist/src/index.d.ts +35 -0
  161. package/dist/src/index.js +2344 -0
  162. package/dist/src/index.js.map +1 -0
  163. package/dist/src/output/command-receipt.d.ts +90 -0
  164. package/dist/src/output/command-receipt.js +129 -0
  165. package/dist/src/output/command-receipt.js.map +1 -0
  166. package/dist/src/output/debug-log.d.ts +4 -0
  167. package/dist/src/output/debug-log.js +97 -0
  168. package/dist/src/output/debug-log.js.map +1 -0
  169. package/dist/src/output/equivalent-command.d.ts +9 -0
  170. package/dist/src/output/equivalent-command.js +39 -0
  171. package/dist/src/output/equivalent-command.js.map +1 -0
  172. package/dist/src/output/model.d.ts +117 -0
  173. package/dist/src/output/model.js +145 -0
  174. package/dist/src/output/model.js.map +1 -0
  175. package/dist/src/output/rebuild-progress.d.ts +21 -0
  176. package/dist/src/output/rebuild-progress.js +138 -0
  177. package/dist/src/output/rebuild-progress.js.map +1 -0
  178. package/dist/src/output/redact.d.ts +3 -0
  179. package/dist/src/output/redact.js +39 -0
  180. package/dist/src/output/redact.js.map +1 -0
  181. package/dist/src/output/reporter.d.ts +9 -0
  182. package/dist/src/output/reporter.js +133 -0
  183. package/dist/src/output/reporter.js.map +1 -0
  184. package/dist/src/portable/commands.d.ts +120 -0
  185. package/dist/src/portable/commands.js +506 -0
  186. package/dist/src/portable/commands.js.map +1 -0
  187. package/dist/src/portable/materializer.d.ts +50 -0
  188. package/dist/src/portable/materializer.js +408 -0
  189. package/dist/src/portable/materializer.js.map +1 -0
  190. package/dist/src/portable/skills-cli.d.ts +43 -0
  191. package/dist/src/portable/skills-cli.js +148 -0
  192. package/dist/src/portable/skills-cli.js.map +1 -0
  193. package/dist/src/tui/components.d.ts +32 -0
  194. package/dist/src/tui/components.js +42 -0
  195. package/dist/src/tui/components.js.map +1 -0
  196. package/dist/src/tui/console-app-v4.d.ts +20 -0
  197. package/dist/src/tui/console-app-v4.js +2613 -0
  198. package/dist/src/tui/console-app-v4.js.map +1 -0
  199. package/dist/src/tui/controller-runtime.d.ts +11 -0
  200. package/dist/src/tui/controller-runtime.js +902 -0
  201. package/dist/src/tui/controller-runtime.js.map +1 -0
  202. package/dist/src/tui/controller.d.ts +367 -0
  203. package/dist/src/tui/controller.js +1724 -0
  204. package/dist/src/tui/controller.js.map +1 -0
  205. package/dist/src/tui/index.d.ts +13 -0
  206. package/dist/src/tui/index.js +14 -0
  207. package/dist/src/tui/index.js.map +1 -0
  208. package/dist/src/tui/keys.d.ts +12 -0
  209. package/dist/src/tui/keys.js +22 -0
  210. package/dist/src/tui/keys.js.map +1 -0
  211. package/dist/src/tui/layout.d.ts +12 -0
  212. package/dist/src/tui/layout.js +19 -0
  213. package/dist/src/tui/layout.js.map +1 -0
  214. package/dist/src/tui/model.d.ts +279 -0
  215. package/dist/src/tui/model.js +652 -0
  216. package/dist/src/tui/model.js.map +1 -0
  217. package/dist/src/tui/prompt.d.ts +8 -0
  218. package/dist/src/tui/prompt.js +242 -0
  219. package/dist/src/tui/prompt.js.map +1 -0
  220. package/dist/src/tui/router.d.ts +153 -0
  221. package/dist/src/tui/router.js +102 -0
  222. package/dist/src/tui/router.js.map +1 -0
  223. package/dist/src/tui/runner.d.ts +11 -0
  224. package/dist/src/tui/runner.js +71 -0
  225. package/dist/src/tui/runner.js.map +1 -0
  226. package/dist/src/tui/theme.d.ts +18 -0
  227. package/dist/src/tui/theme.js +20 -0
  228. package/dist/src/tui/theme.js.map +1 -0
  229. package/dist/src/tui/views.d.ts +57 -0
  230. package/dist/src/tui/views.js +173 -0
  231. package/dist/src/tui/views.js.map +1 -0
  232. package/dist/src/tui/wizard.d.ts +11 -0
  233. package/dist/src/tui/wizard.js +321 -0
  234. package/dist/src/tui/wizard.js.map +1 -0
  235. package/dist/src/types.d.ts +313 -0
  236. package/dist/src/types.js +33 -0
  237. package/dist/src/types.js.map +1 -0
  238. package/dist/src/utils/active-marketplace-runtime-lock.d.ts +12 -0
  239. package/dist/src/utils/active-marketplace-runtime-lock.js +133 -0
  240. package/dist/src/utils/active-marketplace-runtime-lock.js.map +1 -0
  241. package/dist/src/utils/agent-version.d.ts +13 -0
  242. package/dist/src/utils/agent-version.js +172 -0
  243. package/dist/src/utils/agent-version.js.map +1 -0
  244. package/dist/src/utils/artifact-plan.d.ts +26 -0
  245. package/dist/src/utils/artifact-plan.js +444 -0
  246. package/dist/src/utils/artifact-plan.js.map +1 -0
  247. package/dist/src/utils/artifact-renderer.d.ts +124 -0
  248. package/dist/src/utils/artifact-renderer.js +442 -0
  249. package/dist/src/utils/artifact-renderer.js.map +1 -0
  250. package/dist/src/utils/artifact-sources.d.ts +8 -0
  251. package/dist/src/utils/artifact-sources.js +10 -0
  252. package/dist/src/utils/artifact-sources.js.map +1 -0
  253. package/dist/src/utils/aw-home-mutation-lock.d.ts +10 -0
  254. package/dist/src/utils/aw-home-mutation-lock.js +55 -0
  255. package/dist/src/utils/aw-home-mutation-lock.js.map +1 -0
  256. package/dist/src/utils/bundle-integrity.d.ts +3 -0
  257. package/dist/src/utils/bundle-integrity.js +88 -0
  258. package/dist/src/utils/bundle-integrity.js.map +1 -0
  259. package/dist/src/utils/bundle-layout.d.ts +4 -0
  260. package/dist/src/utils/bundle-layout.js +546 -0
  261. package/dist/src/utils/bundle-layout.js.map +1 -0
  262. package/dist/src/utils/catalog-digests.d.ts +8 -0
  263. package/dist/src/utils/catalog-digests.js +108 -0
  264. package/dist/src/utils/catalog-digests.js.map +1 -0
  265. package/dist/src/utils/catalog-manifest-v3.d.ts +2 -0
  266. package/dist/src/utils/catalog-manifest-v3.js +3 -0
  267. package/dist/src/utils/catalog-manifest-v3.js.map +1 -0
  268. package/dist/src/utils/catalog-manifest-v4.d.ts +5 -0
  269. package/dist/src/utils/catalog-manifest-v4.js +106 -0
  270. package/dist/src/utils/catalog-manifest-v4.js.map +1 -0
  271. package/dist/src/utils/catalog-public-error.d.ts +15 -0
  272. package/dist/src/utils/catalog-public-error.js +84 -0
  273. package/dist/src/utils/catalog-public-error.js.map +1 -0
  274. package/dist/src/utils/catalog-runtime-projection.d.ts +36 -0
  275. package/dist/src/utils/catalog-runtime-projection.js +172 -0
  276. package/dist/src/utils/catalog-runtime-projection.js.map +1 -0
  277. package/dist/src/utils/catalog-snapshot.d.ts +8 -0
  278. package/dist/src/utils/catalog-snapshot.js +12 -0
  279. package/dist/src/utils/catalog-snapshot.js.map +1 -0
  280. package/dist/src/utils/catalog-source-cache.d.ts +61 -0
  281. package/dist/src/utils/catalog-source-cache.js +276 -0
  282. package/dist/src/utils/catalog-source-cache.js.map +1 -0
  283. package/dist/src/utils/catalog-source-identity.d.ts +4 -0
  284. package/dist/src/utils/catalog-source-identity.js +118 -0
  285. package/dist/src/utils/catalog-source-identity.js.map +1 -0
  286. package/dist/src/utils/catalog-source-presentation.d.ts +1 -0
  287. package/dist/src/utils/catalog-source-presentation.js +32 -0
  288. package/dist/src/utils/catalog-source-presentation.js.map +1 -0
  289. package/dist/src/utils/catalog-source-references.d.ts +65 -0
  290. package/dist/src/utils/catalog-source-references.js +1418 -0
  291. package/dist/src/utils/catalog-source-references.js.map +1 -0
  292. package/dist/src/utils/catalog-sources.d.ts +39 -0
  293. package/dist/src/utils/catalog-sources.js +293 -0
  294. package/dist/src/utils/catalog-sources.js.map +1 -0
  295. package/dist/src/utils/codex-config.d.ts +124 -0
  296. package/dist/src/utils/codex-config.js +1011 -0
  297. package/dist/src/utils/codex-config.js.map +1 -0
  298. package/dist/src/utils/codex-project-surface.d.ts +3 -0
  299. package/dist/src/utils/codex-project-surface.js +49 -0
  300. package/dist/src/utils/codex-project-surface.js.map +1 -0
  301. package/dist/src/utils/codex-roles.d.ts +71 -0
  302. package/dist/src/utils/codex-roles.js +257 -0
  303. package/dist/src/utils/codex-roles.js.map +1 -0
  304. package/dist/src/utils/codex-skill-staging.d.ts +9 -0
  305. package/dist/src/utils/codex-skill-staging.js +8 -0
  306. package/dist/src/utils/codex-skill-staging.js.map +1 -0
  307. package/dist/src/utils/config-value.d.ts +3 -0
  308. package/dist/src/utils/config-value.js +23 -0
  309. package/dist/src/utils/config-value.js.map +1 -0
  310. package/dist/src/utils/dynamic-skill-tree.d.ts +32 -0
  311. package/dist/src/utils/dynamic-skill-tree.js +436 -0
  312. package/dist/src/utils/dynamic-skill-tree.js.map +1 -0
  313. package/dist/src/utils/file-rules.d.ts +1 -0
  314. package/dist/src/utils/file-rules.js +2 -0
  315. package/dist/src/utils/file-rules.js.map +1 -0
  316. package/dist/src/utils/git-catalog-provider.d.ts +7 -0
  317. package/dist/src/utils/git-catalog-provider.js +510 -0
  318. package/dist/src/utils/git-catalog-provider.js.map +1 -0
  319. package/dist/src/utils/hooks-contract.d.ts +1 -0
  320. package/dist/src/utils/hooks-contract.js +2 -0
  321. package/dist/src/utils/hooks-contract.js.map +1 -0
  322. package/dist/src/utils/json.d.ts +4 -0
  323. package/dist/src/utils/json.js +29 -0
  324. package/dist/src/utils/json.js.map +1 -0
  325. package/dist/src/utils/lifecycle-active-store.d.ts +175 -0
  326. package/dist/src/utils/lifecycle-active-store.js +1276 -0
  327. package/dist/src/utils/lifecycle-active-store.js.map +1 -0
  328. package/dist/src/utils/local-marketplace.d.ts +41 -0
  329. package/dist/src/utils/local-marketplace.js +317 -0
  330. package/dist/src/utils/local-marketplace.js.map +1 -0
  331. package/dist/src/utils/manifest.d.ts +14 -0
  332. package/dist/src/utils/manifest.js +36 -0
  333. package/dist/src/utils/manifest.js.map +1 -0
  334. package/dist/src/utils/marketplace.d.ts +3 -0
  335. package/dist/src/utils/marketplace.js +76 -0
  336. package/dist/src/utils/marketplace.js.map +1 -0
  337. package/dist/src/utils/multi-source-catalog.d.ts +72 -0
  338. package/dist/src/utils/multi-source-catalog.js +402 -0
  339. package/dist/src/utils/multi-source-catalog.js.map +1 -0
  340. package/dist/src/utils/native-cli.d.ts +75 -0
  341. package/dist/src/utils/native-cli.js +435 -0
  342. package/dist/src/utils/native-cli.js.map +1 -0
  343. package/dist/src/utils/orphan-marketplace-cleanup.d.ts +18 -0
  344. package/dist/src/utils/orphan-marketplace-cleanup.js +202 -0
  345. package/dist/src/utils/orphan-marketplace-cleanup.js.map +1 -0
  346. package/dist/src/utils/ownership.d.ts +130 -0
  347. package/dist/src/utils/ownership.js +766 -0
  348. package/dist/src/utils/ownership.js.map +1 -0
  349. package/dist/src/utils/path-catalog-provider.d.ts +7 -0
  350. package/dist/src/utils/path-catalog-provider.js +87 -0
  351. package/dist/src/utils/path-catalog-provider.js.map +1 -0
  352. package/dist/src/utils/paths.d.ts +41 -0
  353. package/dist/src/utils/paths.js +138 -0
  354. package/dist/src/utils/paths.js.map +1 -0
  355. package/dist/src/utils/platform-entries.d.ts +1 -0
  356. package/dist/src/utils/platform-entries.js +2 -0
  357. package/dist/src/utils/platform-entries.js.map +1 -0
  358. package/dist/src/utils/platform-support.d.ts +1 -0
  359. package/dist/src/utils/platform-support.js +2 -0
  360. package/dist/src/utils/platform-support.js.map +1 -0
  361. package/dist/src/utils/plugin-authoring-capabilities.d.ts +23 -0
  362. package/dist/src/utils/plugin-authoring-capabilities.js +37 -0
  363. package/dist/src/utils/plugin-authoring-capabilities.js.map +1 -0
  364. package/dist/src/utils/plugin-authoring-capabilities.json +92 -0
  365. package/dist/src/utils/plugin-config-write.d.ts +107 -0
  366. package/dist/src/utils/plugin-config-write.js +565 -0
  367. package/dist/src/utils/plugin-config-write.js.map +1 -0
  368. package/dist/src/utils/plugin-config.d.ts +396 -0
  369. package/dist/src/utils/plugin-config.js +1898 -0
  370. package/dist/src/utils/plugin-config.js.map +1 -0
  371. package/dist/src/utils/plugin-dependencies.d.ts +12 -0
  372. package/dist/src/utils/plugin-dependencies.js +162 -0
  373. package/dist/src/utils/plugin-dependencies.js.map +1 -0
  374. package/dist/src/utils/plugin-release.d.ts +2 -0
  375. package/dist/src/utils/plugin-release.js +2 -0
  376. package/dist/src/utils/plugin-release.js.map +1 -0
  377. package/dist/src/utils/plugin-script-contract.d.ts +1 -0
  378. package/dist/src/utils/plugin-script-contract.js +2 -0
  379. package/dist/src/utils/plugin-script-contract.js.map +1 -0
  380. package/dist/src/utils/plugin-scripts.d.ts +172 -0
  381. package/dist/src/utils/plugin-scripts.js +585 -0
  382. package/dist/src/utils/plugin-scripts.js.map +1 -0
  383. package/dist/src/utils/process-lock.d.ts +47 -0
  384. package/dist/src/utils/process-lock.js +532 -0
  385. package/dist/src/utils/process-lock.js.map +1 -0
  386. package/dist/src/utils/process-tree.d.ts +2 -0
  387. package/dist/src/utils/process-tree.js +2 -0
  388. package/dist/src/utils/process-tree.js.map +1 -0
  389. package/dist/src/utils/project-boundary.d.ts +21 -0
  390. package/dist/src/utils/project-boundary.js +95 -0
  391. package/dist/src/utils/project-boundary.js.map +1 -0
  392. package/dist/src/utils/rendered-contract.d.ts +8 -0
  393. package/dist/src/utils/rendered-contract.js +134 -0
  394. package/dist/src/utils/rendered-contract.js.map +1 -0
  395. package/dist/src/utils/runtime-skill-closure.d.ts +13 -0
  396. package/dist/src/utils/runtime-skill-closure.js +863 -0
  397. package/dist/src/utils/runtime-skill-closure.js.map +1 -0
  398. package/dist/src/utils/skill-authoring.d.ts +1 -0
  399. package/dist/src/utils/skill-authoring.js +2 -0
  400. package/dist/src/utils/skill-authoring.js.map +1 -0
  401. package/dist/src/utils/skill-frontmatter-capabilities.d.ts +201 -0
  402. package/dist/src/utils/skill-frontmatter-capabilities.js +5 -0
  403. package/dist/src/utils/skill-frontmatter-capabilities.js.map +1 -0
  404. package/dist/src/utils/skill-frontmatter-capabilities.json +200 -0
  405. package/dist/src/utils/skill-validation.d.ts +37 -0
  406. package/dist/src/utils/skill-validation.js +326 -0
  407. package/dist/src/utils/skill-validation.js.map +1 -0
  408. package/dist/src/utils/slash-commands.d.ts +1 -0
  409. package/dist/src/utils/slash-commands.js +2 -0
  410. package/dist/src/utils/slash-commands.js.map +1 -0
  411. package/dist/src/utils/state-paths.d.ts +13 -0
  412. package/dist/src/utils/state-paths.js +129 -0
  413. package/dist/src/utils/state-paths.js.map +1 -0
  414. package/dist/src/utils/target-eligibility.d.ts +7 -0
  415. package/dist/src/utils/target-eligibility.js +26 -0
  416. package/dist/src/utils/target-eligibility.js.map +1 -0
  417. package/dist/src/utils/target-order.d.ts +7 -0
  418. package/dist/src/utils/target-order.js +10 -0
  419. package/dist/src/utils/target-order.js.map +1 -0
  420. package/dist/src/utils/template-engine.d.ts +1 -0
  421. package/dist/src/utils/template-engine.js +2 -0
  422. package/dist/src/utils/template-engine.js.map +1 -0
  423. package/dist/src/utils/test-path-fence.d.ts +12 -0
  424. package/dist/src/utils/test-path-fence.js +31 -0
  425. package/dist/src/utils/test-path-fence.js.map +1 -0
  426. package/dist/vitest.config.d.ts +2 -0
  427. package/dist/vitest.config.js +16 -0
  428. package/dist/vitest.config.js.map +1 -0
  429. package/package.json +61 -0
@@ -0,0 +1,1681 @@
1
+ import path from 'node:path';
2
+ import fs from 'fs-extra';
3
+ import { probeAgentVersion } from '../utils/agent-version.js';
4
+ import { createNoopDebugLogger } from '../output/debug-log.js';
5
+ import { createNoopReporter } from '../output/reporter.js';
6
+ import { getDefaultNativeCliRunner } from '../utils/native-cli.js';
7
+ import { readPluginManifest, resolvePluginsFromCatalog } from '../utils/manifest.js';
8
+ import { resolveAwHome } from '../utils/paths.js';
9
+ import { resolveCliPackageRoot } from '../utils/paths.js';
10
+ import { supportsPlatform } from '../utils/platform-support.js';
11
+ import { hasCodexProjectManagedArtifacts } from '../utils/codex-project-surface.js';
12
+ import { createRebuildActiveStore, executeRebuildOperation, releaseRebuildOperationLease, } from './rebuild-operations.js';
13
+ import { assertNoClaudeUnboundNativeNameCollision, createRebuildIntegration, discoverRebuildTargetNames, inspectNativeMarketplaceRegistrations, } from './rebuild-integration.js';
14
+ import { getNamespacedMarketplaceName } from '../utils/local-marketplace.js';
15
+ import { formatPluginId, parsePluginId, planPluginSelectorSourceIds, preflightDesiredArtifactCollisions, withResolvedMultiSourceCatalog, } from '../utils/multi-source-catalog.js';
16
+ import { assertStrictSemVer } from '../utils/manifest.js';
17
+ import { assertCatalogSourceInventoryComplete, canonicalMarketplaceRegistrationNames, inventoryCatalogSourceReferences, } from '../utils/catalog-source-references.js';
18
+ import { resolveEffectivePluginConfig } from '../utils/plugin-config.js';
19
+ import { cleanupCorruptExclusivePluginDirectory, inspectOwnedComponents, } from '../utils/ownership.js';
20
+ import { getClaudeHome, getCodexHome, resolveCanonicalRepoProjectKey, resolveRepoRootSync, } from '../utils/state-paths.js';
21
+ import { resolvePluginMetaDependencyClosure } from '../utils/plugin-dependencies.js';
22
+ import { createDependencyOperationPlan, } from './dependency-operation-plan.js';
23
+ let rebuildCommandTestHooks;
24
+ async function emitRebuildActionEvent(runtime, event) {
25
+ await Promise.allSettled([
26
+ Promise.resolve().then(() => runtime.reporter.event(event)),
27
+ Promise.resolve().then(() => runtime.debugLogger.log(event)),
28
+ ]);
29
+ }
30
+ async function withRebuildActionEvent(options) {
31
+ const source = {
32
+ plugin: options.identity.pluginName,
33
+ platform: options.identity.platform,
34
+ scope: options.identity.scope,
35
+ action: options.command,
36
+ };
37
+ const startedAt = Date.now();
38
+ await emitRebuildActionEvent(options.runtime, {
39
+ type: 'rebuild:action',
40
+ source,
41
+ data: { name: options.name, phase: 'start' },
42
+ });
43
+ let result;
44
+ try {
45
+ result = await options.operation();
46
+ }
47
+ catch (error) {
48
+ await emitRebuildActionEvent(options.runtime, {
49
+ type: 'rebuild:action',
50
+ source,
51
+ data: {
52
+ name: options.name,
53
+ phase: 'failure',
54
+ durationMs: Math.max(0, Date.now() - startedAt),
55
+ message: options.name === 'operation.lock'
56
+ ? '获取操作锁失败。'
57
+ : '释放操作锁失败。',
58
+ },
59
+ });
60
+ throw error;
61
+ }
62
+ await emitRebuildActionEvent(options.runtime, {
63
+ type: 'rebuild:action',
64
+ source,
65
+ data: {
66
+ name: options.name,
67
+ phase: 'success',
68
+ durationMs: Math.max(0, Date.now() - startedAt),
69
+ },
70
+ });
71
+ return result;
72
+ }
73
+ export function setRebuildCommandTestHooksForTests(hooks) {
74
+ rebuildCommandTestHooks = hooks;
75
+ }
76
+ function selectedPlatforms(selection) {
77
+ return selection === 'both' ? ['codex', 'claude'] : [selection];
78
+ }
79
+ function createSyntheticPlugin(pluginName, env) {
80
+ const rootDir = path.join(resolveAwHome(env), 'plugins', pluginName);
81
+ return {
82
+ rootDir,
83
+ manifestPath: path.join(rootDir, '.agents-plugin', 'plugin.json'),
84
+ manifest: {
85
+ schemaVersion: 1,
86
+ name: pluginName,
87
+ version: '0.0.0',
88
+ description: 'Cleanup-only target for a plugin missing from the current catalog.',
89
+ compatibility: { aw: { minVersion: '0.0.0' } },
90
+ marketplace: {
91
+ category: 'cleanup',
92
+ strict: true,
93
+ policy: { installation: 'AVAILABLE', authentication: 'ON_INSTALL' },
94
+ },
95
+ },
96
+ };
97
+ }
98
+ function failedResult(command, identity, message, phase = 'preflight') {
99
+ return {
100
+ status: 'failed',
101
+ command,
102
+ target: identity,
103
+ actions: phase === 'preflight' ? [] : [{ name: phase, status: 'failed' }],
104
+ cleanupAttempted: false,
105
+ removed: [],
106
+ absent: [],
107
+ residual: [],
108
+ quarantined: [],
109
+ failures: [{ phase, message }],
110
+ error: { phase, message },
111
+ };
112
+ }
113
+ function appendOperationReleaseFailure(result, message) {
114
+ result.actions.push({ name: 'operation.release', status: 'failed' });
115
+ result.failures.push({ phase: 'operation.release', message });
116
+ if (result.status === 'failed')
117
+ return result;
118
+ return {
119
+ ...result,
120
+ status: 'failed',
121
+ error: { phase: 'operation.release', message },
122
+ };
123
+ }
124
+ function toTargetResult(result) {
125
+ return {
126
+ target: {
127
+ pluginName: result.target.pluginName,
128
+ ...(result.target.sourceId ? {
129
+ sourceId: result.target.sourceId,
130
+ sourceIdentity: result.target.sourceIdentity,
131
+ pluginId: result.target.pluginId,
132
+ } : {}),
133
+ platform: result.target.platform,
134
+ scope: result.target.scope,
135
+ },
136
+ action: result.command,
137
+ state: result.status === 'succeeded' ? 'completed' : 'failed',
138
+ ...(result.status === 'failed' ? { message: result.error.message } : {}),
139
+ };
140
+ }
141
+ async function assertAgentVersions(options) {
142
+ const failures = [];
143
+ for (const platform of options.platforms) {
144
+ const result = await probeAgentVersion(platform, {
145
+ cwd: options.cwd,
146
+ env: options.env,
147
+ runner: options.runtime.nativeCliRunner,
148
+ });
149
+ if (result.status !== 'supported')
150
+ failures.push(result);
151
+ }
152
+ if (failures.length > 0) {
153
+ throw new Error(failures.map((failure) => `${failure.command} 版本检查失败:${failure.details ?? failure.status};最低版本 ${failure.requiredMinVersion}。`)
154
+ .join(';'));
155
+ }
156
+ }
157
+ async function resolveRequestedNames(options) {
158
+ const result = new Map();
159
+ for (const platform of options.platforms) {
160
+ const names = options.command === 'upgrade' && options.all
161
+ ? await discoverRebuildTargetNames({
162
+ cwd: options.cwd,
163
+ env: options.env,
164
+ platform,
165
+ scope: options.scope,
166
+ nativeCliRunner: options.nativeCliRunner,
167
+ nativeFailureMode: 'error',
168
+ })
169
+ : options.pluginNames;
170
+ result.set(platform, [...new Set(names)]);
171
+ }
172
+ return result;
173
+ }
174
+ async function runSingleSourceRebuildCommand(options) {
175
+ const runtime = options.runtime?.preparedTarget?.context ?? {
176
+ env: options.runtime?.env ?? process.env,
177
+ nativeCliRunner: options.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
178
+ reporter: options.runtime?.reporter ?? createNoopReporter(),
179
+ debugLogger: options.runtime?.debugLogger ?? createNoopDebugLogger(),
180
+ runtimeLeaseHeld: options.runtime?.runtimeLeaseHeld,
181
+ lifecycleLeaseHeld: options.runtime?.lifecycleLeaseHeld,
182
+ expectedCatalogConfigDigest: options.runtime?.expectedCatalogConfigDigest,
183
+ };
184
+ const env = runtime.env;
185
+ const selected = selectedPlatforms(options.commandOptions.platform);
186
+ const catalog = options.runtime?.catalogResolution;
187
+ if (!catalog)
188
+ throw new Error('Internal error: a resolved catalog source is required.');
189
+ const catalogPlugins = await resolvePluginsFromCatalog(catalog.rootDir, undefined);
190
+ if (options.runtime?.namespacedSource) {
191
+ for (const plugin of catalogPlugins) {
192
+ plugin.sourceId = options.runtime.namespacedSource.sourceId;
193
+ plugin.sourceIdentity = options.runtime.namespacedSource.sourceIdentity;
194
+ plugin.pluginId = formatPluginId({
195
+ sourceId: options.runtime.namespacedSource.sourceId,
196
+ pluginName: plugin.manifest.name,
197
+ });
198
+ plugin.marketplaceName = options.runtime.namespacedSource.marketplaceName;
199
+ }
200
+ }
201
+ const catalogByName = new Map(catalogPlugins.map((plugin) => [plugin.manifest.name, plugin]));
202
+ const requestedByPlatform = await resolveRequestedNames({
203
+ command: options.command,
204
+ pluginNames: options.pluginNames,
205
+ all: options.all,
206
+ platforms: selected,
207
+ scope: options.commandOptions.scope,
208
+ cwd: options.commandOptions.cwd,
209
+ env,
210
+ nativeCliRunner: runtime.nativeCliRunner,
211
+ });
212
+ if (options.commandOptions.platform === 'both'
213
+ && options.command !== 'cleanup'
214
+ && options.command !== 'uninstall') {
215
+ for (const platform of selected) {
216
+ requestedByPlatform.set(platform, (requestedByPlatform.get(platform) ?? []).filter((pluginName) => {
217
+ const plugin = catalogByName.get(pluginName);
218
+ return !plugin || supportsPlatform(plugin.manifest, platform);
219
+ }));
220
+ }
221
+ }
222
+ const platforms = selected.filter((platform) => (requestedByPlatform.get(platform)?.length ?? 0) > 0);
223
+ await assertAgentVersions({
224
+ platforms,
225
+ cwd: options.commandOptions.cwd,
226
+ env,
227
+ runtime,
228
+ });
229
+ const integration = options.runtime?.preparedTarget
230
+ ? {
231
+ driver: options.runtime.preparedTarget.driver,
232
+ buildTarget: async () => options.runtime.preparedTarget.target,
233
+ }
234
+ : createRebuildIntegration({
235
+ context: runtime,
236
+ scriptTimeoutMs: options.commandOptions.scriptTimeoutMs,
237
+ });
238
+ const activeStore = createRebuildActiveStore({
239
+ env,
240
+ loadPlugin: (bundleRoot) => readPluginManifest(bundleRoot, { mode: 'bundle' }),
241
+ isLifecycleLeaseHeld: () => runtime.lifecycleLeaseHeld === true,
242
+ });
243
+ const targets = [];
244
+ const results = [];
245
+ for (const platform of platforms) {
246
+ for (const pluginName of requestedByPlatform.get(platform) ?? []) {
247
+ const currentPlugin = catalogByName.get(pluginName);
248
+ const identity = {
249
+ ...(options.runtime?.namespacedSource ?? {}),
250
+ ...(options.runtime?.namespacedSource ? {
251
+ pluginId: formatPluginId({
252
+ sourceId: options.runtime.namespacedSource.sourceId,
253
+ pluginName,
254
+ }),
255
+ } : currentPlugin?.pluginId ? { pluginId: currentPlugin.pluginId } : {}),
256
+ pluginName,
257
+ pluginVersion: currentPlugin?.manifest.version ?? '0.0.0',
258
+ platform,
259
+ scope: options.commandOptions.scope,
260
+ cwd: options.commandOptions.cwd,
261
+ };
262
+ if (!currentPlugin && options.command === 'upgrade') {
263
+ results.push(failedResult(options.command, identity, `${pluginName} 当前不在 current catalog 中,不能用历史 bundle 升级。请运行 \`aw cleanup ${pluginName} -p ${platform} -s ${options.commandOptions.scope}\` 清理当前可见 AW 输出。`));
264
+ continue;
265
+ }
266
+ if (!currentPlugin && options.command !== 'cleanup' && options.command !== 'uninstall') {
267
+ results.push(failedResult(options.command, identity, `${pluginName} 当前不在 current catalog 中。`));
268
+ continue;
269
+ }
270
+ const plugin = currentPlugin ?? createSyntheticPlugin(pluginName, env);
271
+ if (currentPlugin
272
+ && options.command !== 'cleanup'
273
+ && options.command !== 'uninstall'
274
+ && !supportsPlatform(currentPlugin.manifest, platform)) {
275
+ results.push(failedResult(options.command, identity, options.command === 'upgrade'
276
+ ? `${pluginName} 当前 catalog 不再支持 ${platform},不能升级这个可见目标。请运行 \`aw cleanup ${pluginName} -p ${platform} -s ${options.commandOptions.scope}\`。`
277
+ : `${pluginName} 当前 catalog 不支持 ${platform}。`));
278
+ continue;
279
+ }
280
+ if (currentPlugin
281
+ && platform === 'codex'
282
+ && options.commandOptions.scope === 'project'
283
+ && options.command !== 'cleanup'
284
+ && options.command !== 'uninstall'
285
+ && currentPlugin.manifest.apps) {
286
+ results.push(failedResult(options.command, identity, `${pluginName} 声明了 apps;Codex project scope 不支持 apps。`));
287
+ continue;
288
+ }
289
+ if (currentPlugin
290
+ && platform === 'codex'
291
+ && options.commandOptions.scope === 'project'
292
+ && options.command !== 'cleanup'
293
+ && options.command !== 'uninstall'
294
+ && !hasCodexProjectManagedArtifacts(currentPlugin)) {
295
+ results.push(failedResult(options.command, identity, `${pluginName} 没有 Codex project scope 可生成的 Skills、instructions、roles、MCP、hooks 或 permissions。`));
296
+ continue;
297
+ }
298
+ let operationLock;
299
+ if (!options.runtime?.operationLeaseHeld) {
300
+ try {
301
+ await rebuildCommandTestHooks?.beforeOperationLockAcquire?.({
302
+ command: options.command,
303
+ identity,
304
+ });
305
+ operationLock = await withRebuildActionEvent({
306
+ runtime,
307
+ command: options.command,
308
+ identity,
309
+ name: 'operation.lock',
310
+ operation: () => activeStore.acquireOperation(identity),
311
+ });
312
+ }
313
+ catch (error) {
314
+ results.push(failedResult(options.command, identity, error instanceof Error ? error.message : String(error), 'operation.lock'));
315
+ continue;
316
+ }
317
+ }
318
+ let result;
319
+ try {
320
+ if (options.runtime?.preparedTargetError)
321
+ throw options.runtime.preparedTargetError;
322
+ const target = await integration.buildTarget({
323
+ ...(options.runtime?.namespacedSource ?? {}),
324
+ ...(options.runtime?.namespacedSource ? {
325
+ pluginId: formatPluginId({
326
+ sourceId: options.runtime.namespacedSource.sourceId,
327
+ pluginName,
328
+ }),
329
+ } : plugin.pluginId ? { pluginId: plugin.pluginId } : {}),
330
+ plugin,
331
+ platform,
332
+ scope: options.commandOptions.scope,
333
+ cwd: options.commandOptions.cwd,
334
+ command: options.command,
335
+ catalog,
336
+ includeHistoricalLifecycleArtifacts: true,
337
+ });
338
+ targets.push(target);
339
+ if (!options.runtime?.targetBuiltHookHandled) {
340
+ await rebuildCommandTestHooks?.afterTargetBuilt?.({
341
+ command: options.command,
342
+ identity,
343
+ });
344
+ }
345
+ if (!options.runtime?.dependencyReviewPreflightHandled) {
346
+ await options.runtime?.reviewPreflight?.({
347
+ command: options.command,
348
+ identity,
349
+ ...options.runtime.resolvedReviewEvidenceByPlugin?.[pluginName],
350
+ });
351
+ }
352
+ const { acquireOperation: _acquireOperation, ...operationHeldStore } = activeStore;
353
+ result = await executeRebuildOperation({
354
+ command: options.command,
355
+ target,
356
+ driver: integration.driver,
357
+ activeStore: operationHeldStore,
358
+ onActionEvent: (event) => emitRebuildActionEvent(runtime, event),
359
+ });
360
+ }
361
+ catch (error) {
362
+ result = error.result ?? failedResult(options.command, identity, error instanceof Error ? error.message : String(error), 'preflight');
363
+ }
364
+ result.actions.unshift({ name: 'operation.lock', status: 'succeeded' });
365
+ if (operationLock) {
366
+ try {
367
+ await withRebuildActionEvent({
368
+ runtime,
369
+ command: options.command,
370
+ identity,
371
+ name: 'operation.release',
372
+ operation: () => releaseRebuildOperationLease(operationLock),
373
+ });
374
+ result.actions.push({ name: 'operation.release', status: 'succeeded' });
375
+ }
376
+ catch (error) {
377
+ result = appendOperationReleaseFailure(result, error instanceof Error ? error.message : String(error));
378
+ }
379
+ }
380
+ results.push(result);
381
+ }
382
+ }
383
+ const successful = results.filter((result) => result.status === 'succeeded');
384
+ const artifacts = targets.flatMap((target) => [...target.artifacts]);
385
+ const nativePlugins = {};
386
+ for (const result of successful) {
387
+ const target = targets.find((entry) => entry.identity.pluginName === result.target.pluginName
388
+ && entry.identity.platform === result.target.platform
389
+ && entry.identity.scope === result.target.scope);
390
+ if (target?.requiresNative && options.command !== 'cleanup' && options.command !== 'uninstall') {
391
+ nativePlugins[result.target.platform] ??= [];
392
+ nativePlugins[result.target.platform].push(result.target.pluginName);
393
+ }
394
+ }
395
+ return {
396
+ platforms,
397
+ plugins: [...new Set(successful.map((result) => result.target.pluginName))],
398
+ warnings: [],
399
+ rebuildResults: results,
400
+ targetResults: results.map(toTargetResult),
401
+ overallState: results.every((result) => result.status === 'succeeded') ? 'succeeded' : 'failed',
402
+ nativePlugins,
403
+ repoManagedArtifacts: artifacts,
404
+ receiptTargets: results.map((result) => ({
405
+ pluginName: result.target.pluginName,
406
+ ...(result.target.sourceId ? {
407
+ sourceId: result.target.sourceId,
408
+ pluginId: result.target.pluginId,
409
+ } : {}),
410
+ platform: result.target.platform,
411
+ scope: result.target.scope,
412
+ })),
413
+ };
414
+ }
415
+ function resolveRuntimeCliVersion() {
416
+ const value = fs.readJsonSync(path.join(resolveCliPackageRoot(), 'package.json'));
417
+ return assertStrictSemVer(value.version, 'packages/cli/package.json version');
418
+ }
419
+ function toCatalogResolution(source) {
420
+ return {
421
+ rootDir: source.rootDir,
422
+ source: 'local',
423
+ catalogVersion: source.manifest.catalogVersion,
424
+ channel: source.manifest.channel,
425
+ minAwVersion: source.manifest.compatibility.aw.minVersion,
426
+ };
427
+ }
428
+ function mergeRebuildCommandResults(results) {
429
+ const rebuildResults = results.flatMap((result) => result.rebuildResults);
430
+ const platforms = [...new Set(results.flatMap((result) => result.platforms))];
431
+ const nativePlugins = {};
432
+ for (const result of results) {
433
+ for (const platform of ['codex', 'claude']) {
434
+ const names = result.nativePlugins[platform];
435
+ if (names)
436
+ nativePlugins[platform] = [...new Set([...(nativePlugins[platform] ?? []), ...names])];
437
+ }
438
+ }
439
+ return {
440
+ platforms,
441
+ plugins: [...new Set(results.flatMap((result) => result.plugins))],
442
+ warnings: results.flatMap((result) => result.warnings),
443
+ rebuildResults,
444
+ targetResults: results.flatMap((result) => result.targetResults),
445
+ overallState: rebuildResults.every((result) => result.status === 'succeeded')
446
+ ? 'succeeded'
447
+ : 'failed',
448
+ nativePlugins,
449
+ repoManagedArtifacts: [],
450
+ receiptTargets: results.flatMap((result) => result.receiptTargets),
451
+ ...(results.find((result) => result.dependencyPlan)?.dependencyPlan
452
+ ? { dependencyPlan: results.find((result) => result.dependencyPlan).dependencyPlan }
453
+ : {}),
454
+ };
455
+ }
456
+ function leaseSafeRebuildResult(result) {
457
+ const projectPath = (value) => path.basename(value);
458
+ return {
459
+ ...result,
460
+ repoManagedArtifacts: [],
461
+ rebuildResults: result.rebuildResults.map((entry) => ({
462
+ ...entry,
463
+ target: { ...entry.target, cwd: '.' },
464
+ removed: entry.removed.map(projectPath),
465
+ absent: entry.absent.map(projectPath),
466
+ residual: entry.residual.map(projectPath),
467
+ quarantined: entry.quarantined.map(projectPath),
468
+ })),
469
+ };
470
+ }
471
+ function namespacedPreflightError(message, targets, legacyTargets = []) {
472
+ return Object.assign(new Error(message), { namespacedTargets: targets, legacyTargets });
473
+ }
474
+ function selectedLegacyLiveReferences(references, platforms, scope) {
475
+ return references.filter((reference) => (reference.kind === 'legacyOwner' || reference.kind === 'legacyMarketplace')
476
+ && reference.pluginName
477
+ && reference.scope === scope
478
+ && reference.platform
479
+ && platforms.has(reference.platform));
480
+ }
481
+ function projectLegacyTargets(references) {
482
+ return [...new Map(references.map((reference) => {
483
+ const target = {
484
+ pluginName: reference.pluginName,
485
+ platform: reference.platform,
486
+ scope: reference.scope,
487
+ };
488
+ return [`${target.pluginName}\0${target.platform}\0${target.scope}`, target];
489
+ })).values()];
490
+ }
491
+ function exclusiveSkillRoot(options) {
492
+ if (options.scope === 'user') {
493
+ return path.join(options.platform === 'codex' ? getCodexHome(options.env) : getClaudeHome(options.env), 'skills');
494
+ }
495
+ const repoRoot = resolveRepoRootSync(options.cwd);
496
+ return path.join(repoRoot, options.platform === 'codex' ? '.agents' : '.claude', 'skills');
497
+ }
498
+ function resolveLiveCleanupTargets(options) {
499
+ const visible = options.references.filter((reference) => (reference.kind === 'namespacedOwner'
500
+ || reference.kind === 'namespacedMarketplace'
501
+ || reference.kind === 'namespacedLifecycle')
502
+ && reference.sourceId
503
+ && reference.sourceIdentity
504
+ && reference.pluginName
505
+ && reference.platform
506
+ && options.platforms.includes(reference.platform)
507
+ && reference.scope === options.scope);
508
+ const targets = [];
509
+ const selectors = options.selectors.map((value) => {
510
+ const parsed = parsePluginId(value);
511
+ const matchesByTarget = new Map();
512
+ for (const reference of visible.filter((entry) => entry.pluginName === parsed.pluginName
513
+ && (parsed.sourceId === undefined || entry.sourceId === parsed.sourceId))) {
514
+ const liveNames = new Set(options.references.flatMap((candidate) => candidate.sourceId === reference.sourceId
515
+ && candidate.sourceIdentity === reference.sourceIdentity
516
+ && candidate.pluginName === reference.pluginName
517
+ && candidate.platform === reference.platform
518
+ && candidate.scope === reference.scope
519
+ && candidate.marketplaceName
520
+ ? [candidate.marketplaceName]
521
+ : []));
522
+ const registeredNames = canonicalMarketplaceRegistrationNames(options.references, reference.sourceId);
523
+ const unboundNativeNames = new Set(options.references.flatMap((candidate) => candidate.kind === 'namespacedMarketplace'
524
+ && candidate.sourceId === undefined
525
+ && candidate.pluginName === reference.pluginName
526
+ && candidate.platform === reference.platform
527
+ && candidate.scope === reference.scope
528
+ && candidate.marketplaceName
529
+ ? [candidate.marketplaceName]
530
+ : []));
531
+ const marketplaceName = liveNames.size === 1
532
+ ? [...liveNames][0]
533
+ : liveNames.size === 0 && registeredNames.length === 1
534
+ ? registeredNames[0]
535
+ : undefined;
536
+ const marketplaceIdentityUnresolved = liveNames.size > 1
537
+ || (liveNames.size === 0 && registeredNames.length > 1)
538
+ || (liveNames.size === 0 && registeredNames.length === 0 && unboundNativeNames.size > 0);
539
+ const target = {
540
+ pluginId: formatPluginId({ sourceId: reference.sourceId, pluginName: reference.pluginName }),
541
+ pluginName: reference.pluginName,
542
+ sourceId: reference.sourceId,
543
+ sourceIdentity: reference.sourceIdentity,
544
+ platform: reference.platform,
545
+ scope: reference.scope,
546
+ ...(marketplaceName ? { marketplaceName } : {}),
547
+ ...(marketplaceIdentityUnresolved ? { marketplaceIdentityUnresolved: true } : {}),
548
+ };
549
+ const key = [target.pluginId, target.sourceIdentity, target.platform, target.scope].join('\0');
550
+ const previous = matchesByTarget.get(key);
551
+ matchesByTarget.set(key, previous?.marketplaceName ? previous : target);
552
+ }
553
+ const matches = [...matchesByTarget.values()];
554
+ const identities = [...new Set(matches.map((target) => target.pluginId))];
555
+ if (parsed.sourceId === undefined && identities.length > 1) {
556
+ throw new Error(`pluginSelectorAmbiguous: Plugin "${parsed.pluginName}" has multiple live matches: ${identities.sort().join(', ')}.`);
557
+ }
558
+ targets.push(...matches);
559
+ return identities.length === 1 ? identities[0] : value;
560
+ });
561
+ return {
562
+ selectors,
563
+ targets: [...new Map(targets.map((target) => [[
564
+ target.pluginId, target.sourceIdentity, target.platform, target.scope,
565
+ ].join('\0'), target])).values()],
566
+ };
567
+ }
568
+ async function discoverDamagedExclusiveCleanupTargets(options) {
569
+ const parsed = parsePluginId(options.selector);
570
+ if (!parsed.sourceId)
571
+ return [];
572
+ const targets = [];
573
+ for (const platform of options.platforms) {
574
+ const root = exclusiveSkillRoot({
575
+ platform,
576
+ scope: options.scope,
577
+ cwd: options.cwd,
578
+ env: options.env,
579
+ });
580
+ const entries = await fs.readdir(root, { withFileTypes: true }).catch(() => []);
581
+ for (const entry of entries) {
582
+ if (!entry.isDirectory() || entry.isSymbolicLink())
583
+ continue;
584
+ const markerPath = path.join(root, entry.name, '.agent-workflows-owner.json');
585
+ const markerStats = await fs.lstat(markerPath).catch(() => null);
586
+ if (!markerStats?.isFile() || markerStats.isSymbolicLink())
587
+ continue;
588
+ const raw = await fs.readJson(markerPath).catch(() => null);
589
+ if (!raw
590
+ || raw.schemaVersion !== 2
591
+ || raw.owner !== 'agent-workflows'
592
+ || raw.sourceId !== parsed.sourceId
593
+ || raw.plugin !== parsed.pluginName
594
+ || raw.pluginId !== options.selector
595
+ || raw.platform !== platform
596
+ || raw.scope !== options.scope)
597
+ continue;
598
+ targets.push({
599
+ pluginId: options.selector,
600
+ pluginName: parsed.pluginName,
601
+ sourceId: parsed.sourceId,
602
+ sourceIdentity: typeof raw.sourceIdentity === 'string'
603
+ && /^sha256:[0-9a-f]{64}$/u.test(raw.sourceIdentity)
604
+ ? raw.sourceIdentity
605
+ : `sha256:${'0'.repeat(64)}`,
606
+ platform,
607
+ scope: raw.scope,
608
+ });
609
+ }
610
+ }
611
+ return [...new Map(targets.map((target) => [[target.platform, target.scope].join('\0'), target])).values()];
612
+ }
613
+ async function cleanupOfflineOwnedComponents(options) {
614
+ if (options.targets.some((target) => target.marketplaceIdentityUnresolved)) {
615
+ throw namespacedPreflightError('marketplaceIdentityUnavailable: Cannot uniquely recover the native marketplace name from live inventory or a canonical native registration path.', options.targets);
616
+ }
617
+ const results = [];
618
+ const warnings = [];
619
+ const context = {
620
+ env: options.env,
621
+ nativeCliRunner: options.nativeCliRunner ?? getDefaultNativeCliRunner(),
622
+ reporter: createNoopReporter(),
623
+ debugLogger: createNoopDebugLogger(),
624
+ };
625
+ const integration = createRebuildIntegration({ context });
626
+ const activeStore = createRebuildActiveStore({
627
+ env: options.env,
628
+ loadPlugin: (bundleRoot) => readPluginManifest(bundleRoot, { mode: 'bundle' }),
629
+ isLifecycleLeaseHeld: () => context.lifecycleLeaseHeld === true,
630
+ });
631
+ for (const target of options.targets) {
632
+ const exclusiveRecovery = {
633
+ removed: [], absent: [], residual: [], quarantined: [], failures: [],
634
+ };
635
+ if (options.force) {
636
+ const root = exclusiveSkillRoot({
637
+ platform: target.platform,
638
+ scope: target.scope,
639
+ cwd: options.cwd,
640
+ env: options.env,
641
+ });
642
+ const entries = await fs.readdir(root, { withFileTypes: true }).catch(() => []);
643
+ for (const entry of entries) {
644
+ if (!entry.isDirectory() || entry.isSymbolicLink())
645
+ continue;
646
+ const directory = path.join(root, entry.name);
647
+ let recovered;
648
+ try {
649
+ recovered = await cleanupCorruptExclusivePluginDirectory({
650
+ directory,
651
+ allowedRoot: root,
652
+ sourceId: target.sourceId,
653
+ pluginName: target.pluginName,
654
+ platform: target.platform,
655
+ scope: target.scope,
656
+ ...options.corruptExclusiveDirectoryOperations,
657
+ });
658
+ }
659
+ catch (error) {
660
+ recovered = {
661
+ removed: [], absent: [], residual: [directory], quarantined: [],
662
+ failures: [{
663
+ label: directory,
664
+ phase: 'mutation',
665
+ message: error instanceof Error ? error.message : String(error),
666
+ }],
667
+ };
668
+ }
669
+ if (recovered) {
670
+ exclusiveRecovery.removed.push(...recovered.removed);
671
+ exclusiveRecovery.absent.push(...recovered.absent);
672
+ exclusiveRecovery.residual.push(...recovered.residual);
673
+ exclusiveRecovery.quarantined.push(...recovered.quarantined);
674
+ exclusiveRecovery.failures.push(...recovered.failures);
675
+ }
676
+ }
677
+ }
678
+ const plugin = createSyntheticPlugin(target.pluginName, options.env);
679
+ plugin.sourceId = target.sourceId;
680
+ plugin.sourceIdentity = target.sourceIdentity;
681
+ plugin.pluginId = target.pluginId;
682
+ const marketplaceName = target.marketplaceName ?? 'aw';
683
+ plugin.marketplaceName = marketplaceName;
684
+ const desired = await integration.buildTarget({
685
+ sourceId: target.sourceId,
686
+ sourceIdentity: target.sourceIdentity,
687
+ pluginId: target.pluginId,
688
+ marketplaceName,
689
+ marketplaceRoot: path.join(resolveAwHome(options.env), 'marketplaces', target.sourceId),
690
+ plugin,
691
+ platform: target.platform,
692
+ scope: target.scope,
693
+ cwd: options.cwd,
694
+ command: 'cleanup',
695
+ catalog: {
696
+ rootDir: resolveAwHome(options.env),
697
+ source: 'local',
698
+ catalogVersion: '0.0.0',
699
+ channel: 'beta',
700
+ minAwVersion: '0.0.0',
701
+ },
702
+ includeHistoricalLifecycleArtifacts: false,
703
+ });
704
+ let result;
705
+ const operationLock = await activeStore.acquireOperation(desired.identity);
706
+ try {
707
+ const { acquireOperation: _acquireOperation, ...operationHeldStore } = activeStore;
708
+ result = await executeRebuildOperation({
709
+ command: 'cleanup',
710
+ target: desired,
711
+ driver: integration.driver,
712
+ activeStore: operationHeldStore,
713
+ });
714
+ }
715
+ finally {
716
+ await releaseRebuildOperationLease(operationLock);
717
+ }
718
+ const exclusiveResidual = (await Promise.all(exclusiveRecovery.residual.map(async (entry) => await fs.pathExists(entry) ? entry : null))).filter((entry) => entry !== null);
719
+ const exclusiveQuarantined = (await Promise.all(exclusiveRecovery.quarantined.map(async (entry) => await fs.pathExists(entry) ? entry : null))).filter((entry) => entry !== null);
720
+ const exclusiveFailures = (await Promise.all(exclusiveRecovery.failures.map(async (failure) => {
721
+ const residualPath = failure.quarantinePath ?? failure.label;
722
+ return await fs.pathExists(residualPath) ? failure : null;
723
+ }))).filter((failure) => failure !== null);
724
+ const removed = [...new Set([...result.removed, ...exclusiveRecovery.removed])];
725
+ const absent = [...new Set([...result.absent, ...exclusiveRecovery.absent])]
726
+ .filter((entry) => !removed.includes(entry));
727
+ result = {
728
+ ...result,
729
+ removed,
730
+ absent,
731
+ residual: [...new Set([...result.residual, ...exclusiveResidual])],
732
+ quarantined: [...new Set([...result.quarantined, ...exclusiveQuarantined])],
733
+ };
734
+ if (exclusiveFailures.length > 0) {
735
+ const failures = exclusiveFailures.map((failure) => ({
736
+ phase: 'cleanup.owned',
737
+ label: failure.label,
738
+ message: `exclusiveRecoveryFailed: ${failure.phase} ${failure.label}: ${failure.message}`,
739
+ }));
740
+ const message = failures[0].message;
741
+ result = {
742
+ ...result,
743
+ status: 'failed',
744
+ actions: [{ name: 'cleanup.owned', status: 'failed' }],
745
+ failures: [...result.failures, ...failures],
746
+ error: { phase: 'cleanup.owned', message },
747
+ };
748
+ }
749
+ results.push(result);
750
+ }
751
+ const obsoleteContracts = path.join(resolveAwHome(options.env), 'installation-contracts');
752
+ try {
753
+ await (options.removeObsoleteInstallationContracts ?? fs.remove)(obsoleteContracts);
754
+ }
755
+ catch (error) {
756
+ warnings.push(`obsoleteContractsCleanupFailed: ${error instanceof Error ? error.message : String(error)}`);
757
+ }
758
+ return leaseSafeRebuildResult({
759
+ platforms: [...new Set(results.map((result) => result.target.platform))],
760
+ plugins: results.filter((result) => result.status === 'succeeded').map((result) => result.target.pluginName),
761
+ warnings,
762
+ rebuildResults: results,
763
+ targetResults: results.map(toTargetResult),
764
+ overallState: results.every((result) => result.status === 'succeeded') ? 'succeeded' : 'failed',
765
+ nativePlugins: {}, repoManagedArtifacts: [],
766
+ receiptTargets: results.map((result) => ({
767
+ pluginName: result.target.pluginName,
768
+ pluginId: result.target.pluginId,
769
+ sourceId: result.target.sourceId,
770
+ platform: result.target.platform,
771
+ scope: result.target.scope,
772
+ })),
773
+ });
774
+ }
775
+ async function assertOfflineCleanupDependents(options) {
776
+ const inventory = await inventoryCatalogSourceReferences({
777
+ cwd: options.cwd,
778
+ env: options.env,
779
+ includeHistoricalProjects: true,
780
+ });
781
+ const currentProjectKey = await resolveCanonicalRepoProjectKey(options.cwd);
782
+ for (const target of options.targets) {
783
+ const pluginsRoot = path.join(resolveAwHome(options.env), 'marketplaces', target.sourceId, 'plugins');
784
+ const entries = await fs.readdir(pluginsRoot, { withFileTypes: true }).catch(() => []);
785
+ for (const entry of entries) {
786
+ if (!entry.isDirectory() || entry.name === target.pluginName)
787
+ continue;
788
+ const consumer = await readPluginManifest(path.join(pluginsRoot, entry.name), { mode: 'bundle' })
789
+ .catch(() => null);
790
+ if (!consumer?.manifest.dependencies?.includes(target.pluginName))
791
+ continue;
792
+ const consumerId = formatPluginId({ sourceId: target.sourceId, pluginName: consumer.manifest.name });
793
+ const live = inventory.references.some((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
794
+ && reference.sourceId === target.sourceId
795
+ && reference.sourceIdentity === target.sourceIdentity
796
+ && reference.pluginName === consumer.manifest.name
797
+ && reference.platform === target.platform
798
+ && (target.scope === 'user' || reference.scope === 'project')
799
+ && (target.scope === 'user' || reference.projectKey === currentProjectKey));
800
+ if (live) {
801
+ throw namespacedPreflightError(`dependencyStillRequired: ${target.pluginId} is required by ${consumerId}.`, options.targets);
802
+ }
803
+ }
804
+ }
805
+ }
806
+ export async function runRebuildCommand(options) {
807
+ if (options.runtime?.catalogResolution && options.runtime.bypassDependencyPlan) {
808
+ return runSingleSourceRebuildCommand(options);
809
+ }
810
+ const runtimeEnv = options.runtime?.env ?? process.env;
811
+ let requestedPluginNames = options.pluginNames;
812
+ const cleanupForce = options.command === 'cleanup'
813
+ && options.commandOptions.force === true;
814
+ let cleanupInventory;
815
+ let cleanupLiveTargets = [];
816
+ let cleanupHasDamagedExclusiveTarget = false;
817
+ let liveTargets = [];
818
+ let legacyLiveTargets = [];
819
+ if (options.command === 'cleanup' && !options.all) {
820
+ cleanupInventory = await inventoryCatalogSourceReferences({
821
+ cwd: options.commandOptions.cwd,
822
+ env: runtimeEnv,
823
+ });
824
+ const live = resolveLiveCleanupTargets({
825
+ selectors: requestedPluginNames,
826
+ platforms: selectedPlatforms(options.commandOptions.platform),
827
+ scope: options.commandOptions.scope,
828
+ references: cleanupInventory.references,
829
+ });
830
+ requestedPluginNames = live.selectors;
831
+ cleanupLiveTargets = live.targets;
832
+ if (cleanupForce) {
833
+ const damagedTargets = (await Promise.all(requestedPluginNames.map(async (selector) => parsePluginId(selector).sourceId
834
+ ? discoverDamagedExclusiveCleanupTargets({
835
+ selector,
836
+ platforms: selectedPlatforms(options.commandOptions.platform),
837
+ scope: options.commandOptions.scope,
838
+ cwd: options.commandOptions.cwd,
839
+ env: runtimeEnv,
840
+ })
841
+ : []))).flat();
842
+ cleanupHasDamagedExclusiveTarget = damagedTargets.length > 0;
843
+ cleanupLiveTargets = [...new Map([
844
+ ...damagedTargets,
845
+ ...cleanupLiveTargets,
846
+ ].map((target) => [[target.pluginId, target.platform, target.scope].join('\0'), target])).values()];
847
+ }
848
+ liveTargets = cleanupLiveTargets;
849
+ }
850
+ if (cleanupHasDamagedExclusiveTarget) {
851
+ return cleanupOfflineOwnedComponents({
852
+ targets: cleanupLiveTargets,
853
+ cwd: options.commandOptions.cwd,
854
+ env: runtimeEnv,
855
+ force: true,
856
+ removeObsoleteInstallationContracts: options.runtime?.removeObsoleteInstallationContracts,
857
+ nativeCliRunner: options.runtime?.nativeCliRunner,
858
+ corruptExclusiveDirectoryOperations: options.runtime?.corruptExclusiveDirectoryOperations,
859
+ });
860
+ }
861
+ if (options.all) {
862
+ const inventory = await inventoryCatalogSourceReferences({
863
+ cwd: options.commandOptions.cwd,
864
+ env: runtimeEnv,
865
+ });
866
+ if (options.command !== 'cleanup')
867
+ assertCatalogSourceInventoryComplete(inventory);
868
+ const requestedPlatforms = new Set(selectedPlatforms(options.commandOptions.platform));
869
+ legacyLiveTargets = projectLegacyTargets(selectedLegacyLiveReferences(inventory.references, requestedPlatforms, options.commandOptions.scope));
870
+ const live = inventory.references.filter((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
871
+ && reference.sourceId
872
+ && reference.pluginName
873
+ && reference.scope === options.commandOptions.scope
874
+ && reference.platform
875
+ && requestedPlatforms.has(reference.platform));
876
+ const projectedTargets = [...new Map(live.map((reference) => {
877
+ const target = {
878
+ pluginId: formatPluginId({
879
+ sourceId: reference.sourceId,
880
+ pluginName: reference.pluginName,
881
+ }),
882
+ pluginName: reference.pluginName,
883
+ sourceId: reference.sourceId,
884
+ sourceIdentity: reference.sourceIdentity ?? 'unavailable',
885
+ platform: reference.platform,
886
+ scope: reference.scope,
887
+ };
888
+ return [[
889
+ target.pluginId,
890
+ target.sourceIdentity,
891
+ target.platform,
892
+ target.scope,
893
+ ].join('\0'), target];
894
+ })).values()];
895
+ liveTargets = projectedTargets;
896
+ const identities = new Map();
897
+ for (const reference of live) {
898
+ if (!reference.sourceIdentity) {
899
+ throw namespacedPreflightError(`legacyStateUnsupported: ${reference.location} lacks a schema 2 source identity.`, projectedTargets, legacyLiveTargets);
900
+ }
901
+ const pluginId = formatPluginId({ sourceId: reference.sourceId, pluginName: reference.pluginName });
902
+ const previous = identities.get(pluginId);
903
+ if (previous && previous !== reference.sourceIdentity) {
904
+ throw namespacedPreflightError(`sourceChanged: ${pluginId} live targets have different source identities.`, projectedTargets, legacyLiveTargets);
905
+ }
906
+ identities.set(pluginId, reference.sourceIdentity);
907
+ }
908
+ requestedPluginNames = [...identities.keys()];
909
+ }
910
+ const selectors = requestedPluginNames.map(parsePluginId);
911
+ const sourceIds = planPluginSelectorSourceIds(selectors);
912
+ if (options.all && selectors.length === 0) {
913
+ if (legacyLiveTargets.length > 0) {
914
+ throw namespacedPreflightError(`legacyStateUnsupported: legacy live runtime state exists for ${legacyLiveTargets.map((target) => `${target.pluginName}:${target.platform}/${target.scope}`).join(', ')}.`, [], legacyLiveTargets);
915
+ }
916
+ return mergeRebuildCommandResults([]);
917
+ }
918
+ try {
919
+ const resolvedResult = await withResolvedMultiSourceCatalog({
920
+ cliVersion: resolveRuntimeCliVersion(),
921
+ freshnessPolicy: options.command === 'cleanup' ? 'cacheFirst' : 'requireRemote',
922
+ ...(sourceIds ? { sourceIds } : {}),
923
+ env: runtimeEnv,
924
+ consume: async (catalog) => {
925
+ const failedSources = catalog.sources.filter((source) => source.error);
926
+ if (failedSources.length > 0) {
927
+ throw namespacedPreflightError(`Cannot resolve required catalog sources: ${failedSources.map((source) => source.sourceId).join(', ')}.`, liveTargets, legacyLiveTargets);
928
+ }
929
+ const available = (await Promise.all(catalog.sources.map(async (item) => {
930
+ const source = item.resolution;
931
+ const plugins = await resolvePluginsFromCatalog(source.rootDir, undefined);
932
+ return plugins.map((plugin) => {
933
+ const pluginId = formatPluginId({ sourceId: source.sourceId, pluginName: plugin.manifest.name });
934
+ plugin.sourceId = source.sourceId;
935
+ plugin.sourceIdentity = source.sourceIdentity;
936
+ plugin.pluginId = pluginId;
937
+ return { source, plugin, pluginId };
938
+ });
939
+ }))).flat();
940
+ const selected = selectors.map((selector, index) => {
941
+ const matches = available.filter((entry) => entry.plugin.manifest.name === selector.pluginName
942
+ && (selector.sourceId === undefined || entry.source.sourceId === selector.sourceId));
943
+ if (matches.length === 0) {
944
+ throw new Error(`Plugin "${requestedPluginNames[index]}" does not exist in the required catalog source set.`);
945
+ }
946
+ if (matches.length > 1) {
947
+ throw new Error(`Plugin "${selector.pluginName}" is ambiguous across sources: ${matches.map((entry) => entry.source.sourceId).join(', ')}.`);
948
+ }
949
+ return matches[0];
950
+ });
951
+ const dependencyEnabled = options.command === 'install'
952
+ || options.command === 'upgrade'
953
+ || options.command === 'reinstall';
954
+ const selectedIds = new Set(selected.map((entry) => entry.pluginId));
955
+ const resolveClosureEntries = (rootsBySource) => catalog.sources.flatMap((item) => {
956
+ const source = item.resolution;
957
+ const roots = rootsBySource
958
+ .filter((entry) => entry.source.sourceId === source.sourceId)
959
+ .map((entry) => entry.plugin.manifest.name);
960
+ if (roots.length === 0)
961
+ return [];
962
+ const sourcePlugins = available
963
+ .filter((entry) => entry.source.sourceId === source.sourceId)
964
+ .map((entry) => entry.plugin);
965
+ const closure = resolvePluginMetaDependencyClosure(sourcePlugins, roots);
966
+ return closure.map((plugin) => available.find((entry) => entry.source.sourceId === source.sourceId
967
+ && entry.plugin.manifest.name === plugin.manifest.name));
968
+ });
969
+ const closureEntriesByPlatform = new Map();
970
+ if (dependencyEnabled) {
971
+ for (const platform of selectedPlatforms(options.commandOptions.platform)) {
972
+ const platformRoots = options.commandOptions.platform === 'both'
973
+ ? selected.filter((entry) => supportsPlatform(entry.plugin.manifest, platform))
974
+ : selected;
975
+ closureEntriesByPlatform.set(platform, resolveClosureEntries(platformRoots));
976
+ }
977
+ }
978
+ const closureEntries = dependencyEnabled
979
+ ? [...new Map([...closureEntriesByPlatform.values()].flat().map((entry) => [entry.pluginId, entry])).values()]
980
+ : selected;
981
+ const rawExecutionSelections = options.all
982
+ ? liveTargets.flatMap((target) => {
983
+ const entry = selected.find((candidate) => candidate.pluginId === target.pluginId);
984
+ if (entry.source.sourceIdentity !== target.sourceIdentity) {
985
+ throw namespacedPreflightError(`sourceChanged: ${target.pluginId} live target has a different source identity.`, liveTargets, legacyLiveTargets);
986
+ }
987
+ const sourcePlugins = available
988
+ .filter((candidate) => candidate.source.sourceId === entry.source.sourceId)
989
+ .map((candidate) => candidate.plugin);
990
+ return resolvePluginMetaDependencyClosure(sourcePlugins, [entry.plugin.manifest.name]).map((plugin) => ({
991
+ entry: available.find((candidate) => candidate.source.sourceId === entry.source.sourceId
992
+ && candidate.plugin.manifest.name === plugin.manifest.name),
993
+ platform: target.platform,
994
+ }));
995
+ })
996
+ : selectedPlatforms(options.commandOptions.platform).flatMap((platform) => (dependencyEnabled ? closureEntriesByPlatform.get(platform) ?? [] : closureEntries)
997
+ .flatMap((entry) => options.command !== 'cleanup'
998
+ && options.command !== 'uninstall'
999
+ && options.commandOptions.platform === 'both'
1000
+ && !supportsPlatform(entry.plugin.manifest, platform)
1001
+ ? []
1002
+ : [{ entry, platform }]));
1003
+ let executionSelections = [...new Map(rawExecutionSelections.map((selection) => [[
1004
+ selection.entry.pluginId,
1005
+ selection.entry.source.sourceIdentity,
1006
+ selection.platform,
1007
+ options.commandOptions.scope,
1008
+ ].join('\0'), selection])).values()];
1009
+ const preflightTargets = executionSelections.map(({ entry, platform }) => ({
1010
+ pluginId: entry.pluginId,
1011
+ pluginName: entry.plugin.manifest.name,
1012
+ sourceId: entry.source.sourceId,
1013
+ sourceIdentity: entry.source.sourceIdentity,
1014
+ pluginVersion: entry.plugin.manifest.version,
1015
+ platform,
1016
+ scope: options.commandOptions.scope,
1017
+ }));
1018
+ const stateInventory = await inventoryCatalogSourceReferences({
1019
+ cwd: options.commandOptions.cwd,
1020
+ env: runtimeEnv,
1021
+ });
1022
+ if (options.command !== 'cleanup')
1023
+ assertCatalogSourceInventoryComplete(stateInventory);
1024
+ const commandProjectKey = await resolveCanonicalRepoProjectKey(options.commandOptions.cwd);
1025
+ const selectedLegacy = selectedLegacyLiveReferences(stateInventory.references, new Set(executionSelections.map((selection) => selection.platform)), options.commandOptions.scope);
1026
+ const legacy = options.all
1027
+ ? selectedLegacy
1028
+ : selectedLegacy.filter((reference) => executionSelections.some((selection) => selection.entry.plugin.manifest.name === reference.pluginName
1029
+ && selection.platform === reference.platform));
1030
+ if (legacy.length > 0) {
1031
+ const blockingLegacyTargets = projectLegacyTargets(legacy);
1032
+ throw namespacedPreflightError(`legacyStateUnsupported: legacy live runtime state exists at ${legacy.map((reference) => reference.location).join(', ')}.`, preflightTargets, blockingLegacyTargets);
1033
+ }
1034
+ for (const entry of closureEntries) {
1035
+ const changed = stateInventory.references.find((reference) => reference.sourceId === entry.source.sourceId
1036
+ && reference.sourceIdentity
1037
+ && reference.sourceIdentity !== entry.source.sourceIdentity);
1038
+ if (changed) {
1039
+ throw namespacedPreflightError(`sourceChanged: ${entry.source.sourceId} state at ${changed.location} has a different source identity.`, options.all
1040
+ ? preflightTargets
1041
+ : preflightTargets.filter((target) => target.pluginId === entry.pluginId));
1042
+ }
1043
+ }
1044
+ const marketplaceNamesBySource = new Map();
1045
+ for (const entry of new Map(closureEntries.map((candidate) => [
1046
+ candidate.source.sourceId,
1047
+ candidate,
1048
+ ])).values()) {
1049
+ const sourceNames = new Set(stateInventory.references.flatMap((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
1050
+ && reference.sourceId === entry.source.sourceId
1051
+ && (reference.sourceIdentity === undefined
1052
+ || reference.sourceIdentity === entry.source.sourceIdentity)
1053
+ && reference.marketplaceName
1054
+ ? [reference.marketplaceName]
1055
+ : []));
1056
+ if (sourceNames.size > 1) {
1057
+ throw new Error('marketplaceIdentityUnavailable: Multiple canonical native marketplace registrations match the source.');
1058
+ }
1059
+ const persistedName = [...sourceNames][0];
1060
+ const marketplaceRoot = path.join(resolveAwHome(runtimeEnv), 'marketplaces', entry.source.sourceId);
1061
+ let marketplaceName = persistedName
1062
+ ?? (entry.source.sourceId === catalog.primarySourceId
1063
+ ? 'aw'
1064
+ : getNamespacedMarketplaceName(entry.source.sourceId));
1065
+ if (options.command === 'cleanup' || options.command === 'uninstall') {
1066
+ marketplaceNamesBySource.set(entry.source.sourceId, marketplaceName);
1067
+ continue;
1068
+ }
1069
+ let registrations = await inspectNativeMarketplaceRegistrations({
1070
+ marketplaceName,
1071
+ marketplaceRoot,
1072
+ cwd: options.commandOptions.cwd,
1073
+ env: runtimeEnv,
1074
+ });
1075
+ if (!persistedName
1076
+ && marketplaceName === 'aw'
1077
+ && Object.values(registrations).includes('foreign')) {
1078
+ marketplaceName = getNamespacedMarketplaceName(entry.source.sourceId);
1079
+ registrations = await inspectNativeMarketplaceRegistrations({
1080
+ marketplaceName,
1081
+ marketplaceRoot,
1082
+ cwd: options.commandOptions.cwd,
1083
+ env: runtimeEnv,
1084
+ });
1085
+ }
1086
+ const foreignPlatforms = Object.entries(registrations).flatMap(([platform, state]) => state === 'foreign' ? [platform] : []);
1087
+ if (foreignPlatforms.length > 0) {
1088
+ throw new Error(`externalOwnershipPresent: Marketplace ${marketplaceName} is foreign on ${foreignPlatforms.join(', ')}.`);
1089
+ }
1090
+ marketplaceNamesBySource.set(entry.source.sourceId, marketplaceName);
1091
+ }
1092
+ const marketplaceNameFor = (entry, ..._placement) => {
1093
+ const marketplaceName = marketplaceNamesBySource.get(entry.source.sourceId);
1094
+ if (!marketplaceName) {
1095
+ throw new Error('marketplaceIdentityUnavailable: No marketplace name was selected for the source.');
1096
+ }
1097
+ return marketplaceName;
1098
+ };
1099
+ const executionContext = {
1100
+ env: runtimeEnv,
1101
+ nativeCliRunner: options.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
1102
+ reporter: options.runtime?.reporter ?? createNoopReporter(),
1103
+ debugLogger: options.runtime?.debugLogger ?? createNoopDebugLogger(),
1104
+ runtimeLeaseHeld: options.runtime?.runtimeLeaseHeld,
1105
+ lifecycleLeaseHeld: options.runtime?.lifecycleLeaseHeld,
1106
+ expectedCatalogConfigDigest: catalog.configDigest,
1107
+ };
1108
+ const inspection = createRebuildIntegration({
1109
+ context: executionContext,
1110
+ scriptTimeoutMs: options.commandOptions.scriptTimeoutMs,
1111
+ });
1112
+ const createPlan = async () => {
1113
+ const inventory = await inventoryCatalogSourceReferences({
1114
+ cwd: options.commandOptions.cwd,
1115
+ env: runtimeEnv,
1116
+ });
1117
+ if (options.command !== 'cleanup')
1118
+ assertCatalogSourceInventoryComplete(inventory);
1119
+ const targets = [];
1120
+ for (const [order, { entry, platform }] of executionSelections.entries()) {
1121
+ const relation = selectedIds.has(entry.pluginId) ? 'requested' : 'dependency';
1122
+ let resolvedScope = options.commandOptions.scope;
1123
+ const inspectScope = async (scope) => {
1124
+ const marketplaceName = marketplaceNameFor(entry, platform, scope);
1125
+ entry.plugin.marketplaceName = marketplaceName;
1126
+ const desired = await inspection.buildTarget({
1127
+ sourceId: entry.source.sourceId,
1128
+ sourceIdentity: entry.source.sourceIdentity,
1129
+ pluginId: entry.pluginId,
1130
+ marketplaceName,
1131
+ marketplaceRoot: path.join(resolveAwHome(runtimeEnv), 'marketplaces', entry.source.sourceId),
1132
+ plugin: entry.plugin,
1133
+ platform,
1134
+ scope,
1135
+ cwd: options.commandOptions.cwd,
1136
+ command: options.command,
1137
+ catalog: toCatalogResolution(entry.source),
1138
+ includeHistoricalLifecycleArtifacts: false,
1139
+ readOnlyInspectionPlan: true,
1140
+ });
1141
+ const result = await inspectOwnedComponents({
1142
+ components: desired.ownedComponents,
1143
+ nativeProbe: inspection.driver.probeNative,
1144
+ verifyHealth: true,
1145
+ });
1146
+ if (result.state === 'error'
1147
+ || result.components.some((component) => component.state === 'error'))
1148
+ return result;
1149
+ const required = new Set(desired.desiredOwnedComponents ?? desired.ownedComponents);
1150
+ const optional = new Set(desired.optionalOwnedComponents ?? []);
1151
+ const presentRequired = [...required].every((component) => result.components.some((entry) => entry.component === component && entry.state === 'present'));
1152
+ const hasUnexpectedPresent = result.components.some((entry) => entry.state === 'present' && !required.has(entry.component) && !optional.has(entry.component));
1153
+ const hasPartial = result.components.some((entry) => entry.state === 'partial');
1154
+ const hasAnyPresent = result.components.some((entry) => entry.state === 'present');
1155
+ const state = !hasAnyPresent
1156
+ && result.components.every((entry) => entry.state === 'absent')
1157
+ ? 'absent'
1158
+ : hasPartial || hasUnexpectedPresent || !presentRequired
1159
+ ? 'partial'
1160
+ : required.size > 0
1161
+ ? 'present'
1162
+ : hasAnyPresent ? 'present' : 'absent';
1163
+ return { ...result, state };
1164
+ };
1165
+ const [requestedInspection, otherInspection] = await Promise.all([
1166
+ inspectScope(resolvedScope),
1167
+ inspectScope(resolvedScope === 'user' ? 'project' : 'user'),
1168
+ ]);
1169
+ let state = requestedInspection.state;
1170
+ let action = relation === 'requested'
1171
+ ? options.command
1172
+ : options.command === 'reinstall' ? 'reinstall' : 'upgrade';
1173
+ let errorCode;
1174
+ const hasForeignCollision = [...requestedInspection.components, ...otherInspection.components]
1175
+ .some((component) => component.diagnostic?.includes('foreign collision'));
1176
+ if (dependencyEnabled && hasForeignCollision) {
1177
+ action = 'block';
1178
+ errorCode = 'artifactCollision';
1179
+ }
1180
+ else if (dependencyEnabled && relation === 'requested'
1181
+ && (requestedInspection.state === 'error'
1182
+ || (requestedInspection.state === 'partial' && options.command !== 'reinstall'))) {
1183
+ action = 'block';
1184
+ errorCode = 'dependencyNotReady';
1185
+ }
1186
+ if (!hasForeignCollision && relation === 'dependency'
1187
+ && requestedInspection.state === 'present'
1188
+ && otherInspection.state === 'present') {
1189
+ action = 'block';
1190
+ state = 'partial';
1191
+ errorCode = 'dependencyScopeConflict';
1192
+ }
1193
+ else if (!hasForeignCollision && relation === 'dependency'
1194
+ && options.commandOptions.scope === 'project'
1195
+ && otherInspection.state === 'present') {
1196
+ resolvedScope = 'user';
1197
+ state = 'present';
1198
+ }
1199
+ else if (!hasForeignCollision && relation === 'dependency'
1200
+ && options.commandOptions.scope === 'project'
1201
+ && (otherInspection.state === 'partial' || otherInspection.state === 'error')) {
1202
+ resolvedScope = 'user';
1203
+ state = otherInspection.state;
1204
+ if (otherInspection.state === 'error') {
1205
+ action = 'block';
1206
+ errorCode = 'dependencyNotReady';
1207
+ }
1208
+ }
1209
+ else if (!hasForeignCollision && relation === 'dependency'
1210
+ && options.commandOptions.scope === 'user'
1211
+ && otherInspection.state !== 'absent') {
1212
+ action = 'block';
1213
+ errorCode = 'dependencyScopeTooNarrow';
1214
+ }
1215
+ const resolvedInspection = resolvedScope === options.commandOptions.scope
1216
+ ? requestedInspection
1217
+ : otherInspection;
1218
+ state = resolvedInspection.state;
1219
+ if (!hasForeignCollision && !errorCode
1220
+ && relation === 'dependency' && options.command === 'install') {
1221
+ action = state === 'present' ? 'keep' : state === 'partial' ? 'reinstall' : 'install';
1222
+ }
1223
+ if (!hasForeignCollision && relation === 'dependency'
1224
+ && resolvedInspection.state === 'error') {
1225
+ action = 'block';
1226
+ state = resolvedInspection.state;
1227
+ errorCode ??= 'dependencyNotReady';
1228
+ }
1229
+ if (!hasForeignCollision && relation === 'dependency'
1230
+ && platform === 'codex'
1231
+ && resolvedScope === 'project'
1232
+ && (entry.plugin.manifest.apps || !hasCodexProjectManagedArtifacts(entry.plugin))) {
1233
+ action = 'block';
1234
+ errorCode = 'dependencyTargetUnsupported';
1235
+ }
1236
+ if (entry.plugin.manifest.config?.schema
1237
+ && (action === 'install' || action === 'upgrade' || action === 'reinstall')) {
1238
+ const effective = await resolveEffectivePluginConfig({
1239
+ sourceId: entry.source.sourceId,
1240
+ sourceIdentity: entry.source.sourceIdentity,
1241
+ pluginName: entry.plugin.manifest.name,
1242
+ manifest: entry.plugin.manifest,
1243
+ cwd: options.commandOptions.cwd,
1244
+ env: runtimeEnv,
1245
+ });
1246
+ if (effective.issues.length > 0) {
1247
+ action = 'block';
1248
+ errorCode = 'invalidConfig';
1249
+ }
1250
+ }
1251
+ targets.push({
1252
+ pluginId: entry.pluginId,
1253
+ pluginName: entry.plugin.manifest.name,
1254
+ platform,
1255
+ requestedScope: options.commandOptions.scope,
1256
+ resolvedScope,
1257
+ relation,
1258
+ requiredBy: executionSelections.filter((candidate) => candidate.platform === platform
1259
+ && candidate.entry.source.sourceId === entry.source.sourceId
1260
+ && candidate.entry.plugin.manifest.dependencies?.includes(entry.plugin.manifest.name))
1261
+ .map((candidate) => candidate.entry.pluginId).sort(),
1262
+ state,
1263
+ action,
1264
+ order,
1265
+ ...(errorCode ? { errorCode } : {}),
1266
+ });
1267
+ }
1268
+ return createDependencyOperationPlan({
1269
+ requestedPluginIds: selected.map((entry) => entry.pluginId),
1270
+ resolvedPluginIds: closureEntries.map((entry) => entry.pluginId),
1271
+ dependencyEdges: closureEntries.flatMap((entry) => (entry.plugin.manifest.dependencies ?? []).map((dependency) => ({
1272
+ from: entry.pluginId,
1273
+ to: formatPluginId({ sourceId: entry.source.sourceId, pluginName: dependency }),
1274
+ }))),
1275
+ targets,
1276
+ });
1277
+ };
1278
+ if (options.runtime?.previewDependencyPlanOnly) {
1279
+ const initialPlan = await createPlan();
1280
+ const preview = mergeRebuildCommandResults([]);
1281
+ preview.dependencyPlan = initialPlan;
1282
+ return preview;
1283
+ }
1284
+ for (const { entry, platform } of executionSelections.filter((selection) => selectedIds.has(selection.entry.pluginId))) {
1285
+ await options.runtime?.reviewPreflight?.({
1286
+ command: options.command,
1287
+ identity: {
1288
+ sourceId: entry.source.sourceId,
1289
+ sourceIdentity: entry.source.sourceIdentity,
1290
+ pluginId: entry.pluginId,
1291
+ pluginName: entry.plugin.manifest.name,
1292
+ pluginVersion: entry.plugin.manifest.version,
1293
+ platform,
1294
+ scope: options.commandOptions.scope,
1295
+ cwd: options.commandOptions.cwd,
1296
+ },
1297
+ configDigest: catalog.configDigest,
1298
+ sourceId: entry.source.sourceId,
1299
+ sourceIdentity: entry.source.sourceIdentity,
1300
+ resolvedCommit: entry.source.resolvedCommit,
1301
+ manifestDigest: entry.source.manifestDigest,
1302
+ snapshotDigest: entry.source.snapshotDigest,
1303
+ contentDigest: entry.source.manifest.entries.find((candidate) => candidate.name === entry.plugin.manifest.name)?.contentDigest,
1304
+ });
1305
+ }
1306
+ const lockedPlan = await createPlan();
1307
+ for (const pluginName of new Set(lockedPlan.targets.flatMap((target) => target.platform === 'claude'
1308
+ && (target.action === 'install'
1309
+ || target.action === 'upgrade'
1310
+ || target.action === 'reinstall')
1311
+ ? [target.pluginName]
1312
+ : []))) {
1313
+ await assertNoClaudeUnboundNativeNameCollision({
1314
+ pluginName,
1315
+ cwd: options.commandOptions.cwd,
1316
+ env: runtimeEnv,
1317
+ });
1318
+ }
1319
+ await assertAgentVersions({
1320
+ platforms: [...new Set(executionSelections.flatMap(({ entry, platform }) => supportsPlatform(entry.plugin.manifest, platform) ? [platform] : []))],
1321
+ cwd: options.commandOptions.cwd,
1322
+ env: runtimeEnv,
1323
+ runtime: {
1324
+ env: runtimeEnv,
1325
+ nativeCliRunner: options.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
1326
+ reporter: options.runtime?.reporter ?? createNoopReporter(),
1327
+ debugLogger: options.runtime?.debugLogger ?? createNoopDebugLogger(),
1328
+ },
1329
+ });
1330
+ const preparedTargets = new Map();
1331
+ const preparedTargetErrors = new Map();
1332
+ const lockedCollisionSelections = [];
1333
+ for (const { entry, platform } of executionSelections) {
1334
+ const planned = lockedPlan.targets.find((candidate) => candidate.pluginId === entry.pluginId && candidate.platform === platform);
1335
+ if (planned.action !== 'install'
1336
+ && planned.action !== 'upgrade'
1337
+ && planned.action !== 'reinstall')
1338
+ continue;
1339
+ const marketplaceName = marketplaceNameFor(entry, platform, planned.resolvedScope);
1340
+ try {
1341
+ const target = await inspection.buildTarget({
1342
+ sourceId: entry.source.sourceId,
1343
+ sourceIdentity: entry.source.sourceIdentity,
1344
+ pluginId: entry.pluginId,
1345
+ marketplaceName,
1346
+ marketplaceRoot: path.join(resolveAwHome(runtimeEnv), 'marketplaces', entry.source.sourceId),
1347
+ plugin: entry.plugin,
1348
+ platform,
1349
+ scope: planned.resolvedScope,
1350
+ cwd: options.commandOptions.cwd,
1351
+ command: planned.relation === 'dependency' ? planned.action : options.command,
1352
+ catalog: toCatalogResolution(entry.source),
1353
+ includeHistoricalLifecycleArtifacts: true,
1354
+ });
1355
+ preparedTargets.set(`${entry.pluginId}\0${platform}`, {
1356
+ target,
1357
+ driver: inspection.driver,
1358
+ context: executionContext,
1359
+ });
1360
+ if (selectedIds.has(entry.pluginId)) {
1361
+ await rebuildCommandTestHooks?.afterTargetBuilt?.({
1362
+ command: options.command,
1363
+ identity: target.identity,
1364
+ });
1365
+ }
1366
+ lockedCollisionSelections.push({
1367
+ pluginId: entry.pluginId,
1368
+ targetKey: `${platform}/${target.identity.scope}`,
1369
+ artifactKeys: (target.desiredOwnedComponents ?? target.ownedComponents)
1370
+ .filter((component) => !(component.kind === 'shared-config'
1371
+ && component.identity.artifactKey.startsWith('marketplace-')))
1372
+ .map((component) => 'path' in component
1373
+ ? path.resolve(component.path)
1374
+ : component.kind === 'native-plugin'
1375
+ ? `native:${component.pluginId}`
1376
+ : `shared:${component.label}`),
1377
+ });
1378
+ }
1379
+ catch (error) {
1380
+ preparedTargetErrors.set(`${entry.pluginId}\0${platform}`, error);
1381
+ }
1382
+ }
1383
+ const lockedCollisions = preflightDesiredArtifactCollisions(lockedCollisionSelections);
1384
+ if (lockedCollisions.length > 0) {
1385
+ throw namespacedPreflightError(`artifactCollision: ${lockedCollisions.map((collision) => `${collision.targetKey} (${collision.pluginIds.join(', ')})`).join('; ')}`, preflightTargets);
1386
+ }
1387
+ const removalRequiredConsumers = new Map();
1388
+ if ((options.command === 'cleanup' && !cleanupForce) || options.command === 'uninstall') {
1389
+ const removalStateInventory = await inventoryCatalogSourceReferences({
1390
+ cwd: options.commandOptions.cwd,
1391
+ env: runtimeEnv,
1392
+ includeHistoricalProjects: true,
1393
+ });
1394
+ if (options.command !== 'cleanup')
1395
+ assertCatalogSourceInventoryComplete(removalStateInventory);
1396
+ const inspectConsumer = async (options_) => {
1397
+ const marketplaceName = marketplaceNameFor(options_.entry, options_.platform, options_.scope, options_.scope === 'project' ? options_.cwd : null);
1398
+ options_.entry.plugin.marketplaceName = marketplaceName;
1399
+ const consumerTarget = await inspection.buildTarget({
1400
+ sourceId: options_.entry.source.sourceId,
1401
+ sourceIdentity: options_.entry.source.sourceIdentity,
1402
+ pluginId: options_.entry.pluginId,
1403
+ marketplaceName,
1404
+ marketplaceRoot: path.join(resolveAwHome(runtimeEnv), 'marketplaces', options_.entry.source.sourceId),
1405
+ plugin: options_.entry.plugin,
1406
+ platform: options_.platform,
1407
+ scope: options_.scope,
1408
+ cwd: options_.cwd,
1409
+ command: 'cleanup',
1410
+ catalog: toCatalogResolution(options_.entry.source),
1411
+ includeHistoricalLifecycleArtifacts: false,
1412
+ readOnlyInspectionPlan: true,
1413
+ });
1414
+ const consumerInspection = await inspectOwnedComponents({
1415
+ components: consumerTarget.ownedComponents,
1416
+ nativeProbe: inspection.driver.probeNative,
1417
+ verifyHealth: true,
1418
+ });
1419
+ return consumerInspection.state === 'absent' ? 'absent' : 'live';
1420
+ };
1421
+ const currentConsumerCandidates = [...new Map(removalStateInventory.references.flatMap((reference) => {
1422
+ if ((reference.kind !== 'namespacedOwner' && reference.kind !== 'namespacedMarketplace')
1423
+ || !reference.sourceId
1424
+ || !reference.sourceIdentity
1425
+ || !reference.pluginName
1426
+ || (reference.platform !== 'codex' && reference.platform !== 'claude')
1427
+ || (reference.scope !== 'user' && reference.scope !== 'project'))
1428
+ return [];
1429
+ const entry = available.find((candidate) => candidate.source.sourceId === reference.sourceId
1430
+ && candidate.source.sourceIdentity === reference.sourceIdentity
1431
+ && candidate.plugin.manifest.name === reference.pluginName);
1432
+ if (!entry)
1433
+ return [];
1434
+ if (reference.scope === 'project' && !reference.projectKey) {
1435
+ throw namespacedPreflightError(`dependencyStillRequired: cannot inspect project consumer ${entry.pluginId} without its project identity.`, preflightTargets);
1436
+ }
1437
+ const key = [
1438
+ entry.pluginId,
1439
+ reference.platform,
1440
+ reference.scope,
1441
+ reference.projectKey ?? '',
1442
+ ].join('\0');
1443
+ return [[key, {
1444
+ entry,
1445
+ platform: reference.platform,
1446
+ scope: reference.scope,
1447
+ projectKey: reference.projectKey ?? null,
1448
+ }]];
1449
+ })).values()];
1450
+ for (const dependencyTarget of executionSelections) {
1451
+ const dependencyPluginName = dependencyTarget.entry.plugin.manifest.name;
1452
+ for (const consumer of currentConsumerCandidates) {
1453
+ if (consumer.entry.source.sourceId
1454
+ !== dependencyTarget.entry.source.sourceId
1455
+ || !consumer.entry.plugin.manifest.dependencies?.includes(dependencyPluginName)
1456
+ || consumer.platform !== dependencyTarget.platform
1457
+ || (consumer.scope === 'user'
1458
+ && options.commandOptions.scope !== 'user')
1459
+ || (options.commandOptions.scope === 'project'
1460
+ && consumer.scope === 'project'
1461
+ && consumer.projectKey !== commandProjectKey))
1462
+ continue;
1463
+ const plannedConsumer = executionSelections.find((selection) => selection.entry.pluginId === consumer.entry.pluginId
1464
+ && selection.platform === consumer.platform
1465
+ && lockedPlan.targets.some((target) => target.pluginId === selection.entry.pluginId
1466
+ && target.platform === selection.platform
1467
+ && target.resolvedScope === consumer.scope
1468
+ && (consumer.scope === 'user' || consumer.projectKey === commandProjectKey)));
1469
+ if (plannedConsumer) {
1470
+ const dependencyExecutionKey = `${dependencyTarget.entry.pluginId}\0${consumer.platform}`;
1471
+ const required = removalRequiredConsumers.get(dependencyExecutionKey) ?? new Set();
1472
+ required.add(`${consumer.entry.pluginId}\0${consumer.platform}`);
1473
+ removalRequiredConsumers.set(dependencyExecutionKey, required);
1474
+ continue;
1475
+ }
1476
+ try {
1477
+ if (await inspectConsumer({
1478
+ entry: consumer.entry,
1479
+ platform: consumer.platform,
1480
+ scope: consumer.scope,
1481
+ cwd: consumer.projectKey ?? options.commandOptions.cwd,
1482
+ }) !== 'absent') {
1483
+ throw new Error('consumer is present, partial, or unreadable');
1484
+ }
1485
+ }
1486
+ catch {
1487
+ throw namespacedPreflightError(`dependencyStillRequired: ${dependencyTarget.entry.pluginId} is required by ${consumer.entry.pluginId}.`, preflightTargets);
1488
+ }
1489
+ }
1490
+ }
1491
+ const orderedSelections = [];
1492
+ const remaining = new Set(executionSelections);
1493
+ while (remaining.size > 0) {
1494
+ const ready = [...remaining].filter((candidate) => ![...remaining].some((consumer) => consumer.platform === candidate.platform
1495
+ && consumer.entry.source.sourceId === candidate.entry.source.sourceId
1496
+ && consumer.entry.plugin.manifest.dependencies?.includes(candidate.entry.plugin.manifest.name)))
1497
+ .sort((left, right) => left.entry.pluginId.localeCompare(right.entry.pluginId, 'en'));
1498
+ if (ready.length === 0) {
1499
+ throw namespacedPreflightError('dependencyGraphInvalid: removal graph contains a cycle.', preflightTargets);
1500
+ }
1501
+ for (const selection of ready) {
1502
+ orderedSelections.push(selection);
1503
+ remaining.delete(selection);
1504
+ }
1505
+ }
1506
+ executionSelections = orderedSelections;
1507
+ }
1508
+ const results = [];
1509
+ const dependencyStates = new Map();
1510
+ for (const { entry, platform } of executionSelections) {
1511
+ const planned = lockedPlan.targets.find((target) => target.pluginId === entry.pluginId && target.platform === platform);
1512
+ const directDependencyIds = (entry.plugin.manifest.dependencies ?? []).map((pluginName) => formatPluginId({ sourceId: entry.source.sourceId, pluginName }));
1513
+ const failedDependency = directDependencyIds.find((pluginId) => {
1514
+ const state = dependencyStates.get(`${pluginId}\0${platform}`);
1515
+ return state === 'failed' || state === 'skipped';
1516
+ });
1517
+ const failedConsumer = [...(removalRequiredConsumers.get(`${entry.pluginId}\0${platform}`) ?? [])]
1518
+ .find((consumerKey) => {
1519
+ const state = dependencyStates.get(consumerKey);
1520
+ return state === 'failed' || state === 'skipped';
1521
+ });
1522
+ const identity = {
1523
+ sourceId: entry.source.sourceId,
1524
+ sourceIdentity: entry.source.sourceIdentity,
1525
+ pluginId: entry.pluginId,
1526
+ pluginName: entry.plugin.manifest.name,
1527
+ pluginVersion: entry.plugin.manifest.version,
1528
+ platform,
1529
+ scope: planned.resolvedScope,
1530
+ cwd: options.commandOptions.cwd,
1531
+ };
1532
+ if (failedDependency || failedConsumer || planned.action === 'block') {
1533
+ const code = failedConsumer
1534
+ ? 'dependencyStillRequired'
1535
+ : failedDependency ? 'dependencyInstallFailed' : planned.errorCode ?? 'dependencyNotReady';
1536
+ const message = `${code}: ${failedConsumer
1537
+ ? `${entry.pluginId} retained because consumer ${failedConsumer.split('\0', 1)[0]} was not removed.`
1538
+ : failedDependency
1539
+ ? `${entry.pluginId} requires failed dependency ${failedDependency}.`
1540
+ : code === 'artifactCollision'
1541
+ ? `${entry.pluginId} has foreign-owned output. Remove or relocate it, then run cleanup and reinstall.`
1542
+ : code === 'dependencyNotReady'
1543
+ ? `${entry.pluginId} live state is unreadable. Run cleanup, then reinstall.`
1544
+ : `${entry.pluginId} dependency preflight is blocked.`}`;
1545
+ const result = failedResult(options.command, identity, message);
1546
+ results.push({
1547
+ platforms: [platform], plugins: [], warnings: [], rebuildResults: [result],
1548
+ targetResults: [{
1549
+ target: identity,
1550
+ action: failedDependency || failedConsumer ? 'skipped' : planned.action,
1551
+ state: 'failed',
1552
+ errorCode: code,
1553
+ message,
1554
+ }],
1555
+ overallState: 'failed', nativePlugins: {}, repoManagedArtifacts: [],
1556
+ receiptTargets: [{
1557
+ pluginName: identity.pluginName, pluginId: identity.pluginId,
1558
+ sourceId: identity.sourceId, platform, scope: planned.resolvedScope,
1559
+ }],
1560
+ });
1561
+ dependencyStates.set(`${entry.pluginId}\0${platform}`, failedDependency || failedConsumer ? 'skipped' : 'failed');
1562
+ continue;
1563
+ }
1564
+ if (planned.action === 'keep') {
1565
+ const result = {
1566
+ status: 'succeeded', command: options.command, target: identity, actions: [],
1567
+ cleanupAttempted: false, removed: [], absent: [], residual: [], quarantined: [], failures: [],
1568
+ };
1569
+ results.push({
1570
+ platforms: [platform], plugins: [identity.pluginName], warnings: [], rebuildResults: [result],
1571
+ targetResults: [{ target: identity, action: 'keep', state: 'completed' }],
1572
+ overallState: 'succeeded', nativePlugins: {}, repoManagedArtifacts: [],
1573
+ receiptTargets: [{
1574
+ pluginName: identity.pluginName, pluginId: identity.pluginId,
1575
+ sourceId: identity.sourceId, platform, scope: planned.resolvedScope,
1576
+ }],
1577
+ });
1578
+ dependencyStates.set(`${entry.pluginId}\0${platform}`, 'kept');
1579
+ continue;
1580
+ }
1581
+ const marketplaceName = marketplaceNameFor(entry, platform, planned.resolvedScope);
1582
+ const namespacedSource = {
1583
+ sourceId: entry.source.sourceId,
1584
+ sourceIdentity: entry.source.sourceIdentity,
1585
+ marketplaceName,
1586
+ marketplaceRoot: path.join(resolveAwHome(runtimeEnv), 'marketplaces', entry.source.sourceId),
1587
+ };
1588
+ entry.plugin.marketplaceName = marketplaceName;
1589
+ const executionResult = await runSingleSourceRebuildCommand({
1590
+ ...options,
1591
+ command: planned.relation === 'dependency'
1592
+ ? planned.action
1593
+ : options.command,
1594
+ pluginNames: [entry.plugin.manifest.name],
1595
+ all: false,
1596
+ commandOptions: { ...options.commandOptions, platform, scope: planned.resolvedScope },
1597
+ runtime: {
1598
+ ...options.runtime,
1599
+ env: runtimeEnv,
1600
+ catalogResolution: toCatalogResolution(entry.source),
1601
+ namespacedSource,
1602
+ operationLeaseHeld: true,
1603
+ dependencyReviewPreflightHandled: true,
1604
+ targetBuiltHookHandled: true,
1605
+ preparedTarget: preparedTargets.get(`${entry.pluginId}\0${platform}`),
1606
+ preparedTargetError: preparedTargetErrors.get(`${entry.pluginId}\0${platform}`),
1607
+ expectedCatalogConfigDigest: catalog.configDigest,
1608
+ resolvedReviewEvidenceByPlugin: {
1609
+ [entry.plugin.manifest.name]: {
1610
+ configDigest: catalog.configDigest,
1611
+ sourceId: entry.source.sourceId,
1612
+ sourceIdentity: entry.source.sourceIdentity,
1613
+ resolvedCommit: entry.source.resolvedCommit,
1614
+ manifestDigest: entry.source.manifestDigest,
1615
+ snapshotDigest: entry.source.snapshotDigest,
1616
+ contentDigest: entry.source.manifest.entries.find((candidate) => candidate.name === entry.plugin.manifest.name)?.contentDigest,
1617
+ },
1618
+ },
1619
+ },
1620
+ });
1621
+ results.push(executionResult);
1622
+ dependencyStates.set(`${entry.pluginId}\0${platform}`, executionResult.overallState === 'succeeded' ? 'completed' : 'failed');
1623
+ }
1624
+ const merged = mergeRebuildCommandResults(results);
1625
+ merged.dependencyPlan = lockedPlan;
1626
+ return leaseSafeRebuildResult(merged);
1627
+ },
1628
+ });
1629
+ if (cleanupForce) {
1630
+ try {
1631
+ await (options.runtime?.removeObsoleteInstallationContracts ?? fs.remove)(path.join(resolveAwHome(runtimeEnv), 'installation-contracts'));
1632
+ }
1633
+ catch (error) {
1634
+ resolvedResult.warnings.push(`obsoleteContractsCleanupFailed: ${error instanceof Error ? error.message : String(error)}`);
1635
+ }
1636
+ }
1637
+ return resolvedResult;
1638
+ }
1639
+ catch (error) {
1640
+ if (options.all && (liveTargets.length > 0 || legacyLiveTargets.length > 0)) {
1641
+ const projected = error;
1642
+ error = namespacedPreflightError(error instanceof Error ? error.message : String(error), projected.namespacedTargets ?? liveTargets, projected.legacyTargets ?? legacyLiveTargets);
1643
+ }
1644
+ if (options.command !== 'cleanup' && options.command !== 'uninstall')
1645
+ throw error;
1646
+ const message = error instanceof Error ? error.message : String(error);
1647
+ const catalogUnavailable = message.startsWith('Cannot resolve required catalog sources:')
1648
+ || message.includes('does not exist in the required catalog source set')
1649
+ || (message.includes('Catalog source') && message.includes('does not exist'));
1650
+ if (options.command === 'cleanup'
1651
+ && (catalogUnavailable || message.includes('sourceChanged'))
1652
+ && cleanupInventory
1653
+ && cleanupLiveTargets.length > 0) {
1654
+ if (!cleanupForce) {
1655
+ await assertOfflineCleanupDependents({
1656
+ targets: cleanupLiveTargets,
1657
+ cwd: options.commandOptions.cwd,
1658
+ env: runtimeEnv,
1659
+ });
1660
+ }
1661
+ return cleanupOfflineOwnedComponents({
1662
+ targets: cleanupLiveTargets,
1663
+ cwd: options.commandOptions.cwd,
1664
+ env: runtimeEnv,
1665
+ force: cleanupForce,
1666
+ removeObsoleteInstallationContracts: options.runtime?.removeObsoleteInstallationContracts,
1667
+ nativeCliRunner: options.runtime?.nativeCliRunner,
1668
+ corruptExclusiveDirectoryOperations: options.runtime?.corruptExclusiveDirectoryOperations,
1669
+ });
1670
+ }
1671
+ if (options.command === 'uninstall' && catalogUnavailable) {
1672
+ throw namespacedPreflightError(`catalogSourceUnavailable: ${message} Restore the source to run lifecycle uninstall, or use cleanup; use cleanup --force only for exclusively owned damaged output.`, liveTargets, legacyLiveTargets);
1673
+ }
1674
+ if ((message.includes('Catalog source') && message.includes('does not exist'))
1675
+ || message.includes('does not exist in the required catalog source set')) {
1676
+ throw namespacedPreflightError(`sourceMissing: ${message} Run cleanup for owner recovery, or cleanup --force for an exclusively owned damaged target.`, liveTargets, legacyLiveTargets);
1677
+ }
1678
+ throw error;
1679
+ }
1680
+ }
1681
+ //# sourceMappingURL=rebuild-command.js.map