@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,11 +1,17 @@
1
1
  import path from 'node:path';
2
2
  import fs from 'fs-extra';
3
- import { SKILL_OWNER_MARKER, readSkillOwnerMarker } from './ownership.js';
3
+ import { normalizeInstalledCommandProducer, validateCommandEntryFiles } from '@lesliechan721/aw-plugin-core/manifest';
4
+ import { readSkillOwnerMarker } from './ownership.js';
4
5
  import { readJsonFile } from './json.js';
5
6
  import { assertStrictSemVer } from './manifest.js';
6
7
  import { resolveCliPackageRoot } from './paths.js';
8
+ import { canonicalizePathThroughExistingAncestor } from './state-paths.js';
7
9
  import { sanitizeCatalogSourceErrorMessage } from './catalog-public-error.js';
8
10
  import { normalizeMarketplaceProductToken } from './platform-support.js';
11
+ import { CODEX_NATIVE_RENDER_RECEIPT_PATH, parseCodexNativeRenderReceipt, serializeCodexNativeRenderReceipt, } from './codex-native-render-receipt.js';
12
+ import { calculateCodexNativeRenderPayloadDigest } from './catalog-digests.js';
13
+ import { createCodexSkillStagingTreeContentDigest } from './codex-skill-staging.js';
14
+ import { readDynamicSkillTree } from './dynamic-skill-tree.js';
9
15
  const SOURCE_IDENTITY_PATTERN = /^sha256:[0-9a-f]{64}$/;
