@lesliechan721/aw 0.1.0-beta.10

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 (508) hide show
  1. package/dist/authoring/assets/aw-config.d.mts +51 -0
  2. package/dist/authoring/assets/aw-config.mjs +1025 -0
  3. package/dist/authoring/assets/aw-config.mjs.map +1 -0
  4. package/dist/authoring/scripts/add-skill.d.mts +2 -0
  5. package/dist/authoring/scripts/add-skill.mjs +355 -0
  6. package/dist/authoring/scripts/add-skill.mjs.map +1 -0
  7. package/dist/authoring/scripts/init-plugin.d.mts +2 -0
  8. package/dist/authoring/scripts/init-plugin.mjs +487 -0
  9. package/dist/authoring/scripts/init-plugin.mjs.map +1 -0
  10. package/dist/authoring/scripts/lib/javascript-import-scanner.d.mts +4 -0
  11. package/dist/authoring/scripts/lib/javascript-import-scanner.mjs +261 -0
  12. package/dist/authoring/scripts/lib/javascript-import-scanner.mjs.map +1 -0
  13. package/dist/authoring/scripts/lib/plugin-root.d.mts +26 -0
  14. package/dist/authoring/scripts/lib/plugin-root.mjs +125 -0
  15. package/dist/authoring/scripts/lib/plugin-root.mjs.map +1 -0
  16. package/dist/authoring/scripts/lib/plugin-version-check.d.mts +69 -0
  17. package/dist/authoring/scripts/lib/plugin-version-check.mjs +563 -0
  18. package/dist/authoring/scripts/lib/plugin-version-check.mjs.map +1 -0
  19. package/dist/authoring/scripts/lib/semver.d.mts +9 -0
  20. package/dist/authoring/scripts/lib/semver.mjs +63 -0
  21. package/dist/authoring/scripts/lib/semver.mjs.map +1 -0
  22. package/dist/authoring/scripts/lib/skill-scaffold.d.mts +111 -0
  23. package/dist/authoring/scripts/lib/skill-scaffold.mjs +353 -0
  24. package/dist/authoring/scripts/lib/skill-scaffold.mjs.map +1 -0
  25. package/dist/authoring/scripts/plugin-status.d.mts +2 -0
  26. package/dist/authoring/scripts/plugin-status.mjs +93 -0
  27. package/dist/authoring/scripts/plugin-status.mjs.map +1 -0
  28. package/dist/authoring/scripts/remove-plugin.d.mts +2 -0
  29. package/dist/authoring/scripts/remove-plugin.mjs +367 -0
  30. package/dist/authoring/scripts/remove-plugin.mjs.map +1 -0
  31. package/dist/authoring/scripts/validate-plugin.d.mts +2 -0
  32. package/dist/authoring/scripts/validate-plugin.mjs +3465 -0
  33. package/dist/authoring/scripts/validate-plugin.mjs.map +1 -0
  34. package/dist/authoring/scripts/validate-skill.d.mts +2 -0
  35. package/dist/authoring/scripts/validate-skill.mjs +126 -0
  36. package/dist/authoring/scripts/validate-skill.mjs.map +1 -0
  37. package/dist/authoring/templates/aw-config-runtime.d.mts +2 -0
  38. package/dist/authoring/templates/aw-config-runtime.mjs +407 -0
  39. package/dist/authoring/templates/aw-config-runtime.mjs.map +1 -0
  40. package/dist/index.d.ts +2 -0
  41. package/dist/index.js +8 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/scripts/aw-skill-eval-materializer.d.ts +24 -0
  44. package/dist/scripts/aw-skill-eval-materializer.js +309 -0
  45. package/dist/scripts/aw-skill-eval-materializer.js.map +1 -0
  46. package/dist/scripts/bundle-plugins.d.ts +17 -0
  47. package/dist/scripts/bundle-plugins.js +126 -0
  48. package/dist/scripts/bundle-plugins.js.map +1 -0
  49. package/dist/scripts/plugin-staging.d.ts +26 -0
  50. package/dist/scripts/plugin-staging.js +76 -0
  51. package/dist/scripts/plugin-staging.js.map +1 -0
  52. package/dist/scripts/test-plugin-scripts.d.ts +7 -0
  53. package/dist/scripts/test-plugin-scripts.js +610 -0
  54. package/dist/scripts/test-plugin-scripts.js.map +1 -0
  55. package/dist/src/adapters/helpers.d.ts +44 -0
  56. package/dist/src/adapters/helpers.js +95 -0
  57. package/dist/src/adapters/helpers.js.map +1 -0
  58. package/dist/src/authoring/workspace-commands.d.ts +70 -0
  59. package/dist/src/authoring/workspace-commands.js +158 -0
  60. package/dist/src/authoring/workspace-commands.js.map +1 -0
  61. package/dist/src/commands/aw-capabilities.d.ts +78 -0
  62. package/dist/src/commands/aw-capabilities.js +254 -0
  63. package/dist/src/commands/aw-capabilities.js.map +1 -0
  64. package/dist/src/commands/catalog-dev-source.d.ts +120 -0
  65. package/dist/src/commands/catalog-dev-source.js +434 -0
  66. package/dist/src/commands/catalog-dev-source.js.map +1 -0
  67. package/dist/src/commands/catalog-generation.d.ts +16 -0
  68. package/dist/src/commands/catalog-generation.js +9 -0
  69. package/dist/src/commands/catalog-generation.js.map +1 -0
  70. package/dist/src/commands/catalog-publication-inspection.d.ts +138 -0
  71. package/dist/src/commands/catalog-publication-inspection.js +711 -0
  72. package/dist/src/commands/catalog-publication-inspection.js.map +1 -0
  73. package/dist/src/commands/catalog-publication-journal.d.ts +56 -0
  74. package/dist/src/commands/catalog-publication-journal.js +215 -0
  75. package/dist/src/commands/catalog-publication-journal.js.map +1 -0
  76. package/dist/src/commands/catalog-publication-target.d.ts +18 -0
  77. package/dist/src/commands/catalog-publication-target.js +95 -0
  78. package/dist/src/commands/catalog-publication-target.js.map +1 -0
  79. package/dist/src/commands/catalog-publish.d.ts +103 -0
  80. package/dist/src/commands/catalog-publish.js +804 -0
  81. package/dist/src/commands/catalog-publish.js.map +1 -0
  82. package/dist/src/commands/catalog-source.d.ts +134 -0
  83. package/dist/src/commands/catalog-source.js +377 -0
  84. package/dist/src/commands/catalog-source.js.map +1 -0
  85. package/dist/src/commands/catalog-status.d.ts +56 -0
  86. package/dist/src/commands/catalog-status.js +217 -0
  87. package/dist/src/commands/catalog-status.js.map +1 -0
  88. package/dist/src/commands/catalog-store.d.ts +80 -0
  89. package/dist/src/commands/catalog-store.js +348 -0
  90. package/dist/src/commands/catalog-store.js.map +1 -0
  91. package/dist/src/commands/catalog-workspace-resolution.d.ts +13 -0
  92. package/dist/src/commands/catalog-workspace-resolution.js +42 -0
  93. package/dist/src/commands/catalog-workspace-resolution.js.map +1 -0
  94. package/dist/src/commands/console.d.ts +3 -0
  95. package/dist/src/commands/console.js +44 -0
  96. package/dist/src/commands/console.js.map +1 -0
  97. package/dist/src/commands/dependency-operation-plan.d.ts +58 -0
  98. package/dist/src/commands/dependency-operation-plan.js +261 -0
  99. package/dist/src/commands/dependency-operation-plan.js.map +1 -0
  100. package/dist/src/commands/init.d.ts +25 -0
  101. package/dist/src/commands/init.js +42 -0
  102. package/dist/src/commands/init.js.map +1 -0
  103. package/dist/src/commands/offline-cleanup-evidence.d.ts +59 -0
  104. package/dist/src/commands/offline-cleanup-evidence.js +163 -0
  105. package/dist/src/commands/offline-cleanup-evidence.js.map +1 -0
  106. package/dist/src/commands/operation-plan.d.ts +126 -0
  107. package/dist/src/commands/operation-plan.js +47 -0
  108. package/dist/src/commands/operation-plan.js.map +1 -0
  109. package/dist/src/commands/operation-planner.d.ts +46 -0
  110. package/dist/src/commands/operation-planner.js +139 -0
  111. package/dist/src/commands/operation-planner.js.map +1 -0
  112. package/dist/src/commands/options.d.ts +70 -0
  113. package/dist/src/commands/options.js +194 -0
  114. package/dist/src/commands/options.js.map +1 -0
  115. package/dist/src/commands/plugin-capabilities.d.ts +22 -0
  116. package/dist/src/commands/plugin-capabilities.js +159 -0
  117. package/dist/src/commands/plugin-capabilities.js.map +1 -0
  118. package/dist/src/commands/rebuild-command.d.ts +88 -0
  119. package/dist/src/commands/rebuild-command.js +3626 -0
  120. package/dist/src/commands/rebuild-command.js.map +1 -0
  121. package/dist/src/commands/rebuild-integration.d.ts +190 -0
  122. package/dist/src/commands/rebuild-integration.js +4439 -0
  123. package/dist/src/commands/rebuild-integration.js.map +1 -0
  124. package/dist/src/commands/rebuild-operations.d.ts +100 -0
  125. package/dist/src/commands/rebuild-operations.js +625 -0
  126. package/dist/src/commands/rebuild-operations.js.map +1 -0
  127. package/dist/src/commands/reconcile-operation-plan.d.ts +26 -0
  128. package/dist/src/commands/reconcile-operation-plan.js +28 -0
  129. package/dist/src/commands/reconcile-operation-plan.js.map +1 -0
  130. package/dist/src/commands/review-publication.d.ts +99 -0
  131. package/dist/src/commands/review-publication.js +904 -0
  132. package/dist/src/commands/review-publication.js.map +1 -0
  133. package/dist/src/commands/runtime.d.ts +172 -0
  134. package/dist/src/commands/runtime.js +720 -0
  135. package/dist/src/commands/runtime.js.map +1 -0
  136. package/dist/src/commands/skill-eval.d.ts +33 -0
  137. package/dist/src/commands/skill-eval.js +363 -0
  138. package/dist/src/commands/skill-eval.js.map +1 -0
  139. package/dist/src/commands/status-v6.d.ts +206 -0
  140. package/dist/src/commands/status-v6.js +2175 -0
  141. package/dist/src/commands/status-v6.js.map +1 -0
  142. package/dist/src/commands/sync-command.d.ts +23 -0
  143. package/dist/src/commands/sync-command.js +242 -0
  144. package/dist/src/commands/sync-command.js.map +1 -0
  145. package/dist/src/commands/wizard.d.ts +56 -0
  146. package/dist/src/commands/wizard.js +58 -0
  147. package/dist/src/commands/wizard.js.map +1 -0
  148. package/dist/src/commands/write-commands.d.ts +7 -0
  149. package/dist/src/commands/write-commands.js +190 -0
  150. package/dist/src/commands/write-commands.js.map +1 -0
  151. package/dist/src/constants.d.ts +31 -0
  152. package/dist/src/constants.js +32 -0
  153. package/dist/src/constants.js.map +1 -0
  154. package/dist/src/eval/manifest-v1.d.ts +67 -0
  155. package/dist/src/eval/manifest-v1.js +347 -0
  156. package/dist/src/eval/manifest-v1.js.map +1 -0
  157. package/dist/src/generators/agents.d.ts +3 -0
  158. package/dist/src/generators/agents.js +46 -0
  159. package/dist/src/generators/agents.js.map +1 -0
  160. package/dist/src/generators/hooks.d.ts +15 -0
  161. package/dist/src/generators/hooks.js +76 -0
  162. package/dist/src/generators/hooks.js.map +1 -0
  163. package/dist/src/generators/instructions.d.ts +13 -0
  164. package/dist/src/generators/instructions.js +66 -0
  165. package/dist/src/generators/instructions.js.map +1 -0
  166. package/dist/src/generators/local-plugin.d.ts +56 -0
  167. package/dist/src/generators/local-plugin.js +1373 -0
  168. package/dist/src/generators/local-plugin.js.map +1 -0
  169. package/dist/src/generators/permissions.d.ts +10 -0
  170. package/dist/src/generators/permissions.js +37 -0
  171. package/dist/src/generators/permissions.js.map +1 -0
  172. package/dist/src/generators/shared.d.ts +2 -0
  173. package/dist/src/generators/shared.js +15 -0
  174. package/dist/src/generators/shared.js.map +1 -0
  175. package/dist/src/index.d.ts +41 -0
  176. package/dist/src/index.js +3327 -0
  177. package/dist/src/index.js.map +1 -0
  178. package/dist/src/output/command-receipt.d.ts +87 -0
  179. package/dist/src/output/command-receipt.js +302 -0
  180. package/dist/src/output/command-receipt.js.map +1 -0
  181. package/dist/src/output/debug-log.d.ts +4 -0
  182. package/dist/src/output/debug-log.js +97 -0
  183. package/dist/src/output/debug-log.js.map +1 -0
  184. package/dist/src/output/equivalent-command.d.ts +9 -0
  185. package/dist/src/output/equivalent-command.js +39 -0
  186. package/dist/src/output/equivalent-command.js.map +1 -0
  187. package/dist/src/output/model.d.ts +76 -0
  188. package/dist/src/output/model.js +2 -0
  189. package/dist/src/output/model.js.map +1 -0
  190. package/dist/src/output/rebuild-progress.d.ts +21 -0
  191. package/dist/src/output/rebuild-progress.js +128 -0
  192. package/dist/src/output/rebuild-progress.js.map +1 -0
  193. package/dist/src/output/redact.d.ts +3 -0
  194. package/dist/src/output/redact.js +39 -0
  195. package/dist/src/output/redact.js.map +1 -0
  196. package/dist/src/output/reporter.d.ts +9 -0
  197. package/dist/src/output/reporter.js +133 -0
  198. package/dist/src/output/reporter.js.map +1 -0
  199. package/dist/src/portable/commands.d.ts +124 -0
  200. package/dist/src/portable/commands.js +557 -0
  201. package/dist/src/portable/commands.js.map +1 -0
  202. package/dist/src/portable/materializer.d.ts +50 -0
  203. package/dist/src/portable/materializer.js +462 -0
  204. package/dist/src/portable/materializer.js.map +1 -0
  205. package/dist/src/portable/skills-cli.d.ts +43 -0
  206. package/dist/src/portable/skills-cli.js +148 -0
  207. package/dist/src/portable/skills-cli.js.map +1 -0
  208. package/dist/src/tui/catalog-freshness.d.ts +1 -0
  209. package/dist/src/tui/catalog-freshness.js +2 -0
  210. package/dist/src/tui/catalog-freshness.js.map +1 -0
  211. package/dist/src/tui/catalog-generation.d.ts +21 -0
  212. package/dist/src/tui/catalog-generation.js +116 -0
  213. package/dist/src/tui/catalog-generation.js.map +1 -0
  214. package/dist/src/tui/catalog-sources/projection.d.ts +4 -0
  215. package/dist/src/tui/catalog-sources/projection.js +17 -0
  216. package/dist/src/tui/catalog-sources/projection.js.map +1 -0
  217. package/dist/src/tui/catalog-sources/review.d.ts +3 -0
  218. package/dist/src/tui/catalog-sources/review.js +13 -0
  219. package/dist/src/tui/catalog-sources/review.js.map +1 -0
  220. package/dist/src/tui/catalog-sources/screens.d.ts +12 -0
  221. package/dist/src/tui/catalog-sources/screens.js +33 -0
  222. package/dist/src/tui/catalog-sources/screens.js.map +1 -0
  223. package/dist/src/tui/catalog-sources/session.d.ts +22 -0
  224. package/dist/src/tui/catalog-sources/session.js +225 -0
  225. package/dist/src/tui/catalog-sources/session.js.map +1 -0
  226. package/dist/src/tui/catalog-sources/types.d.ts +41 -0
  227. package/dist/src/tui/catalog-sources/types.js +2 -0
  228. package/dist/src/tui/catalog-sources/types.js.map +1 -0
  229. package/dist/src/tui/components.d.ts +102 -0
  230. package/dist/src/tui/components.js +184 -0
  231. package/dist/src/tui/components.js.map +1 -0
  232. package/dist/src/tui/console-app-v4.d.ts +20 -0
  233. package/dist/src/tui/console-app-v4.js +5066 -0
  234. package/dist/src/tui/console-app-v4.js.map +1 -0
  235. package/dist/src/tui/controller-runtime.d.ts +23 -0
  236. package/dist/src/tui/controller-runtime.js +2011 -0
  237. package/dist/src/tui/controller-runtime.js.map +1 -0
  238. package/dist/src/tui/controller.d.ts +557 -0
  239. package/dist/src/tui/controller.js +2120 -0
  240. package/dist/src/tui/controller.js.map +1 -0
  241. package/dist/src/tui/diagnostics.d.ts +30 -0
  242. package/dist/src/tui/diagnostics.js +71 -0
  243. package/dist/src/tui/diagnostics.js.map +1 -0
  244. package/dist/src/tui/index.d.ts +17 -0
  245. package/dist/src/tui/index.js +17 -0
  246. package/dist/src/tui/index.js.map +1 -0
  247. package/dist/src/tui/input-display.d.ts +8 -0
  248. package/dist/src/tui/input-display.js +36 -0
  249. package/dist/src/tui/input-display.js.map +1 -0
  250. package/dist/src/tui/keys.d.ts +12 -0
  251. package/dist/src/tui/keys.js +22 -0
  252. package/dist/src/tui/keys.js.map +1 -0
  253. package/dist/src/tui/layout.d.ts +12 -0
  254. package/dist/src/tui/layout.js +19 -0
  255. package/dist/src/tui/layout.js.map +1 -0
  256. package/dist/src/tui/model.d.ts +424 -0
  257. package/dist/src/tui/model.js +1493 -0
  258. package/dist/src/tui/model.js.map +1 -0
  259. package/dist/src/tui/operation-review-planner.d.ts +21 -0
  260. package/dist/src/tui/operation-review-planner.js +622 -0
  261. package/dist/src/tui/operation-review-planner.js.map +1 -0
  262. package/dist/src/tui/prompt.d.ts +8 -0
  263. package/dist/src/tui/prompt.js +231 -0
  264. package/dist/src/tui/prompt.js.map +1 -0
  265. package/dist/src/tui/router.d.ts +206 -0
  266. package/dist/src/tui/router.js +137 -0
  267. package/dist/src/tui/router.js.map +1 -0
  268. package/dist/src/tui/runner.d.ts +11 -0
  269. package/dist/src/tui/runner.js +71 -0
  270. package/dist/src/tui/runner.js.map +1 -0
  271. package/dist/src/tui/source-ref-presets.d.ts +3 -0
  272. package/dist/src/tui/source-ref-presets.js +11 -0
  273. package/dist/src/tui/source-ref-presets.js.map +1 -0
  274. package/dist/src/tui/theme.d.ts +26 -0
  275. package/dist/src/tui/theme.js +28 -0
  276. package/dist/src/tui/theme.js.map +1 -0
  277. package/dist/src/tui/viewport.d.ts +20 -0
  278. package/dist/src/tui/viewport.js +29 -0
  279. package/dist/src/tui/viewport.js.map +1 -0
  280. package/dist/src/tui/views.d.ts +57 -0
  281. package/dist/src/tui/views.js +201 -0
  282. package/dist/src/tui/views.js.map +1 -0
  283. package/dist/src/tui/wizard.d.ts +11 -0
  284. package/dist/src/tui/wizard.js +323 -0
  285. package/dist/src/tui/wizard.js.map +1 -0
  286. package/dist/src/types.d.ts +474 -0
  287. package/dist/src/types.js +34 -0
  288. package/dist/src/types.js.map +1 -0
  289. package/dist/src/utils/agent-version.d.ts +19 -0
  290. package/dist/src/utils/agent-version.js +205 -0
  291. package/dist/src/utils/agent-version.js.map +1 -0
  292. package/dist/src/utils/artifact-plan.d.ts +27 -0
  293. package/dist/src/utils/artifact-plan.js +453 -0
  294. package/dist/src/utils/artifact-plan.js.map +1 -0
  295. package/dist/src/utils/artifact-renderer.d.ts +129 -0
  296. package/dist/src/utils/artifact-renderer.js +400 -0
  297. package/dist/src/utils/artifact-renderer.js.map +1 -0
  298. package/dist/src/utils/artifact-request.d.ts +16 -0
  299. package/dist/src/utils/artifact-request.js +42 -0
  300. package/dist/src/utils/artifact-request.js.map +1 -0
  301. package/dist/src/utils/artifact-sources.d.ts +8 -0
  302. package/dist/src/utils/artifact-sources.js +10 -0
  303. package/dist/src/utils/artifact-sources.js.map +1 -0
  304. package/dist/src/utils/aw-home-mutation-lock.d.ts +11 -0
  305. package/dist/src/utils/aw-home-mutation-lock.js +83 -0
  306. package/dist/src/utils/aw-home-mutation-lock.js.map +1 -0
  307. package/dist/src/utils/bundle-integrity.d.ts +2 -0
  308. package/dist/src/utils/bundle-integrity.js +63 -0
  309. package/dist/src/utils/bundle-integrity.js.map +1 -0
  310. package/dist/src/utils/bundle-layout.d.ts +4 -0
  311. package/dist/src/utils/bundle-layout.js +531 -0
  312. package/dist/src/utils/bundle-layout.js.map +1 -0
  313. package/dist/src/utils/catalog-digests.d.ts +18 -0
  314. package/dist/src/utils/catalog-digests.js +156 -0
  315. package/dist/src/utils/catalog-digests.js.map +1 -0
  316. package/dist/src/utils/catalog-generation-control-snapshot.d.ts +11 -0
  317. package/dist/src/utils/catalog-generation-control-snapshot.js +45 -0
  318. package/dist/src/utils/catalog-generation-control-snapshot.js.map +1 -0
  319. package/dist/src/utils/catalog-generation-error.d.ts +16 -0
  320. package/dist/src/utils/catalog-generation-error.js +30 -0
  321. package/dist/src/utils/catalog-generation-error.js.map +1 -0
  322. package/dist/src/utils/catalog-generation-resolver.d.ts +32 -0
  323. package/dist/src/utils/catalog-generation-resolver.js +251 -0
  324. package/dist/src/utils/catalog-generation-resolver.js.map +1 -0
  325. package/dist/src/utils/catalog-generation-service.d.ts +161 -0
  326. package/dist/src/utils/catalog-generation-service.js +1237 -0
  327. package/dist/src/utils/catalog-generation-service.js.map +1 -0
  328. package/dist/src/utils/catalog-generation-state.d.ts +22 -0
  329. package/dist/src/utils/catalog-generation-state.js +192 -0
  330. package/dist/src/utils/catalog-generation-state.js.map +1 -0
  331. package/dist/src/utils/catalog-generation-store.d.ts +57 -0
  332. package/dist/src/utils/catalog-generation-store.js +397 -0
  333. package/dist/src/utils/catalog-generation-store.js.map +1 -0
  334. package/dist/src/utils/catalog-manifest-v7.d.ts +5 -0
  335. package/dist/src/utils/catalog-manifest-v7.js +98 -0
  336. package/dist/src/utils/catalog-manifest-v7.js.map +1 -0
  337. package/dist/src/utils/catalog-operation-context.d.ts +20 -0
  338. package/dist/src/utils/catalog-operation-context.js +141 -0
  339. package/dist/src/utils/catalog-operation-context.js.map +1 -0
  340. package/dist/src/utils/catalog-public-error.d.ts +19 -0
  341. package/dist/src/utils/catalog-public-error.js +100 -0
  342. package/dist/src/utils/catalog-public-error.js.map +1 -0
  343. package/dist/src/utils/catalog-runtime-projection.d.ts +33 -0
  344. package/dist/src/utils/catalog-runtime-projection.js +77 -0
  345. package/dist/src/utils/catalog-runtime-projection.js.map +1 -0
  346. package/dist/src/utils/catalog-snapshot.d.ts +10 -0
  347. package/dist/src/utils/catalog-snapshot.js +20 -0
  348. package/dist/src/utils/catalog-snapshot.js.map +1 -0
  349. package/dist/src/utils/catalog-source-identity.d.ts +5 -0
  350. package/dist/src/utils/catalog-source-identity.js +137 -0
  351. package/dist/src/utils/catalog-source-identity.js.map +1 -0
  352. package/dist/src/utils/catalog-source-impact.d.ts +20 -0
  353. package/dist/src/utils/catalog-source-impact.js +222 -0
  354. package/dist/src/utils/catalog-source-impact.js.map +1 -0
  355. package/dist/src/utils/catalog-source-presentation.d.ts +1 -0
  356. package/dist/src/utils/catalog-source-presentation.js +32 -0
  357. package/dist/src/utils/catalog-source-presentation.js.map +1 -0
  358. package/dist/src/utils/catalog-source-references.d.ts +66 -0
  359. package/dist/src/utils/catalog-source-references.js +1180 -0
  360. package/dist/src/utils/catalog-source-references.js.map +1 -0
  361. package/dist/src/utils/catalog-sources.d.ts +53 -0
  362. package/dist/src/utils/catalog-sources.js +456 -0
  363. package/dist/src/utils/catalog-sources.js.map +1 -0
  364. package/dist/src/utils/codex-config.d.ts +126 -0
  365. package/dist/src/utils/codex-config.js +1032 -0
  366. package/dist/src/utils/codex-config.js.map +1 -0
  367. package/dist/src/utils/codex-manager.d.ts +81 -0
  368. package/dist/src/utils/codex-manager.js +810 -0
  369. package/dist/src/utils/codex-manager.js.map +1 -0
  370. package/dist/src/utils/codex-marketplace-path.d.ts +5 -0
  371. package/dist/src/utils/codex-marketplace-path.js +45 -0
  372. package/dist/src/utils/codex-marketplace-path.js.map +1 -0
  373. package/dist/src/utils/codex-native-observation.d.ts +16 -0
  374. package/dist/src/utils/codex-native-observation.js +22 -0
  375. package/dist/src/utils/codex-native-observation.js.map +1 -0
  376. package/dist/src/utils/codex-native-render-receipt.d.ts +40 -0
  377. package/dist/src/utils/codex-native-render-receipt.js +205 -0
  378. package/dist/src/utils/codex-native-render-receipt.js.map +1 -0
  379. package/dist/src/utils/codex-reconciler.d.ts +128 -0
  380. package/dist/src/utils/codex-reconciler.js +294 -0
  381. package/dist/src/utils/codex-reconciler.js.map +1 -0
  382. package/dist/src/utils/codex-roles.d.ts +71 -0
  383. package/dist/src/utils/codex-roles.js +257 -0
  384. package/dist/src/utils/codex-roles.js.map +1 -0
  385. package/dist/src/utils/codex-shared-native.d.ts +63 -0
  386. package/dist/src/utils/codex-shared-native.js +142 -0
  387. package/dist/src/utils/codex-shared-native.js.map +1 -0
  388. package/dist/src/utils/codex-skill-staging.d.ts +11 -0
  389. package/dist/src/utils/codex-skill-staging.js +8 -0
  390. package/dist/src/utils/codex-skill-staging.js.map +1 -0
  391. package/dist/src/utils/codex-surface-analysis.d.ts +45 -0
  392. package/dist/src/utils/codex-surface-analysis.js +245 -0
  393. package/dist/src/utils/codex-surface-analysis.js.map +1 -0
  394. package/dist/src/utils/config-value.d.ts +3 -0
  395. package/dist/src/utils/config-value.js +23 -0
  396. package/dist/src/utils/config-value.js.map +1 -0
  397. package/dist/src/utils/dynamic-skill-tree.d.ts +36 -0
  398. package/dist/src/utils/dynamic-skill-tree.js +466 -0
  399. package/dist/src/utils/dynamic-skill-tree.js.map +1 -0
  400. package/dist/src/utils/file-rules.d.ts +1 -0
  401. package/dist/src/utils/file-rules.js +2 -0
  402. package/dist/src/utils/file-rules.js.map +1 -0
  403. package/dist/src/utils/git-catalog-provider.d.ts +22 -0
  404. package/dist/src/utils/git-catalog-provider.js +497 -0
  405. package/dist/src/utils/git-catalog-provider.js.map +1 -0
  406. package/dist/src/utils/hooks-contract.d.ts +1 -0
  407. package/dist/src/utils/hooks-contract.js +2 -0
  408. package/dist/src/utils/hooks-contract.js.map +1 -0
  409. package/dist/src/utils/json.d.ts +4 -0
  410. package/dist/src/utils/json.js +29 -0
  411. package/dist/src/utils/json.js.map +1 -0
  412. package/dist/src/utils/local-marketplace.d.ts +41 -0
  413. package/dist/src/utils/local-marketplace.js +316 -0
  414. package/dist/src/utils/local-marketplace.js.map +1 -0
  415. package/dist/src/utils/manifest.d.ts +11 -0
  416. package/dist/src/utils/manifest.js +33 -0
  417. package/dist/src/utils/manifest.js.map +1 -0
  418. package/dist/src/utils/marketplace.d.ts +3 -0
  419. package/dist/src/utils/marketplace.js +76 -0
  420. package/dist/src/utils/marketplace.js.map +1 -0
  421. package/dist/src/utils/multi-source-catalog.d.ts +66 -0
  422. package/dist/src/utils/multi-source-catalog.js +345 -0
  423. package/dist/src/utils/multi-source-catalog.js.map +1 -0
  424. package/dist/src/utils/native-cli.d.ts +118 -0
  425. package/dist/src/utils/native-cli.js +518 -0
  426. package/dist/src/utils/native-cli.js.map +1 -0
  427. package/dist/src/utils/orphan-marketplace-cleanup.d.ts +18 -0
  428. package/dist/src/utils/orphan-marketplace-cleanup.js +198 -0
  429. package/dist/src/utils/orphan-marketplace-cleanup.js.map +1 -0
  430. package/dist/src/utils/ownership.d.ts +194 -0
  431. package/dist/src/utils/ownership.js +723 -0
  432. package/dist/src/utils/ownership.js.map +1 -0
  433. package/dist/src/utils/path-catalog-provider.d.ts +7 -0
  434. package/dist/src/utils/path-catalog-provider.js +74 -0
  435. package/dist/src/utils/path-catalog-provider.js.map +1 -0
  436. package/dist/src/utils/paths.d.ts +40 -0
  437. package/dist/src/utils/paths.js +137 -0
  438. package/dist/src/utils/paths.js.map +1 -0
  439. package/dist/src/utils/platform-entries.d.ts +1 -0
  440. package/dist/src/utils/platform-entries.js +2 -0
  441. package/dist/src/utils/platform-entries.js.map +1 -0
  442. package/dist/src/utils/platform-support.d.ts +1 -0
  443. package/dist/src/utils/platform-support.js +2 -0
  444. package/dist/src/utils/platform-support.js.map +1 -0
  445. package/dist/src/utils/plugin-config-write.d.ts +110 -0
  446. package/dist/src/utils/plugin-config-write.js +773 -0
  447. package/dist/src/utils/plugin-config-write.js.map +1 -0
  448. package/dist/src/utils/plugin-config.d.ts +389 -0
  449. package/dist/src/utils/plugin-config.js +1642 -0
  450. package/dist/src/utils/plugin-config.js.map +1 -0
  451. package/dist/src/utils/plugin-dependencies.d.ts +12 -0
  452. package/dist/src/utils/plugin-dependencies.js +162 -0
  453. package/dist/src/utils/plugin-dependencies.js.map +1 -0
  454. package/dist/src/utils/plugin-intent-state.d.ts +34 -0
  455. package/dist/src/utils/plugin-intent-state.js +289 -0
  456. package/dist/src/utils/plugin-intent-state.js.map +1 -0
  457. package/dist/src/utils/plugin-script-contract.d.ts +1 -0
  458. package/dist/src/utils/plugin-script-contract.js +2 -0
  459. package/dist/src/utils/plugin-script-contract.js.map +1 -0
  460. package/dist/src/utils/plugin-scripts.d.ts +101 -0
  461. package/dist/src/utils/plugin-scripts.js +253 -0
  462. package/dist/src/utils/plugin-scripts.js.map +1 -0
  463. package/dist/src/utils/process-lock.d.ts +47 -0
  464. package/dist/src/utils/process-lock.js +532 -0
  465. package/dist/src/utils/process-lock.js.map +1 -0
  466. package/dist/src/utils/process-tree.d.ts +2 -0
  467. package/dist/src/utils/process-tree.js +2 -0
  468. package/dist/src/utils/process-tree.js.map +1 -0
  469. package/dist/src/utils/project-boundary.d.ts +9 -0
  470. package/dist/src/utils/project-boundary.js +67 -0
  471. package/dist/src/utils/project-boundary.js.map +1 -0
  472. package/dist/src/utils/rendered-contract.d.ts +8 -0
  473. package/dist/src/utils/rendered-contract.js +134 -0
  474. package/dist/src/utils/rendered-contract.js.map +1 -0
  475. package/dist/src/utils/runtime-skill-closure.d.ts +13 -0
  476. package/dist/src/utils/runtime-skill-closure.js +863 -0
  477. package/dist/src/utils/runtime-skill-closure.js.map +1 -0
  478. package/dist/src/utils/safe-fs.d.ts +21 -0
  479. package/dist/src/utils/safe-fs.js +111 -0
  480. package/dist/src/utils/safe-fs.js.map +1 -0
  481. package/dist/src/utils/skill-authoring.d.ts +1 -0
  482. package/dist/src/utils/skill-authoring.js +2 -0
  483. package/dist/src/utils/skill-authoring.js.map +1 -0
  484. package/dist/src/utils/skill-validation.d.ts +37 -0
  485. package/dist/src/utils/skill-validation.js +326 -0
  486. package/dist/src/utils/skill-validation.js.map +1 -0
  487. package/dist/src/utils/slash-commands.d.ts +1 -0
  488. package/dist/src/utils/slash-commands.js +2 -0
  489. package/dist/src/utils/slash-commands.js.map +1 -0
  490. package/dist/src/utils/state-paths.d.ts +14 -0
  491. package/dist/src/utils/state-paths.js +139 -0
  492. package/dist/src/utils/state-paths.js.map +1 -0
  493. package/dist/src/utils/target-eligibility.d.ts +13 -0
  494. package/dist/src/utils/target-eligibility.js +35 -0
  495. package/dist/src/utils/target-eligibility.js.map +1 -0
  496. package/dist/src/utils/target-order.d.ts +7 -0
  497. package/dist/src/utils/target-order.js +10 -0
  498. package/dist/src/utils/target-order.js.map +1 -0
  499. package/dist/src/utils/template-engine.d.ts +1 -0
  500. package/dist/src/utils/template-engine.js +2 -0
  501. package/dist/src/utils/template-engine.js.map +1 -0
  502. package/dist/src/utils/test-path-fence.d.ts +12 -0
  503. package/dist/src/utils/test-path-fence.js +31 -0
  504. package/dist/src/utils/test-path-fence.js.map +1 -0
  505. package/dist/vitest.config.d.ts +2 -0
  506. package/dist/vitest.config.js +16 -0
  507. package/dist/vitest.config.js.map +1 -0
  508. package/package.json +64 -0
