@lesliechan721/aw 0.1.0-beta.7 → 0.1.0-beta.9

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 (341) hide show
  1. package/dist/authoring/scripts/add-skill.mjs +4 -4
  2. package/dist/authoring/scripts/add-skill.mjs.map +1 -1
  3. package/dist/authoring/scripts/init-plugin.mjs +8 -37
  4. package/dist/authoring/scripts/init-plugin.mjs.map +1 -1
  5. package/dist/authoring/scripts/lib/plugin-version-check.mjs +1 -1
  6. package/dist/authoring/scripts/lib/skill-scaffold.d.mts +77 -90
  7. package/dist/authoring/scripts/lib/skill-scaffold.mjs +99 -120
  8. package/dist/authoring/scripts/lib/skill-scaffold.mjs.map +1 -1
  9. package/dist/authoring/scripts/plugin-status.mjs +8 -11
  10. package/dist/authoring/scripts/plugin-status.mjs.map +1 -1
  11. package/dist/authoring/scripts/remove-plugin.mjs +2 -1
  12. package/dist/authoring/scripts/remove-plugin.mjs.map +1 -1
  13. package/dist/authoring/scripts/validate-plugin.mjs +64 -758
  14. package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
  15. package/dist/scripts/aw-skill-eval-materializer.d.ts +24 -0
  16. package/dist/scripts/{plugin-eval-materializer.js → aw-skill-eval-materializer.js} +34 -145
  17. package/dist/scripts/aw-skill-eval-materializer.js.map +1 -0
  18. package/dist/scripts/bundle-plugins.d.ts +1 -0
  19. package/dist/scripts/bundle-plugins.js +2 -1
  20. package/dist/scripts/bundle-plugins.js.map +1 -1
  21. package/dist/scripts/plugin-staging.d.ts +6 -8
  22. package/dist/scripts/plugin-staging.js +15 -28
  23. package/dist/scripts/plugin-staging.js.map +1 -1
  24. package/dist/scripts/test-plugin-scripts.js +2 -33
  25. package/dist/scripts/test-plugin-scripts.js.map +1 -1
  26. package/dist/src/adapters/helpers.js +2 -2
  27. package/dist/src/adapters/helpers.js.map +1 -1
  28. package/dist/src/authoring/workspace-commands.d.ts +17 -1
  29. package/dist/src/authoring/workspace-commands.js +21 -4
  30. package/dist/src/authoring/workspace-commands.js.map +1 -1
  31. package/dist/src/commands/aw-capabilities.d.ts +78 -0
  32. package/dist/src/commands/aw-capabilities.js +254 -0
  33. package/dist/src/commands/aw-capabilities.js.map +1 -0
  34. package/dist/src/commands/catalog-dev-source.d.ts +118 -0
  35. package/dist/src/commands/catalog-dev-source.js +417 -0
  36. package/dist/src/commands/catalog-dev-source.js.map +1 -0
  37. package/dist/src/commands/catalog-generation.d.ts +13 -0
  38. package/dist/src/commands/catalog-generation.js +13 -0
  39. package/dist/src/commands/catalog-generation.js.map +1 -0
  40. package/dist/src/commands/catalog-publication-inspection.d.ts +29 -28
  41. package/dist/src/commands/catalog-publication-inspection.js +138 -50
  42. package/dist/src/commands/catalog-publication-inspection.js.map +1 -1
  43. package/dist/src/commands/catalog-publication-journal.d.ts +49 -0
  44. package/dist/src/commands/catalog-publication-journal.js +147 -0
  45. package/dist/src/commands/catalog-publication-journal.js.map +1 -0
  46. package/dist/src/commands/catalog-publication-target.d.ts +18 -0
  47. package/dist/src/commands/catalog-publication-target.js +95 -0
  48. package/dist/src/commands/catalog-publication-target.js.map +1 -0
  49. package/dist/src/commands/catalog-publish.d.ts +58 -15
  50. package/dist/src/commands/catalog-publish.js +590 -210
  51. package/dist/src/commands/catalog-publish.js.map +1 -1
  52. package/dist/src/commands/catalog-source.d.ts +12 -15
  53. package/dist/src/commands/catalog-source.js +61 -86
  54. package/dist/src/commands/catalog-source.js.map +1 -1
  55. package/dist/src/commands/catalog-status.d.ts +18 -22
  56. package/dist/src/commands/catalog-status.js +81 -115
  57. package/dist/src/commands/catalog-status.js.map +1 -1
  58. package/dist/src/commands/catalog-workspace-resolution.d.ts +13 -0
  59. package/dist/src/commands/catalog-workspace-resolution.js +42 -0
  60. package/dist/src/commands/catalog-workspace-resolution.js.map +1 -0
  61. package/dist/src/commands/dependency-operation-plan.d.ts +88 -9
  62. package/dist/src/commands/dependency-operation-plan.js +331 -6
  63. package/dist/src/commands/dependency-operation-plan.js.map +1 -1
  64. package/dist/src/commands/init.d.ts +5 -11
  65. package/dist/src/commands/init.js +30 -51
  66. package/dist/src/commands/init.js.map +1 -1
  67. package/dist/src/commands/offline-cleanup-evidence.d.ts +43 -0
  68. package/dist/src/commands/offline-cleanup-evidence.js +116 -0
  69. package/dist/src/commands/offline-cleanup-evidence.js.map +1 -0
  70. package/dist/src/commands/options.d.ts +7 -1
  71. package/dist/src/commands/options.js +65 -6
  72. package/dist/src/commands/options.js.map +1 -1
  73. package/dist/src/commands/plugin-capabilities.js +5 -1
  74. package/dist/src/commands/plugin-capabilities.js.map +1 -1
  75. package/dist/src/commands/rebuild-command.d.ts +27 -13
  76. package/dist/src/commands/rebuild-command.js +1472 -471
  77. package/dist/src/commands/rebuild-command.js.map +1 -1
  78. package/dist/src/commands/rebuild-integration.d.ts +63 -8
  79. package/dist/src/commands/rebuild-integration.js +761 -439
  80. package/dist/src/commands/rebuild-integration.js.map +1 -1
  81. package/dist/src/commands/rebuild-operations.d.ts +2 -8
  82. package/dist/src/commands/rebuild-operations.js +48 -132
  83. package/dist/src/commands/rebuild-operations.js.map +1 -1
  84. package/dist/src/commands/runtime.js +21 -34
  85. package/dist/src/commands/runtime.js.map +1 -1
  86. package/dist/src/commands/skill-eval.d.ts +33 -0
  87. package/dist/src/commands/skill-eval.js +363 -0
  88. package/dist/src/commands/skill-eval.js.map +1 -0
  89. package/dist/src/commands/status-v6.d.ts +202 -0
  90. package/dist/src/commands/status-v6.js +1938 -0
  91. package/dist/src/commands/status-v6.js.map +1 -0
  92. package/dist/src/commands/sync-command.d.ts +21 -0
  93. package/dist/src/commands/sync-command.js +206 -0
  94. package/dist/src/commands/sync-command.js.map +1 -0
  95. package/dist/src/commands/wizard.d.ts +2 -2
  96. package/dist/src/commands/wizard.js +2 -2
  97. package/dist/src/commands/wizard.js.map +1 -1
  98. package/dist/src/commands/write-commands.js +33 -19
  99. package/dist/src/commands/write-commands.js.map +1 -1
  100. package/dist/src/constants.d.ts +7 -1
  101. package/dist/src/constants.js +7 -1
  102. package/dist/src/constants.js.map +1 -1
  103. package/dist/src/eval/manifest-v1.d.ts +66 -0
  104. package/dist/src/eval/manifest-v1.js +326 -0
  105. package/dist/src/eval/manifest-v1.js.map +1 -0
  106. package/dist/src/generators/local-plugin.d.ts +3 -0
  107. package/dist/src/generators/local-plugin.js +167 -45
  108. package/dist/src/generators/local-plugin.js.map +1 -1
  109. package/dist/src/index.d.ts +6 -1
  110. package/dist/src/index.js +863 -126
  111. package/dist/src/index.js.map +1 -1
  112. package/dist/src/output/command-receipt.d.ts +58 -8
  113. package/dist/src/output/command-receipt.js +141 -11
  114. package/dist/src/output/command-receipt.js.map +1 -1
  115. package/dist/src/output/model.d.ts +3 -44
  116. package/dist/src/output/model.js +1 -144
  117. package/dist/src/output/model.js.map +1 -1
  118. package/dist/src/output/rebuild-progress.js +0 -3
  119. package/dist/src/output/rebuild-progress.js.map +1 -1
  120. package/dist/src/portable/commands.d.ts +6 -2
  121. package/dist/src/portable/commands.js +57 -6
  122. package/dist/src/portable/commands.js.map +1 -1
  123. package/dist/src/portable/materializer.d.ts +4 -4
  124. package/dist/src/portable/materializer.js +61 -12
  125. package/dist/src/portable/materializer.js.map +1 -1
  126. package/dist/src/tui/catalog-generation.d.ts +35 -0
  127. package/dist/src/tui/catalog-generation.js +85 -0
  128. package/dist/src/tui/catalog-generation.js.map +1 -0
  129. package/dist/src/tui/components.js +1 -2
  130. package/dist/src/tui/components.js.map +1 -1
  131. package/dist/src/tui/console-app-v4.d.ts +1 -1
  132. package/dist/src/tui/console-app-v4.js +647 -196
  133. package/dist/src/tui/console-app-v4.js.map +1 -1
  134. package/dist/src/tui/controller-runtime.d.ts +6 -2
  135. package/dist/src/tui/controller-runtime.js +646 -137
  136. package/dist/src/tui/controller-runtime.js.map +1 -1
  137. package/dist/src/tui/controller.d.ts +77 -15
  138. package/dist/src/tui/controller.js +647 -306
  139. package/dist/src/tui/controller.js.map +1 -1
  140. package/dist/src/tui/diagnostics.d.ts +1 -2
  141. package/dist/src/tui/diagnostics.js.map +1 -1
  142. package/dist/src/tui/index.d.ts +1 -0
  143. package/dist/src/tui/index.js +1 -0
  144. package/dist/src/tui/index.js.map +1 -1
  145. package/dist/src/tui/input-display.d.ts +8 -0
  146. package/dist/src/tui/input-display.js +36 -0
  147. package/dist/src/tui/input-display.js.map +1 -0
  148. package/dist/src/tui/model.d.ts +102 -14
  149. package/dist/src/tui/model.js +630 -139
  150. package/dist/src/tui/model.js.map +1 -1
  151. package/dist/src/tui/router.d.ts +35 -0
  152. package/dist/src/tui/router.js.map +1 -1
  153. package/dist/src/tui/source-ref-presets.d.ts +3 -0
  154. package/dist/src/tui/source-ref-presets.js +11 -0
  155. package/dist/src/tui/source-ref-presets.js.map +1 -0
  156. package/dist/src/tui/views.js +31 -3
  157. package/dist/src/tui/views.js.map +1 -1
  158. package/dist/src/types.d.ts +104 -13
  159. package/dist/src/types.js.map +1 -1
  160. package/dist/src/utils/agent-version.d.ts +7 -1
  161. package/dist/src/utils/agent-version.js +41 -8
  162. package/dist/src/utils/agent-version.js.map +1 -1
  163. package/dist/src/utils/aw-home-mutation-lock.d.ts +1 -0
  164. package/dist/src/utils/aw-home-mutation-lock.js +32 -4
  165. package/dist/src/utils/aw-home-mutation-lock.js.map +1 -1
  166. package/dist/src/utils/bundle-integrity.d.ts +0 -1
  167. package/dist/src/utils/bundle-integrity.js +0 -25
  168. package/dist/src/utils/bundle-integrity.js.map +1 -1
  169. package/dist/src/utils/bundle-layout.js +8 -6
  170. package/dist/src/utils/bundle-layout.js.map +1 -1
  171. package/dist/src/utils/catalog-digests.d.ts +7 -0
  172. package/dist/src/utils/catalog-digests.js +40 -2
  173. package/dist/src/utils/catalog-digests.js.map +1 -1
  174. package/dist/src/utils/catalog-generation-control-snapshot.d.ts +11 -0
  175. package/dist/src/utils/catalog-generation-control-snapshot.js +45 -0
  176. package/dist/src/utils/catalog-generation-control-snapshot.js.map +1 -0
  177. package/dist/src/utils/catalog-generation-error.d.ts +13 -0
  178. package/dist/src/utils/catalog-generation-error.js +28 -0
  179. package/dist/src/utils/catalog-generation-error.js.map +1 -0
  180. package/dist/src/utils/catalog-generation-resolver.d.ts +20 -0
  181. package/dist/src/utils/catalog-generation-resolver.js +143 -0
  182. package/dist/src/utils/catalog-generation-resolver.js.map +1 -0
  183. package/dist/src/utils/catalog-generation-service.d.ts +43 -0
  184. package/dist/src/utils/catalog-generation-service.js +306 -0
  185. package/dist/src/utils/catalog-generation-service.js.map +1 -0
  186. package/dist/src/utils/catalog-generation-state.d.ts +17 -0
  187. package/dist/src/utils/catalog-generation-state.js +168 -0
  188. package/dist/src/utils/catalog-generation-state.js.map +1 -0
  189. package/dist/src/utils/catalog-generation-store.d.ts +34 -0
  190. package/dist/src/utils/catalog-generation-store.js +251 -0
  191. package/dist/src/utils/catalog-generation-store.js.map +1 -0
  192. package/dist/src/utils/catalog-manifest-v6.d.ts +5 -0
  193. package/dist/src/utils/{catalog-manifest-v4.js → catalog-manifest-v6.js} +35 -43
  194. package/dist/src/utils/catalog-manifest-v6.js.map +1 -0
  195. package/dist/src/utils/catalog-operation-context.d.ts +20 -0
  196. package/dist/src/utils/catalog-operation-context.js +141 -0
  197. package/dist/src/utils/catalog-operation-context.js.map +1 -0
  198. package/dist/src/utils/catalog-public-error.d.ts +7 -3
  199. package/dist/src/utils/catalog-public-error.js +21 -8
  200. package/dist/src/utils/catalog-public-error.js.map +1 -1
  201. package/dist/src/utils/catalog-runtime-projection.d.ts +3 -0
  202. package/dist/src/utils/catalog-runtime-projection.js +5 -40
  203. package/dist/src/utils/catalog-runtime-projection.js.map +1 -1
  204. package/dist/src/utils/catalog-snapshot.d.ts +5 -3
  205. package/dist/src/utils/catalog-snapshot.js +11 -3
  206. package/dist/src/utils/catalog-snapshot.js.map +1 -1
  207. package/dist/src/utils/catalog-source-identity.d.ts +1 -0
  208. package/dist/src/utils/catalog-source-identity.js +21 -2
  209. package/dist/src/utils/catalog-source-identity.js.map +1 -1
  210. package/dist/src/utils/catalog-source-references.d.ts +7 -0
  211. package/dist/src/utils/catalog-source-references.js +44 -55
  212. package/dist/src/utils/catalog-source-references.js.map +1 -1
  213. package/dist/src/utils/catalog-sources.d.ts +1 -0
  214. package/dist/src/utils/catalog-sources.js +55 -20
  215. package/dist/src/utils/catalog-sources.js.map +1 -1
  216. package/dist/src/utils/codex-config.d.ts +2 -0
  217. package/dist/src/utils/codex-config.js +26 -5
  218. package/dist/src/utils/codex-config.js.map +1 -1
  219. package/dist/src/utils/codex-manager.d.ts +81 -0
  220. package/dist/src/utils/codex-manager.js +810 -0
  221. package/dist/src/utils/codex-manager.js.map +1 -0
  222. package/dist/src/utils/codex-reconciler.d.ts +131 -0
  223. package/dist/src/utils/codex-reconciler.js +327 -0
  224. package/dist/src/utils/codex-reconciler.js.map +1 -0
  225. package/dist/src/utils/codex-shared-native.d.ts +56 -0
  226. package/dist/src/utils/codex-shared-native.js +87 -0
  227. package/dist/src/utils/codex-shared-native.js.map +1 -0
  228. package/dist/src/utils/codex-skill-staging.d.ts +2 -0
  229. package/dist/src/utils/codex-skill-staging.js.map +1 -1
  230. package/dist/src/utils/codex-surface-analysis.d.ts +44 -0
  231. package/dist/src/utils/codex-surface-analysis.js +247 -0
  232. package/dist/src/utils/codex-surface-analysis.js.map +1 -0
  233. package/dist/src/utils/dynamic-skill-tree.d.ts +4 -0
  234. package/dist/src/utils/dynamic-skill-tree.js +35 -5
  235. package/dist/src/utils/dynamic-skill-tree.js.map +1 -1
  236. package/dist/src/utils/git-catalog-provider.js +66 -140
  237. package/dist/src/utils/git-catalog-provider.js.map +1 -1
  238. package/dist/src/utils/lifecycle-active-store.d.ts +0 -28
  239. package/dist/src/utils/lifecycle-active-store.js +35 -247
  240. package/dist/src/utils/lifecycle-active-store.js.map +1 -1
  241. package/dist/src/utils/manifest.d.ts +1 -3
  242. package/dist/src/utils/manifest.js +1 -3
  243. package/dist/src/utils/manifest.js.map +1 -1
  244. package/dist/src/utils/multi-source-catalog.d.ts +3 -9
  245. package/dist/src/utils/multi-source-catalog.js +53 -110
  246. package/dist/src/utils/multi-source-catalog.js.map +1 -1
  247. package/dist/src/utils/native-cli.d.ts +49 -6
  248. package/dist/src/utils/native-cli.js +116 -33
  249. package/dist/src/utils/native-cli.js.map +1 -1
  250. package/dist/src/utils/orphan-marketplace-cleanup.js +1 -3
  251. package/dist/src/utils/orphan-marketplace-cleanup.js.map +1 -1
  252. package/dist/src/utils/ownership.d.ts +10 -11
  253. package/dist/src/utils/ownership.js +55 -112
  254. package/dist/src/utils/ownership.js.map +1 -1
  255. package/dist/src/utils/path-catalog-provider.d.ts +1 -1
  256. package/dist/src/utils/path-catalog-provider.js +52 -65
  257. package/dist/src/utils/path-catalog-provider.js.map +1 -1
  258. package/dist/src/utils/paths.d.ts +0 -1
  259. package/dist/src/utils/paths.js +0 -1
  260. package/dist/src/utils/paths.js.map +1 -1
  261. package/dist/src/utils/plugin-config-write.js +18 -40
  262. package/dist/src/utils/plugin-config-write.js.map +1 -1
  263. package/dist/src/utils/plugin-config.d.ts +1 -12
  264. package/dist/src/utils/plugin-config.js +107 -226
  265. package/dist/src/utils/plugin-config.js.map +1 -1
  266. package/dist/src/utils/plugin-intent-state.d.ts +39 -0
  267. package/dist/src/utils/plugin-intent-state.js +325 -0
  268. package/dist/src/utils/plugin-intent-state.js.map +1 -0
  269. package/dist/src/utils/plugin-scripts.d.ts +1 -1
  270. package/dist/src/utils/plugin-scripts.js +1 -1
  271. package/dist/src/utils/plugin-scripts.js.map +1 -1
  272. package/dist/src/utils/state-paths.js +7 -2
  273. package/dist/src/utils/state-paths.js.map +1 -1
  274. package/dist/src/utils/target-eligibility.d.ts +8 -2
  275. package/dist/src/utils/target-eligibility.js +9 -5
  276. package/dist/src/utils/target-eligibility.js.map +1 -1
  277. package/package.json +6 -4
  278. package/dist/authoring/scripts/check-plugin-versions.d.mts +0 -2
  279. package/dist/authoring/scripts/check-plugin-versions.mjs +0 -5
  280. package/dist/authoring/scripts/check-plugin-versions.mjs.map +0 -1
  281. package/dist/scripts/aw-skill-eval-engine.d.ts +0 -13
  282. package/dist/scripts/aw-skill-eval-engine.js +0 -31
  283. package/dist/scripts/aw-skill-eval-engine.js.map +0 -1
  284. package/dist/scripts/codex-eval-app-server.d.ts +0 -89
  285. package/dist/scripts/codex-eval-app-server.js +0 -1228
  286. package/dist/scripts/codex-eval-app-server.js.map +0 -1
  287. package/dist/scripts/codex-eval-isolation.d.ts +0 -61
  288. package/dist/scripts/codex-eval-isolation.js +0 -318
  289. package/dist/scripts/codex-eval-isolation.js.map +0 -1
  290. package/dist/scripts/codex-eval-process-management.d.ts +0 -8
  291. package/dist/scripts/codex-eval-process-management.js +0 -69
  292. package/dist/scripts/codex-eval-process-management.js.map +0 -1
  293. package/dist/scripts/codex-eval-process-tree.d.ts +0 -38
  294. package/dist/scripts/codex-eval-process-tree.js +0 -803
  295. package/dist/scripts/codex-eval-process-tree.js.map +0 -1
  296. package/dist/scripts/codex-eval-runtime-config.d.ts +0 -62
  297. package/dist/scripts/codex-eval-runtime-config.js +0 -843
  298. package/dist/scripts/codex-eval-runtime-config.js.map +0 -1
  299. package/dist/scripts/codex-trigger-eval.d.ts +0 -84
  300. package/dist/scripts/codex-trigger-eval.js +0 -968
  301. package/dist/scripts/codex-trigger-eval.js.map +0 -1
  302. package/dist/scripts/eval-plugin-skills-audited.d.ts +0 -6
  303. package/dist/scripts/eval-plugin-skills-audited.js +0 -261
  304. package/dist/scripts/eval-plugin-skills-audited.js.map +0 -1
  305. package/dist/scripts/eval-plugin-skills.d.ts +0 -45
  306. package/dist/scripts/eval-plugin-skills.js +0 -1586
  307. package/dist/scripts/eval-plugin-skills.js.map +0 -1
  308. package/dist/scripts/eval-run-layout.d.ts +0 -17
  309. package/dist/scripts/eval-run-layout.js +0 -26
  310. package/dist/scripts/eval-run-layout.js.map +0 -1
  311. package/dist/scripts/plugin-eval-contract.d.ts +0 -185
  312. package/dist/scripts/plugin-eval-contract.js +0 -695
  313. package/dist/scripts/plugin-eval-contract.js.map +0 -1
  314. package/dist/scripts/plugin-eval-materializer.d.ts +0 -13
  315. package/dist/scripts/plugin-eval-materializer.js.map +0 -1
  316. package/dist/scripts/skill-reporting.d.ts +0 -212
  317. package/dist/scripts/skill-reporting.js +0 -922
  318. package/dist/scripts/skill-reporting.js.map +0 -1
  319. package/dist/src/commands/status-v4.d.ts +0 -123
  320. package/dist/src/commands/status-v4.js +0 -905
  321. package/dist/src/commands/status-v4.js.map +0 -1
  322. package/dist/src/commands/status.d.ts +0 -93
  323. package/dist/src/commands/status.js +0 -442
  324. package/dist/src/commands/status.js.map +0 -1
  325. package/dist/src/utils/active-marketplace-runtime-lock.d.ts +0 -12
  326. package/dist/src/utils/active-marketplace-runtime-lock.js +0 -133
  327. package/dist/src/utils/active-marketplace-runtime-lock.js.map +0 -1
  328. package/dist/src/utils/catalog-manifest-v3.d.ts +0 -2
  329. package/dist/src/utils/catalog-manifest-v3.js +0 -3
  330. package/dist/src/utils/catalog-manifest-v3.js.map +0 -1
  331. package/dist/src/utils/catalog-manifest-v4.d.ts +0 -5
  332. package/dist/src/utils/catalog-manifest-v4.js.map +0 -1
  333. package/dist/src/utils/catalog-source-cache.d.ts +0 -62
  334. package/dist/src/utils/catalog-source-cache.js +0 -296
  335. package/dist/src/utils/catalog-source-cache.js.map +0 -1
  336. package/dist/src/utils/codex-project-surface.d.ts +0 -3
  337. package/dist/src/utils/codex-project-surface.js +0 -49
  338. package/dist/src/utils/codex-project-surface.js.map +0 -1
  339. package/dist/src/utils/plugin-release.d.ts +0 -2
  340. package/dist/src/utils/plugin-release.js +0 -2
  341. package/dist/src/utils/plugin-release.js.map +0 -1