10
16
  export function getNamespacedMarketplaceName(sourceId) {
11
17
  return `aw-${sourceId}`;
@@ -32,6 +38,28 @@ export function projectMarketplaceManifestForPlatform(manifest, platform) {
32
38
  export function getLocalMarketplacePluginRoot(rootDir, pluginName) {
33
39
  return path.join(rootDir, 'plugins', pluginName);
34
40
  }
41
+ export async function assertSafeNamespacedMarketplacePluginRoot(rootDir, pluginName) {
42
+ const pluginsRoot = path.join(rootDir, 'plugins');
43
+ const pluginRoot = getLocalMarketplacePluginRoot(rootDir, pluginName);
44
+ const pluginsStats = await lstatMarketplacePath(pluginsRoot);
45
+ if (pluginsStats && (!pluginsStats.isDirectory() || pluginsStats.isSymbolicLink())) {
46
+ throw new MarketplaceRootValidationError(pluginsRoot, 'marketplace plugins ancestor must be a regular directory.', 'unsafe');
47
+ }
48
+ const pluginStats = pluginsStats ? await lstatMarketplacePath(pluginRoot) : null;
49
+ if (pluginStats && (!pluginStats.isDirectory() || pluginStats.isSymbolicLink())) {
50
+ throw new MarketplaceRootValidationError(pluginRoot, 'marketplace plugin projection must be a regular directory.', 'unsafe');
51
+ }
52
+ const physicalRoot = await fs.realpath(rootDir);
53
+ for (const candidate of [pluginsStats ? pluginsRoot : null, pluginStats ? pluginRoot : null]) {
54
+ if (!candidate)
55
+ continue;
56
+ const relative = path.relative(physicalRoot, await fs.realpath(candidate));
57
+ if (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
58
+ throw new MarketplaceRootValidationError(candidate, 'marketplace plugin path escapes its physical root.', 'unsafe');
59
+ }
60
+ }
61
+ return pluginRoot;
62
+ }
35
63
  export function getLocalMarketplaceCodexSkillsRoot(rootDir, pluginName) {
36
64
  return path.join(getLocalMarketplacePluginRoot(rootDir, pluginName), 'codex', 'skills');
37
65
  }
@@ -47,10 +75,12 @@ export async function readCliPackageInfo() {
47
75
  }
48
76
  export class MarketplaceRootValidationError extends Error {
49
77
  location;
78
+ reason;
50
79
  code = 'marketplaceRootInvalid';
51
- constructor(location, message, cause) {
80
+ constructor(location, message, reason, cause) {
52
81
  super(`marketplaceRootInvalid: ${message}`, cause === undefined ? undefined : { cause });
53
82
  this.location = location;
83
+ this.reason = reason;
54
84
  this.name = 'MarketplaceRootValidationError';
55
85
  }
56
86
  }
@@ -59,7 +89,7 @@ function assertMarketplacePathBoundary(trustedRoot, candidatePath) {
59
89
  const candidate = path.resolve(candidatePath);
60
90
  const relative = path.relative(root, candidate);
61
91
  if (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
62
- throw new MarketplaceRootValidationError(candidate, 'marketplace path escapes its trusted root.');
92
+ throw new MarketplaceRootValidationError(candidate, 'marketplace path escapes its trusted root.', 'unsafe');
63
93
  }
64
94
  return { root, candidate };
65
95
  }
@@ -76,34 +106,48 @@ async function lstatMarketplacePath(filePath) {
76
106
  }
77
107
  async function inspectMarketplacePath(trustedRoot, candidatePath, finalKind) {
78
108
  const { root, candidate } = assertMarketplacePathBoundary(trustedRoot, candidatePath);
79
- const paths = [root];
80
- let current = root;
81
- for (const segment of path.relative(root, candidate).split(path.sep).filter(Boolean)) {
82
- current = path.join(current, segment);
83
- paths.push(current);
84
- }
85
- let candidateStats = null;
86
- for (const currentPath of paths) {
87
- let stats;
88
- try {
89
- stats = await lstatMarketplacePath(currentPath);
90
- }
91
- catch (error) {
92
- throw new MarketplaceRootValidationError(currentPath, 'marketplace path cannot be inspected.', error);
93
- }
94
- if (!stats)
95
- return null;
96
- const isFinal = currentPath === candidate;
97
- const valid = isFinal && finalKind === 'file'
98
- ? stats.isFile() && !stats.isSymbolicLink()
99
- : stats.isDirectory() && !stats.isSymbolicLink();
100
- if (!valid) {
101
- throw new MarketplaceRootValidationError(currentPath, isFinal && finalKind === 'file'
102
- ? 'marketplace JSON target must be a regular file.'
103
- : 'marketplace path must be a regular directory.');
104
- }
105
- if (isFinal)
106
- candidateStats = stats;
109
+ let rootStats;
110
+ let candidateStats;
111
+ try {
112
+ [rootStats, candidateStats] = await Promise.all([
113
+ lstatMarketplacePath(root),
114
+ lstatMarketplacePath(candidate),
115
+ ]);
116
+ }
117
+ catch (error) {
118
+ throw new MarketplaceRootValidationError(candidate, 'marketplace path cannot be inspected.', 'unreadable', error);
119
+ }
120
+ if (!rootStats)
121
+ return null;
122
+ if (!rootStats.isDirectory() || rootStats.isSymbolicLink()) {
123
+ throw new MarketplaceRootValidationError(root, 'marketplace root must be a regular directory.', 'unsafe');
124
+ }
125
+ let physicalRoot;
126
+ let physicalCandidate;
127
+ try {
128
+ [physicalRoot, physicalCandidate] = await Promise.all([
129
+ canonicalizePathThroughExistingAncestor(root),
130
+ canonicalizePathThroughExistingAncestor(candidate),
131
+ ]);
132
+ }
133
+ catch (error) {
134
+ throw new MarketplaceRootValidationError(candidate, 'marketplace path cannot be resolved.', 'unreadable', error);
135
+ }
136
+ try {
137
+ assertMarketplacePathBoundary(physicalRoot, physicalCandidate);
138
+ }
139
+ catch {
140
+ throw new MarketplaceRootValidationError(candidate, 'marketplace physical path escapes its trusted root.', 'unsafe');
141
+ }
142
+ if (!candidateStats)
143
+ return null;
144
+ const valid = finalKind === 'file'
145
+ ? candidateStats.isFile() && !candidateStats.isSymbolicLink()
146
+ : candidateStats.isDirectory() && !candidateStats.isSymbolicLink();
147
+ if (!valid) {
148
+ throw new MarketplaceRootValidationError(candidate, finalKind === 'file'
149
+ ? 'marketplace JSON target must be a regular file.'
150
+ : 'marketplace path must be a regular directory.', 'unsafe');
107
151
  }
108
152
  return candidateStats;
109
153
  }
@@ -113,28 +157,14 @@ async function readStrictOptionalJsonObject(trustedRoot, filePath) {
113
157
  try {
114
158
  const value = await fs.readJson(filePath);
115
159
  if (!isRecord(value)) {
116
- throw new MarketplaceRootValidationError(filePath, 'marketplace JSON must contain an object.');
160
+ throw new MarketplaceRootValidationError(filePath, 'marketplace JSON must contain an object.', 'invalid');
117
161
  }
118
162
  return value;
119
163
  }
120
164
  catch (error) {
121
165
  if (error instanceof MarketplaceRootValidationError)
122
166
  throw error;
123
- throw new MarketplaceRootValidationError(filePath, 'marketplace JSON cannot be read.', error);
124
- }
125
- }
126
- async function readOptionalJsonObject(filePath) {
127
- try {
128
- const value = await fs.readJson(filePath);
129
- if (!isRecord(value))
130
- throw new Error(`Expected a JSON object at ${filePath}.`);
131
- return value;
132
- }
133
- catch (error) {
134
- const code = error.code;
135
- if (code === 'ENOENT' || code === 'ENOTDIR')
136
- return null;
137
- throw error;
167
+ throw new MarketplaceRootValidationError(filePath, 'marketplace JSON cannot be read.', error instanceof SyntaxError ? 'invalid' : 'unreadable', error);
138
168
  }
139
169
  }
140
170
  export async function readStrictNamespacedMarketplaceRoot(options) {
@@ -149,10 +179,12 @@ export async function readStrictNamespacedMarketplaceRoot(options) {
149
179
  || config.sourceId.length === 0
150
180
  || typeof config.sourceIdentity !== 'string'
151
181
  || !SOURCE_IDENTITY_PATTERN.test(config.sourceIdentity)
182
+ || (config.logicalIdentity !== undefined
183
+ && (typeof config.logicalIdentity !== 'string' || config.logicalIdentity.trim() === ''))
152
184
  || typeof config.marketplaceName !== 'string'
153
185
  || config.marketplaceName.length === 0
154
186
  || config.sourceId !== path.basename(options.rootDir)) {
155
- throw new MarketplaceRootValidationError(configPath, 'marketplace config must contain a canonical schema 2 identity.');
187
+ throw new MarketplaceRootValidationError(configPath, 'marketplace config must contain a canonical schema 2 identity.', 'invalid');
156
188
  }
157
189
  if ((options.sourceId !== undefined && config.sourceId !== options.sourceId)
158
190
  || (options.sourceIdentity !== undefined && config.sourceIdentity !== options.sourceIdentity)
@@ -161,11 +193,11 @@ export async function readStrictNamespacedMarketplaceRoot(options) {
161
193
  }
162
194
  const agentsManifest = await readStrictOptionalJsonObject(trustedMarketplaceRoot, path.join(options.rootDir, '.agents', 'plugins', 'marketplace.json'));
163
195
  if (!agentsManifest || agentsManifest.name !== config.marketplaceName) {
164
- throw new MarketplaceRootValidationError(path.join(options.rootDir, '.agents', 'plugins', 'marketplace.json'), 'Codex marketplace manifest name does not match config.');
196
+ throw new MarketplaceRootValidationError(path.join(options.rootDir, '.agents', 'plugins', 'marketplace.json'), 'Codex marketplace manifest name does not match config.', 'invalid');
165
197
  }
166
198
  const claudeManifest = await readStrictOptionalJsonObject(trustedMarketplaceRoot, path.join(options.rootDir, '.claude-plugin', 'marketplace.json'));
167
199
  if (claudeManifest && claudeManifest.name !== config.marketplaceName) {
168
- throw new MarketplaceRootValidationError(path.join(options.rootDir, '.claude-plugin', 'marketplace.json'), 'Claude marketplace manifest name does not match config.');
200
+ throw new MarketplaceRootValidationError(path.join(options.rootDir, '.claude-plugin', 'marketplace.json'), 'Claude marketplace manifest name does not match config.', 'invalid');
169
201
  }
170
202
  return {
171
203
  rootDir: options.rootDir,
@@ -176,8 +208,14 @@ export async function readStrictNamespacedMarketplaceRoot(options) {
176
208
  }
177
209
  function normalizePluginRelativeDirectory(value, fallback) {
178
210
  const raw = typeof value === 'string' ? value : fallback;
179
- const normalized = path.posix.normalize(raw.replace(/^\.\//, ''));
180
- if (!normalized || normalized === '.' || normalized === '..' || normalized.startsWith('../')) {
211
+ const normalizedSeparators = raw.replace(/\\/gu, '/');
212
+ const normalized = path.posix.normalize(normalizedSeparators.replace(/^\.\//, ''));
213
+ if (!normalized
214
+ || normalized === '.'
215
+ || normalized === '..'
216
+ || normalized.startsWith('../')
217
+ || path.posix.isAbsolute(normalizedSeparators)
218
+ || path.win32.isAbsolute(raw)) {
181
219
  return null;
182
220
  }
183
221
  return normalized;
@@ -190,19 +228,337 @@ async function assertTreeHasNoSymlinks(root) {
190
228
  await assertTreeHasNoSymlinks(path.join(root, entry.name));
191
229
  }
192
230
  }
193
- async function pathExists(filePath) {
231
+ class CodexNativeProjectionNotReusableError extends Error {
232
+ }
233
+ function nativeCodexTargets(manifest) {
234
+ const targets = manifest.artifacts?.targets ?? [];
235
+ if (!Array.isArray(targets))
236
+ return [];
237
+ return targets.flatMap((target) => {
238
+ if (!isRecord(target)
239
+ || target.platform !== 'codex'
240
+ || target.target !== 'codex.skill'
241
+ || !isRecord(target.delivery)
242
+ || target.delivery.mode !== 'codex-native'
243
+ || typeof target.id !== 'string'
244
+ || typeof target.skillKey !== 'string')
245
+ return [];
246
+ return [{ id: target.id, skillKey: target.skillKey }];
247
+ }).sort((left, right) => left.id < right.id ? -1 : left.id > right.id ? 1 : 0);
248
+ }
249
+ async function assertRegularProjectionTree(root, rejectOwnerMarker = false) {
250
+ for (const entry of await fs.readdir(root, { withFileTypes: true })) {
251
+ if (entry.isSymbolicLink() || (!entry.isDirectory() && !entry.isFile())) {
252
+ throw new Error(`codexNativeProjectionUnsafe: projection contains an unsafe node: ${entry.name}`);
253
+ }
254
+ if (rejectOwnerMarker && entry.name === '.agent-workflows-owner.json') {
255
+ throw new Error('codexNativeProjectionUnsafe: native Skill cannot contain an AW owner marker.');
256
+ }
257
+ if (entry.isDirectory()) {
258
+ await assertRegularProjectionTree(path.join(root, entry.name), rejectOwnerMarker);
259
+ }
260
+ }
261
+ }
262
+ async function readProjectionJson(trustedRoot, filePath) {
263
+ const stats = await inspectMarketplacePath(trustedRoot, filePath, 'file');
264
+ if (!stats)
265
+ throw new CodexNativeProjectionNotReusableError();
194
266
  try {
195
- await fs.lstat(filePath);
196
- return true;
267
+ const value = await fs.readJson(filePath);
268
+ if (!isRecord(value))
269
+ throw new CodexNativeProjectionNotReusableError();
270
+ return value;
197
271
  }
198
272
  catch (error) {
199
- const code = error.code;
200
- if (code === 'ENOENT' || code === 'ENOTDIR')
201
- return false;
202
- throw error;
273
+ if (error instanceof CodexNativeProjectionNotReusableError)
274
+ throw error;
275
+ if (error.code)
276
+ throw error;
277
+ throw new CodexNativeProjectionNotReusableError();
203
278
  }
204
279
  }
205
- async function readOverlayDirectory(directoryPath, redactedRoots) {
280
+ async function readValidatedCodexProjection(options) {
281
+ const pluginRoot = path.join(options.sourceRoot, 'plugins', options.pluginName);
282
+ const platformManifest = await readProjectionJson(options.sourceRoot, path.join(pluginRoot, '.codex-plugin', 'plugin.json'));
283
+ if (platformManifest.name !== options.pluginName)
284
+ throw new Error('codexNativeProjectionIdentityMismatch: plugin identity does not match its marketplace path.');
285
+ const skillsRelative = normalizePluginRelativeDirectory(platformManifest.skills, 'codex/skills');
286
+ if (!skillsRelative)
287
+ throw new Error('codexNativeProjectionUnsafe: Codex Skills root is unsafe.');
288
+ const receiptPath = path.join(pluginRoot, CODEX_NATIVE_RENDER_RECEIPT_PATH);
289
+ if (!await inspectMarketplacePath(options.sourceRoot, receiptPath, 'file'))
290
+ throw new CodexNativeProjectionNotReusableError();
291
+ let receipt;
292
+ try {
293
+ receipt = parseCodexNativeRenderReceipt(await fs.readFile(receiptPath, 'utf8'));
294
+ }
295
+ catch (error) {
296
+ if (error.code)
297
+ throw error;
298
+ throw new CodexNativeProjectionNotReusableError();
299
+ }
300
+ if (receipt.logicalPluginId !== `${options.sourceId}/${options.pluginName}` || receipt.sourceIdentity !== options.sourceIdentity) {
301
+ throw new Error('codexNativeProjectionIdentityMismatch: receipt identity does not match its marketplace.');
302
+ }
303
+ // The other platform may have updated the common bundle metadata. The installed
304
+ // Codex manifest and verified receipt retain this platform's actual version and targets.
305
+ if (platformManifest.version !== receipt.pluginVersion)
306
+ throw new CodexNativeProjectionNotReusableError();
307
+ const emptyDigest = createCodexSkillStagingTreeContentDigest({ skillKey: 'empty', files: {} });
308
+ for (const target of receipt.targets) {
309
+ const skillRoot = path.join(pluginRoot, ...skillsRelative.split('/'), target.skillKey);
310
+ const stats = await inspectMarketplacePath(options.sourceRoot, skillRoot, 'directory');
311
+ if (stats)
312
+ await assertRegularProjectionTree(skillRoot, true);
313
+ let tree;
314
+ try {
315
+ tree = stats ? await readDynamicSkillTree(skillRoot, 'codex.skill') : null;
316
+ }
317
+ catch (error) {
318
+ if (error.code)
319
+ throw error;
320
+ throw new CodexNativeProjectionNotReusableError();
321
+ }
322
+ if ((stats && !tree) || (tree ? createCodexSkillStagingTreeContentDigest(tree) : emptyDigest) !== target.artifactDigest)
323
+ throw new CodexNativeProjectionNotReusableError();
324
+ }
325
+ if (await calculateCodexNativeRenderPayloadDigest(pluginRoot) !== receipt.payloadDigest)
326
+ throw new CodexNativeProjectionNotReusableError();
327
+ return receipt;
328
+ }
329
+ async function preserveMarketplacePluginProjection(options) {
330
+ const sourcePluginRoot = path.join(options.sourceRoot, 'plugins', options.pluginName);
331
+ const stagingPluginRoot = path.join(options.stagingRoot, 'plugins', options.pluginName);
332
+ const sourceManifest = await readProjectionJson(options.sourceRoot, path.join(sourcePluginRoot, '.agents-plugin', 'plugin.json'));
333
+ const stagingManifest = await readProjectionJson(options.stagingRoot, path.join(stagingPluginRoot, '.agents-plugin', 'plugin.json'));
334
+ if (sourceManifest.name !== options.pluginName || stagingManifest.name !== options.pluginName)
335
+ throw new Error(`${nativeCodexTargets(sourceManifest).length ? 'codexNativeProjectionIdentityMismatch' : 'marketplaceProjectionIdentityMismatch'}: plugin identity does not match its marketplace path.`);
336
+ await assertRegularProjectionTree(sourcePluginRoot);
337
+ await assertRegularProjectionTree(stagingPluginRoot);
338
+ let receipt;
339
+ if (nativeCodexTargets(sourceManifest).length || await inspectMarketplacePath(options.sourceRoot, path.join(sourcePluginRoot, CODEX_NATIVE_RENDER_RECEIPT_PATH), 'file')) {
340
+ receipt = await readValidatedCodexProjection(options);
341
+ }
342
+ else {
343
+ for (const platform of ['codex', 'claude']) {
344
+ const manifestPath = path.join(sourcePluginRoot, `.${platform}-plugin`, 'plugin.json');
345
+ if (!await inspectMarketplacePath(options.sourceRoot, manifestPath, 'file'))
346
+ continue;
347
+ const manifest = await readProjectionJson(options.sourceRoot, manifestPath);
348
+ if (manifest.name !== options.pluginName)
349
+ throw new Error('marketplaceProjectionIdentityMismatch: plugin identity does not match its marketplace path.');
350
+ assertStrictSemVer(manifest.version, 'preserved platform plugin version');
351
+ }
352
+ }
353
+ await fs.remove(stagingPluginRoot);
354
+ await fs.copy(sourcePluginRoot, stagingPluginRoot, { dereference: false });
355
+ if (receipt && await calculateCodexNativeRenderPayloadDigest(stagingPluginRoot) !== receipt.payloadDigest)
356
+ throw new CodexNativeProjectionNotReusableError();
357
+ }
358
+ async function preserveUnrequestedMarketplacePlatforms(options) {
359
+ if (options.requested.has('codex') && options.requested.has('claude'))
360
+ return { platforms: [] };
361
+ const sourcePluginRoot = path.join(options.sourceRoot, 'plugins', options.pluginName);
362
+ const stagingPluginRoot = path.join(options.stagingRoot, 'plugins', options.pluginName);
363
+ const sourceManifest = await readProjectionJson(options.sourceRoot, path.join(sourcePluginRoot, '.agents-plugin', 'plugin.json'));
364
+ if (sourceManifest.name !== options.pluginName)
365
+ throw new Error('marketplaceProjectionIdentityMismatch: retained plugin identity does not match its path.');
366
+ const platforms = [];
367
+ let receipt;
368
+ for (const platform of ['codex', 'claude']) {
369
+ if (options.requested.has(platform))
370
+ continue;
371
+ const manifestRelative = `.${platform}-plugin`;
372
+ if (!await inspectMarketplacePath(options.sourceRoot, path.join(sourcePluginRoot, manifestRelative, 'plugin.json'), 'file'))
373
+ continue;
374
+ const manifest = await readProjectionJson(options.sourceRoot, path.join(sourcePluginRoot, manifestRelative, 'plugin.json'));
375
+ if (manifest.name !== options.pluginName)
376
+ throw new Error('marketplaceProjectionIdentityMismatch: retained platform identity does not match its path.');
377
+ assertStrictSemVer(manifest.version, 'preserved platform plugin version');
378
+ const roots = new Set([platform, manifestRelative]);
379
+ const skillsRelative = manifest.skills === undefined ? undefined : normalizePluginRelativeDirectory(manifest.skills, `${platform}/skills`);
380
+ if (manifest.skills !== undefined) {
381
+ const relative = normalizePluginRelativeDirectory(manifest.skills, `${platform}/skills`);
382
+ if (!relative || ['codex', 'claude'].some((other) => other !== platform && (relative === other || relative.startsWith(`${other}/`))) || ['.agents-plugin', '.codex-plugin', '.claude-plugin'].some((root) => relative === root || relative.startsWith(`${root}/`))) {
383
+ throw new Error('marketplaceProjectionInvalid: retained Skill root overlaps another platform.');
384
+ }
385
+ roots.add(relative);
386
+ }
387
+ for (const requested of options.requested) {
388
+ const requestedManifest = await readProjectionJson(options.stagingRoot, path.join(stagingPluginRoot, `.${requested}-plugin`, 'plugin.json'));
389
+ const requestedSkills = requestedManifest.skills === undefined ? undefined : normalizePluginRelativeDirectory(requestedManifest.skills, `${requested}/skills`);
390
+ if (requestedManifest.skills !== undefined && !requestedSkills)
391
+ throw new Error('marketplaceProjectionInvalid: requested Skill root is unsafe.');
392
+ for (const retainedRoot of roots)
393
+ for (const requestedRoot of [requested, `.${requested}-plugin`, '.agents-plugin', ...(requestedSkills ? [requestedSkills] : [])]) {
394
+ if (retainedRoot === requestedRoot || retainedRoot.startsWith(`${requestedRoot}/`) || requestedRoot.startsWith(`${retainedRoot}/`))
395
+ throw new Error('marketplaceProjectionInvalid: retained platform resources overlap the requested platform.');
396
+ }
397
+ }
398
+ const codexReceipt = platform === 'codex' && await inspectMarketplacePath(options.sourceRoot, path.join(sourcePluginRoot, CODEX_NATIVE_RENDER_RECEIPT_PATH), 'file')
399
+ ? await readValidatedCodexProjection(options) : undefined;
400
+ if (platform === 'codex' && !codexReceipt) {
401
+ for (const target of nativeCodexTargets(sourceManifest)) {
402
+ const tree = skillsRelative ? path.join(sourcePluginRoot, ...skillsRelative.split('/'), target.skillKey) : undefined;
403
+ if (tree && await inspectMarketplacePath(options.sourceRoot, tree, 'directory'))
404
+ throw new Error('codexNativeProjectionDamaged: an installed dynamic Skill has no render receipt; reinstall both platforms.');
405
+ }
406
+ }
407
+ const checked = new Set();
408
+ const validateRecords = async (directory) => {
409
+ if (checked.has(directory))
410
+ return;
411
+ checked.add(directory);
412
+ for (const entry of await fs.readdir(directory, { withFileTypes: true })) {
413
+ const absolute = path.join(directory, entry.name);
414
+ if (entry.isDirectory())
415
+ await validateRecords(absolute);
416
+ else if (entry.name === '.aw-command-producer.json') {
417
+ const record = normalizeInstalledCommandProducer(await fs.readJson(absolute));
418
+ const producer = record.producer;
419
+ if (producer.sourceId !== options.sourceId || producer.sourceIdentity !== options.sourceIdentity || producer.pluginName !== options.pluginName || producer.platform !== platform || producer.scope !== 'user' || producer.projectRoot !== null || producer.kind === 'package')
420
+ throw new Error('commandOwnerMismatch: retained native producer does not match its platform and source.');
421
+ const skillKey = producer.kind === 'static-skill' ? producer.key : codexReceipt?.targets.find((target) => target.id === producer.key)?.skillKey;
422
+ if (!skillsRelative || !skillKey || directory !== path.join(sourcePluginRoot, ...skillsRelative.split('/'), skillKey))
423
+ throw new Error('commandOwnerMismatch: retained native producer is outside its exact Skill path.');
424
+ if (!await readDynamicSkillTree(directory, `${platform}.skill`))
425
+ throw new Error('commandResourceInvalid: retained native producer has no valid Skill.');
426
+ await validateCommandEntryFiles(directory, record.sets.flatMap((set) => set.entries));
427
+ }
428
+ }
429
+ };
430
+ for (const relative of roots) {
431
+ const source = path.join(sourcePluginRoot, ...relative.split('/'));
432
+ if (await inspectMarketplacePath(options.sourceRoot, source, 'directory')) {
433
+ await assertRegularProjectionTree(source, true);
434
+ await validateRecords(source);
435
+ }
436
+ }
437
+ if (codexReceipt) {
438
+ receipt = { pluginName: options.pluginName, receipt: codexReceipt };
439
+ await fs.copy(path.join(sourcePluginRoot, CODEX_NATIVE_RENDER_RECEIPT_PATH), path.join(stagingPluginRoot, CODEX_NATIVE_RENDER_RECEIPT_PATH));
440
+ }
441
+ for (const relative of roots) {
442
+ const source = path.join(sourcePluginRoot, ...relative.split('/'));
443
+ const destination = path.join(stagingPluginRoot, ...relative.split('/'));
444
+ await fs.remove(destination);
445
+ if (await inspectMarketplacePath(options.sourceRoot, source, 'directory'))
446
+ await fs.copy(source, destination, { dereference: false });
447
+ }
448
+ platforms.push(platform);
449
+ }
450
+ return { platforms, ...(receipt ? { receipt } : {}) };
451
+ }
452
+ /** Rebind only the combined payload digest after verified, unrelated platform changes. */
453
+ export async function refreshPreservedPlatformReceipt(stagingRoot, retained) {
454
+ const pluginRoot = path.join(stagingRoot, 'plugins', retained.pluginName);
455
+ const payloadDigest = await calculateCodexNativeRenderPayloadDigest(pluginRoot);
456
+ await fs.outputFile(path.join(pluginRoot, CODEX_NATIVE_RENDER_RECEIPT_PATH), serializeCodexNativeRenderReceipt({ ...retained.receipt, payloadDigest }), 'utf8');
457
+ }
458
+ /**
459
+ * Replays unselected plugin copies into a fresh Catalog generation.
460
+ * Retains their payload and marketplace entries even when the Catalog changes.
461
+ * Codex native dynamic projections must also retain their original validated receipt.
462
+ * Damaged weak projections are skipped so their owning plugin can recover by sync.
463
+ */
464
+ export async function replayNamespacedMarketplacePluginProjections(options) {
465
+ let existing;
466
+ try {
467
+ existing = await readStrictNamespacedMarketplaceRoot({
468
+ trustedMarketplaceRoot: path.dirname(options.sourceRoot),
469
+ rootDir: options.sourceRoot,
470
+ sourceId: options.sourceId,
471
+ sourceIdentity: options.sourceIdentity,
472
+ marketplaceName: options.marketplaceName,
473
+ });
474
+ }
475
+ catch (error) {
476
+ if (error instanceof Error && error.message.startsWith('sourceChanged:'))
477
+ throw error;
478
+ throw new Error(`marketplaceProjectionReadFailed: ${sanitizeCatalogSourceErrorMessage(error instanceof Error ? error.message : String(error), process.env, [options.sourceRoot, options.stagingRoot])}`);
479
+ }
480
+ if (!existing)
481
+ return;
482
+ const retainedPluginNames = { codex: new Set(), claude: new Set() };
483
+ const pluginsRoot = path.join(options.sourceRoot, 'plugins');
484
+ let entries;
485
+ try {
486
+ entries = await readOverlayDirectory(options.sourceRoot, pluginsRoot, [options.sourceRoot, options.stagingRoot]);
487
+ }
488
+ catch (error) {
489
+ throw new Error(`marketplaceProjectionReadFailed: ${sanitizeCatalogSourceErrorMessage(error instanceof Error ? error.message : String(error), process.env, [options.sourceRoot, options.stagingRoot])}`);
490
+ }
491
+ for (const entry of entries) {
492
+ if (entry.isSymbolicLink()) {
493
+ throw new Error('codexNativeProjectionUnsafe: plugin root cannot be a symlink.');
494
+ }
495
+ if (!entry.isDirectory())
496
+ continue;
497
+ const logicalPluginId = `${options.sourceId}/${entry.name}`;
498
+ if (options.rematerializedPluginIds?.has(logicalPluginId)) {
499
+ const requested = options.rematerializedPluginPlatforms?.get(logicalPluginId);
500
+ if (requested) {
501
+ try {
502
+ const retained = await preserveUnrequestedMarketplacePlatforms({ ...options, pluginName: entry.name, requested });
503
+ for (const platform of retained.platforms)
504
+ retainedPluginNames[platform].add(entry.name);
505
+ if (retained.receipt)
506
+ options.onPreservedPlatformReceipt?.(retained.receipt);
507
+ }
508
+ catch (error) {
509
+ throw new Error(`marketplaceProjectionInvalid: cannot preserve the unrequested platform for ${logicalPluginId}; reinstall both platforms. ${error instanceof Error ? error.message : String(error)}`);
510
+ }
511
+ }
512
+ continue;
513
+ }
514
+ try {
515
+ await preserveMarketplacePluginProjection({ ...options, pluginName: entry.name });
516
+ retainedPluginNames.codex.add(entry.name);
517
+ retainedPluginNames.claude.add(entry.name);
518
+ }
519
+ catch (error) {
520
+ if (error instanceof CodexNativeProjectionNotReusableError)
521
+ continue;
522
+ throw new Error(`marketplaceProjectionReadFailed: ${sanitizeCatalogSourceErrorMessage(error instanceof Error ? error.message : String(error), process.env, [options.sourceRoot, options.stagingRoot])}`);
523
+ }
524
+ }
525
+ for (const [sourceManifest, relativePath, platform] of [
526
+ [existing.agentsManifest, '.agents/plugins/marketplace.json', 'codex'],
527
+ [existing.claudeManifest, '.claude-plugin/marketplace.json', 'claude'],
528
+ ]) {
529
+ const manifestPath = path.join(options.stagingRoot, relativePath);
530
+ const stagingManifest = await readStrictOptionalJsonObject(options.stagingRoot, manifestPath);
531
+ const retainedNames = retainedPluginNames[platform];
532
+ if (!stagingManifest || retainedNames.size === 0)
533
+ continue;
534
+ if (!Array.isArray(stagingManifest.plugins) || (sourceManifest && !Array.isArray(sourceManifest.plugins))) {
535
+ throw new Error('marketplaceProjectionInvalid: marketplace plugins must be an array.');
536
+ }
537
+ const retainedEntries = (sourceManifest?.plugins ?? []).filter((entry) => isRecord(entry)
538
+ && typeof entry.name === 'string' && retainedNames.has(entry.name));
539
+ await fs.writeJson(manifestPath, {
540
+ ...stagingManifest,
541
+ plugins: [
542
+ ...stagingManifest.plugins.filter((entry) => !isRecord(entry) || !retainedNames.has(String(entry.name))),
543
+ ...retainedEntries.map((entry) => ({
544
+ ...entry,
545
+ source: `./plugins/${entry.name}`,
546
+ })),
547
+ ],
548
+ }, { spaces: 2 });
549
+ }
550
+ }
551
+ async function inspectOverlayPath(trustedRoot, targetPath, finalKind, redactedRoots) {
552
+ try {
553
+ return await inspectMarketplacePath(trustedRoot, targetPath, finalKind);
554
+ }
555
+ catch (error) {
556
+ throw new Error(`marketplaceOverlayReadFailed: ${sanitizeCatalogSourceErrorMessage(error instanceof Error ? error.message : String(error), process.env, redactedRoots)}`);
557
+ }
558
+ }
559
+ async function readOverlayDirectory(trustedRoot, directoryPath, redactedRoots) {
560
+ if (!await inspectOverlayPath(trustedRoot, directoryPath, 'directory', redactedRoots))
561
+ return [];
206
562
  try {
207
563
  return await fs.readdir(directoryPath, { withFileTypes: true });
208
564
  }
@@ -233,7 +589,7 @@ export async function replayNamespacedCodexSkillOverlays(options) {
233
589
  return;
234
590
  const pluginsRoot = path.join(options.sourceRoot, 'plugins');
235
591
  const redactedRoots = [options.sourceRoot, options.stagingRoot];
236
- for (const pluginEntry of await readOverlayDirectory(pluginsRoot, redactedRoots)) {
592
+ for (const pluginEntry of await readOverlayDirectory(options.sourceRoot, pluginsRoot, redactedRoots)) {
237
593
  if (pluginEntry.isSymbolicLink()) {
238
594
  throw new Error(`Codex Skill overlay plugin root cannot be a symlink: ${pluginEntry.name}`);
239
595
  }
@@ -241,28 +597,25 @@ export async function replayNamespacedCodexSkillOverlays(options) {
241
597
  continue;
242
598
  const pluginName = pluginEntry.name;
243
599
  const sourcePluginRoot = path.join(pluginsRoot, pluginName);
244
- const sourcePlatformManifest = await readOptionalJsonObject(path.join(sourcePluginRoot, '.codex-plugin', 'plugin.json'));
600
+ const sourcePlatformManifest = await readStrictOptionalJsonObject(options.sourceRoot, path.join(sourcePluginRoot, '.codex-plugin', 'plugin.json'));
245
601
  const sourceSkillsRelative = normalizePluginRelativeDirectory(sourcePlatformManifest?.skills, 'codex/skills');
246
602
  if (!sourceSkillsRelative)
247
603
  continue;
248
604
  const sourceSkillsRoot = path.join(sourcePluginRoot, ...sourceSkillsRelative.split('/'));
249
605
  const overlays = [];
250
- for (const entry of await readOverlayDirectory(sourceSkillsRoot, redactedRoots)) {
606
+ for (const entry of await readOverlayDirectory(options.sourceRoot, sourceSkillsRoot, redactedRoots)) {
251
607
  if (entry.isSymbolicLink()) {
252
608
  throw new Error(`Codex Skill overlay cannot be a symlink: ${path.join(sourceSkillsRoot, entry.name)}`);
253
609
  }
254
610
  if (!entry.isDirectory())
255
611
  continue;
256
612
  const skillRoot = path.join(sourceSkillsRoot, entry.name);
257
- if (!await pathExists(path.join(skillRoot, SKILL_OWNER_MARKER)))
258
- continue;
259
- await readSkillOwnerMarker({
613
+ const owner = await readSkillOwnerMarker({
260
614
  skillRoot,
261
615
  allowedRoot: sourceSkillsRoot,
262
616
  expectedIdentity: {
263
617
  owner: 'agent-workflows',
264
618
  sourceId: options.sourceId,
265
- sourceIdentity: options.sourceIdentity,
266
619
  pluginId: `${options.sourceId}/${pluginName}`,
267
620
  plugin: pluginName,
268
621
  artifactKey: entry.name,
@@ -270,47 +623,44 @@ export async function replayNamespacedCodexSkillOverlays(options) {
270
623
  scope: 'user',
271
624
  },
272
625
  });
626
+ if (!owner)
627
+ continue;
273
628
  overlays.push({ key: entry.name, root: skillRoot });
274
629
  }
275
630
  if (overlays.length === 0)
276
631
  continue;
277
632
  const stagingPluginRoot = path.join(options.stagingRoot, 'plugins', pluginName);
278
- if (!await pathExists(stagingPluginRoot)) {
279
- await assertTreeHasNoSymlinks(sourcePluginRoot);
280
- await fs.copy(sourcePluginRoot, stagingPluginRoot, {
281
- overwrite: false, errorOnExist: true, dereference: false,
282
- });
633
+ if (!await inspectOverlayPath(options.stagingRoot, stagingPluginRoot, 'directory', redactedRoots))
283
634
  continue;
284
- }
285
- const stagingManifest = await readOptionalJsonObject(path.join(stagingPluginRoot, '.agents-plugin', 'plugin.json'));
635
+ const stagingManifest = await readStrictOptionalJsonObject(options.stagingRoot, path.join(stagingPluginRoot, '.agents-plugin', 'plugin.json'));
286
636
  const targets = stagingManifest?.artifacts?.targets ?? [];
287
637
  const dynamicKeys = new Set(targets.flatMap((target) => {
288
638
  if (!isRecord(target))
289
639
  return [];
290
640
  return target.platform === 'codex'
291
641
  && target.target === 'codex.skill'
642
+ && isRecord(target.delivery)
643
+ && target.delivery.mode === 'codex-native'
292
644
  && Array.isArray(target.scopes)
293
645
  && target.scopes.includes('user')
294
646
  && typeof target.skillKey === 'string'
295
647
  ? [target.skillKey]
296
648
  : [];
297
649
  }));
298
- const stagingPlatformManifest = await readOptionalJsonObject(path.join(stagingPluginRoot, '.codex-plugin', 'plugin.json'));
650
+ const stagingPlatformManifest = await readStrictOptionalJsonObject(options.stagingRoot, path.join(stagingPluginRoot, '.codex-plugin', 'plugin.json'));
299
651
  const stagingSkillsRelative = normalizePluginRelativeDirectory(stagingPlatformManifest?.skills, 'codex/skills');
300
652
  if (!stagingSkillsRelative)
301
653
  continue;
302
654
  const stagingSkillsRoot = path.join(stagingPluginRoot, ...stagingSkillsRelative.split('/'));
655
+ await inspectOverlayPath(options.stagingRoot, stagingSkillsRoot, 'directory', redactedRoots);
303
656
  for (const overlay of overlays) {
657
+ if (!dynamicKeys.has(overlay.key))
658
+ continue;
304
659
  const destination = path.join(stagingSkillsRoot, overlay.key);
305
- if (dynamicKeys.has(overlay.key) || !await pathExists(destination)) {
306
- await assertTreeHasNoSymlinks(overlay.root);
307
- await fs.copy(overlay.root, destination, {
308
- overwrite: true, errorOnExist: false, dereference: false,
309
- });
310
- }
311
- else {
312
- await fs.copyFile(path.join(overlay.root, SKILL_OWNER_MARKER), path.join(destination, SKILL_OWNER_MARKER));
313
- }
660
+ await assertTreeHasNoSymlinks(overlay.root);
661
+ await fs.copy(overlay.root, destination, {
662
+ overwrite: true, errorOnExist: false, dereference: false,
663
+ });
314
664
  }
315
665
  }
316
666
  }