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

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 +263 -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,1276 +0,0 @@
1
- import crypto from 'node:crypto';
2
- import path from 'node:path';
3
- import fs from 'fs-extra';
4
- import { calculateFileDigest, calculatePluginBundleFingerprintV2, } from './bundle-integrity.js';
5
- import { acquireActiveMarketplaceLifecycleLeaseAtRoot, markActiveMarketplaceDurableCommit, releaseActiveMarketplaceCoordinationLease, resolveActiveMarketplaceRuntimeCoordinationRoot, withActiveMarketplaceLifecycleLease, } from './active-marketplace-runtime-lock.js';
6
- import { PLUGIN_LIFECYCLE_EVENTS } from './plugin-script-contract.js';
7
- import { acquireProcessLock, } from './process-lock.js';
8
- import { canonicalizePathThroughExistingAncestor, createProjectLocationKey, getClaudeHome, getCodexHome, resolveCanonicalRepoProjectKey, resolveAwHome, resolveAwHomeCanonical, resolveRepoRoot, } from './state-paths.js';
9
- import { assertTestWritablePath } from './test-path-fence.js';
10
- export const LIFECYCLE_ACTIVE_DIR = 'lifecycle-active';
11
- export const LIFECYCLE_ACTIVE_SCHEMA_VERSION = 2;
12
- export const LIFECYCLE_ACTIVE_METADATA_FILE = 'metadata.json';
13
- const SOURCE_MANIFEST_PATH = path.join('.agents-plugin', 'plugin.json');
14
- const PLUGIN_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
15
- const DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/;
16
- const STAGE_ID_PATTERN = /^stage-[0-9a-f]{24}$/;
17
- const BACKUP_ID_PATTERN = /^backup-[0-9a-f]{24}$/;
18
- const ARTIFACT_KINDS = new Set([
19
- 'instruction',
20
- 'permission',
21
- 'hook',
22
- 'agent',
23
- 'skill',
24
- 'mcpServer',
25
- ]);
26
- const ARTIFACT_TARGETS = new Set([
27
- 'codex.developerInstructionsBlock',
28
- 'codex.agentRole',
29
- 'codex.skill',
30
- 'claude.skill',
31
- ]);
32
- const ARTIFACT_STATES = new Set(['present', 'disabled']);
33
- const preparedContexts = new WeakMap();
34
- const readContexts = new WeakMap();
35
- const releasedReads = new WeakSet();
36
- const finalizedPrepared = new WeakSet();
37
- let beforePruneStagingRootForTests;
38
- let processLockFileSystemForTests;
39
- export function setLifecycleActiveBeforePruneForTests(hook) {
40
- beforePruneStagingRootForTests = hook;
41
- }
42
- export function setLifecycleActiveLockFileSystemForTests(fileSystem) {
43
- processLockFileSystemForTests = fileSystem;
44
- }
45
- export class LifecycleActiveSnapshotError extends Error {
46
- code = 'invalidLifecycleActiveSnapshot';
47
- constructor(message, options) {
48
- super(message, options);
49
- this.name = 'LifecycleActiveSnapshotError';
50
- }
51
- }
52
- function fail(message) {
53
- throw new LifecycleActiveSnapshotError(message);
54
- }
55
- function isInsidePath(childPath, rootPath) {
56
- const relative = path.relative(rootPath, childPath);
57
- return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
58
- }
59
- function assertInsidePath(childPath, rootPath, fieldName) {
60
- if (!isInsidePath(path.resolve(childPath), path.resolve(rootPath))) {
61
- fail(`${fieldName} is outside its allowed lifecycle root.`);
62
- }
63
- }
64
- function assertAllowedKeys(value, allowedKeys, fieldName) {
65
- for (const key of Object.keys(value)) {
66
- if (!allowedKeys.includes(key)) {
67
- fail(`${fieldName} contains unknown field "${key}".`);
68
- }
69
- }
70
- }
71
- function expectRecord(value, fieldName) {
72
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
73
- fail(`${fieldName} must be an object.`);
74
- }
75
- return value;
76
- }
77
- function expectString(value, fieldName) {
78
- if (typeof value !== 'string' || value.length === 0) {
79
- fail(`${fieldName} must be a non-empty string.`);
80
- }
81
- return value;
82
- }
83
- function expectOptionalString(value, fieldName) {
84
- return value === undefined ? undefined : expectString(value, fieldName);
85
- }
86
- function expectPlatform(value, fieldName) {
87
- if (value !== 'codex' && value !== 'claude') {
88
- fail(`${fieldName} must be "codex" or "claude".`);
89
- }
90
- return value;
91
- }
92
- function expectScope(value, fieldName) {
93
- if (value !== 'user' && value !== 'project') {
94
- fail(`${fieldName} must be "user" or "project".`);
95
- }
96
- return value;
97
- }
98
- function assertPluginName(pluginName) {
99
- if (!PLUGIN_NAME_PATTERN.test(pluginName)) {
100
- fail(`Invalid lifecycle active plugin name "${pluginName}".`);
101
- }
102
- }
103
- export function createLifecycleProjectLocationKey(projectKey) {
104
- return createProjectLocationKey(projectKey);
105
- }
106
- function assertWritableStorePath(targetPath) {
107
- return assertTestWritablePath(targetPath, 'lifecycle active store', 'Use an isolated AW_HOME or register the lifecycle active root as writable.');
108
- }
109
- export async function resolveLifecycleActiveTarget(options) {
110
- assertPluginName(options.pluginName);
111
- if (options.sourceId !== undefined) {
112
- assertPluginName(options.sourceId);
113
- if (!options.sourceIdentity)
114
- fail('sourceIdentity is required for a namespaced lifecycle target.');
115
- }
116
- const platform = expectPlatform(options.platform, 'platform');
117
- const scope = expectScope(options.scope, 'scope');
118
- const env = options.env ?? process.env;
119
- const rawAwHome = path.resolve(resolveAwHome(env));
120
- const awHome = await canonicalizePathThroughExistingAncestor(await resolveAwHomeCanonical(env));
121
- const rawProjectRoot = scope === 'project'
122
- ? path.resolve(await resolveRepoRoot(options.cwd))
123
- : null;
124
- const projectKey = rawProjectRoot ? await resolveCanonicalRepoProjectKey(options.cwd) : null;
125
- const rawPlatformHome = path.resolve(platform === 'codex' ? getCodexHome(env) : getClaudeHome(env));
126
- const platformHome = await canonicalizePathThroughExistingAncestor(rawPlatformHome);
127
- const locationKey = projectKey ? createLifecycleProjectLocationKey(projectKey) : 'user';
128
- const coordinationRoot = resolveActiveMarketplaceRuntimeCoordinationRoot(env);
129
- const storeRoot = assertWritableStorePath(path.join(awHome, LIFECYCLE_ACTIVE_DIR));
130
- const targetRoot = assertWritableStorePath(path.join(storeRoot, ...(options.sourceId ? [options.sourceId] : []), platform, scope, locationKey, options.pluginName));
131
- const lockParent = assertWritableStorePath(path.join(coordinationRoot, 'lifecycle-locks', platform, scope, locationKey));
132
- const lockPath = assertWritableStorePath(path.join(lockParent, `.${options.sourceId ? `${options.sourceId}.` : ''}${options.pluginName}.lock`));
133
- const operationLockPath = assertWritableStorePath(path.join(lockParent, `.${options.sourceId ? `${options.sourceId}.` : ''}${options.pluginName}.operation.lock`));
134
- return {
135
- ...(options.sourceId ? {
136
- sourceId: options.sourceId,
137
- sourceIdentity: options.sourceIdentity,
138
- pluginId: `${options.sourceId}/${options.pluginName}`,
139
- } : {}),
140
- pluginName: options.pluginName,
141
- platform,
142
- scope,
143
- projectKey,
144
- locationKey,
145
- awHome,
146
- coordinationRoot,
147
- storeRoot,
148
- targetRoot,
149
- activeRoot: path.join(targetRoot, 'active'),
150
- stagingRoot: path.join(targetRoot, 'staging'),
151
- lockPath,
152
- operationLockPath,
153
- artifactOutputRoots: [awHome, platformHome, ...(projectKey ? [projectKey] : [])],
154
- pathAliases: [
155
- { source: rawAwHome, canonical: awHome },
156
- { source: rawPlatformHome, canonical: platformHome },
157
- ...(rawProjectRoot && projectKey
158
- ? [{ source: rawProjectRoot, canonical: projectKey }]
159
- : []),
160
- ],
161
- };
162
- }
163
- async function lstatIfExists(targetPath) {
164
- try {
165
- return await fs.lstat(targetPath);
166
- }
167
- catch (error) {
168
- if (error.code === 'ENOENT') {
169
- return null;
170
- }
171
- throw error;
172
- }
173
- }
174
- async function assertExistingPathChainHasNoSymlinks(rootPath, targetPath) {
175
- assertInsidePath(targetPath, rootPath, 'store path');
176
- const rootStat = await lstatIfExists(rootPath);
177
- if (rootStat?.isSymbolicLink()) {
178
- fail(`Lifecycle active store path contains a symbolic link: ${rootPath}`);
179
- }
180
- if (rootStat && !rootStat.isDirectory()) {
181
- fail(`Lifecycle active store path is not a directory: ${rootPath}`);
182
- }
183
- if (!rootStat) {
184
- return;
185
- }
186
- let current = rootPath;
187
- for (const segment of path.relative(rootPath, targetPath).split(path.sep).filter(Boolean)) {
188
- current = path.join(current, segment);
189
- const stat = await lstatIfExists(current);
190
- if (!stat) {
191
- return;
192
- }
193
- if (stat.isSymbolicLink()) {
194
- fail(`Lifecycle active store path contains a symbolic link: ${current}`);
195
- }
196
- if (!stat.isDirectory()) {
197
- fail(`Lifecycle active store path is not a directory: ${current}`);
198
- }
199
- }
200
- }
201
- async function assertExistingDirectoryBoundary(target, candidatePath, fieldName) {
202
- await assertExistingPathChainHasNoSymlinks(target.awHome, candidatePath);
203
- const stat = await lstatIfExists(candidatePath);
204
- if (!stat) {
205
- return;
206
- }
207
- if (!stat.isDirectory() || stat.isSymbolicLink()) {
208
- fail(`${fieldName} must be a regular directory.`);
209
- }
210
- const [realStoreRoot, realCandidate] = await Promise.all([
211
- fs.realpath(target.storeRoot),
212
- fs.realpath(candidatePath),
213
- ]);
214
- if (!isInsidePath(realCandidate, realStoreRoot) || realCandidate !== path.resolve(candidatePath)) {
215
- fail(`${fieldName} escapes the canonical lifecycle active store.`);
216
- }
217
- }
218
- async function acquireTargetLock(target, lifecycleLeaseHeld = false) {
219
- const lifecycleLease = lifecycleLeaseHeld
220
- ? undefined
221
- : await acquireActiveMarketplaceLifecycleLeaseAtRoot(target.coordinationRoot);
222
- const lockParent = path.dirname(target.lockPath);
223
- let targetLease;
224
- try {
225
- await assertExistingPathChainHasNoSymlinks(target.coordinationRoot, lockParent);
226
- await fs.ensureDir(lockParent);
227
- await assertExistingPathChainHasNoSymlinks(target.coordinationRoot, lockParent);
228
- targetLease = await acquireProcessLock({
229
- lockPath: target.lockPath,
230
- fileSystem: processLockFileSystemForTests,
231
- });
232
- }
233
- catch (error) {
234
- try {
235
- if (lifecycleLease)
236
- await releaseActiveMarketplaceCoordinationLease(lifecycleLease);
237
- }
238
- catch (releaseError) {
239
- emitLifecycleReleaseWarning('Lifecycle target lock acquisition failed, and lifecycle lease release also failed', releaseError);
240
- }
241
- throw error;
242
- }
243
- let targetReleased = false;
244
- let lifecycleReleased = false;
245
- return {
246
- lockPath: targetLease.lockPath,
247
- owner: targetLease.owner,
248
- release: async () => {
249
- if (!targetReleased) {
250
- await targetLease.release();
251
- targetReleased = true;
252
- }
253
- if (lifecycleLease && !lifecycleReleased) {
254
- await lifecycleLease.release();
255
- lifecycleReleased = true;
256
- }
257
- },
258
- };
259
- }
260
- export async function acquireLifecycleOperationLock(options) {
261
- const target = await resolveLifecycleActiveTarget(options);
262
- const lockParent = path.dirname(target.operationLockPath);
263
- await assertExistingPathChainHasNoSymlinks(target.coordinationRoot, lockParent);
264
- await fs.ensureDir(lockParent);
265
- await assertExistingPathChainHasNoSymlinks(target.coordinationRoot, lockParent);
266
- return acquireProcessLock({
267
- lockPath: target.operationLockPath,
268
- fileSystem: processLockFileSystemForTests,
269
- });
270
- }
271
- async function assertNoSymlinks(rootPath) {
272
- const rootStat = await fs.lstat(rootPath);
273
- if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
274
- fail(`Lifecycle active snapshot root is not a regular directory: ${rootPath}`);
275
- }
276
- for (const entry of await fs.readdir(rootPath, { withFileTypes: true })) {
277
- const entryPath = path.join(rootPath, entry.name);
278
- const stat = await fs.lstat(entryPath);
279
- if (stat.isSymbolicLink()) {
280
- fail(`Lifecycle active snapshot contains a symbolic link: ${entryPath}`);
281
- }
282
- if (stat.isDirectory()) {
283
- await assertNoSymlinks(entryPath);
284
- }
285
- else if (!stat.isFile()) {
286
- fail(`Lifecycle active snapshot contains a special file: ${entryPath}`);
287
- }
288
- }
289
- }
290
- function lifecycleEvents(manifest) {
291
- return PLUGIN_LIFECYCLE_EVENTS.filter((event) => manifest.scripts?.lifecycle?.[event] !== undefined);
292
- }
293
- function stableStringify(value) {
294
- if (Array.isArray(value)) {
295
- return `[${value.map((entry) => stableStringify(entry)).join(',')}]`;
296
- }
297
- if (value && typeof value === 'object') {
298
- const record = value;
299
- return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`).join(',')}}`;
300
- }
301
- return JSON.stringify(value);
302
- }
303
- function calculateMetadataIntegrityDigest(payload) {
304
- return `sha256:${crypto.createHash('sha256').update(stableStringify(payload)).digest('hex')}`;
305
- }
306
- function assertAbsoluteNormalizedPath(value, fieldName) {
307
- if (!path.isAbsolute(value) || path.normalize(value) !== value) {
308
- fail(`${fieldName} must be an absolute normalized path.`);
309
- }
310
- }
311
- function assertArtifactOutputPath(value, outputRoots, fieldName) {
312
- assertAbsoluteNormalizedPath(value, fieldName);
313
- if (!outputRoots.some((root) => isInsidePath(value, root))) {
314
- fail(`${fieldName} is outside the lifecycle target output roots.`);
315
- }
316
- }
317
- function canonicalizeArtifactPath(value, target) {
318
- let aliasedValue = value;
319
- for (const alias of target.pathAliases) {
320
- if (isInsidePath(value, alias.source)) {
321
- aliasedValue = path.join(alias.canonical, path.relative(alias.source, value));
322
- break;
323
- }
324
- }
325
- let existingAncestor = aliasedValue;
326
- const missingSegments = [];
327
- while (true) {
328
- try {
329
- fs.lstatSync(existingAncestor);
330
- try {
331
- return path.join(fs.realpathSync(existingAncestor), ...missingSegments);
332
- }
333
- catch (error) {
334
- if (error.code === 'ENOENT') {
335
- fail(`Artifact path crosses a dangling symbolic link: ${existingAncestor}`);
336
- }
337
- throw error;
338
- }
339
- }
340
- catch (error) {
341
- if (error.code !== 'ENOENT') {
342
- throw error;
343
- }
344
- }
345
- missingSegments.unshift(path.basename(existingAncestor));
346
- const parent = path.dirname(existingAncestor);
347
- if (parent === existingAncestor)
348
- return aliasedValue;
349
- existingAncestor = parent;
350
- }
351
- }
352
- function descriptorIdentityKeys(artifact) {
353
- const keys = [
354
- artifact.id ? `${artifact.kind}:id:${artifact.id}` : null,
355
- artifact.artifactKey ? `${artifact.kind}:artifactKey:${artifact.artifactKey}` : null,
356
- artifact.roleKey ? `${artifact.kind}:roleKey:${artifact.roleKey}` : null,
357
- ].filter((key) => key !== null);
358
- return keys.length > 0 ? keys : [`${artifact.kind}:path:${artifact.path}`];
359
- }
360
- function createArtifactDescriptors(artifacts, target) {
361
- const outputRoots = target.artifactOutputRoots;
362
- const owner = {
363
- ...(target.sourceId ? {
364
- sourceId: target.sourceId,
365
- sourceIdentity: target.sourceIdentity,
366
- pluginId: target.pluginId,
367
- } : {}),
368
- pluginName: target.pluginName,
369
- platform: target.platform,
370
- scope: target.scope,
371
- projectKey: target.projectKey,
372
- };
373
- const identities = new Set();
374
- return artifacts.map((artifact, index) => {
375
- if (artifact.platform !== target.platform || !ARTIFACT_KINDS.has(artifact.kind)) {
376
- fail(`artifacts[${index}] does not match the lifecycle target platform or kind.`);
377
- }
378
- const artifactPath = canonicalizeArtifactPath(artifact.path, target);
379
- assertArtifactOutputPath(artifactPath, outputRoots, `artifacts[${index}].path`);
380
- const paths = artifact.paths?.map((entryPath, pathIndex) => {
381
- const canonicalPath = canonicalizeArtifactPath(entryPath, target);
382
- assertArtifactOutputPath(canonicalPath, outputRoots, `artifacts[${index}].paths[${pathIndex}]`);
383
- return canonicalPath;
384
- });
385
- if (paths && new Set(paths).size !== paths.length) {
386
- fail(`artifacts[${index}].paths contains duplicates.`);
387
- }
388
- for (const [fieldName, value] of [
389
- ['artifactKey', artifact.artifactKey],
390
- ['id', artifact.id],
391
- ['roleKey', artifact.roleKey],
392
- ]) {
393
- if (value !== undefined && value.length === 0) {
394
- fail(`artifacts[${index}].${fieldName} must be a non-empty string.`);
395
- }
396
- }
397
- if (artifact.target !== undefined && !ARTIFACT_TARGETS.has(artifact.target)) {
398
- fail(`artifacts[${index}].target is invalid.`);
399
- }
400
- if (artifact.state !== undefined && !ARTIFACT_STATES.has(artifact.state)) {
401
- fail(`artifacts[${index}].state is invalid.`);
402
- }
403
- const descriptor = {
404
- path: artifactPath,
405
- ...(paths ? { paths } : {}),
406
- kind: artifact.kind,
407
- platform: artifact.platform,
408
- ...(artifact.artifactKey ? { artifactKey: artifact.artifactKey } : {}),
409
- ...(artifact.hookGroups ? { hookGroups: artifact.hookGroups.map((group) => ({ ...group })) } : {}),
410
- ...(artifact.id ? { id: artifact.id } : {}),
411
- ...(artifact.target ? { target: artifact.target } : {}),
412
- ...(artifact.state ? { state: artifact.state } : {}),
413
- ...(artifact.refreshKeys ? { refreshKeys: [...artifact.refreshKeys] } : {}),
414
- ...(artifact.roleKey ? { roleKey: artifact.roleKey } : {}),
415
- owner: { ...owner },
416
- };
417
- for (const identity of descriptorIdentityKeys(descriptor)) {
418
- if (identities.has(identity)) {
419
- fail(`artifacts[${index}] duplicates another lifecycle artifact identity.`);
420
- }
421
- identities.add(identity);
422
- }
423
- return descriptor;
424
- });
425
- }
426
- function parseStringArray(value, fieldName) {
427
- if (value === undefined) {
428
- return undefined;
429
- }
430
- if (!Array.isArray(value)) {
431
- fail(`${fieldName} must be an array.`);
432
- }
433
- const parsed = value.map((entry, index) => expectString(entry, `${fieldName}[${index}]`));
434
- if (new Set(parsed).size !== parsed.length) {
435
- fail(`${fieldName} contains duplicates.`);
436
- }
437
- return parsed;
438
- }
439
- function parseHookGroups(value, fieldName) {
440
- if (value === undefined) {
441
- return undefined;
442
- }
443
- if (!Array.isArray(value)) {
444
- fail(`${fieldName} must be an array.`);
445
- }
446
- const identities = new Set();
447
- return value.map((entry, index) => {
448
- const group = expectRecord(entry, `${fieldName}[${index}]`);
449
- assertAllowedKeys(group, ['event', 'matcher', 'command'], `${fieldName}[${index}]`);
450
- const parsed = {
451
- event: expectString(group.event, `${fieldName}[${index}].event`),
452
- ...(group.matcher === undefined
453
- ? {}
454
- : { matcher: expectString(group.matcher, `${fieldName}[${index}].matcher`) }),
455
- command: expectString(group.command, `${fieldName}[${index}].command`),
456
- };
457
- const identity = `${parsed.event}\0${parsed.matcher ?? ''}\0${parsed.command}`;
458
- if (identities.has(identity)) {
459
- fail(`${fieldName} contains duplicate hook group identities.`);
460
- }
461
- identities.add(identity);
462
- return parsed;
463
- });
464
- }
465
- function parseArtifactDescriptors(value, target) {
466
- if (!Array.isArray(value)) {
467
- fail('metadata.artifacts must be an array.');
468
- }
469
- const outputRoots = target.artifactOutputRoots;
470
- const identities = new Set();
471
- return value.map((entry, index) => {
472
- const fieldName = `metadata.artifacts[${index}]`;
473
- const artifact = expectRecord(entry, fieldName);
474
- assertAllowedKeys(artifact, [
475
- 'path', 'paths', 'kind', 'platform', 'artifactKey', 'hookGroups', 'id', 'target',
476
- 'state', 'refreshKeys', 'roleKey', 'owner',
477
- ], fieldName);
478
- if (!ARTIFACT_KINDS.has(artifact.kind)) {
479
- fail(`${fieldName}.kind is invalid.`);
480
- }
481
- const platform = expectPlatform(artifact.platform, `${fieldName}.platform`);
482
- if (platform !== target.platform) {
483
- fail(`${fieldName}.platform does not match the lifecycle target.`);
484
- }
485
- const artifactPath = expectString(artifact.path, `${fieldName}.path`);
486
- const canonicalArtifactPath = canonicalizeArtifactPath(artifactPath, target);
487
- assertArtifactOutputPath(canonicalArtifactPath, outputRoots, `${fieldName}.path`);
488
- if (canonicalArtifactPath !== artifactPath) {
489
- fail(`${fieldName}.path is not canonical or crosses a symbolic link.`);
490
- }
491
- const paths = parseStringArray(artifact.paths, `${fieldName}.paths`);
492
- paths?.forEach((entryPath, pathIndex) => {
493
- const canonicalPath = canonicalizeArtifactPath(entryPath, target);
494
- assertArtifactOutputPath(canonicalPath, outputRoots, `${fieldName}.paths[${pathIndex}]`);
495
- if (canonicalPath !== entryPath) {
496
- fail(`${fieldName}.paths[${pathIndex}] is not canonical or crosses a symbolic link.`);
497
- }
498
- });
499
- const targetValue = artifact.target === undefined
500
- ? undefined
501
- : expectString(artifact.target, `${fieldName}.target`);
502
- if (targetValue && !ARTIFACT_TARGETS.has(targetValue)) {
503
- fail(`${fieldName}.target is invalid.`);
504
- }
505
- const state = artifact.state === undefined
506
- ? undefined
507
- : expectString(artifact.state, `${fieldName}.state`);
508
- if (state && !ARTIFACT_STATES.has(state)) {
509
- fail(`${fieldName}.state is invalid.`);
510
- }
511
- const owner = expectRecord(artifact.owner, `${fieldName}.owner`);
512
- assertAllowedKeys(owner, [
513
- 'sourceId', 'sourceIdentity', 'pluginId', 'pluginName', 'platform', 'scope', 'projectKey',
514
- ], `${fieldName}.owner`);
515
- const parsedOwner = {
516
- ...(target.sourceId ? {
517
- sourceId: expectString(owner.sourceId, `${fieldName}.owner.sourceId`),
518
- sourceIdentity: expectString(owner.sourceIdentity, `${fieldName}.owner.sourceIdentity`),
519
- pluginId: expectString(owner.pluginId, `${fieldName}.owner.pluginId`),
520
- } : {}),
521
- pluginName: expectString(owner.pluginName, `${fieldName}.owner.pluginName`),
522
- platform: expectPlatform(owner.platform, `${fieldName}.owner.platform`),
523
- scope: expectScope(owner.scope, `${fieldName}.owner.scope`),
524
- projectKey: owner.projectKey === null
525
- ? null
526
- : expectString(owner.projectKey, `${fieldName}.owner.projectKey`),
527
- };
528
- if (parsedOwner.pluginName !== target.pluginName
529
- || parsedOwner.sourceId !== target.sourceId
530
- || parsedOwner.sourceIdentity !== target.sourceIdentity
531
- || parsedOwner.pluginId !== target.pluginId
532
- || parsedOwner.platform !== target.platform
533
- || parsedOwner.scope !== target.scope
534
- || parsedOwner.projectKey !== target.projectKey) {
535
- fail(`${fieldName}.owner does not match the lifecycle target.`);
536
- }
537
- const parsed = {
538
- path: artifactPath,
539
- ...(paths ? { paths } : {}),
540
- kind: artifact.kind,
541
- platform,
542
- ...(expectOptionalString(artifact.artifactKey, `${fieldName}.artifactKey`)
543
- ? { artifactKey: artifact.artifactKey }
544
- : {}),
545
- ...(artifact.hookGroups === undefined
546
- ? {}
547
- : { hookGroups: parseHookGroups(artifact.hookGroups, `${fieldName}.hookGroups`) }),
548
- ...(expectOptionalString(artifact.id, `${fieldName}.id`) ? { id: artifact.id } : {}),
549
- ...(targetValue ? { target: targetValue } : {}),
550
- ...(state ? { state } : {}),
551
- ...(artifact.refreshKeys === undefined
552
- ? {}
553
- : { refreshKeys: parseStringArray(artifact.refreshKeys, `${fieldName}.refreshKeys`) }),
554
- ...(expectOptionalString(artifact.roleKey, `${fieldName}.roleKey`)
555
- ? { roleKey: artifact.roleKey }
556
- : {}),
557
- owner: parsedOwner,
558
- };
559
- for (const identity of descriptorIdentityKeys(parsed)) {
560
- if (identities.has(identity)) {
561
- fail(`${fieldName} duplicates another lifecycle artifact identity.`);
562
- }
563
- identities.add(identity);
564
- }
565
- return parsed;
566
- });
567
- }
568
- function parseMetadata(raw, target) {
569
- const value = expectRecord(raw, 'metadata');
570
- assertAllowedKeys(value, [
571
- 'schemaVersion', 'sourceId', 'sourceIdentity', 'pluginId',
572
- 'pluginName', 'pluginVersion', 'platform', 'scope', 'projectKey',
573
- 'sourceManifestDigest', 'fingerprintVersion', 'bundleFingerprint', 'events', 'artifacts',
574
- 'metadataIntegrityDigest',
575
- ], 'metadata');
576
- if (value.schemaVersion !== 1 && value.schemaVersion !== LIFECYCLE_ACTIVE_SCHEMA_VERSION) {
577
- fail('metadata.schemaVersion is unsupported.');
578
- }
579
- if (target.sourceId !== undefined && value.schemaVersion === 1) {
580
- fail('legacyStateUnsupported: schema 1 lifecycle state is not supported.');
581
- }
582
- const sourceId = value.schemaVersion === 2
583
- ? expectString(value.sourceId, 'metadata.sourceId')
584
- : undefined;
585
- const sourceIdentity = value.schemaVersion === 2
586
- ? expectString(value.sourceIdentity, 'metadata.sourceIdentity')
587
- : undefined;
588
- const pluginId = value.schemaVersion === 2
589
- ? expectString(value.pluginId, 'metadata.pluginId')
590
- : undefined;
591
- const pluginName = expectString(value.pluginName, 'metadata.pluginName');
592
- assertPluginName(pluginName);
593
- const pluginVersion = expectString(value.pluginVersion, 'metadata.pluginVersion');
594
- const platform = expectPlatform(value.platform, 'metadata.platform');
595
- const scope = expectScope(value.scope, 'metadata.scope');
596
- const projectKey = value.projectKey === null
597
- ? null
598
- : expectString(value.projectKey, 'metadata.projectKey');
599
- if (sourceId !== target.sourceId
600
- || (sourceId !== undefined && sourceIdentity !== target.sourceIdentity)
601
- || (sourceId !== undefined && pluginId !== target.pluginId)
602
- ||
603
- pluginName !== target.pluginName
604
- || platform !== target.platform
605
- || scope !== target.scope
606
- || projectKey !== target.projectKey) {
607
- if (sourceId === target.sourceId && sourceIdentity !== target.sourceIdentity) {
608
- fail('sourceChanged: lifecycle source identity does not match the configured source.');
609
- }
610
- fail('Lifecycle active metadata target identity does not match the requested target.');
611
- }
612
- if (scope === 'user' ? projectKey !== null : projectKey === null) {
613
- fail('metadata.projectKey does not match metadata.scope.');
614
- }
615
- const sourceManifestDigest = expectString(value.sourceManifestDigest, 'metadata.sourceManifestDigest');
616
- if (value.fingerprintVersion !== 2) {
617
- fail('metadata.fingerprintVersion must be 2.');
618
- }
619
- const bundleFingerprint = expectString(value.bundleFingerprint, 'metadata.bundleFingerprint');
620
- const metadataIntegrityDigest = expectString(value.metadataIntegrityDigest, 'metadata.metadataIntegrityDigest');
621
- if (!DIGEST_PATTERN.test(sourceManifestDigest)
622
- || !DIGEST_PATTERN.test(bundleFingerprint)
623
- || !DIGEST_PATTERN.test(metadataIntegrityDigest)) {
624
- fail('metadata integrity fields must be SHA-256 digests.');
625
- }
626
- if (!Array.isArray(value.events)) {
627
- fail('metadata.events must be an array.');
628
- }
629
- const events = value.events.map((event, index) => {
630
- if (!PLUGIN_LIFECYCLE_EVENTS.includes(event)) {
631
- fail(`metadata.events[${index}] is invalid.`);
632
- }
633
- return event;
634
- });
635
- const expectedOrder = PLUGIN_LIFECYCLE_EVENTS.filter((event) => events.includes(event));
636
- if (events.length !== new Set(events).size
637
- || events.some((event, index) => expectedOrder[index] !== event)
638
- || !events.includes('uninstall')) {
639
- fail('metadata.events must be unique, ordered lifecycle events that include uninstall.');
640
- }
641
- const artifacts = parseArtifactDescriptors(value.artifacts, target);
642
- const payload = {
643
- schemaVersion: value.schemaVersion,
644
- ...(sourceId ? { sourceId, sourceIdentity, pluginId } : {}),
645
- pluginName,
646
- pluginVersion,
647
- platform,
648
- scope,
649
- projectKey,
650
- sourceManifestDigest,
651
- fingerprintVersion: 2,
652
- bundleFingerprint,
653
- events,
654
- artifacts,
655
- };
656
- if (calculateMetadataIntegrityDigest(payload) !== metadataIntegrityDigest) {
657
- fail('Lifecycle active metadata integrity digest does not match metadata.');
658
- }
659
- return { ...payload, metadataIntegrityDigest };
660
- }
661
- async function validateSnapshotRoot(snapshotRoot, target, loadPlugin) {
662
- assertInsidePath(snapshotRoot, target.targetRoot, 'snapshotRoot');
663
- await assertExistingDirectoryBoundary(target, snapshotRoot, 'snapshotRoot');
664
- await assertNoSymlinks(snapshotRoot);
665
- const topLevelEntries = (await fs.readdir(snapshotRoot)).sort();
666
- if (topLevelEntries.length !== 2
667
- || topLevelEntries[0] !== 'bundle'
668
- || topLevelEntries[1] !== LIFECYCLE_ACTIVE_METADATA_FILE) {
669
- fail('Lifecycle active snapshot must contain only bundle and metadata.json.');
670
- }
671
- const resolvedSnapshotRoot = await fs.realpath(snapshotRoot);
672
- const bundleRoot = path.join(snapshotRoot, 'bundle');
673
- const metadataPath = path.join(snapshotRoot, LIFECYCLE_ACTIVE_METADATA_FILE);
674
- const manifestPath = path.join(bundleRoot, SOURCE_MANIFEST_PATH);
675
- const [resolvedBundleRoot, resolvedMetadataPath, resolvedManifestPath] = await Promise.all([
676
- fs.realpath(bundleRoot),
677
- fs.realpath(metadataPath),
678
- fs.realpath(manifestPath),
679
- ]);
680
- if (resolvedBundleRoot !== path.join(resolvedSnapshotRoot, 'bundle')
681
- || resolvedMetadataPath !== path.join(resolvedSnapshotRoot, LIFECYCLE_ACTIVE_METADATA_FILE)
682
- || resolvedManifestPath !== path.join(resolvedBundleRoot, SOURCE_MANIFEST_PATH)) {
683
- fail('Lifecycle active snapshot layout escapes its expected path boundaries.');
684
- }
685
- let rawMetadata;
686
- try {
687
- rawMetadata = await fs.readJson(resolvedMetadataPath);
688
- }
689
- catch (error) {
690
- throw new LifecycleActiveSnapshotError('Lifecycle active metadata is not valid JSON.', { cause: error });
691
- }
692
- const metadata = parseMetadata(rawMetadata, target);
693
- const [manifestDigest, bundleFingerprint] = await Promise.all([
694
- calculateFileDigest(resolvedManifestPath),
695
- calculatePluginBundleFingerprintV2(resolvedBundleRoot),
696
- ]);
697
- if (manifestDigest !== metadata.sourceManifestDigest) {
698
- fail('Lifecycle active manifest digest does not match metadata.');
699
- }
700
- if (bundleFingerprint !== metadata.bundleFingerprint) {
701
- fail('Lifecycle active bundle fingerprint does not match metadata.');
702
- }
703
- let plugin;
704
- try {
705
- plugin = await loadPlugin(resolvedBundleRoot, resolvedManifestPath);
706
- }
707
- catch (error) {
708
- throw new LifecycleActiveSnapshotError('Lifecycle active plugin manifest is invalid.', { cause: error });
709
- }
710
- if (plugin.manifest.name !== metadata.pluginName || plugin.manifest.version !== metadata.pluginVersion) {
711
- fail('Lifecycle active plugin identity does not match metadata.');
712
- }
713
- if (await fs.realpath(plugin.rootDir) !== resolvedBundleRoot
714
- || await fs.realpath(plugin.manifestPath) !== resolvedManifestPath) {
715
- fail('Lifecycle active plugin loader returned paths outside the snapshot bundle.');
716
- }
717
- const declaredEvents = lifecycleEvents(plugin.manifest);
718
- if (declaredEvents.length !== metadata.events.length
719
- || declaredEvents.some((event, index) => metadata.events[index] !== event)) {
720
- fail('Lifecycle active plugin events do not match metadata.');
721
- }
722
- if (metadata.sourceId) {
723
- plugin.sourceId = metadata.sourceId;
724
- plugin.sourceIdentity = metadata.sourceIdentity;
725
- plugin.pluginId = metadata.pluginId;
726
- }
727
- return { metadata, bundleRoot: resolvedBundleRoot, manifestPath: resolvedManifestPath, plugin };
728
- }
729
- async function materializeBundleEntry(options) {
730
- const resolvedSource = await fs.realpath(options.sourcePath);
731
- if (!options.allowedRoots.some((root) => isInsidePath(resolvedSource, root))) {
732
- fail(`Lifecycle bundle link escapes its allowed closure roots: ${options.sourcePath}`);
733
- }
734
- const stat = await fs.stat(resolvedSource);
735
- if (stat.isDirectory()) {
736
- if (options.directoryStack.has(resolvedSource)) {
737
- fail(`Lifecycle bundle contains a directory link cycle: ${options.sourcePath}`);
738
- }
739
- const nextStack = new Set(options.directoryStack).add(resolvedSource);
740
- await fs.ensureDir(options.destinationPath);
741
- for (const entry of (await fs.readdir(options.sourcePath, { withFileTypes: true }))
742
- .sort((left, right) => left.name.localeCompare(right.name))) {
743
- await materializeBundleEntry({
744
- sourcePath: path.join(options.sourcePath, entry.name),
745
- destinationPath: path.join(options.destinationPath, entry.name),
746
- allowedRoots: options.allowedRoots,
747
- directoryStack: nextStack,
748
- });
749
- }
750
- await fs.chmod(options.destinationPath, stat.mode & 0o777);
751
- return;
752
- }
753
- if (stat.isFile()) {
754
- await fs.ensureDir(path.dirname(options.destinationPath));
755
- await fs.copyFile(resolvedSource, options.destinationPath, fs.constants.COPYFILE_EXCL);
756
- await fs.chmod(options.destinationPath, stat.mode & 0o777);
757
- return;
758
- }
759
- fail(`Lifecycle bundle contains a special entry: ${options.sourcePath}`);
760
- }
761
- async function materializeLifecycleBundle(options) {
762
- const sourceRoot = await fs.realpath(options.sourceRoot);
763
- const sourceStat = await fs.stat(sourceRoot);
764
- if (!sourceStat.isDirectory()) {
765
- fail(`Lifecycle bundle source root is not a directory: ${options.sourceRoot}`);
766
- }
767
- await materializeBundleEntry({
768
- sourcePath: options.sourceRoot,
769
- destinationPath: options.destinationRoot,
770
- allowedRoots: [sourceRoot],
771
- directoryStack: new Set(),
772
- });
773
- await assertNoSymlinks(options.destinationRoot);
774
- }
775
- async function pruneEmptyStagingRoot(stagingRoot) {
776
- const entries = await fs.readdir(stagingRoot).catch((error) => {
777
- if (error.code === 'ENOENT') {
778
- return null;
779
- }
780
- throw error;
781
- });
782
- if (entries?.length === 0) {
783
- await beforePruneStagingRootForTests?.();
784
- await fs.rmdir(stagingRoot);
785
- }
786
- }
787
- async function recoverTransientBackup(target, loadPlugin) {
788
- const entries = await fs.readdir(target.targetRoot).catch((error) => {
789
- if (error.code === 'ENOENT') {
790
- return [];
791
- }
792
- throw error;
793
- });
794
- const backups = entries.filter((entry) => BACKUP_ID_PATTERN.test(entry));
795
- if (backups.length > 1) {
796
- fail('Lifecycle active target contains multiple transient backups.');
797
- }
798
- const backupPath = backups[0] ? path.join(target.targetRoot, backups[0]) : null;
799
- if (!backupPath) {
800
- return;
801
- }
802
- await assertExistingDirectoryBoundary(target, backupPath, 'backupRoot');
803
- if (await lstatIfExists(target.activeRoot)) {
804
- await fs.remove(backupPath);
805
- return;
806
- }
807
- await validateSnapshotRoot(backupPath, target, loadPlugin);
808
- await fs.rename(backupPath, target.activeRoot);
809
- }
810
- async function cleanupOrphanStages(target) {
811
- const stagingStat = await lstatIfExists(target.stagingRoot);
812
- if (!stagingStat) {
813
- return;
814
- }
815
- await assertExistingDirectoryBoundary(target, target.stagingRoot, 'stagingRoot');
816
- const entries = await fs.readdir(target.stagingRoot);
817
- for (const entry of entries) {
818
- if (!STAGE_ID_PATTERN.test(entry)) {
819
- fail(`Lifecycle active staging contains an unknown entry: ${entry}`);
820
- }
821
- const stageRoot = path.join(target.stagingRoot, entry);
822
- await assertExistingDirectoryBoundary(target, stageRoot, 'orphanStageRoot');
823
- await assertNoSymlinks(stageRoot);
824
- await fs.remove(stageRoot);
825
- }
826
- await pruneEmptyStagingRoot(target.stagingRoot);
827
- }
828
- async function cleanupTransientState(target, loadPlugin) {
829
- await assertExistingDirectoryBoundary(target, target.targetRoot, 'targetRoot');
830
- await recoverTransientBackup(target, loadPlugin);
831
- await cleanupOrphanStages(target);
832
- }
833
- function attachPreparedLock(prepared, lock, loadPlugin) {
834
- preparedContexts.set(prepared, { lock, loadPlugin });
835
- return prepared;
836
- }
837
- function requirePreparedContext(prepared) {
838
- const context = preparedContexts.get(prepared);
839
- if (!context) {
840
- fail('Lifecycle active prepared snapshot no longer owns its target lock.');
841
- }
842
- return context;
843
- }
844
- function isRetryableReleaseError(error) {
845
- return new Set(['EACCES', 'EBUSY', 'EINTR', 'EIO', 'ENOTEMPTY', 'EPERM']).has(error.code ?? '');
846
- }
847
- function isPostCommitReleaseWarning(error) {
848
- const code = error.code ?? '';
849
- return code === 'EBUSY' || code === 'EPERM';
850
- }
851
- async function releaseLeaseWithRetry(lock) {
852
- let lastError;
853
- for (let attempt = 0; attempt < 3; attempt += 1) {
854
- try {
855
- await lock.release();
856
- return;
857
- }
858
- catch (error) {
859
- lastError = error;
860
- if (!isRetryableReleaseError(error))
861
- throw error;
862
- }
863
- }
864
- await lock.release().catch(() => undefined);
865
- throw lastError;
866
- }
867
- function emitLifecycleReleaseWarning(message, _releaseError) {
868
- try {
869
- process.emitWarning(`${message}.`, { code: 'AW_LIFECYCLE_LOCK_RELEASE_FAILED' });
870
- }
871
- catch {
872
- // Diagnostics cannot replace the primary lifecycle error.
873
- }
874
- }
875
- function emitLifecycleHousekeepingWarning() {
876
- try {
877
- process.emitWarning('Lifecycle active promote committed, but old backup cleanup failed.', { code: 'AW_LIFECYCLE_HOUSEKEEPING_FAILED' });
878
- }
879
- catch {
880
- // Diagnostics cannot replace a durable lifecycle commit.
881
- }
882
- }
883
- export async function prepareLifecycleActiveSnapshot(options) {
884
- const env = options.env ?? process.env;
885
- const target = await resolveLifecycleActiveTarget({
886
- ...(options.sourceId ? {
887
- sourceId: options.sourceId,
888
- sourceIdentity: options.sourceIdentity,
889
- } : {}),
890
- pluginName: options.plugin.manifest.name,
891
- platform: options.platform,
892
- scope: options.scope,
893
- cwd: options.cwd,
894
- env,
895
- });
896
- const lock = await acquireTargetLock(target, options.lifecycleLeaseHeld);
897
- let stageRoot = null;
898
- try {
899
- await cleanupTransientState(target, options.loadPlugin);
900
- await fs.ensureDir(target.stagingRoot);
901
- await assertExistingDirectoryBoundary(target, target.stagingRoot, 'stagingRoot');
902
- const stageId = `stage-${crypto.randomBytes(12).toString('hex')}`;
903
- stageRoot = path.join(target.stagingRoot, stageId);
904
- await fs.mkdir(stageRoot);
905
- const bundleRoot = path.join(stageRoot, 'bundle');
906
- await materializeLifecycleBundle({
907
- sourceRoot: options.plugin.rootDir,
908
- destinationRoot: bundleRoot,
909
- });
910
- const stagedManifestPath = path.join(bundleRoot, SOURCE_MANIFEST_PATH);
911
- const stagedPlugin = await options.loadPlugin(bundleRoot, stagedManifestPath);
912
- if (await fs.realpath(stagedPlugin.rootDir) !== await fs.realpath(bundleRoot)
913
- || await fs.realpath(stagedPlugin.manifestPath) !== await fs.realpath(stagedManifestPath)) {
914
- fail('Lifecycle active plugin loader returned paths outside the staged bundle.');
915
- }
916
- if (stagedPlugin.manifest.name !== options.plugin.manifest.name
917
- || stagedPlugin.manifest.version !== options.plugin.manifest.version) {
918
- fail('Lifecycle active source plugin identity changed during staging.');
919
- }
920
- if (!stagedPlugin.manifest.scripts?.lifecycle?.uninstall) {
921
- await fs.remove(stageRoot);
922
- stageRoot = null;
923
- await pruneEmptyStagingRoot(target.stagingRoot);
924
- return attachPreparedLock({
925
- status: 'not-required',
926
- reason: 'no-uninstall-lifecycle',
927
- target,
928
- }, lock, options.loadPlugin);
929
- }
930
- const [sourceManifestDigest, bundleFingerprint] = await Promise.all([
931
- calculateFileDigest(stagedPlugin.manifestPath),
932
- calculatePluginBundleFingerprintV2(bundleRoot),
933
- ]);
934
- const payload = {
935
- schemaVersion: target.sourceId ? LIFECYCLE_ACTIVE_SCHEMA_VERSION : 1,
936
- ...(target.sourceId ? {
937
- sourceId: target.sourceId,
938
- sourceIdentity: target.sourceIdentity,
939
- pluginId: target.pluginId,
940
- } : {}),
941
- pluginName: stagedPlugin.manifest.name,
942
- pluginVersion: stagedPlugin.manifest.version,
943
- platform: target.platform,
944
- scope: target.scope,
945
- projectKey: target.projectKey,
946
- sourceManifestDigest,
947
- fingerprintVersion: 2,
948
- bundleFingerprint,
949
- events: lifecycleEvents(stagedPlugin.manifest),
950
- artifacts: createArtifactDescriptors(options.artifacts ?? [], target),
951
- };
952
- const metadata = {
953
- ...payload,
954
- metadataIntegrityDigest: calculateMetadataIntegrityDigest(payload),
955
- };
956
- await fs.writeJson(path.join(stageRoot, LIFECYCLE_ACTIVE_METADATA_FILE), metadata, { spaces: 2 });
957
- const validated = await validateSnapshotRoot(stageRoot, target, options.loadPlugin);
958
- if (stableStringify(validated.metadata) !== stableStringify(metadata)) {
959
- fail('Lifecycle active staged metadata changed during validation.');
960
- }
961
- return attachPreparedLock({ status: 'staged', target, stageId, stageRoot, metadata }, lock, options.loadPlugin);
962
- }
963
- catch (error) {
964
- if (stageRoot) {
965
- await fs.remove(stageRoot).catch(() => undefined);
966
- await pruneEmptyStagingRoot(target.stagingRoot).catch(() => undefined);
967
- }
968
- try {
969
- await releaseLeaseWithRetry(lock);
970
- }
971
- catch (releaseError) {
972
- emitLifecycleReleaseWarning('Lifecycle active prepare failed, and its target lock could not be released', releaseError);
973
- }
974
- throw error;
975
- }
976
- }
977
- function createReadSnapshot(target, validated) {
978
- return {
979
- target,
980
- activeRoot: target.activeRoot,
981
- bundleRoot: validated.bundleRoot,
982
- manifestPath: validated.manifestPath,
983
- metadata: validated.metadata,
984
- plugin: validated.plugin,
985
- artifacts: validated.metadata.artifacts.map(({ owner: _owner, ...artifact }) => ({ ...artifact })),
986
- };
987
- }
988
- async function restoreBackupAfterFailedPromote(options) {
989
- if (options.installedNewActive) {
990
- await assertExistingDirectoryBoundary(options.target, options.target.activeRoot, 'activeRoot');
991
- await fs.remove(options.target.activeRoot);
992
- }
993
- if (options.backupPath && await lstatIfExists(options.backupPath)) {
994
- if (await lstatIfExists(options.target.activeRoot)) {
995
- fail('Lifecycle active promote cannot restore backup over an unexpected active snapshot.');
996
- }
997
- await fs.rename(options.backupPath, options.target.activeRoot);
998
- }
999
- }
1000
- export async function promoteLifecycleActiveSnapshot(prepared) {
1001
- const { lock, loadPlugin } = requirePreparedContext(prepared);
1002
- let backupPath = null;
1003
- let installedNewActive = false;
1004
- let durableCommit = false;
1005
- let primaryError;
1006
- try {
1007
- await assertExistingDirectoryBoundary(prepared.target, prepared.target.targetRoot, 'targetRoot');
1008
- if (prepared.status === 'not-required') {
1009
- await removeLifecycleSnapshotDataLocked(prepared.target);
1010
- durableCommit = true;
1011
- markActiveMarketplaceDurableCommit();
1012
- return null;
1013
- }
1014
- const expectedStageRoot = path.join(prepared.target.stagingRoot, prepared.stageId);
1015
- if (!STAGE_ID_PATTERN.test(prepared.stageId)
1016
- || path.resolve(prepared.stageRoot) !== path.resolve(expectedStageRoot)) {
1017
- fail('Lifecycle active stage identity is invalid.');
1018
- }
1019
- const staged = await validateSnapshotRoot(prepared.stageRoot, prepared.target, loadPlugin);
1020
- if (stableStringify(staged.metadata) !== stableStringify(prepared.metadata)) {
1021
- fail('Lifecycle active stage metadata no longer matches its prepared generation.');
1022
- }
1023
- if (await lstatIfExists(prepared.target.activeRoot)) {
1024
- await validateSnapshotRoot(prepared.target.activeRoot, prepared.target, loadPlugin);
1025
- backupPath = path.join(prepared.target.targetRoot, `backup-${crypto.randomBytes(12).toString('hex')}`);
1026
- await fs.rename(prepared.target.activeRoot, backupPath);
1027
- }
1028
- await fs.rename(prepared.stageRoot, prepared.target.activeRoot);
1029
- installedNewActive = true;
1030
- const active = await validateSnapshotRoot(prepared.target.activeRoot, prepared.target, loadPlugin);
1031
- if (stableStringify(active.metadata) !== stableStringify(prepared.metadata)) {
1032
- fail('Lifecycle active promoted generation changed during promotion.');
1033
- }
1034
- durableCommit = true;
1035
- markActiveMarketplaceDurableCommit();
1036
- if (backupPath) {
1037
- try {
1038
- await fs.remove(backupPath);
1039
- backupPath = null;
1040
- }
1041
- catch {
1042
- emitLifecycleHousekeepingWarning();
1043
- }
1044
- }
1045
- await pruneEmptyStagingRoot(prepared.target.stagingRoot).catch(() => undefined);
1046
- return createReadSnapshot(prepared.target, active);
1047
- }
1048
- catch (error) {
1049
- primaryError = error;
1050
- if (durableCommit)
1051
- throw error;
1052
- try {
1053
- await restoreBackupAfterFailedPromote({
1054
- target: prepared.target,
1055
- backupPath,
1056
- installedNewActive,
1057
- });
1058
- if (prepared.status === 'staged' && await lstatIfExists(prepared.stageRoot)) {
1059
- await fs.remove(prepared.stageRoot);
1060
- }
1061
- await pruneEmptyStagingRoot(prepared.target.stagingRoot).catch(() => undefined);
1062
- }
1063
- catch (restoreError) {
1064
- primaryError = new AggregateError([error, restoreError], 'Lifecycle active promote failed and its previous active generation could not be restored.', { cause: error });
1065
- throw primaryError;
1066
- }
1067
- throw error;
1068
- }
1069
- finally {
1070
- try {
1071
- await releaseLeaseWithRetry(lock);
1072
- }
1073
- catch (releaseError) {
1074
- if (primaryError !== undefined) {
1075
- emitLifecycleReleaseWarning('Lifecycle active promote failed, and its target lock could not be released', releaseError);
1076
- }
1077
- else if (durableCommit && isPostCommitReleaseWarning(releaseError)) {
1078
- emitLifecycleReleaseWarning('Lifecycle active promote committed, but its target lock could not be released', releaseError);
1079
- }
1080
- else {
1081
- throw releaseError;
1082
- }
1083
- }
1084
- finally {
1085
- finalizedPrepared.add(prepared);
1086
- preparedContexts.delete(prepared);
1087
- }
1088
- }
1089
- }
1090
- export async function discardLifecycleActiveSnapshot(prepared) {
1091
- const context = preparedContexts.get(prepared);
1092
- if (!context && finalizedPrepared.has(prepared)) {
1093
- return;
1094
- }
1095
- if (!context) {
1096
- fail('Lifecycle active prepared snapshot no longer owns its target lock.');
1097
- }
1098
- const { lock } = context;
1099
- let primaryError;
1100
- try {
1101
- if (prepared.status === 'staged') {
1102
- const expectedStageRoot = path.join(prepared.target.stagingRoot, prepared.stageId);
1103
- if (path.resolve(prepared.stageRoot) !== path.resolve(expectedStageRoot)) {
1104
- fail('Lifecycle active discard stage identity is invalid.');
1105
- }
1106
- await assertExistingDirectoryBoundary(prepared.target, prepared.stageRoot, 'stageRoot');
1107
- await fs.remove(prepared.stageRoot);
1108
- await pruneEmptyStagingRoot(prepared.target.stagingRoot);
1109
- }
1110
- }
1111
- catch (error) {
1112
- primaryError = error;
1113
- throw error;
1114
- }
1115
- finally {
1116
- try {
1117
- await releaseLeaseWithRetry(lock);
1118
- }
1119
- catch (releaseError) {
1120
- if (primaryError !== undefined) {
1121
- emitLifecycleReleaseWarning('Lifecycle active discard failed, and its target lock could not be released', releaseError);
1122
- throw primaryError;
1123
- }
1124
- throw releaseError;
1125
- }
1126
- finalizedPrepared.add(prepared);
1127
- preparedContexts.delete(prepared);
1128
- }
1129
- }
1130
- async function readLifecycleActiveSnapshotUnlocked(options) {
1131
- const target = await resolveLifecycleActiveTarget(options);
1132
- await assertExistingPathChainHasNoSymlinks(target.awHome, target.activeRoot);
1133
- if (!await lstatIfExists(target.activeRoot)) {
1134
- return null;
1135
- }
1136
- try {
1137
- return createReadSnapshot(target, await validateSnapshotRoot(target.activeRoot, target, options.loadPlugin));
1138
- }
1139
- catch (error) {
1140
- if (error instanceof LifecycleActiveSnapshotError) {
1141
- throw error;
1142
- }
1143
- throw new LifecycleActiveSnapshotError('Lifecycle active snapshot is corrupt.', { cause: error });
1144
- }
1145
- }
1146
- export async function readLifecycleActiveSnapshot(options) {
1147
- return withActiveMarketplaceLifecycleLease(options.env, () => readLifecycleActiveSnapshotUnlocked(options));
1148
- }
1149
- // Catalog reference inventory can run while the runtime coordination lease is held.
1150
- // Active publication also needs that lease, so inventory must not acquire lifecycle after runtime.
1151
- export async function inspectLifecycleActiveSnapshotForInventory(options) {
1152
- return readLifecycleActiveSnapshotUnlocked(options);
1153
- }
1154
- export async function leaseLifecycleActiveSnapshot(options) {
1155
- const target = await resolveLifecycleActiveTarget(options);
1156
- const lock = await acquireTargetLock(target, options.lifecycleLeaseHeld);
1157
- let snapshot;
1158
- try {
1159
- await assertExistingPathChainHasNoSymlinks(target.awHome, target.activeRoot);
1160
- if (!await lstatIfExists(target.activeRoot)) {
1161
- snapshot = null;
1162
- }
1163
- else {
1164
- snapshot = createReadSnapshot(target, await validateSnapshotRoot(target.activeRoot, target, options.loadPlugin));
1165
- }
1166
- }
1167
- catch (error) {
1168
- const primaryError = error instanceof LifecycleActiveSnapshotError
1169
- ? error
1170
- : new LifecycleActiveSnapshotError('Lifecycle active snapshot is corrupt.', { cause: error });
1171
- try {
1172
- await releaseLeaseWithRetry(lock);
1173
- }
1174
- catch (releaseError) {
1175
- emitLifecycleReleaseWarning('Lifecycle active read failed, and its target lock could not be released', releaseError);
1176
- }
1177
- throw primaryError;
1178
- }
1179
- if (!snapshot) {
1180
- await releaseLeaseWithRetry(lock);
1181
- return null;
1182
- }
1183
- readContexts.set(snapshot, lock);
1184
- return snapshot;
1185
- }
1186
- export async function releaseLifecycleActiveSnapshot(snapshot) {
1187
- const lock = readContexts.get(snapshot);
1188
- if (!lock && releasedReads.has(snapshot))
1189
- return;
1190
- if (!lock) {
1191
- fail('Lifecycle active read snapshot no longer owns its target lock.');
1192
- }
1193
- await releaseLeaseWithRetry(lock);
1194
- readContexts.delete(snapshot);
1195
- releasedReads.add(snapshot);
1196
- }
1197
- export function restoreLifecycleActiveScriptInputs(snapshot) {
1198
- return { currentPlugin: snapshot.plugin, artifacts: snapshot.artifacts };
1199
- }
1200
- async function removeLifecycleSnapshotDataLocked(target) {
1201
- await assertExistingDirectoryBoundary(target, target.targetRoot, 'targetRoot');
1202
- for (const ownedPath of [target.activeRoot, target.stagingRoot]) {
1203
- const stat = await lstatIfExists(ownedPath);
1204
- if (!stat) {
1205
- continue;
1206
- }
1207
- await assertExistingDirectoryBoundary(target, ownedPath, path.basename(ownedPath));
1208
- await fs.remove(ownedPath);
1209
- }
1210
- const remaining = await fs.readdir(target.targetRoot).catch((error) => {
1211
- if (error.code === 'ENOENT') {
1212
- return null;
1213
- }
1214
- throw error;
1215
- });
1216
- if (remaining?.length === 0) {
1217
- await fs.rmdir(target.targetRoot);
1218
- }
1219
- }
1220
- async function removeTransientBackupsLocked(target) {
1221
- const entries = await fs.readdir(target.targetRoot).catch((error) => {
1222
- if (error.code === 'ENOENT')
1223
- return [];
1224
- throw error;
1225
- });
1226
- for (const entry of entries.filter((name) => BACKUP_ID_PATTERN.test(name))) {
1227
- const backupPath = path.join(target.targetRoot, entry);
1228
- await assertExistingDirectoryBoundary(target, backupPath, 'backupRoot');
1229
- await fs.remove(backupPath);
1230
- }
1231
- }
1232
- export async function removeLifecycleActiveSnapshot(options) {
1233
- const target = await resolveLifecycleActiveTarget(options);
1234
- const lock = await acquireTargetLock(target, options.lifecycleLeaseHeld);
1235
- let durableCommit = false;
1236
- let primaryError;
1237
- try {
1238
- if (options.expectedMetadataIntegrityDigest !== undefined) {
1239
- await assertExistingDirectoryBoundary(target, target.activeRoot, 'activeRoot');
1240
- const metadata = await fs.readJson(path.join(target.activeRoot, LIFECYCLE_ACTIVE_METADATA_FILE));
1241
- if (metadata === null
1242
- || typeof metadata !== 'object'
1243
- || Array.isArray(metadata)
1244
- || metadata.metadataIntegrityDigest
1245
- !== options.expectedMetadataIntegrityDigest) {
1246
- fail('stateInventoryFailed: lifecycle active generation changed before removal.');
1247
- }
1248
- }
1249
- await cleanupOrphanStages(target);
1250
- await removeTransientBackupsLocked(target);
1251
- await removeLifecycleSnapshotDataLocked(target);
1252
- durableCommit = true;
1253
- markActiveMarketplaceDurableCommit();
1254
- }
1255
- catch (error) {
1256
- primaryError = error;
1257
- throw error;
1258
- }
1259
- finally {
1260
- try {
1261
- await releaseLeaseWithRetry(lock);
1262
- }
1263
- catch (releaseError) {
1264
- if (primaryError !== undefined) {
1265
- emitLifecycleReleaseWarning('Lifecycle active remove failed, and its target lock could not be released', releaseError);
1266
- }
1267
- else if (durableCommit && isPostCommitReleaseWarning(releaseError)) {
1268
- emitLifecycleReleaseWarning('Lifecycle active remove committed, but its target lock could not be released', releaseError);
1269
- }
1270
- else {
1271
- throw releaseError;
1272
- }
1273
- }
1274
- }
1275
- }
1276
- //# sourceMappingURL=lifecycle-active-store.js.map