@lesliechan721/aw 0.1.0-beta.6 → 0.1.0-beta.60

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 (621) 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 -92
  16. package/dist/authoring/scripts/lib/skill-scaffold.mjs +99 -124
  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 +552 -1142
  23. package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
  24. package/dist/native-runtime/reader-runtime.mjs +34 -0
  25. package/dist/native-runtime/reader.d.mts +6 -0
  26. package/dist/native-runtime/reader.mjs +11 -0
  27. package/dist/scripts/aw-skill-eval-materializer.d.ts +26 -0
  28. package/dist/scripts/aw-skill-eval-materializer.js +306 -0
  29. package/dist/scripts/aw-skill-eval-materializer.js.map +1 -0
  30. package/dist/scripts/bundle-plugins.d.ts +1 -0
  31. package/dist/scripts/bundle-plugins.js +19 -8
  32. package/dist/scripts/bundle-plugins.js.map +1 -1
  33. package/dist/scripts/plugin-staging.d.ts +7 -9
  34. package/dist/scripts/plugin-staging.js +18 -29
  35. package/dist/scripts/plugin-staging.js.map +1 -1
  36. package/dist/scripts/plugin-test-reporter.d.mts +2 -0
  37. package/dist/scripts/plugin-test-reporter.mjs +21 -0
  38. package/dist/scripts/plugin-test-reporter.mjs.map +1 -0
  39. package/dist/scripts/test-plugin-scripts.d.ts +5 -0
  40. package/dist/scripts/test-plugin-scripts.js +208 -89
  41. package/dist/scripts/test-plugin-scripts.js.map +1 -1
  42. package/dist/scripts/test-workers.d.mts +24 -0
  43. package/dist/scripts/test-workers.mjs +59 -0
  44. package/dist/scripts/test-workers.mjs.map +1 -0
  45. package/dist/src/adapters/helpers.d.ts +7 -0
  46. package/dist/src/adapters/helpers.js +2 -2
  47. package/dist/src/adapters/helpers.js.map +1 -1
  48. package/dist/src/authoring/workspace-commands.d.ts +19 -1
  49. package/dist/src/authoring/workspace-commands.js +24 -5
  50. package/dist/src/authoring/workspace-commands.js.map +1 -1
  51. package/dist/src/commands/aw-capabilities.d.ts +78 -0
  52. package/dist/src/commands/aw-capabilities.js +266 -0
  53. package/dist/src/commands/aw-capabilities.js.map +1 -0
  54. package/dist/src/commands/catalog-dev-source.d.ts +154 -0
  55. package/dist/src/commands/catalog-dev-source.js +655 -0
  56. package/dist/src/commands/catalog-dev-source.js.map +1 -0
  57. package/dist/src/commands/catalog-generation.d.ts +21 -0
  58. package/dist/src/commands/catalog-generation.js +9 -0
  59. package/dist/src/commands/catalog-generation.js.map +1 -0
  60. package/dist/src/commands/catalog-publication-inspection.d.ts +71 -30
  61. package/dist/src/commands/catalog-publication-inspection.js +475 -63
  62. package/dist/src/commands/catalog-publication-inspection.js.map +1 -1
  63. package/dist/src/commands/catalog-publication-journal.d.ts +68 -0
  64. package/dist/src/commands/catalog-publication-journal.js +292 -0
  65. package/dist/src/commands/catalog-publication-journal.js.map +1 -0
  66. package/dist/src/commands/catalog-publication-target.d.ts +18 -0
  67. package/dist/src/commands/catalog-publication-target.js +95 -0
  68. package/dist/src/commands/catalog-publication-target.js.map +1 -0
  69. package/dist/src/commands/catalog-publish.d.ts +73 -15
  70. package/dist/src/commands/catalog-publish.js +701 -212
  71. package/dist/src/commands/catalog-publish.js.map +1 -1
  72. package/dist/src/commands/catalog-source.d.ts +60 -22
  73. package/dist/src/commands/catalog-source.js +311 -91
  74. package/dist/src/commands/catalog-source.js.map +1 -1
  75. package/dist/src/commands/catalog-status.d.ts +18 -22
  76. package/dist/src/commands/catalog-status.js +81 -115
  77. package/dist/src/commands/catalog-status.js.map +1 -1
  78. package/dist/src/commands/catalog-store.d.ts +104 -0
  79. package/dist/src/commands/catalog-store.js +685 -0
  80. package/dist/src/commands/catalog-store.js.map +1 -0
  81. package/dist/src/commands/catalog-workspace-resolution.d.ts +13 -0
  82. package/dist/src/commands/catalog-workspace-resolution.js +42 -0
  83. package/dist/src/commands/catalog-workspace-resolution.js.map +1 -0
  84. package/dist/src/commands/console.js +28 -17
  85. package/dist/src/commands/console.js.map +1 -1
  86. package/dist/src/commands/dependency-operation-plan.d.ts +52 -15
  87. package/dist/src/commands/dependency-operation-plan.js +289 -7
  88. package/dist/src/commands/dependency-operation-plan.js.map +1 -1
  89. package/dist/src/commands/init.d.ts +5 -11
  90. package/dist/src/commands/init.js +30 -51
  91. package/dist/src/commands/init.js.map +1 -1
  92. package/dist/src/commands/managed-commands.d.ts +28 -0
  93. package/dist/src/commands/managed-commands.js +315 -0
  94. package/dist/src/commands/managed-commands.js.map +1 -0
  95. package/dist/src/commands/offline-cleanup-evidence.d.ts +67 -0
  96. package/dist/src/commands/offline-cleanup-evidence.js +181 -0
  97. package/dist/src/commands/offline-cleanup-evidence.js.map +1 -0
  98. package/dist/src/commands/operation-plan.d.ts +182 -0
  99. package/dist/src/commands/operation-plan.js +71 -0
  100. package/dist/src/commands/operation-plan.js.map +1 -0
  101. package/dist/src/commands/operation-planner.d.ts +47 -0
  102. package/dist/src/commands/operation-planner.js +142 -0
  103. package/dist/src/commands/operation-planner.js.map +1 -0
  104. package/dist/src/commands/options.d.ts +9 -7
  105. package/dist/src/commands/options.js +83 -21
  106. package/dist/src/commands/options.js.map +1 -1
  107. package/dist/src/commands/plugin-capabilities.js +65 -4
  108. package/dist/src/commands/plugin-capabilities.js.map +1 -1
  109. package/dist/src/commands/rebuild-command.d.ts +78 -31
  110. package/dist/src/commands/rebuild-command.js +5229 -942
  111. package/dist/src/commands/rebuild-command.js.map +1 -1
  112. package/dist/src/commands/rebuild-integration.d.ts +143 -21
  113. package/dist/src/commands/rebuild-integration.js +3384 -1342
  114. package/dist/src/commands/rebuild-integration.js.map +1 -1
  115. package/dist/src/commands/rebuild-operations.d.ts +60 -30
  116. package/dist/src/commands/rebuild-operations.js +267 -320
  117. package/dist/src/commands/rebuild-operations.js.map +1 -1
  118. package/dist/src/commands/reconcile-operation-plan.d.ts +28 -0
  119. package/dist/src/commands/reconcile-operation-plan.js +47 -0
  120. package/dist/src/commands/reconcile-operation-plan.js.map +1 -0
  121. package/dist/src/commands/review-inspection.d.ts +60 -0
  122. package/dist/src/commands/review-inspection.js +422 -0
  123. package/dist/src/commands/review-inspection.js.map +1 -0
  124. package/dist/src/commands/review-preparation.d.ts +49 -0
  125. package/dist/src/commands/review-preparation.js +427 -0
  126. package/dist/src/commands/review-preparation.js.map +1 -0
  127. package/dist/src/commands/runtime.d.ts +1 -5
  128. package/dist/src/commands/runtime.js +27 -53
  129. package/dist/src/commands/runtime.js.map +1 -1
  130. package/dist/src/commands/skill-eval.d.ts +39 -0
  131. package/dist/src/commands/skill-eval.js +400 -0
  132. package/dist/src/commands/skill-eval.js.map +1 -0
  133. package/dist/src/commands/status-v6.d.ts +279 -0
  134. package/dist/src/commands/status-v6.js +2785 -0
  135. package/dist/src/commands/status-v6.js.map +1 -0
  136. package/dist/src/commands/sync-command.d.ts +40 -0
  137. package/dist/src/commands/sync-command.js +254 -0
  138. package/dist/src/commands/sync-command.js.map +1 -0
  139. package/dist/src/commands/wizard.d.ts +8 -5
  140. package/dist/src/commands/wizard.js +6 -4
  141. package/dist/src/commands/wizard.js.map +1 -1
  142. package/dist/src/commands/write-commands.d.ts +9 -3
  143. package/dist/src/commands/write-commands.js +136 -31
  144. package/dist/src/commands/write-commands.js.map +1 -1
  145. package/dist/src/constants.d.ts +7 -2
  146. package/dist/src/constants.js +7 -2
  147. package/dist/src/constants.js.map +1 -1
  148. package/dist/src/eval/manifest-v1.d.ts +68 -0
  149. package/dist/src/eval/manifest-v1.js +353 -0
  150. package/dist/src/eval/manifest-v1.js.map +1 -0
  151. package/dist/src/generators/local-plugin.d.ts +5 -1
  152. package/dist/src/generators/local-plugin.js +261 -109
  153. package/dist/src/generators/local-plugin.js.map +1 -1
  154. package/dist/src/generators/permissions.d.ts +5 -2
  155. package/dist/src/generators/permissions.js +28 -15
  156. package/dist/src/generators/permissions.js.map +1 -1
  157. package/dist/src/index.d.ts +10 -4
  158. package/dist/src/index.js +1774 -609
  159. package/dist/src/index.js.map +1 -1
  160. package/dist/src/output/command-receipt.d.ts +47 -46
  161. package/dist/src/output/command-receipt.js +277 -79
  162. package/dist/src/output/command-receipt.js.map +1 -1
  163. package/dist/src/output/model.d.ts +3 -44
  164. package/dist/src/output/model.js +1 -144
  165. package/dist/src/output/model.js.map +1 -1
  166. package/dist/src/output/rebuild-progress.js +15 -13
  167. package/dist/src/output/rebuild-progress.js.map +1 -1
  168. package/dist/src/portable/commands.d.ts +46 -7
  169. package/dist/src/portable/commands.js +349 -37
  170. package/dist/src/portable/commands.js.map +1 -1
  171. package/dist/src/portable/materializer.d.ts +17 -4
  172. package/dist/src/portable/materializer.js +186 -41
  173. package/dist/src/portable/materializer.js.map +1 -1
  174. package/dist/src/portable/skills-cli.d.ts +15 -7
  175. package/dist/src/portable/skills-cli.js +74 -20
  176. package/dist/src/portable/skills-cli.js.map +1 -1
  177. package/dist/src/review/eval-source-input.d.ts +43 -0
  178. package/dist/src/review/eval-source-input.js +207 -0
  179. package/dist/src/review/eval-source-input.js.map +1 -0
  180. package/dist/src/review/review-profile.d.ts +17 -0
  181. package/dist/src/review/review-profile.js +234 -0
  182. package/dist/src/review/review-profile.js.map +1 -0
  183. package/dist/src/review/review-selection.d.ts +30 -0
  184. package/dist/src/review/review-selection.js +527 -0
  185. package/dist/src/review/review-selection.js.map +1 -0
  186. package/dist/src/review/review-types.d.ts +68 -0
  187. package/dist/src/review/review-types.js +16 -0
  188. package/dist/src/review/review-types.js.map +1 -0
  189. package/dist/src/review/skill-materialization.d.ts +26 -0
  190. package/dist/src/review/skill-materialization.js +217 -0
  191. package/dist/src/review/skill-materialization.js.map +1 -0
  192. package/dist/src/review/source-binding.d.ts +183 -0
  193. package/dist/src/review/source-binding.js +708 -0
  194. package/dist/src/review/source-binding.js.map +1 -0
  195. package/dist/src/tui/catalog-freshness.d.ts +1 -0
  196. package/dist/src/tui/catalog-freshness.js +2 -0
  197. package/dist/src/tui/catalog-freshness.js.map +1 -0
  198. package/dist/src/tui/catalog-generation.d.ts +21 -0
  199. package/dist/src/tui/catalog-generation.js +156 -0
  200. package/dist/src/tui/catalog-generation.js.map +1 -0
  201. package/dist/src/tui/catalog-sources/projection.d.ts +4 -0
  202. package/dist/src/tui/catalog-sources/projection.js +17 -0
  203. package/dist/src/tui/catalog-sources/projection.js.map +1 -0
  204. package/dist/src/tui/catalog-sources/review.d.ts +3 -0
  205. package/dist/src/tui/catalog-sources/review.js +13 -0
  206. package/dist/src/tui/catalog-sources/review.js.map +1 -0
  207. package/dist/src/tui/catalog-sources/screens.d.ts +12 -0
  208. package/dist/src/tui/catalog-sources/screens.js +40 -0
  209. package/dist/src/tui/catalog-sources/screens.js.map +1 -0
  210. package/dist/src/tui/catalog-sources/session.d.ts +32 -0
  211. package/dist/src/tui/catalog-sources/session.js +300 -0
  212. package/dist/src/tui/catalog-sources/session.js.map +1 -0
  213. package/dist/src/tui/catalog-sources/types.d.ts +54 -0
  214. package/dist/src/tui/catalog-sources/types.js +2 -0
  215. package/dist/src/tui/catalog-sources/types.js.map +1 -0
  216. package/dist/src/tui/catalog-store-task.d.ts +16 -0
  217. package/dist/src/tui/catalog-store-task.js +19 -0
  218. package/dist/src/tui/catalog-store-task.js.map +1 -0
  219. package/dist/src/tui/clipboard.d.ts +13 -0
  220. package/dist/src/tui/clipboard.js +95 -0
  221. package/dist/src/tui/clipboard.js.map +1 -0
  222. package/dist/src/tui/components.d.ts +110 -3
  223. package/dist/src/tui/components.js +183 -36
  224. package/dist/src/tui/components.js.map +1 -1
  225. package/dist/src/tui/config-array-draft.d.ts +29 -0
  226. package/dist/src/tui/config-array-draft.js +48 -0
  227. package/dist/src/tui/config-array-draft.js.map +1 -0
  228. package/dist/src/tui/config-leaf-editor.d.ts +19 -0
  229. package/dist/src/tui/config-leaf-editor.js +212 -0
  230. package/dist/src/tui/config-leaf-editor.js.map +1 -0
  231. package/dist/src/tui/config-references.d.ts +34 -0
  232. package/dist/src/tui/config-references.js +70 -0
  233. package/dist/src/tui/config-references.js.map +1 -0
  234. package/dist/src/tui/config-value-presentation.d.ts +20 -0
  235. package/dist/src/tui/config-value-presentation.js +104 -0
  236. package/dist/src/tui/config-value-presentation.js.map +1 -0
  237. package/dist/src/tui/console-app-v4.d.ts +14 -4
  238. package/dist/src/tui/console-app-v4.js +9205 -1951
  239. package/dist/src/tui/console-app-v4.js.map +1 -1
  240. package/dist/src/tui/content-item-card.d.ts +13 -0
  241. package/dist/src/tui/content-item-card.js +51 -0
  242. package/dist/src/tui/content-item-card.js.map +1 -0
  243. package/dist/src/tui/controller-runtime.d.ts +10 -2
  244. package/dist/src/tui/controller-runtime.js +3289 -388
  245. package/dist/src/tui/controller-runtime.js.map +1 -1
  246. package/dist/src/tui/controller.d.ts +622 -45
  247. package/dist/src/tui/controller.js +3589 -768
  248. package/dist/src/tui/controller.js.map +1 -1
  249. package/dist/src/tui/dependency-graph-view.d.ts +39 -0
  250. package/dist/src/tui/dependency-graph-view.js +121 -0
  251. package/dist/src/tui/dependency-graph-view.js.map +1 -0
  252. package/dist/src/tui/dependency-graph.d.ts +81 -0
  253. package/dist/src/tui/dependency-graph.js +452 -0
  254. package/dist/src/tui/dependency-graph.js.map +1 -0
  255. package/dist/src/tui/diagnostic-projection.d.ts +23 -0
  256. package/dist/src/tui/diagnostic-projection.js +595 -0
  257. package/dist/src/tui/diagnostic-projection.js.map +1 -0
  258. package/dist/src/tui/diagnostics.d.ts +3 -3
  259. package/dist/src/tui/diagnostics.js +14 -2
  260. package/dist/src/tui/diagnostics.js.map +1 -1
  261. package/dist/src/tui/entity-cards.d.ts +55 -0
  262. package/dist/src/tui/entity-cards.js +220 -0
  263. package/dist/src/tui/entity-cards.js.map +1 -0
  264. package/dist/src/tui/glossary.d.ts +23 -0
  265. package/dist/src/tui/glossary.js +42 -0
  266. package/dist/src/tui/glossary.js.map +1 -0
  267. package/dist/src/tui/index.d.ts +6 -1
  268. package/dist/src/tui/index.js +5 -1
  269. package/dist/src/tui/index.js.map +1 -1
  270. package/dist/src/tui/input-display.d.ts +9 -0
  271. package/dist/src/tui/input-display.js +58 -0
  272. package/dist/src/tui/input-display.js.map +1 -0
  273. package/dist/src/tui/keys.d.ts +44 -0
  274. package/dist/src/tui/keys.js +43 -15
  275. package/dist/src/tui/keys.js.map +1 -1
  276. package/dist/src/tui/lifecycle-action-view.d.ts +6 -0
  277. package/dist/src/tui/lifecycle-action-view.js +36 -0
  278. package/dist/src/tui/lifecycle-action-view.js.map +1 -0
  279. package/dist/src/tui/model.d.ts +224 -31
  280. package/dist/src/tui/model.js +1510 -397
  281. package/dist/src/tui/model.js.map +1 -1
  282. package/dist/src/tui/operation-diagnostic-screens.d.ts +8 -0
  283. package/dist/src/tui/operation-diagnostic-screens.js +71 -0
  284. package/dist/src/tui/operation-diagnostic-screens.js.map +1 -0
  285. package/dist/src/tui/operation-history.d.ts +81 -0
  286. package/dist/src/tui/operation-history.js +136 -0
  287. package/dist/src/tui/operation-history.js.map +1 -0
  288. package/dist/src/tui/operation-review-planner.d.ts +21 -0
  289. package/dist/src/tui/operation-review-planner.js +1392 -0
  290. package/dist/src/tui/operation-review-planner.js.map +1 -0
  291. package/dist/src/tui/plugin-content.d.ts +31 -0
  292. package/dist/src/tui/plugin-content.js +680 -0
  293. package/dist/src/tui/plugin-content.js.map +1 -0
  294. package/dist/src/tui/plugin-detail.d.ts +52 -0
  295. package/dist/src/tui/plugin-detail.js +165 -0
  296. package/dist/src/tui/plugin-detail.js.map +1 -0
  297. package/dist/src/tui/plugin-write-task.d.ts +69 -0
  298. package/dist/src/tui/plugin-write-task.js +286 -0
  299. package/dist/src/tui/plugin-write-task.js.map +1 -0
  300. package/dist/src/tui/project-inventory.d.ts +68 -0
  301. package/dist/src/tui/project-inventory.js +203 -0
  302. package/dist/src/tui/project-inventory.js.map +1 -0
  303. package/dist/src/tui/prompt.js +4 -15
  304. package/dist/src/tui/prompt.js.map +1 -1
  305. package/dist/src/tui/query-header.d.ts +30 -0
  306. package/dist/src/tui/query-header.js +40 -0
  307. package/dist/src/tui/query-header.js.map +1 -0
  308. package/dist/src/tui/reader.d.ts +37 -0
  309. package/dist/src/tui/reader.js +47 -0
  310. package/dist/src/tui/reader.js.map +1 -0
  311. package/dist/src/tui/router.d.ts +197 -10
  312. package/dist/src/tui/router.js +338 -50
  313. package/dist/src/tui/router.js.map +1 -1
  314. package/dist/src/tui/screen-registry.d.ts +701 -0
  315. package/dist/src/tui/screen-registry.js +230 -0
  316. package/dist/src/tui/screen-registry.js.map +1 -0
  317. package/dist/src/tui/session-console-app.d.ts +6 -0
  318. package/dist/src/tui/session-console-app.js +13 -0
  319. package/dist/src/tui/session-console-app.js.map +1 -0
  320. package/dist/src/tui/session-host.d.ts +45 -0
  321. package/dist/src/tui/session-host.js +209 -0
  322. package/dist/src/tui/session-host.js.map +1 -0
  323. package/dist/src/tui/source-detail-card.d.ts +29 -0
  324. package/dist/src/tui/source-detail-card.js +45 -0
  325. package/dist/src/tui/source-detail-card.js.map +1 -0
  326. package/dist/src/tui/source-ref-presets.d.ts +3 -0
  327. package/dist/src/tui/source-ref-presets.js +11 -0
  328. package/dist/src/tui/source-ref-presets.js.map +1 -0
  329. package/dist/src/tui/theme.d.ts +12 -0
  330. package/dist/src/tui/theme.js +12 -0
  331. package/dist/src/tui/theme.js.map +1 -1
  332. package/dist/src/tui/viewport.d.ts +1 -0
  333. package/dist/src/tui/viewport.js +23 -0
  334. package/dist/src/tui/viewport.js.map +1 -1
  335. package/dist/src/tui/views.js +31 -3
  336. package/dist/src/tui/views.js.map +1 -1
  337. package/dist/src/tui/wizard.js +37 -13
  338. package/dist/src/tui/wizard.js.map +1 -1
  339. package/dist/src/types.d.ts +264 -21
  340. package/dist/src/types.js +1 -0
  341. package/dist/src/types.js.map +1 -1
  342. package/dist/src/utils/agent-version.d.ts +7 -1
  343. package/dist/src/utils/agent-version.js +36 -7
  344. package/dist/src/utils/agent-version.js.map +1 -1
  345. package/dist/src/utils/artifact-plan.d.ts +8 -6
  346. package/dist/src/utils/artifact-plan.js +67 -13
  347. package/dist/src/utils/artifact-plan.js.map +1 -1
  348. package/dist/src/utils/artifact-renderer.d.ts +24 -10
  349. package/dist/src/utils/artifact-renderer.js +230 -220
  350. package/dist/src/utils/artifact-renderer.js.map +1 -1
  351. package/dist/src/utils/artifact-request.d.ts +32 -0
  352. package/dist/src/utils/artifact-request.js +90 -0
  353. package/dist/src/utils/artifact-request.js.map +1 -0
  354. package/dist/src/utils/artifact-sources.d.ts +4 -0
  355. package/dist/src/utils/artifact-sources.js +17 -0
  356. package/dist/src/utils/artifact-sources.js.map +1 -1
  357. package/dist/src/utils/aw-home-mutation-lock.d.ts +1 -0
  358. package/dist/src/utils/aw-home-mutation-lock.js +32 -4
  359. package/dist/src/utils/aw-home-mutation-lock.js.map +1 -1
  360. package/dist/src/utils/bundle-integrity.d.ts +0 -1
  361. package/dist/src/utils/bundle-integrity.js +0 -25
  362. package/dist/src/utils/bundle-integrity.js.map +1 -1
  363. package/dist/src/utils/bundle-layout.js +29 -29
  364. package/dist/src/utils/bundle-layout.js.map +1 -1
  365. package/dist/src/utils/catalog-capability-projection.d.ts +8 -0
  366. package/dist/src/utils/catalog-capability-projection.js +14 -0
  367. package/dist/src/utils/catalog-capability-projection.js.map +1 -0
  368. package/dist/src/utils/catalog-digests.d.ts +10 -0
  369. package/dist/src/utils/catalog-digests.js +57 -20
  370. package/dist/src/utils/catalog-digests.js.map +1 -1
  371. package/dist/src/utils/catalog-generation-control-snapshot.d.ts +11 -0
  372. package/dist/src/utils/catalog-generation-control-snapshot.js +45 -0
  373. package/dist/src/utils/catalog-generation-control-snapshot.js.map +1 -0
  374. package/dist/src/utils/catalog-generation-error.d.ts +16 -0
  375. package/dist/src/utils/catalog-generation-error.js +30 -0
  376. package/dist/src/utils/catalog-generation-error.js.map +1 -0
  377. package/dist/src/utils/catalog-generation-resolver.d.ts +44 -0
  378. package/dist/src/utils/catalog-generation-resolver.js +273 -0
  379. package/dist/src/utils/catalog-generation-resolver.js.map +1 -0
  380. package/dist/src/utils/catalog-generation-service.d.ts +172 -0
  381. package/dist/src/utils/catalog-generation-service.js +1271 -0
  382. package/dist/src/utils/catalog-generation-service.js.map +1 -0
  383. package/dist/src/utils/catalog-generation-state.d.ts +22 -0
  384. package/dist/src/utils/catalog-generation-state.js +192 -0
  385. package/dist/src/utils/catalog-generation-state.js.map +1 -0
  386. package/dist/src/utils/catalog-generation-store.d.ts +58 -0
  387. package/dist/src/utils/catalog-generation-store.js +452 -0
  388. package/dist/src/utils/catalog-generation-store.js.map +1 -0
  389. package/dist/src/utils/catalog-manifest-v7.d.ts +5 -0
  390. package/dist/src/utils/{catalog-manifest-v4.js → catalog-manifest-v7.js} +35 -43
  391. package/dist/src/utils/catalog-manifest-v7.js.map +1 -0
  392. package/dist/src/utils/catalog-operation-context.d.ts +20 -0
  393. package/dist/src/utils/catalog-operation-context.js +142 -0
  394. package/dist/src/utils/catalog-operation-context.js.map +1 -0
  395. package/dist/src/utils/catalog-public-error.d.ts +7 -3
  396. package/dist/src/utils/catalog-public-error.js +28 -8
  397. package/dist/src/utils/catalog-public-error.js.map +1 -1
  398. package/dist/src/utils/catalog-runtime-projection.d.ts +3 -0
  399. package/dist/src/utils/catalog-runtime-projection.js +5 -40
  400. package/dist/src/utils/catalog-runtime-projection.js.map +1 -1
  401. package/dist/src/utils/catalog-snapshot.d.ts +5 -3
  402. package/dist/src/utils/catalog-snapshot.js +11 -3
  403. package/dist/src/utils/catalog-snapshot.js.map +1 -1
  404. package/dist/src/utils/catalog-source-identity.d.ts +1 -0
  405. package/dist/src/utils/catalog-source-identity.js +21 -2
  406. package/dist/src/utils/catalog-source-identity.js.map +1 -1
  407. package/dist/src/utils/catalog-source-impact.d.ts +21 -0
  408. package/dist/src/utils/catalog-source-impact.js +344 -0
  409. package/dist/src/utils/catalog-source-impact.js.map +1 -0
  410. package/dist/src/utils/catalog-source-references.d.ts +3 -2
  411. package/dist/src/utils/catalog-source-references.js +195 -347
  412. package/dist/src/utils/catalog-source-references.js.map +1 -1
  413. package/dist/src/utils/catalog-sources.d.ts +15 -1
  414. package/dist/src/utils/catalog-sources.js +206 -27
  415. package/dist/src/utils/catalog-sources.js.map +1 -1
  416. package/dist/src/utils/claude-skills-root.d.ts +8 -0
  417. package/dist/src/utils/claude-skills-root.js +76 -0
  418. package/dist/src/utils/claude-skills-root.js.map +1 -0
  419. package/dist/src/utils/codex-config.d.ts +2 -0
  420. package/dist/src/utils/codex-config.js +26 -5
  421. package/dist/src/utils/codex-config.js.map +1 -1
  422. package/dist/src/utils/codex-manager.d.ts +79 -0
  423. package/dist/src/utils/codex-manager.js +735 -0
  424. package/dist/src/utils/codex-manager.js.map +1 -0
  425. package/dist/src/utils/codex-marketplace-path.d.ts +5 -0
  426. package/dist/src/utils/codex-marketplace-path.js +45 -0
  427. package/dist/src/utils/codex-marketplace-path.js.map +1 -0
  428. package/dist/src/utils/codex-native-observation.d.ts +49 -0
  429. package/dist/src/utils/codex-native-observation.js +154 -0
  430. package/dist/src/utils/codex-native-observation.js.map +1 -0
  431. package/dist/src/utils/codex-native-render-receipt.d.ts +40 -0
  432. package/dist/src/utils/codex-native-render-receipt.js +205 -0
  433. package/dist/src/utils/codex-native-render-receipt.js.map +1 -0
  434. package/dist/src/utils/codex-reconciler.d.ts +126 -0
  435. package/dist/src/utils/codex-reconciler.js +298 -0
  436. package/dist/src/utils/codex-reconciler.js.map +1 -0
  437. package/dist/src/utils/codex-shared-native.d.ts +43 -0
  438. package/dist/src/utils/codex-shared-native.js +81 -0
  439. package/dist/src/utils/codex-shared-native.js.map +1 -0
  440. package/dist/src/utils/codex-skill-staging.d.ts +2 -0
  441. package/dist/src/utils/codex-skill-staging.js.map +1 -1
  442. package/dist/src/utils/codex-skills-root.d.ts +4 -0
  443. package/dist/src/utils/codex-skills-root.js +25 -0
  444. package/dist/src/utils/codex-skills-root.js.map +1 -0
  445. package/dist/src/utils/codex-surface-analysis.d.ts +46 -0
  446. package/dist/src/utils/codex-surface-analysis.js +247 -0
  447. package/dist/src/utils/codex-surface-analysis.js.map +1 -0
  448. package/dist/src/utils/dynamic-skill-tree.d.ts +5 -0
  449. package/dist/src/utils/dynamic-skill-tree.js +56 -7
  450. package/dist/src/utils/dynamic-skill-tree.js.map +1 -1
  451. package/dist/src/utils/git-catalog-provider.d.ts +16 -0
  452. package/dist/src/utils/git-catalog-provider.js +177 -145
  453. package/dist/src/utils/git-catalog-provider.js.map +1 -1
  454. package/dist/src/utils/local-marketplace.d.ts +27 -1
  455. package/dist/src/utils/local-marketplace.js +434 -84
  456. package/dist/src/utils/local-marketplace.js.map +1 -1
  457. package/dist/src/utils/managed-command-closure.d.ts +3 -0
  458. package/dist/src/utils/managed-command-closure.js +35 -0
  459. package/dist/src/utils/managed-command-closure.js.map +1 -0
  460. package/dist/src/utils/managed-command-evidence.d.ts +7 -0
  461. package/dist/src/utils/managed-command-evidence.js +86 -0
  462. package/dist/src/utils/managed-command-evidence.js.map +1 -0
  463. package/dist/src/utils/managed-command-materialization.d.ts +115 -0
  464. package/dist/src/utils/managed-command-materialization.js +359 -0
  465. package/dist/src/utils/managed-command-materialization.js.map +1 -0
  466. package/dist/src/utils/managed-command-runtime.d.ts +33 -0
  467. package/dist/src/utils/managed-command-runtime.js +121 -0
  468. package/dist/src/utils/managed-command-runtime.js.map +1 -0
  469. package/dist/src/utils/managed-command-store.d.ts +128 -0
  470. package/dist/src/utils/managed-command-store.js +589 -0
  471. package/dist/src/utils/managed-command-store.js.map +1 -0
  472. package/dist/src/utils/manifest.d.ts +1 -3
  473. package/dist/src/utils/manifest.js +1 -3
  474. package/dist/src/utils/manifest.js.map +1 -1
  475. package/dist/src/utils/multi-source-catalog.d.ts +3 -9
  476. package/dist/src/utils/multi-source-catalog.js +54 -110
  477. package/dist/src/utils/multi-source-catalog.js.map +1 -1
  478. package/dist/src/utils/native-cli.d.ts +61 -7
  479. package/dist/src/utils/native-cli.js +426 -58
  480. package/dist/src/utils/native-cli.js.map +1 -1
  481. package/dist/src/utils/native-tool-context.d.ts +14 -0
  482. package/dist/src/utils/native-tool-context.js +38 -0
  483. package/dist/src/utils/native-tool-context.js.map +1 -0
  484. package/dist/src/utils/native-tool-review.d.ts +21 -0
  485. package/dist/src/utils/native-tool-review.js +102 -0
  486. package/dist/src/utils/native-tool-review.js.map +1 -0
  487. package/dist/src/utils/orphan-marketplace-cleanup.js +0 -4
  488. package/dist/src/utils/orphan-marketplace-cleanup.js.map +1 -1
  489. package/dist/src/utils/ownership.d.ts +88 -20
  490. package/dist/src/utils/ownership.js +185 -223
  491. package/dist/src/utils/ownership.js.map +1 -1
  492. package/dist/src/utils/path-catalog-provider.d.ts +1 -1
  493. package/dist/src/utils/path-catalog-provider.js +54 -65
  494. package/dist/src/utils/path-catalog-provider.js.map +1 -1
  495. package/dist/src/utils/paths.d.ts +0 -1
  496. package/dist/src/utils/paths.js +0 -1
  497. package/dist/src/utils/paths.js.map +1 -1
  498. package/dist/src/utils/plugin-config-impact.d.ts +40 -0
  499. package/dist/src/utils/plugin-config-impact.js +373 -0
  500. package/dist/src/utils/plugin-config-impact.js.map +1 -0
  501. package/dist/src/utils/plugin-config-write.d.ts +52 -27
  502. package/dist/src/utils/plugin-config-write.js +1112 -298
  503. package/dist/src/utils/plugin-config-write.js.map +1 -1
  504. package/dist/src/utils/plugin-config.d.ts +153 -93
  505. package/dist/src/utils/plugin-config.js +1116 -968
  506. package/dist/src/utils/plugin-config.js.map +1 -1
  507. package/dist/src/utils/plugin-intent-state.d.ts +49 -0
  508. package/dist/src/utils/plugin-intent-state.js +320 -0
  509. package/dist/src/utils/plugin-intent-state.js.map +1 -0
  510. package/dist/src/utils/plugin-scripts.d.ts +66 -125
  511. package/dist/src/utils/plugin-scripts.js +518 -526
  512. package/dist/src/utils/plugin-scripts.js.map +1 -1
  513. package/dist/src/utils/process-lock.js +14 -5
  514. package/dist/src/utils/process-lock.js.map +1 -1
  515. package/dist/src/utils/process-tree.d.ts +2 -2
  516. package/dist/src/utils/process-tree.js +1 -1
  517. package/dist/src/utils/process-tree.js.map +1 -1
  518. package/dist/src/utils/project-boundary.d.ts +11 -13
  519. package/dist/src/utils/project-boundary.js +28 -34
  520. package/dist/src/utils/project-boundary.js.map +1 -1
  521. package/dist/src/utils/rendered-contract.js +18 -1
  522. package/dist/src/utils/rendered-contract.js.map +1 -1
  523. package/dist/src/utils/runtime-config.d.ts +20 -0
  524. package/dist/src/utils/runtime-config.js +75 -0
  525. package/dist/src/utils/runtime-config.js.map +1 -0
  526. package/dist/src/utils/runtime-skill-closure.js +47 -6
  527. package/dist/src/utils/runtime-skill-closure.js.map +1 -1
  528. package/dist/src/utils/safe-fs.d.ts +21 -0
  529. package/dist/src/utils/safe-fs.js +111 -0
  530. package/dist/src/utils/safe-fs.js.map +1 -0
  531. package/dist/src/utils/safe-operation-diagnostic.d.ts +15 -0
  532. package/dist/src/utils/safe-operation-diagnostic.js +33 -0
  533. package/dist/src/utils/safe-operation-diagnostic.js.map +1 -0
  534. package/dist/src/utils/sensitive-content.d.ts +4 -0
  535. package/dist/src/utils/sensitive-content.js +36 -0
  536. package/dist/src/utils/sensitive-content.js.map +1 -0
  537. package/dist/src/utils/state-paths.js +7 -2
  538. package/dist/src/utils/state-paths.js.map +1 -1
  539. package/dist/src/utils/target-eligibility.d.ts +8 -2
  540. package/dist/src/utils/target-eligibility.js +17 -8
  541. package/dist/src/utils/target-eligibility.js.map +1 -1
  542. package/dist/src/utils/windows-claude-shim.d.ts +7 -0
  543. package/dist/src/utils/windows-claude-shim.js +10 -0
  544. package/dist/src/utils/windows-claude-shim.js.map +1 -0
  545. package/dist/src/utils/windows-npm-shim.d.ts +14 -0
  546. package/dist/src/utils/windows-npm-shim.js +140 -0
  547. package/dist/src/utils/windows-npm-shim.js.map +1 -0
  548. package/dist/vitest.config.js +100 -9
  549. package/dist/vitest.config.js.map +1 -1
  550. package/package.json +31 -21
  551. package/dist/authoring/scripts/check-plugin-versions.d.mts +0 -2
  552. package/dist/authoring/scripts/check-plugin-versions.mjs +0 -5
  553. package/dist/authoring/scripts/check-plugin-versions.mjs.map +0 -1
  554. package/dist/scripts/aw-skill-eval-engine.d.ts +0 -13
  555. package/dist/scripts/aw-skill-eval-engine.js +0 -31
  556. package/dist/scripts/aw-skill-eval-engine.js.map +0 -1
  557. package/dist/scripts/codex-eval-app-server.d.ts +0 -89
  558. package/dist/scripts/codex-eval-app-server.js +0 -1228
  559. package/dist/scripts/codex-eval-app-server.js.map +0 -1
  560. package/dist/scripts/codex-eval-isolation.d.ts +0 -61
  561. package/dist/scripts/codex-eval-isolation.js +0 -318
  562. package/dist/scripts/codex-eval-isolation.js.map +0 -1
  563. package/dist/scripts/codex-eval-process-management.d.ts +0 -8
  564. package/dist/scripts/codex-eval-process-management.js +0 -69
  565. package/dist/scripts/codex-eval-process-management.js.map +0 -1
  566. package/dist/scripts/codex-eval-process-tree.d.ts +0 -38
  567. package/dist/scripts/codex-eval-process-tree.js +0 -803
  568. package/dist/scripts/codex-eval-process-tree.js.map +0 -1
  569. package/dist/scripts/codex-eval-runtime-config.d.ts +0 -62
  570. package/dist/scripts/codex-eval-runtime-config.js +0 -843
  571. package/dist/scripts/codex-eval-runtime-config.js.map +0 -1
  572. package/dist/scripts/codex-trigger-eval.d.ts +0 -84
  573. package/dist/scripts/codex-trigger-eval.js +0 -968
  574. package/dist/scripts/codex-trigger-eval.js.map +0 -1
  575. package/dist/scripts/eval-plugin-skills-audited.d.ts +0 -6
  576. package/dist/scripts/eval-plugin-skills-audited.js +0 -261
  577. package/dist/scripts/eval-plugin-skills-audited.js.map +0 -1
  578. package/dist/scripts/eval-plugin-skills.d.ts +0 -45
  579. package/dist/scripts/eval-plugin-skills.js +0 -1586
  580. package/dist/scripts/eval-plugin-skills.js.map +0 -1
  581. package/dist/scripts/eval-run-layout.d.ts +0 -17
  582. package/dist/scripts/eval-run-layout.js +0 -26
  583. package/dist/scripts/eval-run-layout.js.map +0 -1
  584. package/dist/scripts/plugin-eval-contract.d.ts +0 -185
  585. package/dist/scripts/plugin-eval-contract.js +0 -695
  586. package/dist/scripts/plugin-eval-contract.js.map +0 -1
  587. package/dist/scripts/plugin-eval-materializer.d.ts +0 -13
  588. package/dist/scripts/plugin-eval-materializer.js +0 -421
  589. package/dist/scripts/plugin-eval-materializer.js.map +0 -1
  590. package/dist/scripts/skill-reporting.d.ts +0 -212
  591. package/dist/scripts/skill-reporting.js +0 -922
  592. package/dist/scripts/skill-reporting.js.map +0 -1
  593. package/dist/src/commands/review-publication.d.ts +0 -99
  594. package/dist/src/commands/review-publication.js +0 -904
  595. package/dist/src/commands/review-publication.js.map +0 -1
  596. package/dist/src/commands/status-v4.d.ts +0 -123
  597. package/dist/src/commands/status-v4.js +0 -905
  598. package/dist/src/commands/status-v4.js.map +0 -1
  599. package/dist/src/commands/status.d.ts +0 -93
  600. package/dist/src/commands/status.js +0 -442
  601. package/dist/src/commands/status.js.map +0 -1
  602. package/dist/src/utils/active-marketplace-runtime-lock.d.ts +0 -12
  603. package/dist/src/utils/active-marketplace-runtime-lock.js +0 -133
  604. package/dist/src/utils/active-marketplace-runtime-lock.js.map +0 -1
  605. package/dist/src/utils/catalog-manifest-v3.d.ts +0 -2
  606. package/dist/src/utils/catalog-manifest-v3.js +0 -3
  607. package/dist/src/utils/catalog-manifest-v3.js.map +0 -1
  608. package/dist/src/utils/catalog-manifest-v4.d.ts +0 -5
  609. package/dist/src/utils/catalog-manifest-v4.js.map +0 -1
  610. package/dist/src/utils/catalog-source-cache.d.ts +0 -62
  611. package/dist/src/utils/catalog-source-cache.js +0 -296
  612. package/dist/src/utils/catalog-source-cache.js.map +0 -1
  613. package/dist/src/utils/codex-project-surface.d.ts +0 -3
  614. package/dist/src/utils/codex-project-surface.js +0 -49
  615. package/dist/src/utils/codex-project-surface.js.map +0 -1
  616. package/dist/src/utils/lifecycle-active-store.d.ts +0 -175
  617. package/dist/src/utils/lifecycle-active-store.js +0 -1276
  618. package/dist/src/utils/lifecycle-active-store.js.map +0 -1
  619. package/dist/src/utils/plugin-release.d.ts +0 -2
  620. package/dist/src/utils/plugin-release.js +0 -2
  621. package/dist/src/utils/plugin-release.js.map +0 -1