package/dist/src/index.js CHANGED
@@ -4,14 +4,17 @@ import path from 'node:path';
4
4
  import { spawn } from 'node:child_process';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import { Command, CommanderError, Option } from 'commander';
7
+ import { doctorEvalProviders } from '@lesliechan721/agent-skill-eval';
7
8
  import { initCommand } from './commands/init.js';
9
+ import { resolveCatalogWorkspaceRoot } from './commands/catalog-workspace-resolution.js';
8
10
  import { addCatalogSourceCommand, explicitRefPolicy, listCatalogSources, removeCatalogSourceCommand, setPrimaryCatalogSourceCommand, updateCatalogSourceCommand, } from './commands/catalog-source.js';
11
+ import { catalogSourceStatusCommand, syncCatalogSourceCommand, } from './commands/catalog-generation.js';
9
12
  import { cleanupWriteCommand as cleanupCommand, installWriteCommand as installCommand, reinstallWriteCommand as reinstallCommand, uninstallWriteCommand as uninstallCommand, upgradeWriteCommand as upgradeCommand, } from './commands/write-commands.js';
13
+ import { syncCommand } from './commands/sync-command.js';
10
14
  import { formatInteractiveConsoleUnavailableMessage, runConsoleController, } from './commands/console.js';
11
15
  import { runCommandWizard, toWizardCandidates, WizardExecutionError, } from './commands/wizard.js';
12
16
  import { createCliExecutionContext, emitCommandEvent, } from './commands/runtime.js';
13
- import { loadConsoleItemsResult } from './commands/status.js';
14
- import { statusCommandV4 } from './commands/status-v4.js';
17
+ import { loadConsoleItemsResult, statusCommandV6 } from './commands/status-v6.js';
15
18
  import { normalizeUninstallCommandOptions, normalizeCleanupCommandOptions, resolveConfigReadResolution, resolveConfigProjectLayer, resolveConfigWriteScope, normalizeInstallCommandOptions, normalizeReinstallCommandOptions, normalizeUpgradeCommandOptions, } from './commands/options.js';
16
19
  import { isCommandWarningError, } from './types.js';
