@mannyc1/ts-release 0.0.6 → 0.2.2

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 (639) hide show
  1. package/ARCHITECTURE.md +124 -87
  2. package/CHANGELOG.md +115 -0
  3. package/LICENSE +21 -0
  4. package/README.md +272 -540
  5. package/SPEC.md +206 -305
  6. package/apps/release-ts/README.md +32 -0
  7. package/apps/release-ts/src/cli/command.ts +164 -0
  8. package/apps/release-ts/src/cli/commands.ts +351 -0
  9. package/apps/release-ts/src/cli/main.ts +43 -0
  10. package/apps/release-ts/src/cli/node-main.ts +49 -0
  11. package/apps/ts-release-agents/LICENSE +21 -0
  12. package/apps/ts-release-agents/README.md +21 -0
  13. package/apps/ts-release-agents/evals/cases.json +11 -0
  14. package/apps/ts-release-agents/manifests/claude.json +5 -0
  15. package/apps/ts-release-agents/manifests/codex.json +5 -0
  16. package/apps/ts-release-agents/package.json +11 -0
  17. package/apps/ts-release-agents/skills/release/SKILL.md +48 -0
  18. package/apps/ts-release-agents/skills/release/references/configuration.md +18 -0
  19. package/apps/ts-release-agents/skills/release/references/recovery.md +10 -0
  20. package/apps/ts-release-agents/skills/release/references/staged-workflow.md +12 -0
  21. package/apps/ts-release-agents/skills/release/references/target-selection.md +13 -0
  22. package/apps/ts-release-agents/skills/release/references/verification.md +14 -0
  23. package/apps/ts-release-agents/src/build.ts +105 -0
  24. package/apps/ts-release-agents/src/check.ts +117 -0
  25. package/apps/ts-release-agents/src/install.ts +121 -0
  26. package/apps/ts-release-agents/test/contract.test.ts +56 -0
  27. package/apps/ts-release-agents/tsconfig.json +5 -0
  28. package/dist/api/api.d.ts +15 -0
  29. package/dist/api/api.d.ts.map +1 -0
  30. package/dist/api/api.js +244 -0
  31. package/dist/api/api.js.map +1 -0
  32. package/dist/api/errors.d.ts +39 -0
  33. package/dist/api/errors.d.ts.map +1 -0
  34. package/dist/api/errors.js +32 -0
  35. package/dist/api/errors.js.map +1 -0
  36. package/dist/api/input.d.ts +10 -0
  37. package/dist/api/input.d.ts.map +1 -0
  38. package/dist/api/input.js +73 -0
  39. package/dist/api/input.js.map +1 -0
  40. package/dist/api/runtime.d.ts +18 -0
  41. package/dist/api/runtime.d.ts.map +1 -0
  42. package/dist/api/runtime.js +7 -0
  43. package/dist/api/runtime.js.map +1 -0
  44. package/dist/api/types.d.ts +76 -0
  45. package/dist/api/types.d.ts.map +1 -0
  46. package/dist/api/types.js +17 -0
  47. package/dist/api/types.js.map +1 -0
  48. package/dist/bin/ts-release.js +39239 -0
  49. package/dist/capabilities/bun-targets.d.ts +3 -0
  50. package/dist/capabilities/bun-targets.d.ts.map +1 -0
  51. package/dist/capabilities/bun-targets.js +3 -0
  52. package/dist/capabilities/bun-targets.js.map +1 -0
  53. package/dist/capabilities/field-ownership.d.ts +17 -0
  54. package/dist/capabilities/field-ownership.d.ts.map +1 -0
  55. package/dist/capabilities/field-ownership.js +40 -0
  56. package/dist/capabilities/field-ownership.js.map +1 -0
  57. package/dist/capabilities/module.d.ts +91 -0
  58. package/dist/capabilities/module.d.ts.map +1 -0
  59. package/dist/capabilities/module.js +2 -0
  60. package/dist/capabilities/module.js.map +1 -0
  61. package/dist/capabilities/registry.d.ts +829 -0
  62. package/dist/capabilities/registry.d.ts.map +1 -0
  63. package/dist/capabilities/registry.js +291 -0
  64. package/dist/capabilities/registry.js.map +1 -0
  65. package/dist/config/config.d.ts +6 -0
  66. package/dist/config/config.d.ts.map +1 -0
  67. package/dist/config/config.js +42 -0
  68. package/dist/config/config.js.map +1 -0
  69. package/dist/correction/coordinator.d.ts +248 -0
  70. package/dist/correction/coordinator.d.ts.map +1 -0
  71. package/dist/correction/coordinator.js +274 -0
  72. package/dist/correction/coordinator.js.map +1 -0
  73. package/dist/correction/index.d.ts +3 -0
  74. package/dist/correction/index.d.ts.map +1 -0
  75. package/dist/correction/index.js +3 -0
  76. package/dist/correction/index.js.map +1 -0
  77. package/dist/correction/intent.d.ts +111 -0
  78. package/dist/correction/intent.d.ts.map +1 -0
  79. package/dist/correction/intent.js +146 -0
  80. package/dist/correction/intent.js.map +1 -0
  81. package/dist/drivers/archive.d.ts +8 -0
  82. package/dist/drivers/archive.d.ts.map +1 -0
  83. package/dist/drivers/archive.js +101 -0
  84. package/dist/drivers/archive.js.map +1 -0
  85. package/dist/drivers/contain.d.ts +6 -0
  86. package/dist/drivers/contain.d.ts.map +1 -0
  87. package/dist/drivers/contain.js +17 -0
  88. package/dist/drivers/contain.js.map +1 -0
  89. package/dist/drivers/environment.d.ts +4 -0
  90. package/dist/drivers/environment.d.ts.map +1 -0
  91. package/dist/drivers/environment.js +18 -0
  92. package/dist/drivers/environment.js.map +1 -0
  93. package/dist/drivers/errors.d.ts +9 -0
  94. package/dist/drivers/errors.d.ts.map +1 -0
  95. package/dist/drivers/errors.js +6 -0
  96. package/dist/drivers/errors.js.map +1 -0
  97. package/dist/drivers/glob.d.ts +2 -0
  98. package/dist/drivers/glob.d.ts.map +1 -0
  99. package/dist/drivers/glob.js +162 -0
  100. package/dist/drivers/glob.js.map +1 -0
  101. package/dist/drivers/process.d.ts +48 -0
  102. package/dist/drivers/process.d.ts.map +1 -0
  103. package/dist/drivers/process.js +257 -0
  104. package/dist/drivers/process.js.map +1 -0
  105. package/dist/drivers/redact.d.ts +4 -0
  106. package/dist/drivers/redact.d.ts.map +1 -0
  107. package/dist/drivers/redact.js +24 -0
  108. package/dist/drivers/redact.js.map +1 -0
  109. package/dist/drivers/seccomp-helper-source.d.ts +7 -0
  110. package/dist/drivers/seccomp-helper-source.d.ts.map +1 -0
  111. package/dist/drivers/seccomp-helper-source.js +121 -0
  112. package/dist/drivers/seccomp-helper-source.js.map +1 -0
  113. package/dist/drivers/utils.d.ts +4 -0
  114. package/dist/drivers/utils.d.ts.map +1 -0
  115. package/dist/drivers/utils.js +5 -0
  116. package/dist/drivers/utils.js.map +1 -0
  117. package/dist/drivers/workspace.d.ts +6 -0
  118. package/dist/drivers/workspace.d.ts.map +1 -0
  119. package/dist/drivers/workspace.js +49 -0
  120. package/dist/drivers/workspace.js.map +1 -0
  121. package/dist/extensions/provider-adapter.d.ts +48 -0
  122. package/dist/extensions/provider-adapter.d.ts.map +1 -0
  123. package/dist/extensions/provider-adapter.js +64 -0
  124. package/dist/extensions/provider-adapter.js.map +1 -0
  125. package/dist/host.d.ts +33 -0
  126. package/dist/host.d.ts.map +1 -0
  127. package/dist/host.js +20 -0
  128. package/dist/host.js.map +1 -0
  129. package/dist/index.d.ts +19 -1
  130. package/dist/index.d.ts.map +1 -1
  131. package/dist/index.js +12 -1
  132. package/dist/index.js.map +1 -1
  133. package/dist/model/artifact-collection.d.ts +84 -0
  134. package/dist/model/artifact-collection.d.ts.map +1 -0
  135. package/dist/model/artifact-collection.js +185 -0
  136. package/dist/model/artifact-collection.js.map +1 -0
  137. package/dist/model/authority.d.ts +89 -0
  138. package/dist/model/authority.d.ts.map +1 -0
  139. package/dist/model/authority.js +80 -0
  140. package/dist/model/authority.js.map +1 -0
  141. package/dist/model/bun-targets.d.ts +34 -0
  142. package/dist/model/bun-targets.d.ts.map +1 -0
  143. package/dist/model/bun-targets.js +17 -0
  144. package/dist/model/bun-targets.js.map +1 -0
  145. package/dist/model/canonical.d.ts +8 -0
  146. package/dist/model/canonical.d.ts.map +1 -0
  147. package/dist/model/canonical.js +205 -0
  148. package/dist/model/canonical.js.map +1 -0
  149. package/dist/model/catalog.d.ts +76 -0
  150. package/dist/model/catalog.d.ts.map +1 -0
  151. package/dist/model/catalog.js +174 -0
  152. package/dist/model/catalog.js.map +1 -0
  153. package/dist/model/digest.d.ts +53 -0
  154. package/dist/model/digest.d.ts.map +1 -0
  155. package/dist/model/digest.js +127 -0
  156. package/dist/model/digest.js.map +1 -0
  157. package/dist/model/errors.d.ts +14 -0
  158. package/dist/model/errors.d.ts.map +1 -0
  159. package/dist/model/errors.js +8 -0
  160. package/dist/model/errors.js.map +1 -0
  161. package/dist/model/primitives.d.ts +19 -0
  162. package/dist/model/primitives.d.ts.map +1 -0
  163. package/dist/model/primitives.js +18 -0
  164. package/dist/model/primitives.js.map +1 -0
  165. package/dist/model/pypi.d.ts +12 -0
  166. package/dist/model/pypi.d.ts.map +1 -0
  167. package/dist/model/pypi.js +20 -0
  168. package/dist/model/pypi.js.map +1 -0
  169. package/dist/model/python-distribution.d.ts +33 -0
  170. package/dist/model/python-distribution.d.ts.map +1 -0
  171. package/dist/model/python-distribution.js +367 -0
  172. package/dist/model/python-distribution.js.map +1 -0
  173. package/dist/model/secret-patterns.d.ts +2 -0
  174. package/dist/model/secret-patterns.d.ts.map +1 -0
  175. package/dist/model/secret-patterns.js +12 -0
  176. package/dist/model/secret-patterns.js.map +1 -0
  177. package/dist/platform/bun.d.ts +7 -0
  178. package/dist/platform/bun.d.ts.map +1 -0
  179. package/dist/platform/bun.js +15 -0
  180. package/dist/platform/bun.js.map +1 -0
  181. package/dist/platform/credentials.d.ts +32 -0
  182. package/dist/platform/credentials.d.ts.map +1 -0
  183. package/dist/platform/credentials.js +772 -0
  184. package/dist/platform/credentials.js.map +1 -0
  185. package/dist/platform/host-support.d.ts +2 -0
  186. package/dist/platform/host-support.d.ts.map +1 -0
  187. package/dist/platform/host-support.js +4 -0
  188. package/dist/platform/host-support.js.map +1 -0
  189. package/dist/platform/node.d.ts +7 -0
  190. package/dist/platform/node.d.ts.map +1 -0
  191. package/dist/platform/node.js +15 -0
  192. package/dist/platform/node.js.map +1 -0
  193. package/dist/platform/release-runtime.d.ts +11 -0
  194. package/dist/platform/release-runtime.d.ts.map +1 -0
  195. package/dist/platform/release-runtime.js +34 -0
  196. package/dist/platform/release-runtime.js.map +1 -0
  197. package/dist/platform/services.d.ts +15 -0
  198. package/dist/platform/services.d.ts.map +1 -0
  199. package/dist/platform/services.js +30 -0
  200. package/dist/platform/services.js.map +1 -0
  201. package/dist/platform/source-observer.d.ts +5 -0
  202. package/dist/platform/source-observer.d.ts.map +1 -0
  203. package/dist/platform/source-observer.js +159 -0
  204. package/dist/platform/source-observer.js.map +1 -0
  205. package/dist/provider-sdk.d.ts +14 -0
  206. package/dist/provider-sdk.d.ts.map +1 -0
  207. package/dist/provider-sdk.js +10 -0
  208. package/dist/provider-sdk.js.map +1 -0
  209. package/dist/publication/adapter.d.ts +212 -0
  210. package/dist/publication/adapter.d.ts.map +1 -0
  211. package/dist/publication/adapter.js +83 -0
  212. package/dist/publication/adapter.js.map +1 -0
  213. package/dist/publication/authority.d.ts +137 -0
  214. package/dist/publication/authority.d.ts.map +1 -0
  215. package/dist/publication/authority.js +233 -0
  216. package/dist/publication/authority.js.map +1 -0
  217. package/dist/publication/catalog-git.d.ts +37 -0
  218. package/dist/publication/catalog-git.d.ts.map +1 -0
  219. package/dist/publication/catalog-git.js +451 -0
  220. package/dist/publication/catalog-git.js.map +1 -0
  221. package/dist/publication/claim.d.ts +39 -0
  222. package/dist/publication/claim.d.ts.map +1 -0
  223. package/dist/publication/claim.js +31 -0
  224. package/dist/publication/claim.js.map +1 -0
  225. package/dist/publication/coordinator.d.ts +246 -0
  226. package/dist/publication/coordinator.d.ts.map +1 -0
  227. package/dist/publication/coordinator.js +370 -0
  228. package/dist/publication/coordinator.js.map +1 -0
  229. package/dist/publication/github.d.ts +36 -0
  230. package/dist/publication/github.d.ts.map +1 -0
  231. package/dist/publication/github.js +644 -0
  232. package/dist/publication/github.js.map +1 -0
  233. package/dist/publication/http.d.ts +69 -0
  234. package/dist/publication/http.d.ts.map +1 -0
  235. package/dist/publication/http.js +29 -0
  236. package/dist/publication/http.js.map +1 -0
  237. package/dist/publication/index.d.ts +5 -0
  238. package/dist/publication/index.d.ts.map +1 -0
  239. package/dist/publication/index.js +5 -0
  240. package/dist/publication/index.js.map +1 -0
  241. package/dist/publication/npm.d.ts +40 -0
  242. package/dist/publication/npm.d.ts.map +1 -0
  243. package/dist/publication/npm.js +359 -0
  244. package/dist/publication/npm.js.map +1 -0
  245. package/dist/publication/profiles.d.ts +136 -0
  246. package/dist/publication/profiles.d.ts.map +1 -0
  247. package/dist/publication/profiles.js +90 -0
  248. package/dist/publication/profiles.js.map +1 -0
  249. package/dist/publication/publisher.d.ts +82 -0
  250. package/dist/publication/publisher.d.ts.map +1 -0
  251. package/dist/publication/publisher.js +53 -0
  252. package/dist/publication/publisher.js.map +1 -0
  253. package/dist/publication/pypi.d.ts +45 -0
  254. package/dist/publication/pypi.d.ts.map +1 -0
  255. package/dist/publication/pypi.js +369 -0
  256. package/dist/publication/pypi.js.map +1 -0
  257. package/dist/publication/recovery.d.ts +663 -0
  258. package/dist/publication/recovery.d.ts.map +1 -0
  259. package/dist/publication/recovery.js +252 -0
  260. package/dist/publication/recovery.js.map +1 -0
  261. package/dist/publication/report.d.ts +1061 -0
  262. package/dist/publication/report.d.ts.map +1 -0
  263. package/dist/publication/report.js +441 -0
  264. package/dist/publication/report.js.map +1 -0
  265. package/dist/recipes/config.d.ts +296 -0
  266. package/dist/recipes/config.d.ts.map +1 -0
  267. package/dist/recipes/config.js +325 -0
  268. package/dist/recipes/config.js.map +1 -0
  269. package/dist/release/capabilities.d.ts +12 -0
  270. package/dist/release/capabilities.d.ts.map +1 -0
  271. package/dist/release/capabilities.js +395 -0
  272. package/dist/release/capabilities.js.map +1 -0
  273. package/dist/release/compiler.d.ts +5 -0
  274. package/dist/release/compiler.d.ts.map +1 -0
  275. package/dist/release/compiler.js +19 -0
  276. package/dist/release/compiler.js.map +1 -0
  277. package/dist/release/config.d.ts +5 -0
  278. package/dist/release/config.d.ts.map +1 -0
  279. package/dist/release/config.js +10 -0
  280. package/dist/release/config.js.map +1 -0
  281. package/dist/release/context.d.ts +96 -0
  282. package/dist/release/context.d.ts.map +1 -0
  283. package/dist/release/context.js +168 -0
  284. package/dist/release/context.js.map +1 -0
  285. package/dist/release/graph.d.ts +271 -0
  286. package/dist/release/graph.d.ts.map +1 -0
  287. package/dist/release/graph.js +766 -0
  288. package/dist/release/graph.js.map +1 -0
  289. package/dist/release/inspect.d.ts +88 -0
  290. package/dist/release/inspect.d.ts.map +1 -0
  291. package/dist/release/inspect.js +75 -0
  292. package/dist/release/inspect.js.map +1 -0
  293. package/dist/release/prepare.d.ts +24 -0
  294. package/dist/release/prepare.d.ts.map +1 -0
  295. package/dist/release/prepare.js +1116 -0
  296. package/dist/release/prepare.js.map +1 -0
  297. package/dist/release/prepared-ref.d.ts +60 -0
  298. package/dist/release/prepared-ref.d.ts.map +1 -0
  299. package/dist/release/prepared-ref.js +131 -0
  300. package/dist/release/prepared-ref.js.map +1 -0
  301. package/dist/release/prepared-store.d.ts +90 -0
  302. package/dist/release/prepared-store.d.ts.map +1 -0
  303. package/dist/release/prepared-store.js +337 -0
  304. package/dist/release/prepared-store.js.map +1 -0
  305. package/dist/release/prepared.d.ts +172 -0
  306. package/dist/release/prepared.d.ts.map +1 -0
  307. package/dist/release/prepared.js +268 -0
  308. package/dist/release/prepared.js.map +1 -0
  309. package/dist/release/staging.d.ts +31 -0
  310. package/dist/release/staging.d.ts.map +1 -0
  311. package/dist/release/staging.js +218 -0
  312. package/dist/release/staging.js.map +1 -0
  313. package/dist/resolve/authored.d.ts +53 -0
  314. package/dist/resolve/authored.d.ts.map +1 -0
  315. package/dist/resolve/authored.js +55 -0
  316. package/dist/resolve/authored.js.map +1 -0
  317. package/dist/resolve/encode.d.ts +3 -0
  318. package/dist/resolve/encode.d.ts.map +1 -0
  319. package/dist/resolve/encode.js +21 -0
  320. package/dist/resolve/encode.js.map +1 -0
  321. package/dist/resolve/errors.d.ts +7 -0
  322. package/dist/resolve/errors.d.ts.map +1 -0
  323. package/dist/resolve/errors.js +17 -0
  324. package/dist/resolve/errors.js.map +1 -0
  325. package/dist/resolve/facts.d.ts +12 -0
  326. package/dist/resolve/facts.d.ts.map +1 -0
  327. package/dist/resolve/facts.js +18 -0
  328. package/dist/resolve/facts.js.map +1 -0
  329. package/dist/resolve/resolve.d.ts +10 -0
  330. package/dist/resolve/resolve.d.ts.map +1 -0
  331. package/dist/resolve/resolve.js +242 -0
  332. package/dist/resolve/resolve.js.map +1 -0
  333. package/dist/store.d.ts +11 -0
  334. package/dist/store.d.ts.map +1 -0
  335. package/dist/store.js +9 -0
  336. package/dist/store.js.map +1 -0
  337. package/examples/README.md +20 -30
  338. package/examples/github-release/release.config.json +11 -18
  339. package/examples/homebrew-tap/README.md +11 -0
  340. package/examples/homebrew-tap/release.config.json +40 -28
  341. package/examples/multi-target/release.config.json +28 -53
  342. package/examples/npm-first-publish/release.config.json +23 -25
  343. package/examples/npm-only/release.config.json +22 -30
  344. package/examples/portable-cli/README.md +17 -0
  345. package/examples/portable-cli/artifacts/portable-example-0.1.0-darwin-arm64 +1 -0
  346. package/examples/portable-cli/artifacts/portable-example-0.1.0-darwin-x64 +1 -0
  347. package/examples/portable-cli/artifacts/portable-example-0.1.0-linux-arm64 +1 -0
  348. package/examples/portable-cli/artifacts/portable-example-0.1.0-linux-x64 +1 -0
  349. package/examples/portable-cli/artifacts/portable-example-0.1.0-windows-x64.exe +1 -0
  350. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-macosx_10_15_x86_64.whl +1 -0
  351. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-macosx_11_0_arm64.whl +1 -0
  352. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-manylinux2014_aarch64.whl +1 -0
  353. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-manylinux2014_x86_64.whl +1 -0
  354. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-win_amd64.whl +1 -0
  355. package/examples/portable-cli/package.json +9 -0
  356. package/examples/portable-cli/release.config.json +53 -0
  357. package/examples/portable-cli/src/cli.ts +3 -0
  358. package/examples/pypi-registry/README.md +8 -0
  359. package/examples/scoop-bucket/README.md +10 -0
  360. package/examples/scoop-bucket/release.config.json +40 -30
  361. package/package.json +61 -154
  362. package/src/api/api.ts +365 -0
  363. package/src/api/errors.ts +36 -0
  364. package/src/api/input.ts +92 -0
  365. package/src/api/runtime.ts +14 -0
  366. package/src/api/types.ts +103 -0
  367. package/src/capabilities/bun-targets.ts +2 -0
  368. package/src/capabilities/field-ownership.ts +60 -0
  369. package/src/capabilities/module.ts +158 -0
  370. package/src/capabilities/registry.ts +333 -0
  371. package/src/config/config.ts +48 -0
  372. package/src/correction/coordinator.ts +336 -0
  373. package/src/correction/index.ts +2 -0
  374. package/src/correction/intent.ts +172 -0
  375. package/src/drivers/archive.ts +102 -0
  376. package/src/drivers/contain.ts +20 -0
  377. package/src/drivers/environment.ts +28 -0
  378. package/src/drivers/errors.ts +6 -0
  379. package/src/drivers/glob.ts +137 -0
  380. package/src/drivers/process.ts +340 -0
  381. package/src/drivers/redact.ts +31 -0
  382. package/src/drivers/seccomp-helper-source.ts +121 -0
  383. package/src/drivers/utils.ts +10 -0
  384. package/src/drivers/workspace.ts +40 -0
  385. package/src/extensions/provider-adapter.ts +99 -0
  386. package/src/host.ts +140 -0
  387. package/src/index.ts +64 -0
  388. package/src/model/artifact-collection.ts +237 -0
  389. package/src/model/authority.ts +116 -0
  390. package/src/model/bun-targets.ts +34 -0
  391. package/src/model/canonical.ts +205 -0
  392. package/src/model/catalog.ts +220 -0
  393. package/src/model/digest.ts +172 -0
  394. package/src/model/errors.ts +6 -0
  395. package/src/model/primitives.ts +37 -0
  396. package/src/model/pypi.ts +30 -0
  397. package/src/model/python-distribution.ts +360 -0
  398. package/src/model/secret-patterns.ts +11 -0
  399. package/src/platform/bun.ts +38 -0
  400. package/src/platform/credentials.ts +1083 -0
  401. package/src/platform/host-support.ts +4 -0
  402. package/src/platform/node.ts +38 -0
  403. package/src/platform/release-runtime.ts +47 -0
  404. package/src/platform/services.ts +57 -0
  405. package/src/platform/source-observer.ts +193 -0
  406. package/src/provider-sdk.ts +48 -0
  407. package/src/publication/adapter.ts +132 -0
  408. package/src/publication/authority.ts +397 -0
  409. package/src/publication/catalog-git.ts +603 -0
  410. package/src/publication/claim.ts +51 -0
  411. package/src/publication/coordinator.ts +578 -0
  412. package/src/publication/github.ts +954 -0
  413. package/src/publication/http.ts +101 -0
  414. package/src/publication/index.ts +4 -0
  415. package/src/publication/npm.ts +525 -0
  416. package/src/publication/profiles.ts +94 -0
  417. package/src/publication/publisher.ts +130 -0
  418. package/src/publication/pypi.ts +463 -0
  419. package/src/publication/recovery.ts +349 -0
  420. package/src/publication/report.ts +628 -0
  421. package/src/recipes/config.ts +395 -0
  422. package/src/release/capabilities.ts +459 -0
  423. package/src/release/compiler.ts +28 -0
  424. package/src/release/config.ts +12 -0
  425. package/src/release/context.ts +223 -0
  426. package/src/release/graph.ts +866 -0
  427. package/src/release/inspect.ts +83 -0
  428. package/src/release/prepare.ts +1331 -0
  429. package/src/release/prepared-ref.ts +193 -0
  430. package/src/release/prepared-store.ts +377 -0
  431. package/src/release/prepared.ts +299 -0
  432. package/src/release/staging.ts +257 -0
  433. package/src/resolve/authored.ts +64 -0
  434. package/src/resolve/encode.ts +22 -0
  435. package/src/resolve/errors.ts +15 -0
  436. package/src/resolve/facts.ts +18 -0
  437. package/src/resolve/resolve.ts +328 -0
  438. package/src/store.ts +28 -0
  439. package/templates/README.md +55 -59
  440. package/templates/bun-cli-github/README.md +12 -0
  441. package/templates/bun-cli-github/release.config.json +51 -0
  442. package/templates/github-actions/release.yml +57 -0
  443. package/templates/github-actions/reviewed-release.yml +80 -0
  444. package/templates/multi-target-homebrew/README.md +10 -0
  445. package/templates/multi-target-homebrew/release.config.json +43 -60
  446. package/templates/multi-target-scoop/README.md +10 -0
  447. package/templates/multi-target-scoop/release.config.json +43 -62
  448. package/templates/npm-github/release.config.json +25 -38
  449. package/templates/npm-github/reviewed-release.config.json +37 -0
  450. package/templates/npm-only/README.md +10 -0
  451. package/templates/npm-only/release.config.json +15 -30
  452. package/templates/portable-cli/README.md +13 -0
  453. package/templates/portable-cli/release.config.json +53 -0
  454. package/dist/config/errors.d.ts +0 -24
  455. package/dist/config/errors.d.ts.map +0 -1
  456. package/dist/config/errors.js +0 -19
  457. package/dist/config/errors.js.map +0 -1
  458. package/dist/config/load.d.ts +0 -9
  459. package/dist/config/load.d.ts.map +0 -1
  460. package/dist/config/load.js +0 -29
  461. package/dist/config/load.js.map +0 -1
  462. package/dist/config/schema.d.ts +0 -12
  463. package/dist/config/schema.d.ts.map +0 -1
  464. package/dist/config/schema.js +0 -19
  465. package/dist/config/schema.js.map +0 -1
  466. package/dist/domain/artifact.d.ts +0 -36
  467. package/dist/domain/artifact.d.ts.map +0 -1
  468. package/dist/domain/artifact.js +0 -29
  469. package/dist/domain/artifact.js.map +0 -1
  470. package/dist/domain/evidence.d.ts +0 -108
  471. package/dist/domain/evidence.d.ts.map +0 -1
  472. package/dist/domain/evidence.js +0 -96
  473. package/dist/domain/evidence.js.map +0 -1
  474. package/dist/domain/operation.d.ts +0 -153
  475. package/dist/domain/operation.d.ts.map +0 -1
  476. package/dist/domain/operation.js +0 -320
  477. package/dist/domain/operation.js.map +0 -1
  478. package/dist/domain/release.d.ts +0 -141
  479. package/dist/domain/release.d.ts.map +0 -1
  480. package/dist/domain/release.js +0 -127
  481. package/dist/domain/release.js.map +0 -1
  482. package/dist/domain/remote-state.d.ts +0 -85
  483. package/dist/domain/remote-state.d.ts.map +0 -1
  484. package/dist/domain/remote-state.js +0 -77
  485. package/dist/domain/remote-state.js.map +0 -1
  486. package/dist/domain/status.d.ts +0 -43
  487. package/dist/domain/status.d.ts.map +0 -1
  488. package/dist/domain/status.js +0 -51
  489. package/dist/domain/status.js.map +0 -1
  490. package/dist/domain/target.d.ts +0 -135
  491. package/dist/domain/target.d.ts.map +0 -1
  492. package/dist/domain/target.js +0 -137
  493. package/dist/domain/target.js.map +0 -1
  494. package/dist/host/host.d.ts +0 -32
  495. package/dist/host/host.d.ts.map +0 -1
  496. package/dist/host/host.js +0 -24
  497. package/dist/host/host.js.map +0 -1
  498. package/dist/host/http-live.d.ts +0 -6
  499. package/dist/host/http-live.d.ts.map +0 -1
  500. package/dist/host/http-live.js +0 -86
  501. package/dist/host/http-live.js.map +0 -1
  502. package/dist/host/http.d.ts +0 -43
  503. package/dist/host/http.d.ts.map +0 -1
  504. package/dist/host/http.js +0 -59
  505. package/dist/host/http.js.map +0 -1
  506. package/dist/host/platform.d.ts +0 -10
  507. package/dist/host/platform.d.ts.map +0 -1
  508. package/dist/host/platform.js +0 -114
  509. package/dist/host/platform.js.map +0 -1
  510. package/dist/host/test.d.ts +0 -23
  511. package/dist/host/test.d.ts.map +0 -1
  512. package/dist/host/test.js +0 -222
  513. package/dist/host/test.js.map +0 -1
  514. package/dist/internal/workflow-phases.d.ts +0 -3
  515. package/dist/internal/workflow-phases.d.ts.map +0 -1
  516. package/dist/internal/workflow-phases.js +0 -2
  517. package/dist/internal/workflow-phases.js.map +0 -1
  518. package/dist/internal/workspace-path.d.ts +0 -15
  519. package/dist/internal/workspace-path.d.ts.map +0 -1
  520. package/dist/internal/workspace-path.js +0 -36
  521. package/dist/internal/workspace-path.js.map +0 -1
  522. package/dist/planner/artifact-inventory.d.ts +0 -9
  523. package/dist/planner/artifact-inventory.d.ts.map +0 -1
  524. package/dist/planner/artifact-inventory.js +0 -84
  525. package/dist/planner/artifact-inventory.js.map +0 -1
  526. package/dist/planner/create-release-plan.d.ts +0 -5
  527. package/dist/planner/create-release-plan.d.ts.map +0 -1
  528. package/dist/planner/create-release-plan.js +0 -25
  529. package/dist/planner/create-release-plan.js.map +0 -1
  530. package/dist/planner/errors.d.ts +0 -81
  531. package/dist/planner/errors.d.ts.map +0 -1
  532. package/dist/planner/errors.js +0 -70
  533. package/dist/planner/errors.js.map +0 -1
  534. package/dist/planner/evidence-recorder.d.ts +0 -26
  535. package/dist/planner/evidence-recorder.d.ts.map +0 -1
  536. package/dist/planner/evidence-recorder.js +0 -330
  537. package/dist/planner/evidence-recorder.js.map +0 -1
  538. package/dist/planner/executor.d.ts +0 -58
  539. package/dist/planner/executor.d.ts.map +0 -1
  540. package/dist/planner/executor.js +0 -159
  541. package/dist/planner/executor.js.map +0 -1
  542. package/dist/planner/normalize-release.d.ts +0 -16
  543. package/dist/planner/normalize-release.d.ts.map +0 -1
  544. package/dist/planner/normalize-release.js +0 -218
  545. package/dist/planner/normalize-release.js.map +0 -1
  546. package/dist/planner/reconcile.d.ts +0 -17
  547. package/dist/planner/reconcile.d.ts.map +0 -1
  548. package/dist/planner/reconcile.js +0 -261
  549. package/dist/planner/reconcile.js.map +0 -1
  550. package/dist/planner/release-eligibility.d.ts +0 -39
  551. package/dist/planner/release-eligibility.d.ts.map +0 -1
  552. package/dist/planner/release-eligibility.js +0 -578
  553. package/dist/planner/release-eligibility.js.map +0 -1
  554. package/dist/planner/render-plan.d.ts +0 -15
  555. package/dist/planner/render-plan.d.ts.map +0 -1
  556. package/dist/planner/render-plan.js +0 -238
  557. package/dist/planner/render-plan.js.map +0 -1
  558. package/dist/planner/status.d.ts +0 -40
  559. package/dist/planner/status.d.ts.map +0 -1
  560. package/dist/planner/status.js +0 -313
  561. package/dist/planner/status.js.map +0 -1
  562. package/dist/targets/adapter-helpers.d.ts +0 -64
  563. package/dist/targets/adapter-helpers.d.ts.map +0 -1
  564. package/dist/targets/adapter-helpers.js +0 -124
  565. package/dist/targets/adapter-helpers.js.map +0 -1
  566. package/dist/targets/adapter.d.ts +0 -17
  567. package/dist/targets/adapter.d.ts.map +0 -1
  568. package/dist/targets/adapter.js +0 -2
  569. package/dist/targets/adapter.js.map +0 -1
  570. package/dist/targets/github-release.d.ts +0 -25
  571. package/dist/targets/github-release.d.ts.map +0 -1
  572. package/dist/targets/github-release.js +0 -82
  573. package/dist/targets/github-release.js.map +0 -1
  574. package/dist/targets/github.d.ts +0 -11
  575. package/dist/targets/github.d.ts.map +0 -1
  576. package/dist/targets/github.js +0 -125
  577. package/dist/targets/github.js.map +0 -1
  578. package/dist/targets/homebrew.d.ts +0 -11
  579. package/dist/targets/homebrew.d.ts.map +0 -1
  580. package/dist/targets/homebrew.js +0 -97
  581. package/dist/targets/homebrew.js.map +0 -1
  582. package/dist/targets/live.d.ts +0 -5
  583. package/dist/targets/live.d.ts.map +0 -1
  584. package/dist/targets/live.js +0 -50
  585. package/dist/targets/live.js.map +0 -1
  586. package/dist/targets/npm.d.ts +0 -10
  587. package/dist/targets/npm.d.ts.map +0 -1
  588. package/dist/targets/npm.js +0 -118
  589. package/dist/targets/npm.js.map +0 -1
  590. package/dist/targets/pypi.d.ts +0 -11
  591. package/dist/targets/pypi.d.ts.map +0 -1
  592. package/dist/targets/pypi.js +0 -103
  593. package/dist/targets/pypi.js.map +0 -1
  594. package/dist/targets/registry.d.ts +0 -25
  595. package/dist/targets/registry.d.ts.map +0 -1
  596. package/dist/targets/registry.js +0 -34
  597. package/dist/targets/registry.js.map +0 -1
  598. package/dist/targets/scoop.d.ts +0 -11
  599. package/dist/targets/scoop.d.ts.map +0 -1
  600. package/dist/targets/scoop.js +0 -78
  601. package/dist/targets/scoop.js.map +0 -1
  602. package/dist/types/effect-internal.d.ts +0 -5
  603. package/dist/types/effect-internal.d.ts.map +0 -1
  604. package/dist/types/effect-internal.js +0 -2
  605. package/dist/types/effect-internal.js.map +0 -1
  606. package/dist/workflows/config.d.ts +0 -252
  607. package/dist/workflows/config.d.ts.map +0 -1
  608. package/dist/workflows/config.js +0 -465
  609. package/dist/workflows/config.js.map +0 -1
  610. package/dist/workflows/diagnostics.d.ts +0 -62
  611. package/dist/workflows/diagnostics.d.ts.map +0 -1
  612. package/dist/workflows/diagnostics.js +0 -527
  613. package/dist/workflows/diagnostics.js.map +0 -1
  614. package/dist/workflows/evidence.d.ts +0 -26
  615. package/dist/workflows/evidence.d.ts.map +0 -1
  616. package/dist/workflows/evidence.js +0 -44
  617. package/dist/workflows/evidence.js.map +0 -1
  618. package/dist/workflows/index.d.ts +0 -7
  619. package/dist/workflows/index.d.ts.map +0 -1
  620. package/dist/workflows/index.js +0 -6
  621. package/dist/workflows/index.js.map +0 -1
  622. package/dist/workflows/init.d.ts +0 -84
  623. package/dist/workflows/init.d.ts.map +0 -1
  624. package/dist/workflows/init.js +0 -441
  625. package/dist/workflows/init.js.map +0 -1
  626. package/dist/workflows/live.d.ts +0 -9
  627. package/dist/workflows/live.d.ts.map +0 -1
  628. package/dist/workflows/live.js +0 -7
  629. package/dist/workflows/live.js.map +0 -1
  630. package/dist/workflows/options.d.ts +0 -30
  631. package/dist/workflows/options.d.ts.map +0 -1
  632. package/dist/workflows/options.js +0 -16
  633. package/dist/workflows/options.js.map +0 -1
  634. package/examples/non-strict-skips/artifacts/release-example-skips-0.1.0.tgz +0 -1
  635. package/examples/non-strict-skips/release.config.json +0 -31
  636. package/examples/pypi-registry/release.config.json +0 -31
  637. package/templates/github-actions/plan-and-approved-execute.yml +0 -58
  638. package/templates/github-actions/plan-only.yml +0 -33
  639. package/templates/github-actions/trusted-publishing.yml +0 -61
