@lesliechan721/aw 0.1.0-beta.5 → 0.1.0-beta.50

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 (566) 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/assets/aw-runtime-config.d.mts +13 -0
  4. package/dist/authoring/assets/aw-runtime-config.mjs +199 -0
  5. package/dist/authoring/assets/aw-runtime-config.mjs.map +1 -0
  6. package/dist/authoring/scripts/add-skill.mjs +4 -4
  7. package/dist/authoring/scripts/add-skill.mjs.map +1 -1
  8. package/dist/authoring/scripts/init-plugin.mjs +67 -97
  9. package/dist/authoring/scripts/init-plugin.mjs.map +1 -1
  10. package/dist/authoring/scripts/lib/plugin-root.mjs +4 -4
  11. package/dist/authoring/scripts/lib/plugin-root.mjs.map +1 -1
  12. package/dist/authoring/scripts/lib/plugin-version-check.d.mts +1 -0
  13. package/dist/authoring/scripts/lib/plugin-version-check.mjs +229 -8
  14. package/dist/authoring/scripts/lib/plugin-version-check.mjs.map +1 -1
  15. package/dist/authoring/scripts/lib/skill-scaffold.d.mts +77 -90
  16. package/dist/authoring/scripts/lib/skill-scaffold.mjs +99 -120
  17. package/dist/authoring/scripts/lib/skill-scaffold.mjs.map +1 -1
  18. package/dist/authoring/scripts/plugin-status.mjs +8 -11
  19. package/dist/authoring/scripts/plugin-status.mjs.map +1 -1
  20. package/dist/authoring/scripts/remove-plugin.mjs +3 -2
  21. package/dist/authoring/scripts/remove-plugin.mjs.map +1 -1
  22. package/dist/authoring/scripts/validate-plugin.mjs +346 -1131
  23. package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
  24. package/dist/scripts/aw-skill-eval-materializer.d.ts +26 -0
  25. package/dist/scripts/aw-skill-eval-materializer.js +306 -0
  26. package/dist/scripts/aw-skill-eval-materializer.js.map +1 -0
  27. package/dist/scripts/bundle-plugins.d.ts +1 -0
  28. package/dist/scripts/bundle-plugins.js +20 -5
  29. package/dist/scripts/bundle-plugins.js.map +1 -1
  30. package/dist/scripts/plugin-staging.d.ts +7 -9
  31. package/dist/scripts/plugin-staging.js +18 -29
  32. package/dist/scripts/plugin-staging.js.map +1 -1
  33. package/dist/scripts/test-plugin-scripts.d.ts +2 -0
  34. package/dist/scripts/test-plugin-scripts.js +47 -76
  35. package/dist/scripts/test-plugin-scripts.js.map +1 -1
  36. package/dist/scripts/test-workers.d.mts +24 -0
  37. package/dist/scripts/test-workers.mjs +59 -0
  38. package/dist/scripts/test-workers.mjs.map +1 -0
  39. package/dist/src/adapters/helpers.js +2 -2
  40. package/dist/src/adapters/helpers.js.map +1 -1
  41. package/dist/src/authoring/workspace-commands.d.ts +17 -1
  42. package/dist/src/authoring/workspace-commands.js +21 -4
  43. package/dist/src/authoring/workspace-commands.js.map +1 -1
  44. package/dist/src/commands/aw-capabilities.d.ts +78 -0
  45. package/dist/src/commands/aw-capabilities.js +264 -0
  46. package/dist/src/commands/aw-capabilities.js.map +1 -0
  47. package/dist/src/commands/catalog-dev-source.d.ts +154 -0
  48. package/dist/src/commands/catalog-dev-source.js +655 -0
  49. package/dist/src/commands/catalog-dev-source.js.map +1 -0
  50. package/dist/src/commands/catalog-generation.d.ts +21 -0
  51. package/dist/src/commands/catalog-generation.js +9 -0
  52. package/dist/src/commands/catalog-generation.js.map +1 -0
  53. package/dist/src/commands/catalog-publication-inspection.d.ts +71 -30
  54. package/dist/src/commands/catalog-publication-inspection.js +475 -63
  55. package/dist/src/commands/catalog-publication-inspection.js.map +1 -1
  56. package/dist/src/commands/catalog-publication-journal.d.ts +68 -0
  57. package/dist/src/commands/catalog-publication-journal.js +292 -0
  58. package/dist/src/commands/catalog-publication-journal.js.map +1 -0
  59. package/dist/src/commands/catalog-publication-target.d.ts +18 -0
  60. package/dist/src/commands/catalog-publication-target.js +95 -0
  61. package/dist/src/commands/catalog-publication-target.js.map +1 -0
  62. package/dist/src/commands/catalog-publish.d.ts +73 -15
  63. package/dist/src/commands/catalog-publish.js +701 -212
  64. package/dist/src/commands/catalog-publish.js.map +1 -1
  65. package/dist/src/commands/catalog-source.d.ts +60 -22
  66. package/dist/src/commands/catalog-source.js +311 -91
  67. package/dist/src/commands/catalog-source.js.map +1 -1
  68. package/dist/src/commands/catalog-status.d.ts +18 -22
  69. package/dist/src/commands/catalog-status.js +81 -115
  70. package/dist/src/commands/catalog-status.js.map +1 -1
  71. package/dist/src/commands/catalog-store.d.ts +104 -0
  72. package/dist/src/commands/catalog-store.js +685 -0
  73. package/dist/src/commands/catalog-store.js.map +1 -0
  74. package/dist/src/commands/catalog-workspace-resolution.d.ts +13 -0
  75. package/dist/src/commands/catalog-workspace-resolution.js +42 -0
  76. package/dist/src/commands/catalog-workspace-resolution.js.map +1 -0
  77. package/dist/src/commands/console.js +28 -17
  78. package/dist/src/commands/console.js.map +1 -1
  79. package/dist/src/commands/dependency-operation-plan.d.ts +52 -15
  80. package/dist/src/commands/dependency-operation-plan.js +289 -7
  81. package/dist/src/commands/dependency-operation-plan.js.map +1 -1
  82. package/dist/src/commands/init.d.ts +5 -11
  83. package/dist/src/commands/init.js +30 -51
  84. package/dist/src/commands/init.js.map +1 -1
  85. package/dist/src/commands/offline-cleanup-evidence.d.ts +67 -0
  86. package/dist/src/commands/offline-cleanup-evidence.js +181 -0
  87. package/dist/src/commands/offline-cleanup-evidence.js.map +1 -0
  88. package/dist/src/commands/operation-plan.d.ts +146 -0
  89. package/dist/src/commands/operation-plan.js +71 -0
  90. package/dist/src/commands/operation-plan.js.map +1 -0
  91. package/dist/src/commands/operation-planner.d.ts +46 -0
  92. package/dist/src/commands/operation-planner.js +141 -0
  93. package/dist/src/commands/operation-planner.js.map +1 -0
  94. package/dist/src/commands/options.d.ts +9 -7
  95. package/dist/src/commands/options.js +83 -21
  96. package/dist/src/commands/options.js.map +1 -1
  97. package/dist/src/commands/plugin-capabilities.js +23 -3
  98. package/dist/src/commands/plugin-capabilities.js.map +1 -1
  99. package/dist/src/commands/rebuild-command.d.ts +77 -31
  100. package/dist/src/commands/rebuild-command.js +4862 -729
  101. package/dist/src/commands/rebuild-command.js.map +1 -1
  102. package/dist/src/commands/rebuild-integration.d.ts +131 -21
  103. package/dist/src/commands/rebuild-integration.js +2866 -1339
  104. package/dist/src/commands/rebuild-integration.js.map +1 -1
  105. package/dist/src/commands/rebuild-operations.d.ts +58 -30
  106. package/dist/src/commands/rebuild-operations.js +260 -319
  107. package/dist/src/commands/rebuild-operations.js.map +1 -1
  108. package/dist/src/commands/reconcile-operation-plan.d.ts +28 -0
  109. package/dist/src/commands/reconcile-operation-plan.js +47 -0
  110. package/dist/src/commands/reconcile-operation-plan.js.map +1 -0
  111. package/dist/src/commands/review-inspection.d.ts +228 -0
  112. package/dist/src/commands/review-inspection.js +1341 -0
  113. package/dist/src/commands/review-inspection.js.map +1 -0
  114. package/dist/src/commands/review-preparation.d.ts +49 -0
  115. package/dist/src/commands/review-preparation.js +427 -0
  116. package/dist/src/commands/review-preparation.js.map +1 -0
  117. package/dist/src/commands/runtime.d.ts +1 -5
  118. package/dist/src/commands/runtime.js +24 -50
  119. package/dist/src/commands/runtime.js.map +1 -1
  120. package/dist/src/commands/skill-eval.d.ts +39 -0
  121. package/dist/src/commands/skill-eval.js +400 -0
  122. package/dist/src/commands/skill-eval.js.map +1 -0
  123. package/dist/src/commands/status-v6.d.ts +279 -0
  124. package/dist/src/commands/status-v6.js +2787 -0
  125. package/dist/src/commands/status-v6.js.map +1 -0
  126. package/dist/src/commands/sync-command.d.ts +40 -0
  127. package/dist/src/commands/sync-command.js +250 -0
  128. package/dist/src/commands/sync-command.js.map +1 -0
  129. package/dist/src/commands/wizard.d.ts +8 -5
  130. package/dist/src/commands/wizard.js +6 -4
  131. package/dist/src/commands/wizard.js.map +1 -1
  132. package/dist/src/commands/write-commands.d.ts +9 -3
  133. package/dist/src/commands/write-commands.js +127 -31
  134. package/dist/src/commands/write-commands.js.map +1 -1
  135. package/dist/src/constants.d.ts +7 -1
  136. package/dist/src/constants.js +7 -1
  137. package/dist/src/constants.js.map +1 -1
  138. package/dist/src/eval/manifest-v1.d.ts +71 -0
  139. package/dist/src/eval/manifest-v1.js +370 -0
  140. package/dist/src/eval/manifest-v1.js.map +1 -0
  141. package/dist/src/generators/local-plugin.d.ts +5 -1
  142. package/dist/src/generators/local-plugin.js +236 -109
  143. package/dist/src/generators/local-plugin.js.map +1 -1
  144. package/dist/src/index.d.ts +10 -4
  145. package/dist/src/index.js +1793 -486
  146. package/dist/src/index.js.map +1 -1
  147. package/dist/src/output/command-receipt.d.ts +43 -46
  148. package/dist/src/output/command-receipt.js +256 -80
  149. package/dist/src/output/command-receipt.js.map +1 -1
  150. package/dist/src/output/model.d.ts +3 -44
  151. package/dist/src/output/model.js +1 -144
  152. package/dist/src/output/model.js.map +1 -1
  153. package/dist/src/output/rebuild-progress.js +1 -13
  154. package/dist/src/output/rebuild-progress.js.map +1 -1
  155. package/dist/src/portable/commands.d.ts +46 -7
  156. package/dist/src/portable/commands.js +349 -37
  157. package/dist/src/portable/commands.js.map +1 -1
  158. package/dist/src/portable/materializer.d.ts +17 -4
  159. package/dist/src/portable/materializer.js +179 -41
  160. package/dist/src/portable/materializer.js.map +1 -1
  161. package/dist/src/portable/skills-cli.d.ts +15 -7
  162. package/dist/src/portable/skills-cli.js +74 -20
  163. package/dist/src/portable/skills-cli.js.map +1 -1
  164. package/dist/src/review/eval-source-input.d.ts +43 -0
  165. package/dist/src/review/eval-source-input.js +207 -0
  166. package/dist/src/review/eval-source-input.js.map +1 -0
  167. package/dist/src/review/review-profile.d.ts +17 -0
  168. package/dist/src/review/review-profile.js +234 -0
  169. package/dist/src/review/review-profile.js.map +1 -0
  170. package/dist/src/review/review-selection.d.ts +30 -0
  171. package/dist/src/review/review-selection.js +527 -0
  172. package/dist/src/review/review-selection.js.map +1 -0
  173. package/dist/src/review/review-types.d.ts +68 -0
  174. package/dist/src/review/review-types.js +16 -0
  175. package/dist/src/review/review-types.js.map +1 -0
  176. package/dist/src/review/skill-materialization.d.ts +13 -0
  177. package/dist/src/review/skill-materialization.js +75 -0
  178. package/dist/src/review/skill-materialization.js.map +1 -0
  179. package/dist/src/review/source-binding.d.ts +183 -0
  180. package/dist/src/review/source-binding.js +708 -0
  181. package/dist/src/review/source-binding.js.map +1 -0
  182. package/dist/src/tui/catalog-freshness.d.ts +1 -0
  183. package/dist/src/tui/catalog-freshness.js +2 -0
  184. package/dist/src/tui/catalog-freshness.js.map +1 -0
  185. package/dist/src/tui/catalog-generation.d.ts +21 -0
  186. package/dist/src/tui/catalog-generation.js +156 -0
  187. package/dist/src/tui/catalog-generation.js.map +1 -0
  188. package/dist/src/tui/catalog-sources/projection.d.ts +4 -0
  189. package/dist/src/tui/catalog-sources/projection.js +17 -0
  190. package/dist/src/tui/catalog-sources/projection.js.map +1 -0
  191. package/dist/src/tui/catalog-sources/review.d.ts +3 -0
  192. package/dist/src/tui/catalog-sources/review.js +13 -0
  193. package/dist/src/tui/catalog-sources/review.js.map +1 -0
  194. package/dist/src/tui/catalog-sources/screens.d.ts +12 -0
  195. package/dist/src/tui/catalog-sources/screens.js +40 -0
  196. package/dist/src/tui/catalog-sources/screens.js.map +1 -0
  197. package/dist/src/tui/catalog-sources/session.d.ts +32 -0
  198. package/dist/src/tui/catalog-sources/session.js +300 -0
  199. package/dist/src/tui/catalog-sources/session.js.map +1 -0
  200. package/dist/src/tui/catalog-sources/types.d.ts +54 -0
  201. package/dist/src/tui/catalog-sources/types.js +2 -0
  202. package/dist/src/tui/catalog-sources/types.js.map +1 -0
  203. package/dist/src/tui/catalog-store-task.d.ts +16 -0
  204. package/dist/src/tui/catalog-store-task.js +19 -0
  205. package/dist/src/tui/catalog-store-task.js.map +1 -0
  206. package/dist/src/tui/clipboard.d.ts +13 -0
  207. package/dist/src/tui/clipboard.js +95 -0
  208. package/dist/src/tui/clipboard.js.map +1 -0
  209. package/dist/src/tui/components.d.ts +110 -3
  210. package/dist/src/tui/components.js +183 -36
  211. package/dist/src/tui/components.js.map +1 -1
  212. package/dist/src/tui/config-array-draft.d.ts +29 -0
  213. package/dist/src/tui/config-array-draft.js +48 -0
  214. package/dist/src/tui/config-array-draft.js.map +1 -0
  215. package/dist/src/tui/config-leaf-editor.d.ts +16 -0
  216. package/dist/src/tui/config-leaf-editor.js +206 -0
  217. package/dist/src/tui/config-leaf-editor.js.map +1 -0
  218. package/dist/src/tui/config-value-presentation.d.ts +20 -0
  219. package/dist/src/tui/config-value-presentation.js +104 -0
  220. package/dist/src/tui/config-value-presentation.js.map +1 -0
  221. package/dist/src/tui/console-app-v4.d.ts +14 -4
  222. package/dist/src/tui/console-app-v4.js +8941 -1872
  223. package/dist/src/tui/console-app-v4.js.map +1 -1
  224. package/dist/src/tui/content-item-card.d.ts +13 -0
  225. package/dist/src/tui/content-item-card.js +51 -0
  226. package/dist/src/tui/content-item-card.js.map +1 -0
  227. package/dist/src/tui/controller-runtime.d.ts +10 -2
  228. package/dist/src/tui/controller-runtime.js +3211 -388
  229. package/dist/src/tui/controller-runtime.js.map +1 -1
  230. package/dist/src/tui/controller.d.ts +615 -45
  231. package/dist/src/tui/controller.js +3558 -768
  232. package/dist/src/tui/controller.js.map +1 -1
  233. package/dist/src/tui/dependency-graph-view.d.ts +39 -0
  234. package/dist/src/tui/dependency-graph-view.js +121 -0
  235. package/dist/src/tui/dependency-graph-view.js.map +1 -0
  236. package/dist/src/tui/dependency-graph.d.ts +81 -0
  237. package/dist/src/tui/dependency-graph.js +452 -0
  238. package/dist/src/tui/dependency-graph.js.map +1 -0
  239. package/dist/src/tui/diagnostic-projection.d.ts +23 -0
  240. package/dist/src/tui/diagnostic-projection.js +567 -0
  241. package/dist/src/tui/diagnostic-projection.js.map +1 -0
  242. package/dist/src/tui/diagnostics.d.ts +3 -3
  243. package/dist/src/tui/diagnostics.js +14 -2
  244. package/dist/src/tui/diagnostics.js.map +1 -1
  245. package/dist/src/tui/entity-cards.d.ts +55 -0
  246. package/dist/src/tui/entity-cards.js +220 -0
  247. package/dist/src/tui/entity-cards.js.map +1 -0
  248. package/dist/src/tui/glossary.d.ts +23 -0
  249. package/dist/src/tui/glossary.js +42 -0
  250. package/dist/src/tui/glossary.js.map +1 -0
  251. package/dist/src/tui/index.d.ts +6 -1
  252. package/dist/src/tui/index.js +5 -1
  253. package/dist/src/tui/index.js.map +1 -1
  254. package/dist/src/tui/input-display.d.ts +9 -0
  255. package/dist/src/tui/input-display.js +58 -0
  256. package/dist/src/tui/input-display.js.map +1 -0
  257. package/dist/src/tui/keys.d.ts +44 -0
  258. package/dist/src/tui/keys.js +43 -15
  259. package/dist/src/tui/keys.js.map +1 -1
  260. package/dist/src/tui/lifecycle-action-view.d.ts +6 -0
  261. package/dist/src/tui/lifecycle-action-view.js +36 -0
  262. package/dist/src/tui/lifecycle-action-view.js.map +1 -0
  263. package/dist/src/tui/model.d.ts +223 -31
  264. package/dist/src/tui/model.js +1510 -397
  265. package/dist/src/tui/model.js.map +1 -1
  266. package/dist/src/tui/operation-diagnostic-screens.d.ts +8 -0
  267. package/dist/src/tui/operation-diagnostic-screens.js +71 -0
  268. package/dist/src/tui/operation-diagnostic-screens.js.map +1 -0
  269. package/dist/src/tui/operation-history.d.ts +81 -0
  270. package/dist/src/tui/operation-history.js +136 -0
  271. package/dist/src/tui/operation-history.js.map +1 -0
  272. package/dist/src/tui/operation-review-planner.d.ts +21 -0
  273. package/dist/src/tui/operation-review-planner.js +1295 -0
  274. package/dist/src/tui/operation-review-planner.js.map +1 -0
  275. package/dist/src/tui/plugin-content.d.ts +31 -0
  276. package/dist/src/tui/plugin-content.js +680 -0
  277. package/dist/src/tui/plugin-content.js.map +1 -0
  278. package/dist/src/tui/plugin-detail.d.ts +52 -0
  279. package/dist/src/tui/plugin-detail.js +165 -0
  280. package/dist/src/tui/plugin-detail.js.map +1 -0
  281. package/dist/src/tui/plugin-write-task.d.ts +69 -0
  282. package/dist/src/tui/plugin-write-task.js +286 -0
  283. package/dist/src/tui/plugin-write-task.js.map +1 -0
  284. package/dist/src/tui/project-inventory.d.ts +68 -0
  285. package/dist/src/tui/project-inventory.js +203 -0
  286. package/dist/src/tui/project-inventory.js.map +1 -0
  287. package/dist/src/tui/prompt.js +4 -15
  288. package/dist/src/tui/prompt.js.map +1 -1
  289. package/dist/src/tui/query-header.d.ts +30 -0
  290. package/dist/src/tui/query-header.js +40 -0
  291. package/dist/src/tui/query-header.js.map +1 -0
  292. package/dist/src/tui/reader.d.ts +37 -0
  293. package/dist/src/tui/reader.js +47 -0
  294. package/dist/src/tui/reader.js.map +1 -0
  295. package/dist/src/tui/router.d.ts +197 -10
  296. package/dist/src/tui/router.js +338 -50
  297. package/dist/src/tui/router.js.map +1 -1
  298. package/dist/src/tui/screen-registry.d.ts +701 -0
  299. package/dist/src/tui/screen-registry.js +230 -0
  300. package/dist/src/tui/screen-registry.js.map +1 -0
  301. package/dist/src/tui/session-console-app.d.ts +6 -0
  302. package/dist/src/tui/session-console-app.js +13 -0
  303. package/dist/src/tui/session-console-app.js.map +1 -0
  304. package/dist/src/tui/session-host.d.ts +45 -0
  305. package/dist/src/tui/session-host.js +209 -0
  306. package/dist/src/tui/session-host.js.map +1 -0
  307. package/dist/src/tui/source-detail-card.d.ts +29 -0
  308. package/dist/src/tui/source-detail-card.js +45 -0
  309. package/dist/src/tui/source-detail-card.js.map +1 -0
  310. package/dist/src/tui/source-ref-presets.d.ts +3 -0
  311. package/dist/src/tui/source-ref-presets.js +11 -0
  312. package/dist/src/tui/source-ref-presets.js.map +1 -0
  313. package/dist/src/tui/theme.d.ts +12 -0
  314. package/dist/src/tui/theme.js +12 -0
  315. package/dist/src/tui/theme.js.map +1 -1
  316. package/dist/src/tui/viewport.d.ts +1 -0
  317. package/dist/src/tui/viewport.js +23 -0
  318. package/dist/src/tui/viewport.js.map +1 -1
  319. package/dist/src/tui/views.js +31 -3
  320. package/dist/src/tui/views.js.map +1 -1
  321. package/dist/src/tui/wizard.js +37 -13
  322. package/dist/src/tui/wizard.js.map +1 -1
  323. package/dist/src/types.d.ts +244 -20
  324. package/dist/src/types.js +1 -0
  325. package/dist/src/types.js.map +1 -1
  326. package/dist/src/utils/agent-version.d.ts +7 -1
  327. package/dist/src/utils/agent-version.js +41 -8
  328. package/dist/src/utils/agent-version.js.map +1 -1
  329. package/dist/src/utils/artifact-plan.d.ts +5 -4
  330. package/dist/src/utils/artifact-plan.js +18 -7
  331. package/dist/src/utils/artifact-plan.js.map +1 -1
  332. package/dist/src/utils/artifact-renderer.d.ts +17 -7
  333. package/dist/src/utils/artifact-renderer.js +214 -216
  334. package/dist/src/utils/artifact-renderer.js.map +1 -1
  335. package/dist/src/utils/artifact-request.d.ts +21 -0
  336. package/dist/src/utils/artifact-request.js +78 -0
  337. package/dist/src/utils/artifact-request.js.map +1 -0
  338. package/dist/src/utils/aw-home-mutation-lock.d.ts +1 -0
  339. package/dist/src/utils/aw-home-mutation-lock.js +32 -4
  340. package/dist/src/utils/aw-home-mutation-lock.js.map +1 -1
  341. package/dist/src/utils/bundle-integrity.d.ts +0 -1
  342. package/dist/src/utils/bundle-integrity.js +0 -25
  343. package/dist/src/utils/bundle-integrity.js.map +1 -1
  344. package/dist/src/utils/bundle-layout.js +22 -29
  345. package/dist/src/utils/bundle-layout.js.map +1 -1
  346. package/dist/src/utils/catalog-capability-projection.d.ts +8 -0
  347. package/dist/src/utils/catalog-capability-projection.js +14 -0
  348. package/dist/src/utils/catalog-capability-projection.js.map +1 -0
  349. package/dist/src/utils/catalog-digests.d.ts +10 -0
  350. package/dist/src/utils/catalog-digests.js +57 -20
  351. package/dist/src/utils/catalog-digests.js.map +1 -1
  352. package/dist/src/utils/catalog-generation-control-snapshot.d.ts +11 -0
  353. package/dist/src/utils/catalog-generation-control-snapshot.js +45 -0
  354. package/dist/src/utils/catalog-generation-control-snapshot.js.map +1 -0
  355. package/dist/src/utils/catalog-generation-error.d.ts +16 -0
  356. package/dist/src/utils/catalog-generation-error.js +30 -0
  357. package/dist/src/utils/catalog-generation-error.js.map +1 -0
  358. package/dist/src/utils/catalog-generation-resolver.d.ts +44 -0
  359. package/dist/src/utils/catalog-generation-resolver.js +273 -0
  360. package/dist/src/utils/catalog-generation-resolver.js.map +1 -0
  361. package/dist/src/utils/catalog-generation-service.d.ts +172 -0
  362. package/dist/src/utils/catalog-generation-service.js +1271 -0
  363. package/dist/src/utils/catalog-generation-service.js.map +1 -0
  364. package/dist/src/utils/catalog-generation-state.d.ts +22 -0
  365. package/dist/src/utils/catalog-generation-state.js +192 -0
  366. package/dist/src/utils/catalog-generation-state.js.map +1 -0
  367. package/dist/src/utils/catalog-generation-store.d.ts +58 -0
  368. package/dist/src/utils/catalog-generation-store.js +452 -0
  369. package/dist/src/utils/catalog-generation-store.js.map +1 -0
  370. package/dist/src/utils/catalog-manifest-v7.d.ts +5 -0
  371. package/dist/src/utils/{catalog-manifest-v4.js → catalog-manifest-v7.js} +35 -43
  372. package/dist/src/utils/catalog-manifest-v7.js.map +1 -0
  373. package/dist/src/utils/catalog-operation-context.d.ts +20 -0
  374. package/dist/src/utils/catalog-operation-context.js +142 -0
  375. package/dist/src/utils/catalog-operation-context.js.map +1 -0
  376. package/dist/src/utils/catalog-public-error.d.ts +7 -3
  377. package/dist/src/utils/catalog-public-error.js +28 -8
  378. package/dist/src/utils/catalog-public-error.js.map +1 -1
  379. package/dist/src/utils/catalog-runtime-projection.d.ts +3 -0
  380. package/dist/src/utils/catalog-runtime-projection.js +5 -40
  381. package/dist/src/utils/catalog-runtime-projection.js.map +1 -1
  382. package/dist/src/utils/catalog-snapshot.d.ts +5 -3
  383. package/dist/src/utils/catalog-snapshot.js +11 -3
  384. package/dist/src/utils/catalog-snapshot.js.map +1 -1
  385. package/dist/src/utils/catalog-source-identity.d.ts +1 -0
  386. package/dist/src/utils/catalog-source-identity.js +21 -2
  387. package/dist/src/utils/catalog-source-identity.js.map +1 -1
  388. package/dist/src/utils/catalog-source-impact.d.ts +21 -0
  389. package/dist/src/utils/catalog-source-impact.js +344 -0
  390. package/dist/src/utils/catalog-source-impact.js.map +1 -0
  391. package/dist/src/utils/catalog-source-references.d.ts +3 -2
  392. package/dist/src/utils/catalog-source-references.js +195 -347
  393. package/dist/src/utils/catalog-source-references.js.map +1 -1
  394. package/dist/src/utils/catalog-sources.d.ts +15 -1
  395. package/dist/src/utils/catalog-sources.js +206 -27
  396. package/dist/src/utils/catalog-sources.js.map +1 -1
  397. package/dist/src/utils/codex-config.d.ts +2 -0
  398. package/dist/src/utils/codex-config.js +26 -5
  399. package/dist/src/utils/codex-config.js.map +1 -1
  400. package/dist/src/utils/codex-manager.d.ts +79 -0
  401. package/dist/src/utils/codex-manager.js +747 -0
  402. package/dist/src/utils/codex-manager.js.map +1 -0
  403. package/dist/src/utils/codex-marketplace-path.d.ts +5 -0
  404. package/dist/src/utils/codex-marketplace-path.js +45 -0
  405. package/dist/src/utils/codex-marketplace-path.js.map +1 -0
  406. package/dist/src/utils/codex-native-observation.d.ts +49 -0
  407. package/dist/src/utils/codex-native-observation.js +154 -0
  408. package/dist/src/utils/codex-native-observation.js.map +1 -0
  409. package/dist/src/utils/codex-native-render-receipt.d.ts +40 -0
  410. package/dist/src/utils/codex-native-render-receipt.js +205 -0
  411. package/dist/src/utils/codex-native-render-receipt.js.map +1 -0
  412. package/dist/src/utils/codex-reconciler.d.ts +126 -0
  413. package/dist/src/utils/codex-reconciler.js +298 -0
  414. package/dist/src/utils/codex-reconciler.js.map +1 -0
  415. package/dist/src/utils/codex-shared-native.d.ts +43 -0
  416. package/dist/src/utils/codex-shared-native.js +81 -0
  417. package/dist/src/utils/codex-shared-native.js.map +1 -0
  418. package/dist/src/utils/codex-skill-staging.d.ts +2 -0
  419. package/dist/src/utils/codex-skill-staging.js.map +1 -1
  420. package/dist/src/utils/codex-surface-analysis.d.ts +46 -0
  421. package/dist/src/utils/codex-surface-analysis.js +247 -0
  422. package/dist/src/utils/codex-surface-analysis.js.map +1 -0
  423. package/dist/src/utils/dynamic-skill-tree.d.ts +4 -0
  424. package/dist/src/utils/dynamic-skill-tree.js +35 -5
  425. package/dist/src/utils/dynamic-skill-tree.js.map +1 -1
  426. package/dist/src/utils/git-catalog-provider.d.ts +16 -0
  427. package/dist/src/utils/git-catalog-provider.js +177 -145
  428. package/dist/src/utils/git-catalog-provider.js.map +1 -1
  429. package/dist/src/utils/local-marketplace.d.ts +18 -1
  430. package/dist/src/utils/local-marketplace.js +354 -84
  431. package/dist/src/utils/local-marketplace.js.map +1 -1
  432. package/dist/src/utils/manifest.d.ts +1 -3
  433. package/dist/src/utils/manifest.js +1 -3
  434. package/dist/src/utils/manifest.js.map +1 -1
  435. package/dist/src/utils/multi-source-catalog.d.ts +3 -9
  436. package/dist/src/utils/multi-source-catalog.js +54 -110
  437. package/dist/src/utils/multi-source-catalog.js.map +1 -1
  438. package/dist/src/utils/native-cli.d.ts +55 -7
  439. package/dist/src/utils/native-cli.js +400 -58
  440. package/dist/src/utils/native-cli.js.map +1 -1
  441. package/dist/src/utils/orphan-marketplace-cleanup.js +0 -4
  442. package/dist/src/utils/orphan-marketplace-cleanup.js.map +1 -1
  443. package/dist/src/utils/ownership.d.ts +84 -20
  444. package/dist/src/utils/ownership.js +179 -222
  445. package/dist/src/utils/ownership.js.map +1 -1
  446. package/dist/src/utils/path-catalog-provider.d.ts +1 -1
  447. package/dist/src/utils/path-catalog-provider.js +54 -65
  448. package/dist/src/utils/path-catalog-provider.js.map +1 -1
  449. package/dist/src/utils/paths.d.ts +0 -1
  450. package/dist/src/utils/paths.js +0 -1
  451. package/dist/src/utils/paths.js.map +1 -1
  452. package/dist/src/utils/plugin-config-impact.d.ts +33 -0
  453. package/dist/src/utils/plugin-config-impact.js +298 -0
  454. package/dist/src/utils/plugin-config-impact.js.map +1 -0
  455. package/dist/src/utils/plugin-config-write.d.ts +52 -27
  456. package/dist/src/utils/plugin-config-write.js +1000 -296
  457. package/dist/src/utils/plugin-config-write.js.map +1 -1
  458. package/dist/src/utils/plugin-config.d.ts +153 -93
  459. package/dist/src/utils/plugin-config.js +1116 -968
  460. package/dist/src/utils/plugin-config.js.map +1 -1
  461. package/dist/src/utils/plugin-intent-state.d.ts +49 -0
  462. package/dist/src/utils/plugin-intent-state.js +320 -0
  463. package/dist/src/utils/plugin-intent-state.js.map +1 -0
  464. package/dist/src/utils/plugin-scripts.d.ts +65 -125
  465. package/dist/src/utils/plugin-scripts.js +484 -524
  466. package/dist/src/utils/plugin-scripts.js.map +1 -1
  467. package/dist/src/utils/process-tree.d.ts +2 -2
  468. package/dist/src/utils/process-tree.js +1 -1
  469. package/dist/src/utils/process-tree.js.map +1 -1
  470. package/dist/src/utils/project-boundary.d.ts +11 -13
  471. package/dist/src/utils/project-boundary.js +28 -34
  472. package/dist/src/utils/project-boundary.js.map +1 -1
  473. package/dist/src/utils/runtime-config.d.ts +20 -0
  474. package/dist/src/utils/runtime-config.js +75 -0
  475. package/dist/src/utils/runtime-config.js.map +1 -0
  476. package/dist/src/utils/safe-fs.d.ts +21 -0
  477. package/dist/src/utils/safe-fs.js +111 -0
  478. package/dist/src/utils/safe-fs.js.map +1 -0
  479. package/dist/src/utils/safe-operation-diagnostic.d.ts +15 -0
  480. package/dist/src/utils/safe-operation-diagnostic.js +33 -0
  481. package/dist/src/utils/safe-operation-diagnostic.js.map +1 -0
  482. package/dist/src/utils/sensitive-content.d.ts +4 -0
  483. package/dist/src/utils/sensitive-content.js +36 -0
  484. package/dist/src/utils/sensitive-content.js.map +1 -0
  485. package/dist/src/utils/state-paths.js +7 -2
  486. package/dist/src/utils/state-paths.js.map +1 -1
  487. package/dist/src/utils/target-eligibility.d.ts +8 -2
  488. package/dist/src/utils/target-eligibility.js +17 -8
  489. package/dist/src/utils/target-eligibility.js.map +1 -1
  490. package/dist/src/utils/windows-claude-shim.d.ts +7 -0
  491. package/dist/src/utils/windows-claude-shim.js +10 -0
  492. package/dist/src/utils/windows-claude-shim.js.map +1 -0
  493. package/dist/src/utils/windows-npm-shim.d.ts +14 -0
  494. package/dist/src/utils/windows-npm-shim.js +140 -0
  495. package/dist/src/utils/windows-npm-shim.js.map +1 -0
  496. package/dist/vitest.config.js +92 -10
  497. package/dist/vitest.config.js.map +1 -1
  498. package/package.json +27 -18
  499. package/dist/authoring/scripts/check-plugin-versions.d.mts +0 -2
  500. package/dist/authoring/scripts/check-plugin-versions.mjs +0 -5
  501. package/dist/authoring/scripts/check-plugin-versions.mjs.map +0 -1
  502. package/dist/scripts/aw-skill-eval-engine.d.ts +0 -13
  503. package/dist/scripts/aw-skill-eval-engine.js +0 -31
  504. package/dist/scripts/aw-skill-eval-engine.js.map +0 -1
  505. package/dist/scripts/codex-eval-app-server.d.ts +0 -89
  506. package/dist/scripts/codex-eval-app-server.js +0 -1228
  507. package/dist/scripts/codex-eval-app-server.js.map +0 -1
  508. package/dist/scripts/codex-eval-isolation.d.ts +0 -61
  509. package/dist/scripts/codex-eval-isolation.js +0 -318
  510. package/dist/scripts/codex-eval-isolation.js.map +0 -1
  511. package/dist/scripts/codex-eval-process-management.d.ts +0 -8
  512. package/dist/scripts/codex-eval-process-management.js +0 -69
  513. package/dist/scripts/codex-eval-process-management.js.map +0 -1
  514. package/dist/scripts/codex-eval-process-tree.d.ts +0 -38
  515. package/dist/scripts/codex-eval-process-tree.js +0 -803
  516. package/dist/scripts/codex-eval-process-tree.js.map +0 -1
  517. package/dist/scripts/codex-eval-runtime-config.d.ts +0 -62
  518. package/dist/scripts/codex-eval-runtime-config.js +0 -843
  519. package/dist/scripts/codex-eval-runtime-config.js.map +0 -1
  520. package/dist/scripts/codex-trigger-eval.d.ts +0 -84
  521. package/dist/scripts/codex-trigger-eval.js +0 -968
  522. package/dist/scripts/codex-trigger-eval.js.map +0 -1
  523. package/dist/scripts/eval-plugin-skills-audited.d.ts +0 -6
  524. package/dist/scripts/eval-plugin-skills-audited.js +0 -261
  525. package/dist/scripts/eval-plugin-skills-audited.js.map +0 -1
  526. package/dist/scripts/eval-plugin-skills.d.ts +0 -45
  527. package/dist/scripts/eval-plugin-skills.js +0 -1586
  528. package/dist/scripts/eval-plugin-skills.js.map +0 -1
  529. package/dist/scripts/eval-run-layout.d.ts +0 -17
  530. package/dist/scripts/eval-run-layout.js +0 -26
  531. package/dist/scripts/eval-run-layout.js.map +0 -1
  532. package/dist/scripts/plugin-eval-contract.d.ts +0 -185
  533. package/dist/scripts/plugin-eval-contract.js +0 -695
  534. package/dist/scripts/plugin-eval-contract.js.map +0 -1
  535. package/dist/scripts/plugin-eval-materializer.d.ts +0 -13
  536. package/dist/scripts/plugin-eval-materializer.js +0 -421
  537. package/dist/scripts/plugin-eval-materializer.js.map +0 -1
  538. package/dist/scripts/skill-reporting.d.ts +0 -212
  539. package/dist/scripts/skill-reporting.js +0 -922
  540. package/dist/scripts/skill-reporting.js.map +0 -1
  541. package/dist/src/commands/status-v4.d.ts +0 -123
  542. package/dist/src/commands/status-v4.js +0 -905
  543. package/dist/src/commands/status-v4.js.map +0 -1
  544. package/dist/src/commands/status.d.ts +0 -93
  545. package/dist/src/commands/status.js +0 -442
  546. package/dist/src/commands/status.js.map +0 -1
  547. package/dist/src/utils/active-marketplace-runtime-lock.d.ts +0 -12
  548. package/dist/src/utils/active-marketplace-runtime-lock.js +0 -133
  549. package/dist/src/utils/active-marketplace-runtime-lock.js.map +0 -1
  550. package/dist/src/utils/catalog-manifest-v3.d.ts +0 -2
  551. package/dist/src/utils/catalog-manifest-v3.js +0 -3
  552. package/dist/src/utils/catalog-manifest-v3.js.map +0 -1
  553. package/dist/src/utils/catalog-manifest-v4.d.ts +0 -5
  554. package/dist/src/utils/catalog-manifest-v4.js.map +0 -1
  555. package/dist/src/utils/catalog-source-cache.d.ts +0 -62
  556. package/dist/src/utils/catalog-source-cache.js +0 -296
  557. package/dist/src/utils/catalog-source-cache.js.map +0 -1
  558. package/dist/src/utils/codex-project-surface.d.ts +0 -3
  559. package/dist/src/utils/codex-project-surface.js +0 -49
  560. package/dist/src/utils/codex-project-surface.js.map +0 -1
  561. package/dist/src/utils/lifecycle-active-store.d.ts +0 -175
  562. package/dist/src/utils/lifecycle-active-store.js +0 -1276
  563. package/dist/src/utils/lifecycle-active-store.js.map +0 -1
  564. package/dist/src/utils/plugin-release.d.ts +0 -2
  565. package/dist/src/utils/plugin-release.js +0 -2
  566. package/dist/src/utils/plugin-release.js.map +0 -1