17
20
  import { formatWarnings } from './output/reporter.js';
@@ -26,6 +29,8 @@ import { writeCandidateEligibility } from './utils/target-eligibility.js';
26
29
  import { assertCatalogSourceReferencesSupported, inventoryLegacyConfigReferences, } from './utils/catalog-source-references.js';
27
30
  import { parsePluginId, withResolvedCatalogPlugin, withResolvedMultiSourceCatalog, } from './utils/multi-source-catalog.js';
28
31
  import { sanitizeCatalogSourceError } from './utils/catalog-public-error.js';
32
+ import { catalogGenerationErrorCode } from './utils/catalog-generation-error.js';
33
+ import { resolveCatalogOperationContext, } from './utils/catalog-operation-context.js';
29
34
  import { formatConfigCommandValue, parseConfigValue, } from './utils/config-value.js';
30
35
  import { withAwHomeMutationLock, } from './utils/aw-home-mutation-lock.js';
31
36
  import { installPortableSkills, materializePortableSkillsToDirectory, PortableCommandError, renderPortableReview, } from './portable/commands.js';
@@ -33,9 +38,12 @@ import { SkillsCliError } from './portable/skills-cli.js';
33
38
  import { computeReviewComponentDigest, listReviewRecords, parseReviewAttachment, publishReviewRecord, showReviewRecord, verifyReviewRecord, } from './commands/review-publication.js';
34
39
  import { resolveRepoRoot } from './utils/state-paths.js';
35
40
  import { runCatalogBuildCommand, runCatalogInitCommand, runCatalogValidateCommand, runCatalogVersionCommand, runPluginBuildCommand, runPluginTestCommand, } from './authoring/workspace-commands.js';
36
- import { runCatalogPublishCommand } from './commands/catalog-publish.js';
41
+ import { runCatalogPublishApplyCommand, runCatalogPublishPlanCommand, } from './commands/catalog-publish.js';
37
42
  import { getCatalogStatus, renderCatalogStatus } from './commands/catalog-status.js';
43
+ import { activateCatalogDevSource, catalogDevSourceError, createCatalogDevFailureReceipt, deactivateCatalogDevSource, getCatalogDevSourceStatus, } from './commands/catalog-dev-source.js';
38
44
  import { getPluginCapabilitiesResult, parsePluginCapabilitySurface, renderPluginCapabilities, } from './commands/plugin-capabilities.js';