@@ -0,0 +1,1116 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schema from "effect/Schema";
3
+ import { createHash } from "node:crypto";
4
+ import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, rmSync } from "node:fs";
5
+ import { basename, isAbsolute, join, relative, resolve, sep } from "node:path";
6
+ import { tmpdir } from "node:os";
7
+ import { tarGz, zip } from "../drivers/archive.js";
8
+ import { secureRead, secureWrite } from "../drivers/workspace.js";
9
+ import { encodeCanonicalJson } from "../model/canonical.js";
10
+ import { ArtifactCollectionMember, cardinalityAccepts, collectionMemberBytesIssue, collectionMemberId, collectionMemberPath, normalizeCollectionMemberKey } from "../model/artifact-collection.js";
11
+ import { sha256Digest } from "../model/digest.js";
12
+ import { CatalogManagedState, PreparedCatalogDownload, PreparedCatalogRenderer, encodeCatalogManagedState, renderCatalog } from "../model/catalog.js";
13
+ import { inspectPythonDistribution } from "../model/python-distribution.js";
14
+ import { NonEmptyName, OutputId, SafeRelativePath, Version, WorkspaceRoot } from "../model/primitives.js";
15
+ import { ExplicitInputSnapshot, VerifiedReleaseContext } from "./context.js";
16
+ import { OutputDeclaration, ReleaseGraph } from "./graph.js";
17
+ import { PreparedArtifact, PreparedArtifactCollection, PreparedCatalogPublication, PreparedExecutionInputs, PreparedGitHubPublication, PreparedNpmPublication, PreparedPyPiFile, PreparedPyPiPublication, PreparedProject, PreparedProvenance, PreparedReleaseV2, PreparedSource } from "./prepared.js";
18
+ import { CompletePreparedReleaseRef } from "./prepared-ref.js";
19
+ import { PreparedCommitHandoffError, PreparedStoreError } from "./prepared-store.js";
20
+ import { assertSnapshotPresent, materializeExplicitInput, preparationBasisDigest, selectStagingSnapshot, snapshotDifference, snapshotStaging, snapshotsEqual } from "./staging.js";
21
+ export class PreparationError extends Schema.TaggedErrorClass()("PreparationError", {
22
+ reason: Schema.String,
23
+ prepared: Schema.optionalKey(CompletePreparedReleaseRef)
24
+ }) {
25
+ }
26
+ const failure = (cause) => PreparationError.make({
27
+ reason: cause instanceof PreparedCommitHandoffError
28
+ ? cause.reason
29
+ : cause instanceof Error
30
+ ? cause.message
31
+ : String(cause),
32
+ ...(cause instanceof PreparedCommitHandoffError ? { prepared: cause.prepared } : {})
33
+ });
34
+ const attempt = (body) => Effect.try({
35
+ try: body,
36
+ catch: failure
37
+ });
38
+ const bunCompileTargets = new Set([
39
+ "bun-linux-x64",
40
+ "bun-linux-arm64",
41
+ "bun-darwin-x64",
42
+ "bun-darwin-arm64"
43
+ ]);
44
+ const expectedBunCompileTarget = (argv) => (argv.length === 8 || argv.length === 9) && argv[0] === "bun" && argv[1] === "build" &&
45
+ argv[2]?.startsWith("-") === false && argv[3] === "--compile" && argv[4] === "--target" &&
46
+ argv[6] === "--outfile" && argv[7]?.startsWith("-") === false &&
47
+ (argv.length === 8 || argv[8] === "--minify") && bunCompileTargets.has(argv[5])
48
+ ? argv[5]
49
+ : undefined;
50
+ const assertBunCompileRuntime = (argv, outcome) => {
51
+ const expected = expectedBunCompileTarget(argv);
52
+ const runtime = outcome.bunCompileRuntime;
53
+ if (expected === undefined) {
54
+ if (runtime !== undefined)
55
+ throw new Error("A non-certified command reported a Bun compile runtime identity.");
56
+ return;
57
+ }
58
+ if (runtime === undefined || runtime.target !== expected || !/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/u.test(runtime.bunVersion) ||
59
+ !/^[a-f0-9]{64}$/u.test(runtime.sha256)) {
60
+ throw new Error(`Certified Bun compile target ${expected} did not report its exact runtime identity.`);
61
+ }
62
+ if (expected === "bun-linux-x64") {
63
+ if (runtime.source !== "executing-bun" || runtime.cacheFile !== "executing-bun" ||
64
+ outcome.tool?.protocol !== "ts-release-executable/v1" || outcome.tool.sha256 !== runtime.sha256) {
65
+ throw new Error("Certified Linux x64 compilation did not bind the executing Bun bytes.");
66
+ }
67
+ return;
68
+ }
69
+ const platform = expected.slice(4).replace("arm64", "aarch64");
70
+ if (runtime.source !== "host-cache-private-copy" || runtime.cacheFile !== `bun-${platform}-v${runtime.bunVersion}`) {
71
+ throw new Error(`Certified Bun compile target ${expected} did not bind its canonical private cache file.`);
72
+ }
73
+ };
74
+ const materializeBunDependencies = Effect.fn("materializeBunDependencies")(function* (input) {
75
+ const requiresBun = input.request.graph.preparations.some((preparation) => (preparation._tag === "GraphCommandCheck" || preparation._tag === "GraphCommandArtifact" ||
76
+ preparation._tag === "GraphCommandCollection" || preparation._tag === "GraphNpmPackageBuild") &&
77
+ preparation.argv[0] === "bun");
78
+ if (!requiresBun)
79
+ return undefined;
80
+ const lockfiles = input.sourceSnapshot.entries.filter((entry) => (entry.path.toString() === "bun.lock" || entry.path.toString() === "bun.lockb") &&
81
+ (entry.kind === "file" || entry.kind === "executable"));
82
+ if (lockfiles.length !== 1) {
83
+ return yield* new PreparationError({
84
+ reason: "Bun preparation requires exactly one tracked root bun.lock or bun.lockb for isolated dependency materialization."
85
+ });
86
+ }
87
+ if (input.sourceSnapshot.entries.some((entry) => entry.path.toString().split("/").includes("node_modules"))) {
88
+ return yield* new PreparationError({ reason: "Verified Git source must not contain a tracked node_modules tree." });
89
+ }
90
+ const stageRoot = input.request.context.workspace.toString();
91
+ const dependencyPath = SafeRelativePath.make("node_modules");
92
+ const stageDependencies = join(stageRoot, dependencyPath);
93
+ if (existsSync(stageDependencies)) {
94
+ return yield* new PreparationError({ reason: "Private dependency destination already exists before isolated install." });
95
+ }
96
+ const before = yield* attempt(() => snapshotStaging(stageRoot, { exclude: [dependencyPath] }));
97
+ const versionOutcome = yield* input.request.run({
98
+ argv: ["bun", "--version"],
99
+ cwd: stageRoot,
100
+ environmentNames: [],
101
+ network: "offline-cli"
102
+ }).pipe(Effect.mapError(failure));
103
+ const bunVersion = versionOutcome.stdout.trim();
104
+ if (versionOutcome.exitCode !== 0 || !/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/u.test(bunVersion)) {
105
+ return yield* new PreparationError({
106
+ reason: `Unable to establish the exact Bun dependency materializer version: ${versionOutcome.stderr.trim()}`
107
+ });
108
+ }
109
+ const outcome = yield* input.request.run({
110
+ argv: [
111
+ "bun",
112
+ "install",
113
+ "--offline",
114
+ "--frozen-lockfile",
115
+ "--ignore-scripts",
116
+ "--no-save",
117
+ "--linker=hoisted"
118
+ ],
119
+ cwd: stageRoot,
120
+ environmentNames: [],
121
+ network: "offline-cli"
122
+ }).pipe(Effect.mapError(failure));
123
+ if (outcome.exitCode !== 0) {
124
+ return yield* new PreparationError({
125
+ reason: `Isolated Bun dependency install exited ${outcome.exitCode}: ${outcome.stderr.trim()}`
126
+ });
127
+ }
128
+ if (!existsSync(stageDependencies))
129
+ yield* attempt(() => mkdirSync(stageDependencies, { mode: 0o700 }));
130
+ yield* attempt(() => {
131
+ if (lstatSync(stageDependencies).isSymbolicLink() || !lstatSync(stageDependencies).isDirectory() ||
132
+ !contained(stageRoot, realpathSync(stageDependencies))) {
133
+ throw new Error("Isolated Bun install did not produce a real dependency directory inside private staging.");
134
+ }
135
+ assertNoWorkspaceInodeAliases(stageDependencies, join(input.sourceWorkspace, "node_modules"));
136
+ });
137
+ const wholeStage = yield* attempt(() => snapshotStaging(stageRoot));
138
+ const dependencySnapshot = selectStagingSnapshot(wholeStage, [dependencyPath]);
139
+ const after = yield* attempt(() => snapshotStaging(stageRoot, { exclude: [dependencyPath] }));
140
+ if (!snapshotsEqual(before, after)) {
141
+ return yield* new PreparationError({
142
+ reason: `Isolated Bun install changed source or wrote an undeclared cache: ${snapshotDifference(before, after)}.`
143
+ });
144
+ }
145
+ yield* attempt(() => assertSnapshotPresent(stageRoot, input.sourceSnapshot, "Verified source"));
146
+ const lockfile = lockfiles[0];
147
+ const toolDigest = sha256Digest(new TextEncoder().encode(`bun@${bunVersion}`));
148
+ return {
149
+ bunVersion,
150
+ input: ExplicitInputSnapshot.make({
151
+ id: `isolated-bun-dependencies@${bunVersion}`,
152
+ path: dependencyPath,
153
+ kind: "directory",
154
+ size: dependencySnapshot.entries
155
+ .filter((entry) => entry.kind !== "directory")
156
+ .reduce((sum, entry) => sum + entry.size, 0),
157
+ digest: dependencySnapshot.digest,
158
+ materializer: `bun@${bunVersion}:install--offline--frozen-lockfile--ignore-scripts--no-save--linker=hoisted`,
159
+ materializationBasis: [lockfile.digest, toolDigest]
160
+ })
161
+ };
162
+ });
163
+ const byCodepoint = (left, right) => {
164
+ const a = left.id.toString();
165
+ const b = right.id.toString();
166
+ return a < b ? -1 : a > b ? 1 : 0;
167
+ };
168
+ const pathOf = (context, path) => join(context.workspace, path);
169
+ const contained = (root, path) => {
170
+ const value = relative(root, path);
171
+ return value === "" || (value !== ".." && !value.startsWith(`..${sep}`) && !isAbsolute(value));
172
+ };
173
+ const portablePathsOverlap = (left, right) => {
174
+ const a = left.toLocaleLowerCase("en-US");
175
+ const b = right.toLocaleLowerCase("en-US");
176
+ return a === b || a.startsWith(`${b}/`) || b.startsWith(`${a}/`);
177
+ };
178
+ const inodeKey = (path) => {
179
+ const stat = lstatSync(path, { bigint: true });
180
+ return stat.isFile() ? `${stat.dev}:${stat.ino}` : undefined;
181
+ };
182
+ const fileInodes = (root) => {
183
+ const result = new Set();
184
+ if (!existsSync(root))
185
+ return result;
186
+ const walk = (path) => {
187
+ const stat = lstatSync(path);
188
+ if (stat.isSymbolicLink())
189
+ return;
190
+ const identity = inodeKey(path);
191
+ if (identity !== undefined)
192
+ result.add(identity);
193
+ if (stat.isDirectory())
194
+ for (const entry of readdirSync(path))
195
+ walk(join(path, entry));
196
+ };
197
+ walk(root);
198
+ return result;
199
+ };
200
+ const assertNoWorkspaceInodeAliases = (stageDependencies, workspaceDependencies) => {
201
+ const workspaceInodes = fileInodes(workspaceDependencies);
202
+ if (workspaceInodes.size === 0)
203
+ return;
204
+ const walk = (path) => {
205
+ const stat = lstatSync(path);
206
+ if (stat.isSymbolicLink())
207
+ return;
208
+ const identity = inodeKey(path);
209
+ if (identity !== undefined && workspaceInodes.has(identity)) {
210
+ throw new Error(`Isolated dependency path ${relative(stageDependencies, path) || "."} aliases a workspace inode.`);
211
+ }
212
+ if (stat.isDirectory())
213
+ for (const entry of readdirSync(path))
214
+ walk(join(path, entry));
215
+ };
216
+ walk(stageDependencies);
217
+ };
218
+ const hashBytes = (algorithm, bytes) => createHash(algorithm).update(bytes).digest("hex");
219
+ const stagedContext = (context, root) => VerifiedReleaseContext.make({
220
+ workspace: WorkspaceRoot.make(root),
221
+ source: context.source,
222
+ package: context.package
223
+ });
224
+ const capture = (context, declaration) => attempt(() => {
225
+ if (declaration.kind === "package") {
226
+ throw new Error(`Directory output ${declaration.id} cannot enter a blob store.`);
227
+ }
228
+ return new Uint8Array(secureRead(context.workspace, declaration.path).bytes);
229
+ });
230
+ const replaceReferences = (value, inputs, outputs, collection) => value.replace(/\{(input|output|collection):([^}]+)\}/gu, (_match, direction, id) => {
231
+ if (direction === "collection") {
232
+ if (collection === undefined || collection.id.toString() !== id) {
233
+ throw new Error(`Unresolved command collection reference collection:${id}.`);
234
+ }
235
+ return collection.root.toString();
236
+ }
237
+ const declarations = direction === "input" ? inputs : outputs;
238
+ const declaration = declarations.find((candidate) => candidate.id.toString() === id);
239
+ if (declaration === undefined)
240
+ throw new Error(`Unresolved command path reference ${direction}:${id}.`);
241
+ return declaration.path.toString();
242
+ });
243
+ const assertCommandContract = (stageRoot, preparation, inputs, outputs, sourceSnapshot, explicitInputs) => {
244
+ const cwd = resolve(stageRoot, preparation.cwd.toString());
245
+ if (!contained(stageRoot, cwd) || !existsSync(cwd) || lstatSync(cwd).isSymbolicLink() || !lstatSync(cwd).isDirectory()) {
246
+ throw new Error(`Command ${preparation.id} cwd escapes private staging or is not a real directory.`);
247
+ }
248
+ const collectionRoot = preparation._tag === "GraphCommandCollection"
249
+ ? preparation.collection.root.toString()
250
+ : undefined;
251
+ const roots = [...inputs.map((item) => ["input", item.path.toString()]),
252
+ ...outputs.map((item) => ["output", item.path.toString()]),
253
+ ...(collectionRoot === undefined ? [] : [["collection", collectionRoot]])];
254
+ for (const [kind, path] of roots) {
255
+ const resolved = resolve(stageRoot, path);
256
+ if (!contained(stageRoot, resolved))
257
+ throw new Error(`Command ${preparation.id} ${kind} root ${path} escapes private staging.`);
258
+ }
259
+ const writablePaths = [...outputs.map((output) => output.path.toString()),
260
+ ...(collectionRoot === undefined ? [] : [collectionRoot])];
261
+ for (const outputPath of writablePaths) {
262
+ const sourceOverlap = sourceSnapshot.entries.find((entry) => portablePathsOverlap(entry.path.toString(), outputPath));
263
+ if (sourceOverlap !== undefined) {
264
+ throw new Error(`Command ${preparation.id} writable root ${outputPath} overlaps verified source ${sourceOverlap.path}.`);
265
+ }
266
+ const explicitOverlap = explicitInputs.find((input) => portablePathsOverlap(input.path.toString(), outputPath));
267
+ if (explicitOverlap !== undefined) {
268
+ throw new Error(`Command ${preparation.id} writable root ${outputPath} overlaps explicit input ${explicitOverlap.id}.`);
269
+ }
270
+ for (const input of inputs) {
271
+ const a = outputPath;
272
+ const b = input.path.toString();
273
+ if (portablePathsOverlap(a, b)) {
274
+ throw new Error(`Command ${preparation.id} writable root ${a} overlaps read-only input ${b}.`);
275
+ }
276
+ }
277
+ }
278
+ for (let index = 0; index < writablePaths.length; index += 1) {
279
+ for (const other of writablePaths.slice(index + 1)) {
280
+ const a = writablePaths[index];
281
+ const b = other;
282
+ if (portablePathsOverlap(a, b)) {
283
+ throw new Error(`Command ${preparation.id} has ambiguous overlapping outputs ${a} and ${b}.`);
284
+ }
285
+ }
286
+ }
287
+ if (collectionRoot !== undefined && existsSync(resolve(stageRoot, collectionRoot))) {
288
+ throw new Error(`Command ${preparation.id} collection root ${collectionRoot} must not exist before its producer runs.`);
289
+ }
290
+ };
291
+ const assertRealDirectoryTree = (stageRoot, root) => {
292
+ const location = resolve(stageRoot, root.toString());
293
+ if (!contained(stageRoot, location) || !existsSync(location) || lstatSync(location).isSymbolicLink() ||
294
+ !lstatSync(location).isDirectory() || !contained(stageRoot, realpathSync(location))) {
295
+ throw new Error(`npm package build output root ${root} is missing, linked, or outside private staging.`);
296
+ }
297
+ const walk = (directory) => {
298
+ for (const name of readdirSync(directory)) {
299
+ const path = join(directory, name);
300
+ const stat = lstatSync(path);
301
+ if (stat.isSymbolicLink())
302
+ throw new Error(`npm package build output ${relative(stageRoot, path)} is a forbidden symlink.`);
303
+ if (!contained(stageRoot, realpathSync(path)))
304
+ throw new Error(`npm package build output ${relative(stageRoot, path)} escapes private staging.`);
305
+ if (stat.isDirectory())
306
+ walk(path);
307
+ else if (!stat.isFile())
308
+ throw new Error(`npm package build output ${relative(stageRoot, path)} has an unsupported filesystem kind.`);
309
+ }
310
+ };
311
+ walk(location);
312
+ };
313
+ const runNpmPackageBuild = (request, preparation, sourceSnapshot, explicitInputs) => {
314
+ const stageRoot = request.context.workspace.toString();
315
+ const writable = preparation.outputRoots;
316
+ const cleanup = () => {
317
+ for (const root of writable)
318
+ rmSync(resolve(stageRoot, root.toString()), { recursive: true, force: true });
319
+ };
320
+ return Effect.gen(function* () {
321
+ const cwd = resolve(stageRoot, preparation.cwd.toString());
322
+ if (!contained(stageRoot, cwd) || !existsSync(cwd) || lstatSync(cwd).isSymbolicLink() || !lstatSync(cwd).isDirectory()) {
323
+ return yield* new PreparationError({ reason: "npm package build cwd is not a real directory inside private staging." });
324
+ }
325
+ yield* attempt(() => {
326
+ for (const root of writable) {
327
+ if (sourceSnapshot.entries.some((entry) => portablePathsOverlap(entry.path.toString(), root.toString()))) {
328
+ throw new Error(`npm package build output root ${root} overlaps verified source.`);
329
+ }
330
+ if (explicitInputs.some((input) => portablePathsOverlap(input.path.toString(), root.toString()))) {
331
+ throw new Error(`npm package build output root ${root} overlaps explicit input.`);
332
+ }
333
+ if (existsSync(resolve(stageRoot, root.toString()))) {
334
+ throw new Error(`npm package build output root ${root} must be initially absent.`);
335
+ }
336
+ }
337
+ assertSnapshotPresent(stageRoot, sourceSnapshot, "Verified source", { exclude: writable });
338
+ });
339
+ const before = yield* attempt(() => snapshotStaging(stageRoot, { exclude: writable }));
340
+ const outcome = yield* request.run({
341
+ argv: preparation.argv,
342
+ cwd,
343
+ environmentNames: [],
344
+ network: "deny"
345
+ }).pipe(Effect.mapError(failure));
346
+ if (outcome.exitCode !== 0) {
347
+ return yield* new PreparationError({
348
+ reason: `npm package build exited ${outcome.exitCode}: ${outcome.stderr.trim()}`
349
+ });
350
+ }
351
+ yield* attempt(() => assertBunCompileRuntime(preparation.argv, outcome));
352
+ const after = yield* attempt(() => snapshotStaging(stageRoot, { exclude: writable }));
353
+ if (!snapshotsEqual(before, after)) {
354
+ return yield* new PreparationError({
355
+ reason: `npm package build changed undeclared staged paths: ${snapshotDifference(before, after)}.`
356
+ });
357
+ }
358
+ yield* attempt(() => {
359
+ for (const root of writable)
360
+ assertRealDirectoryTree(stageRoot, root);
361
+ assertSnapshotPresent(stageRoot, sourceSnapshot, "Verified source", { exclude: writable });
362
+ });
363
+ return {
364
+ outputs: [], declarations: [],
365
+ ...(outcome.networkIsolation === undefined ? {} : { networkIsolation: outcome.networkIsolation }),
366
+ ...(outcome.bunCompileRuntime === undefined ? {} : { bunCompileRuntime: outcome.bunCompileRuntime })
367
+ };
368
+ }).pipe(Effect.onError(() => Effect.sync(cleanup)));
369
+ };
370
+ const discoverCollection = (context, contract) => {
371
+ const stageRoot = context.workspace.toString();
372
+ const root = resolve(stageRoot, contract.root.toString());
373
+ if (!contained(stageRoot, root) || !existsSync(root) || lstatSync(root).isSymbolicLink() ||
374
+ !lstatSync(root).isDirectory() || !contained(stageRoot, realpathSync(root))) {
375
+ throw new Error(`Artifact collection ${contract.id} root ${contract.root} is missing, linked, or outside private staging.`);
376
+ }
377
+ const rows = [];
378
+ const foldedKeys = new Map();
379
+ const ids = new Set();
380
+ const walk = (directory, prefix) => {
381
+ for (const entry of readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0)) {
382
+ const rawKey = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
383
+ const key = normalizeCollectionMemberKey(rawKey);
384
+ const folded = key.toString().toLocaleLowerCase("en-US");
385
+ const previous = foldedKeys.get(folded);
386
+ if (previous !== undefined) {
387
+ throw new Error(`Artifact collection ${contract.id} paths ${previous} and ${key} collide under portable case folding.`);
388
+ }
389
+ foldedKeys.set(folded, key.toString());
390
+ const location = join(directory, entry.name);
391
+ const stat = lstatSync(location);
392
+ if (stat.isSymbolicLink()) {
393
+ throw new Error(`Artifact collection ${contract.id} member ${key} is a forbidden symlink.`);
394
+ }
395
+ if (!contained(stageRoot, realpathSync(location))) {
396
+ throw new Error(`Artifact collection ${contract.id} member ${key} escapes private staging.`);
397
+ }
398
+ if (stat.isDirectory()) {
399
+ walk(location, key.toString());
400
+ continue;
401
+ }
402
+ if (!stat.isFile()) {
403
+ throw new Error(`Artifact collection ${contract.id} member ${key} has an unsupported filesystem kind.`);
404
+ }
405
+ if (!key.toString().endsWith(contract.pathSuffix.toString())) {
406
+ throw new Error(`Artifact collection ${contract.id} member ${key} does not match declared pathSuffix ${contract.pathSuffix}.`);
407
+ }
408
+ const executable = (stat.mode & 0o111) !== 0;
409
+ if ((contract.artifactKind === "executable") !== executable) {
410
+ throw new Error(`Artifact collection ${contract.id} member ${key} does not match declared kind ${contract.artifactKind}.`);
411
+ }
412
+ const artifactId = collectionMemberId(contract, key);
413
+ if (ids.has(artifactId.toString())) {
414
+ throw new Error(`Artifact collection ${contract.id} repeats stable artifact id ${artifactId}.`);
415
+ }
416
+ ids.add(artifactId.toString());
417
+ const declaration = OutputDeclaration.make({
418
+ id: artifactId,
419
+ path: collectionMemberPath(contract, key),
420
+ kind: contract.artifactKind,
421
+ mediaType: contract.mediaType
422
+ });
423
+ const bytes = new Uint8Array(secureRead(stageRoot, declaration.path).bytes);
424
+ const bytesIssue = collectionMemberBytesIssue(contract, bytes);
425
+ if (bytesIssue !== undefined) {
426
+ throw new Error(`Artifact collection ${contract.id} member ${key}: ${bytesIssue}.`);
427
+ }
428
+ rows.push({ key, declaration, bytes });
429
+ }
430
+ };
431
+ walk(root, "");
432
+ rows.sort((left, right) => left.key < right.key ? -1 : left.key > right.key ? 1 : 0);
433
+ if (!cardinalityAccepts(contract.cardinality, rows.length)) {
434
+ throw new Error(`Artifact collection ${contract.id} discovered ${rows.length} members outside its declared cardinality.`);
435
+ }
436
+ return {
437
+ outputs: rows.map((row) => [row.declaration.id.toString(), row.bytes]),
438
+ declarations: rows.map((row) => row.declaration),
439
+ collection: PreparedArtifactCollection.make({
440
+ contract,
441
+ members: rows.map((row) => ArtifactCollectionMember.make({
442
+ key: row.key,
443
+ artifactId: row.declaration.id
444
+ }))
445
+ })
446
+ };
447
+ };
448
+ const runCommand = (request, preparation, declarations, sourceSnapshot, explicitInputs) => Effect.gen(function* () {
449
+ const inputs = preparation.inputs.map((id) => declarations.get(id.toString()) ?? (() => {
450
+ throw new Error(`Missing input ${id}.`);
451
+ })());
452
+ const outputs = preparation._tag === "GraphCommandArtifact" ? preparation.outputs : [];
453
+ const collection = preparation._tag === "GraphCommandCollection" ? preparation.collection : undefined;
454
+ yield* attempt(() => assertCommandContract(request.context.workspace, preparation, inputs, outputs, sourceSnapshot, explicitInputs));
455
+ const writable = [...outputs.map((output) => output.path),
456
+ ...(collection === undefined ? [] : [collection.root])];
457
+ // Every verified source and explicit-input byte remains immutable unless it
458
+ // is beneath a declared output root. Checks have no persistent writable root.
459
+ yield* attempt(() => {
460
+ assertSnapshotPresent(request.context.workspace, sourceSnapshot, "Verified source", { exclude: writable });
461
+ for (const input of explicitInputs) {
462
+ const location = join(request.context.workspace, input.path.toString());
463
+ if (!existsSync(location) || lstatSync(location).isSymbolicLink()) {
464
+ throw new Error(`Explicit input ${input.id} is missing or no longer private.`);
465
+ }
466
+ }
467
+ });
468
+ const before = yield* attempt(() => snapshotStaging(request.context.workspace, { exclude: writable }));
469
+ const argv = preparation.argv.map((part) => replaceReferences(part, inputs, outputs, collection));
470
+ const outcome = yield* request.run({
471
+ argv,
472
+ cwd: pathOf(request.context, preparation.cwd),
473
+ environmentNames: [],
474
+ network: "deny"
475
+ }).pipe(Effect.mapError(failure));
476
+ if (outcome.exitCode !== 0) {
477
+ return yield* new PreparationError({
478
+ reason: `Command ${preparation.id} exited ${outcome.exitCode}: ${outcome.stderr.trim()}`
479
+ });
480
+ }
481
+ yield* attempt(() => assertBunCompileRuntime(argv, outcome));
482
+ const after = yield* attempt(() => snapshotStaging(request.context.workspace, { exclude: writable }));
483
+ if (!snapshotsEqual(before, after)) {
484
+ return yield* new PreparationError({
485
+ reason: `Command ${preparation.id} changed undeclared staged paths: ${snapshotDifference(before, after)}. ` +
486
+ "Declare persistent bytes as command outputs; caches and scratch must not live in the staged source tree."
487
+ });
488
+ }
489
+ yield* attempt(() => assertSnapshotPresent(request.context.workspace, sourceSnapshot, "Verified source", { exclude: writable }));
490
+ if (preparation._tag === "GraphCommandCheck")
491
+ return {
492
+ outputs: [], declarations: [],
493
+ ...(outcome.networkIsolation === undefined ? {} : { networkIsolation: outcome.networkIsolation }),
494
+ ...(outcome.bunCompileRuntime === undefined ? {} : { bunCompileRuntime: outcome.bunCompileRuntime })
495
+ };
496
+ if (preparation._tag === "GraphCommandCollection") {
497
+ const discovered = yield* attempt(() => discoverCollection(request.context, preparation.collection));
498
+ return {
499
+ ...discovered,
500
+ ...(outcome.networkIsolation === undefined ? {} : { networkIsolation: outcome.networkIsolation }),
501
+ ...(outcome.bunCompileRuntime === undefined ? {} : { bunCompileRuntime: outcome.bunCompileRuntime })
502
+ };
503
+ }
504
+ const produced = [];
505
+ for (const output of outputs) {
506
+ produced.push([output.id.toString(), yield* capture(request.context, output)]);
507
+ }
508
+ return {
509
+ outputs: produced, declarations: [],
510
+ ...(outcome.networkIsolation === undefined ? {} : { networkIsolation: outcome.networkIsolation }),
511
+ ...(outcome.bunCompileRuntime === undefined ? {} : { bunCompileRuntime: outcome.bunCompileRuntime })
512
+ };
513
+ });
514
+ const structured = (request, preparation, declarations, bytes, sourceSnapshot, explicitInputs) => {
515
+ switch (preparation._tag) {
516
+ case "GraphCommandCheck":
517
+ case "GraphCommandArtifact":
518
+ case "GraphCommandCollection":
519
+ return runCommand(request, preparation, declarations, sourceSnapshot, explicitInputs);
520
+ case "GraphNpmPackageBuild":
521
+ return runNpmPackageBuild(request, preparation, sourceSnapshot, explicitInputs);
522
+ case "GraphArchive":
523
+ return attempt(() => {
524
+ assertSnapshotPresent(request.context.workspace, sourceSnapshot, "Verified source");
525
+ const entries = preparation.inputs.map((id) => {
526
+ const declaration = declarations.get(id.toString());
527
+ const value = bytes.get(id.toString());
528
+ if (declaration === undefined || value === undefined) {
529
+ throw new Error(`Archive ${preparation.id} references unavailable artifact ${id}.`);
530
+ }
531
+ return {
532
+ path: basename(declaration.path),
533
+ data: value,
534
+ mode: declaration.kind === "executable" ? 0o100755 : 0o100644
535
+ };
536
+ }).sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0);
537
+ if (entries.length === 0)
538
+ throw new Error(`Archive ${preparation.id} has no inputs.`);
539
+ if (new Set(entries.map((entry) => entry.path)).size !== entries.length) {
540
+ throw new Error(`Archive ${preparation.id} contains duplicate normalized member names.`);
541
+ }
542
+ const value = preparation.format === "zip" ? zip(entries) : tarGz(entries);
543
+ secureWrite(request.context.workspace, preparation.output.path, value);
544
+ assertSnapshotPresent(request.context.workspace, sourceSnapshot, "Verified source");
545
+ return { outputs: [[preparation.output.id.toString(), value]], declarations: [] };
546
+ });
547
+ case "GraphChecksum":
548
+ return attempt(() => {
549
+ assertSnapshotPresent(request.context.workspace, sourceSnapshot, "Verified source");
550
+ const lines = preparation.inputs.map((id) => {
551
+ const value = bytes.get(id.toString());
552
+ const declaration = declarations.get(id.toString());
553
+ if (value === undefined || declaration === undefined) {
554
+ throw new Error(`Checksum ${preparation.id} references unavailable artifact ${id}.`);
555
+ }
556
+ return `${hashBytes(preparation.algorithm, value)} ${basename(declaration.path)}`;
557
+ });
558
+ const value = new TextEncoder().encode(`${lines.join("\n")}\n`);
559
+ secureWrite(request.context.workspace, preparation.output.path, value);
560
+ assertSnapshotPresent(request.context.workspace, sourceSnapshot, "Verified source");
561
+ return { outputs: [[preparation.output.id.toString(), value]], declarations: [] };
562
+ });
563
+ case "GraphCatalogRender":
564
+ return attempt(() => {
565
+ assertSnapshotPresent(request.context.workspace, sourceSnapshot, "Verified source");
566
+ const downloads = preparation.sources.map((source) => {
567
+ const value = bytes.get(source.artifactId.toString());
568
+ const declaration = declarations.get(source.artifactId.toString());
569
+ if (value === undefined || declaration === undefined || basename(declaration.path) !== source.filename.toString()) {
570
+ throw new Error(`Catalog renderer ${preparation.id} references unavailable or renamed artifact ${source.artifactId}.`);
571
+ }
572
+ return PreparedCatalogDownload.make({
573
+ architecture: source.architecture,
574
+ url: source.url,
575
+ filename: source.filename,
576
+ sha256: sha256Digest(value)
577
+ });
578
+ });
579
+ const value = renderCatalog(preparation.version, preparation.renderer, downloads);
580
+ secureWrite(request.context.workspace, preparation.output.path, value);
581
+ assertSnapshotPresent(request.context.workspace, sourceSnapshot, "Verified source");
582
+ return { outputs: [[preparation.output.id.toString(), value]], declarations: [] };
583
+ });
584
+ }
585
+ };
586
+ const assertNpmLiteralSelectionsPresent = (packageRoot) => {
587
+ const manifestPath = join(packageRoot, "package.json");
588
+ const parsed = JSON.parse(readFileSync(manifestPath, "utf8"));
589
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
590
+ throw new Error("npm package manifest root must be an object.");
591
+ }
592
+ const files = parsed.files;
593
+ if (files === undefined)
594
+ return;
595
+ if (!Array.isArray(files) || files.some((entry) => typeof entry !== "string")) {
596
+ throw new Error("npm package files must be an array of strings.");
597
+ }
598
+ for (const entry of files) {
599
+ const normalized = entry.replace(/^\.\//u, "").replace(/\/$/u, "");
600
+ // Glob and exclusion semantics are certified by npm's reported file list;
601
+ // exact selections must already exist in private staging.
602
+ if (normalized.startsWith("!") || /[*?\[\]{}]/u.test(normalized))
603
+ continue;
604
+ const safe = SafeRelativePath.make(normalized);
605
+ const selected = resolve(packageRoot, safe.toString());
606
+ if (!contained(packageRoot, selected) || !existsSync(selected) || lstatSync(selected).isSymbolicLink()) {
607
+ throw new Error(`npm literal package selection ${entry} is absent from verified staging; declare non-Git bytes as an explicit input.`);
608
+ }
609
+ }
610
+ };
611
+ const decodeNpmPackFiles = (stdout) => {
612
+ let value;
613
+ try {
614
+ value = JSON.parse(stdout);
615
+ }
616
+ catch {
617
+ throw new Error("npm pack --json did not return valid JSON.");
618
+ }
619
+ if (!Array.isArray(value) || value.length !== 1 || typeof value[0] !== "object" || value[0] === null) {
620
+ throw new Error("npm pack --json must report exactly one package.");
621
+ }
622
+ const files = value[0].files;
623
+ if (!Array.isArray(files) || files.length === 0)
624
+ throw new Error("npm pack reported no selected package files.");
625
+ const decoded = files.map((file) => {
626
+ if (typeof file !== "object" || file === null)
627
+ throw new Error("npm pack reported a malformed file entry.");
628
+ const item = file;
629
+ if (typeof item.path !== "string" || !SafeRelativePath.make(item.path) ||
630
+ !Number.isSafeInteger(item.size) || item.size < 0 || !Number.isSafeInteger(item.mode)) {
631
+ throw new Error("npm pack reported a malformed file path, size, or mode.");
632
+ }
633
+ return { path: item.path, size: item.size, mode: item.mode };
634
+ }).sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0);
635
+ if (new Set(decoded.map((file) => file.path.toLocaleLowerCase("en-US"))).size !== decoded.length) {
636
+ throw new Error("npm package file list contains a duplicate or case-colliding normalized path.");
637
+ }
638
+ return decoded;
639
+ };
640
+ const npmPackFlags = ["--json", "--offline", "--ignore-scripts", "--pack-destination", "{destination}", "--cache", "{cache}"];
641
+ const sameExecutable = (left, right) => left?.protocol === right.protocol && left.command === right.command && left.sha256 === right.sha256;
642
+ const establishNpmPackIdentity = (request) => Effect.gen(function* () {
643
+ const outcome = yield* request.run({
644
+ argv: ["npm", "--version"],
645
+ cwd: request.context.workspace.toString(),
646
+ environmentNames: [],
647
+ network: "offline-cli"
648
+ }).pipe(Effect.mapError(failure));
649
+ const version = outcome.stdout.trim();
650
+ if (outcome.exitCode !== 0 || !/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/u.test(version)) {
651
+ return yield* new PreparationError({
652
+ reason: `Unable to establish the exact npm pack version: ${outcome.stderr.trim()}`
653
+ });
654
+ }
655
+ if (outcome.tool?.protocol !== "ts-release-executable/v1" || outcome.tool.command !== "npm" ||
656
+ !/^[a-f0-9]{64}$/u.test(outcome.tool.sha256)) {
657
+ return yield* new PreparationError({ reason: "npm --version did not report an exact executable identity." });
658
+ }
659
+ return {
660
+ protocol: "ts-release-npm-pack/v1",
661
+ version,
662
+ executable: outcome.tool,
663
+ flags: npmPackFlags,
664
+ stdout: "complete-redacted-protocol"
665
+ };
666
+ });
667
+ const npmTarball = (request, publication, declarations, sourceSnapshot, basis, npmPackIdentity) => Effect.gen(function* () {
668
+ const packageId = publication.packageArtifact;
669
+ const packageDeclaration = declarations.get(packageId.toString());
670
+ if (packageDeclaration?.kind !== "package") {
671
+ return yield* new PreparationError({
672
+ reason: `npm publication ${publication.id} does not reference its declared package artifact.`
673
+ });
674
+ }
675
+ yield* attempt(() => assertNpmLiteralSelectionsPresent(resolve(request.context.workspace, packageDeclaration.path.toString())));
676
+ assertSnapshotPresent(request.context.workspace, sourceSnapshot, "Verified source");
677
+ const destination = SafeRelativePath.make(`.release/ts-release/npm/${publication.id}`);
678
+ const cache = SafeRelativePath.make(`.release/ts-release/npm-cache/${publication.id}`);
679
+ mkdirSync(join(request.context.workspace, destination), { recursive: true });
680
+ mkdirSync(join(request.context.workspace, cache), { recursive: true });
681
+ if (readdirSync(join(request.context.workspace, destination)).length > 0) {
682
+ return yield* new PreparationError({ reason: `npm publication ${publication.id} has a non-empty output directory.` });
683
+ }
684
+ const allowed = [destination, cache];
685
+ const before = yield* attempt(() => snapshotStaging(request.context.workspace, { exclude: allowed }));
686
+ const outcome = yield* request.run({
687
+ argv: ["npm", "pack", packageDeclaration.path.toString(), "--json", "--offline", "--ignore-scripts", "--pack-destination", destination, "--cache", cache],
688
+ cwd: request.context.workspace,
689
+ environmentNames: [],
690
+ stdout: "complete-protocol",
691
+ network: "offline-cli"
692
+ }).pipe(Effect.mapError(failure));
693
+ if (!sameExecutable(outcome.tool, npmPackIdentity.executable)) {
694
+ return yield* new PreparationError({
695
+ reason: "npm pack executable identity disagrees with the preflighted npm executable."
696
+ });
697
+ }
698
+ if (outcome.exitCode !== 0) {
699
+ return yield* new PreparationError({ reason: `npm pack exited ${outcome.exitCode}: ${outcome.stderr.trim()}` });
700
+ }
701
+ const after = yield* attempt(() => snapshotStaging(request.context.workspace, { exclude: allowed }));
702
+ if (!snapshotsEqual(before, after)) {
703
+ return yield* new PreparationError({
704
+ reason: `npm pack changed package source outside its private output/cache roots: ${snapshotDifference(before, after)}.`
705
+ });
706
+ }
707
+ assertSnapshotPresent(request.context.workspace, sourceSnapshot, "Verified source", { exclude: allowed });
708
+ const packageFiles = yield* attempt(() => decodeNpmPackFiles(outcome.stdout));
709
+ for (const file of packageFiles) {
710
+ const selected = resolve(request.context.workspace, packageDeclaration.path.toString(), file.path);
711
+ if (!contained(request.context.workspace, selected) || !existsSync(selected) || lstatSync(selected).isSymbolicLink() ||
712
+ !lstatSync(selected).isFile() || lstatSync(selected).size !== file.size) {
713
+ return yield* new PreparationError({
714
+ reason: `npm selected undeclared, escaped, linked, or size-mismatched package file ${file.path}.`
715
+ });
716
+ }
717
+ }
718
+ const outputEntries = readdirSync(join(request.context.workspace, destination), { withFileTypes: true });
719
+ if (outputEntries.length !== 1 || !outputEntries[0].isFile() || !outputEntries[0].name.endsWith(".tgz")) {
720
+ return yield* new PreparationError({ reason: "npm pack produced an invalid output directory." });
721
+ }
722
+ const path = SafeRelativePath.make(`${destination}/${outputEntries[0].name}`);
723
+ const artifactBytes = yield* capture(request.context, { id: packageId, path, kind: "archive" });
724
+ const digest = sha256Digest(artifactBytes);
725
+ return PreparedArtifact.make({
726
+ id: packageId,
727
+ path,
728
+ kind: "archive",
729
+ size: artifactBytes.length,
730
+ digest,
731
+ blob: digest,
732
+ mediaType: "application/gzip",
733
+ producer: NonEmptyName.make(`npm-pack:${publication.id}`),
734
+ inputBasis: basis
735
+ });
736
+ });
737
+ const runtimeIdentity = (bunVersion, isolation, bunCompileRuntimes, npmPack, releaseGraph) => PreparedExecutionInputs.make({
738
+ environment: "closed",
739
+ network: "prohibited",
740
+ timezone: "UTC",
741
+ locale: "C",
742
+ clock: "source-date-epoch=0;host-clock-not-isolated",
743
+ randomness: "host-randomness-not-isolated",
744
+ platform: `${process.platform}-${process.arch}`,
745
+ runtime: bunVersion === undefined ? `bun@${process.versions.bun}` : `bun@${bunVersion}`,
746
+ networkIsolation: isolation === undefined
747
+ ? "host-provided-network-deny/no-helper-identity"
748
+ : encodeCanonicalJson(isolation),
749
+ bunCompileRuntimes: bunCompileRuntimes.length === 0
750
+ ? "not-used"
751
+ : encodeCanonicalJson(bunCompileRuntimes),
752
+ npmPack: npmPack === undefined ? "not-used" : encodeCanonicalJson(npmPack),
753
+ releaseGraph,
754
+ preparer: "@mannyc1/ts-release@0.2.2"
755
+ });
756
+ export const prepareRelease = Effect.fn("prepareRelease")(function* (input) {
757
+ const sourceRoot = input.context.workspace.toString();
758
+ const root = yield* attempt(() => mkdtempSync(join(tmpdir(), "ts-release-prepare-")));
759
+ try {
760
+ const sourceSnapshot = yield* input.materializeSource(input.context, WorkspaceRoot.make(root)).pipe(Effect.mapError(failure));
761
+ const context = stagedContext(input.context, root);
762
+ const declarations = new Map(input.graph.artifacts.map((artifact) => [artifact.id.toString(), artifact]));
763
+ const produced = new Set(input.graph.preparations.flatMap((preparation) => preparation._tag === "GraphCommandArtifact"
764
+ ? preparation.outputs.map((output) => output.id.toString())
765
+ : preparation._tag === "GraphArchive" || preparation._tag === "GraphChecksum" || preparation._tag === "GraphCatalogRender"
766
+ ? [preparation.output.id.toString()]
767
+ : []));
768
+ const externalInputs = [];
769
+ for (const artifact of input.graph.artifacts) {
770
+ if (produced.has(artifact.id.toString()) || artifact.kind === "package")
771
+ continue;
772
+ const path = artifact.path.toString();
773
+ const tracked = sourceSnapshot.entries.some((entry) => entry.path.toString() === path || entry.path.toString().startsWith(`${path}/`));
774
+ if (tracked)
775
+ continue;
776
+ externalInputs.push(yield* attempt(() => materializeExplicitInput({
777
+ id: artifact.id.toString(),
778
+ sourceWorkspace: sourceRoot,
779
+ stageRoot: root,
780
+ path: artifact.path
781
+ })));
782
+ }
783
+ const request = { ...input, context };
784
+ const dependencies = yield* materializeBunDependencies({
785
+ request,
786
+ sourceWorkspace: sourceRoot,
787
+ sourceSnapshot
788
+ });
789
+ if (dependencies !== undefined)
790
+ externalInputs.push(dependencies.input);
791
+ const bytes = new Map();
792
+ const producers = new Map();
793
+ const preparedCollections = new Map();
794
+ const isolationIdentities = [];
795
+ const bunCompileRuntimes = new Map();
796
+ for (const artifact of input.graph.artifacts) {
797
+ if (produced.has(artifact.id.toString()) || artifact.kind === "package")
798
+ continue;
799
+ bytes.set(artifact.id.toString(), yield* capture(context, artifact));
800
+ producers.set(artifact.id.toString(), externalInputs.some((item) => item.id === artifact.id.toString())
801
+ ? `explicit-input:${artifact.id}`
802
+ : "verified-source");
803
+ }
804
+ for (const preparation of input.graph.preparations) {
805
+ const result = yield* structured(request, preparation, declarations, bytes, sourceSnapshot, externalInputs);
806
+ if (result.networkIsolation !== undefined)
807
+ isolationIdentities.push(result.networkIsolation);
808
+ if (result.bunCompileRuntime !== undefined) {
809
+ const prior = bunCompileRuntimes.get(result.bunCompileRuntime.target);
810
+ if (prior !== undefined && encodeCanonicalJson(prior) !== encodeCanonicalJson(result.bunCompileRuntime)) {
811
+ return yield* new PreparationError({
812
+ reason: `Bun compile target ${result.bunCompileRuntime.target} reported inconsistent private runtime identities.`
813
+ });
814
+ }
815
+ bunCompileRuntimes.set(result.bunCompileRuntime.target, result.bunCompileRuntime);
816
+ }
817
+ for (const declaration of result.declarations) {
818
+ const id = declaration.id.toString();
819
+ const idCollision = [...declarations.keys()].find((candidate) => candidate.toLocaleLowerCase("en-US") === id.toLocaleLowerCase("en-US"));
820
+ if (idCollision !== undefined) {
821
+ return yield* new PreparationError({
822
+ reason: `Runtime artifact ${id} collides with existing artifact id ${idCollision}.`
823
+ });
824
+ }
825
+ const path = declaration.path.toString();
826
+ const pathCollision = [...declarations.values()].find((candidate) => candidate.path.toString().toLocaleLowerCase("en-US") === path.toLocaleLowerCase("en-US"));
827
+ if (pathCollision !== undefined) {
828
+ return yield* new PreparationError({
829
+ reason: `Runtime artifact ${id} path ${path} collides with ${pathCollision.id} at ${pathCollision.path}.`
830
+ });
831
+ }
832
+ declarations.set(id, declaration);
833
+ }
834
+ if (result.collection !== undefined) {
835
+ const id = result.collection.contract.id.toString();
836
+ if (preparedCollections.has(id)) {
837
+ return yield* new PreparationError({ reason: `Runtime artifact collection ${id} was produced more than once.` });
838
+ }
839
+ preparedCollections.set(id, result.collection);
840
+ }
841
+ for (const [id, value] of result.outputs) {
842
+ bytes.set(id, value);
843
+ producers.set(id, preparation.id.toString());
844
+ }
845
+ }
846
+ const isolation = isolationIdentities[0];
847
+ if (isolation !== undefined && isolationIdentities.some((value) => encodeCanonicalJson(value) !== encodeCanonicalJson(isolation))) {
848
+ return yield* new PreparationError({
849
+ reason: "Network-isolated commands reported inconsistent helper, libseccomp, kernel, architecture, or syscall identities."
850
+ });
851
+ }
852
+ const hasNpmPublication = input.graph.publications.some((publication) => publication._tag === "GraphNpmPublication");
853
+ if (hasNpmPublication)
854
+ yield* attempt(() => {
855
+ for (const publication of input.graph.publications) {
856
+ if (publication._tag !== "GraphNpmPublication")
857
+ continue;
858
+ const declaration = declarations.get(publication.packageArtifact.toString());
859
+ if (declaration?.kind !== "package")
860
+ throw new Error(`npm publication ${publication.id} does not reference its declared package artifact.`);
861
+ assertNpmLiteralSelectionsPresent(resolve(root, declaration.path.toString()));
862
+ }
863
+ });
864
+ const npmPackIdentity = hasNpmPublication ? yield* establishNpmPackIdentity(request) : undefined;
865
+ const releaseGraph = sha256Digest(new TextEncoder().encode(encodeCanonicalJson(Schema.encodeSync(ReleaseGraph)(input.graph))));
866
+ const execution = runtimeIdentity(dependencies?.bunVersion, isolation, [...bunCompileRuntimes.values()].sort((left, right) => left.target < right.target ? -1 : left.target > right.target ? 1 : 0), npmPackIdentity, releaseGraph);
867
+ const basis = preparationBasisDigest(sourceSnapshot, externalInputs, {
868
+ environment: execution.environment,
869
+ network: execution.network,
870
+ timezone: execution.timezone,
871
+ locale: execution.locale,
872
+ clock: execution.clock,
873
+ randomness: execution.randomness,
874
+ platform: execution.platform,
875
+ runtime: execution.runtime,
876
+ networkIsolation: execution.networkIsolation,
877
+ bunCompileRuntimes: execution.bunCompileRuntimes,
878
+ npmPack: execution.npmPack,
879
+ releaseGraph: execution.releaseGraph.hex,
880
+ preparer: execution.preparer
881
+ });
882
+ const preparedArtifacts = new Map();
883
+ for (const artifact of [...declarations.values()].sort(byCodepoint)) {
884
+ const value = bytes.get(artifact.id.toString());
885
+ if (value === undefined || artifact.kind === "package")
886
+ continue;
887
+ const digest = sha256Digest(value);
888
+ preparedArtifacts.set(artifact.id.toString(), PreparedArtifact.make({
889
+ id: artifact.id,
890
+ path: artifact.path,
891
+ kind: artifact.kind,
892
+ size: value.length,
893
+ digest,
894
+ blob: digest,
895
+ ...(artifact.mediaType === undefined ? {} : { mediaType: artifact.mediaType }),
896
+ producer: NonEmptyName.make(producers.get(artifact.id.toString()) ?? "verified-source"),
897
+ inputBasis: basis
898
+ }));
899
+ }
900
+ const publications = [];
901
+ for (const publication of input.graph.publications) {
902
+ if (publication._tag === "GraphNpmPublication") {
903
+ const artifact = yield* npmTarball(request, publication, declarations, sourceSnapshot, basis, npmPackIdentity);
904
+ const artifactBytes = yield* capture(context, { id: artifact.id, path: artifact.path, kind: artifact.kind });
905
+ bytes.set(artifact.id.toString(), artifactBytes);
906
+ preparedArtifacts.set(artifact.id.toString(), artifact);
907
+ publications.push(PreparedNpmPublication.make({
908
+ id: NonEmptyName.make(publication.id),
909
+ packageName: publication.packageName,
910
+ version: Version.make(publication.version.toString()),
911
+ registryUrl: publication.registryUrl,
912
+ artifactId: artifact.id,
913
+ distTag: publication.distTag,
914
+ access: publication.access,
915
+ authentication: publication.authentication,
916
+ provenance: publication.provenance,
917
+ authority: publication.authority
918
+ }));
919
+ }
920
+ else if (publication._tag === "GraphPyPiPublication") {
921
+ const files = publication.files.map((file) => {
922
+ const artifact = preparedArtifacts.get(file.artifactId.toString());
923
+ const value = bytes.get(file.artifactId.toString());
924
+ if (artifact === undefined || value === undefined) {
925
+ throw new Error(`PyPI publication ${publication.id} references unavailable artifact ${file.artifactId}.`);
926
+ }
927
+ if (basename(artifact.path.toString()) !== file.filename.toString()) {
928
+ throw new Error(`PyPI artifact ${file.artifactId} filename changed after graph linking.`);
929
+ }
930
+ const distribution = inspectPythonDistribution(file.filename.toString(), value, publication.project.toString(), publication.version.toString());
931
+ if (artifact.mediaType !== undefined && artifact.mediaType !== distribution.mediaType) {
932
+ throw new Error(`PyPI artifact ${file.artifactId} declared media type disagrees with its verified distribution type.`);
933
+ }
934
+ const typedArtifact = artifact.mediaType === distribution.mediaType
935
+ ? artifact
936
+ : PreparedArtifact.make({ ...artifact, mediaType: distribution.mediaType });
937
+ preparedArtifacts.set(file.artifactId.toString(), typedArtifact);
938
+ const digest = sha256Digest(value);
939
+ return PreparedPyPiFile.make({
940
+ artifactId: typedArtifact.id,
941
+ filename: file.filename,
942
+ size: value.length,
943
+ sha256: digest,
944
+ mediaType: distribution.mediaType,
945
+ distribution,
946
+ authority: file.authority
947
+ });
948
+ });
949
+ publications.push(PreparedPyPiPublication.make({
950
+ id: NonEmptyName.make(publication.id),
951
+ project: publication.project,
952
+ version: publication.version,
953
+ repository: publication.repository,
954
+ simpleBaseUrl: publication.simpleBaseUrl,
955
+ projectUrl: publication.projectUrl,
956
+ uploadUrl: publication.uploadUrl,
957
+ authentication: publication.authentication,
958
+ files
959
+ }));
960
+ }
961
+ else if (publication._tag === "GraphGitHubPublication") {
962
+ const selectedIds = publication.assetCollections.flatMap((selector) => {
963
+ const collection = preparedCollections.get(selector.collection.toString());
964
+ if (collection === undefined) {
965
+ throw new Error(`GitHub publication ${publication.id} collection ${selector.collection} is unavailable.`);
966
+ }
967
+ if (!cardinalityAccepts(selector.cardinality, collection.members.length)) {
968
+ throw new Error(`GitHub publication ${publication.id} collection ${selector.collection} selected ${collection.members.length} members outside its cardinality.`);
969
+ }
970
+ return collection.members.map((member) => member.artifactId);
971
+ });
972
+ const assets = [...publication.assetIds, ...selectedIds].map((id) => {
973
+ const artifact = preparedArtifacts.get(id.toString());
974
+ if (artifact === undefined)
975
+ throw new Error(`GitHub publication ${publication.id} references unavailable artifact ${id}.`);
976
+ return {
977
+ artifactId: artifact.id,
978
+ name: NonEmptyName.make(basename(artifact.path)),
979
+ mediaType: artifact.mediaType ?? "application/octet-stream"
980
+ };
981
+ });
982
+ const assetNames = new Map();
983
+ for (const asset of assets) {
984
+ const folded = asset.name.toLocaleLowerCase("en-US");
985
+ const previous = assetNames.get(folded);
986
+ if (previous !== undefined) {
987
+ throw new Error(`GitHub publication ${publication.id} assets ${previous} and ${asset.name} have duplicate portable names.`);
988
+ }
989
+ assetNames.set(folded, asset.name);
990
+ }
991
+ const body = publication.bodyArtifact === undefined
992
+ ? publication.body
993
+ : new TextDecoder().decode(bytes.get(publication.bodyArtifact.toString()) ?? (() => {
994
+ throw new Error(`GitHub body artifact ${publication.bodyArtifact} is unavailable.`);
995
+ })());
996
+ publications.push(PreparedGitHubPublication.make({
997
+ id: NonEmptyName.make(publication.id),
998
+ repository: publication.repository,
999
+ tag: publication.tag,
1000
+ title: publication.title,
1001
+ draft: publication.draft,
1002
+ prerelease: publication.prerelease,
1003
+ targetCommit: context.source.commit,
1004
+ ...(body === undefined ? {} : { body }),
1005
+ assets,
1006
+ authority: publication.authority
1007
+ }));
1008
+ }
1009
+ else {
1010
+ const target = preparedArtifacts.get(publication.targetArtifact.toString());
1011
+ const targetBytes = bytes.get(publication.targetArtifact.toString());
1012
+ const render = input.graph.preparations.find((candidate) => candidate._tag === "GraphCatalogRender" && candidate.output.id.toString() === publication.targetArtifact.toString());
1013
+ if (target === undefined || targetBytes === undefined || render === undefined) {
1014
+ throw new Error(`Catalog publication ${publication.id} references no verified renderer output.`);
1015
+ }
1016
+ const downloads = publication.sources.map((source) => {
1017
+ const value = bytes.get(source.artifactId.toString());
1018
+ const declaration = declarations.get(source.artifactId.toString());
1019
+ if (value === undefined || declaration === undefined || basename(declaration.path) !== source.filename.toString()) {
1020
+ throw new Error(`Catalog publication ${publication.id} references unavailable source ${source.artifactId}.`);
1021
+ }
1022
+ return PreparedCatalogDownload.make({
1023
+ architecture: source.architecture,
1024
+ url: source.url,
1025
+ filename: source.filename,
1026
+ sha256: sha256Digest(value)
1027
+ });
1028
+ });
1029
+ const targetDigest = sha256Digest(targetBytes);
1030
+ const stateBytes = encodeCatalogManagedState(CatalogManagedState.make({
1031
+ schemaVersion: "ts-release/catalog-state/v2",
1032
+ catalogId: publication.catalogId,
1033
+ renderer: publication.renderer._tag,
1034
+ generation: publication.version,
1035
+ status: "active",
1036
+ targetDigest,
1037
+ sourceRepository: publication.sourceRepository,
1038
+ sourceTag: publication.sourceTag
1039
+ }));
1040
+ const stateDigest = sha256Digest(stateBytes);
1041
+ const stateArtifactId = OutputId.make(`catalog-state-${publication.catalogId}`);
1042
+ if (preparedArtifacts.has(stateArtifactId.toString()) || bytes.has(stateArtifactId.toString())) {
1043
+ throw new Error(`Catalog state artifact ${stateArtifactId} collides with another prepared artifact.`);
1044
+ }
1045
+ const stateArtifact = PreparedArtifact.make({
1046
+ id: stateArtifactId,
1047
+ path: SafeRelativePath.make(`.release/catalog-state/${publication.catalogId}.json`),
1048
+ kind: "file",
1049
+ size: stateBytes.length,
1050
+ digest: stateDigest,
1051
+ blob: stateDigest,
1052
+ mediaType: "application/json",
1053
+ producer: NonEmptyName.make(publication.id.toString()),
1054
+ inputBasis: basis
1055
+ });
1056
+ bytes.set(stateArtifactId.toString(), stateBytes);
1057
+ preparedArtifacts.set(stateArtifactId.toString(), stateArtifact);
1058
+ publications.push(PreparedCatalogPublication.make({
1059
+ id: NonEmptyName.make(publication.id.toString()),
1060
+ catalogId: publication.catalogId,
1061
+ targetArtifactId: target.id,
1062
+ stateArtifactId,
1063
+ targetDigest,
1064
+ stateDigest,
1065
+ repository: publication.repository,
1066
+ branch: publication.branch,
1067
+ targetPath: publication.targetPath,
1068
+ statePath: publication.statePath,
1069
+ version: publication.version,
1070
+ sourceRepository: publication.sourceRepository,
1071
+ sourceTag: publication.sourceTag,
1072
+ renderer: PreparedCatalogRenderer.make({ renderer: publication.renderer, downloads }),
1073
+ authority: publication.authority
1074
+ }));
1075
+ }
1076
+ }
1077
+ assertSnapshotPresent(root, sourceSnapshot, "Verified source");
1078
+ const githubPublication = input.graph.publications.find((publication) => publication._tag === "GraphGitHubPublication");
1079
+ const npmPublication = input.graph.publications.find((publication) => publication._tag === "GraphNpmPublication");
1080
+ const manifest = PreparedReleaseV2.make({
1081
+ kind: "complete",
1082
+ schemaVersion: "prepared-release/v2",
1083
+ source: PreparedSource.make({
1084
+ commit: context.source.commit,
1085
+ tree: context.source.tree,
1086
+ clean: true,
1087
+ packageManifestPath: context.source.packageManifestPath,
1088
+ packageManifestDigest: context.source.packageManifestDigest,
1089
+ materialized: sourceSnapshot
1090
+ }),
1091
+ project: PreparedProject.make({
1092
+ name: context.package.name,
1093
+ version: context.package.version,
1094
+ tag: githubPublication?.tag ?? NonEmptyName.make(`v${context.package.version}`),
1095
+ ...(npmPublication === undefined ? {} : { packageName: npmPublication.packageName }),
1096
+ ...(context.package.repository === undefined ? {} : { repository: context.package.repository })
1097
+ }),
1098
+ provenance: PreparedProvenance.make({
1099
+ source: sourceSnapshot,
1100
+ externalInputs,
1101
+ execution,
1102
+ inputBasis: basis,
1103
+ reproducibility: "not-asserted"
1104
+ }),
1105
+ artifacts: [...preparedArtifacts.values()].sort(byCodepoint),
1106
+ collections: [...preparedCollections.values()].sort((left, right) => left.contract.id < right.contract.id ? -1 : left.contract.id > right.contract.id ? 1 : 0),
1107
+ publications
1108
+ });
1109
+ const blobMap = new Map([...bytes.entries()].filter(([id]) => preparedArtifacts.has(id)));
1110
+ return yield* input.store.commit(manifest, blobMap).pipe(Effect.mapError((cause) => cause instanceof PreparedStoreError ? PreparationError.make({ reason: cause.reason }) : failure(cause)));
1111
+ }
1112
+ finally {
1113
+ rmSync(root, { recursive: true, force: true });
1114
+ }
1115
+ });
1116
+ //# sourceMappingURL=prepare.js.map