@@ -0,0 +1,1341 @@
1
+ import path from 'node:path';
2
+ import { canonicalJson, computeCaseCorpusDigest, computeSkillDigest, } from '@lesliechan721/agent-skill-eval';
3
+ import { calculateCatalogWorkspaceSourceIdentity, DEFAULT_CATALOG_OUTPUT_PATH, GENERATED_OUTPUT_MARKER_FILENAME, readCatalogWorkspace, resolveSupportedPlatforms, validateCatalogSnapshotComplete, } from '@lesliechan721/aw-plugin-core';
4
+ import fs from 'fs-extra';
5
+ import { readAwSkillEvalManifest, } from '../eval/manifest-v1.js';
6
+ import { CLI_RESERVED_IMPORTS } from '../utils/manifest.js';
7
+ import { resolveCatalogWorkspaceRoot, } from './catalog-workspace-resolution.js';
8
+ import { computeReviewComponentDigest } from './review-publication.js';
9
+ import { computeAwSourceBindingSelectedCasesDigest, computeAwSourceBindingSuiteDefaultsDigest, readAwSourceBinding, resolvePortablePluginProfileConfig, resolveEvalProfileBindingInput, selectAwSourceBindingEvalCases, validateAwSourceBindingForWorkspace, } from '../review/source-binding.js';
10
+ import { resolveReviewDynamicSkillSource, resolveReviewSelection, reviewBindingMatchesSelection, } from '../review/review-selection.js';
11
+ import { resolveEffectivePluginConfigFromStores, } from '../utils/plugin-config.js';
12
+ export class ReviewInspectionInputError extends Error {
13
+ code;
14
+ exitCode = 2;
15
+ constructor(code, message) {
16
+ super(`${code}: ${message}`);
17
+ this.name = 'ReviewInspectionInputError';
18
+ this.code = code;
19
+ }
20
+ }
21
+ class ReviewInspectionResolvedTargetError extends Error {
22
+ code;
23
+ exitCode;
24
+ reviewTarget;
25
+ constructor(error, target) {
26
+ super(error instanceof Error ? error.message : String(error), { cause: error });
27
+ this.name = 'ReviewInspectionResolvedTargetError';
28
+ this.code = getReviewInspectionErrorCode(error);
29
+ this.exitCode = getReviewInspectionExitCode(error);
30
+ this.reviewTarget = target;
31
+ }
32
+ }
33
+ const compareText = (left, right) => left < right ? -1 : left > right ? 1 : 0;
34
+ function stripDotSlash(value) {
35
+ return value.startsWith('./') ? value.slice(2) : value;
36
+ }
37
+ function relativeWorkspacePath(workspaceRoot, filePath) {
38
+ return path.relative(workspaceRoot, filePath).split(path.sep).join('/') || '.';
39
+ }
40
+ function sourceKey(options) {
41
+ const sourcePaths = options.roots.map((root) => relativeWorkspacePath(options.workspaceRoot, root));
42
+ const sourceIdentity = encodeURIComponent(JSON.stringify({
43
+ primary: sourcePaths[0],
44
+ sources: [...sourcePaths].sort(compareText),
45
+ }));
46
+ return `source:${options.plugin}:${options.skill}:${options.kind}:${sourceIdentity}`;
47
+ }
48
+ function requiredFinalKey(seed) {
49
+ return [
50
+ 'final',
51
+ seed.plugin.manifest.name,
52
+ seed.skill,
53
+ seed.profile,
54
+ seed.targetId ?? 'static',
55
+ ].join(':');
56
+ }
57
+ function materializationIdentityKey(options) {
58
+ return [
59
+ options.plugin,
60
+ options.skill,
61
+ options.profile,
62
+ options.materializationProfile.kind,
63
+ options.materializationProfile.id,
64
+ options.materializationProfile.inputDigest,
65
+ ].join(':');
66
+ }
67
+ function scopeFromProfile(profile) {
68
+ return profile.endsWith('-project') ? 'project' : 'user';
69
+ }
70
+ function finalProfileFromBinding(profile) {
71
+ if (profile.kind === 'eval')
72
+ return `codex-${profile.scope}`;
73
+ if (profile.kind === 'portable')
74
+ return `agent-skills-${profile.scope}`;
75
+ return `${profile.platform}-${profile.scope}`;
76
+ }
77
+ async function directSkillDirectories(root) {
78
+ const entries = await fs.readdir(root, { withFileTypes: true });
79
+ const result = [];
80
+ for (const entry of entries.sort((left, right) => compareText(left.name, right.name))) {
81
+ const entryPath = path.join(root, entry.name);
82
+ const stat = await fs.lstat(entryPath);
83
+ if (stat.isSymbolicLink() || !stat.isDirectory()) {
84
+ throw new Error(`Skill collection direct child must be a regular directory: ${entryPath}`);
85
+ }
86
+ result.push({ name: entry.name, root: await fs.realpath(entryPath) });
87
+ }
88
+ return result;
89
+ }
90
+ function pluginImports(plugin) {
91
+ return [
92
+ ...(plugin.manifest.buildConfig?.buildImports ?? []).map((entry) => ({
93
+ purpose: 'build',
94
+ provider: entry.plugin,
95
+ export: entry.export,
96
+ consumer: entry.env,
97
+ })),
98
+ ...(plugin.manifest.buildConfig?.skillRuntimeFiles ?? []).flatMap((entry) => entry.import ? [{
99
+ purpose: 'skill-runtime-file',
100
+ provider: entry.import.plugin,
101
+ export: entry.import.export,
102
+ consumer: `${entry.skill}/${entry.target}`,
103
+ }] : []),
104
+ ...(plugin.manifest.artifacts?.targets ?? []).flatMap((target) => (target.runtimeImports ?? []).map((entry) => ({
105
+ purpose: 'artifact-runtime',
106
+ provider: entry.plugin,
107
+ export: entry.export,
108
+ consumer: `${target.id}/${entry.name}`,
109
+ }))),
110
+ ].sort((left, right) => compareText(`${left.purpose}\0${left.consumer}\0${left.provider}\0${left.export}`, `${right.purpose}\0${right.consumer}\0${right.provider}\0${right.export}`));
111
+ }
112
+ async function inspectSnapshot(workspace, workspaceSourceIdentity) {
113
+ const snapshotPath = path.join(workspace.workspaceRoot, DEFAULT_CATALOG_OUTPUT_PATH);
114
+ if (!await fs.pathExists(snapshotPath)) {
115
+ return {
116
+ receipt: {
117
+ path: snapshotPath,
118
+ state: 'absent',
119
+ catalogVersion: null,
120
+ snapshotDigest: null,
121
+ workspaceIdentity: null,
122
+ sourceIdentity: null,
123
+ },
124
+ entries: new Map(),
125
+ root: null,
126
+ };
127
+ }
128
+ try {
129
+ const [validation, marker] = await Promise.all([
130
+ validateCatalogSnapshotComplete(snapshotPath),
131
+ fs.readJson(path.join(snapshotPath, GENERATED_OUTPUT_MARKER_FILENAME)),
132
+ ]);
133
+ const current = marker.workspaceIdentity === workspace.workspaceIdentity
134
+ && marker.sourceIdentity === workspaceSourceIdentity;
135
+ return {
136
+ receipt: {
137
+ path: snapshotPath,
138
+ state: current ? 'current' : 'stale',
139
+ catalogVersion: validation.manifest.catalogVersion,
140
+ snapshotDigest: validation.snapshotDigest,
141
+ workspaceIdentity: marker.workspaceIdentity,
142
+ sourceIdentity: marker.sourceIdentity,
143
+ },
144
+ entries: new Map(validation.manifest.entries.map((entry) => [entry.name, entry])),
145
+ root: current ? validation.rootDir : null,
146
+ };
147
+ }
148
+ catch {
149
+ return {
150
+ receipt: {
151
+ path: snapshotPath,
152
+ state: 'invalid',
153
+ catalogVersion: null,
154
+ snapshotDigest: null,
155
+ workspaceIdentity: null,
156
+ sourceIdentity: null,
157
+ },
158
+ entries: new Map(),
159
+ root: null,
160
+ };
161
+ }
162
+ }
163
+ async function addSourceSubject(options) {
164
+ const key = sourceKey({
165
+ workspaceRoot: options.workspace.workspaceRoot,
166
+ plugin: options.plugin.manifest.name,
167
+ skill: options.skill,
168
+ kind: options.kind,
169
+ roots: options.sourceRoots ?? [options.root],
170
+ });
171
+ if (options.subjects.some((subject) => subject.key === key))
172
+ return key;
173
+ const digest = options.kind === 'artifact-source'
174
+ ? (await computeReviewComponentDigest({
175
+ repoRoot: options.workspace.workspaceRoot,
176
+ path: options.root,
177
+ })).digest
178
+ : await computeSkillDigest(options.root);
179
+ options.subjects.push({
180
+ key,
181
+ kind: options.kind,
182
+ plugin: options.plugin.manifest.name,
183
+ skill: options.skill,
184
+ path: options.root,
185
+ profile: null,
186
+ digest,
187
+ origin: 'workspace',
188
+ });
189
+ return key;
190
+ }
191
+ async function inventoryPluginSource(options) {
192
+ const { workspace, plugin, subjects } = options;
193
+ const nativeSkills = plugin.manifest.skills
194
+ ? await directSkillDirectories(path.join(plugin.rootDir, stripDotSlash(plugin.manifest.skills)))
195
+ : [];
196
+ const portableSkills = plugin.manifest.distributions?.agentSkills?.skills
197
+ ? await directSkillDirectories(path.join(plugin.rootDir, stripDotSlash(plugin.manifest.distributions.agentSkills.skills)))
198
+ : [];
199
+ const nativeDynamicByPlatform = new Map([
200
+ ['claude', new Set()],
201
+ ['codex', new Set()],
202
+ ]);
203
+ const portableDynamic = new Set();
204
+ const sourceSubjectKeys = [];
205
+ const seeds = [];
206
+ for (const target of plugin.manifest.artifacts?.targets ?? []) {
207
+ if (!['codex.skill', 'claude.skill', 'agent-skills.skill'].includes(target.target))
208
+ continue;
209
+ const skill = target.skillKey;
210
+ if (target.target === 'agent-skills.skill')
211
+ portableDynamic.add(skill);
212
+ else
213
+ nativeDynamicByPlatform.get(target.target === 'codex.skill' ? 'codex' : 'claude').add(skill);
214
+ }
215
+ for (const skill of nativeSkills) {
216
+ sourceSubjectKeys.push(await addSourceSubject({
217
+ workspace,
218
+ subjects,
219
+ plugin,
220
+ skill: skill.name,
221
+ root: skill.root,
222
+ kind: 'source-skill',
223
+ }));
224
+ }
225
+ for (const skill of portableSkills) {
226
+ sourceSubjectKeys.push(await addSourceSubject({
227
+ workspace,
228
+ subjects,
229
+ plugin,
230
+ skill: skill.name,
231
+ root: skill.root,
232
+ kind: 'portable-source-skill',
233
+ }));
234
+ }
235
+ for (const platform of [...resolveSupportedPlatforms(plugin.manifest)].sort(compareText)) {
236
+ for (const skill of nativeSkills) {
237
+ if (nativeDynamicByPlatform.get(platform).has(skill.name))
238
+ continue;
239
+ for (const scope of ['project', 'user']) {
240
+ seeds.push({
241
+ plugin,
242
+ skill: skill.name,
243
+ profile: `${platform}-${scope}`,
244
+ targetId: null,
245
+ sourceSubjectKey: sourceKey({
246
+ workspaceRoot: workspace.workspaceRoot,
247
+ plugin: plugin.manifest.name,
248
+ skill: skill.name,
249
+ kind: 'source-skill',
250
+ roots: [skill.root],
251
+ }),
252
+ dynamic: false,
253
+ });
254
+ }
255
+ }
256
+ }
257
+ if (plugin.manifest.distributions?.agentSkills) {
258
+ for (const skill of portableSkills) {
259
+ if (portableDynamic.has(skill.name))
260
+ continue;
261
+ for (const scope of ['project', 'user']) {
262
+ seeds.push({
263
+ plugin,
264
+ skill: skill.name,
265
+ profile: `agent-skills-${scope}`,
266
+ targetId: null,
267
+ sourceSubjectKey: sourceKey({
268
+ workspaceRoot: workspace.workspaceRoot,
269
+ plugin: plugin.manifest.name,
270
+ skill: skill.name,
271
+ kind: 'portable-source-skill',
272
+ roots: [skill.root],
273
+ }),
274
+ dynamic: false,
275
+ });
276
+ }
277
+ }
278
+ }
279
+ for (const target of plugin.manifest.artifacts?.targets ?? []) {
280
+ if (!['codex.skill', 'claude.skill', 'agent-skills.skill'].includes(target.target))
281
+ continue;
282
+ const skill = target.skillKey;
283
+ const platform = target.target === 'agent-skills.skill'
284
+ ? 'agent-skills'
285
+ : target.target === 'codex.skill' ? 'codex' : 'claude';
286
+ const source = await resolveReviewDynamicSkillSource({
287
+ plugin,
288
+ target,
289
+ nativeSkillPaths: nativeSkills.map((entry) => entry.root),
290
+ portableSkillPaths: portableSkills.map((entry) => entry.root),
291
+ });
292
+ const sourceSubjectKey = await addSourceSubject({
293
+ workspace,
294
+ subjects,
295
+ plugin,
296
+ skill,
297
+ root: source.sourcePath,
298
+ sourceRoots: source.sourcePaths,
299
+ kind: source.sourceKind,
300
+ });
301
+ sourceSubjectKeys.push(sourceSubjectKey);
302
+ for (const scope of target.scopes) {
303
+ seeds.push({
304
+ plugin,
305
+ skill,
306
+ profile: `${platform}-${scope}`,
307
+ targetId: target.id,
308
+ sourceSubjectKey,
309
+ dynamic: true,
310
+ });
311
+ }
312
+ }
313
+ return {
314
+ seeds: seeds.sort((left, right) => compareText(requiredFinalKey(left), requiredFinalKey(right))),
315
+ sourceSubjectKeys: [...new Set(sourceSubjectKeys)].sort(compareText),
316
+ };
317
+ }
318
+ function releaseCases(suite, document, runs) {
319
+ const splits = new Set(suite.releaseSplits ?? []);
320
+ return document.cases
321
+ .filter((entry) => splits.size === 0 || splits.has('all') || splits.has(entry.split))
322
+ .map((entry) => ({ id: entry.id, split: entry.split, minimumRuns: runs }))
323
+ .sort((left, right) => compareText(left.id, right.id));
324
+ }
325
+ async function inventoryRequiredEvals(options) {
326
+ const required = [];
327
+ const caseDigests = new Map();
328
+ const bySkill = new Map();
329
+ for (const seed of options.seeds) {
330
+ const key = `${seed.plugin.manifest.name}\0${seed.skill}`;
331
+ bySkill.set(key, [...(bySkill.get(key) ?? []), seed]);
332
+ }
333
+ for (const seeds of bySkill.values()) {
334
+ const first = seeds[0];
335
+ const manifestPath = path.join(first.plugin.rootDir, 'skills', first.skill, 'evals', 'manifest.json');
336
+ if (!await fs.pathExists(manifestPath))
337
+ continue;
338
+ let loaded;
339
+ try {
340
+ loaded = await readAwSkillEvalManifest({ plugin: first.plugin, skill: first.skill });
341
+ }
342
+ catch (error) {
343
+ options.issues.push({
344
+ category: 'invalid',
345
+ code: 'evalManifestInvalid',
346
+ message: error instanceof Error ? error.message : String(error),
347
+ blocking: true,
348
+ path: relativeWorkspacePath(options.workspace.workspaceRoot, manifestPath),
349
+ });
350
+ continue;
351
+ }
352
+ const requiredSuites = loaded.manifest.suites.filter((suite) => suite.requiredForRelease === true);
353
+ const profileBindings = new Map();
354
+ const invalidProfileIds = new Set();
355
+ const codexSeeds = seeds.filter((seed) => seed.profile.startsWith('codex-'));
356
+ for (const suite of requiredSuites) {
357
+ const accepted = suite.profiles ? new Set(suite.profiles) : null;
358
+ const suiteProfiles = loaded.manifest.profiles.filter((profile) => !accepted || accepted.has(profile.id));
359
+ for (const profile of suiteProfiles) {
360
+ if (!profileBindings.has(profile.id) && !invalidProfileIds.has(profile.id)) {
361
+ try {
362
+ profileBindings.set(profile.id, resolveEvalProfileBindingInput(profile, options.workspace.plugins));
363
+ }
364
+ catch (error) {
365
+ invalidProfileIds.add(profile.id);
366
+ options.issues.push({
367
+ category: 'invalid',
368
+ code: 'evalProfileInvalid',
369
+ message: error instanceof Error ? error.message : String(error),
370
+ blocking: true,
371
+ path: relativeWorkspacePath(options.workspace.workspaceRoot, manifestPath),
372
+ });
373
+ }
374
+ }
375
+ const profileBinding = profileBindings.get(profile.id);
376
+ if (!profileBinding)
377
+ continue;
378
+ const matchingSeeds = codexSeeds.filter((seed) => scopeFromProfile(seed.profile) === profile.scope);
379
+ if (matchingSeeds.length === 0) {
380
+ options.issues.push({
381
+ category: 'unsupported',
382
+ code: 'requiredEvalTargetUnsupported',
383
+ message: `Required Eval ${first.plugin.manifest.name}/${first.skill}/${suite.id}/${profile.id} has no declared Codex ${profile.scope} final.`,
384
+ blocking: true,
385
+ path: relativeWorkspacePath(options.workspace.workspaceRoot, manifestPath),
386
+ });
387
+ continue;
388
+ }
389
+ const document = loaded.casesBySuite.get(suite.id);
390
+ const casesPath = path.join(loaded.evalRoot, suite.cases);
391
+ const runs = suite.runs ?? loaded.manifest.defaults.runs ?? 1;
392
+ const timeoutMs = suite.timeoutMs ?? loaded.manifest.defaults.timeoutMs ?? null;
393
+ let casesDigest = caseDigests.get(casesPath);
394
+ if (!casesDigest) {
395
+ casesDigest = await computeCaseCorpusDigest([casesPath]);
396
+ caseDigests.set(casesPath, casesDigest);
397
+ }
398
+ const minimumPassRate = typeof document.suite.runtime?.minimumPassRate === 'number'
399
+ ? document.suite.runtime.minimumPassRate
400
+ : 1;
401
+ const selected = releaseCases(suite, document, runs);
402
+ const selectedDocument = selected.length === 0
403
+ ? { ...document, cases: [] }
404
+ : selectAwSourceBindingEvalCases(document, {
405
+ caseIds: selected.map((entry) => entry.id),
406
+ });
407
+ for (const seed of matchingSeeds) {
408
+ const finalKey = requiredFinalKey(seed);
409
+ required.push({
410
+ key: `eval:${finalKey}:${profile.id}:${suite.id}`,
411
+ plugin: first.plugin.manifest.name,
412
+ skill: first.skill,
413
+ finalProfile: seed.profile,
414
+ requiredFinalKey: finalKey,
415
+ evalProfile: {
416
+ id: profile.id,
417
+ scope: profile.scope,
418
+ inputDigest: profileBinding.profile.inputDigest,
419
+ plugins: profileBinding.materializationProfile.plugins
420
+ .map((entry) => entry.name)
421
+ .sort(compareText),
422
+ },
423
+ suite: {
424
+ id: suite.id,
425
+ kind: suite.kind,
426
+ provider: suite.provider ?? null,
427
+ suiteDefaultsDigest: computeAwSourceBindingSuiteDefaultsDigest(suite, loaded.manifest.defaults),
428
+ },
429
+ cases: {
430
+ sourcePath: relativeWorkspacePath(options.workspace.workspaceRoot, casesPath),
431
+ sourceCorpusDigest: casesDigest,
432
+ selectedCasesDigest: computeAwSourceBindingSelectedCasesDigest(selectedDocument),
433
+ selected,
434
+ },
435
+ runs,
436
+ timeoutMs,
437
+ minimumPassRate,
438
+ processManagement: suite.releaseProcessManagement ?? 'managed-only',
439
+ materializedFinalKeys: [],
440
+ verifiedBindingPaths: [],
441
+ });
442
+ }
443
+ }
444
+ }
445
+ }
446
+ return required.sort((left, right) => compareText(left.key, right.key));
447
+ }
448
+ async function resolveTarget(options) {
449
+ if (options.target === 'catalog') {
450
+ return {
451
+ kind: 'catalog',
452
+ id: options.workspace.workspaceIdentity,
453
+ path: options.workspace.workspaceRoot,
454
+ plugins: options.workspace.plugins,
455
+ };
456
+ }
457
+ const named = options.workspace.plugins.find((plugin) => plugin.manifest.name === options.target);
458
+ if (named) {
459
+ return { kind: 'plugin', id: named.manifest.name, path: named.rootDir, plugins: [named] };
460
+ }
461
+ const candidate = path.resolve(options.cwd, options.target);
462
+ const stat = await fs.lstat(candidate).catch(() => null);
463
+ if (!stat) {
464
+ throw new ReviewInspectionInputError('targetNotFound', `Review target was not found: ${candidate}`);
465
+ }
466
+ if (!stat.isDirectory() || stat.isSymbolicLink()) {
467
+ throw new ReviewInspectionInputError('invalidArguments', 'The release view requires a canonical Plugin or Catalog Workspace directory.');
468
+ }
469
+ const real = await fs.realpath(candidate);
470
+ if (real === options.workspace.workspaceRoot) {
471
+ return {
472
+ kind: 'catalog',
473
+ id: options.workspace.workspaceIdentity,
474
+ path: real,
475
+ plugins: options.workspace.plugins,
476
+ };
477
+ }
478
+ const plugin = options.workspace.plugins.find((entry) => entry.rootDir === real);
479
+ if (!plugin) {
480
+ throw new ReviewInspectionInputError('invalidArguments', 'The release view requires the complete Plugin or Catalog target.');
481
+ }
482
+ return { kind: 'plugin', id: plugin.manifest.name, path: real, plugins: [plugin] };
483
+ }
484
+ async function inspectMaterializations(options) {
485
+ const materializations = [];
486
+ const finals = new Map();
487
+ const targetPluginNames = new Set(options.targetPlugins.map((plugin) => plugin.manifest.name));
488
+ const context = {
489
+ workspace: options.workspace,
490
+ source: {
491
+ kind: 'workspace',
492
+ workspaceIdentity: options.workspace.workspaceIdentity,
493
+ sourceIdentity: options.workspaceSourceIdentity,
494
+ },
495
+ };
496
+ const bindingPaths = [...new Set(options.paths.map((entry) => path.resolve(entry)))].sort(compareText);
497
+ for (const bindingPath of bindingPaths) {
498
+ let parsed = null;
499
+ try {
500
+ parsed = await readAwSourceBinding(bindingPath);
501
+ }
502
+ catch {
503
+ // The validator returns the public typed state and safe issue below.
504
+ }
505
+ const expectedSubject = parsed?.subject ?? {
506
+ plugin: options.targetPlugins[0]?.manifest.name ?? 'unknown',
507
+ };
508
+ const validation = await validateAwSourceBindingForWorkspace({
509
+ bindingPath,
510
+ context,
511
+ expectedSubject,
512
+ cwd: options.workspace.workspaceRoot,
513
+ env: options.env,
514
+ });
515
+ if (validation.state !== 'verified') {
516
+ materializations.push({
517
+ path: bindingPath,
518
+ state: validation.state,
519
+ plugin: validation.binding?.subject.plugin ?? null,
520
+ skill: validation.binding?.subject.skill ?? null,
521
+ profile: validation.binding ? finalProfileFromBinding(validation.binding.profile) : null,
522
+ finalKeys: [],
523
+ verifiedBinding: null,
524
+ issues: validation.issues.map((issue) => issue.message),
525
+ });
526
+ continue;
527
+ }
528
+ const profile = finalProfileFromBinding(validation.binding.profile);
529
+ const finalKeys = [];
530
+ for (const output of validation.outputs) {
531
+ if (output.kind !== 'eval-target'
532
+ && output.kind !== 'portable-skill'
533
+ && output.kind !== 'review-skill')
534
+ continue;
535
+ const outputPlugin = output.kind === 'portable-skill' || output.kind === 'review-skill'
536
+ ? output.plugin
537
+ : validation.binding.subject.plugin;
538
+ if (!targetPluginNames.has(outputPlugin))
539
+ continue;
540
+ const compatibleRequired = options.requiredFinals.filter((required) => required.plugin === outputPlugin
541
+ && required.skill === output.skill
542
+ && required.profile === profile
543
+ && (validation.binding.profile.kind !== 'eval'
544
+ || required.targetId === null
545
+ || options.targetPlugins
546
+ .find((plugin) => plugin.manifest.name === required.plugin)
547
+ ?.manifest.artifacts?.targets
548
+ ?.find((target) => target.id === required.targetId)
549
+ ?.delivery?.mode !== 'codex-native'));
550
+ if (compatibleRequired.length === 0) {
551
+ options.issues.push({
552
+ category: 'unknown',
553
+ code: 'materializedOutputOwnerUnknown',
554
+ message: `The verified source binding does not contain a selected leaf for ${outputPlugin}/${output.skill}/${profile}.`,
555
+ blocking: false,
556
+ path: output.path,
557
+ });
558
+ continue;
559
+ }
560
+ const identityKey = materializationIdentityKey({
561
+ plugin: outputPlugin,
562
+ skill: output.skill,
563
+ profile,
564
+ materializationProfile: validation.binding.profile,
565
+ });
566
+ const key = [
567
+ 'materialized',
568
+ identityKey,
569
+ output.digest,
570
+ ].join(':');
571
+ const existingSubject = options.subjects.find((subject) => subject.key === key);
572
+ if (existingSubject) {
573
+ if (compareText(output.path, existingSubject.path) < 0)
574
+ existingSubject.path = output.path;
575
+ }
576
+ else {
577
+ options.subjects.push({
578
+ key,
579
+ kind: 'materialized-skill',
580
+ plugin: outputPlugin,
581
+ skill: output.skill,
582
+ path: output.path,
583
+ profile,
584
+ digest: output.digest,
585
+ origin: 'source-binding',
586
+ materializationProfile: validation.binding.profile,
587
+ });
588
+ }
589
+ finalKeys.push(key);
590
+ const existingFinal = finals.get(key);
591
+ if (existingFinal) {
592
+ if (compareText(output.path, existingFinal.path) < 0)
593
+ existingFinal.path = output.path;
594
+ }
595
+ else {
596
+ finals.set(key, {
597
+ key,
598
+ plugin: outputPlugin,
599
+ skill: output.skill,
600
+ profile,
601
+ materializationProfile: validation.binding.profile,
602
+ identityKey,
603
+ path: output.path,
604
+ digest: output.digest,
605
+ requiredKeys: compatibleRequired.map((required) => required.key).sort(compareText),
606
+ });
607
+ }
608
+ }
609
+ const materializationIssues = [];
610
+ if (finalKeys.length === 0) {
611
+ const message = 'The verified source binding does not contribute a final to the selected inspection target.';
612
+ materializationIssues.push(message);
613
+ options.issues.push({
614
+ category: 'unknown',
615
+ code: 'sourceBindingUnused',
616
+ message,
617
+ blocking: false,
618
+ path: bindingPath,
619
+ });
620
+ }
621
+ materializations.push({
622
+ path: bindingPath,
623
+ state: 'verified',
624
+ plugin: validation.binding.subject.plugin,
625
+ skill: validation.binding.subject.skill ?? null,
626
+ profile,
627
+ finalKeys: [...new Set(finalKeys)].sort(compareText),
628
+ verifiedBinding: {
629
+ source: validation.binding.source,
630
+ subject: validation.binding.subject,
631
+ profile: validation.binding.profile,
632
+ evalInput: validation.binding.evalInput ?? null,
633
+ finalDigest: validation.binding.finalDigest,
634
+ artifacts: [...validation.outputs].sort((left, right) => compareText(`${left.kind}\0${'plugin' in left ? left.plugin : ''}\0${'skill' in left ? left.skill : ''}\0${left.path}`, `${right.kind}\0${'plugin' in right ? right.plugin : ''}\0${'skill' in right ? right.skill : ''}\0${right.path}`)),
635
+ },
636
+ issues: materializationIssues,
637
+ });
638
+ }
639
+ return {
640
+ materializations,
641
+ finals: [...finals.values()].sort((left, right) => compareText(left.key, right.key)),
642
+ };
643
+ }
644
+ function sameResolvedConfig(left, right) {
645
+ return canonicalJson({ values: left.values, sources: left.sources })
646
+ === canonicalJson({ values: right.values, sources: right.sources });
647
+ }
648
+ function selectResolvedConfig(config, keys) {
649
+ return {
650
+ values: Object.fromEntries(keys.flatMap((key) => Object.hasOwn(config.values, key) ? [[key, config.values[key]]] : [])),
651
+ sources: Object.fromEntries(keys.flatMap((key) => Object.hasOwn(config.sources, key) ? [[key, config.sources[key]]] : [])),
652
+ };
653
+ }
654
+ function selectedSkillConfig(profile, skill) {
655
+ const entries = profile.pluginConfigs.filter((entry) => entry.pluginName === skill.pluginName);
656
+ if (entries.length === 0)
657
+ return skill.refreshKeys.length === 0 ? { values: {}, sources: {} } : null;
658
+ const values = Object.assign({}, ...entries.map((entry) => entry.values));
659
+ const sources = Object.assign({}, ...entries.map((entry) => entry.sources));
660
+ return selectResolvedConfig({ values, sources }, skill.refreshKeys);
661
+ }
662
+ function legacyProfileStore(scope, values) {
663
+ return {
664
+ path: `<legacy-${scope}-profile>`,
665
+ exists: Object.keys(values).length > 0,
666
+ state: 'ready',
667
+ values,
668
+ issues: [],
669
+ };
670
+ }
671
+ async function legacyBindingMatchesSelection(options) {
672
+ const { binding, requestedProfile, skill } = options;
673
+ if (binding.profile.scope !== requestedProfile.scope)
674
+ return false;
675
+ if (binding.profile.kind === 'eval') {
676
+ if (requestedProfile.platform !== 'codex'
677
+ || !binding.subject.skill
678
+ || skill.delivery === 'codex-native')
679
+ return false;
680
+ const plugin = options.selection.workspace.plugins.find((entry) => entry.manifest.name === binding.subject.plugin);
681
+ if (!plugin)
682
+ return false;
683
+ const loaded = await readAwSkillEvalManifest({ plugin, skill: binding.subject.skill });
684
+ const evalProfile = loaded.manifest.profiles.find((entry) => entry.id === binding.profile.id);
685
+ if (!evalProfile)
686
+ return false;
687
+ const config = Object.fromEntries(evalProfile.plugins.map((entry) => [entry.name, entry.config]));
688
+ try {
689
+ const requested = selectedSkillConfig(requestedProfile, skill);
690
+ if (!requested)
691
+ return false;
692
+ const overrides = config[skill.pluginName] ?? {};
693
+ const userValues = binding.profile.scope === 'user' ? overrides : {};
694
+ const effective = await resolveEffectivePluginConfigFromStores({
695
+ pluginName: skill.pluginName,
696
+ manifest: skill.plugin.manifest,
697
+ targetScope: binding.profile.scope,
698
+ projectRoot: options.selection.workspace.workspaceRoot,
699
+ stores: {
700
+ user: legacyProfileStore('user', userValues),
701
+ ...(binding.profile.scope === 'project'
702
+ ? { project: legacyProfileStore('project', overrides) }
703
+ : {}),
704
+ },
705
+ });
706
+ return sameResolvedConfig(requested, selectResolvedConfig(effective, skill.refreshKeys));
707
+ }
708
+ catch {
709
+ return false;
710
+ }
711
+ }
712
+ if (binding.profile.kind !== 'portable' || requestedProfile.platform !== 'agent-skills') {
713
+ return false;
714
+ }
715
+ try {
716
+ const requested = selectedSkillConfig(requestedProfile, skill);
717
+ if (!requested)
718
+ return false;
719
+ const current = await resolvePortablePluginProfileConfig({
720
+ plugin: skill.plugin,
721
+ scope: skill.configScope,
722
+ cwd: options.selection.workspace.workspaceRoot,
723
+ env: options.env,
724
+ });
725
+ return sameResolvedConfig(requested, selectResolvedConfig(current.config, skill.refreshKeys));
726
+ }
727
+ catch {
728
+ return false;
729
+ }
730
+ }
731
+ function bindingOutputIdentity(binding, artifact) {
732
+ if (artifact.kind === 'eval-target') {
733
+ return { plugin: binding.subject.plugin, skill: artifact.skill };
734
+ }
735
+ if (artifact.kind === 'portable-skill' || artifact.kind === 'review-skill') {
736
+ return { plugin: artifact.plugin, skill: artifact.skill };
737
+ }
738
+ return null;
739
+ }
740
+ async function inspectNavigationBindings(options) {
741
+ const candidates = new Map();
742
+ const issues = [];
743
+ const context = {
744
+ workspace: options.selection.workspace,
745
+ source: {
746
+ kind: 'workspace',
747
+ workspaceIdentity: options.selection.workspace.workspaceIdentity,
748
+ sourceIdentity: options.selection.sourceIdentity,
749
+ },
750
+ };
751
+ const bindingPaths = [...new Set(options.materializations.map((entry) => path.resolve(entry)))]
752
+ .sort(compareText);
753
+ for (const bindingPath of bindingPaths) {
754
+ let binding;
755
+ try {
756
+ binding = await readAwSourceBinding(bindingPath);
757
+ }
758
+ catch (error) {
759
+ throw new ReviewInspectionInputError('sourceBindingInvalid', error instanceof Error ? error.message : String(error));
760
+ }
761
+ const validation = await validateAwSourceBindingForWorkspace({
762
+ bindingPath,
763
+ context,
764
+ expectedSubject: binding.subject,
765
+ cwd: options.selection.workspace.workspaceRoot,
766
+ env: options.env,
767
+ });
768
+ if (validation.state === 'invalid' || validation.state === 'incomplete') {
769
+ throw new ReviewInspectionInputError('sourceBindingInvalid', validation.issues.map((entry) => entry.message).join('; '));
770
+ }
771
+ let selected = false;
772
+ for (const requestedProfile of options.selection.profiles) {
773
+ const profileMatches = binding.profile.kind === 'review'
774
+ ? binding.profile.platform === requestedProfile.platform
775
+ && binding.profile.scope === requestedProfile.scope
776
+ : binding.profile.kind === 'eval'
777
+ ? requestedProfile.platform === 'codex'
778
+ : requestedProfile.platform === 'agent-skills';
779
+ if (!profileMatches)
780
+ continue;
781
+ for (const artifact of binding.artifacts) {
782
+ const identity = bindingOutputIdentity(binding, artifact);
783
+ if (!identity)
784
+ continue;
785
+ const skill = requestedProfile.skills.find((entry) => entry.pluginName === identity.plugin && entry.name === identity.skill);
786
+ if (!skill)
787
+ continue;
788
+ if (binding.profile.kind === 'review'
789
+ && !await reviewBindingMatchesSelection({
790
+ workspace: options.selection.workspace,
791
+ bindingProfile: binding.profile,
792
+ requestedProfile,
793
+ pluginName: identity.plugin,
794
+ skill: identity.skill,
795
+ }))
796
+ continue;
797
+ if (binding.profile.kind !== 'review'
798
+ && !await legacyBindingMatchesSelection({
799
+ selection: options.selection,
800
+ requestedProfile,
801
+ skill,
802
+ binding,
803
+ env: options.env,
804
+ }))
805
+ continue;
806
+ selected = true;
807
+ const key = `${identity.plugin}\0${identity.skill}\0${requestedProfile.platform}\0${requestedProfile.scope}`;
808
+ const candidate = {
809
+ path: path.resolve(path.dirname(bindingPath), ...artifact.path.split('/')),
810
+ digest: artifact.digest,
811
+ evidencePath: bindingPath,
812
+ state: validation.state === 'verified' ? 'ready' : 'stale',
813
+ };
814
+ candidates.set(key, [...(candidates.get(key) ?? []), candidate]);
815
+ }
816
+ }
817
+ if (!selected) {
818
+ issues.push({
819
+ code: 'materializationNotSelected',
820
+ path: bindingPath,
821
+ message: 'The source binding does not match the selected Skill, profile, and config input.',
822
+ });
823
+ }
824
+ else if (validation.state === 'drifted') {
825
+ issues.push({
826
+ code: 'sourceBindingDrifted',
827
+ path: bindingPath,
828
+ message: validation.issues.map((entry) => entry.message).join('; '),
829
+ });
830
+ }
831
+ }
832
+ return { candidates, issues };
833
+ }
834
+ function navigationSkillKey(skill, profile) {
835
+ return `${skill.pluginName}\0${skill.name}\0${profile.platform}\0${profile.scope}`;
836
+ }
837
+ async function inspectNavigationTarget(options) {
838
+ const selection = await resolveReviewSelection({
839
+ cwd: options.cwd,
840
+ target: options.target,
841
+ ...(options.workspaceRoot === undefined ? {} : { workspaceRoot: options.workspaceRoot }),
842
+ ...(options.skills === undefined ? {} : { skills: options.skills }),
843
+ ...(options.platform === undefined ? {} : { platform: options.platform }),
844
+ ...(options.scope === undefined ? {} : { scope: options.scope }),
845
+ ...(options.configFile === undefined ? {} : { configFile: options.configFile }),
846
+ ...(options.env === undefined ? {} : { env: options.env }),
847
+ });
848
+ try {
849
+ const snapshot = await inspectSnapshot(selection.workspace, selection.sourceIdentity);
850
+ const binding = await inspectNavigationBindings({
851
+ selection,
852
+ materializations: options.materializations ?? [],
853
+ env: options.env,
854
+ });
855
+ const skills = [];
856
+ const issues = [...binding.issues];
857
+ if (snapshot.receipt.state === 'invalid' || snapshot.receipt.state === 'stale') {
858
+ issues.push({
859
+ code: snapshot.receipt.state === 'invalid' ? 'snapshotInvalid' : 'snapshotStale',
860
+ path: snapshot.receipt.path,
861
+ message: snapshot.receipt.state === 'invalid'
862
+ ? 'The existing Catalog snapshot is invalid.'
863
+ : 'The existing Catalog snapshot is not bound to the current Workspace source.',
864
+ });
865
+ }
866
+ for (const profile of selection.profiles) {
867
+ for (const skill of profile.skills) {
868
+ const key = navigationSkillKey(skill, profile);
869
+ const candidates = [...(binding.candidates.get(key) ?? [])];
870
+ if (snapshot.root
871
+ && !skill.dynamic
872
+ && profile.platform !== 'agent-skills') {
873
+ const finalPath = path.join(snapshot.root, 'plugins', skill.pluginName, profile.platform, 'skills', skill.name);
874
+ try {
875
+ candidates.push({
876
+ path: finalPath,
877
+ digest: await computeSkillDigest(finalPath),
878
+ evidencePath: snapshot.receipt.path,
879
+ state: 'ready',
880
+ });
881
+ }
882
+ catch {
883
+ // Complete snapshot validation reports invalid final content through its own state.
884
+ }
885
+ }
886
+ const ready = candidates.filter((entry) => entry.state === 'ready');
887
+ const readyDigests = new Set(ready.map((entry) => entry.digest));
888
+ let state = 'missing';
889
+ let chosen = null;
890
+ if (readyDigests.size > 1) {
891
+ state = 'invalid';
892
+ issues.push({
893
+ code: 'materializationAmbiguous',
894
+ path: null,
895
+ message: `Current materializations have different digests for ${skill.pluginName}/${skill.name}/${profile.profile.id}.`,
896
+ });
897
+ }
898
+ else if (ready.length > 0) {
899
+ state = 'ready';
900
+ chosen = ready.sort((left, right) => compareText(`${left.evidencePath}\0${left.path}`, `${right.evidencePath}\0${right.path}`))[0];
901
+ }
902
+ else {
903
+ const stale = candidates.filter((entry) => entry.state === 'stale')
904
+ .sort((left, right) => compareText(left.evidencePath, right.evidencePath));
905
+ if (stale.length > 0) {
906
+ state = 'stale';
907
+ chosen = stale[0];
908
+ }
909
+ }
910
+ if (state === 'missing') {
911
+ issues.push({
912
+ code: 'requiredFinalMissing',
913
+ path: skill.sourcePath,
914
+ message: `No current final is available for ${skill.pluginName}/${skill.name}/${profile.profile.id}.`,
915
+ });
916
+ }
917
+ skills.push({
918
+ skill: skill.name,
919
+ sourcePath: skill.sourcePath,
920
+ profile: {
921
+ platform: profile.platform,
922
+ scope: profile.scope,
923
+ inputDigest: profile.profile.inputDigest,
924
+ },
925
+ finalPath: chosen?.path ?? null,
926
+ digest: chosen?.digest ?? null,
927
+ state,
928
+ evidencePath: chosen?.evidencePath ?? null,
929
+ });
930
+ }
931
+ }
932
+ skills.sort((left, right) => compareText(`${left.skill}\0${left.profile.platform}\0${left.profile.scope}\0${left.sourcePath}`, `${right.skill}\0${right.profile.platform}\0${right.profile.scope}\0${right.sourcePath}`));
933
+ issues.sort((left, right) => compareText(`${left.code}\0${left.path ?? ''}\0${left.message}`, `${right.code}\0${right.path ?? ''}\0${right.message}`));
934
+ return {
935
+ schemaVersion: 2,
936
+ command: 'review:inspect',
937
+ view: 'review',
938
+ ok: true,
939
+ target: { kind: selection.target.kind, path: selection.target.path },
940
+ sources: [...new Set(selection.sources.map((entry) => path.resolve(entry)))].sort(compareText),
941
+ ...(selection.target.kind === 'catalog'
942
+ ? { snapshot: { path: snapshot.receipt.path, state: snapshot.receipt.state } }
943
+ : {}),
944
+ skills,
945
+ issues,
946
+ };
947
+ }
948
+ catch (error) {
949
+ throw new ReviewInspectionResolvedTargetError(error, {
950
+ kind: selection.target.kind,
951
+ path: selection.target.path,
952
+ });
953
+ }
954
+ }
955
+ async function inspectReleaseTarget(options) {
956
+ const targetCandidate = options.target === 'catalog' ? null : path.resolve(options.cwd, options.target);
957
+ const targetCandidateStat = targetCandidate
958
+ ? await fs.lstat(targetCandidate).catch(() => null)
959
+ : null;
960
+ if (targetCandidateStat && (!targetCandidateStat.isDirectory() || targetCandidateStat.isSymbolicLink())) {
961
+ throw new ReviewInspectionInputError('invalidArguments', 'The release view requires a canonical Plugin or Catalog Workspace directory.');
962
+ }
963
+ const resolution = await resolveCatalogWorkspaceRoot({
964
+ cwd: options.workspaceRoot === undefined && targetCandidateStat?.isDirectory()
965
+ ? targetCandidate
966
+ : options.cwd,
967
+ ...(options.workspaceRoot === undefined ? {} : { explicitRoot: options.workspaceRoot }),
968
+ mode: 'existing',
969
+ });
970
+ const workspace = await readCatalogWorkspace(resolution.workspaceRoot, {
971
+ reservedImports: CLI_RESERVED_IMPORTS,
972
+ });
973
+ const workspaceSourceIdentity = await calculateCatalogWorkspaceSourceIdentity(workspace);
974
+ const [target, snapshot] = await Promise.all([
975
+ resolveTarget({ cwd: options.cwd, target: options.target, workspace }),
976
+ inspectSnapshot(workspace, workspaceSourceIdentity),
977
+ ]);
978
+ const issues = [];
979
+ const subjects = [{
980
+ key: 'catalog:source',
981
+ kind: 'catalog-source',
982
+ plugin: null,
983
+ skill: null,
984
+ path: workspace.workspaceRoot,
985
+ profile: null,
986
+ digest: workspaceSourceIdentity,
987
+ origin: 'workspace',
988
+ }];
989
+ if (snapshot.receipt.state === 'current') {
990
+ subjects.push({
991
+ key: 'catalog:snapshot',
992
+ kind: 'catalog-snapshot',
993
+ plugin: null,
994
+ skill: null,
995
+ path: snapshot.receipt.path,
996
+ profile: null,
997
+ digest: snapshot.receipt.snapshotDigest,
998
+ origin: 'catalog-snapshot',
999
+ });
1000
+ }
1001
+ else if (snapshot.receipt.state !== 'absent') {
1002
+ issues.push({
1003
+ category: snapshot.receipt.state === 'invalid' ? 'invalid' : 'unknown',
1004
+ code: snapshot.receipt.state === 'invalid' ? 'snapshotInvalid' : 'snapshotStale',
1005
+ message: snapshot.receipt.state === 'invalid'
1006
+ ? 'The existing Catalog snapshot is invalid.'
1007
+ : 'The existing Catalog snapshot is not bound to the current Workspace source.',
1008
+ blocking: false,
1009
+ path: relativeWorkspacePath(workspace.workspaceRoot, snapshot.receipt.path),
1010
+ });
1011
+ }
1012
+ const seeds = [];
1013
+ const pluginInputs = [];
1014
+ for (const plugin of target.plugins) {
1015
+ const sourceContainerKey = `plugin:${plugin.manifest.name}:source`;
1016
+ const component = await computeReviewComponentDigest({
1017
+ repoRoot: workspace.workspaceRoot,
1018
+ path: plugin.rootDir,
1019
+ });
1020
+ subjects.push({
1021
+ key: sourceContainerKey,
1022
+ kind: 'aw-plugin-source',
1023
+ plugin: plugin.manifest.name,
1024
+ skill: null,
1025
+ path: plugin.rootDir,
1026
+ profile: null,
1027
+ digest: component.digest,
1028
+ origin: 'workspace',
1029
+ });
1030
+ const source = await inventoryPluginSource({ workspace, plugin, subjects });
1031
+ seeds.push(...source.seeds);
1032
+ pluginInputs.push({ plugin, sourceContainerKey, sourceSubjectKeys: source.sourceSubjectKeys });
1033
+ }
1034
+ const requiredFinals = seeds.map((seed) => ({
1035
+ key: requiredFinalKey(seed),
1036
+ kind: 'materialized-skill',
1037
+ plugin: seed.plugin.manifest.name,
1038
+ skill: seed.skill,
1039
+ path: null,
1040
+ profile: seed.profile,
1041
+ digest: null,
1042
+ targetId: seed.targetId,
1043
+ sourceSubjectKey: seed.sourceSubjectKey,
1044
+ status: 'missing',
1045
+ matchedFinalKeys: [],
1046
+ }));
1047
+ const requiredByKey = new Map(requiredFinals.map((entry) => [entry.key, entry]));
1048
+ if (snapshot.root) {
1049
+ for (const seed of seeds.filter((entry) => !entry.dynamic && !entry.profile.startsWith('agent-skills-'))) {
1050
+ const platform = seed.profile.startsWith('codex-') ? 'codex' : 'claude';
1051
+ const finalPath = path.join(snapshot.root, 'plugins', seed.plugin.manifest.name, platform, 'skills', seed.skill);
1052
+ try {
1053
+ const digest = await computeSkillDigest(finalPath);
1054
+ const key = `${requiredFinalKey(seed)}:snapshot`;
1055
+ subjects.push({
1056
+ key,
1057
+ kind: 'materialized-skill',
1058
+ plugin: seed.plugin.manifest.name,
1059
+ skill: seed.skill,
1060
+ path: finalPath,
1061
+ profile: seed.profile,
1062
+ digest,
1063
+ origin: 'catalog-snapshot',
1064
+ });
1065
+ const required = requiredByKey.get(requiredFinalKey(seed));
1066
+ required.path = finalPath;
1067
+ required.digest = digest;
1068
+ required.status = 'resolved';
1069
+ required.matchedFinalKeys.push(key);
1070
+ }
1071
+ catch (error) {
1072
+ const required = requiredByKey.get(requiredFinalKey(seed));
1073
+ required.status = 'invalid';
1074
+ issues.push({
1075
+ category: 'invalid',
1076
+ code: 'snapshotFinalInvalid',
1077
+ message: error instanceof Error ? error.message : String(error),
1078
+ blocking: true,
1079
+ subjectKey: required.key,
1080
+ path: relativeWorkspacePath(workspace.workspaceRoot, finalPath),
1081
+ });
1082
+ }
1083
+ }
1084
+ }
1085
+ const binding = await inspectMaterializations({
1086
+ paths: options.materializations ?? [],
1087
+ workspace,
1088
+ workspaceSourceIdentity,
1089
+ targetPlugins: target.plugins,
1090
+ requiredFinals,
1091
+ subjects,
1092
+ issues,
1093
+ env: options.env,
1094
+ });
1095
+ const bindingFinalsByRequiredKey = new Map();
1096
+ for (const final of binding.finals) {
1097
+ const candidates = requiredFinals.filter((required) => required.plugin === final.plugin
1098
+ && required.skill === final.skill
1099
+ && required.profile === final.profile
1100
+ && final.requiredKeys.includes(required.key));
1101
+ if (candidates.length === 1) {
1102
+ const required = candidates[0];
1103
+ bindingFinalsByRequiredKey.set(required.key, [...(bindingFinalsByRequiredKey.get(required.key) ?? []), final]);
1104
+ }
1105
+ else if (candidates.length > 1) {
1106
+ issues.push({
1107
+ category: 'unknown',
1108
+ code: 'materializedFinalAmbiguous',
1109
+ message: `Materialized final ${final.plugin}/${final.skill}/${final.profile} matches multiple declarations.`,
1110
+ blocking: true,
1111
+ subjectKey: final.key,
1112
+ });
1113
+ }
1114
+ }
1115
+ for (const required of requiredFinals) {
1116
+ const finals = bindingFinalsByRequiredKey.get(required.key) ?? [];
1117
+ const byIdentity = new Map();
1118
+ for (const final of finals) {
1119
+ byIdentity.set(final.identityKey, [...(byIdentity.get(final.identityKey) ?? []), final]);
1120
+ }
1121
+ const ambiguous = [...byIdentity.entries()]
1122
+ .filter(([, entries]) => new Set(entries.map((entry) => entry.digest)).size > 1)
1123
+ .sort(([left], [right]) => compareText(left, right));
1124
+ required.matchedFinalKeys = [...new Set([
1125
+ ...required.matchedFinalKeys,
1126
+ ...finals.map((final) => final.key),
1127
+ ])].sort(compareText);
1128
+ if (ambiguous.length > 0) {
1129
+ required.status = 'unknown';
1130
+ required.path = null;
1131
+ required.digest = null;
1132
+ for (const [identity] of ambiguous) {
1133
+ issues.push({
1134
+ category: 'unknown',
1135
+ code: 'materializedFinalDigestAmbiguous',
1136
+ message: `One materialization identity produced different target digests for ${required.plugin}/${required.skill}/${required.profile}: ${identity}.`,
1137
+ blocking: true,
1138
+ subjectKey: required.key,
1139
+ });
1140
+ }
1141
+ continue;
1142
+ }
1143
+ if (finals.length > 0)
1144
+ required.status = 'resolved';
1145
+ if (required.matchedFinalKeys.length === 1) {
1146
+ const subject = subjects.find((entry) => entry.key === required.matchedFinalKeys[0]);
1147
+ required.path = subject.path;
1148
+ required.digest = subject.digest;
1149
+ }
1150
+ else if (required.matchedFinalKeys.length > 1) {
1151
+ required.path = null;
1152
+ required.digest = null;
1153
+ }
1154
+ }
1155
+ for (const required of requiredFinals.filter((entry) => entry.status === 'missing')) {
1156
+ issues.push({
1157
+ category: 'missing',
1158
+ code: 'requiredFinalMissing',
1159
+ message: `No current final is available for ${required.plugin}/${required.skill}/${required.profile}.`,
1160
+ blocking: false,
1161
+ subjectKey: required.key,
1162
+ });
1163
+ }
1164
+ const requiredEvals = await inventoryRequiredEvals({ workspace, seeds, issues });
1165
+ for (const required of requiredEvals) {
1166
+ required.materializedFinalKeys = binding.finals
1167
+ .filter((final) => final.plugin === required.plugin
1168
+ && final.skill === required.skill
1169
+ && final.profile === required.finalProfile
1170
+ && final.materializationProfile.kind === 'eval'
1171
+ && final.materializationProfile.id === required.evalProfile.id
1172
+ && final.materializationProfile.inputDigest === required.evalProfile.inputDigest)
1173
+ .map((final) => final.key)
1174
+ .sort(compareText);
1175
+ required.verifiedBindingPaths = [...new Set(binding.materializations
1176
+ .filter((materialization) => materialization.state === 'verified'
1177
+ && materialization.verifiedBinding?.subject.plugin === required.plugin
1178
+ && materialization.verifiedBinding.subject.skill === required.skill
1179
+ && materialization.verifiedBinding.subject.suite === required.suite.id
1180
+ && materialization.verifiedBinding.profile.kind === 'eval'
1181
+ && materialization.verifiedBinding.profile.id === required.evalProfile.id
1182
+ && materialization.verifiedBinding.profile.inputDigest === required.evalProfile.inputDigest)
1183
+ .map((materialization) => materialization.path))]
1184
+ .sort(compareText);
1185
+ if (required.materializedFinalKeys.length === 0) {
1186
+ const snapshotFinal = (requiredByKey.get(required.requiredFinalKey)?.matchedFinalKeys ?? [])
1187
+ .filter((key) => subjects.some((subject) => subject.key === key && subject.origin === 'catalog-snapshot'));
1188
+ required.materializedFinalKeys = [...snapshotFinal];
1189
+ }
1190
+ }
1191
+ const plugins = pluginInputs.map(({ plugin, sourceContainerKey, sourceSubjectKeys }) => {
1192
+ const entry = snapshot.receipt.state === 'current' ? snapshot.entries.get(plugin.manifest.name) : undefined;
1193
+ let finalContainerKey = null;
1194
+ if (entry && snapshot.root) {
1195
+ finalContainerKey = `plugin:${plugin.manifest.name}:snapshot`;
1196
+ subjects.push({
1197
+ key: finalContainerKey,
1198
+ kind: 'aw-plugin',
1199
+ plugin: plugin.manifest.name,
1200
+ skill: null,
1201
+ path: path.join(snapshot.root, 'plugins', plugin.manifest.name),
1202
+ profile: null,
1203
+ digest: entry.artifactDigest,
1204
+ origin: 'catalog-snapshot',
1205
+ });
1206
+ }
1207
+ const pluginFinals = requiredFinals.filter((required) => required.plugin === plugin.manifest.name);
1208
+ const pluginEvals = requiredEvals.filter((required) => required.plugin === plugin.manifest.name);
1209
+ return {
1210
+ id: plugin.manifest.name,
1211
+ name: plugin.manifest.name,
1212
+ version: plugin.manifest.version,
1213
+ path: plugin.rootDir,
1214
+ sourceContainerKey,
1215
+ finalContainerKey,
1216
+ dependencies: [...(plugin.manifest.dependencies ?? [])].sort(compareText),
1217
+ supportedPlatforms: [...resolveSupportedPlatforms(plugin.manifest)].sort(compareText),
1218
+ finalProfiles: [...new Set(pluginFinals.map((entry) => entry.profile))].sort(compareText),
1219
+ imports: pluginImports(plugin),
1220
+ snapshotEntry: entry ? {
1221
+ artifactDigest: entry.artifactDigest,
1222
+ manifestDigest: entry.manifestDigest,
1223
+ contentDigest: entry.contentDigest,
1224
+ } : null,
1225
+ sourceSubjectKeys,
1226
+ requiredFinalKeys: pluginFinals.map((entry) => entry.key).sort(compareText),
1227
+ requiredEvalKeys: pluginEvals.map((entry) => entry.key).sort(compareText),
1228
+ };
1229
+ });
1230
+ issues.push(...binding.materializations
1231
+ .filter((entry) => entry.state !== 'verified')
1232
+ .map((entry) => ({
1233
+ category: entry.state === 'incomplete'
1234
+ ? 'missing'
1235
+ : entry.state === 'unsupported' ? 'unsupported' : entry.state === 'drifted' ? 'unknown' : 'invalid',
1236
+ code: `sourceBinding${entry.state[0].toUpperCase()}${entry.state.slice(1)}`,
1237
+ message: entry.issues.join('; ') || `Source binding is ${entry.state}.`,
1238
+ blocking: true,
1239
+ path: entry.path,
1240
+ })));
1241
+ issues.sort((left, right) => compareText(`${left.code}\0${left.subjectKey ?? ''}\0${left.path ?? ''}`, `${right.code}\0${right.subjectKey ?? ''}\0${right.path ?? ''}`));
1242
+ subjects.sort((left, right) => compareText(left.key, right.key));
1243
+ const ok = !issues.some((issue) => issue.blocking);
1244
+ return {
1245
+ schemaVersion: 2,
1246
+ command: 'review:inspect',
1247
+ view: 'release',
1248
+ ok,
1249
+ completeness: ok && requiredFinals.every((entry) => entry.status === 'resolved')
1250
+ ? 'complete' : 'incomplete',
1251
+ target: { kind: target.kind, id: target.id, path: target.path },
1252
+ workspace: {
1253
+ root: workspace.workspaceRoot,
1254
+ resolvedFrom: resolution.workspaceRootResolvedFrom,
1255
+ identity: workspace.workspaceIdentity,
1256
+ sourceIdentity: workspaceSourceIdentity,
1257
+ catalogVersion: workspace.metadata.catalog.version,
1258
+ },
1259
+ snapshot: snapshot.receipt,
1260
+ plugins,
1261
+ subjects,
1262
+ requiredFinals,
1263
+ finalMappings: requiredFinals.map((required) => ({
1264
+ requiredFinalKey: required.key,
1265
+ sourceSubjectKey: required.sourceSubjectKey,
1266
+ finalSubjectKeys: [...required.matchedFinalKeys].sort(compareText),
1267
+ status: required.status,
1268
+ })),
1269
+ requiredEvals,
1270
+ materializations: binding.materializations,
1271
+ issues,
1272
+ };
1273
+ }
1274
+ export async function inspectReviewTarget(options) {
1275
+ const view = options.view ?? 'review';
1276
+ if (view === 'release') {
1277
+ if ((options.skills !== undefined && options.skills.length > 0)
1278
+ || options.platform !== undefined
1279
+ || options.scope !== undefined
1280
+ || options.configFile !== undefined) {
1281
+ throw new ReviewInspectionInputError('invalidArguments', 'The release view requires the complete Plugin or Catalog target and does not accept selection options.');
1282
+ }
1283
+ return await inspectReleaseTarget(options);
1284
+ }
1285
+ return await inspectNavigationTarget(options);
1286
+ }
1287
+ export function getReviewInspectionErrorCode(error, fallback = 'reviewInspectionFailed') {
1288
+ if (error && typeof error === 'object' && 'code' in error) {
1289
+ const code = error.code;
1290
+ if (typeof code === 'string' && code !== '')
1291
+ return code;
1292
+ }
1293
+ return fallback;
1294
+ }
1295
+ export function getReviewInspectionExitCode(error) {
1296
+ if (error && typeof error === 'object' && 'exitCode' in error) {
1297
+ const exitCode = error.exitCode;
1298
+ if (exitCode === 2 || exitCode === 3)
1299
+ return exitCode;
1300
+ }
1301
+ return 1;
1302
+ }
1303
+ function getReviewInspectionResolvedTarget(error) {
1304
+ if (!error || typeof error !== 'object' || !('reviewTarget' in error))
1305
+ return null;
1306
+ const target = error.reviewTarget;
1307
+ if (!target || typeof target !== 'object')
1308
+ return null;
1309
+ const kind = target.kind;
1310
+ const targetPath = target.path;
1311
+ if ((kind !== 'skill' && kind !== 'plugin' && kind !== 'catalog')
1312
+ || typeof targetPath !== 'string'
1313
+ || targetPath === '')
1314
+ return null;
1315
+ return { kind, path: targetPath };
1316
+ }
1317
+ export function createReviewInspectionFailure(error, view = 'review', fallbackCode = 'reviewInspectionFailed') {
1318
+ const code = getReviewInspectionErrorCode(error, fallbackCode);
1319
+ const message = error instanceof Error ? error.message : String(error);
1320
+ if (view === 'release') {
1321
+ return {
1322
+ schemaVersion: 2,
1323
+ command: 'review:inspect',
1324
+ view,
1325
+ ok: false,
1326
+ completeness: 'incomplete',
1327
+ issues: [{ category: 'invalid', code, message, blocking: true }],
1328
+ };
1329
+ }
1330
+ return {
1331
+ schemaVersion: 2,
1332
+ command: 'review:inspect',
1333
+ view,
1334
+ ok: false,
1335
+ target: getReviewInspectionResolvedTarget(error),
1336
+ sources: [],
1337
+ skills: [],
1338
+ issues: [{ code, path: null, message }],
1339
+ };
1340
+ }
1341
+ //# sourceMappingURL=review-inspection.js.map