45
+ import { AwCapabilityUnsupportedError, checkCurrentAw, describeCurrentAw, inspectPluginRequirements, } from './commands/aw-capabilities.js';
46
+ import { prepareSkillEval } from './commands/skill-eval.js';
39
47
  function createDefaultIo() {
40
48
  return {
41
49
  stdout: (text) => process.stdout.write(text),
@@ -61,6 +69,148 @@ function resolveCommandReceiptExitCode(result) {
61
69
  }
62
70
  return 0;
63
71
  }
72
+ class WriteCommandRequestError extends Error {
73
+ code = 'invalidArguments';
74
+ }
75
+ function normalizeWriteRequest(normalize) {
76
+ try {
77
+ return normalize();
78
+ }
79
+ catch (error) {
80
+ throw new WriteCommandRequestError(error instanceof Error ? error.message : String(error));
81
+ }
82
+ }
83
+ function writeCommandFailure(error) {
84
+ const message = redactString(error instanceof Error ? error.message : String(error));
85
+ if (error instanceof CommanderError || error instanceof WriteCommandRequestError) {
86
+ return { code: 'invalidArguments', message };
87
+ }
88
+ const explicitCode = error?.code;
89
+ if (typeof explicitCode === 'string' && /^[A-Za-z][A-Za-z0-9]*$/u.test(explicitCode)) {
90
+ return { code: explicitCode, message };
91
+ }
92
+ const separator = message.indexOf(':');
93
+ const prefix = separator > 0 ? message.slice(0, separator) : '';
94
+ return {
95
+ code: /^[A-Za-z][A-Za-z0-9]*$/u.test(prefix) ? prefix : 'writeCommandFailed',
96
+ message,
97
+ };
98
+ }
99
+ function preparseWriteReceiptRequest(argv) {
100
+ const request = { json: false, plugins: [] };
101
+ let positionalOnly = false;
102
+ for (let index = 1; index < argv.length; index += 1) {
103
+ const token = argv[index];
104
+ if (positionalOnly) {
105
+ request.plugins.push(token);
106
+ continue;
107
+ }
108
+ if (token === '--') {
109
+ positionalOnly = true;
110
+ continue;
111
+ }
112
+ if (token === '--json') {
113
+ request.json = true;
114
+ continue;
115
+ }
116
+ if (token === '--platform' || token === '--scope') {
117
+ const value = argv[index + 1];
118
+ if (token === '--platform')
119
+ request.platform = value;
120
+ else
121
+ request.scope = value;
122
+ index += 1;
123
+ continue;
124
+ }
125
+ if (token.startsWith('--platform=')) {
126
+ request.platform = token.slice('--platform='.length);
127
+ continue;
128
+ }
129
+ if (token.startsWith('--scope=')) {
130
+ request.scope = token.slice('--scope='.length);
131
+ continue;
132
+ }
133
+ if (token === '--dependency-scope' || token === '--script-timeout' || token === '--log-file') {
134
+ index += 1;
135
+ continue;
136
+ }
137
+ if (token.startsWith('--'))
138
+ continue;
139
+ if (token.startsWith('-') && token !== '-') {
140
+ const shortOptions = token.slice(1);
141
+ for (let offset = 0; offset < shortOptions.length; offset += 1) {
142
+ const option = shortOptions[offset];
143
+ if (option === 'j') {
144
+ request.json = true;
145
+ continue;
146
+ }
147
+ if (option === 'p' || option === 's') {
148
+ const value = shortOptions.slice(offset + 1) || argv[index + 1];
149
+ if (option === 'p')
150
+ request.platform = value;
151
+ else
152
+ request.scope = value;
153
+ if (shortOptions.length === offset + 1)
154
+ index += 1;
155
+ break;
156
+ }
157
+ }
158
+ continue;
159
+ }
160
+ request.plugins.push(token);
161
+ }
162
+ return request;
163
+ }
164
+ function jsonWriteCommandRequest(argv) {
165
+ const command = argv[0];
166
+ if (!['install', 'upgrade', 'reinstall', 'uninstall', 'cleanup', 'sync'].includes(command ?? '')) {
167
+ return null;
168
+ }
169
+ const request = preparseWriteReceiptRequest(argv);
170
+ if (!request.json)
171
+ return null;
172
+ const rawPlatform = request.platform;
173
+ const platform = rawPlatform === 'codex' || rawPlatform === 'claude' || rawPlatform === 'both'
174
+ ? rawPlatform
175
+ : 'codex';
176
+ return {
177
+ command: command,
178
+ plugins: request.plugins,
179
+ platform,
180
+ scope: request.scope === 'project' ? 'project' : 'user',
181
+ };
182
+ }
183
+ function writeCommandFailureReceipt(write, request, error) {
184
+ const platforms = request.platform === 'both'
185
+ ? ['codex', 'claude']
186
+ : [request.platform];
187
+ writeJsonReceipt(write, buildRebuildReceiptJson(request.command, {
188
+ platforms,
189
+ plugins: request.plugins,
190
+ warnings: [],
191
+ overallState: 'failed',
192
+ errors: [writeCommandFailure(error)],
193
+ receiptTargets: request.plugins.flatMap((selector) => platforms.map((platform) => {
194
+ let pluginName = selector;
195
+ let sourceId;
196
+ try {
197
+ const parsed = parsePluginId(selector);
198
+ pluginName = parsed.pluginName;
199
+ sourceId = parsed.sourceId;
200
+ }
201
+ catch {
202
+ // Keep the raw selector in the failed receipt.
203
+ }
204
+ return {
205
+ pluginName,
206
+ pluginId: selector,
207
+ ...(sourceId ? { sourceId } : {}),
208
+ platform,
209
+ scope: request.scope,
210
+ };
211
+ })),
212
+ }));
213
+ }
64
214
  async function runAuthoringScript(options) {
65
215
  const scriptPath = path.join(resolveCliPackageRoot(), 'dist', 'authoring', 'scripts', options.scriptName);
66
216
  return new Promise((resolve, reject) => {
@@ -141,6 +291,12 @@ export function buildEquivalentWriteCommandTokens(command, selection, rawOptions
141
291
  selection.platform ?? 'both',
142
292
  '--scope',
143
293
  selection.scope ?? 'user',
294
+ ...(rawOptions.allowManagedCodexInstall === true
295
+ ? ['--allow-managed-codex-install']
296
+ : []),
297
+ ...(command === 'install'
298
+ ? (rawOptions.dependencyScope ?? []).flatMap((value) => ['--dependency-scope', value])
299
+ : []),
144
300
  ...(command === 'cleanup' ? [] : optionTokens('--script-timeout', rawOptions.scriptTimeout)),
145
301
  ...(!all && selection.plugins.length > 0 ? ['--', ...selection.plugins] : []),
146
302
  ];
@@ -209,7 +365,6 @@ async function loadWizardCandidates(context, rawOptions) {
209
365
  cwd: context.cwd,
210
366
  scope: rawOptions.scope,
211
367
  platform: rawOptions.platform,
212
- includeCatalogOnly: true,
213
368
  }, context);
214
369
  return toWizardCandidates(loaded.items);
215
370
  }
@@ -301,7 +456,6 @@ async function resolveStoredOnlyConfigIdentity(options) {
301
456
  const sourceIdentity = [...identities][0];
302
457
  await withResolvedMultiSourceCatalog({
303
458
  cliVersion: resolveCliVersion(),
304
- freshnessPolicy: 'cacheFirst',
305
459
  sourceIds: [parsed.sourceId],
306
460
  env: options.context.env,
307
461
  consume: async (catalog) => {
@@ -330,7 +484,6 @@ async function resolveMultiSourceConfigRead(options) {
330
484
  return withResolvedCatalogPlugin({
331
485
  selector: options.selector,
332
486
  cliVersion: resolveCliVersion(),
333
- freshnessPolicy: 'cacheFirst',
334
487
  env: options.context.env,
335
488
  consume: async ({ pluginId, source, plugin }) => {
336
489
  const result = await resolveConfigRead({
@@ -389,9 +542,23 @@ async function resolveMultiSourceConfigRead(options) {
389
542
  return { ...stored, result };
390
543
  });
391
544
  }
392
- async function executeWriteCommand(command, pluginNames, rawOptions, context) {
545
+ export function createManagedCodexAuthorizer(rawOptions, context) {
546
+ if (rawOptions.allowManagedCodexInstall === true)
547
+ return async () => true;
548
+ if (!(context.interactive && context.isTty && !context.isCi && rawOptions.json !== true)
549
+ || !context.prompt.confirm)
550
+ return undefined;
551
+ return async () => {
552
+ const response = await context.prompt.confirm({
553
+ message: '系统中没有可用的 Codex CLI。是否获取本次操作所需的 AW-managed Codex runtime?',
554
+ defaultValue: false,
555
+ });
556
+ return !response.cancelled && response.value === true;
557
+ };
558
+ }
559
+ async function executeWriteCommand(command, pluginNames, rawOptions, context, directCli = false) {
393
560
  const raw = { cwd: context.cwd, ...rawOptions };
394
- const commandOptions = command === 'install'
561
+ const commandOptions = normalizeWriteRequest(() => command === 'install'
395
562
  ? normalizeInstallCommandOptions(raw)
396
563
  : command === 'upgrade'
397
564
  ? normalizeUpgradeCommandOptions(raw)
@@ -399,25 +566,32 @@ async function executeWriteCommand(command, pluginNames, rawOptions, context) {
399
566
  ? normalizeUninstallCommandOptions(raw)
400
567
  : command === 'cleanup'
401
568
  ? normalizeCleanupCommandOptions(raw)
402
- : normalizeReinstallCommandOptions(raw);
569
+ : normalizeReinstallCommandOptions(raw));
403
570
  await emitCommandEvent(context, {
404
571
  type: 'options:normalized',
405
572
  data: { plugins: pluginNames, options: commandOptions },
406
573
  });
574
+ const managedCodexAuthorizer = createManagedCodexAuthorizer(rawOptions, context);
575
+ const runtime = {
576
+ ...context,
577
+ directCli,
578
+ ...(managedCodexAuthorizer ? { managedCodexAuthorizer } : {}),
579
+ };
407
580
  switch (command) {
408
- case 'install': return installCommand(pluginNames, commandOptions, context);
409
- case 'upgrade': return upgradeCommand(pluginNames, commandOptions, context);
410
- case 'uninstall': return uninstallCommand(pluginNames, commandOptions, context);
411
- case 'cleanup': return cleanupCommand(pluginNames, commandOptions, context);
412
- case 'reinstall': return reinstallCommand(pluginNames, commandOptions, context);
581
+ case 'install': return installCommand(pluginNames, commandOptions, runtime);
582
+ case 'upgrade': return upgradeCommand(pluginNames, commandOptions, runtime);
583
+ case 'uninstall': return uninstallCommand(pluginNames, commandOptions, runtime);
584
+ case 'cleanup': return cleanupCommand(pluginNames, commandOptions, runtime);
585
+ case 'reinstall': return reinstallCommand(pluginNames, commandOptions, runtime);
413
586
  }
414
587
  }
415
588
  async function runWriteCommandAction(command, pluginNames, rawOptions, context) {
416
589
  if ((command === 'cleanup' || command === 'reinstall') && pluginNames.length > 1) {
417
- throw new Error(`${command} 命令当前只支持单个插件目标。`);
590
+ throw new WriteCommandRequestError(`${command} 命令当前只支持单个插件目标。`);
591
+ }
592
+ if (command === 'upgrade') {
593
+ normalizeWriteRequest(() => assertUpgradeAllConflict(pluginNames, rawOptions.all === true));
418
594
  }
419
- if (command === 'upgrade')
420
- assertUpgradeAllConflict(pluginNames, rawOptions.all === true);
421
595
  const missingPlugin = pluginNames.length === 0 && !(command === 'upgrade' && rawOptions.all === true);
422
596
  const missingPlatform = rawOptions.platform === undefined;
423
597
  const missingScope = command === 'cleanup' && rawOptions.scope === undefined;
@@ -433,17 +607,16 @@ async function runWriteCommandAction(command, pluginNames, rawOptions, context)
433
607
  if (!missing) {
434
608
  return {
435
609
  cancelled: false,
436
- result: await executeWriteCommand(command, pluginNames, rawOptions, context),
610
+ result: await executeWriteCommand(command, pluginNames, rawOptions, context, true),
437
611
  };
438
612
  }
439
613
  if (!isWizardAvailable(context, rawOptions)) {
440
- throw new Error(writeCommandUsage(command));
614
+ throw new WriteCommandRequestError(writeCommandUsage(command));
441
615
  }
442
616
  const loaded = await loadConsoleItemsResult({
443
617
  cwd: context.cwd,
444
618
  scope: rawOptions.scope,
445
619
  platform: rawOptions.platform,
446
- includeCatalogOnly: true,
447
620
  }, context);
448
621
  if (loaded.catalogUnavailable) {
449
622
  throw new Error('插件目录不可用。请运行 `aw init` 或 `aw init --force`,或使用完整参数重试。');
@@ -676,9 +849,32 @@ export function buildProgram(options = {}) {
676
849
  const plugin = program
677
850
  .command('plugin')
678
851
  .description('Create and validate AW plugin source');
852
+ const self = program
853
+ .command('self')
854
+ .description('Describe and check this AW executable');
855
+ self
856
+ .command('describe')
857
+ .description('Describe implemented AW capabilities')
858
+ .requiredOption('--json', 'emit one machine-readable JSON object')
859
+ .action(() => {
860
+ writeJsonReceipt(io.stdout, describeCurrentAw(resolveCliVersion()));
861
+ });
862
+ self
863
+ .command('check')
864
+ .description('Check nearby plugin requirements against this AW executable')
865
+ .option('--from <path>', 'start discovery from this file or directory')
866
+ .requiredOption('--json', 'emit one machine-readable JSON object')
867
+ .action(async (rawOptions) => {
868
+ const result = await checkCurrentAw({
869
+ awVersion: resolveCliVersion(),
870
+ from: path.resolve(cwd, rawOptions.from ?? '.'),
871
+ });
872
+ writeJsonReceipt(io.stdout, result);
873
+ commandExitState.exitCode = result.ok ? 0 : 1;
874
+ });
679
875
  plugin
680
876
  .command('capabilities')
681
- .description('Show the current plugin authoring capability contract')
877
+ .description('Show the current plugin manifest authoring surface')
682
878
  .option('--surface <surface>', 'manifest | build-config | extensions | slash-commands | mcp-apps | config | lifecycle | artifacts')
683
879
  .option('--json', 'emit one machine-readable JSON object', false)
684
880
  .action((rawOptions) => {
@@ -701,9 +897,128 @@ export function buildProgram(options = {}) {
701
897
  commandExitState.exitCode = 1;
702
898
  }
703
899
  });
900
+ plugin
901
+ .command('requirements')
902
+ .description('Inspect or update effective AW capabilities required by a plugin')
903
+ .argument('<plugin-directory>', 'plugin source directory')
904
+ .option('--workspace-root <root>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
905
+ .option('--add <capability>', 'add one declared AW capability')
906
+ .option('--remove <capability>', 'remove one declared AW capability')
907
+ .requiredOption('--json', 'emit one machine-readable JSON object')
908
+ .action(async (pluginDirectory, rawOptions) => {
909
+ try {
910
+ const result = await inspectPluginRequirements({
911
+ pluginDirectory,
912
+ ...(rawOptions.workspaceRoot ? { workspaceRoot: rawOptions.workspaceRoot } : {}),
913
+ ...(rawOptions.add ? { add: rawOptions.add } : {}),
914
+ ...(rawOptions.remove ? { remove: rawOptions.remove } : {}),
915
+ cwd,
916
+ });
917
+ writeJsonReceipt(io.stdout, result);
918
+ if (result.observations.some((observation) => observation.blocking)) {
919
+ commandExitState.exitCode = 1;
920
+ }
921
+ }
922
+ catch (error) {
923
+ writeJsonReceipt(io.stdout, {
924
+ schemaVersion: 1,
925
+ command: 'plugin:requirements',
926
+ ok: false,
927
+ error: error instanceof Error ? error.message : String(error),
928
+ });
929
+ commandExitState.exitCode = 1;
930
+ }
931
+ });
704
932
  const skill = program
705
933
  .command('skill')
706
934
  .description('Install, materialize, or validate Agent Skills');
935
+ const skillEval = skill
936
+ .command('eval')
937
+ .description('Prepare or diagnose deterministic Agent Skill Eval inputs');
938
+ skillEval
939
+ .command('doctor')
940
+ .description('Inspect Agent Skill Eval provider readiness without model execution')
941
+ .requiredOption('--json', 'emit one provider doctor JSON object')
942
+ .action(async () => {
943
+ try {
944
+ writeJsonReceipt(io.stdout, await doctorEvalProviders({ sourceEnv: env }));
945
+ }
946
+ catch (error) {
947
+ writeJsonReceipt(io.stdout, {
948
+ ok: false,
949
+ error: redactString(error instanceof Error ? error.message : String(error)),
950
+ });
951
+ commandExitState.exitCode = 1;
952
+ }
953
+ });
954
+ skillEval
955
+ .command('prepare')
956
+ .description('Prepare one complete Agent Skill Eval input directory')
957
+ .argument('<plugin>', 'canonical Workspace plugin name')
958
+ .argument('<skill>', 'owner Skill name')
959
+ .option('--suite <suite>', 'Eval suite ID')
960
+ .option('--profile <profile>', 'Eval profile ID')
961
+ .option('--workspace-root <root>', 'Catalog Workspace root')
962
+ .option('--split <split>', 'case split filter')
963
+ .option('--case <id>', 'case ID filter')
964
+ .option('--runs <count>', 'runs per selected case')
965
+ .option('--timeout-ms <milliseconds>', 'timeout for each provider attempt')
966
+ .option('--baseline <mode>', 'append without-skill comparison')
967
+ .option('--previous-version <runtime-skill-root>', 'append a previous-version comparison')
968
+ .option('--keep-workspace', 'retain the preparation materialization workspace', false)
969
+ .requiredOption('--output <spec-directory>', 'new EvalSpec directory')
970
+ .requiredOption('--json', 'emit one preparation receipt JSON object')
971
+ .action(async (pluginName, skillName, rawOptions) => {
972
+ try {
973
+ const workspace = await resolveCatalogWorkspaceRoot({
974
+ cwd,
975
+ ...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
976
+ mode: 'existing',
977
+ env,
978
+ });
979
+ const runs = rawOptions.runs === undefined
980
+ ? undefined
981
+ : (/^[1-9][0-9]*$/u.test(rawOptions.runs) ? Number(rawOptions.runs) : Number.NaN);
982
+ const timeoutMs = rawOptions.timeoutMs === undefined
983
+ ? undefined
984
+ : (/^[1-9][0-9]*$/u.test(rawOptions.timeoutMs) ? Number(rawOptions.timeoutMs) : Number.NaN);
985
+ const receipt = await prepareSkillEval({
986
+ workspaceRoot: workspace.workspaceRoot,
987
+ workspaceRootResolvedFrom: workspace.workspaceRootResolvedFrom,
988
+ pluginName,
989
+ skillName,
990
+ ...(rawOptions.suite === undefined ? {} : { suiteId: rawOptions.suite }),
991
+ ...(rawOptions.profile === undefined ? {} : { profileId: rawOptions.profile }),
992
+ output: rawOptions.output,
993
+ cwd,
994
+ env,
995
+ ...(rawOptions.split === undefined ? {} : { split: rawOptions.split }),
996
+ ...(rawOptions.case === undefined ? {} : { caseId: rawOptions.case }),
997
+ ...(runs === undefined ? {} : { runs }),
998
+ ...(timeoutMs === undefined ? {} : { timeoutMs }),
999
+ ...(rawOptions.baseline === undefined ? {} : {
1000
+ baseline: rawOptions.baseline,
1001
+ }),
1002
+ ...(rawOptions.previousVersion === undefined ? {} : {
1003
+ previousVersion: rawOptions.previousVersion,
1004
+ }),
1005
+ ...(rawOptions.keepWorkspace === true ? { keepWorkspace: true } : {}),
1006
+ });
1007
+ writeJsonReceipt(io.stdout, receipt);
1008
+ }
1009
+ catch (error) {
1010
+ writeJsonReceipt(io.stdout, {
1011
+ schemaVersion: 1,
1012
+ command: 'skill:eval:prepare',
1013
+ ok: false,
1014
+ errors: [{
1015
+ code: 'evalPreparationFailed',
1016
+ message: redactString(error instanceof Error ? error.message : String(error)),
1017
+ }],
1018
+ });
1019
+ commandExitState.exitCode = 1;
1020
+ }
1021
+ });
707
1022
  const review = program
708
1023
  .command('review')
709
1024
  .description('Publish and inspect immutable review records');
@@ -864,15 +1179,17 @@ export function buildProgram(options = {}) {
864
1179
  .option('--skill <name...>', 'install only selected Skill names')
865
1180
  .option('--agent <id...>', 'install to explicit Agent IDs')
866
1181
  .option('-y, --yes', 'confirm the reviewed install', false)
867
- .option('-j, --json', 'emit one receipt v4 JSON object', false)
1182
+ .option('-j, --json', 'emit one receipt v5 JSON object', false)
868
1183
  .action(async (selector, rawOptions) => {
869
1184
  const context = createActionContext('skill:install', {});
870
1185
  const writeFailure = (error) => {
871
- const code = error instanceof PortableCommandError || error instanceof SkillsCliError
872
- ? error.code
873
- : 'portableInstallFailed';
1186
+ const capabilityError = error instanceof AwCapabilityUnsupportedError ? error : undefined;
1187
+ const code = capabilityError?.code
1188
+ ?? (error instanceof PortableCommandError || error instanceof SkillsCliError
1189
+ ? error.code
1190
+ : 'portableInstallFailed');
874
1191
  writeJsonReceipt(io.stdout, {
875
- receiptSchemaVersion: 4,
1192
+ receiptSchemaVersion: 5,
876
1193
  command: 'skill:install',
877
1194
  ok: false,
878
1195
  status: 'failed',
@@ -888,7 +1205,15 @@ export function buildProgram(options = {}) {
888
1205
  materializationDigest: null,
889
1206
  verification: { records: [], missing: [] },
890
1207
  warnings: [],
891
- failures: [{ code, message: `${code}: portable Skill 安装未执行。` }],
1208
+ failures: [{
1209
+ code,
1210
+ message: capabilityError?.message ?? `${code}: portable Skill 安装未执行。`,
1211
+ ...(capabilityError ? {
1212
+ plugin: capabilityError.plugin,
1213
+ missingCapabilities: capabilityError.missingCapabilities,
1214
+ availableCapabilities: capabilityError.availableCapabilities,
1215
+ } : {}),
1216
+ }],
892
1217
  });
893
1218
  };
894
1219
  if (rawOptions.json && !rawOptions.yes) {
@@ -958,7 +1283,7 @@ export function buildProgram(options = {}) {
958
1283
  .requiredOption('-s, --scope <scope>', 'project or user')
959
1284
  .requiredOption('--out <dir>', 'output directory')
960
1285
  .option('--skill <name...>', 'write only selected Skill names')
961
- .option('-j, --json', 'emit one receipt v4 JSON object', false)
1286
+ .option('-j, --json', 'emit one receipt v5 JSON object', false)
962
1287
  .action(async (selector, rawOptions) => {
963
1288
  const context = createActionContext('skill:materialize', {});
964
1289
  try {
@@ -979,11 +1304,13 @@ export function buildProgram(options = {}) {
979
1304
  catch (error) {
980
1305
  if (!rawOptions.json)
981
1306
  throw error;
982
- const code = error instanceof PortableCommandError || error instanceof SkillsCliError
983
- ? error.code
984
- : 'portableMaterializeFailed';
1307
+ const capabilityError = error instanceof AwCapabilityUnsupportedError ? error : undefined;
1308
+ const code = capabilityError?.code
1309
+ ?? (error instanceof PortableCommandError || error instanceof SkillsCliError
1310
+ ? error.code
1311
+ : 'portableMaterializeFailed');
985
1312
  writeJsonReceipt(io.stdout, {
986
- receiptSchemaVersion: 4,
1313
+ receiptSchemaVersion: 5,
987
1314
  command: 'skill:materialize',
988
1315
  ok: false,
989
1316
  plugin: { id: selector },
@@ -995,7 +1322,15 @@ export function buildProgram(options = {}) {
995
1322
  configDigest: null,
996
1323
  materializationDigest: null,
997
1324
  outputDigest: null,
998
- errors: [{ code, message: `${code}: portable Skill 导出未执行。` }],
1325
+ errors: [{
1326
+ code,
1327
+ message: capabilityError?.message ?? `${code}: portable Skill 导出未执行。`,
1328
+ ...(capabilityError ? {
1329
+ plugin: capabilityError.plugin,
1330
+ missingCapabilities: capabilityError.missingCapabilities,
1331
+ availableCapabilities: capabilityError.availableCapabilities,
1332
+ } : {}),
1333
+ }],
999
1334
  });
1000
1335
  commandExitState.exitCode = 1;
1001
1336
  }
@@ -1007,7 +1342,7 @@ export function buildProgram(options = {}) {
1007
1342
  '',
1008
1343
  'During development, keep the current stable target when production content changes.',
1009
1344
  'Next, run `aw plugin validate`, `aw plugin test`, `aw plugin build`, and `aw catalog build`.',
1010
- 'Publish only as an explicit later step; inspect `aw catalog publish --help` first.',
1345
+ 'Publish only as an explicit later step; inspect `aw catalog publish plan --help` first.',
1011
1346
  '',
1012
1347
  ].join('\n'))
1013
1348
  .argument('<plugin-name>', 'lowercase hyphen-case plugin name')
@@ -1019,9 +1354,7 @@ export function buildProgram(options = {}) {
1019
1354
  .option('--skill-short-description <text>', 'initial Skill UI summary (25-64 characters)')
1020
1355
  .option('--skill-invocation <mode>', 'model | manual | claude-model-only (default: model)')
1021
1356
  .option('--version <semver>', 'initial stable plugin version (default: 0.1.0)')
1022
- .option('--min-version <semver>', 'compatibility.aw.minVersion')
1023
- .option('--catalog-min-version <semver>', 'target catalog compatibility minimum')
1024
- .option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
1357
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
1025
1358
  .option('--no-skills', 'create the plugin without a skills directory')
1026
1359
  .option('--with-mcp', 'add a minimal .mcp.json', false)
1027
1360
  .option('--with-apps', 'add a minimal .app.json', false)
@@ -1034,7 +1367,7 @@ export function buildProgram(options = {}) {
1034
1367
  '',
1035
1368
  'During development, keep the current stable target when production content changes.',
1036
1369
  'Next, run `aw plugin validate`, `aw plugin test`, `aw plugin build`, and `aw catalog build`.',
1037
- 'Publish only as an explicit later step; inspect `aw catalog publish --help` first.',
1370
+ 'Publish only as an explicit later step; inspect `aw catalog publish plan --help` first.',
1038
1371
  '',
1039
1372
  ].join('\n'))
1040
1373
  .argument('<plugin-name>', 'existing lowercase hyphen-case plugin name')
@@ -1042,35 +1375,39 @@ export function buildProgram(options = {}) {
1042
1375
  .option('--skill-description <text>', 'Skill goal and discovery description (required)')
1043
1376
  .option('--skill-short-description <text>', 'Skill UI summary (25-64 characters)')
1044
1377
  .option('--skill-invocation <mode>', 'model | manual | claude-model-only (default: model)')
1045
- .option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)');
1378
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)');
1046
1379
  plugin
1047
1380
  .command('remove')
1048
1381
  .description('Remove one committed and unchanged canonical plugin source tree')
1049
1382
  .argument('<plugin-name>', 'existing lowercase hyphen-case plugin name')
1050
- .requiredOption('--workspace-root <path>', 'Catalog Workspace root')
1383
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
1051
1384
  .option('--yes', 'confirm plugin source deletion', false)
1052
1385
  .option('--json', 'emit one schema 1 JSON object', false);
1053
1386
  plugin
1054
1387
  .command('validate')
1055
1388
  .description('Validate one source plugin directory')
1056
1389
  .argument('<plugin-directory>', 'source plugin directory')
1057
- .option('--catalog-min-version <semver>', 'validate compatibility against a target catalog')
1058
1390
  .option('--strict-agent-skills', 'allow only Agent Skills portable core frontmatter', false)
1059
1391
  .option('--claude-skill-profile <profile>', 'minimum | current (default: minimum)')
1060
1392
  .option('--version-base <git-ref>', 'production bundle comparison base (default: HEAD)')
1061
- .option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
1393
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
1062
1394
  .option('--json', 'emit one machine-readable JSON result', false);
1063
1395
  plugin
1064
1396
  .command('test')
1065
1397
  .description('Run deterministic Node tests declared by one source plugin')
1066
1398
  .argument('<plugin-directory>', 'source plugin directory')
1067
- .option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
1399
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
1068
1400
  .option('--json', 'emit one machine-readable JSON result', false)
1069
1401
  .action(async (pluginDirectory, rawOptions) => {
1070
1402
  try {
1403
+ const workspace = await resolveCatalogWorkspaceRoot({
1404
+ cwd: path.resolve(cwd, pluginDirectory),
1405
+ ...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: path.resolve(cwd, rawOptions.workspaceRoot) }),
1406
+ mode: 'existing',
1407
+ });
1071
1408
  commandExitState.exitCode = await runPluginTestCommand({
1072
- workspaceRoot: path.resolve(cwd, rawOptions.workspaceRoot ?? '.'),
1073
- pluginDirectory,
1409
+ ...workspace,
1410
+ pluginDirectory: path.resolve(cwd, pluginDirectory),
1074
1411
  json: rawOptions.json,
1075
1412
  io,
1076
1413
  });
@@ -1087,15 +1424,20 @@ export function buildProgram(options = {}) {
1087
1424
  .command('build')
1088
1425
  .description('Build and inspect one source plugin bundle')
1089
1426
  .argument('<plugin-directory>', 'source plugin directory')
1090
- .option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
1427
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
1091
1428
  .option('--out <path>', 'output path inside the Catalog Workspace')
1092
1429
  .option('--force', 'replace an existing generated output', false)
1093
1430
  .option('--json', 'emit one machine-readable JSON result', false)
1094
1431
  .action(async (pluginDirectory, rawOptions) => {
1095
1432
  try {
1433
+ const workspace = await resolveCatalogWorkspaceRoot({
1434
+ cwd: path.resolve(cwd, pluginDirectory),
1435
+ ...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: path.resolve(cwd, rawOptions.workspaceRoot) }),
1436
+ mode: 'existing',
1437
+ });
1096
1438
  await runPluginBuildCommand({
1097
- workspaceRoot: path.resolve(cwd, rawOptions.workspaceRoot ?? '.'),
1098
- pluginDirectory,
1439
+ ...workspace,
1440
+ pluginDirectory: path.resolve(cwd, pluginDirectory),
1099
1441
  out: rawOptions.out,
1100
1442
  force: rawOptions.force,
1101
1443
  json: rawOptions.json,
@@ -1117,15 +1459,7 @@ export function buildProgram(options = {}) {
1117
1459
  .option('--all', 'check every current Catalog Workspace plugin', false)
1118
1460
  .option('--base <git-ref>', 'explicit Git comparison base')
1119
1461
  .option('--json', 'emit one schema v3 JSON document', false)
1120
- .option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)');
1121
- plugin
1122
- .command('check-versions')
1123
- .description('Deprecated alias for plugin status')
1124
- .argument('[plugin-name]', 'one explicit plugin name')
1125
- .option('--all', 'check every plugin changed relative to the Git base', false)
1126
- .option('--base <git-ref>', 'explicit Git comparison base')
1127
- .option('--json', 'emit one schema v3 JSON document', false)
1128
- .option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)');
1462
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)');
1129
1463
  skill
1130
1464
  .command('validate')
1131
1465
  .description('Validate one Agent Skill directory')
@@ -1139,7 +1473,7 @@ export function buildProgram(options = {}) {
1139
1473
  catalog
1140
1474
  .command('init')
1141
1475
  .description('Initialize a local AW Catalog Workspace')
1142
- .option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
1476
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor, then Git worktree root, then current directory)')
1143
1477
  .option('--owner-name <name>', 'catalog owner name')
1144
1478
  .option('--owner-url <url>', 'catalog owner URL')
1145
1479
  .option('--display-name <name>', 'catalog display name')
@@ -1148,9 +1482,15 @@ export function buildProgram(options = {}) {
1148
1482
  .option('--json', 'emit one machine-readable JSON result', false)
1149
1483
  .action(async (rawOptions) => {
1150
1484
  try {
1485
+ const workspace = await resolveCatalogWorkspaceRoot({
1486
+ cwd,
1487
+ ...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
1488
+ mode: 'initialize',
1489
+ env,
1490
+ });
1151
1491
  await runCatalogInitCommand({
1152
1492
  ...rawOptions,
1153
- workspaceRoot: path.resolve(cwd, rawOptions.workspaceRoot ?? '.'),
1493
+ ...workspace,
1154
1494
  io,
1155
1495
  });
1156
1496
  }
@@ -1167,12 +1507,17 @@ export function buildProgram(options = {}) {
1167
1507
  .description('Read or set the Catalog version')
1168
1508
  .argument('[version]', 'stable or x.y.z-beta.N catalog version')
1169
1509
  .option('--bump <level>', 'bump the stable SemVer base: patch, minor, or major')
1170
- .option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
1510
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
1171
1511
  .option('--json', 'emit one machine-readable JSON result', false)
1172
1512
  .action(async (version, rawOptions) => {
1173
1513
  try {
1514
+ const workspace = await resolveCatalogWorkspaceRoot({
1515
+ cwd,
1516
+ ...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
1517
+ mode: 'existing',
1518
+ });
1174
1519
  await runCatalogVersionCommand({
1175
- workspaceRoot: path.resolve(cwd, rawOptions.workspaceRoot ?? '.'),
1520
+ ...workspace,
1176
1521
  version,
1177
1522
  bump: rawOptions.bump,
1178
1523
  json: rawOptions.json,
@@ -1190,14 +1535,19 @@ export function buildProgram(options = {}) {
1190
1535
  catalog
1191
1536
  .command('build')
1192
1537
  .description('Build a deterministic development Catalog snapshot')
1193
- .option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
1538
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
1194
1539
  .option('--out <path>', 'output path inside the Catalog Workspace')
1195
1540
  .option('--force', 'replace an existing generated output', false)
1196
1541
  .option('--json', 'emit one machine-readable JSON result', false)
1197
1542
  .action(async (rawOptions) => {
1198
1543
  try {
1544
+ const workspace = await resolveCatalogWorkspaceRoot({
1545
+ cwd,
1546
+ ...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
1547
+ mode: 'existing',
1548
+ });
1199
1549
  await runCatalogBuildCommand({
1200
- workspaceRoot: path.resolve(cwd, rawOptions.workspaceRoot ?? '.'),
1550
+ ...workspace,
1201
1551
  out: rawOptions.out,
1202
1552
  force: rawOptions.force,
1203
1553
  json: rawOptions.json,
@@ -1214,7 +1564,7 @@ export function buildProgram(options = {}) {
1214
1564
  });
1215
1565
  catalog
1216
1566
  .command('validate')
1217
- .description('Validate a schema 4 Catalog snapshot')
1567
+ .description('Validate a schema 6 Catalog snapshot')
1218
1568
  .argument('<snapshot-directory>', 'Catalog snapshot directory')
1219
1569
  .option('--json', 'emit one machine-readable JSON result', false)
1220
1570
  .action(async (snapshotDirectory, rawOptions) => {
@@ -1235,18 +1585,13 @@ export function buildProgram(options = {}) {
1235
1585
  });
1236
1586
  catalog
1237
1587
  .command('status')
1238
- .description('Inspect a Catalog Workspace; --preflight executes plugin validation and build code')
1239
- .option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
1240
- .option('--remote <name>', 'configured Git remote name for preflight (default: origin)')
1241
- .option('--branch <name>', 'dedicated Catalog branch for preflight (default: catalog)')
1242
- .option('--preflight', 'run publication validation and temporary plugin builds (executes plugin code)', false)
1588
+ .description('Inspect static Catalog Workspace, snapshot, and Git facts')
1589
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
1243
1590
  .option('--json', 'emit one machine-readable JSON status object', false)
1244
1591
  .action(async (rawOptions) => {
1245
1592
  const receipt = await getCatalogStatus({
1246
- workspaceRoot: path.resolve(cwd, rawOptions.workspaceRoot ?? '.'),
1247
- remote: rawOptions.remote,
1248
- branch: rawOptions.branch,
1249
- preflight: rawOptions.preflight,
1593
+ cwd,
1594
+ workspaceRoot: rawOptions.workspaceRoot,
1250
1595
  env,
1251
1596
  });
1252
1597
  if (rawOptions.json)
@@ -1255,23 +1600,70 @@ export function buildProgram(options = {}) {
1255
1600
  io.stdout(renderCatalogStatus(receipt));
1256
1601
  commandExitState.exitCode = receipt.ok ? 0 : 1;
1257
1602
  });
1258
- catalog
1603
+ const catalogPublish = catalog
1259
1604
  .command('publish')
1260
- .description('Publish a versioned Catalog snapshot to a configured Git remote')
1261
- .option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
1262
- .option('--remote <name>', 'configured Git remote name (default: origin)')
1605
+ .description('Plan or apply a versioned Catalog publication');
1606
+ catalogPublish
1607
+ .command('plan')
1608
+ .description('Prepare and inspect the exact Catalog publication plan')
1609
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
1610
+ .option('--remote <name>', 'Git remote (default: origin, otherwise sole remote; explicit if ambiguous)')
1611
+ .option('--branch <name>', 'dedicated Catalog branch (default: catalog)')
1612
+ .option('--json', 'emit one machine-readable JSON result', false)
1613
+ .action(async (rawOptions) => {
1614
+ try {
1615
+ const result = await runCatalogPublishPlanCommand({
1616
+ cwd,
1617
+ workspaceRoot: rawOptions.workspaceRoot,
1618
+ remote: rawOptions.remote,
1619
+ branch: rawOptions.branch,
1620
+ env,
1621
+ io,
1622
+ });
1623
+ if (rawOptions.json)
1624
+ writeJsonReceipt(io.stdout, result);
1625
+ else {
1626
+ writeLine(io.stdout, `Workspace identity: ${result.workspaceIdentity}`);
1627
+ writeLine(io.stdout, `Source HEAD: ${result.sourceHead}`);
1628
+ writeLine(io.stdout, `Remote identity: ${result.descriptor.remote.identityDigest}`);
1629
+ writeLine(io.stdout, `Remote: ${result.remote} (${result.remoteUrl})`);
1630
+ writeLine(io.stdout, `Branch: refs/heads/${result.branch}`);
1631
+ writeLine(io.stdout, `Parent: ${result.parent ?? '<root>'}`);
1632
+ writeLine(io.stdout, `Tag: refs/tags/${result.tag}`);
1633
+ writeLine(io.stdout, `Snapshot digest: ${result.snapshotDigest}`);
1634
+ writeLine(io.stdout, `Plan digest: ${result.planDigest}`);
1635
+ }
1636
+ }
1637
+ catch (error) {
1638
+ const message = error instanceof Error ? error.message : String(error);
1639
+ if (rawOptions.json)
1640
+ writeJsonReceipt(io.stdout, {
1641
+ command: 'catalog:publish:plan',
1642
+ ok: false,
1643
+ errors: [{ message }],
1644
+ });
1645
+ writeLine(io.stderr, message);
1646
+ commandExitState.exitCode = 1;
1647
+ }
1648
+ });
1649
+ catalogPublish
1650
+ .command('apply')
1651
+ .description('Apply an authorized Catalog publication plan')
1652
+ .option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
1653
+ .option('--remote <name>', 'Git remote (default: origin, otherwise sole remote; explicit if ambiguous)')
1263
1654
  .option('--branch <name>', 'dedicated Catalog branch (default: catalog)')
1264
- .option('--expected-descriptor-digest <digest>', 'required exact descriptor returned by publication preflight')
1655
+ .requiredOption('--expected-plan-digest <sha256>', 'exact plan digest returned by catalog publish plan')
1265
1656
  .option('-y, --yes', 'confirm publication without a prompt', false)
1266
1657
  .option('--json', 'emit one machine-readable JSON result', false)
1267
1658
  .action(async (rawOptions) => {
1268
1659
  try {
1269
- const context = createActionContext('catalog:publish', {});
1270
- const result = await runCatalogPublishCommand({
1271
- workspaceRoot: path.resolve(cwd, rawOptions.workspaceRoot ?? '.'),
1660
+ const context = createActionContext('catalog:publish:apply', {});
1661
+ const result = await runCatalogPublishApplyCommand({
1662
+ cwd,
1663
+ workspaceRoot: rawOptions.workspaceRoot,
1272
1664
  remote: rawOptions.remote,
1273
1665
  branch: rawOptions.branch,
1274
- expectedDescriptorDigest: rawOptions.expectedDescriptorDigest,
1666
+ expectedPlanDigest: rawOptions.expectedPlanDigest,
1275
1667
  yes: rawOptions.yes,
1276
1668
  json: rawOptions.json,
1277
1669
  env,
@@ -1300,7 +1692,7 @@ export function buildProgram(options = {}) {
1300
1692
  const message = error instanceof Error ? error.message : String(error);
1301
1693
  if (rawOptions.json)
1302
1694
  writeJsonReceipt(io.stdout, {
1303
- command: 'catalog:publish',
1695
+ command: 'catalog:publish:apply',
1304
1696
  ok: false,
1305
1697
  errors: [{ message }],
1306
1698
  });
@@ -1308,6 +1700,82 @@ export function buildProgram(options = {}) {
1308
1700
  commandExitState.exitCode = 1;
1309
1701
  }
1310
1702
  });
1703
+ const catalogDev = catalog
1704
+ .command('dev')
1705
+ .description('Manage the current Catalog Workspace development source');
1706
+ catalogDev
1707
+ .command('activate')
1708
+ .option('--workspace-root <path>', 'explicit Catalog Workspace root')
1709
+ .option('--source-id <id>', 'explicit managed source ID')
1710
+ .option('--primary', 'make the development source primary', false)
1711
+ .option('--force-build', 'rebuild a current snapshot', false)
1712
+ .requiredOption('--json', 'emit one schema 2 JSON receipt')
1713
+ .action(async (rawOptions) => {
1714
+ try {
1715
+ const receipt = await activateCatalogDevSource({
1716
+ cwd,
1717
+ workspaceRoot: rawOptions.workspaceRoot,
1718
+ sourceId: rawOptions.sourceId,
1719
+ primary: rawOptions.primary,
1720
+ forceBuild: rawOptions.forceBuild,
1721
+ cliVersion: resolveCliVersion(),
1722
+ env,
1723
+ });
1724
+ writeJsonReceipt(io.stdout, receipt);
1725
+ commandExitState.exitCode = receipt.ok ? 0 : 1;
1726
+ }
1727
+ catch (error) {
1728
+ const failure = catalogDevSourceError(error);
1729
+ writeJsonReceipt(io.stdout, createCatalogDevFailureReceipt({
1730
+ command: 'activate', cwd, workspaceRoot: rawOptions.workspaceRoot,
1731
+ sourceId: rawOptions.sourceId, ...failure,
1732
+ }));
1733
+ commandExitState.exitCode = 1;
1734
+ }
1735
+ });
1736
+ catalogDev
1737
+ .command('status')
1738
+ .option('--workspace-root <path>', 'explicit Catalog Workspace root')
1739
+ .requiredOption('--json', 'emit one schema 3 JSON receipt')
1740
+ .action(async (rawOptions) => {
1741
+ const receipt = await getCatalogDevSourceStatus({
1742
+ cwd,
1743
+ workspaceRoot: rawOptions.workspaceRoot,
1744
+ cliVersion: resolveCliVersion(),
1745
+ env,
1746
+ });
1747
+ writeJsonReceipt(io.stdout, receipt);
1748
+ commandExitState.exitCode = receipt.ok ? 0 : 1;
1749
+ });
1750
+ catalogDev
1751
+ .command('deactivate')
1752
+ .option('--workspace-root <path>', 'explicit Catalog Workspace root')
1753
+ .option('--source-id <id>', 'recover one managed source by exact ID')
1754
+ .option('--replacement-primary <id>', 'replacement when the target source is primary')
1755
+ .option('-y, --yes', 'confirm recovery by source ID', false)
1756
+ .requiredOption('--json', 'emit one schema 2 JSON receipt')
1757
+ .action(async (rawOptions) => {
1758
+ try {
1759
+ const receipt = await deactivateCatalogDevSource({
1760
+ cwd,
1761
+ workspaceRoot: rawOptions.workspaceRoot,
1762
+ sourceId: rawOptions.sourceId,
1763
+ replacementPrimary: rawOptions.replacementPrimary,
1764
+ yes: rawOptions.yes,
1765
+ env,
1766
+ });
1767
+ writeJsonReceipt(io.stdout, receipt);
1768
+ commandExitState.exitCode = receipt.ok ? 0 : 1;
1769
+ }
1770
+ catch (error) {
1771
+ const failure = catalogDevSourceError(error);
1772
+ writeJsonReceipt(io.stdout, createCatalogDevFailureReceipt({
1773
+ command: 'deactivate', cwd, workspaceRoot: rawOptions.workspaceRoot,
1774
+ sourceId: rawOptions.sourceId, ...failure,
1775
+ }));
1776
+ commandExitState.exitCode = 1;
1777
+ }
1778
+ });
1311
1779
  const catalogSource = catalog
1312
1780
  .command('source')
1313
1781
  .description('Manage catalog sources');
@@ -1316,7 +1784,7 @@ export function buildProgram(options = {}) {
1316
1784
  const message = failure instanceof Error ? failure.message : String(error);
1317
1785
  if (json) {
1318
1786
  writeJsonReceipt(io.stdout, {
1319
- receiptSchemaVersion: 4,
1787
+ receiptSchemaVersion: 5,
1320
1788
  command,
1321
1789
  ok: false,
1322
1790
  changed: false,
@@ -1328,20 +1796,43 @@ export function buildProgram(options = {}) {
1328
1796
  writeLine(io.stderr, message);
1329
1797
  commandExitState.exitCode = 1;
1330
1798
  };
1799
+ const writeCatalogGenerationFailure = (command, sourceId, json, error) => {
1800
+ const failure = sanitizeCatalogSourceError(error, env);
1801
+ const message = redactString(failure.message);
1802
+ if (json) {
1803
+ writeJsonReceipt(io.stdout, {
1804
+ ...(command === 'catalog:source:sync'
1805
+ ? { catalogGenerationSchemaVersion: 1 }
1806
+ : { catalogGenerationStatusSchemaVersion: 1 }),
1807
+ command,
1808
+ ok: false,
1809
+ ...(sourceId ? { sourceId } : {}),
1810
+ errors: [{ code: catalogGenerationErrorCode(error), message }],
1811
+ });
1812
+ }
1813
+ writeLine(io.stderr, message);
1814
+ commandExitState.exitCode = 1;
1815
+ };
1331
1816
  const writeConfigMutationFailure = (command, plugin, json, error) => {
1332
1817
  const message = error instanceof Error ? error.message : String(error);
1333
- const code = message.includes('legacyStateUnsupported')
1334
- ? 'legacyStateUnsupported'
1335
- : message.includes('sourceChanged')
1336
- ? 'sourceChanged'
1337
- : message.includes('sourceMissing')
1338
- ? 'sourceMissing'
1339
- : message.startsWith('Cannot resolve required catalog sources:')
1340
- ? 'catalogSourceUnavailable'
1341
- : message.split(':', 1)[0] || 'configMutationFailed';
1818
+ const generationCode = catalogGenerationErrorCode(error);
1819
+ const code = generationCode === 'catalogGenerationUnavailable'
1820
+ || generationCode === 'catalogGenerationSourceMissing'
1821
+ ? 'catalogSourceUnavailable'
1822
+ : generationCode !== 'catalogGenerationFailed'
1823
+ ? generationCode
1824
+ : message.includes('legacyStateUnsupported')
1825
+ ? 'legacyStateUnsupported'
1826
+ : message.includes('sourceChanged')
1827
+ ? 'sourceChanged'
1828
+ : message.includes('sourceMissing')
1829
+ ? 'sourceMissing'
1830
+ : message.startsWith('Cannot resolve required catalog sources:')
1831
+ ? 'catalogSourceUnavailable'
1832
+ : message.split(':', 1)[0] || 'configMutationFailed';
1342
1833
  if (json && !message.includes('Usage:')) {
1343
1834
  writeJsonReceipt(io.stdout, {
1344
- receiptSchemaVersion: 4,
1835
+ receiptSchemaVersion: 5,
1345
1836
  command,
1346
1837
  ok: false,
1347
1838
  overallState: 'failed',
@@ -1352,16 +1843,25 @@ export function buildProgram(options = {}) {
1352
1843
  writeLine(io.stderr, message);
1353
1844
  commandExitState.exitCode = 1;
1354
1845
  };
1355
- const withResolvedConfigMutationPlugin = (context, selector, consume) => withAwHomeMutationLock({
1356
- env: context.env,
1357
- action: (awHomeMutationToken) => withResolvedCatalogPlugin({
1358
- selector,
1359
- cliVersion: resolveCliVersion(),
1360
- freshnessPolicy: 'requireRemote',
1846
+ const withResolvedConfigMutationPlugin = (context, selector, consume) => (async () => {
1847
+ const parsed = parsePluginId(selector);
1848
+ return withAwHomeMutationLock({
1361
1849
  env: context.env,
1362
- consume: (resolution) => consume(resolution, awHomeMutationToken),
1363
- }),
1364
- });
1850
+ action: async (awHomeMutationToken) => {
1851
+ const catalogOperationContext = await resolveCatalogOperationContext({
1852
+ ...(parsed.sourceId ? { sourceIds: [parsed.sourceId] } : {}),
1853
+ env: context.env,
1854
+ });
1855
+ return withResolvedCatalogPlugin({
1856
+ selector,
1857
+ cliVersion: resolveCliVersion(),
1858
+ operationContext: catalogOperationContext,
1859
+ env: context.env,
1860
+ consume: (resolution) => consume(resolution, awHomeMutationToken, catalogOperationContext),
1861
+ });
1862
+ },
1863
+ });
1864
+ })();
1365
1865
  catalogSource
1366
1866
  .command('list')
1367
1867
  .option('-j, --json', 'print catalog sources as JSON', false)
@@ -1376,6 +1876,60 @@ export function buildProgram(options = {}) {
1376
1876
  writeLine(io.stdout, `${source.primary ? '*' : '-'} ${source.id} ${source.type} ${source.sourceIdentity}`);
1377
1877
  }
1378
1878
  });
1879
+ catalogSource
1880
+ .command('sync')
1881
+ .argument('<id>')
1882
+ .option('--check', 'fetch and validate without changing the Catalog store or Active state', false)
1883
+ .option('-j, --json', 'print the source sync result as JSON', false)
1884
+ .action(async (id, rawOptions) => {
1885
+ try {
1886
+ const result = await syncCatalogSourceCommand({
1887
+ sourceId: id,
1888
+ cliVersion: resolveCliVersion(),
1889
+ check: rawOptions.check === true,
1890
+ env,
1891
+ });
1892
+ if (rawOptions.json) {
1893
+ writeJsonReceipt(io.stdout, {
1894
+ ...result,
1895
+ command: 'catalog:source:sync',
1896
+ ok: true,
1897
+ });
1898
+ }
1899
+ else {
1900
+ writeLine(io.stdout, rawOptions.check
1901
+ ? `Catalog source ${id} is valid.`
1902
+ : `Catalog source ${id}: ${result.outcome}.`);
1903
+ }
1904
+ }
1905
+ catch (error) {
1906
+ writeCatalogGenerationFailure('catalog:source:sync', id, rawOptions.json === true, error);
1907
+ }
1908
+ });
1909
+ catalogSource
1910
+ .command('status')
1911
+ .argument('[id]')
1912
+ .option('-j, --json', 'print offline Catalog source status as JSON', false)
1913
+ .action(async (id, rawOptions) => {
1914
+ try {
1915
+ const result = await catalogSourceStatusCommand({ sourceId: id, env });
1916
+ if (rawOptions.json) {
1917
+ writeJsonReceipt(io.stdout, result);
1918
+ }
1919
+ else {
1920
+ for (const source of result.sources) {
1921
+ const active = source.active
1922
+ ? `Active ${source.active.snapshotDigest}`
1923
+ : 'no Active';
1924
+ const readiness = source.activeReady ? 'ready' : 'not ready';
1925
+ writeLine(io.stdout, `${source.sourceId}: ${active}, ${readiness}`);
1926
+ }
1927
+ }
1928
+ }
1929
+ catch (error) {
1930
+ writeCatalogGenerationFailure('catalog:source:status', id, rawOptions.json === true, error);
1931
+ }
1932
+ });
1379
1933
  catalogSource
1380
1934
  .command('add')
1381
1935
  .argument('<id>')
@@ -1520,7 +2074,6 @@ export function buildProgram(options = {}) {
1520
2074
  });
1521
2075
  program
1522
2076
  .command('init')
1523
- .option('-f, --force', 're-fetch and rebuild the current catalog cache entry', false)
1524
2077
  .option('-j, --json', 'print receipt as JSON', false)
1525
2078
  .option('-v, --verbose', 'show command diagnostics', false)
1526
2079
  .option('-D, --debug', 'write debug diagnostics to a log file', false)
@@ -1528,8 +2081,6 @@ export function buildProgram(options = {}) {
1528
2081
  .action(async (rawOptions) => {
1529
2082
  const context = createActionContext('init', rawOptions);
1530
2083
  const result = await runActionWithContext(context, () => initCommand({
1531
- force: rawOptions.force,
1532
- cliVersion: resolveCliVersion(),
1533
2084
  env: context.env,
1534
2085
  }));
1535
2086
  if (rawOptions.json) {
@@ -1540,19 +2091,68 @@ export function buildProgram(options = {}) {
1540
2091
  writeLine(io.stdout, line);
1541
2092
  }
1542
2093
  }
1543
- writeWarnings(io.stderr, result.warnings, { actionableOnly: true });
1544
2094
  for (const source of result.sources) {
1545
2095
  if (!source.ok && source.error)
1546
2096
  writeLine(io.stderr, `${source.id}: ${source.error}`);
1547
2097
  }
1548
2098
  commandExitState.exitCode = result.ok ? 0 : 1;
1549
2099
  });
2100
+ program
2101
+ .command('sync')
2102
+ .description('Reconcile Codex actual state from existing desired intent')
2103
+ .argument('[plugins...]')
2104
+ .requiredOption('-s, --scope <scope>', 'project or user')
2105
+ .requiredOption('-p, --platform <platform>', 'codex')
2106
+ .option('-a, --all', 'reconcile every desired plugin in the selected scope', false)
2107
+ .option('-y, --yes', 'authorize shared native replacement or forced repair', false)
2108
+ .option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
2109
+ .option('-j, --json', 'print sync receipt as JSON', false)
2110
+ .option('-v, --verbose', 'show command diagnostics', false)
2111
+ .option('-D, --debug', 'write debug diagnostics to a log file', false)
2112
+ .option('--log-file <path>', 'write debug diagnostics to the specified file')
2113
+ .action(async (plugins, rawOptions) => {
2114
+ const context = createActionContext('sync', rawOptions);
2115
+ const normalized = normalizeWriteRequest(() => normalizeInstallCommandOptions({
2116
+ cwd: context.cwd,
2117
+ scope: rawOptions.scope,
2118
+ platform: rawOptions.platform,
2119
+ allowManagedCodexInstall: rawOptions.allowManagedCodexInstall,
2120
+ }));
2121
+ if (normalized.platform !== 'codex') {
2122
+ throw new Error('syncPlatformUnsupported: sync requires --platform codex.');
2123
+ }
2124
+ const syncPlatform = normalized.platform;
2125
+ const result = await runActionWithContext(context, () => syncCommand(plugins ?? [], {
2126
+ cwd: context.cwd,
2127
+ env: context.env,
2128
+ platform: syncPlatform,
2129
+ scope: normalized.scope,
2130
+ all: rawOptions.all,
2131
+ yes: rawOptions.yes,
2132
+ json: rawOptions.json,
2133
+ interactive: context.interactive && context.isTty && !context.isCi,
2134
+ prompt: context.prompt,
2135
+ allowManagedCodexInstall: rawOptions.allowManagedCodexInstall,
2136
+ }, context));
2137
+ if (rawOptions.json) {
2138
+ writeJsonReceipt(io.stdout, buildRebuildReceiptJson('sync', result));
2139
+ }
2140
+ else {
2141
+ for (const line of renderRebuildReceipt('sync', result))
2142
+ writeLine(io.stdout, line);
2143
+ }
2144
+ writeWarnings(io.stderr, result.warnings, { actionableOnly: true });
2145
+ commandExitState.exitCode = resolveCommandReceiptExitCode(result);
2146
+ });
1550
2147
  program
1551
2148
  .command('install')
1552
2149
  .argument('[plugins...]')
1553
2150
  .option('-s, --scope <scope>', 'project or user')
1554
2151
  .option('-p, --platform <platform>', 'codex | claude | both')
2152
+ .option('--dependency-scope <pluginId[#platform]=scope>', 'place one dependency at project or user scope; repeat for more dependencies', (value, previous) => [...previous, value], [])
1555
2153
  .option('--script-timeout <ms>', 'override plugin lifecycle script timeout in milliseconds')
2154
+ .option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
2155
+ .option('-y, --yes', 'authorize shared Codex native replacement', false)
1556
2156
  .option('-j, --json', 'print receipt as JSON', false)
1557
2157
  .option('-v, --verbose', 'show command diagnostics', false)
1558
2158
  .option('-D, --debug', 'write debug diagnostics to a log file', false)
@@ -1580,6 +2180,7 @@ export function buildProgram(options = {}) {
1580
2180
  .option('-s, --scope <scope>', 'project or user')
1581
2181
  .option('-p, --platform <platform>', 'codex | claude | both')
1582
2182
  .option('--script-timeout <ms>', 'override plugin lifecycle script timeout in milliseconds')
2183
+ .option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
1583
2184
  .option('-j, --json', 'print receipt as JSON', false)
1584
2185
  .option('-v, --verbose', 'show command diagnostics', false)
1585
2186
  .option('-D, --debug', 'write debug diagnostics to a log file', false)
@@ -1608,6 +2209,8 @@ export function buildProgram(options = {}) {
1608
2209
  .option('-s, --scope <scope>', 'project or user')
1609
2210
  .option('-p, --platform <platform>', 'codex | claude | both')
1610
2211
  .option('--script-timeout <ms>', 'override plugin lifecycle script timeout in milliseconds')
2212
+ .option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
2213
+ .option('-y, --yes', 'authorize shared Codex native replacement', false)
1611
2214
  .option('-j, --json', 'print receipt as JSON', false)
1612
2215
  .option('-v, --verbose', 'show command diagnostics', false)
1613
2216
  .option('-D, --debug', 'write debug diagnostics to a log file', false)
@@ -1636,6 +2239,7 @@ export function buildProgram(options = {}) {
1636
2239
  .option('-p, --platform <platform>', 'codex | claude | both')
1637
2240
  .option('-j, --json', 'print cleanup result as JSON', false)
1638
2241
  .option('--force', 'remove exclusively owned plugin output without dependency protection', false)
2242
+ .option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
1639
2243
  .option('-v, --verbose', 'show command diagnostics', false)
1640
2244
  .option('-D, --debug', 'write debug diagnostics to a log file', false)
1641
2245
  .option('--log-file <path>', 'write debug diagnostics to the specified file')
@@ -1662,6 +2266,8 @@ export function buildProgram(options = {}) {
1662
2266
  .option('-s, --scope <scope>', 'project or user')
1663
2267
  .option('-p, --platform <platform>', 'codex | claude | both')
1664
2268
  .option('--script-timeout <ms>', 'override plugin lifecycle script timeout in milliseconds')
2269
+ .option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
2270
+ .option('-y, --yes', 'authorize shared Codex native replacement or forced reinstall', false)
1665
2271
  .option('-j, --json', 'print receipt as JSON', false)
1666
2272
  .option('-v, --verbose', 'show command diagnostics', false)
1667
2273
  .option('-D, --debug', 'write debug diagnostics to a log file', false)
@@ -1852,7 +2458,7 @@ export function buildProgram(options = {}) {
1852
2458
  outcome = await runActionWithContext(context, async () => {
1853
2459
  const scope = resolveConfigWriteScope(rawOptions.scope);
1854
2460
  const projectLayer = resolveConfigProjectLayer(rawOptions);
1855
- const execute = async (selectedPlugin, selectedKey, inputValue) => withResolvedConfigMutationPlugin(context, selectedPlugin, async ({ pluginId, source, plugin }, awHomeMutationToken) => {
2461
+ const execute = async (selectedPlugin, selectedKey, inputValue) => withResolvedConfigMutationPlugin(context, selectedPlugin, async ({ pluginId, source, plugin }, awHomeMutationToken, catalogOperationContext) => {
1856
2462
  if (!plugin.manifest.config?.schema) {
1857
2463
  throw new Error(`configSchemaUnavailable: Plugin "${selectedPlugin}" does not declare an AW config schema.`);
1858
2464
  }
@@ -1867,7 +2473,12 @@ export function buildProgram(options = {}) {
1867
2473
  cwd: context.cwd,
1868
2474
  env: context.env,
1869
2475
  nativeCliRunner: context.nativeCliRunner,
1870
- rebuildRuntime: { ...context, awHomeMutationToken },
2476
+ rebuildRuntime: {
2477
+ ...context,
2478
+ awHomeMutationToken,
2479
+ catalogOperationContext,
2480
+ expectedGenerationSetDigest: catalogOperationContext.generationSetDigest,
2481
+ },
1871
2482
  awHomeMutationToken,
1872
2483
  request: {
1873
2484
  updates: { [selectedKey]: inputValue },
@@ -1875,7 +2486,7 @@ export function buildProgram(options = {}) {
1875
2486
  });
1876
2487
  return {
1877
2488
  ok: writeReceipt.overallState === 'succeeded',
1878
- receiptSchemaVersion: 4,
2489
+ receiptSchemaVersion: 5,
1879
2490
  command: 'config:set',
1880
2491
  ...writeReceipt,
1881
2492
  plugin: plugin.manifest.name,
@@ -1993,7 +2604,7 @@ export function buildProgram(options = {}) {
1993
2604
  outcome = await runActionWithContext(context, async () => {
1994
2605
  const scope = resolveConfigWriteScope(rawOptions.scope);
1995
2606
  const projectLayer = resolveConfigProjectLayer(rawOptions);
1996
- const execute = async (selectedPlugin, selectedKey) => withResolvedConfigMutationPlugin(context, selectedPlugin, async ({ pluginId, source, plugin }, awHomeMutationToken) => {
2607
+ const execute = async (selectedPlugin, selectedKey) => withResolvedConfigMutationPlugin(context, selectedPlugin, async ({ pluginId, source, plugin }, awHomeMutationToken, catalogOperationContext) => {
1997
2608
  if (plugin.manifest.config?.schema && !plugin.manifest.config.schema[selectedKey]) {
1998
2609
  throw new Error(`Unknown config key "${selectedKey}".`);
1999
2610
  }
@@ -2017,7 +2628,12 @@ export function buildProgram(options = {}) {
2017
2628
  cwd: context.cwd,
2018
2629
  env: context.env,
2019
2630
  nativeCliRunner: context.nativeCliRunner,
2020
- rebuildRuntime: { ...context, awHomeMutationToken },
2631
+ rebuildRuntime: {
2632
+ ...context,
2633
+ awHomeMutationToken,
2634
+ catalogOperationContext,
2635
+ expectedGenerationSetDigest: catalogOperationContext.generationSetDigest,
2636
+ },
2021
2637
  awHomeMutationToken,
2022
2638
  request: {
2023
2639
  removeKeys: [selectedKey],
@@ -2025,7 +2641,7 @@ export function buildProgram(options = {}) {
2025
2641
  });
2026
2642
  return {
2027
2643
  ok: writeReceipt.overallState === 'succeeded',
2028
- receiptSchemaVersion: 4,
2644
+ receiptSchemaVersion: 5,
2029
2645
  command: 'config:unset',
2030
2646
  ...writeReceipt,
2031
2647
  plugin: plugin.manifest.name,
@@ -2122,7 +2738,7 @@ export function buildProgram(options = {}) {
2122
2738
  if (!confirmed) {
2123
2739
  throw new Error(`Reset requires confirmation. Re-run \`aw config reset ${selectedPlugin} -s ${selectedScope}${projectLayer === 'local' ? ' --local' : ''} --yes\` to delete this store.`);
2124
2740
  }
2125
- return withResolvedConfigMutationPlugin(context, selectedPlugin, async ({ pluginId, source, plugin }, awHomeMutationToken) => {
2741
+ return withResolvedConfigMutationPlugin(context, selectedPlugin, async ({ pluginId, source, plugin }, awHomeMutationToken, catalogOperationContext) => {
2126
2742
  const affectedFields = await describeResetAffectedFields({
2127
2743
  pluginName: plugin.manifest.name,
2128
2744
  plugin,
@@ -2138,13 +2754,18 @@ export function buildProgram(options = {}) {
2138
2754
  cwd: context.cwd,
2139
2755
  env: context.env,
2140
2756
  nativeCliRunner: context.nativeCliRunner,
2141
- rebuildRuntime: { ...context, awHomeMutationToken },
2757
+ rebuildRuntime: {
2758
+ ...context,
2759
+ awHomeMutationToken,
2760
+ catalogOperationContext,
2761
+ expectedGenerationSetDigest: catalogOperationContext.generationSetDigest,
2762
+ },
2142
2763
  awHomeMutationToken,
2143
2764
  plugin,
2144
2765
  });
2145
2766
  return {
2146
2767
  ok: resetReceipt.overallState === 'succeeded',
2147
- receiptSchemaVersion: 4,
2768
+ receiptSchemaVersion: 5,
2148
2769
  command: 'config:reset',
2149
2770
  ...resetReceipt,
2150
2771
  plugin: plugin.manifest.name,
@@ -2252,7 +2873,7 @@ export function buildProgram(options = {}) {
2252
2873
  .option('-j, --json', 'print status as JSON', false)
2253
2874
  .action(async (plugins, rawOptions) => {
2254
2875
  const context = createActionContext('status', rawOptions);
2255
- const result = await runActionWithContext(context, () => statusCommandV4({
2876
+ const result = await runActionWithContext(context, () => statusCommandV6({
2256
2877
  plugins: plugins ?? [],
2257
2878
  cwd,
2258
2879
  env: context.env,
@@ -2295,10 +2916,17 @@ export async function runCli(argv, options = {}) {
2295
2916
  ...options.io,
2296
2917
  };
2297
2918
  const jsonAuthoringCommand = argv.includes('--json')
2298
- && ((argv[0] === 'catalog' && ['init', 'version', 'build', 'validate', 'status', 'publish'].includes(argv[1] ?? ''))
2299
- || (argv[0] === 'plugin' && ['build', 'test'].includes(argv[1] ?? '')))
2919
+ && ((argv[0] === 'catalog' && ['init', 'context', 'version', 'build', 'validate', 'status', 'publish'].includes(argv[1] ?? ''))
2920
+ || (argv[0] === 'plugin' && ['build', 'test', 'validate', 'status', 'remove'].includes(argv[1] ?? '')))
2300
2921
  ? `${argv[0]}:${argv[1]}`
2301
2922
  : null;
2923
+ const jsonCatalogDevCommand = argv.includes('--json')
2924
+ && argv[0] === 'catalog'
2925
+ && argv[1] === 'dev'
2926
+ && ['activate', 'status', 'deactivate'].includes(argv[2] ?? '')
2927
+ ? argv[2]
2928
+ : null;
2929
+ const jsonWriteRequest = jsonWriteCommandRequest(argv);
2302
2930
  try {
2303
2931
  const authoringScriptByCommand = {
2304
2932
  init: 'init-plugin.mjs',
@@ -2306,7 +2934,6 @@ export async function runCli(argv, options = {}) {
2306
2934
  remove: 'remove-plugin.mjs',
2307
2935
  validate: 'validate-plugin.mjs',
2308
2936
  status: 'plugin-status.mjs',
2309
- 'check-versions': 'check-plugin-versions.mjs',
2310
2937
  };
2311
2938
  const authoringScript = argv[0] === 'plugin'
2312
2939
  ? authoringScriptByCommand[argv[1] ?? '']
@@ -2315,16 +2942,52 @@ export async function runCli(argv, options = {}) {
2315
2942
  : undefined;
2316
2943
  if (authoringScript && !argv.includes('--help') && !argv.includes('-h')) {
2317
2944
  const authoringArgs = argv.slice(2);
2945
+ let authoringEnv = options.env ?? process.env;
2318
2946
  if (argv[0] === 'plugin'
2319
- && argv[1] === 'validate'
2320
- && !authoringArgs.some((token) => token === '--workspace-root' || token.startsWith('--workspace-root='))) {
2321
- authoringArgs.push('--workspace-root', options.cwd ?? process.cwd());
2947
+ && !authoringArgs.some((token) => token === '--plugin-root' || token.startsWith('--plugin-root='))) {
2948
+ let explicitRoot;
2949
+ for (let index = 0; index < authoringArgs.length; index += 1) {
2950
+ const token = authoringArgs[index];
2951
+ if (token.startsWith('--workspace-root='))
2952
+ explicitRoot = token.slice('--workspace-root='.length);
2953
+ if (token === '--workspace-root')
2954
+ explicitRoot = authoringArgs[index + 1];
2955
+ }
2956
+ const originalCwd = options.cwd ?? process.cwd();
2957
+ let discoveryCwd = originalCwd;
2958
+ if (argv[1] === 'validate') {
2959
+ const valueOptions = new Set(['--workspace-root', '--claude-skill-profile', '--version-base']);
2960
+ for (let index = 0; index < authoringArgs.length; index += 1) {
2961
+ const token = authoringArgs[index];
2962
+ if (valueOptions.has(token)) {
2963
+ index += 1;
2964
+ continue;
2965
+ }
2966
+ if (!token.startsWith('-')) {
2967
+ discoveryCwd = path.resolve(originalCwd, token);
2968
+ authoringArgs[index] = discoveryCwd;
2969
+ break;
2970
+ }
2971
+ }
2972
+ }
2973
+ const workspace = await resolveCatalogWorkspaceRoot({
2974
+ cwd: discoveryCwd,
2975
+ ...(explicitRoot === undefined ? {} : { explicitRoot: path.resolve(options.cwd ?? process.cwd(), explicitRoot) }),
2976
+ mode: 'existing',
2977
+ });
2978
+ authoringEnv = {
2979
+ ...authoringEnv,
2980
+ AW_AUTHORING_WORKSPACE_ROOT: workspace.workspaceRoot,
2981
+ AW_AUTHORING_WORKSPACE_ROOT_RESOLVED_FROM: workspace.workspaceRootResolvedFrom,
2982
+ };
2983
+ if (explicitRoot === undefined)
2984
+ authoringArgs.push('--workspace-root', workspace.workspaceRoot);
2322
2985
  }
2323
2986
  return runAuthoringScript({
2324
2987
  scriptName: authoringScript,
2325
2988
  args: authoringArgs,
2326
2989
  cwd: options.cwd ?? process.cwd(),
2327
- env: options.env ?? process.env,
2990
+ env: authoringEnv,
2328
2991
  io,
2329
2992
  });
2330
2993
  }
@@ -2333,7 +2996,7 @@ export async function runCli(argv, options = {}) {
2333
2996
  const message = 'option --subdir cannot be used with option --no-subdir';
2334
2997
  if (argv.includes('--json') && argv[0] === 'catalog' && argv[1] === 'source' && argv[2] === 'update') {
2335
2998
  writeJsonReceipt(io.stdout, {
2336
- receiptSchemaVersion: 4,
2999
+ receiptSchemaVersion: 5,
2337
3000
  command: 'catalog:source:update',
2338
3001
  ok: false,
2339
3002
  changed: false,
@@ -2367,7 +3030,9 @@ export async function runCli(argv, options = {}) {
2367
3030
  }
2368
3031
  const program = buildProgram({
2369
3032
  ...options,
2370
- io,
3033
+ io: jsonCatalogDevCommand || jsonWriteRequest
3034
+ ? { ...io, stderr: () => undefined }
3035
+ : io,
2371
3036
  diagnostics: {
2372
3037
  ...options.diagnostics,
2373
3038
  metadata: {
@@ -2380,6 +3045,78 @@ export async function runCli(argv, options = {}) {
2380
3045
  return program.__awCommandExitState?.exitCode ?? 0;
2381
3046
  }
2382
3047
  catch (error) {
3048
+ if (jsonCatalogDevCommand) {
3049
+ const workspaceRootIndex = argv.findIndex((token) => token === '--workspace-root');
3050
+ const workspaceRootOption = argv.find((token) => token.startsWith('--workspace-root='));
3051
+ const workspaceRoot = workspaceRootOption?.slice('--workspace-root='.length)
3052
+ ?? (workspaceRootIndex >= 0 ? argv[workspaceRootIndex + 1] : undefined);
3053
+ const sourceIdIndex = argv.findIndex((token) => token === '--source-id');
3054
+ const sourceIdOption = argv.find((token) => token.startsWith('--source-id='));
3055
+ const sourceId = sourceIdOption?.slice('--source-id='.length)
3056
+ ?? (sourceIdIndex >= 0 ? argv[sourceIdIndex + 1] : undefined);
3057
+ const failure = error instanceof CommanderError
3058
+ ? { code: 'invalidArguments', message: error.message }
3059
+ : catalogDevSourceError(error);
3060
+ writeJsonReceipt(io.stdout, createCatalogDevFailureReceipt({
3061
+ command: jsonCatalogDevCommand,
3062
+ cwd: options.cwd ?? process.cwd(),
3063
+ workspaceRoot,
3064
+ sourceId,
3065
+ ...failure,
3066
+ }));
3067
+ return 1;
3068
+ }
3069
+ if (jsonWriteRequest) {
3070
+ writeCommandFailureReceipt(io.stdout, jsonWriteRequest, error);
3071
+ return 1;
3072
+ }
3073
+ if (jsonAuthoringCommand && !(error instanceof CommanderError)) {
3074
+ const message = error instanceof Error ? error.message : String(error);
3075
+ if (jsonAuthoringCommand === 'plugin:validate') {
3076
+ writeJsonReceipt(io.stdout, {
3077
+ ok: false,
3078
+ profile: 'unknown',
3079
+ warnings: [],
3080
+ errors: [message],
3081
+ });
3082
+ }
3083
+ else if (jsonAuthoringCommand === 'plugin:status') {
3084
+ writeJsonReceipt(io.stdout, {
3085
+ schemaVersion: 3,
3086
+ policy: 'development',
3087
+ ok: false,
3088
+ base: null,
3089
+ requestedBase: null,
3090
+ baseCommit: null,
3091
+ checkedPlugins: 0,
3092
+ checks: [],
3093
+ workspaceRoot: null,
3094
+ workspaceRootResolvedFrom: null,
3095
+ errors: [{ code: 'workspaceResolutionFailed', message }],
3096
+ });
3097
+ }
3098
+ else if (jsonAuthoringCommand === 'plugin:remove') {
3099
+ writeJsonReceipt(io.stdout, {
3100
+ schemaVersion: 1,
3101
+ command: 'plugin:remove',
3102
+ ok: false,
3103
+ workspaceRoot: null,
3104
+ workspaceRootResolvedFrom: null,
3105
+ baseCommit: null,
3106
+ plugin: null,
3107
+ removed: false,
3108
+ errors: [{ code: 'workspaceResolutionFailed', message }],
3109
+ });
3110
+ }
3111
+ else {
3112
+ writeJsonReceipt(io.stdout, {
3113
+ command: jsonAuthoringCommand,
3114
+ ok: false,
3115
+ errors: [{ code: 'workspaceResolutionFailed', message }],
3116
+ });
3117
+ }
3118
+ return 1;
3119
+ }
2383
3120
  if (jsonAuthoringCommand && error instanceof CommanderError) {
2384
3121
  writeJsonReceipt(io.stdout, {
2385
3122
  command: jsonAuthoringCommand,