@@ -0,0 +1,2175 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { analyzeCodexSurface } from '../utils/codex-surface-analysis.js';
4
+ import { catalogSourceErrorCode, sanitizeCatalogSourceError, } from '../utils/catalog-public-error.js';
5
+ import { calculateCatalogSourceIdentity } from '../utils/catalog-source-identity.js';
6
+ import { canonicalMarketplaceRegistrationNames, inventoryCatalogSourceReferences, inventoryLegacyOwnerReferences, } from '../utils/catalog-source-references.js';
7
+ import { readCatalogSourcesConfigSnapshot, resolveCatalogSourceRef } from '../utils/catalog-sources.js';
8
+ import { formatPluginId, parsePluginId, planPluginSelectorSourceIds, withResolvedMultiSourceCatalog, } from '../utils/multi-source-catalog.js';
9
+ import { assertStrictSemVer, checkAwCapabilitySupport, compareStrictSemVer, readPluginManifest, tryParseStrictSemVer, } from '../utils/manifest.js';
10
+ import { resolveCliPackageRoot, resolveCodexPaths } from '../utils/paths.js';
11
+ import { supportsPlatform } from '../utils/platform-support.js';
12
+ import { parsePlatformValue, parseScopeValue } from './options.js';
13
+ import { inspectCodexPluginRegistrationLive, inspectCodexSharedNativeLive, inspectRebuildTarget, } from './rebuild-integration.js';
14
+ import { createNoopReporter } from '../output/reporter.js';
15
+ import { createNoopDebugLogger } from '../output/debug-log.js';
16
+ import { getDefaultNativeCliRunner } from '../utils/native-cli.js';
17
+ import { resolveAwHome } from '../utils/paths.js';
18
+ import { codexProjectConfigAliasesUserHome, createProjectLocationKey, getClaudeHome, getCodexHome, resolveCanonicalRepoProjectKey, } from '../utils/state-paths.js';
19
+ import { resolveEffectivePluginConfig, resolveProjectArtifactRenderConfig, } from '../utils/plugin-config.js';
20
+ import { readCodexConfigFile } from '../utils/codex-config.js';
21
+ import { readPluginIntentState, } from '../utils/plugin-intent-state.js';
22
+ import { IMPLEMENTED_AW_CAPABILITIES } from './aw-capabilities.js';
23
+ import { createDependencyPlacementPlan } from './dependency-operation-plan.js';
24
+ import { getCodexOperationRequirement } from '../utils/agent-version.js';
25
+ import { inspectSystemCodexFilesystem, } from '../utils/codex-manager.js';
26
+ export function projectStatusSharedNativeReasons(sharedNative, existingReasonCodes = [], desiredEnabled = false) {
27
+ if (!sharedNative)
28
+ return [];
29
+ const warning = (code, message) => ({
30
+ code,
31
+ message: `${code}: ${message}`,
32
+ severity: 'warning',
33
+ });
34
+ const blocking = (code, message) => ({
35
+ code,
36
+ message: `${code}: ${message}`,
37
+ severity: 'blocking',
38
+ });
39
+ return [
40
+ ...(sharedNative.state === 'blocked' && sharedNative.reason === 'foreign'
41
+ && !existingReasonCodes.includes('codexSharedNativeForeign')
42
+ ? [blocking('codexSharedNativeForeign', `${sharedNative.pluginId} is foreign and was preserved.`)]
43
+ : []),
44
+ ...(sharedNative.state === 'blocked' && sharedNative.reason === 'unreadable'
45
+ && !existingReasonCodes.includes('codexSharedNativeCorrupt')
46
+ ? [blocking('codexSharedNativeCorrupt', `${sharedNative.pluginId} is unreadable.`)]
47
+ : []),
48
+ ...(sharedNative.state === 'replaceable' && sharedNative.reason === 'damaged'
49
+ ? [warning('codexSharedNativeCorrupt', `${sharedNative.pluginId} is damaged and can be replaced.`)]
50
+ : []),
51
+ ...(sharedNative.state === 'replaceable' && sharedNative.reason === 'outdated'
52
+ ? [warning('codexSharedNativeUpdateRequired', `${sharedNative.pluginId} requires a shared update.`)]
53
+ : []),
54
+ ...(sharedNative.state === 'replaceable' && sharedNative.reason === 'renderDrift'
55
+ ? [warning('codexSharedNativeRenderDrift', `${sharedNative.pluginId} render inputs changed and the shared native projection can be replaced.`)]
56
+ : []),
57
+ ...(sharedNative.staleCacheObserved
58
+ ? [warning('staleCacheObserved', `${sharedNative.pluginId} has non-blocking stale Codex cache residue.`)]
59
+ : []),
60
+ ...(sharedNative.state === 'unobserved' && desiredEnabled
61
+ ? [warning('codexSharedNativeUnobserved', `${sharedNative.pluginId} was not observed by a compatible Codex consumer.`)]
62
+ : []),
63
+ ];
64
+ }
65
+ function statusComponent(target, kind, key) {
66
+ return target.components.find((component) => component.kind === kind && (key === undefined || component.key === key));
67
+ }
68
+ export function statusTargetIntent(target) {
69
+ const metadata = statusComponent(target, 'intent', 'desired')?.metadata;
70
+ return {
71
+ enabled: metadata?.enabled === true,
72
+ scopes: Array.isArray(metadata?.scopes)
73
+ ? metadata.scopes.filter((scope) => scope === 'user' || scope === 'project')
74
+ : [],
75
+ relation: metadata?.relation === 'root'
76
+ || metadata?.relation === 'dependency'
77
+ || metadata?.relation === 'managed'
78
+ ? metadata.relation
79
+ : 'none',
80
+ };
81
+ }
82
+ export function statusTargetOwnershipState(target) {
83
+ const components = target.components.filter((component) => component.kind === 'ownership');
84
+ if (components.some((component) => component.state === 'error'))
85
+ return 'error';
86
+ if (components.some((component) => component.state === 'partial'))
87
+ return 'partial';
88
+ if (components.some((component) => component.state === 'present'))
89
+ return 'present';
90
+ return 'absent';
91
+ }
92
+ export function statusTargetSharedNative(target) {
93
+ const component = statusComponent(target, 'sharedNative');
94
+ if (!component || (component.state !== 'missing'
95
+ && component.state !== 'usable'
96
+ && component.state !== 'replaceable'
97
+ && component.state !== 'blocked'
98
+ && component.state !== 'unobserved'))
99
+ return undefined;
100
+ const reason = component.metadata?.reason;
101
+ return {
102
+ pluginId: component.key,
103
+ state: component.state,
104
+ ...(reason === 'outdated' || reason === 'damaged' || reason === 'renderDrift'
105
+ || reason === 'foreign' || reason === 'unreadable'
106
+ ? { reason }
107
+ : {}),
108
+ ...(typeof component.metadata?.version === 'string'
109
+ ? { version: component.metadata.version }
110
+ : {}),
111
+ ...(typeof component.metadata?.desiredVersion === 'string'
112
+ ? { desiredVersion: component.metadata.desiredVersion }
113
+ : {}),
114
+ ...(typeof component.metadata?.diagnostic === 'string'
115
+ ? { diagnostic: component.metadata.diagnostic }
116
+ : {}),
117
+ ...(component.metadata?.staleCacheObserved === true ? { staleCacheObserved: true } : {}),
118
+ };
119
+ }
120
+ export function statusTargetActivation(target) {
121
+ const user = statusComponent(target, 'activation', 'user');
122
+ const project = statusComponent(target, 'activation', 'project');
123
+ const consumer = statusComponent(target, 'systemConsumer', 'codex');
124
+ if (!user && !project && !consumer)
125
+ return undefined;
126
+ const activation = user ?? project ?? consumer;
127
+ const evidence = activation?.metadata?.evidence;
128
+ const requiredMinVersion = consumer?.metadata?.requiredMinVersion;
129
+ let systemConsumer;
130
+ if (consumer && typeof requiredMinVersion === 'string') {
131
+ const detectedVersion = consumer.metadata?.detectedVersion;
132
+ const code = consumer.metadata?.code;
133
+ const diagnostic = consumer.metadata?.diagnostic;
134
+ systemConsumer = consumer.state === 'missing' || consumer.state === 'unobserved'
135
+ ? { state: consumer.state, requiredMinVersion }
136
+ : consumer.state === 'compatible' && typeof detectedVersion === 'string'
137
+ ? { state: 'compatible', detectedVersion, requiredMinVersion }
138
+ : consumer.state === 'incompatible'
139
+ && (code === 'codexProjectPluginVersionTooLow' || code === 'codexSystemCliUnsupported')
140
+ && typeof detectedVersion === 'string'
141
+ && typeof diagnostic === 'string'
142
+ ? { state: 'incompatible', code, detectedVersion, diagnostic, requiredMinVersion }
143
+ : consumer.state === 'unresolved'
144
+ && (code === 'codexProjectPluginUnsupported' || code === 'codexSystemCliUnsupported')
145
+ && typeof diagnostic === 'string'
146
+ ? { state: 'unresolved', code, diagnostic, requiredMinVersion }
147
+ : undefined;
148
+ }
149
+ return {
150
+ ...(user ? { user: user.state === 'enabled' } : {}),
151
+ ...(project ? { project: project.state === 'enabled' } : {}),
152
+ ...(typeof activation?.metadata?.effective === 'boolean'
153
+ ? { effective: activation.metadata.effective }
154
+ : {}),
155
+ evidence: evidence === 'observed' || evidence === 'unobserved' ? evidence : 'assumed',
156
+ ...(systemConsumer ? { systemConsumer } : {}),
157
+ };
158
+ }
159
+ export function statusTargetExtensions(target) {
160
+ const component = statusComponent(target, 'extension', 'aw');
161
+ if (!component || (component.state !== 'ready'
162
+ && component.state !== 'missing'
163
+ && component.state !== 'drifted'
164
+ && component.state !== 'conflict'))
165
+ return undefined;
166
+ const kinds = Array.isArray(component.metadata?.kinds)
167
+ ? component.metadata.kinds.filter((kind) => kind === 'skill'
168
+ || kind === 'instruction'
169
+ || kind === 'permission'
170
+ || kind === 'agent'
171
+ || kind === 'config')
172
+ : [];
173
+ return { state: component.state, kinds };
174
+ }
175
+ let dependencyInspectionHookForTests;
176
+ export function setStatusDependencyInspectionHookForTests(hook) {
177
+ dependencyInspectionHookForTests = hook;
178
+ }
179
+ export async function loadConsoleItemsResult(options = {}, runtime = {}) {
180
+ const result = await statusCommandV7({
181
+ cwd: options.cwd ?? process.cwd(),
182
+ env: runtime.env,
183
+ platform: options.platform,
184
+ scope: options.scope,
185
+ verbose: options.verbose,
186
+ });
187
+ const groups = new Map();
188
+ const summaries = new Map(result.pluginSummaries.map((summary) => [summary.pluginId, summary]));
189
+ for (const target of result.payload.targets) {
190
+ const summary = summaries.get(target.pluginId);
191
+ let pluginSummary;
192
+ if (summary !== undefined) {
193
+ const { pluginName: _pluginName, pluginId: _pluginId, ...projected } = summary;
194
+ pluginSummary = projected;
195
+ }
196
+ const current = groups.get(target.pluginId) ?? {
197
+ pluginName: target.pluginId,
198
+ ...(target.version ? { version: target.version } : {}),
199
+ ...(pluginSummary ? { pluginSummary } : {}),
200
+ targets: [],
201
+ };
202
+ current.targets.push(target);
203
+ groups.set(target.pluginId, current);
204
+ }
205
+ const allSourcesFailed = result.payload.catalog.sources.length > 0
206
+ && result.payload.catalog.sources.every((source) => source.error !== undefined);
207
+ return {
208
+ items: [...groups.values()].sort((left, right) => left.pluginName.localeCompare(right.pluginName)),
209
+ catalogUnavailable: allSourcesFailed,
210
+ status: result.payload,
211
+ };
212
+ }
213
+ export async function loadConsoleItems(options = {}, runtime = {}) {
214
+ return (await loadConsoleItemsResult(options, runtime)).items;
215
+ }
216
+ function projectStateInventoryError(error, env, cwd) {
217
+ const sanitized = sanitizeCatalogSourceError(error, env, [
218
+ getCodexHome(env),
219
+ getClaudeHome(env),
220
+ path.resolve(cwd),
221
+ ]);
222
+ const native = /(?:Codex|Claude|config\.toml|settings|installed_plugins)/iu.test(sanitized.message);
223
+ const code = native ? 'nativeStateUnreadable' : 'stateInventoryFailed';
224
+ return { code, message: `${code}: ${sanitized.message}`, relevance: { global: true } };
225
+ }
226
+ function inventoryErrorMatchesSelection(options) {
227
+ const relevance = options.error.relevance;
228
+ if (relevance.global)
229
+ return true;
230
+ if (relevance.projectLocationKey
231
+ && relevance.projectLocationKey !== options.currentProjectLocationKey)
232
+ return false;
233
+ if (options.platformExplicit && relevance.platform
234
+ && !options.platforms.includes(relevance.platform))
235
+ return false;
236
+ if (options.scopeExplicit && relevance.scope
237
+ && !options.scopes.includes(relevance.scope))
238
+ return false;
239
+ if (options.selectors.length === 0 || (!relevance.sourceId && !relevance.pluginName))
240
+ return true;
241
+ return options.selectors.some((selector) => (!relevance.pluginName || selector.parsed.pluginName === relevance.pluginName)
242
+ && (!relevance.sourceId
243
+ || selector.parsed.sourceId === undefined
244
+ || selector.parsed.sourceId === relevance.sourceId));
245
+ }
246
+ function finalizeTargetError(error, targetState) {
247
+ return {
248
+ ...error,
249
+ severity: error.code === 'artifactCollision'
250
+ || (targetState === 'error'
251
+ && error.dependencyPluginId === undefined)
252
+ ? 'blocking'
253
+ : 'warning',
254
+ };
255
+ }
256
+ function projectTargetError(error, env, cwd, targetState) {
257
+ const sanitized = sanitizeCatalogSourceError(new Error(error.message), env, [
258
+ getCodexHome(env),
259
+ getClaudeHome(env),
260
+ path.resolve(cwd),
261
+ ]);
262
+ return finalizeTargetError({ ...error, message: sanitized.message }, targetState);
263
+ }
264
+ function sourceRequestedRef(source, cliVersion) {
265
+ return source.type === 'git' ? resolveCatalogSourceRef(source.refPolicy, cliVersion) : 'path';
266
+ }
267
+ function selectedPlatforms(value) {
268
+ const selection = value === undefined ? 'both' : parsePlatformValue(value);
269
+ return selection === 'both' ? ['codex', 'claude'] : [selection];
270
+ }
271
+ function selectedScopes(value) {
272
+ return value === undefined ? ['user', 'project'] : [parseScopeValue(value)];
273
+ }
274
+ function emptyIntent() {
275
+ return {
276
+ schemaVersion: 2,
277
+ kind: 'aw-plugin-intents',
278
+ roots: [],
279
+ dependencyScopeOverrides: [],
280
+ };
281
+ }
282
+ function desiredTargetKey(pluginId, platform) {
283
+ return `${pluginId}\0${platform}`;
284
+ }
285
+ function calculateDesiredTargetStates(options) {
286
+ const desired = new Map();
287
+ const add = (pluginId, platform, scope, relation) => {
288
+ const key = desiredTargetKey(pluginId, platform);
289
+ const current = desired.get(key) ?? { scopes: new Set(), relation: 'none' };
290
+ current.scopes.add(scope);
291
+ if (relation === 'root' || (relation === 'dependency' && current.relation !== 'root')) {
292
+ current.relation = relation;
293
+ }
294
+ desired.set(key, current);
295
+ };
296
+ const byId = new Map(options.available.map((entry) => [
297
+ formatPluginId({ sourceId: entry.source.id, pluginName: entry.name }),
298
+ entry,
299
+ ]));
300
+ for (const [scope, intent] of [
301
+ ['user', options.userIntent],
302
+ ['project', options.projectIntent],
303
+ ]) {
304
+ for (const root of intent.roots) {
305
+ for (const platform of root.platforms)
306
+ add(root.pluginId, platform, scope, 'root');
307
+ }
308
+ for (const platform of ['codex', 'claude']) {
309
+ const platformRoots = intent.roots.filter((root) => root.platforms.includes(platform) && byId.has(root.pluginId));
310
+ const closure = new Set();
311
+ const visit = (pluginId) => {
312
+ if (closure.has(pluginId))
313
+ return;
314
+ closure.add(pluginId);
315
+ const entry = byId.get(pluginId);
316
+ if (!entry)
317
+ return;
318
+ for (const dependency of entry.dependencies) {
319
+ visit(formatPluginId({ sourceId: entry.source.id, pluginName: dependency }));
320
+ }
321
+ };
322
+ for (const root of platformRoots)
323
+ visit(root.pluginId);
324
+ const nodes = [...closure].flatMap((pluginId) => {
325
+ const entry = byId.get(pluginId);
326
+ if (!entry || !entry.targets[platform].user && !entry.targets[platform].project)
327
+ return [];
328
+ const allowedScopes = [
329
+ ...(entry.targets[platform].project
330
+ && (platform !== 'codex' || options.codexProjectAllowed) ? ['project'] : []),
331
+ ...(entry.targets[platform].user ? ['user'] : []),
332
+ ];
333
+ return allowedScopes.length === 0 ? [] : [{
334
+ pluginId,
335
+ pluginName: entry.name,
336
+ platform,
337
+ relation: platformRoots.some((root) => root.pluginId === pluginId)
338
+ ? 'requested'
339
+ : 'dependency',
340
+ depth: platformRoots.some((root) => root.pluginId === pluginId) ? 0 : 1,
341
+ allowedScopes,
342
+ ...(scope === 'project'
343
+ && !platformRoots.some((root) => root.pluginId === pluginId)
344
+ && entry.states?.[platform]?.user?.state === 'present'
345
+ && !entry.states[platform]?.user?.errors.some((error) => error.severity === 'blocking')
346
+ ? { preferredScope: 'user', preferredScopeReason: 'existingWiderTarget' }
347
+ : {}),
348
+ }];
349
+ });
350
+ const nodeIds = new Set(nodes.map((node) => node.pluginId));
351
+ const roots = platformRoots.flatMap((root) => nodeIds.has(root.pluginId)
352
+ ? [{ pluginId: root.pluginId, platform, scope }]
353
+ : []);
354
+ if (roots.length === 0)
355
+ continue;
356
+ const edges = nodes.flatMap((node) => {
357
+ const entry = byId.get(node.pluginId);
358
+ return entry.dependencies.flatMap((dependency) => {
359
+ const dependencyId = formatPluginId({
360
+ sourceId: entry.source.id,
361
+ pluginName: dependency,
362
+ });
363
+ return nodeIds.has(dependencyId)
364
+ ? [{ from: node.pluginId, to: dependencyId, platform }]
365
+ : [];
366
+ });
367
+ });
368
+ const plan = createDependencyPlacementPlan({
369
+ requestedPluginIds: roots.map((root) => root.pluginId),
370
+ nodes,
371
+ roots,
372
+ dependencyEdges: edges,
373
+ scopeOverrides: intent.dependencyScopeOverrides.filter((override) => nodeIds.has(override.pluginId)
374
+ && (override.platform === undefined || override.platform === platform)),
375
+ });
376
+ for (const target of plan.targets) {
377
+ add(target.pluginId, target.platform, target.resolvedScope, target.relation === 'requested' ? 'root' : 'dependency');
378
+ }
379
+ }
380
+ }
381
+ return new Map([...desired].map(([key, value]) => [key, {
382
+ scopes: [...value.scopes].sort(),
383
+ relation: value.relation,
384
+ }]));
385
+ }
386
+ function statusRecovery(options) {
387
+ if (options.errorCodes?.some((code) => code === 'codexProjectPluginVersionTooLow'
388
+ || code === 'codexProjectPluginUnsupported'
389
+ || code === 'codexSystemCliUnsupported')) {
390
+ return [{
391
+ command: 'manual',
392
+ description: '升级或修复官方 system Codex CLI 后重试原操作。',
393
+ }];
394
+ }
395
+ if (options.errorCodes?.includes('awCapabilityUnsupported')) {
396
+ return [{
397
+ command: 'manual',
398
+ description: '升级 AW CLI 到支持插件所需 capability 的版本后重试。',
399
+ }];
400
+ }
401
+ if (options.state === 'ready' || options.state === 'absent')
402
+ return [];
403
+ if (options.state === 'orphaned') {
404
+ return [{ command: 'cleanup', description: '清理可证明属于 AW 的遗留输出。' }];
405
+ }
406
+ if (options.state === 'blocked' && options.errorCodes?.some((code) => code === 'sourceMissing'
407
+ || code === 'catalogSourceUnavailable'
408
+ || code === 'bundleUnavailable'
409
+ || code === 'codexIntentSourceUnavailable')) {
410
+ return [
411
+ { command: 'sync', description: '来源恢复后同步 desired intent。' },
412
+ { command: 'cleanup', description: '来源无法恢复时清理可证明属于 AW 的输出。' },
413
+ ];
414
+ }
415
+ if (options.state === 'blocked') {
416
+ if (options.desired.scopes.includes('user') && options.desired.scopes.includes('project')) {
417
+ return ['user', 'project'].flatMap((scope) => {
418
+ const retainedScope = scope === 'user' ? 'project' : 'user';
419
+ const retainedRoot = options.conflictRoots?.[retainedScope]?.[0];
420
+ if (!retainedRoot)
421
+ return [];
422
+ return (options.conflictRoots?.[scope] ?? []).map((rootPluginId) => ({
423
+ command: 'uninstall',
424
+ scope,
425
+ description: `运行 aw uninstall ${rootPluginId} --platform ${options.platform} --scope ${scope},再运行 aw sync ${retainedRoot} --platform ${options.platform} --scope ${retainedScope}。`,
426
+ }));
427
+ });
428
+ }
429
+ const collision = options.sharedNative?.state === 'blocked'
430
+ ? `Codex shared native ${options.sharedNative.pluginId}`
431
+ : `${options.pluginId} 的 foreign extension`;
432
+ return [
433
+ {
434
+ command: 'sync',
435
+ description: `先移除或重命名 ${collision},再运行 aw sync ${options.pluginId} --platform ${options.platform}。cleanup 会保留 foreign 内容,不会删除该冲突。`,
436
+ },
437
+ ];
438
+ }
439
+ return [{
440
+ command: options.errorCodes?.some((code) => code === 'codexSharedNativeCorrupt'
441
+ || code === 'codexActivationDrift'
442
+ || code === 'codexExtensionDrift') ? 'reinstall' : 'sync',
443
+ ...(options.desired.scopes.length === 1 ? { scope: options.desired.scopes[0] } : {}),
444
+ description: '同步 desired intent 和当前现场;现场损坏时使用重新安装修复。',
445
+ }];
446
+ }
447
+ function rootIntentsForTarget(options) {
448
+ const byId = new Map(options.available.map((entry) => [
449
+ formatPluginId({ sourceId: entry.source.id, pluginName: entry.name }),
450
+ entry,
451
+ ]));
452
+ const result = {};
453
+ for (const [scope, intent] of [
454
+ ['user', options.userIntent],
455
+ ['project', options.projectIntent],
456
+ ]) {
457
+ const roots = intent.roots.filter((root) => {
458
+ if (!root.platforms.includes(options.platform))
459
+ return false;
460
+ const seen = new Set();
461
+ const reaches = (pluginId) => {
462
+ if (pluginId === options.pluginId)
463
+ return true;
464
+ if (seen.has(pluginId))
465
+ return false;
466
+ seen.add(pluginId);
467
+ const entry = byId.get(pluginId);
468
+ return entry?.dependencies.some((dependency) => reaches(formatPluginId({
469
+ sourceId: entry.source.id,
470
+ pluginName: dependency,
471
+ }))) === true;
472
+ };
473
+ return reaches(root.pluginId);
474
+ }).map((root) => root.pluginId).sort();
475
+ if (roots.length > 0)
476
+ result[scope] = roots;
477
+ }
478
+ return result;
479
+ }
480
+ function projectedLiveState(options) {
481
+ if (options.inspection.state === 'error'
482
+ || options.inspection.components.some((entry) => entry.state === 'error'))
483
+ return 'error';
484
+ const owned = options.inspection.components.filter((entry) => (entry.state === 'present' || entry.state === 'partial'));
485
+ if (owned.length === 0)
486
+ return 'absent';
487
+ if (owned.some((entry) => entry.state === 'partial'))
488
+ return 'partial';
489
+ const required = new Set(options.required);
490
+ const optional = new Set(options.optional);
491
+ if (options.inspection.components.some((entry) => entry.state === 'present' && !required.has(entry.component) && !optional.has(entry.component))) {
492
+ return 'partial';
493
+ }
494
+ if (!options.required.every((component) => options.inspection.components.some((entry) => entry.component === component && entry.state === 'present')))
495
+ return 'partial';
496
+ if (options.required.length > 0)
497
+ return 'present';
498
+ return options.optional.some((component) => options.inspection.components.some((entry) => entry.component === component && entry.state === 'present')) ? 'present' : 'absent';
499
+ }
500
+ export function projectTargetRevision(availableVersion, installedVersion) {
501
+ if (!availableVersion || !installedVersion
502
+ || !tryParseStrictSemVer(availableVersion)
503
+ || !tryParseStrictSemVer(installedVersion)) {
504
+ return {
505
+ state: 'unknown',
506
+ ...(availableVersion ? { availableVersion } : {}),
507
+ ...(installedVersion ? { installedVersion } : {}),
508
+ };
509
+ }
510
+ const relation = compareStrictSemVer(installedVersion, availableVersion);
511
+ if (relation === 0)
512
+ return { state: 'current', availableVersion, installedVersion };
513
+ if (relation < 0)
514
+ return { state: 'upgradeAvailable', availableVersion, installedVersion };
515
+ return { state: 'unknown', availableVersion, installedVersion };
516
+ }
517
+ function renderStatusV7(payload, verbose) {
518
+ const lines = [`Catalog sources: ${payload.catalog.sources.length}`];
519
+ for (const source of payload.catalog.sources) {
520
+ lines.push(`${source.primary ? '*' : '-'} ${source.id}: ${source.error ?? source.freshness ?? 'unavailable'}`);
521
+ }
522
+ for (const target of payload.targets) {
523
+ const reasons = target.reasons.length > 0
524
+ ? ` [${target.reasons.map((reason) => `${reason.code}: ${reason.message}`).join('; ')}]`
525
+ : '';
526
+ lines.push(`${target.pluginId} ${target.platform}: ${target.state}${reasons}`);
527
+ if (verbose) {
528
+ for (const component of target.components) {
529
+ lines.push(` component ${component.kind}/${component.key}: ${component.state}`);
530
+ }
531
+ for (const action of target.recoveryActions) {
532
+ lines.push(` recovery ${action.command}: ${action.description}`);
533
+ }
534
+ }
535
+ }
536
+ for (const error of payload.errors)
537
+ lines.push(`Error: ${error.message}`);
538
+ return lines.join('\n');
539
+ }
540
+ function collisionMessage(collision) {
541
+ const reason = {
542
+ ownerMismatch: '已有内容属于其他 owner',
543
+ unownedContent: '已有内容没有 AW owner 标记',
544
+ typeMismatch: '已有内容类型与目标不匹配',
545
+ }[collision.reason];
546
+ return `artifactCollision: ${collision.artifactKind} ${collision.artifactKey}: ${reason}。请移除或迁移冲突内容后重试。`;
547
+ }
548
+ function collisionRootIssueId(options) {
549
+ return [
550
+ 'artifactCollision',
551
+ options.pluginId,
552
+ options.platform,
553
+ options.scope,
554
+ options.collision.artifactKind,
555
+ options.collision.artifactKey,
556
+ ].join(':');
557
+ }
558
+ export async function statusCommandV7(options) {
559
+ const env = options.env ?? process.env;
560
+ const dependencyPluginCache = new Map();
561
+ const dependencyInspectionCache = new Map();
562
+ const cliVersion = options.cliVersion ?? assertStrictSemVer(JSON.parse(fs.readFileSync(path.join(resolveCliPackageRoot(), 'package.json'), 'utf8')).version, 'packages/cli/package.json version');
563
+ const snapshot = await readCatalogSourcesConfigSnapshot(env);
564
+ const intentErrors = [];
565
+ const readIntent = async (scope) => {
566
+ try {
567
+ return await readPluginIntentState({ scope, cwd: options.cwd, env });
568
+ }
569
+ catch {
570
+ intentErrors.push({
571
+ code: 'pluginIntentStateInvalid',
572
+ message: `pluginIntentStateInvalid: ${scope} plugin intent state is invalid.`,
573
+ });
574
+ return emptyIntent();
575
+ }
576
+ };
577
+ const [userIntent, projectIntent] = await Promise.all([
578
+ readIntent('user'),
579
+ readIntent('project'),
580
+ ]);
581
+ const codexConfigErrors = [];
582
+ const readActivationConfig = async (scope) => {
583
+ try {
584
+ return await readCodexConfigFile(resolveCodexPaths(options.cwd, scope, env).configTomlPath);
585
+ }
586
+ catch {
587
+ codexConfigErrors.push({
588
+ scope,
589
+ code: 'codexActivationDrift',
590
+ message: `codexActivationDrift: ${scope} Codex activation config is unreadable.`,
591
+ });
592
+ return undefined;
593
+ }
594
+ };
595
+ const [userCodexConfig, projectCodexConfig] = await Promise.all([
596
+ readActivationConfig('user'),
597
+ readActivationConfig('project'),
598
+ ]);
599
+ const currentProjectKey = await resolveCanonicalRepoProjectKey(options.cwd);
600
+ const currentProjectLocationKey = createProjectLocationKey(currentProjectKey);
601
+ const codexScopePathsAlias = codexProjectConfigAliasesUserHome(options.cwd, env);
602
+ const inventoryErrors = [];
603
+ const readInventory = options.inventoryCatalogSourceReferences
604
+ ?? inventoryCatalogSourceReferences;
605
+ const ownerInventory = await readInventory({ cwd: options.cwd, env }).catch(async (error) => {
606
+ inventoryErrors.push(projectStateInventoryError(error, env, options.cwd));
607
+ return inventoryLegacyOwnerReferences({ cwd: options.cwd, env }).catch((fallbackError) => {
608
+ inventoryErrors.push(projectStateInventoryError(fallbackError, env, options.cwd));
609
+ return { inventorySchemaVersion: 1, references: [], errors: [] };
610
+ });
611
+ });
612
+ for (const error of ownerInventory.errors ?? []) {
613
+ const code = error.kind === 'nativeStateRead' ? 'nativeStateUnreadable' : 'stateInventoryFailed';
614
+ inventoryErrors.push({
615
+ code,
616
+ message: `${code}: ${error.kind}@${error.location}: ${error.message}`,
617
+ relevance: error.relevance,
618
+ });
619
+ }
620
+ const nativeCliRunner = options.nativeCliRunner ?? getDefaultNativeCliRunner();
621
+ const codexSystemConsumerInspections = new Map();
622
+ const inspectCodexSystemConsumer = (scope) => {
623
+ let inspection = codexSystemConsumerInspections.get(scope);
624
+ if (!inspection) {
625
+ inspection = inspectSystemCodexFilesystem({
626
+ cwd: options.cwd,
627
+ env,
628
+ operationRequirement: getCodexOperationRequirement(scope),
629
+ });
630
+ codexSystemConsumerInspections.set(scope, inspection);
631
+ }
632
+ return inspection;
633
+ };
634
+ const codexRegistrationCache = new Map();
635
+ const inspectCodexRegistration = async (pluginId, scope) => {
636
+ const consumer = await inspectCodexSystemConsumer(scope);
637
+ if (consumer.state !== 'compatible') {
638
+ return {
639
+ observation: { state: 'unobserved' },
640
+ observations: { user: false, project: false },
641
+ activations: {},
642
+ };
643
+ }
644
+ let inspection = codexRegistrationCache.get(pluginId);
645
+ if (!inspection) {
646
+ inspection = inspectCodexPluginRegistrationLive({
647
+ pluginId,
648
+ cwd: options.cwd,
649
+ env,
650
+ nativeCliRunner,
651
+ });
652
+ codexRegistrationCache.set(pluginId, inspection);
653
+ }
654
+ return inspection;
655
+ };
656
+ const nativeProbeCache = new Map();
657
+ const codexDesiredUserActivationIds = new Set();
658
+ const readOnlyNativeProbe = (probe) => async () => {
659
+ const key = [
660
+ probe.sourceIdentity,
661
+ probe.pluginName,
662
+ probe.platform,
663
+ probe.scope,
664
+ probe.marketplaceName,
665
+ String(probe.desired),
666
+ ].join('\0');
667
+ let value = nativeProbeCache.get(key);
668
+ if (!value) {
669
+ const hasLocalResidue = ownerInventory.references.some((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
670
+ && reference.sourceId === probe.sourceId
671
+ && reference.pluginName === probe.pluginName
672
+ && reference.platform === probe.platform);
673
+ value = probe.platform === 'codex'
674
+ ? inspectCodexRegistration(`${probe.pluginName}@${probe.marketplaceName}`, options.scope === undefined ? probe.scope : scopes[0]).then((registration) => {
675
+ if (registration.observation.state === 'failed') {
676
+ throw new Error('codexNativeObservationFailed: status requires Codex plugin list evidence.');
677
+ }
678
+ if (registration.observation.state === 'unobserved') {
679
+ return probe.desired || hasLocalResidue ? 'partial' : 'absent';
680
+ }
681
+ if (registration.observation.value === 'absent')
682
+ return 'absent';
683
+ return registration.activations[probe.scope] === true
684
+ ? 'present'
685
+ : 'partial';
686
+ })
687
+ : Promise.resolve(ownerInventory.references.some((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
688
+ && reference.sourceId === probe.sourceId
689
+ && reference.sourceIdentity === probe.sourceIdentity
690
+ && reference.pluginName === probe.pluginName
691
+ && reference.platform === probe.platform
692
+ && reference.scope === probe.scope
693
+ && (probe.scope === 'user' || reference.projectKey === currentProjectKey))
694
+ ? 'present'
695
+ : 'absent');
696
+ nativeProbeCache.set(key, value);
697
+ }
698
+ return value;
699
+ };
700
+ const hasCurrentCodexProjectOwner = (sourceId, pluginName) => ownerInventory.references.some((reference) => reference.kind === 'namespacedOwner'
701
+ && reference.sourceId === sourceId
702
+ && reference.pluginName === pluginName
703
+ && reference.platform === 'codex'
704
+ && reference.scope === 'project'
705
+ && reference.projectKey === currentProjectKey);
706
+ const configured = new Map(snapshot.config.sources.map((source) => [source.id, source]));
707
+ const requested = options.plugins ?? [];
708
+ const platforms = selectedPlatforms(options.platform);
709
+ const scopes = selectedScopes(options.scope);
710
+ const selectorErrors = [];
711
+ const parsedSelectors = [];
712
+ const plannedSelectors = [];
713
+ const liveOnlySelectors = [];
714
+ for (const selector of requested) {
715
+ let parsed;
716
+ try {
717
+ parsed = parsePluginId(selector);
718
+ }
719
+ catch (error) {
720
+ selectorErrors.push({
721
+ code: 'invalidPluginSelector',
722
+ message: error instanceof Error ? error.message : String(error),
723
+ });
724
+ continue;
725
+ }
726
+ parsedSelectors.push({ raw: selector, parsed });
727
+ if (parsed.sourceId !== undefined && !configured.has(parsed.sourceId)) {
728
+ const hasLiveReference = ownerInventory.references.some((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
729
+ && reference.sourceId === parsed.sourceId
730
+ && reference.pluginName === parsed.pluginName
731
+ && platforms.includes(reference.platform)
732
+ && scopes.includes(reference.scope)
733
+ && (reference.scope !== 'project' || reference.projectKey === currentProjectKey));
734
+ if (hasLiveReference) {
735
+ liveOnlySelectors.push({ raw: selector, parsed });
736
+ }
737
+ else if (!inventoryErrors.some((error) => inventoryErrorMatchesSelection({
738
+ error,
739
+ selectors: [{ raw: selector, parsed }],
740
+ platformExplicit: options.platform !== undefined,
741
+ scopeExplicit: options.scope !== undefined,
742
+ platforms,
743
+ scopes,
744
+ currentProjectLocationKey,
745
+ }))) {
746
+ selectorErrors.push({
747
+ code: 'pluginNotFound',
748
+ message: `Plugin "${selector}" was not found because catalog source "${parsed.sourceId}" is not configured.`,
749
+ });
750
+ }
751
+ continue;
752
+ }
753
+ plannedSelectors.push({ raw: selector, parsed });
754
+ }
755
+ const selectedInventoryErrors = inventoryErrors.filter((error) => inventoryErrorMatchesSelection({
756
+ error,
757
+ selectors: parsedSelectors,
758
+ platformExplicit: options.platform !== undefined,
759
+ scopeExplicit: options.scope !== undefined,
760
+ platforms,
761
+ scopes,
762
+ currentProjectLocationKey,
763
+ }));
764
+ const plannedSourceIds = requested.length === 0
765
+ ? undefined
766
+ : planPluginSelectorSourceIds(plannedSelectors.map((selector) => selector.parsed));
767
+ const selectedConfiguredSources = plannedSourceIds === undefined
768
+ ? snapshot.config.sources
769
+ : plannedSourceIds.map((sourceId) => configured.get(sourceId));
770
+ const identityEntries = await Promise.all(selectedConfiguredSources.map(async (source) => {
771
+ try {
772
+ return [source.id, { identity: await calculateCatalogSourceIdentity(source) }];
773
+ }
774
+ catch (error) {
775
+ const sanitized = sanitizeCatalogSourceError(error, env);
776
+ return [source.id, {
777
+ error: sanitized.message,
778
+ }];
779
+ }
780
+ }));
781
+ const identities = new Map(identityEntries);
782
+ const catalog = await withResolvedMultiSourceCatalog({
783
+ cliVersion,
784
+ configSnapshot: snapshot,
785
+ ...(plannedSourceIds === undefined ? {} : { sourceIds: plannedSourceIds }),
786
+ ...(options.catalogOperationContext
787
+ ? { operationContext: options.catalogOperationContext }
788
+ : {}),
789
+ env,
790
+ consume: async (resolution) => ({
791
+ primarySourceId: resolution.primarySourceId,
792
+ configDigest: resolution.configDigest,
793
+ compositeDigest: resolution.compositeDigest,
794
+ sources: await Promise.all(resolution.sources.map(async (item) => {
795
+ const source = configured.get(item.sourceId);
796
+ const identity = identities.get(item.sourceId);
797
+ const base = {
798
+ id: item.sourceId,
799
+ identity: identity.identity ?? 'unavailable',
800
+ type: source.type,
801
+ primary: source.primary,
802
+ requestedRef: item.resolution?.requestedRef ?? sourceRequestedRef(source, cliVersion),
803
+ };
804
+ if (identity.error || item.error) {
805
+ const error = item.error ?? new Error(identity.error);
806
+ return {
807
+ ...base,
808
+ error: [identity.error, item.error?.message].filter(Boolean).join('; '),
809
+ errorCode: catalogSourceErrorCode(error),
810
+ };
811
+ }
812
+ try {
813
+ const placementEntries = item.resolution.manifest.entries.map((entry) => {
814
+ const products = entry.policy.products;
815
+ const supports = (platform) => products === undefined
816
+ || products.includes(platform === 'codex' ? 'CODEX' : 'CLAUDE');
817
+ return {
818
+ name: entry.name,
819
+ dependencies: entry.dependencies,
820
+ source: { id: item.resolution.sourceId },
821
+ targets: {
822
+ codex: { user: supports('codex'), project: supports('codex') },
823
+ claude: { user: supports('claude'), project: supports('claude') },
824
+ },
825
+ };
826
+ });
827
+ const sourceDesired = calculateDesiredTargetStates({
828
+ userIntent,
829
+ projectIntent,
830
+ available: placementEntries,
831
+ codexProjectAllowed: !codexScopePathsAlias,
832
+ });
833
+ const registeredNames = canonicalMarketplaceRegistrationNames(ownerInventory.references, item.resolution.sourceId);
834
+ if (registeredNames.length > 1) {
835
+ throw new Error('marketplaceIdentityUnavailable: Multiple canonical native marketplace registrations match the source.');
836
+ }
837
+ const desiredMarketplaceName = registeredNames[0]
838
+ ?? (item.resolution.sourceId === resolution.primarySourceId
839
+ ? 'aw'
840
+ : `aw-${item.resolution.sourceId}`);
841
+ for (const entry of placementEntries) {
842
+ const pluginId = formatPluginId({
843
+ sourceId: item.resolution.sourceId,
844
+ pluginName: entry.name,
845
+ });
846
+ if (sourceDesired.get(desiredTargetKey(pluginId, 'codex'))?.scopes.includes('user')) {
847
+ codexDesiredUserActivationIds.add(`${entry.name}@${desiredMarketplaceName}`);
848
+ }
849
+ }
850
+ const plugins = await Promise.all(item.resolution.manifest.entries.map(async (entry) => {
851
+ const capabilitySupport = checkAwCapabilitySupport(entry.requires.aw.capabilities ?? [], IMPLEMENTED_AW_CAPABILITIES);
852
+ if (!capabilitySupport.supported) {
853
+ const products = entry.policy.products;
854
+ const supports = (platform) => products === undefined
855
+ || products.includes(platform === 'codex' ? 'CODEX' : 'CLAUDE');
856
+ const states = {};
857
+ const message = `awCapabilityUnsupported: ${item.resolution.sourceId}/${entry.name} requires unsupported AW capabilities: ${capabilitySupport.missing.join(', ')}.`;
858
+ for (const platform of ['codex', 'claude']) {
859
+ if (!supports(platform))
860
+ continue;
861
+ states[platform] = {};
862
+ for (const scope of ['user', 'project']) {
863
+ states[platform][scope] = {
864
+ state: 'error',
865
+ components: [],
866
+ errors: [finalizeTargetError({ code: 'awCapabilityUnsupported', message }, 'error')],
867
+ };
868
+ }
869
+ }
870
+ return {
871
+ name: entry.name,
872
+ version: entry.version,
873
+ displayName: entry.interface?.displayName ?? entry.name,
874
+ shortDescription: entry.interface?.shortDescription ?? entry.description,
875
+ description: entry.description,
876
+ targets: {
877
+ claude: { user: supports('claude'), project: supports('claude') },
878
+ codex: { user: supports('codex'), project: supports('codex') },
879
+ },
880
+ states,
881
+ dependencies: entry.dependencies,
882
+ missingCapabilities: capabilitySupport.missing,
883
+ };
884
+ }
885
+ const plugin = await readPluginManifest(path.join(item.resolution.rootDir, 'plugins', entry.name), { mode: 'bundle' });
886
+ const claude = supportsPlatform(plugin.manifest, 'claude');
887
+ const codex = supportsPlatform(plugin.manifest, 'codex');
888
+ const codexSurface = analyzeCodexSurface(plugin.manifest);
889
+ plugin.sourceId = item.resolution.sourceId;
890
+ plugin.sourceIdentity = item.resolution.sourceIdentity;
891
+ plugin.pluginId = formatPluginId({ sourceId: item.resolution.sourceId, pluginName: entry.name });
892
+ let configIssues;
893
+ let configDiagnostic;
894
+ if (plugin.manifest.config?.fields) {
895
+ const issues = new Map();
896
+ for (const scope of scopes) {
897
+ try {
898
+ const resolved = scope === 'project'
899
+ ? await resolveProjectArtifactRenderConfig({
900
+ sourceId: plugin.sourceId,
901
+ sourceIdentity: plugin.sourceIdentity,
902
+ pluginName: plugin.manifest.name,
903
+ manifest: plugin.manifest,
904
+ cwd: options.cwd,
905
+ env,
906
+ })
907
+ : await resolveEffectivePluginConfig({
908
+ sourceId: plugin.sourceId,
909
+ sourceIdentity: plugin.sourceIdentity,
910
+ pluginName: plugin.manifest.name,
911
+ manifest: plugin.manifest,
912
+ targetScope: 'user',
913
+ cwd: options.cwd,
914
+ env,
915
+ });
916
+ for (const issue of resolved.issues) {
917
+ const source = issue.source ?? 'missing';
918
+ const configIssue = {
919
+ scope,
920
+ type: issue.type,
921
+ key: issue.key,
922
+ title: plugin.manifest.config.fields[issue.key]?.title ?? issue.key,
923
+ source,
924
+ };
925
+ issues.set(`${scope}\0${configIssue.type}\0${configIssue.key}\0${configIssue.source}`, configIssue);
926
+ }
927
+ }
928
+ catch {
929
+ configDiagnostic ??= {
930
+ scope,
931
+ code: 'configReadFailed',
932
+ message: '插件设置当前不可读。未读取或显示设置值。',
933
+ };
934
+ }
935
+ }
936
+ configIssues = [...issues.values()];
937
+ }
938
+ const states = {};
939
+ const defaultMarketplaceName = item.resolution.sourceId === resolution.primarySourceId
940
+ ? 'aw'
941
+ : `aw-${item.resolution.sourceId}`;
942
+ const marketplaceNameFor = (pluginName, platform, scope) => {
943
+ const liveName = ownerInventory.references.find((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
944
+ && reference.sourceId === item.resolution.sourceId
945
+ && reference.sourceIdentity === item.resolution.sourceIdentity
946
+ && reference.pluginName === pluginName
947
+ && reference.platform === platform
948
+ && reference.scope === scope
949
+ && (scope === 'user' || reference.projectKey === currentProjectKey)
950
+ && reference.marketplaceName)?.marketplaceName;
951
+ if (liveName)
952
+ return liveName;
953
+ const registeredNames = canonicalMarketplaceRegistrationNames(ownerInventory.references, item.resolution.sourceId);
954
+ if (registeredNames.length > 1) {
955
+ throw new Error('marketplaceIdentityUnavailable: Multiple canonical native marketplace registrations match the source.');
956
+ }
957
+ return registeredNames[0] ?? defaultMarketplaceName;
958
+ };
959
+ const marketplaceRoot = path.join(resolveAwHome(env), 'marketplaces', item.resolution.sourceId);
960
+ for (const platform of ['codex', 'claude']) {
961
+ states[platform] = {};
962
+ for (const scope of ['user', 'project']) {
963
+ if (platform === 'codex'
964
+ && scope === 'project'
965
+ && codexScopePathsAlias
966
+ && !hasCurrentCodexProjectOwner(item.resolution.sourceId, entry.name))
967
+ continue;
968
+ const supported = platform === 'claude'
969
+ ? claude
970
+ : codex && codexSurface.ok;
971
+ if (!supported)
972
+ continue;
973
+ const changedOwner = ownerInventory.references.find((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
974
+ && reference.sourceId === item.resolution.sourceId
975
+ && reference.pluginName === entry.name
976
+ && reference.platform === platform
977
+ && reference.scope === scope
978
+ && (scope === 'user' || reference.projectKey === currentProjectKey)
979
+ && reference.sourceIdentity
980
+ && reference.sourceIdentity !== item.resolution.sourceIdentity);
981
+ if (changedOwner) {
982
+ states[platform][scope] = {
983
+ state: 'error',
984
+ components: [],
985
+ errors: [finalizeTargetError({
986
+ code: 'sourceChanged',
987
+ message: `sourceChanged: owner at ${changedOwner.location} has a different source identity.`,
988
+ }, 'error')],
989
+ };
990
+ continue;
991
+ }
992
+ try {
993
+ const marketplaceName = marketplaceNameFor(entry.name, platform, scope);
994
+ const inspected = await inspectRebuildTarget({
995
+ sourceId: item.resolution.sourceId,
996
+ sourceIdentity: item.resolution.sourceIdentity,
997
+ pluginId: plugin.pluginId,
998
+ marketplaceName,
999
+ marketplaceRoot,
1000
+ plugin,
1001
+ platform,
1002
+ scope,
1003
+ cwd: options.cwd,
1004
+ catalog: {
1005
+ rootDir: item.resolution.rootDir,
1006
+ source: 'local',
1007
+ },
1008
+ context: {
1009
+ env,
1010
+ nativeCliRunner,
1011
+ reporter: createNoopReporter(),
1012
+ debugLogger: createNoopDebugLogger(),
1013
+ },
1014
+ userActivationDesired: codexDesiredUserActivationIds,
1015
+ nativeProbe: readOnlyNativeProbe({
1016
+ pluginName: entry.name,
1017
+ sourceId: item.resolution.sourceId,
1018
+ sourceIdentity: item.resolution.sourceIdentity,
1019
+ platform,
1020
+ scope,
1021
+ marketplaceName,
1022
+ marketplaceRoot,
1023
+ desired: sourceDesired.get(desiredTargetKey(plugin.pluginId, platform))
1024
+ ?.scopes.includes(scope) === true,
1025
+ }),
1026
+ shallow: true,
1027
+ });
1028
+ const liveState = projectedLiveState({
1029
+ inspection: inspected.inspection,
1030
+ required: inspected.target.desiredOwnedComponents ?? inspected.target.ownedComponents,
1031
+ optional: inspected.target.optionalOwnedComponents ?? [],
1032
+ });
1033
+ const collisionErrors = inspected.inspection.components.flatMap((component) => component.collision ? [finalizeTargetError({
1034
+ code: 'artifactCollision',
1035
+ message: collisionMessage(component.collision),
1036
+ collision: component.collision,
1037
+ rootIssueId: collisionRootIssueId({
1038
+ pluginId: formatPluginId({
1039
+ sourceId: item.resolution.sourceId,
1040
+ pluginName: entry.name,
1041
+ }),
1042
+ platform,
1043
+ scope,
1044
+ collision: component.collision,
1045
+ }),
1046
+ rootIssueCode: 'artifactCollision',
1047
+ }, liveState)] : []);
1048
+ const dependencyErrors = [];
1049
+ const dependencyReadiness = [];
1050
+ const directDependencies = plugin.manifest.dependencies ?? [];
1051
+ if (directDependencies.length > 0
1052
+ && (liveState === 'present' || liveState === 'partial')) {
1053
+ for (const dependencyName of directDependencies) {
1054
+ const dependencyId = formatPluginId({
1055
+ sourceId: item.resolution.sourceId,
1056
+ pluginName: dependencyName,
1057
+ });
1058
+ const dependencyEntry = item.resolution.manifest.entries.find((candidate) => candidate.name === dependencyName);
1059
+ if (!dependencyEntry) {
1060
+ const rootIssueId = `dependencyMissing:${dependencyId}:${platform}:${scope}`;
1061
+ dependencyReadiness.push({
1062
+ dependencyPluginId: dependencyId,
1063
+ dependencyPlatform: platform,
1064
+ dependencyScope: scope,
1065
+ dependencyProject: scope === 'project' ? 'current' : null,
1066
+ state: 'absent',
1067
+ rootIssueId,
1068
+ rootIssueCode: 'dependencyMissing',
1069
+ });
1070
+ dependencyErrors.push(finalizeTargetError({
1071
+ code: 'dependencyMissing',
1072
+ message: `dependencyMissing: ${dependencyId} is not available in the current source snapshot.`,
1073
+ dependencyPluginId: dependencyId,
1074
+ dependencyPlatform: platform,
1075
+ dependencyScope: scope,
1076
+ dependencyProject: scope === 'project' ? 'current' : null,
1077
+ rootIssueId,
1078
+ rootIssueCode: 'dependencyMissing',
1079
+ }, 'partial'));
1080
+ continue;
1081
+ }
1082
+ const dependencySupport = checkAwCapabilitySupport(dependencyEntry.requires.aw.capabilities ?? [], IMPLEMENTED_AW_CAPABILITIES);
1083
+ if (!dependencySupport.supported) {
1084
+ const rootIssueId = `awCapabilityUnsupported:${dependencyId}`;
1085
+ dependencyReadiness.push({
1086
+ dependencyPluginId: dependencyId,
1087
+ dependencyPlatform: platform,
1088
+ dependencyScope: scope,
1089
+ dependencyProject: scope === 'project' ? 'current' : null,
1090
+ state: 'error',
1091
+ rootIssueId,
1092
+ rootIssueCode: 'awCapabilityUnsupported',
1093
+ });
1094
+ dependencyErrors.push(finalizeTargetError({
1095
+ code: 'awCapabilityUnsupported',
1096
+ message: `awCapabilityUnsupported: ${dependencyId} requires unsupported AW capabilities: ${dependencySupport.missing.join(', ')}.`,
1097
+ dependencyPluginId: dependencyId,
1098
+ dependencyPlatform: platform,
1099
+ dependencyScope: scope,
1100
+ dependencyProject: scope === 'project' ? 'current' : null,
1101
+ rootIssueId,
1102
+ rootIssueCode: 'awCapabilityUnsupported',
1103
+ }, 'partial'));
1104
+ continue;
1105
+ }
1106
+ const pluginCacheKey = [item.resolution.sourceIdentity, dependencyId].join('\0');
1107
+ let dependencyPluginPromise = dependencyPluginCache.get(pluginCacheKey);
1108
+ if (!dependencyPluginPromise) {
1109
+ dependencyPluginPromise = readPluginManifest(path.join(item.resolution.rootDir, 'plugins', dependencyName), { mode: 'bundle' }).then((dependencyPlugin) => {
1110
+ dependencyPlugin.sourceId = item.resolution.sourceId;
1111
+ dependencyPlugin.sourceIdentity = item.resolution.sourceIdentity;
1112
+ dependencyPlugin.pluginId = dependencyId;
1113
+ return dependencyPlugin;
1114
+ });
1115
+ dependencyPluginCache.set(pluginCacheKey, dependencyPluginPromise);
1116
+ }
1117
+ const dependencyOverride = (scope === 'project'
1118
+ ? projectIntent
1119
+ : userIntent).dependencyScopeOverrides.find((override) => override.pluginId === dependencyId
1120
+ && (override.platform === undefined || override.platform === platform));
1121
+ const placements = dependencyOverride
1122
+ ? [dependencyOverride.scope]
1123
+ : scope === 'project' ? ['project', 'user'] : ['user'];
1124
+ let dependencyResult = {
1125
+ state: 'absent',
1126
+ };
1127
+ for (const dependencyScope of placements) {
1128
+ const inspectionCacheKey = [
1129
+ item.resolution.sourceIdentity,
1130
+ dependencyId,
1131
+ platform,
1132
+ dependencyScope,
1133
+ dependencyScope === 'project' ? currentProjectKey : '',
1134
+ ].join('\0');
1135
+ let dependencyInspection = dependencyInspectionCache.get(inspectionCacheKey);
1136
+ if (!dependencyInspection) {
1137
+ dependencyInspection = dependencyPluginPromise.then(async (dependencyPlugin) => {
1138
+ dependencyInspectionHookForTests?.();
1139
+ const dependencyMarketplaceName = marketplaceNameFor(dependencyName, platform, dependencyScope);
1140
+ const dependencyInspected = await inspectRebuildTarget({
1141
+ sourceId: item.resolution.sourceId,
1142
+ sourceIdentity: item.resolution.sourceIdentity,
1143
+ pluginId: dependencyId,
1144
+ marketplaceName: dependencyMarketplaceName,
1145
+ marketplaceRoot,
1146
+ plugin: dependencyPlugin,
1147
+ platform,
1148
+ scope: dependencyScope,
1149
+ cwd: options.cwd,
1150
+ catalog: { rootDir: item.resolution.rootDir, source: 'local' },
1151
+ context: {
1152
+ env,
1153
+ nativeCliRunner,
1154
+ reporter: createNoopReporter(),
1155
+ debugLogger: createNoopDebugLogger(),
1156
+ },
1157
+ userActivationDesired: codexDesiredUserActivationIds,
1158
+ nativeProbe: readOnlyNativeProbe({
1159
+ pluginName: dependencyName,
1160
+ sourceId: item.resolution.sourceId,
1161
+ sourceIdentity: item.resolution.sourceIdentity,
1162
+ platform,
1163
+ scope: dependencyScope,
1164
+ marketplaceName: dependencyMarketplaceName,
1165
+ marketplaceRoot,
1166
+ desired: sourceDesired.get(desiredTargetKey(dependencyId, platform))
1167
+ ?.scopes.includes(dependencyScope) === true,
1168
+ }),
1169
+ shallow: true,
1170
+ });
1171
+ const dependencyLiveState = projectedLiveState({
1172
+ inspection: dependencyInspected.inspection,
1173
+ required: dependencyInspected.target.desiredOwnedComponents
1174
+ ?? dependencyInspected.target.ownedComponents,
1175
+ optional: dependencyInspected.target.optionalOwnedComponents ?? [],
1176
+ });
1177
+ const collision = dependencyInspected.inspection.components.find((component) => component.collision)?.collision;
1178
+ if (collision) {
1179
+ return {
1180
+ state: 'blockedByCollision',
1181
+ dependencyScope,
1182
+ rootIssueId: collisionRootIssueId({
1183
+ pluginId: dependencyId,
1184
+ platform,
1185
+ scope: dependencyScope,
1186
+ collision,
1187
+ }),
1188
+ rootIssueCode: 'artifactCollision',
1189
+ };
1190
+ }
1191
+ return {
1192
+ state: dependencyLiveState === 'present' ? 'ready'
1193
+ : dependencyLiveState === 'absent' ? 'absent'
1194
+ : dependencyLiveState === 'partial' ? 'incomplete'
1195
+ : 'error',
1196
+ dependencyScope,
1197
+ ...(dependencyLiveState === 'partial'
1198
+ ? {
1199
+ rootIssueId: `incompleteInstallation:${dependencyId}:${platform}:${dependencyScope}`,
1200
+ rootIssueCode: 'incompleteInstallation',
1201
+ }
1202
+ : dependencyLiveState === 'error'
1203
+ ? {
1204
+ rootIssueId: `diagnostic:${dependencyId}:${platform}:${dependencyScope}`,
1205
+ rootIssueCode: 'diagnostic',
1206
+ }
1207
+ : {}),
1208
+ };
1209
+ }).catch(() => ({
1210
+ state: 'error',
1211
+ dependencyScope,
1212
+ rootIssueId: `diagnostic:${dependencyId}:${platform}:${dependencyScope}`,
1213
+ rootIssueCode: 'diagnostic',
1214
+ }));
1215
+ dependencyInspectionCache.set(inspectionCacheKey, dependencyInspection);
1216
+ }
1217
+ const candidate = await dependencyInspection;
1218
+ if (candidate.state === 'ready') {
1219
+ dependencyResult = candidate;
1220
+ break;
1221
+ }
1222
+ const priority = {
1223
+ ready: 5,
1224
+ blockedByCollision: 4,
1225
+ incomplete: 3,
1226
+ error: 2,
1227
+ absent: 1,
1228
+ };
1229
+ if (priority[candidate.state] > priority[dependencyResult.state]) {
1230
+ dependencyResult = candidate;
1231
+ }
1232
+ }
1233
+ if (dependencyResult.state === 'absent') {
1234
+ const dependencyScope = dependencyResult.dependencyScope ?? placements[0];
1235
+ dependencyResult = {
1236
+ state: 'absent',
1237
+ dependencyScope,
1238
+ rootIssueId: `dependencyMissing:${dependencyId}:${platform}:${dependencyScope}`,
1239
+ rootIssueCode: 'dependencyMissing',
1240
+ };
1241
+ }
1242
+ const dependencyScope = dependencyResult.dependencyScope ?? placements[0];
1243
+ dependencyReadiness.push({
1244
+ dependencyPluginId: dependencyId,
1245
+ dependencyPlatform: platform,
1246
+ dependencyScope,
1247
+ dependencyProject: dependencyScope === 'project' ? 'current' : null,
1248
+ ...dependencyResult,
1249
+ });
1250
+ if (dependencyResult.state === 'absent') {
1251
+ dependencyErrors.push(finalizeTargetError({
1252
+ code: 'dependencyMissing',
1253
+ message: `dependencyMissing: ${dependencyId} is absent from its required live placement.`,
1254
+ dependencyPluginId: dependencyId,
1255
+ dependencyPlatform: platform,
1256
+ dependencyScope,
1257
+ dependencyProject: dependencyScope === 'project' ? 'current' : null,
1258
+ rootIssueId: dependencyResult.rootIssueId,
1259
+ rootIssueCode: dependencyResult.rootIssueCode,
1260
+ }, 'partial'));
1261
+ }
1262
+ else if (dependencyResult.state !== 'ready') {
1263
+ dependencyErrors.push(finalizeTargetError({
1264
+ code: 'dependencyNotReady',
1265
+ message: `dependencyNotReady: ${dependencyId} is not ready at its required live placement.`,
1266
+ dependencyPluginId: dependencyId,
1267
+ dependencyPlatform: platform,
1268
+ dependencyScope,
1269
+ dependencyProject: dependencyScope === 'project' ? 'current' : null,
1270
+ ...(dependencyResult.rootIssueId
1271
+ ? { rootIssueId: dependencyResult.rootIssueId }
1272
+ : {}),
1273
+ ...(dependencyResult.rootIssueCode
1274
+ ? { rootIssueCode: dependencyResult.rootIssueCode }
1275
+ : {}),
1276
+ }, 'partial'));
1277
+ }
1278
+ }
1279
+ }
1280
+ states[platform][scope] = {
1281
+ state: liveState,
1282
+ errors: [...inspected.inspection.errors.map((error) => finalizeTargetError({
1283
+ code: 'componentInspectionFailed',
1284
+ message: `${error.label}: ${error.message}`,
1285
+ }, liveState)), ...collisionErrors, ...dependencyErrors],
1286
+ ...(dependencyReadiness.length > 0 ? { dependencyReadiness } : {}),
1287
+ components: inspected.inspection.components.map((component) => {
1288
+ const projectedError = component.collision
1289
+ ? projectTargetError({
1290
+ code: 'artifactCollision',
1291
+ message: collisionMessage(component.collision),
1292
+ collision: component.collision,
1293
+ }, env, options.cwd, liveState)
1294
+ : component.diagnostic
1295
+ ? projectTargetError({
1296
+ code: 'componentInspectionFailed',
1297
+ message: component.diagnostic,
1298
+ }, env, options.cwd, liveState)
1299
+ : undefined;
1300
+ return {
1301
+ key: component.component.identity.artifactKey,
1302
+ state: component.state,
1303
+ ...(projectedError ? { error: projectedError } : {}),
1304
+ };
1305
+ }),
1306
+ ...(inspected.installedVersion
1307
+ ? { installedVersion: inspected.installedVersion }
1308
+ : {}),
1309
+ };
1310
+ }
1311
+ catch (error) {
1312
+ const message = error instanceof Error ? error.message : String(error);
1313
+ const configErrorCode = platform === 'codex' && codexConfigErrors.length > 0
1314
+ ? codexSurface.nativeKinds.length > 0
1315
+ ? 'codexSharedNativeCorrupt'
1316
+ : 'codexActivationDrift'
1317
+ : undefined;
1318
+ const code = configErrorCode
1319
+ ?? message.split(':', 1)[0]
1320
+ ?? 'targetInspectionFailed';
1321
+ states[platform][scope] = {
1322
+ state: 'error',
1323
+ components: [],
1324
+ errors: [finalizeTargetError({
1325
+ code,
1326
+ message: configErrorCode
1327
+ ? `${configErrorCode}: Codex activation state is unreadable.`
1328
+ : message,
1329
+ }, 'error')],
1330
+ };
1331
+ }
1332
+ }
1333
+ }
1334
+ let codexStatus;
1335
+ if (codex && codexSurface.ok) {
1336
+ const marketplaceName = marketplaceNameFor(entry.name, 'codex', 'user');
1337
+ const codexPluginId = `${entry.name}@${marketplaceName}`;
1338
+ const desiredCodexScopes = sourceDesired.get(desiredTargetKey(formatPluginId({ sourceId: item.resolution.sourceId, pluginName: entry.name }), 'codex'))?.scopes ?? [];
1339
+ const registrationScope = options.scope !== undefined
1340
+ ? scopes[0]
1341
+ : desiredCodexScopes.includes('project')
1342
+ ? 'project'
1343
+ : desiredCodexScopes.includes('user') ? 'user' : 'project';
1344
+ const pluginRegistration = codexSurface.nativeKinds.length > 0
1345
+ ? await inspectCodexRegistration(codexPluginId, registrationScope)
1346
+ : {
1347
+ observation: { state: 'unobserved' },
1348
+ observations: { user: false, project: false },
1349
+ activations: {},
1350
+ };
1351
+ let residueFailed = false;
1352
+ const hasNativeRenderTargets = (plugin.manifest.artifacts?.targets ?? []).some((target) => target.platform === 'codex'
1353
+ && target.target === 'codex.skill'
1354
+ && target.delivery?.mode === 'codex-native');
1355
+ const sharedInspection = codexSurface.nativeKinds.length > 0
1356
+ ? await inspectCodexSharedNativeLive({
1357
+ pluginName: entry.name,
1358
+ sourceId: item.resolution.sourceId,
1359
+ desiredVersion: entry.version,
1360
+ inspectionMode: hasNativeRenderTargets ? 'payload' : 'shallow',
1361
+ cwd: options.cwd,
1362
+ env,
1363
+ marketplaceName,
1364
+ marketplaceRoot,
1365
+ nativeCliRunner,
1366
+ pluginRegistration,
1367
+ ...(hasNativeRenderTargets ? { nativeRenderPlugin: plugin } : {}),
1368
+ }).catch(() => {
1369
+ residueFailed = true;
1370
+ return undefined;
1371
+ })
1372
+ : undefined;
1373
+ const nativeState = sharedInspection?.sharedNative;
1374
+ const sharedNative = residueFailed
1375
+ ? { pluginId: codexPluginId, state: 'blocked', reason: 'unreadable' }
1376
+ : !nativeState
1377
+ ? undefined
1378
+ : nativeState.state === 'unobserved'
1379
+ ? {
1380
+ pluginId: codexPluginId,
1381
+ state: 'unobserved',
1382
+ ...(nativeState.staleCacheObserved ? { staleCacheObserved: true } : {}),
1383
+ }
1384
+ : nativeState.state === 'missing'
1385
+ ? {
1386
+ pluginId: codexPluginId,
1387
+ state: 'missing',
1388
+ ...(nativeState.staleCacheObserved ? { staleCacheObserved: true } : {}),
1389
+ }
1390
+ : nativeState.state === 'usable'
1391
+ ? {
1392
+ pluginId: codexPluginId,
1393
+ state: 'usable',
1394
+ version: nativeState.version,
1395
+ }
1396
+ : nativeState.state === 'replaceable'
1397
+ ? {
1398
+ pluginId: codexPluginId,
1399
+ state: 'replaceable',
1400
+ reason: nativeState.reason,
1401
+ ...(nativeState.version ? { version: nativeState.version } : {}),
1402
+ ...(nativeState.desiredVersion
1403
+ ? { desiredVersion: nativeState.desiredVersion }
1404
+ : {}),
1405
+ ...(nativeState.diagnostic ? { diagnostic: nativeState.diagnostic } : {}),
1406
+ }
1407
+ : {
1408
+ pluginId: codexPluginId,
1409
+ state: 'blocked',
1410
+ reason: nativeState.reason,
1411
+ diagnostic: nativeState.diagnostic,
1412
+ };
1413
+ const configuredUserActivation = userCodexConfig
1414
+ ?.snapshot.plugins[codexPluginId]?.enabled;
1415
+ const configuredProjectActivation = projectCodexConfig
1416
+ ?.snapshot.plugins[codexPluginId]?.enabled;
1417
+ const userActivation = sharedInspection?.activationObservations.user
1418
+ ? sharedInspection.activations.user === true
1419
+ : configuredUserActivation;
1420
+ const projectActivation = sharedInspection?.activationObservations.project
1421
+ && configuredProjectActivation !== undefined
1422
+ ? configuredProjectActivation && sharedInspection.activations.project === true
1423
+ : configuredProjectActivation;
1424
+ const activationObserved = registrationScope === 'project'
1425
+ ? sharedInspection?.activationObservations.project === true
1426
+ : sharedInspection?.activationObservations.user === true;
1427
+ codexStatus = {
1428
+ pluginId: codexPluginId,
1429
+ nativeKinds: codexSurface.nativeKinds,
1430
+ extensionKinds: codexSurface.extensionKinds,
1431
+ ...(sharedNative ? { sharedNative } : {}),
1432
+ activation: {
1433
+ ...(userActivation !== undefined ? { user: userActivation } : {}),
1434
+ ...(projectActivation !== undefined ? { project: projectActivation } : {}),
1435
+ ...((userActivation !== undefined || projectActivation !== undefined)
1436
+ ? { effective: projectActivation === true || userActivation === true }
1437
+ : {}),
1438
+ evidence: activationObserved ? 'observed' : 'assumed',
1439
+ },
1440
+ };
1441
+ }
1442
+ return {
1443
+ name: entry.name,
1444
+ version: entry.version,
1445
+ displayName: plugin.manifest.interface?.displayName ?? entry.name,
1446
+ shortDescription: plugin.manifest.interface?.shortDescription
1447
+ ?? plugin.manifest.description,
1448
+ description: plugin.manifest.description,
1449
+ ...(plugin.manifest.config?.fields
1450
+ ? { configSchema: plugin.manifest.config.fields }
1451
+ : {}),
1452
+ ...(configIssues?.length ? { configIssues } : {}),
1453
+ ...(configDiagnostic ? { configDiagnostic } : {}),
1454
+ targets: {
1455
+ claude: { user: claude, project: claude },
1456
+ codex: {
1457
+ user: codex,
1458
+ project: codex
1459
+ && codexSurface.ok
1460
+ && codexSurface.classification !== 'empty',
1461
+ },
1462
+ },
1463
+ states,
1464
+ dependencies: plugin.manifest.dependencies ?? [],
1465
+ ...(codexStatus ? { codex: codexStatus } : {}),
1466
+ };
1467
+ }));
1468
+ return {
1469
+ ...base,
1470
+ resolvedCommit: item.resolution.resolvedCommit,
1471
+ catalogVersion: item.resolution.manifest.catalogVersion,
1472
+ channel: item.resolution.manifest.channel,
1473
+ freshness: 'active',
1474
+ plugins,
1475
+ };
1476
+ }
1477
+ catch (error) {
1478
+ const sanitized = sanitizeCatalogSourceError(error, env);
1479
+ return {
1480
+ ...base,
1481
+ error: sanitized.message,
1482
+ errorCode: catalogSourceErrorCode(sanitized),
1483
+ };
1484
+ }
1485
+ })),
1486
+ }),
1487
+ });
1488
+ const available = catalog.sources.flatMap((source) => 'plugins' in source
1489
+ ? source.plugins.map((plugin) => ({ ...plugin, source }))
1490
+ : []);
1491
+ const desiredTargetStates = calculateDesiredTargetStates({
1492
+ userIntent,
1493
+ projectIntent,
1494
+ available,
1495
+ codexProjectAllowed: !codexScopePathsAlias,
1496
+ });
1497
+ const failedSourceIds = new Set(catalog.sources.filter((source) => 'error' in source).map((source) => source.id));
1498
+ const selectedById = new Map();
1499
+ if (requested.length === 0) {
1500
+ for (const entry of available) {
1501
+ selectedById.set(formatPluginId({ sourceId: entry.source.id, pluginName: entry.name }), entry);
1502
+ }
1503
+ }
1504
+ else {
1505
+ for (const selector of plannedSelectors) {
1506
+ if (selector.parsed.sourceId === undefined && failedSourceIds.size > 0) {
1507
+ selectorErrors.push({
1508
+ code: 'catalogSourceUnavailable',
1509
+ message: `Cannot resolve bare plugin selector "${selector.raw}" while catalog sources are unavailable: ${[...failedSourceIds].join(', ')}.`,
1510
+ });
1511
+ continue;
1512
+ }
1513
+ if (selector.parsed.sourceId !== undefined && failedSourceIds.has(selector.parsed.sourceId)) {
1514
+ selectorErrors.push({
1515
+ code: 'catalogSourceUnavailable',
1516
+ message: `Cannot resolve plugin selector "${selector.raw}" because catalog source "${selector.parsed.sourceId}" is unavailable.`,
1517
+ });
1518
+ continue;
1519
+ }
1520
+ const matches = available.filter((entry) => entry.name === selector.parsed.pluginName
1521
+ && (selector.parsed.sourceId === undefined || entry.source.id === selector.parsed.sourceId));
1522
+ if (matches.length === 0) {
1523
+ const selectorHasInventoryError = selectedInventoryErrors.some((error) => inventoryErrorMatchesSelection({
1524
+ error,
1525
+ selectors: [selector],
1526
+ platformExplicit: options.platform !== undefined,
1527
+ scopeExplicit: options.scope !== undefined,
1528
+ platforms,
1529
+ scopes,
1530
+ currentProjectLocationKey,
1531
+ }));
1532
+ if (!selectorHasInventoryError) {
1533
+ selectorErrors.push({
1534
+ code: 'pluginNotFound',
1535
+ message: `Plugin "${selector.raw}" was not found in the selected catalog source set.`,
1536
+ });
1537
+ }
1538
+ continue;
1539
+ }
1540
+ if (selector.parsed.sourceId === undefined && matches.length > 1) {
1541
+ selectorErrors.push({
1542
+ code: 'ambiguousPlugin',
1543
+ message: `Plugin "${selector.raw}" is ambiguous across sources: ${matches.map((entry) => entry.source.id).join(', ')}.`,
1544
+ });
1545
+ continue;
1546
+ }
1547
+ for (const entry of matches) {
1548
+ selectedById.set(formatPluginId({ sourceId: entry.source.id, pluginName: entry.name }), entry);
1549
+ }
1550
+ }
1551
+ }
1552
+ const selected = [...selectedById.values()];
1553
+ const explicitTargetFilter = requested.length > 0
1554
+ && (options.platform !== undefined || options.scope !== undefined);
1555
+ const targets = selected.flatMap((entry) => platforms.flatMap((platform) => scopes.flatMap((scope) => {
1556
+ const target = {
1557
+ pluginName: entry.name,
1558
+ sourceId: entry.source.id,
1559
+ sourceIdentity: entry.source.identity,
1560
+ pluginId: formatPluginId({ sourceId: entry.source.id, pluginName: entry.name }),
1561
+ version: entry.version,
1562
+ platform,
1563
+ scope,
1564
+ cwd: path.resolve(options.cwd),
1565
+ components: [],
1566
+ };
1567
+ if (platform === 'codex'
1568
+ && scope === 'project'
1569
+ && codexScopePathsAlias
1570
+ && !hasCurrentCodexProjectOwner(entry.source.id, entry.name)) {
1571
+ if (options.scope !== 'project')
1572
+ return [];
1573
+ return [{
1574
+ ...target,
1575
+ state: 'error',
1576
+ errors: [finalizeTargetError({
1577
+ code: 'codexScopePathAlias',
1578
+ message: 'codexScopePathAlias: Codex project config resolves to the user config directory. Run this command from an actual project directory.',
1579
+ }, 'error')],
1580
+ }];
1581
+ }
1582
+ if (entry.targets[platform][scope]) {
1583
+ const live = entry.states[platform]?.[scope];
1584
+ const dependencyIssueCount = (live?.errors ?? []).filter((error) => error.code.startsWith('dependency')
1585
+ || error.code === 'awCapabilityUnsupported'
1586
+ || error.code === 'sourceChanged').length;
1587
+ return [{
1588
+ ...target,
1589
+ state: live?.state ?? 'error',
1590
+ components: live?.components ?? [],
1591
+ errors: live?.errors ?? [finalizeTargetError({
1592
+ code: 'targetInspectionFailed',
1593
+ message: `No live inspection result exists for ${entry.source.id}/${entry.name}.`,
1594
+ }, 'error')],
1595
+ ...(live?.dependencyReadiness
1596
+ ? { dependencyReadiness: live.dependencyReadiness }
1597
+ : {}),
1598
+ ...(entry.dependencies.length > 0 || dependencyIssueCount > 0 ? {
1599
+ dependency: {
1600
+ directCount: entry.dependencies.length,
1601
+ issueCount: dependencyIssueCount,
1602
+ },
1603
+ } : {}),
1604
+ }];
1605
+ }
1606
+ const unsupportedLiveReference = ownerInventory.references.find((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
1607
+ && reference.sourceId === entry.source.id
1608
+ && reference.pluginName === entry.name
1609
+ && reference.platform === platform
1610
+ && reference.scope === scope
1611
+ && (scope === 'user' || reference.projectKey === currentProjectKey));
1612
+ if (unsupportedLiveReference) {
1613
+ const sourceChanged = Boolean(unsupportedLiveReference.sourceIdentity
1614
+ && unsupportedLiveReference.sourceIdentity !== entry.source.identity);
1615
+ return [{
1616
+ ...target,
1617
+ state: 'error',
1618
+ errors: [finalizeTargetError({
1619
+ code: sourceChanged ? 'sourceChanged' : 'noLongerSupported',
1620
+ message: sourceChanged
1621
+ ? `sourceChanged: live state for ${target.pluginId} has a different source identity.`
1622
+ : `noLongerSupported: ${target.pluginId} has live state for ${platform}/${scope}, but the current bundle no longer supports that target.`,
1623
+ }, 'error')],
1624
+ }];
1625
+ }
1626
+ if (!explicitTargetFilter)
1627
+ return [];
1628
+ return [{
1629
+ ...target,
1630
+ state: 'error',
1631
+ errors: [finalizeTargetError({
1632
+ code: platform === 'codex' && scope === 'project'
1633
+ ? 'codexProjectPluginUnsupported'
1634
+ : 'unsupportedTarget',
1635
+ message: platform === 'codex' && scope === 'project'
1636
+ ? `codexProjectPluginUnsupported: ${entry.source.id}/${entry.name} cannot use the current Codex project plugin contract.`
1637
+ : `${entry.source.id}/${entry.name} does not support ${platform}/${scope}.`,
1638
+ }, 'error')],
1639
+ }];
1640
+ })));
1641
+ const referenceSelectors = [...plannedSelectors, ...liveOnlySelectors];
1642
+ const referenceSelected = (reference) => (reference.pluginName !== undefined
1643
+ && reference.platform !== undefined
1644
+ && reference.scope !== undefined
1645
+ && platforms.includes(reference.platform)
1646
+ && scopes.includes(reference.scope)
1647
+ && (reference.scope !== 'project' || reference.projectKey === currentProjectKey)
1648
+ && (requested.length === 0 || referenceSelectors.some((selector) => selector.parsed.pluginName === reference.pluginName
1649
+ && (selector.parsed.sourceId === undefined || selector.parsed.sourceId === reference.sourceId))));
1650
+ const legacyOwners = ownerInventory.references.filter((reference) => (reference.kind === 'legacyOwner' || reference.kind === 'legacyMarketplace')
1651
+ && reference.pluginName !== undefined
1652
+ && reference.platform !== undefined
1653
+ && reference.scope !== undefined
1654
+ && platforms.includes(reference.platform)
1655
+ && scopes.includes(reference.scope)
1656
+ && (requested.length === 0 || plannedSelectors.some((selector) => selector.parsed.pluginName === reference.pluginName)));
1657
+ const missingSourceOwners = ownerInventory.references.filter((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
1658
+ && reference.sourceId
1659
+ && !configured.has(reference.sourceId)
1660
+ && referenceSelected(reference));
1661
+ const missingTargets = [...new Map(missingSourceOwners.flatMap((reference) => {
1662
+ if (!reference.sourceId || !reference.pluginName
1663
+ || (reference.platform !== 'codex' && reference.platform !== 'claude')
1664
+ || (reference.scope !== 'user' && reference.scope !== 'project'))
1665
+ return [];
1666
+ const pluginId = formatPluginId({ sourceId: reference.sourceId, pluginName: reference.pluginName });
1667
+ const target = {
1668
+ pluginName: reference.pluginName,
1669
+ sourceId: reference.sourceId,
1670
+ sourceIdentity: reference.sourceIdentity ?? 'unavailable',
1671
+ pluginId,
1672
+ platform: reference.platform,
1673
+ scope: reference.scope,
1674
+ cwd: path.resolve(options.cwd),
1675
+ state: 'error',
1676
+ components: [],
1677
+ errors: [finalizeTargetError({
1678
+ code: 'sourceMissing',
1679
+ message: `sourceMissing: catalog source "${reference.sourceId}" is not configured for ${pluginId}.`,
1680
+ }, 'error')],
1681
+ };
1682
+ return [[`${pluginId}\0${reference.platform}\0${reference.scope}`, target]];
1683
+ })).values()];
1684
+ targets.push(...missingTargets);
1685
+ const unavailableSourceReferences = ownerInventory.references.filter((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
1686
+ && reference.sourceId
1687
+ && configured.has(reference.sourceId)
1688
+ && failedSourceIds.has(reference.sourceId)
1689
+ && referenceSelected(reference));
1690
+ const unavailableSourceTargets = [...new Map(unavailableSourceReferences.flatMap((reference) => {
1691
+ if (!reference.sourceId || !reference.pluginName
1692
+ || (reference.platform !== 'codex' && reference.platform !== 'claude')
1693
+ || (reference.scope !== 'user' && reference.scope !== 'project'))
1694
+ return [];
1695
+ const pluginId = formatPluginId({ sourceId: reference.sourceId, pluginName: reference.pluginName });
1696
+ const target = {
1697
+ pluginName: reference.pluginName,
1698
+ sourceId: reference.sourceId,
1699
+ sourceIdentity: reference.sourceIdentity ?? 'unavailable',
1700
+ pluginId,
1701
+ platform: reference.platform,
1702
+ scope: reference.scope,
1703
+ cwd: path.resolve(options.cwd),
1704
+ state: 'error',
1705
+ components: [],
1706
+ errors: [finalizeTargetError({
1707
+ code: 'catalogSourceUnavailable',
1708
+ message: `catalogSourceUnavailable: catalog source "${reference.sourceId}" is unavailable for ${pluginId}.`,
1709
+ }, 'error')],
1710
+ };
1711
+ return [[`${pluginId}\0${reference.platform}\0${reference.scope}`, target]];
1712
+ })).values()];
1713
+ targets.push(...unavailableSourceTargets);
1714
+ const availablePluginIds = new Set(available.map((entry) => formatPluginId({ sourceId: entry.source.id, pluginName: entry.name })));
1715
+ const resolvedSourceIds = new Set(catalog.sources.flatMap((source) => 'plugins' in source ? [source.id] : []));
1716
+ const unavailableBundleReferences = ownerInventory.references.filter((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
1717
+ && reference.sourceId
1718
+ && configured.has(reference.sourceId)
1719
+ && resolvedSourceIds.has(reference.sourceId)
1720
+ && reference.pluginName
1721
+ && referenceSelected(reference)
1722
+ && !availablePluginIds.has(formatPluginId({
1723
+ sourceId: reference.sourceId,
1724
+ pluginName: reference.pluginName,
1725
+ })));
1726
+ const unavailableBundleTargets = [...new Map(unavailableBundleReferences.flatMap((reference) => {
1727
+ if (!reference.sourceId || !reference.pluginName
1728
+ || (reference.platform !== 'codex' && reference.platform !== 'claude')
1729
+ || (reference.scope !== 'user' && reference.scope !== 'project'))
1730
+ return [];
1731
+ const pluginId = formatPluginId({ sourceId: reference.sourceId, pluginName: reference.pluginName });
1732
+ if (requested.length > 0 && !plannedSelectors.some((selector) => selector.parsed.pluginName === reference.pluginName
1733
+ && (selector.parsed.sourceId === undefined || selector.parsed.sourceId === reference.sourceId)))
1734
+ return [];
1735
+ const target = {
1736
+ pluginName: reference.pluginName,
1737
+ sourceId: reference.sourceId,
1738
+ sourceIdentity: reference.sourceIdentity ?? 'unavailable',
1739
+ pluginId,
1740
+ platform: reference.platform,
1741
+ scope: reference.scope,
1742
+ cwd: path.resolve(options.cwd),
1743
+ state: 'error',
1744
+ components: [],
1745
+ errors: [finalizeTargetError({
1746
+ code: 'bundleUnavailable',
1747
+ message: `bundleUnavailable: ${pluginId} has live state but is not present in the current source snapshot.`,
1748
+ }, 'error')],
1749
+ };
1750
+ return [[`${pluginId}\0${reference.platform}\0${reference.scope}`, target]];
1751
+ })).values()];
1752
+ targets.push(...unavailableBundleTargets);
1753
+ const targetKeys = new Set(targets.map((target) => `${target.pluginId}\0${target.platform}\0${target.scope}`));
1754
+ for (const [scope, intent] of [
1755
+ ['user', userIntent],
1756
+ ['project', projectIntent],
1757
+ ]) {
1758
+ for (const root of intent.roots) {
1759
+ const parsed = parsePluginId(root.pluginId);
1760
+ if (!parsed.sourceId)
1761
+ continue;
1762
+ if (requested.length > 0 && !parsedSelectors.some((selector) => selector.parsed.pluginName === parsed.pluginName
1763
+ && (selector.parsed.sourceId === undefined || selector.parsed.sourceId === parsed.sourceId))) {
1764
+ continue;
1765
+ }
1766
+ for (const platform of root.platforms.filter((candidate) => platforms.includes(candidate))) {
1767
+ if (!scopes.includes(scope))
1768
+ continue;
1769
+ const key = `${root.pluginId}\0${platform}\0${scope}`;
1770
+ if (targetKeys.has(key))
1771
+ continue;
1772
+ targets.push({
1773
+ pluginName: parsed.pluginName,
1774
+ sourceId: parsed.sourceId,
1775
+ sourceIdentity: identities.get(parsed.sourceId)?.identity ?? 'unavailable',
1776
+ pluginId: root.pluginId,
1777
+ platform,
1778
+ scope,
1779
+ cwd: path.resolve(options.cwd),
1780
+ state: 'error',
1781
+ components: [],
1782
+ errors: [finalizeTargetError({
1783
+ code: 'codexIntentSourceUnavailable',
1784
+ message: `codexIntentSourceUnavailable: desired intent for ${root.pluginId} cannot be resolved from the current Catalog.`,
1785
+ }, 'partial')],
1786
+ });
1787
+ targetKeys.add(key);
1788
+ }
1789
+ }
1790
+ }
1791
+ const projectedInventoryErrors = [...new Map(selectedInventoryErrors.map((error) => [
1792
+ `${error.code}\0${error.message}`,
1793
+ { code: error.code, message: error.message },
1794
+ ])).values()];
1795
+ const errors = [
1796
+ ...projectedInventoryErrors,
1797
+ ...selectorErrors,
1798
+ ...intentErrors,
1799
+ ...legacyOwners.map((reference) => projectTargetError({
1800
+ code: 'legacyStateUnsupported',
1801
+ message: `legacyStateUnsupported: legacy live ${reference.kind} at ${reference.location}`,
1802
+ }, env, options.cwd, 'error')),
1803
+ ];
1804
+ const draftTargets = targets.map((target) => ({
1805
+ ...target,
1806
+ errors: target.errors.map((error) => projectTargetError(error, env, options.cwd, target.state)),
1807
+ }));
1808
+ const selectedByPluginId = new Map(selected.map((entry) => [
1809
+ formatPluginId({ sourceId: entry.source.id, pluginName: entry.name }),
1810
+ entry,
1811
+ ]));
1812
+ const explicitScope = options.scope === undefined ? undefined : scopes[0];
1813
+ const warning = (code, message) => ({
1814
+ code,
1815
+ message: `${code}: ${message}`,
1816
+ severity: 'warning',
1817
+ });
1818
+ const blocking = (code, message) => ({
1819
+ code,
1820
+ message: `${code}: ${message}`,
1821
+ severity: 'blocking',
1822
+ });
1823
+ const decorateTarget = async (target, groupedScopes, groupedTargets) => {
1824
+ const entry = selectedByPluginId.get(target.pluginId);
1825
+ const codex = entry?.codex;
1826
+ const desiredAll = desiredTargetStates.get(desiredTargetKey(target.pluginId, target.platform))
1827
+ ?? { scopes: [], relation: 'none' };
1828
+ const desired = target.platform === 'codex'
1829
+ ? desiredAll
1830
+ : {
1831
+ scopes: desiredAll.scopes.includes(target.scope) ? [target.scope] : [],
1832
+ relation: desiredAll.relation,
1833
+ };
1834
+ const sharedNative = codex?.sharedNative ?? target.sharedNative;
1835
+ const baseActivation = codex?.activation ?? target.activation;
1836
+ const consumerScope = desired.scopes.includes('project')
1837
+ ? 'project'
1838
+ : desired.scopes.includes('user')
1839
+ ? 'user'
1840
+ : explicitScope ?? (groupedScopes.includes('project') ? 'project' : 'user');
1841
+ const inspectSystemConsumer = target.platform === 'codex'
1842
+ && baseActivation !== undefined
1843
+ && ((codex?.nativeKinds.length ?? 0) > 0 || target.sharedNative !== undefined);
1844
+ const systemConsumer = inspectSystemConsumer
1845
+ ? await inspectCodexSystemConsumer(consumerScope)
1846
+ : undefined;
1847
+ const activation = baseActivation && systemConsumer
1848
+ ? {
1849
+ ...baseActivation,
1850
+ evidence: baseActivation.evidence === 'observed'
1851
+ ? 'observed'
1852
+ : systemConsumer.state === 'missing' ? 'assumed' : 'unobserved',
1853
+ systemConsumer,
1854
+ }
1855
+ : baseActivation;
1856
+ const observationScopes = explicitScope
1857
+ ? [explicitScope]
1858
+ : desired.scopes.length > 0 ? desired.scopes : groupedScopes;
1859
+ const scopedTargets = groupedTargets.filter((candidate) => observationScopes.includes(candidate.scope));
1860
+ const observedTargets = scopedTargets.length > 0 ? scopedTargets : groupedTargets;
1861
+ const ownershipState = observedTargets.some((candidate) => candidate.state === 'error')
1862
+ ? 'error'
1863
+ : observedTargets.some((candidate) => candidate.state === 'partial')
1864
+ ? 'partial'
1865
+ : observedTargets.some((candidate) => candidate.state === 'present')
1866
+ ? 'present'
1867
+ : sharedNative?.staleCacheObserved
1868
+ ? 'partial'
1869
+ : 'absent';
1870
+ const hasSourceError = observedTargets.some((candidate) => candidate.errors.some((error) => error.code === 'sourceMissing'
1871
+ || error.code === 'catalogSourceUnavailable'
1872
+ || error.code === 'bundleUnavailable'
1873
+ || error.code === 'codexIntentSourceUnavailable'));
1874
+ const desiredOverlapConflict = target.platform === 'codex'
1875
+ && (codex?.extensionKinds.length ?? 0) > 0
1876
+ && desired.scopes.includes('user')
1877
+ && desired.scopes.includes('project');
1878
+ const expectedUser = desired.scopes.includes('user');
1879
+ const expectedProject = desired.scopes.includes('project');
1880
+ const activationDrift = target.platform === 'codex'
1881
+ && (codexConfigErrors.some((error) => error.scope === 'user' || observationScopes.includes(error.scope))
1882
+ || ((codex?.nativeKinds.length ?? 0) > 0
1883
+ && ((expectedUser && activation?.user !== true)
1884
+ || (!expectedUser && activation?.user === true)
1885
+ || (expectedProject && activation?.project !== true)
1886
+ || (!expectedProject && activation?.project === true))));
1887
+ const extensionComponents = observedTargets.flatMap((candidate) => candidate.components).filter((component) => component.key !== 'native'
1888
+ && !component.key.startsWith('activation-')
1889
+ && !component.key.startsWith('marketplace-'));
1890
+ const extensions = target.platform !== 'codex'
1891
+ || (codex?.extensionKinds.length ?? 0) === 0
1892
+ ? undefined
1893
+ : {
1894
+ state: desiredOverlapConflict
1895
+ ? 'conflict'
1896
+ : extensionComponents.some((component) => component.error?.code === 'artifactCollision')
1897
+ ? 'conflict'
1898
+ : observedTargets.some((candidate) => candidate.state === 'partial' || candidate.state === 'error')
1899
+ ? 'drifted'
1900
+ : extensionComponents.some((component) => component.state === 'partial' || component.state === 'error')
1901
+ ? 'drifted'
1902
+ : desired.scopes.length > 0 && (extensionComponents.length === 0
1903
+ || extensionComponents.every((component) => component.state === 'absent'))
1904
+ ? 'missing'
1905
+ : 'ready',
1906
+ kinds: codex.extensionKinds,
1907
+ };
1908
+ const desiredEnabled = desired.scopes.length > 0;
1909
+ const consumerIssue = activation?.systemConsumer?.state === 'incompatible'
1910
+ || activation?.systemConsumer?.state === 'unresolved'
1911
+ ? activation.systemConsumer
1912
+ : undefined;
1913
+ const consumerBlocking = consumerIssue !== undefined;
1914
+ const baseTargetErrors = observedTargets.flatMap((candidate) => candidate.errors);
1915
+ const hasBlockingBaseReason = baseTargetErrors.some((reason) => reason.severity === 'blocking');
1916
+ const capabilityUnsupported = baseTargetErrors.some((reason) => reason.code === 'awCapabilityUnsupported');
1917
+ const state = hasSourceError && desiredEnabled
1918
+ ? 'blocked'
1919
+ : consumerBlocking && desiredEnabled
1920
+ ? 'blocked'
1921
+ : desiredOverlapConflict
1922
+ ? 'blocked'
1923
+ : sharedNative?.state === 'blocked' || hasBlockingBaseReason || capabilityUnsupported
1924
+ ? 'blocked'
1925
+ : !desiredEnabled
1926
+ ? ownershipState !== 'absent' || desired.relation === 'managed'
1927
+ ? 'orphaned'
1928
+ : 'absent'
1929
+ : sharedNative?.state === 'missing'
1930
+ || sharedNative?.state === 'replaceable'
1931
+ || sharedNative?.state === 'unobserved'
1932
+ ? 'needsSync'
1933
+ : activationDrift || extensions?.state === 'drifted'
1934
+ ? 'needsSync'
1935
+ : extensions?.state === 'missing' || ownershipState === 'absent'
1936
+ ? 'needsSync'
1937
+ : ownershipState === 'partial' || ownershipState === 'error'
1938
+ ? 'needsSync'
1939
+ : 'ready';
1940
+ const stableErrors = [
1941
+ ...projectStatusSharedNativeReasons(sharedNative, baseTargetErrors.map((error) => error.code), desiredEnabled),
1942
+ ...(desiredOverlapConflict
1943
+ ? [blocking('codexExtensionScopeConflict', `${target.pluginId} has AW extensions desired at user and project scope.`)]
1944
+ : []),
1945
+ ...(activationDrift && sharedNative?.state !== 'missing' && sharedNative?.state !== 'unobserved'
1946
+ ? [warning('codexActivationDrift', `${target.pluginId} activation differs from desired intent.`)]
1947
+ : []),
1948
+ ...(extensions?.state === 'drifted'
1949
+ ? [warning('codexExtensionDrift', `${target.pluginId} extension projection has drifted.`)]
1950
+ : []),
1951
+ ...(target.platform === 'codex' && hasSourceError && desiredEnabled
1952
+ ? [warning('codexIntentSourceUnavailable', `${target.pluginId} desired intent cannot be resolved from the current Catalog.`)]
1953
+ : []),
1954
+ ...(target.platform === 'codex' && consumerBlocking && desiredEnabled
1955
+ ? [blocking(consumerIssue.code, consumerIssue.diagnostic)]
1956
+ : []),
1957
+ ];
1958
+ const targetErrors = [...baseTargetErrors, ...stableErrors];
1959
+ const dedupedErrors = [...new Map(targetErrors.map((error) => [
1960
+ `${error.code}\0${error.message}`,
1961
+ error,
1962
+ ])).values()];
1963
+ const ownershipComponents = [...new Map(observedTargets.flatMap((candidate) => candidate.components)
1964
+ .map((component) => [component.key, component])).values()];
1965
+ const representativeScope = explicitScope
1966
+ ?? (desired.scopes.length === 1
1967
+ ? desired.scopes[0]
1968
+ : observedTargets.find((candidate) => candidate.state !== 'absent')?.scope
1969
+ ?? (groupedScopes.includes('user') ? 'user' : groupedScopes[0] ?? target.scope));
1970
+ const representativeTarget = observedTargets.find((candidate) => candidate.scope === representativeScope) ?? target;
1971
+ const components = [
1972
+ {
1973
+ kind: 'intent',
1974
+ key: 'desired',
1975
+ state: desiredEnabled ? 'desired' : 'absent',
1976
+ metadata: {
1977
+ enabled: desiredEnabled,
1978
+ scopes: desired.scopes,
1979
+ relation: desired.relation,
1980
+ },
1981
+ },
1982
+ ...ownershipComponents.map((component) => ({
1983
+ kind: 'ownership',
1984
+ key: component.key,
1985
+ state: component.key === 'native'
1986
+ && component.state === 'absent'
1987
+ && sharedNative?.staleCacheObserved
1988
+ ? 'partial'
1989
+ : component.state,
1990
+ ...(component.error ? { metadata: { errorCode: component.error.code } } : {}),
1991
+ })),
1992
+ ...(sharedNative ? [{
1993
+ kind: 'sharedNative',
1994
+ key: sharedNative.pluginId,
1995
+ state: sharedNative.state,
1996
+ metadata: {
1997
+ shared: true,
1998
+ ...(sharedNative.reason ? { reason: sharedNative.reason } : {}),
1999
+ ...(sharedNative.version ? { version: sharedNative.version } : {}),
2000
+ ...(sharedNative.desiredVersion ? { desiredVersion: sharedNative.desiredVersion } : {}),
2001
+ ...(sharedNative.diagnostic ? { diagnostic: sharedNative.diagnostic } : {}),
2002
+ ...(sharedNative.staleCacheObserved ? { staleCacheObserved: true } : {}),
2003
+ },
2004
+ }] : []),
2005
+ ...['user', 'project'].flatMap((scope) => activation?.[scope] === undefined ? [] : [{
2006
+ kind: 'activation',
2007
+ key: scope,
2008
+ state: activation[scope] ? 'enabled' : 'disabled',
2009
+ metadata: {
2010
+ evidence: activation.evidence,
2011
+ ...(activation.effective !== undefined ? { effective: activation.effective } : {}),
2012
+ },
2013
+ }]),
2014
+ ...(activation?.systemConsumer ? [{
2015
+ kind: 'systemConsumer',
2016
+ key: 'codex',
2017
+ state: activation.systemConsumer.state,
2018
+ metadata: {
2019
+ evidence: activation.evidence,
2020
+ requiredMinVersion: activation.systemConsumer.requiredMinVersion,
2021
+ ...('detectedVersion' in activation.systemConsumer
2022
+ ? { detectedVersion: activation.systemConsumer.detectedVersion }
2023
+ : {}),
2024
+ ...('code' in activation.systemConsumer ? { code: activation.systemConsumer.code } : {}),
2025
+ ...('diagnostic' in activation.systemConsumer
2026
+ ? { diagnostic: activation.systemConsumer.diagnostic }
2027
+ : {}),
2028
+ },
2029
+ }] : []),
2030
+ ...(extensions ? [{
2031
+ kind: 'extension',
2032
+ key: 'aw',
2033
+ state: extensions.state,
2034
+ metadata: { kinds: extensions.kinds },
2035
+ }] : []),
2036
+ ...(representativeTarget.dependencyReadiness ?? []).map((dependency) => ({
2037
+ kind: 'dependency',
2038
+ key: dependency.dependencyPluginId,
2039
+ state: dependency.state,
2040
+ metadata: {
2041
+ platform: dependency.dependencyPlatform,
2042
+ scope: dependency.dependencyScope,
2043
+ project: dependency.dependencyProject ?? 'none',
2044
+ ...(dependency.rootIssueId ? { rootIssueId: dependency.rootIssueId } : {}),
2045
+ ...(dependency.rootIssueCode ? { rootIssueCode: dependency.rootIssueCode } : {}),
2046
+ },
2047
+ })),
2048
+ ];
2049
+ const { state: _ownershipState, components: _ownershipComponents, errors: _errors, sharedNative: _sharedNative, activation: _activation, extensions: _extensions, dependency: _dependency, dependencyReadiness: _dependencyReadiness, ...identity } = target;
2050
+ return {
2051
+ ...identity,
2052
+ scope: representativeScope,
2053
+ state,
2054
+ components,
2055
+ reasons: dedupedErrors,
2056
+ recoveryActions: statusRecovery({
2057
+ state,
2058
+ desired,
2059
+ platform: target.platform,
2060
+ pluginId: target.pluginId,
2061
+ ...(sharedNative ? { sharedNative } : {}),
2062
+ conflictRoots: rootIntentsForTarget({
2063
+ pluginId: target.pluginId,
2064
+ platform: target.platform,
2065
+ userIntent,
2066
+ projectIntent,
2067
+ available,
2068
+ }),
2069
+ errorCodes: dedupedErrors.map((error) => error.code),
2070
+ }),
2071
+ };
2072
+ };
2073
+ const codexGroups = new Map();
2074
+ const projectedTargets = [];
2075
+ for (const target of draftTargets) {
2076
+ if (target.platform !== 'codex') {
2077
+ projectedTargets.push(await decorateTarget(target, [target.scope], [target]));
2078
+ continue;
2079
+ }
2080
+ const group = codexGroups.get(target.pluginId) ?? [];
2081
+ group.push(target);
2082
+ codexGroups.set(target.pluginId, group);
2083
+ }
2084
+ for (const group of codexGroups.values()) {
2085
+ const scopes = [...new Set(group.map((target) => target.scope))].sort();
2086
+ projectedTargets.push(await decorateTarget(group[0], scopes, group));
2087
+ }
2088
+ projectedTargets.sort((left, right) => `${left.pluginId}\0${left.platform}\0${left.scope}`.localeCompare(`${right.pluginId}\0${right.platform}\0${right.scope}`, 'en'));
2089
+ const targetRevisions = projectedTargets.map((target) => {
2090
+ const entry = selectedByPluginId.get(target.pluginId);
2091
+ return {
2092
+ pluginId: target.pluginId,
2093
+ platform: target.platform,
2094
+ scope: target.scope,
2095
+ revision: projectTargetRevision(entry?.version, entry?.states[target.platform]?.[target.scope]?.installedVersion),
2096
+ };
2097
+ });
2098
+ const payload = {
2099
+ schemaVersion: 7,
2100
+ catalog: {
2101
+ primarySourceId: catalog.primarySourceId,
2102
+ configDigest: catalog.configDigest,
2103
+ compositeDigest: catalog.compositeDigest,
2104
+ ...(options.catalogOperationContext
2105
+ ? { generationSetDigest: options.catalogOperationContext.generationSetDigest }
2106
+ : {}),
2107
+ sources: catalog.sources.map((source) => {
2108
+ if (!('plugins' in source))
2109
+ return source;
2110
+ const { plugins: _plugins, ...projected } = source;
2111
+ return projected;
2112
+ }),
2113
+ },
2114
+ filters: {
2115
+ plugins: requested,
2116
+ platform: options.platform === undefined ? 'both' : parsePlatformValue(options.platform),
2117
+ ...(options.scope === undefined ? {} : { scope: parseScopeValue(options.scope) }),
2118
+ cwd: path.resolve(options.cwd),
2119
+ },
2120
+ targets: projectedTargets,
2121
+ errors,
2122
+ };
2123
+ const hasErrors = payload.catalog.sources.some((source) => source.error !== undefined)
2124
+ || payload.errors.length > 0
2125
+ || payload.targets.some((target) => target.reasons.some((reason) => reason.severity === 'blocking'));
2126
+ return {
2127
+ payload,
2128
+ output: options.json ? JSON.stringify(payload) : renderStatusV7(payload, options.verbose === true),
2129
+ hasErrors,
2130
+ targetRevisions,
2131
+ pluginSummaries: available.map((entry) => {
2132
+ const sourceEntries = available.filter((candidate) => candidate.source.id === entry.source.id);
2133
+ const byName = new Map(sourceEntries.map((candidate) => [candidate.name, candidate]));
2134
+ const transitive = new Set();
2135
+ const visit = (name) => {
2136
+ const candidate = byName.get(name);
2137
+ for (const dependency of candidate?.dependencies ?? []) {
2138
+ if (transitive.has(dependency))
2139
+ continue;
2140
+ transitive.add(dependency);
2141
+ visit(dependency);
2142
+ }
2143
+ };
2144
+ visit(entry.name);
2145
+ const dependencyIssueCount = targets.filter((target) => target.pluginId === formatPluginId({
2146
+ sourceId: entry.source.id,
2147
+ pluginName: entry.name,
2148
+ })).reduce((count, target) => count + target.errors.filter((error) => error.code.startsWith('dependency')
2149
+ || error.code === 'awCapabilityUnsupported'
2150
+ || error.code === 'sourceChanged').length, 0);
2151
+ return {
2152
+ pluginName: entry.name,
2153
+ pluginId: formatPluginId({ sourceId: entry.source.id, pluginName: entry.name }),
2154
+ displayName: entry.displayName,
2155
+ description: entry.shortDescription,
2156
+ version: entry.version,
2157
+ supportedTargets: {
2158
+ codex: ['user', 'project'].filter((scope) => entry.targets.codex[scope]),
2159
+ claude: ['user', 'project'].filter((scope) => entry.targets.claude[scope]),
2160
+ },
2161
+ configFieldCount: Object.keys(entry.configSchema ?? {}).length,
2162
+ ...(entry.configSchema ? { configSchema: entry.configSchema } : {}),
2163
+ ...(entry.configIssues ? { configIssues: entry.configIssues } : {}),
2164
+ ...(entry.configDiagnostic ? { configDiagnostic: entry.configDiagnostic } : {}),
2165
+ dependencyDirectCount: entry.dependencies.length,
2166
+ dependencyTotalCount: transitive.size,
2167
+ dependencyIssueCount,
2168
+ ...(entry.missingCapabilities
2169
+ ? { missingCapabilities: entry.missingCapabilities }
2170
+ : {}),
2171
+ };
2172
+ }),
2173
+ };
2174
+ }
2175
+ //# sourceMappingURL=status-v6.js.map