@@ -1,904 +0,0 @@
1
- import { execFile } from 'node:child_process';
2
- import { createHash, randomUUID } from 'node:crypto';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import { promisify } from 'node:util';
6
- import { computeSkillDigest } from '@lesliechan721/agent-skill-eval';
7
- import fs from 'fs-extra';
8
- import { bundleLocalPlugin, prepareLocalPluginBundleSource, } from '../generators/local-plugin.js';
9
- import { createCatalogRuntimeImportResolver } from '../utils/catalog-runtime-projection.js';
10
- import { readPluginManifest } from '../utils/manifest.js';
11
- const execFileAsync = promisify(execFile);
12
- const digestPattern = /^sha256:[0-9a-f]{64}$/u;
13
- const kebabPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
14
- const reviewIdPattern = /^\d{8}T\d{6}Z-[0-9a-f]{8}-[0-9a-f]{8}$/u;
15
- function sha256(bytes) {
16
- return `sha256:${createHash('sha256').update(bytes).digest('hex')}`;
17
- }
18
- function stableJson(value) {
19
- if (Array.isArray(value))
20
- return `[${value.map(stableJson).join(',')}]`;
21
- if (value !== null && typeof value === 'object') {
22
- const record = value;
23
- return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(',')}}`;
24
- }
25
- return JSON.stringify(value);
26
- }
27
- function normalizeJson(value) {
28
- if (Array.isArray(value))
29
- return value.map(normalizeJson);
30
- if (value !== null && typeof value === 'object') {
31
- const record = value;
32
- return Object.fromEntries(Object.keys(record).sort().map((key) => [key, normalizeJson(record[key])]));
33
- }
34
- return value;
35
- }
36
- function prettyJson(value) {
37
- return `${JSON.stringify(normalizeJson(value), null, 2)}\n`;
38
- }
39
- function exactKeys(value, expected, label) {
40
- const actual = Object.keys(value).sort();
41
- const wanted = [...expected].sort();
42
- if (JSON.stringify(actual) !== JSON.stringify(wanted)) {
43
- throw new Error(`${label} has unknown or missing fields.`);
44
- }
45
- }
46
- function isRecord(value) {
47
- return value !== null && typeof value === 'object' && !Array.isArray(value);
48
- }
49
- function assertKebab(value, label) {
50
- if (typeof value !== 'string' || !kebabPattern.test(value)) {
51
- throw new Error(`${label} must use lowercase kebab-case.`);
52
- }
53
- }
54
- function assertReviewKind(value) {
55
- if (!['skill', 'workflow', 'aw-plugin', 'aw-workflow'].includes(String(value))) {
56
- throw new Error('Invalid review kind.');
57
- }
58
- }
59
- function assertSafeRelativePath(value, label) {
60
- if (typeof value !== 'string' || value.length === 0 || value.includes('\\') || value.includes('\0')) {
61
- throw new Error(`${label} must be a safe relative POSIX path.`);
62
- }
63
- const normalized = path.posix.normalize(value);
64
- if (normalized !== value || value === '..' || value.startsWith('../') || path.posix.isAbsolute(value)) {
65
- throw new Error(`${label} must not escape its root.`);
66
- }
67
- }
68
- function assertDigest(value, label) {
69
- if (typeof value !== 'string' || !digestPattern.test(value)) {
70
- throw new Error(`${label} must be a sha256 digest.`);
71
- }
72
- }
73
- function parseScope(value, expectedKind) {
74
- if (!isRecord(value))
75
- throw new Error('Scope must be a JSON object.');
76
- exactKeys(value, [
77
- 'schemaVersion', 'kind', 'id', 'userOutcome', 'entry', 'components',
78
- 'representativePaths', 'externalDependencies', 'excluded',
79
- ], 'Scope');
80
- if (value.schemaVersion !== 1)
81
- throw new Error('Scope schemaVersion must be 1.');
82
- if (value.kind !== 'workflow' && value.kind !== 'aw-workflow') {
83
- throw new Error('Scope kind must be workflow or aw-workflow.');
84
- }
85
- if (expectedKind !== undefined && value.kind !== expectedKind) {
86
- throw new Error(`Scope kind must match review kind ${expectedKind}.`);
87
- }
88
- if (typeof value.id !== 'string' || value.id.trim() === '')
89
- throw new Error('Scope id must be nonempty.');
90
- if (typeof value.userOutcome !== 'string' || value.userOutcome.trim() === '') {
91
- throw new Error('Scope userOutcome must be nonempty.');
92
- }
93
- if (typeof value.entry !== 'string' || value.entry.trim() === '')
94
- throw new Error('Scope entry must be nonempty.');
95
- assertSafeRelativePath(value.entry, 'Scope entry');
96
- if (!Array.isArray(value.components) || value.components.length === 0) {
97
- throw new Error('Scope components must be nonempty.');
98
- }
99
- const components = value.components.map((component, index) => {
100
- if (!isRecord(component))
101
- throw new Error(`Scope component ${index + 1} must be an object.`);
102
- exactKeys(component, ['kind', 'id', 'path', 'digest'], `Scope component ${index + 1}`);
103
- assertKebab(component.kind, `Scope component ${index + 1} kind`);
104
- if (typeof component.id !== 'string' || component.id.trim() === '') {
105
- throw new Error(`Scope component ${index + 1} id must be nonempty.`);
106
- }
107
- assertSafeRelativePath(component.path, `Scope component ${index + 1} path`);
108
- assertDigest(component.digest, `Scope component ${index + 1} digest`);
109
- return component;
110
- });
111
- if (!Array.isArray(value.representativePaths) || value.representativePaths.length === 0) {
112
- throw new Error('Scope representativePaths must be nonempty.');
113
- }
114
- const representativePaths = value.representativePaths.map((entry, index) => {
115
- if (typeof entry !== 'string' || entry.trim() === '') {
116
- throw new Error(`Scope representative path ${index + 1} must be nonempty.`);
117
- }
118
- return entry;
119
- });
120
- if (!Array.isArray(value.externalDependencies) || !Array.isArray(value.excluded)) {
121
- throw new Error('Scope externalDependencies and excluded must be arrays.');
122
- }
123
- return {
124
- schemaVersion: 1,
125
- kind: value.kind,
126
- id: value.id,
127
- userOutcome: value.userOutcome,
128
- entry: value.entry,
129
- components,
130
- representativePaths,
131
- externalDependencies: value.externalDependencies,
132
- excluded: value.excluded,
133
- };
134
- }
135
- function scopeDigest(scope) {
136
- return sha256(stableJson(scope));
137
- }
138
- function encodeTargetId(value) {
139
- return `id-${Buffer.from(value, 'utf8').toString('base64url')}`;
140
- }
141
- function isEncodedTargetId(value) {
142
- if (!value.startsWith('id-') || value.length === 3)
143
- return false;
144
- const decoded = Buffer.from(value.slice(3), 'base64url').toString('utf8');
145
- return decoded.length > 0 && encodeTargetId(decoded) === value;
146
- }
147
- function assertWithin(root, candidate, label) {
148
- const relative = path.relative(root, candidate);
149
- if (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
150
- throw new Error(`${label} escapes the repository.`);
151
- }
152
- }
153
- async function canonicalRepoRoot(repoRoot) {
154
- const resolved = path.resolve(repoRoot);
155
- const stat = await fs.lstat(resolved).catch(() => null);
156
- if (!stat?.isDirectory() || stat.isSymbolicLink())
157
- throw new Error('repoRoot must be a real directory.');
158
- return fs.realpath(resolved);
159
- }
160
- async function assertNoSymlinkChain(root, candidate, label, allowMissing = false) {
161
- assertWithin(root, candidate, label);
162
- const relative = path.relative(root, candidate);
163
- let current = root;
164
- for (const segment of relative.split(path.sep).filter(Boolean)) {
165
- current = path.join(current, segment);
166
- const stat = await fs.lstat(current).catch(() => null);
167
- if (!stat) {
168
- if (allowMissing)
169
- return false;
170
- throw new Error(`${label} does not exist: ${candidate}.`);
171
- }
172
- if (stat.isSymbolicLink())
173
- throw new Error(`${label} cannot use symlinks: ${candidate}.`);
174
- }
175
- return true;
176
- }
177
- async function assertNoSymlinkAncestors(root, candidate, label) {
178
- assertWithin(root, candidate, label);
179
- const relative = path.relative(root, candidate);
180
- let current = root;
181
- for (const segment of relative.split(path.sep).filter(Boolean)) {
182
- current = path.join(current, segment);
183
- const stat = await fs.lstat(current).catch(() => null);
184
- if (!stat)
185
- return;
186
- if (stat.isSymbolicLink())
187
- throw new Error(`${label} cannot use symlinks: ${current}.`);
188
- if (current !== candidate && !stat.isDirectory()) {
189
- throw new Error(`${label} has a non-directory ancestor: ${current}.`);
190
- }
191
- }
192
- }
193
- async function resolveRepoFile(repoRoot, value, label) {
194
- const candidate = path.resolve(repoRoot, value);
195
- await assertNoSymlinkChain(repoRoot, candidate, label);
196
- const stat = await fs.lstat(candidate);
197
- if (!stat.isFile() || stat.isSymbolicLink())
198
- throw new Error(`${label} must be a regular non-symlink file.`);
199
- const real = await fs.realpath(candidate);
200
- assertWithin(repoRoot, real, label);
201
- return real;
202
- }
203
- async function resolveRepoDirectory(repoRoot, candidate, label) {
204
- const resolved = path.resolve(candidate);
205
- await assertNoSymlinkChain(repoRoot, resolved, label);
206
- const stat = await fs.lstat(resolved);
207
- if (!stat.isDirectory() || stat.isSymbolicLink())
208
- throw new Error(`${label} must be a directory.`);
209
- return fs.realpath(resolved);
210
- }
211
- async function resolveSkillTarget(repoRoot, target) {
212
- let root;
213
- let id;
214
- const parts = target.split('/');
215
- const staticId = parts.length === 1 && kebabPattern.test(parts[0]);
216
- const pluginSkillId = parts.length === 2 && parts.every((part) => kebabPattern.test(part));
217
- if (staticId || pluginSkillId) {
218
- if (staticId) {
219
- id = parts[0];
220
- root = path.join(repoRoot, '.agents', 'skills', id);
221
- }
222
- else {
223
- id = target;
224
- root = path.join(repoRoot, 'plugins', parts[0], 'skills', parts[1]);
225
- }
226
- root = await resolveRepoDirectory(repoRoot, root, 'Skill target');
227
- }
228
- else {
229
- root = await resolveRepoDirectory(repoRoot, path.resolve(repoRoot, target), 'Skill target');
230
- const relative = path.relative(repoRoot, root).split(path.sep).join('/');
231
- let match = /^\.agents\/skills\/([^/]+)$/u.exec(relative);
232
- if (match)
233
- id = match[1];
234
- else {
235
- match = /^plugins\/([^/]+)\/skills\/([^/]+)$/u.exec(relative);
236
- if (!match)
237
- throw new Error('Skill target path must identify a static or plugin Skill root.');
238
- id = `${match[1]}/${match[2]}`;
239
- }
240
- }
241
- return { kind: 'skill', id, digest: await computeSkillDigest(root), root };
242
- }
243
- function compareCodepoint(left, right) {
244
- return left < right ? -1 : left > right ? 1 : 0;
245
- }
246
- async function listStrictRegularFiles(root, label) {
247
- const files = [];
248
- async function walk(current, relative = '') {
249
- const entries = await fs.readdir(current, { withFileTypes: true });
250
- entries.sort((left, right) => compareCodepoint(left.name, right.name));
251
- for (const entry of entries) {
252
- const absolute = path.join(current, entry.name);
253
- const childRelative = relative ? path.posix.join(relative, entry.name) : entry.name;
254
- const stat = await fs.lstat(absolute);
255
- if (stat.isSymbolicLink())
256
- throw new Error(`${label} cannot contain symlinks: ${childRelative}.`);
257
- if (stat.isDirectory())
258
- await walk(absolute, childRelative);
259
- else if (stat.isFile())
260
- files.push({
261
- path: childRelative,
262
- mode: process.platform !== 'win32' && (stat.mode & 0o111) !== 0 ? '100755' : '100644',
263
- bytes: await fs.readFile(absolute),
264
- });
265
- else
266
- throw new Error(`${label} must contain only regular files: ${childRelative}.`);
267
- }
268
- }
269
- await walk(root);
270
- return files;
271
- }
272
- async function reviewComponentDigestAtRoot(repoRoot, relativePath, label) {
273
- const candidate = path.resolve(repoRoot, relativePath);
274
- await assertNoSymlinkChain(repoRoot, candidate, label);
275
- const stat = await fs.lstat(candidate);
276
- if (stat.isFile()) {
277
- return productionTreeDigest([{
278
- path: '.',
279
- mode: process.platform !== 'win32' && (stat.mode & 0o111) !== 0 ? '100755' : '100644',
280
- bytes: await fs.readFile(candidate),
281
- }]);
282
- }
283
- if (stat.isDirectory()) {
284
- return productionTreeDigest(await listStrictRegularFiles(candidate, label));
285
- }
286
- throw new Error(`${label} must be a regular file or directory.`);
287
- }
288
- export async function computeReviewComponentDigest(input) {
289
- const repoRoot = await canonicalRepoRoot(input.repoRoot);
290
- const candidate = path.resolve(repoRoot, input.path);
291
- const digest = await reviewComponentDigestAtRoot(repoRoot, input.path, 'Review component');
292
- return {
293
- path: path.relative(repoRoot, candidate).split(path.sep).join('/') || '.',
294
- digest,
295
- };
296
- }
297
- async function assertScopeComponentBindings(repoRoot, scope) {
298
- for (const [index, component] of scope.components.entries()) {
299
- const label = `Scope component ${index + 1}`;
300
- const actual = await reviewComponentDigestAtRoot(repoRoot, component.path, label);
301
- if (actual !== component.digest) {
302
- throw new Error(`${label} digest does not match repository content: ${component.path}.`);
303
- }
304
- }
305
- }
306
- async function assertPluginSourceNodes(root) {
307
- async function walk(current, relative = '') {
308
- const entries = await fs.readdir(current, { withFileTypes: true });
309
- const skillRoot = entries.some((entry) => entry.isFile() && entry.name === 'SKILL.md');
310
- for (const entry of entries) {
311
- if (['.git', 'node_modules', '.DS_Store'].includes(entry.name))
312
- continue;
313
- if (relative === '' && entry.name === 'reports')
314
- continue;
315
- if (skillRoot && ['evals', 'reports'].includes(entry.name))
316
- continue;
317
- const absolute = path.join(current, entry.name);
318
- const childRelative = relative ? path.posix.join(relative, entry.name) : entry.name;
319
- const stat = await fs.lstat(absolute);
320
- if (stat.isSymbolicLink())
321
- throw new Error(`Plugin target cannot contain symlinks: ${childRelative}.`);
322
- if (stat.isDirectory())
323
- await walk(absolute, childRelative);
324
- else if (!stat.isFile())
325
- throw new Error(`Plugin target contains a non-regular node: ${childRelative}.`);
326
- }
327
- }
328
- await walk(root);
329
- }
330
- function productionTreeDigest(files) {
331
- const hash = createHash('sha256');
332
- const update = (value) => {
333
- const bytes = typeof value === 'string' ? Buffer.from(value) : value;
334
- const length = Buffer.allocUnsafe(8);
335
- length.writeBigUInt64BE(BigInt(bytes.length));
336
- hash.update(length);
337
- hash.update(bytes);
338
- };
339
- update('aw-production-records-v1');
340
- for (const file of files.sort((a, b) => compareCodepoint(a.path, b.path))) {
341
- update(file.path);
342
- update(file.mode);
343
- update(createHash('sha256').update(file.bytes).digest());
344
- }
345
- return `sha256:${hash.digest('hex')}`;
346
- }
347
- function productionProviderNames(manifest) {
348
- const names = [
349
- ...(manifest.buildConfig?.buildImports ?? []).map((entry) => entry.plugin),
350
- ...(manifest.buildConfig?.skillRuntimeFiles ?? [])
351
- .flatMap((entry) => entry.import ? [entry.import.plugin] : []),
352
- ...(manifest.artifacts?.targets ?? [])
353
- .flatMap((target) => (target.runtimeImports ?? []).map((entry) => entry.plugin)),
354
- ];
355
- return [...new Set(names.filter((name) => !name.startsWith('@aw/')))].sort(compareCodepoint);
356
- }
357
- async function resolveProductionProviderSourceSet(repoRoot, plugin) {
358
- const plugins = [plugin];
359
- for (const providerName of productionProviderNames(plugin.manifest)) {
360
- const roots = [...new Set([
361
- path.join(repoRoot, 'plugins', providerName),
362
- path.join(path.dirname(plugin.rootDir), providerName),
363
- ].map((candidate) => path.resolve(candidate)))];
364
- for (const root of roots) {
365
- if (root === plugin.rootDir)
366
- continue;
367
- const rootLabel = `Provider plugin "${providerName}" root`;
368
- if (!await assertNoSymlinkChain(repoRoot, root, rootLabel, true))
369
- continue;
370
- const providerRoot = await resolveRepoDirectory(repoRoot, root, rootLabel);
371
- const metadataPath = path.join(providerRoot, '.agents-plugin');
372
- const metadataLabel = `Provider plugin "${providerName}" metadata`;
373
- if (!await assertNoSymlinkChain(repoRoot, metadataPath, metadataLabel, true))
374
- continue;
375
- await resolveRepoDirectory(repoRoot, metadataPath, metadataLabel);
376
- const manifestPath = path.join(metadataPath, 'plugin.json');
377
- const manifestLabel = `Provider plugin "${providerName}" manifest`;
378
- if (!await assertNoSymlinkChain(repoRoot, manifestPath, manifestLabel, true))
379
- continue;
380
- await resolveRepoFile(repoRoot, manifestPath, manifestLabel);
381
- plugins.push(await readPluginManifest(providerRoot));
382
- }
383
- }
384
- return plugins;
385
- }
386
- async function pluginProductionDigest(repoRoot, pluginRoot) {
387
- await assertPluginSourceNodes(pluginRoot);
388
- const plugin = await readPluginManifest(pluginRoot);
389
- const plugins = await resolveProductionProviderSourceSet(repoRoot, plugin);
390
- const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'aw-review-plugin-bundle-'));
391
- let prepared;
392
- try {
393
- prepared = await prepareLocalPluginBundleSource(plugin, {
394
- buildMode: 'staging',
395
- runtimeResolver: createCatalogRuntimeImportResolver(plugins),
396
- });
397
- const bundleRoot = path.join(tempRoot, 'bundle');
398
- await bundleLocalPlugin(prepared.plugin, bundleRoot, {
399
- buildMode: 'prepared',
400
- preparedRuntimeContext: prepared.runtimeContext,
401
- });
402
- return productionTreeDigest(await listStrictRegularFiles(bundleRoot, 'Plugin production bundle'));
403
- }
404
- finally {
405
- await Promise.all([
406
- prepared?.cleanup() ?? Promise.resolve(),
407
- fs.remove(tempRoot),
408
- ]);
409
- }
410
- }
411
- async function resolvePluginTarget(repoRoot, target) {
412
- const defaultRoot = path.join(repoRoot, 'plugins', target);
413
- const pathTarget = path.resolve(repoRoot, target);
414
- const idTarget = kebabPattern.test(target)
415
- && (await fs.pathExists(defaultRoot) || !await fs.pathExists(pathTarget));
416
- let root;
417
- if (!idTarget) {
418
- root = await resolveRepoDirectory(repoRoot, pathTarget, 'Plugin target');
419
- }
420
- else {
421
- assertKebab(target, 'Plugin id');
422
- root = await resolveRepoDirectory(repoRoot, defaultRoot, 'Plugin target');
423
- }
424
- const manifestPath = await resolveRepoFile(repoRoot, path.join(root, '.agents-plugin', 'plugin.json'), 'Plugin manifest');
425
- const manifest = await fs.readJson(manifestPath);
426
- if (!isRecord(manifest))
427
- throw new Error('Plugin manifest must be a JSON object.');
428
- assertKebab(manifest.name, 'Plugin manifest name');
429
- if (path.basename(root) !== manifest.name)
430
- throw new Error('Plugin manifest name must match target id.');
431
- if (idTarget && target !== manifest.name)
432
- throw new Error('Plugin target id does not match manifest name.');
433
- return {
434
- kind: 'aw-plugin',
435
- id: manifest.name,
436
- digest: await pluginProductionDigest(repoRoot, root),
437
- root,
438
- };
439
- }
440
- async function resolveWorkflowTarget(repoRoot, kind, target, scopePath) {
441
- if (!scopePath)
442
- throw new Error(`${kind} publication requires scope.`);
443
- const resolvedScopePath = await resolveRepoFile(repoRoot, scopePath, 'Scope');
444
- const scope = parseScope(await fs.readJson(resolvedScopePath), kind);
445
- await assertScopeComponentBindings(repoRoot, scope);
446
- if (target === scope.id) {
447
- return { kind, id: scope.id, digest: scopeDigest(scope), scope };
448
- }
449
- if (await fs.pathExists(path.resolve(repoRoot, target))) {
450
- const resolvedTarget = await resolveRepoFile(repoRoot, target, 'Workflow target');
451
- if (resolvedTarget !== resolvedScopePath)
452
- throw new Error('Workflow path target must be the scope file itself.');
453
- }
454
- else {
455
- throw new Error('Workflow target must match scope id.');
456
- }
457
- return { kind, id: scope.id, digest: scopeDigest(scope), scope };
458
- }
459
- async function resolveTarget(repoRoot, kind, target, scope) {
460
- if (kind === 'skill') {
461
- if (scope !== undefined)
462
- throw new Error('skill publication does not accept scope.');
463
- return resolveSkillTarget(repoRoot, target);
464
- }
465
- if (kind === 'aw-plugin') {
466
- if (scope !== undefined)
467
- throw new Error('aw-plugin publication does not accept scope.');
468
- return resolvePluginTarget(repoRoot, target);
469
- }
470
- return resolveWorkflowTarget(repoRoot, kind, target, scope);
471
- }
472
- async function readJsonAttachment(repoRoot, value, label) {
473
- const file = await resolveRepoFile(repoRoot, value, label);
474
- try {
475
- return JSON.parse(await fs.readFile(file, 'utf8'));
476
- }
477
- catch {
478
- throw new Error(`${label} must contain valid JSON.`);
479
- }
480
- }
481
- function validateAttachmentInputs(values, label) {
482
- const seen = new Set();
483
- for (const value of values) {
484
- assertKebab(value.kind, `${label} kind`);
485
- if (seen.has(value.kind))
486
- throw new Error(`${label} kind must be unique: ${value.kind}.`);
487
- seen.add(value.kind);
488
- }
489
- }
490
- export function parseReviewAttachment(value, label = 'Attachment') {
491
- const separator = value.indexOf('=');
492
- if (separator <= 0 || separator === value.length - 1) {
493
- throw new Error(`${label} must use <kind>=<path>.`);
494
- }
495
- const attachment = { kind: value.slice(0, separator), path: value.slice(separator + 1) };
496
- assertKebab(attachment.kind, `${label} kind`);
497
- return attachment;
498
- }
499
- async function gitSource(repoRoot) {
500
- let commit;
501
- try {
502
- const head = await execFileAsync('git', ['rev-parse', 'HEAD'], { cwd: repoRoot, encoding: 'utf8' });
503
- commit = head.stdout.trim();
504
- }
505
- catch {
506
- throw new Error('Review publication requires a Git commit.');
507
- }
508
- if (!/^[0-9a-f]{40,64}$/u.test(commit))
509
- throw new Error('Review publication requires a valid Git commit.');
510
- const status = await execFileAsync('git', [
511
- 'status', '--porcelain=v1', '--untracked-files=normal', '--', '.',
512
- ':(exclude)reports/reviews/**',
513
- ], { cwd: repoRoot, encoding: 'utf8' });
514
- return { commit, dirty: status.stdout.trim() !== '' };
515
- }
516
- function timestamp(date) {
517
- if (Number.isNaN(date.getTime()))
518
- throw new Error('Publication time must be valid.');
519
- return date.toISOString().replace(/[-:]/gu, '').replace(/\.\d{3}Z$/u, 'Z');
520
- }
521
- function createReviewId(date, targetDigest, reportDigest) {
522
- return `${timestamp(date)}-${targetDigest.slice(7, 15)}-${reportDigest.slice(7, 15)}`;
523
- }
524
- function manifestFile(pathValue, bytes) {
525
- return { path: pathValue, digest: sha256(bytes) };
526
- }
527
- async function findManifestPaths(repoRoot) {
528
- const root = path.join(repoRoot, 'reports', 'reviews');
529
- if (!await fs.pathExists(root))
530
- return [];
531
- await assertNoSymlinkChain(repoRoot, root, 'Review storage');
532
- if (!(await fs.lstat(root)).isDirectory())
533
- throw new Error('Review storage must be a directory.');
534
- const result = [];
535
- for (const kindEntry of (await fs.readdir(root, { withFileTypes: true }))
536
- .sort((left, right) => compareCodepoint(left.name, right.name))) {
537
- const kindRoot = path.join(root, kindEntry.name);
538
- if (kindEntry.isSymbolicLink() || !kindEntry.isDirectory()) {
539
- throw new Error(`Review storage kind must be a regular directory: ${kindRoot}.`);
540
- }
541
- assertReviewKind(kindEntry.name);
542
- for (const targetEntry of (await fs.readdir(kindRoot, { withFileTypes: true }))
543
- .sort((left, right) => compareCodepoint(left.name, right.name))) {
544
- const targetRoot = path.join(kindRoot, targetEntry.name);
545
- if (targetEntry.isSymbolicLink() || !targetEntry.isDirectory() || !isEncodedTargetId(targetEntry.name)) {
546
- throw new Error(`Review storage target must be one encoded directory: ${targetRoot}.`);
547
- }
548
- for (const recordEntry of (await fs.readdir(targetRoot, { withFileTypes: true }))
549
- .sort((left, right) => compareCodepoint(left.name, right.name))) {
550
- if (recordEntry.name.startsWith('.tmp-'))
551
- continue;
552
- const recordRoot = path.join(targetRoot, recordEntry.name);
553
- if (recordEntry.isSymbolicLink()
554
- || !recordEntry.isDirectory()
555
- || !reviewIdPattern.test(recordEntry.name)) {
556
- throw new Error(`Review storage contains a foreign record: ${recordRoot}.`);
557
- }
558
- const manifestPath = path.join(recordRoot, 'manifest.json');
559
- const manifestStat = await fs.lstat(manifestPath).catch(() => null);
560
- if (!manifestStat?.isFile() || manifestStat.isSymbolicLink()) {
561
- throw new Error(`Review record is missing a regular manifest: ${recordRoot}.`);
562
- }
563
- result.push(manifestPath);
564
- }
565
- }
566
- }
567
- return result;
568
- }
569
- function parseManifest(value) {
570
- if (!isRecord(value))
571
- throw new Error('Review manifest must be an object.');
572
- exactKeys(value, [
573
- 'schemaVersion', 'reviewId', 'publishedAt', 'target', 'report', 'result',
574
- 'checks', 'evidence', 'releaseCheck', 'source', 'supersedes',
575
- ], 'Review manifest');
576
- if (value.schemaVersion !== 1)
577
- throw new Error('Review manifest schemaVersion must be 1.');
578
- if (typeof value.reviewId !== 'string' || !reviewIdPattern.test(value.reviewId))
579
- throw new Error('Invalid reviewId.');
580
- if (typeof value.publishedAt !== 'string'
581
- || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/u.test(value.publishedAt)
582
- || Number.isNaN(Date.parse(value.publishedAt)))
583
- throw new Error('Invalid publishedAt.');
584
- if (!isRecord(value.target))
585
- throw new Error('Review target must be an object.');
586
- const targetKeys = value.target.scopePath === undefined ? ['kind', 'id', 'digest'] : ['kind', 'id', 'digest', 'scopePath'];
587
- exactKeys(value.target, targetKeys, 'Review target');
588
- if (!['skill', 'workflow', 'aw-plugin', 'aw-workflow'].includes(String(value.target.kind)))
589
- throw new Error('Invalid target kind.');
590
- if (typeof value.target.id !== 'string' || value.target.id.length === 0)
591
- throw new Error('Invalid target id.');
592
- assertDigest(value.target.digest, 'Target digest');
593
- if (['workflow', 'aw-workflow'].includes(String(value.target.kind))) {
594
- if (value.target.scopePath !== 'scope.json')
595
- throw new Error('Workflow target requires scope.json.');
596
- }
597
- else if (value.target.scopePath !== undefined)
598
- throw new Error('Leaf target cannot use scopePath.');
599
- const parseRef = (entry, expectedPath, label) => {
600
- if (!isRecord(entry))
601
- throw new Error(`${label} must be an object.`);
602
- exactKeys(entry, ['path', 'digest'], label);
603
- if (entry.path !== expectedPath)
604
- throw new Error(`${label} path must be ${expectedPath}.`);
605
- assertDigest(entry.digest, `${label} digest`);
606
- return entry;
607
- };
608
- const parseMany = (entry, root, label) => {
609
- if (!Array.isArray(entry))
610
- throw new Error(`${label} must be an array.`);
611
- const seen = new Set();
612
- return entry.map((item) => {
613
- if (!isRecord(item))
614
- throw new Error(`${label} entry must be an object.`);
615
- exactKeys(item, ['kind', 'path', 'digest'], `${label} entry`);
616
- assertKebab(item.kind, `${label} kind`);
617
- if (seen.has(item.kind))
618
- throw new Error(`${label} kind must be unique.`);
619
- seen.add(item.kind);
620
- if (item.path !== `${root}/${item.kind}.json`)
621
- throw new Error(`${label} path is invalid.`);
622
- assertDigest(item.digest, `${label} digest`);
623
- return item;
624
- });
625
- };
626
- if (!isRecord(value.source))
627
- throw new Error('Review source must be an object.');
628
- exactKeys(value.source, ['commit', 'dirty'], 'Review source');
629
- if (typeof value.source.commit !== 'string' || !/^[0-9a-f]{40,64}$/u.test(value.source.commit))
630
- throw new Error('Invalid source commit.');
631
- if (typeof value.source.dirty !== 'boolean')
632
- throw new Error('Invalid source dirty value.');
633
- if (value.supersedes !== null && (typeof value.supersedes !== 'string' || !reviewIdPattern.test(value.supersedes))) {
634
- throw new Error('Invalid supersedes review id.');
635
- }
636
- return {
637
- schemaVersion: 1,
638
- reviewId: value.reviewId,
639
- publishedAt: value.publishedAt,
640
- target: value.target,
641
- report: parseRef(value.report, 'report.md', 'Report'),
642
- result: value.result === null ? null : parseRef(value.result, 'review-result.json', 'Result'),
643
- checks: parseMany(value.checks, 'checks', 'Checks'),
644
- evidence: parseMany(value.evidence, 'evidence', 'Evidence'),
645
- releaseCheck: value.releaseCheck === null ? null : parseRef(value.releaseCheck, 'release-check.json', 'Release check'),
646
- source: value.source,
647
- supersedes: value.supersedes,
648
- };
649
- }
650
- async function verifyJsonFile(root, reference, label) {
651
- const file = path.join(root, ...reference.path.split('/'));
652
- await assertNoSymlinkChain(root, file, label);
653
- const bytes = await fs.readFile(file);
654
- if (sha256(bytes) !== reference.digest)
655
- throw new Error(`${label} digest mismatch.`);
656
- let parsed;
657
- try {
658
- parsed = JSON.parse(bytes.toString('utf8'));
659
- }
660
- catch {
661
- throw new Error(`${label} is invalid JSON.`);
662
- }
663
- if (bytes.toString('utf8') !== prettyJson(parsed))
664
- throw new Error(`${label} is not canonical archived JSON.`);
665
- }
666
- async function verifyAtRoot(repoRoot, root, requireLocation = true) {
667
- await assertNoSymlinkChain(repoRoot, root, 'Review record');
668
- const manifestPath = path.join(root, 'manifest.json');
669
- await assertNoSymlinkChain(root, manifestPath, 'Review manifest');
670
- const manifest = parseManifest(await fs.readJson(manifestPath));
671
- if (requireLocation) {
672
- const expected = path.join(repoRoot, 'reports', 'reviews', manifest.target.kind, encodeTargetId(manifest.target.id), manifest.reviewId);
673
- if (root !== expected)
674
- throw new Error('Review record storage path does not match manifest identity.');
675
- }
676
- const expectedFiles = new Set(['manifest.json', 'report.md']);
677
- if (manifest.target.scopePath)
678
- expectedFiles.add(manifest.target.scopePath);
679
- if (manifest.result)
680
- expectedFiles.add(manifest.result.path);
681
- if (manifest.releaseCheck)
682
- expectedFiles.add(manifest.releaseCheck.path);
683
- for (const entry of [...manifest.checks, ...manifest.evidence])
684
- expectedFiles.add(entry.path);
685
- const actualFiles = [];
686
- async function collect(current, relative = '') {
687
- for (const entry of await fs.readdir(current, { withFileTypes: true })) {
688
- const absolute = path.join(current, entry.name);
689
- const child = relative ? path.posix.join(relative, entry.name) : entry.name;
690
- if (entry.isSymbolicLink())
691
- throw new Error(`Review record cannot contain symlinks: ${child}.`);
692
- if (entry.isDirectory())
693
- await collect(absolute, child);
694
- else if (entry.isFile())
695
- actualFiles.push(child);
696
- else
697
- throw new Error(`Review record contains a non-regular node: ${child}.`);
698
- }
699
- }
700
- await collect(root);
701
- if (JSON.stringify(actualFiles.sort()) !== JSON.stringify([...expectedFiles].sort())) {
702
- throw new Error('Review record file inventory does not match its manifest.');
703
- }
704
- const reportBytes = await fs.readFile(path.join(root, manifest.report.path));
705
- if (sha256(reportBytes) !== manifest.report.digest)
706
- throw new Error('Report digest mismatch.');
707
- const expectedReviewId = createReviewId(new Date(manifest.publishedAt), manifest.target.digest, manifest.report.digest);
708
- if (manifest.reviewId !== expectedReviewId) {
709
- throw new Error('Review manifest identity does not match its publication inputs.');
710
- }
711
- for (const entry of manifest.checks)
712
- await verifyJsonFile(root, entry, `Check ${entry.kind}`);
713
- for (const entry of manifest.evidence)
714
- await verifyJsonFile(root, entry, `Evidence ${entry.kind}`);
715
- if (manifest.result)
716
- await verifyJsonFile(root, manifest.result, 'Review result');
717
- if (manifest.releaseCheck)
718
- await verifyJsonFile(root, manifest.releaseCheck, 'Release check');
719
- if (manifest.target.scopePath) {
720
- const scopeFile = path.join(root, manifest.target.scopePath);
721
- const bytes = await fs.readFile(scopeFile);
722
- const parsed = parseScope(JSON.parse(bytes.toString('utf8')), manifest.target.kind);
723
- if (bytes.toString('utf8') !== prettyJson(parsed))
724
- throw new Error('Scope is not canonical archived JSON.');
725
- if (parsed.id !== manifest.target.id || scopeDigest(parsed) !== manifest.target.digest) {
726
- throw new Error('Scope target binding mismatch.');
727
- }
728
- }
729
- return manifest;
730
- }
731
- export async function verifyReviewRecord(input) {
732
- const repoRoot = await canonicalRepoRoot(input.repoRoot);
733
- const suppliedRepoRoot = path.resolve(input.repoRoot);
734
- const supplied = path.resolve(suppliedRepoRoot, input.reportDir);
735
- const suppliedRelative = path.relative(suppliedRepoRoot, supplied);
736
- const isSafeRelative = (value) => value !== '..' && !value.startsWith(`..${path.sep}`) && !path.isAbsolute(value);
737
- const root = isSafeRelative(suppliedRelative)
738
- ? path.join(repoRoot, suppliedRelative)
739
- : supplied;
740
- await assertNoSymlinkChain(repoRoot, root, 'Review record');
741
- if (!(await fs.lstat(root)).isDirectory())
742
- throw new Error('Review record must be a directory.');
743
- const manifest = await verifyAtRoot(repoRoot, root);
744
- return { root, manifest, existing: true };
745
- }
746
- async function findByReviewId(repoRoot, reviewId) {
747
- const manifests = await findManifestPaths(repoRoot);
748
- return manifests.filter((entry) => path.basename(path.dirname(entry)) === reviewId).map(path.dirname);
749
- }
750
- async function assertSupersedes(repoRoot, target, reviewId) {
751
- if (reviewId === undefined)
752
- return null;
753
- if (!reviewIdPattern.test(reviewId))
754
- throw new Error('supersedes must be a valid review id.');
755
- const matches = await findByReviewId(repoRoot, reviewId);
756
- if (matches.length !== 1)
757
- throw new Error('supersedes must identify one existing review record.');
758
- const manifest = await verifyAtRoot(repoRoot, matches[0]);
759
- if (manifest.target.kind !== target.kind || manifest.target.id !== target.id) {
760
- throw new Error('supersedes must reference the same kind and target.');
761
- }
762
- return reviewId;
763
- }
764
- function equivalentRequest(left, right) {
765
- const normalize = (manifest) => ({
766
- target: manifest.target,
767
- report: manifest.report,
768
- result: manifest.result,
769
- checks: manifest.checks,
770
- evidence: manifest.evidence,
771
- releaseCheck: manifest.releaseCheck,
772
- source: manifest.source,
773
- supersedes: manifest.supersedes,
774
- });
775
- return stableJson(normalize(left)) === stableJson(normalize(right));
776
- }
777
- export async function publishReviewRecord(input) {
778
- const repoRoot = await canonicalRepoRoot(input.repoRoot);
779
- assertReviewKind(input.kind);
780
- const target = await resolveTarget(repoRoot, input.kind, input.target, input.scope);
781
- const reportPath = await resolveRepoFile(repoRoot, input.report, 'Report');
782
- const reportBytes = await fs.readFile(reportPath);
783
- const checks = input.checks ?? [];
784
- const evidence = input.evidence ?? [];
785
- validateAttachmentInputs(checks, 'Check');
786
- validateAttachmentInputs(evidence, 'Evidence');
787
- const archivedChecks = (await Promise.all(checks.map(async (entry) => ({
788
- kind: entry.kind,
789
- bytes: prettyJson(await readJsonAttachment(repoRoot, entry.path, `Check ${entry.kind}`)),
790
- })))).sort((left, right) => compareCodepoint(left.kind, right.kind));
791
- const archivedEvidence = (await Promise.all(evidence.map(async (entry) => ({
792
- kind: entry.kind,
793
- bytes: prettyJson(await readJsonAttachment(repoRoot, entry.path, `Evidence ${entry.kind}`)),
794
- })))).sort((left, right) => compareCodepoint(left.kind, right.kind));
795
- const resultBytes = input.result === undefined ? null
796
- : prettyJson(await readJsonAttachment(repoRoot, input.result, 'Review result'));
797
- const releaseCheckBytes = input.releaseCheck === undefined ? null
798
- : prettyJson(await readJsonAttachment(repoRoot, input.releaseCheck, 'Release check'));
799
- const source = await gitSource(repoRoot);
800
- const supersedes = await assertSupersedes(repoRoot, target, input.supersedes);
801
- const publicationTime = input.now ?? new Date();
802
- const publishedAt = publicationTime.toISOString();
803
- const targetManifest = target.scope
804
- ? { kind: target.kind, id: target.id, digest: target.digest, scopePath: 'scope.json' }
805
- : { kind: target.kind, id: target.id, digest: target.digest };
806
- const report = manifestFile('report.md', reportBytes);
807
- const provisional = {
808
- schemaVersion: 1,
809
- reviewId: createReviewId(publicationTime, target.digest, report.digest),
810
- publishedAt,
811
- target: targetManifest,
812
- report,
813
- result: resultBytes === null ? null : manifestFile('review-result.json', resultBytes),
814
- checks: archivedChecks.map((entry) => ({ kind: entry.kind, ...manifestFile(`checks/${entry.kind}.json`, entry.bytes) })),
815
- evidence: archivedEvidence.map((entry) => ({ kind: entry.kind, ...manifestFile(`evidence/${entry.kind}.json`, entry.bytes) })),
816
- releaseCheck: releaseCheckBytes === null ? null : manifestFile('release-check.json', releaseCheckBytes),
817
- source,
818
- supersedes,
819
- };
820
- const targetParent = path.join(repoRoot, 'reports', 'reviews', target.kind, encodeTargetId(target.id));
821
- await assertNoSymlinkAncestors(repoRoot, targetParent, 'Review storage');
822
- if (await fs.pathExists(targetParent)) {
823
- for (const entry of await fs.readdir(targetParent, { withFileTypes: true })) {
824
- if (entry.name.startsWith('.tmp-'))
825
- continue;
826
- const existingRoot = path.join(targetParent, entry.name);
827
- if (entry.isSymbolicLink() || !entry.isDirectory() || !reviewIdPattern.test(entry.name)) {
828
- throw new Error(`Review storage contains a foreign record: ${existingRoot}.`);
829
- }
830
- const manifest = await verifyAtRoot(repoRoot, existingRoot);
831
- if (manifest.target.digest === target.digest && manifest.report.digest === report.digest) {
832
- if (equivalentRequest(manifest, provisional))
833
- return { root: existingRoot, manifest, existing: true };
834
- throw new Error('A review with the same target and report digests has conflicting publication inputs.');
835
- }
836
- }
837
- }
838
- const destination = path.join(targetParent, provisional.reviewId);
839
- if (await fs.pathExists(destination))
840
- throw new Error(`Review record already exists: ${provisional.reviewId}.`);
841
- await fs.ensureDir(targetParent);
842
- const staging = path.join(targetParent, `.tmp-${process.pid}-${randomUUID()}`);
843
- await fs.mkdir(staging);
844
- try {
845
- if (await fs.pathExists(destination))
846
- throw new Error(`Review record already exists: ${provisional.reviewId}.`);
847
- await fs.writeFile(path.join(staging, 'report.md'), reportBytes, { flag: 'wx' });
848
- if (target.scope)
849
- await fs.writeFile(path.join(staging, 'scope.json'), prettyJson(target.scope), { flag: 'wx' });
850
- if (resultBytes !== null)
851
- await fs.writeFile(path.join(staging, 'review-result.json'), resultBytes, { flag: 'wx' });
852
- if (releaseCheckBytes !== null)
853
- await fs.writeFile(path.join(staging, 'release-check.json'), releaseCheckBytes, { flag: 'wx' });
854
- if (archivedChecks.length > 0)
855
- await fs.mkdir(path.join(staging, 'checks'));
856
- for (const entry of archivedChecks)
857
- await fs.writeFile(path.join(staging, 'checks', `${entry.kind}.json`), entry.bytes, { flag: 'wx' });
858
- if (archivedEvidence.length > 0)
859
- await fs.mkdir(path.join(staging, 'evidence'));
860
- for (const entry of archivedEvidence)
861
- await fs.writeFile(path.join(staging, 'evidence', `${entry.kind}.json`), entry.bytes, { flag: 'wx' });
862
- await fs.writeFile(path.join(staging, 'manifest.json'), prettyJson(provisional), { flag: 'wx' });
863
- await verifyAtRoot(repoRoot, staging, false);
864
- await input.beforeCommit?.();
865
- await fs.rename(staging, destination);
866
- }
867
- catch (error) {
868
- await fs.remove(staging);
869
- throw error;
870
- }
871
- return { root: destination, manifest: provisional, existing: false };
872
- }
873
- export async function listReviewRecords(input) {
874
- const repoRoot = await canonicalRepoRoot(input.repoRoot);
875
- if (input.kind !== undefined)
876
- assertReviewKind(input.kind);
877
- const records = [];
878
- for (const manifestPath of await findManifestPaths(repoRoot)) {
879
- const root = path.dirname(manifestPath);
880
- await assertNoSymlinkChain(repoRoot, manifestPath, 'Review manifest');
881
- const manifest = parseManifest(await fs.readJson(manifestPath));
882
- const expected = path.join(repoRoot, 'reports', 'reviews', manifest.target.kind, encodeTargetId(manifest.target.id), manifest.reviewId);
883
- if (root !== expected)
884
- throw new Error('Review record storage path does not match manifest identity.');
885
- if (input.kind !== undefined && manifest.target.kind !== input.kind)
886
- continue;
887
- if (input.targetId !== undefined && manifest.target.id !== input.targetId)
888
- continue;
889
- records.push({ root, manifest, existing: true });
890
- }
891
- return records.sort((left, right) => compareCodepoint(left.manifest.publishedAt, right.manifest.publishedAt)
892
- || compareCodepoint(left.manifest.reviewId, right.manifest.reviewId));
893
- }
894
- export async function showReviewRecord(input) {
895
- const repoRoot = await canonicalRepoRoot(input.repoRoot);
896
- if (!reviewIdPattern.test(input.reviewId))
897
- throw new Error('Invalid reviewId.');
898
- const matches = await findByReviewId(repoRoot, input.reviewId);
899
- if (matches.length !== 1)
900
- throw new Error(`Expected one review record for ${input.reviewId}; found ${matches.length}.`);
901
- const manifest = await verifyAtRoot(repoRoot, matches[0]);
902
- return { root: matches[0], manifest, existing: true };
903
- }
904
- //# sourceMappingURL=review-publication.js.map