@lesliechan721/aw 0.1.0-beta.3 → 0.1.0-beta.30

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