@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
package/README.md CHANGED
@@ -1,604 +1,336 @@
1
- # release
1
+ # ts-release
2
2
 
3
- `@mannyc1/ts-release` turns release intent into explicit, inspectable, repeatable publishing operations.
3
+ Automate multi-artifact releases and safely resume partial publication.
4
4
 
5
- The root package is the reusable TypeScript release library. The official Bun
6
- CLI app lives in `apps/release-ts`, and the root `cli` script delegates to that
7
- private first-party app.
5
+ ## Release locally
8
6
 
9
- The default workflow is plan-first:
7
+ The normal path is one command from a clean Git checkout:
10
8
 
11
9
  ```sh
12
- bun run cli validate-config --config release.config.json
13
- bun run cli plan --config release.config.json --format text
14
- bun run cli run --config release.config.json --execute --approve-irreversible
10
+ ts-release release --config release.config.json
15
11
  ```
16
12
 
17
- On GitHub Actions, the primary CI integration is the JavaScript action:
13
+ `release` resolves observed package and Git facts, materializes the exact
14
+ verified commit, runs declared local preparation, commits one complete
15
+ `prepared-release/v2` bundle, observes every configured destination, and
16
+ publishes only after a provider-specific decision authorizes that exact
17
+ subject. The command prints the durable prepared reference and correlated
18
+ report. A blocked or uncertain report is preserved and exits nonzero.
18
19
 
19
- ```yaml
20
- - uses: mannyc2/ts-release-action@v1
21
- with:
22
- command: plan
23
- config: release.config.json
24
- format: markdown
25
- ```
26
-
27
- The action calls the TypeScript workflow APIs directly and keeps target-native
28
- operations visible in the plan. It defaults to `runtime: bundled`; workspace
29
- runtime mode is deferred until a same-module-graph Node platform setup can be
30
- required without surprising users. The source currently lives in
31
- `apps/ts-release-action`.
32
-
33
- The action supports the review commands `plan`, `validate-config`, `status`,
34
- `eligibility`, `check-intent`, `doctor`, `check-auth`, and `check-ci`, plus the approved workflow commands
35
- `validate`, `run`, `resume`, and `reconcile`. Use `upload-evidence: true` when
36
- an action job should publish collected `.release/evidence` JSON files even after
37
- a command fails.
38
-
39
- The `run` command is the recommended release path: it renders generated files,
40
- validates every preflight, executes approved publish operations, and verifies
41
- remote state in order. The primitive commands remain available for review and
42
- debug flows:
43
-
44
- ```sh
45
- bun run cli schema --out release-config.schema.json
46
- bun run cli init --template npm-github --package @scope/pkg --repo owner/repo
47
- bun run cli validate-config --config release.config.json --format text
48
- bun run cli plan --config release.config.json --format text
49
- bun run cli plan --config release.config.json --format summary
50
- bun run cli explain npm:npm-publish --config release.config.json
51
- bun run cli doctor --config release.config.json --format text
52
- bun run cli check-auth --config release.config.json --target npm --format text
53
- bun run cli check-ci --config release.config.json --workflow .github/workflows/release.yml --format markdown
54
- bun run cli check-intent --config release.config.json --format text
55
- bun run cli render --config release.config.json --execute
56
- bun run cli validate --config release.config.json
57
- bun run cli print --config release.config.json
58
- bun run cli execute --config release.config.json --execute --approve-irreversible
59
- bun run cli verify --config release.config.json
60
- bun run cli eligibility --config release.config.json --format text
61
- bun run cli reconcile --config release.config.json --execute
62
- ```
63
-
64
- Rendering writes generated target files locally and records `render.json` evidence. `execute` is a lower-level primitive that runs publish operations only. Publishing is blocked unless execution is explicitly approved. Irreversible operations require a second approval flag.
65
-
66
- Status and resume commands use existing `.release/evidence` files to report progress and continue conservative unfinished work:
67
-
68
- ```sh
69
- bun run cli status --config release.config.json --format text
70
- bun run cli resume --config release.config.json --execute --approve-irreversible
71
- ```
72
-
73
- Resume skips operations with successful matching evidence, reruns safe read-only failures, and blocks failed publish operations until remote state is reconciled manually.
74
- `eligibility` resolves the configured release decision strategy and checks npm and GitHub remote state when a release is intended.
75
- `check-intent` is a read-only CI gate for the explicit intent-file strategy, and the GitHub Action exposes the same command for intent-file workflows.
76
- `reconcile` is separate from resume: it inspects GitHub release state through the API and can publish a matching draft release with explicit `--execute` without republishing immutable npm versions.
77
-
78
- The executable is an argv and console adapter over TypeScript workflows. Release workflows are modeled as typed functions first, then exposed through the CLI for terminal and CI usage.
79
-
80
- ## Imports
81
-
82
- The package root export is intentionally empty. For onboarding and application workflow code, import the opt-in workflow facade from `@mannyc1/ts-release/workflows`; for maximum tree-shaking or target-author control, import the exact module you need from an explicit subpath.
83
-
84
- ```ts
85
- import * as Effect from "effect/Effect"
86
- import { type ReleaseIntent } from "@mannyc1/ts-release/domain/release"
87
- import { createReleasePlan } from "@mannyc1/ts-release/planner/create-release-plan"
88
- import { validatePlan } from "@mannyc1/ts-release/planner/executor"
89
-
90
- export const planAndValidate = Effect.fn("docs.planAndValidate")(function*(intent: ReleaseIntent) {
91
- const plan = yield* createReleasePlan(intent)
92
- const evidence = yield* validatePlan(plan)
93
- return { plan, evidence }
94
- })
95
- ```
96
-
97
- `createReleasePlan` needs a `TargetRegistry` layer. Command execution needs a `ReleaseCommandRunner` layer, while artifact checks and checksum generation use Effect Platform `FileSystem`, `Path`, and `Crypto` services directly. High-level config-file workflows, render writes, and evidence writes also need Effect Platform `FileSystem` and `Path` services. Workflows that verify HTTP evidence, such as `verifyPlan`, `runApprovedReleaseWorkflow`, or direct `VerifyHttpOperation` execution, also need a `ReleaseHttp` layer. Applications can compose `@mannyc1/ts-release/workflows` and their platform services at the edge, or use exact lower-level imports from `@mannyc1/ts-release/workflows/live`, `@mannyc1/ts-release/host/platform`, and `@mannyc1/ts-release/host/http`. Tests can import `makeTestReleaseHttpLayer` from `@mannyc1/ts-release/host/http`. Internal Effect imports use deep module paths such as `effect/Effect` and `effect/Layer` to keep bundlers from depending on broad root-package analysis. See `ARCHITECTURE.md` for the module taxonomy.
98
-
99
- Reusable operations in docs and examples should use `Effect.fn`; workflow bodies use `Effect.gen`. Durable data, options, tagged target variants, and typed errors use `Schema.Class`, `Schema.TaggedClass`, and `Schema.TaggedErrorClass`, with `.make(...)` for construction. Runtime layers are provided once at CLI, action, script, application, or test boundaries.
100
-
101
- ## TypeScript Workflows
102
-
103
- Applications can call high-level release workflows without argv arrays or CLI command names:
104
-
105
- ```ts
106
- import * as BunHttpClient from "@effect/platform-bun/BunHttpClient"
107
- import * as BunServices from "@effect/platform-bun/BunServices"
108
- import * as Effect from "effect/Effect"
109
- import * as Layer from "effect/Layer"
110
- import { Config, Live } from "@mannyc1/ts-release/workflows"
111
-
112
- const root = "/path/to/release-workspace"
113
- const RuntimeLayer = Live.makeLayer({ root }).pipe(
114
- Layer.provideMerge(BunServices.layer),
115
- Layer.provideMerge(BunHttpClient.layer)
116
- )
117
-
118
- const textPlan = await Effect.runPromise(
119
- Config.renderPlan({ root, configPath: "release.config.json", format: "text" }).pipe(
120
- Effect.provide(RuntimeLayer)
121
- )
122
- )
123
-
124
- const plan = await Effect.runPromise(
125
- Config.plan({ root, configPath: "release.config.json" }).pipe(
126
- Effect.provide(RuntimeLayer)
127
- )
128
- )
129
-
130
- const evidence = await Effect.runPromise(
131
- Config.run({
132
- root,
133
- configPath: "release.config.json",
134
- execute: true,
135
- approveIrreversible: true
136
- }).pipe(
137
- Effect.provide(RuntimeLayer)
138
- )
139
- )
140
-
141
- const status = await Effect.runPromise(
142
- Config.status({ root, configPath: "release.config.json", format: "json" }).pipe(
143
- Effect.provide(RuntimeLayer)
144
- )
145
- )
146
-
147
- const resumedEvidence = await Effect.runPromise(
148
- Config.resume({
149
- root,
150
- configPath: "release.config.json",
151
- execute: true,
152
- approveIrreversible: true
153
- }).pipe(
154
- Effect.provide(RuntimeLayer)
155
- )
156
- )
157
-
158
- const eligibility = await Effect.runPromise(
159
- Config.checkEligibility({
160
- root,
161
- configPath: "release.config.json"
162
- }).pipe(
163
- Effect.provide(RuntimeLayer)
164
- )
165
- )
166
-
167
- const reconciliationEvidence = await Effect.runPromise(
168
- Config.reconcile({
169
- root,
170
- configPath: "release.config.json",
171
- execute: true
172
- }).pipe(
173
- Effect.provide(RuntimeLayer)
174
- )
175
- )
176
- ```
177
-
178
- Use `@mannyc1/ts-release/workflows` for the curated `Config`, `Init`, `Diagnostics`, `Evidence`, and `Live` namespaces. Exact leaf imports such as `@mannyc1/ts-release/workflows/config`, `@mannyc1/ts-release/workflows/init`, `@mannyc1/ts-release/workflows/diagnostics`, `@mannyc1/ts-release/workflows/evidence`, and `@mannyc1/ts-release/workflows/live` remain stable and are preferred when an application needs maximum tree-shaking or direct access to option classes. Applications provide platform services at the edge, such as `FileSystem`, `Path`, `HttpClient`, and command execution. Use explicit lower-level planner, config, target, host, and domain subpaths when an application needs finer control over planning, execution, or test layers.
179
-
180
- ## Example Config
20
+ npm authentication is always explicit. A GitHub-hosted npm and GitHub release
21
+ can use this authored configuration:
181
22
 
182
23
  ```json
183
24
  {
184
- "$schema": "https://mannyc2.github.io/ts-release/schema/release-config.schema.json",
185
- "identity": {
186
- "name": "@mannyc1/ts-release",
187
- "version": "0.1.0",
188
- "commit": "abc123",
189
- "tag": "v0.1.0",
190
- "notes": "Release notes"
191
- },
192
- "artifacts": [
193
- {
194
- "id": "package",
195
- "path": ".",
196
- "format": "directory",
197
- "consumers": ["npm"]
198
- },
199
- {
200
- "id": "github-asset",
201
- "path": "artifacts/mannyc1-ts-release-0.1.0.tgz",
202
- "format": "tarball",
203
- "consumers": ["github"]
204
- }
205
- ],
206
- "targets": [
207
- {
208
- "_tag": "NpmRegistryTarget",
209
- "id": "npm",
210
- "registry": "https://registry.npmjs.org",
211
- "packageName": "@mannyc1/ts-release",
212
- "packagePath": ".",
213
- "trustedPublishing": {
214
- "provider": "github-actions",
215
- "workflow": "release.yml",
216
- "packageExists": true,
217
- "verifyPackageExists": true
218
- },
219
- "access": "public",
220
- "provenance": true,
221
- "dryRunSupport": "native",
222
- "mutability": "immutable",
223
- "recovery": "publish-new-version"
25
+ "project": { "repository": "owner/repo" },
26
+ "versionFrom": "manifest",
27
+ "npmPackage": { "path": "." },
28
+ "publish": {
29
+ "npm": {
30
+ "authentication": {
31
+ "strategy": "trusted-publishing",
32
+ "attestation": {
33
+ "provider": "github-actions",
34
+ "runner": "github-hosted",
35
+ "repository": "owner/repo",
36
+ "workflow": "release.yml",
37
+ "workflowRef": "refs/heads/main",
38
+ "allowedAction": "npm-publish-direct"
39
+ }
40
+ }
224
41
  },
225
- {
226
- "_tag": "GitHubReleaseTarget",
227
- "id": "github",
228
- "repository": "owner/repo",
229
- "tokenEnv": "GH_TOKEN",
230
- "draft": true,
231
- "dryRunSupport": "simulated",
232
- "mutability": "mutable-release",
233
- "recovery": "delete-and-recreate"
234
- }
235
- ],
236
- "strict": true,
237
- "evidenceDirectory": ".release/evidence/{version}"
238
- }
239
- ```
240
-
241
- The optional `$schema` key powers editor completion and does not change release behavior. Print the derived schema with `bun run cli schema`, and use `bun run cli validate-config` to check JSON syntax and release config shape without running target validators.
242
-
243
- Paths are release-workspace relative and may not be absolute or contain parent traversal. `evidenceDirectory` may include the literal `{version}` placeholder, which is resolved during planning so each release version can use its own evidence directory.
244
- Artifact paths may use `{version}`, `{name}`, and `{normalizedName}`. `normalizedName` removes a leading npm scope marker and replaces `/` with `-`, matching generated self-release artifact names such as `mannyc1-ts-release-0.1.0.tgz`.
245
-
246
- ## Release Strategies
247
-
248
- Release identity and release decisions are strategy-backed data. Target adapters still receive a concrete release identity and still produce reviewable, approval-gated operations.
249
-
250
- | Strategy | Good for | Source of truth |
251
- |---|---|---|
252
- | Static config | audited/manual release identity | release config |
253
- | Package manifest | npm/package releases with one version source | `package.json` |
254
- | Git tag | tag-triggered release workflows | current Git tag |
255
- | Conventional commits | automated SemVer from commit messages | commits since the latest matching tag |
256
- | Intent files | reviewed release intent in PRs | `.release/intents/*.json` |
257
-
258
- Static identity remains supported:
259
-
260
- ```json
261
- {
262
- "identity": {
263
- "name": "@scope/pkg",
264
- "version": "0.1.0",
265
- "commit": "abc123",
266
- "tag": "v0.1.0"
42
+ "github": {}
267
43
  }
268
44
  }
269
45
  ```
270
46
 
271
- For npm-style packages, prefer manifest-derived identity to avoid repeating versions in release config:
47
+ `workflow` and `workflowRef` are local host-admission constraints, not claims
48
+ about fields exposed by npm's trusted-publisher configuration. They must name
49
+ the workflow that actually invokes publication: use `release.yml` with the
50
+ automatic template and `reviewed-release.yml` with the reviewed template. The
51
+ host must observe that exact repository/path/ref on a GitHub-hosted runner
52
+ before it reads either OIDC request value. Public npm metadata reads are always
53
+ anonymous; private or custom-registry authenticated reads are unsupported
54
+ until configured with a distinct read credential.
55
+
56
+ The resolver fills package name, version, tag, commit, and repository only
57
+ when observed facts agree with authored intent. For a non-OIDC host, use
58
+ `{ "strategy": "token", "credential": "NPM_TOKEN" }` instead. The value of
59
+ that environment variable remains host-owned and never enters configuration,
60
+ prepared bytes, reports, or logs.
61
+
62
+ Prebuilt Python distributions can be published to the closed `pypi` or
63
+ `testpypi` destination. Each named artifact must be a valid wheel or gzip
64
+ sdist whose filename and embedded metadata agree with the configured project
65
+ and version:
272
66
 
273
67
  ```json
274
68
  {
275
- "identity": {
276
- "_tag": "PackageManifestReleaseIdentitySource",
277
- "packagePath": "package.json",
278
- "commit": "HEAD",
279
- "tagTemplate": "v{version}"
69
+ "project": { "name": "fixture", "version": "1.0.0", "tag": "v1.0.0" },
70
+ "artifacts": [
71
+ { "id": "wheel", "path": "dist/fixture-1.0.0-py3-none-any.whl", "format": "file" }
72
+ ],
73
+ "publish": {
74
+ "pypi": {
75
+ "artifacts": ["wheel"],
76
+ "repository": "pypi",
77
+ "authentication": {
78
+ "strategy": "token",
79
+ "credential": "PYPI_TOKEN",
80
+ "scope": "project"
81
+ }
82
+ }
280
83
  }
281
84
  }
282
85
  ```
283
86
 
284
- Decision strategies are opt-in through `releaseDecision`. The default `RemoteStateReleaseDecision` uses the resolved identity, then checks npm and GitHub state. Git tag and conventional commit strategies can return `skipped` without error when no release input is present. Intent files are small JSON documents in `.release/intents`:
285
-
286
- ```json
287
- {
288
- "$schema": "https://mannyc2.github.io/ts-release/schema/release-intent.schema.json",
289
- "package": "@scope/pkg",
290
- "release": "patch",
291
- "summary": "Explain the user-visible change.",
292
- "empty": false
293
- }
294
- ```
295
-
296
- This is a first-party intent-file format, not full Changesets compatibility. Publish operations remain plan data until explicit execution approval, regardless of which strategy chose the intended version.
297
-
298
- Homebrew tap targets model catalog updates as generated files plus an approval-gated push:
299
-
300
- ```json
301
- {
302
- "_tag": "HomebrewTapTarget",
303
- "id": "homebrew",
304
- "repository": "owner/homebrew-tap",
305
- "formulaName": "release",
306
- "formulaPath": ".release/generated/release.rb",
307
- "artifactId": "github-asset",
308
- "url": "https://github.com/owner/repo/releases/download/v0.1.0/mannyc1-ts-release-0.1.0.tgz",
309
- "installPath": "bin/release",
310
- "dryRunSupport": "simulated",
311
- "mutability": "mutable-index",
312
- "recovery": "manual"
313
- }
314
- ```
315
-
316
- PyPI registry targets coordinate already-built Python distributions through Twine. They do not build wheels or sdists:
317
-
318
- ```json
319
- {
320
- "_tag": "PyPiRegistryTarget",
321
- "id": "pypi",
322
- "repositoryUrl": "https://test.pypi.org/legacy/",
323
- "usernameEnv": "TWINE_USERNAME",
324
- "passwordEnv": "TWINE_PASSWORD",
325
- "dryRunSupport": "native",
326
- "mutability": "immutable",
327
- "recovery": "publish-new-version"
328
- }
329
- ```
330
-
331
- Use `TWINE_USERNAME` and `TWINE_PASSWORD` for token-based local publishing so secrets stay in environment variables rather than command arguments. PyPI Trusted Publishing belongs at the CI/auth layer; this adapter records Twine commands and their auth requirements. TestPyPI is a real registry publish target, not a dry-run.
87
+ PyPI token upload additionally requires the host to install a shared,
88
+ durable terminal `PublicationClaimStore`; runner-local files and memory do not
89
+ satisfy that contract. The stock CLI and Action deliberately fail closed
90
+ without one. Library hosts can pass it to `makeNodeReleaseLayer`,
91
+ `makeBunReleaseLayer`, or `makeCustomReleaseLayer`. The token is projected as
92
+ PyPI Basic authentication only inside the authorized HTTP sink. PyPI trusted
93
+ publishing is represented as an external, host-owned
94
+ `pypa/gh-action-pypi-publish@release/v1` path; the stock coordinator neither
95
+ exchanges its OIDC token nor claims to recover that external upload.
332
96
 
333
- Scoop bucket targets model Windows installer catalog updates as generated JSON manifests plus an approval-gated push:
334
-
335
- ```json
336
- {
337
- "_tag": "ScoopBucketTarget",
338
- "id": "scoop",
339
- "repository": "owner/scoop-bucket",
340
- "manifestName": "release",
341
- "manifestPath": ".release/generated/release.json",
342
- "artifactId": "github-asset",
343
- "url": "https://github.com/owner/repo/releases/download/v0.1.0/mannyc1-ts-release-0.1.0.zip",
344
- "bin": "release.exe",
345
- "dryRunSupport": "simulated",
346
- "mutability": "mutable-index",
347
- "recovery": "manual"
348
- }
349
- ```
350
-
351
- Tap and bucket pushes use the Git credentials configured for the local checkout; `tokenEnv` is not supported for these catalog targets yet.
352
-
353
- Use `run --execute --approve-irreversible` for the ordered release workflow, or use `plan`, `render --execute`, `validate`, `print`, `execute --execute`, and `verify` separately when generated catalog files need a manual review pause before any tap or bucket update is pushed.
354
-
355
- ## Plan Review
356
-
357
- Text plans include the release identity, evidence directory, artifact inventory, target capabilities, operation commands, HTTP verification requests, validation notes, and execution gates. Command operations include a human command summary plus an `argv:` JSON array that preserves exact argument boundaries for review.
358
-
359
- ```text
360
- @mannyc1/ts-release@0.1.0
361
- commit: abc123
362
- evidence: .release/evidence/0.1.0
363
- artifacts: 2
364
- targets: 2
365
- operations: 9
366
-
367
- targets:
368
- - github [GitHubReleaseTarget] auth=env-token dry-run=simulated strategy=simulated-plan mutability=mutable-release recovery=delete-and-recreate
369
- - npm [NpmRegistryTarget] auth=trusted-publishing runs-in=ci provider=github-actions workflow=release.yml required-permission=id-token:write package-prerequisite=exists dry-run=native strategy=native-command mutability=immutable recovery=publish-new-version
370
- ```
371
-
372
- Summary plans provide a compact human first pass over risk, execution gates, target auth setup, and gated operation IDs:
97
+ With the canonical GitHub origin or package repository configured, `init` can
98
+ discover the exact owner/repository coordinate and write this explicit shape:
373
99
 
374
100
  ```sh
375
- bun run cli plan --config release.config.json --format summary
101
+ ts-release init --preset bun-npm-github
376
102
  ```
377
103
 
378
- Markdown plans are intended for CI artifacts and PR review:
104
+ It refuses to guess when no repository coordinate is observable and strictly
105
+ inspects the exact generated configuration before writing it.
379
106
 
380
- ```sh
381
- bun run cli plan --config release.config.json --format markdown > release-plan.md
382
- ```
383
-
384
- Use `explain` when one operation needs a focused review without executing anything:
107
+ ## Automatic GitHub Actions release
385
108
 
386
- ```sh
387
- bun run cli explain npm:npm-publish --config release.config.json
388
- ```
109
+ The default workflow is one job and one Action invocation. Copy the exact
110
+ [automatic workflow template](templates/github-actions/release.yml). It is
111
+ manual-only and requires `candidate_sha` to equal the current commit on
112
+ `refs/heads/main` before the job can reach checkout. Its
113
+ mutation job grants `contents: write` for the same-repository tag, release, and
114
+ assets, `id-token: write` for npm trusted publishing, and `actions: read` for
115
+ prepared-artifact recovery. It installs the publisher boundary explicitly,
116
+ uses the job-scoped `GITHUB_TOKEN`, and uploads the redacted report as a
117
+ recovery artifact.
389
118
 
390
- JSON plans include the same data in a stable, CI-artifact-friendly shape, including `targetCapabilities`.
391
-
392
- GitHub release verification uses the GitHub REST API to check the release tag, title, draft flag, prerelease flag, and each uploaded artifact name.
393
-
394
- ## Status and Resume
395
-
396
- `status` reads local phase evidence and reports each current operation as pending, passed, failed, blocked, or complete without executing anything. The JSON format is schema-backed for CI or dashboards; the text format is intended for terminal review.
397
-
398
- `resume` is intentionally conservative. It skips successful matching evidence, can rerun missing work and failed read-only validation or verification operations, and never reruns a failed publish operation. A failed publish command can still have changed the outside world, so resume blocks until a maintainer reconciles npm, GitHub, or any other remote state manually.
399
-
400
- `reconcile` is the narrow remote repair path for GitHub Releases. It reads the GitHub release by tag, blocks on mismatched metadata or assets, skips an already matching published release, and can run `gh release edit <tag> --draft=false` for a matching draft when the target expects a public release. It does not run `npm publish`.
401
-
402
- ## Public API
403
-
404
- The intentional public API is the explicit subpath list in `package.json`. The root package export remains empty. Programmatic callers can use the opt-in `@mannyc1/ts-release/workflows` facade for happy-path workflow APIs, or exact leaf subpaths such as `@mannyc1/ts-release/workflows/config`, `@mannyc1/ts-release/workflows/init`, and `@mannyc1/ts-release/workflows/diagnostics` for maximum tree-shaking and direct option-class access. Lower-level planner/config/target/status subpaths remain available for finer control. The official CLI command adapter lives in the private `apps/release-ts` app rather than the reusable root package API.
405
-
406
- The package export checker fails if a new export is added without being added to the intentional API list.
407
-
408
- ## Templates
409
-
410
- Copyable starter configs live in `templates/`. They are authoring starting
411
- points with placeholder package, repository, tap, and bucket names. Runnable
412
- fixtures live in `examples/`.
413
-
414
- Config templates are intentionally narrow:
415
-
416
- - `npm-only` for an existing npm package using GitHub Actions trusted publishing.
417
- - `npm-github` for npm plus GitHub Releases.
418
- - `multi-target-homebrew` for npm, GitHub Releases, and a Homebrew tap.
419
- - `multi-target-scoop` for npm, GitHub Releases, and a Scoop bucket.
420
-
421
- ```sh
422
- bun run cli init --template npm-github --package @scope/pkg --repo owner/repo
423
- bun run cli init --template npm-github --package @scope/pkg --repo owner/repo --write
424
- bun run cli init --template npm-github --package @scope/pkg --repo owner/repo --github-actions --package-manager npm --write
425
- bun run cli plan --config release.config.json --format text
119
+ ```yaml
120
+ - id: release
121
+ uses: mannyc2/ts-release/apps/ts-release-action@v0.2.2
122
+ env:
123
+ GITHUB_TOKEN: ${{ github.token }}
124
+ with:
125
+ command: ${{ inputs.prepared_ref == '' && 'release' || 'publish' }}
126
+ config: ${{ inputs.prepared_ref == '' && 'release.config.json' || '' }}
127
+ prepared: ${{ inputs.prepared_ref }}
426
128
  ```
427
129
 
428
- The npm templates enable provenance and set `verifyPackageExists: true`, which
429
- adds a read-only `npm view <package>` validation before trusted publishing.
430
- Add `--github-actions` to include the action-first trusted-publishing workflow
431
- template in the preview or write set. Workflow scaffolding supports
432
- `--package-manager bun|npm|pnpm|yarn`, plus single-line `--install-command` and
433
- `--build-command` overrides. Those commands are CI setup steps, not release
434
- target policy; publish operations still come from the `ts-release` plan.
435
- Existing files are not overwritten unless `--overwrite` is also passed.
436
-
437
- Action-first GitHub templates live under `templates/github-actions/`. The
438
- checked-in templates use npm setup by default, while this repository's own
439
- self-release workflow uses the Bun preset.
440
-
441
- Use `doctor`, `check-auth`, and `check-ci` after writing a template to inspect
442
- static readiness before any publish operation is approved.
443
-
444
- ## Examples
445
-
446
- Runnable example configs live in `examples/`:
447
-
448
- - `examples/multi-target`
449
- - `examples/npm-only`
450
- - `examples/npm-first-publish`
451
- - `examples/github-release`
452
- - `examples/homebrew-tap`
453
- - `examples/pypi-registry`
454
- - `examples/scoop-bucket`
455
- - `examples/non-strict-skips`
456
-
457
- `examples/multi-target` demonstrates one release coordinated across GitHub Releases, npm, and a Homebrew tap. The focused fixtures cover PyPI, Scoop, npm-only trusted publishing, token-based first npm publish, GitHub-only releases, and non-strict skipped validators. Build the package first, then plan an example from its directory:
130
+ Leave `prepared_ref` empty for a fresh release. To resume after durable
131
+ preparation, dispatch the same candidate with the exact emitted
132
+ `prepared:gha:` reference; the job selects `publish`, loads and verifies the
133
+ original bundle, and does not rebuild.
134
+
135
+ `v0.2.2` is the immutable monorepo-subpath coordinate intended for this
136
+ candidate. Packaging and release certification must stop unless that tag is
137
+ created from the exact certified result commit before consumers can see a
138
+ README that names it. A floating Action branch is never an alternative.
139
+
140
+ ## Optional environment-gated publication
141
+
142
+ When a host policy requires a protected environment, use the
143
+ [two-job workflow template](templates/github-actions/reviewed-release.yml).
144
+ Copy its paired
145
+ [reviewed configuration](templates/npm-github/reviewed-release.config.json)
146
+ to the repository root with the same filename; the workflow loads that exact
147
+ file.
148
+ Its prepare job has read-only repository authority and no OIDC permission. It
149
+ uploads one complete prepared bundle and passes only its content-addressed
150
+ hosted reference. The environment-gated publish job installs the publisher
151
+ toolchain, receives mutation permissions, reloads and verifies the bundle, and
152
+ then observes destinations before any write. The environment gate remains a workflow
153
+ fact; it is not release-engine identity or data.
154
+
155
+ The reviewed configuration attests `workflow: "reviewed-release.yml"` and
156
+ `workflowRef: "refs/heads/main"`. Keep the workflow filename and dispatch it
157
+ from that ref with `candidate_sha` equal to the current commit, or deliberately
158
+ update both constraints. Reusing an automatic configuration that attests
159
+ `release.yml` fails before OIDC acquisition. Recover a failed reviewed
160
+ publication by rerunning the publish job in the same workflow run, not by
161
+ preparing again.
162
+
163
+ ## Prepare without publication
164
+
165
+ Use the split local path for build-only work or when bytes must cross an
166
+ explicit host boundary:
458
167
 
459
168
  ```sh
460
- bun run build
461
- cd examples/multi-target
462
- bun ../../apps/release-ts/src/cli/main.ts plan --config release.config.json --format text
169
+ prepared_ref="$(ts-release prepare --config release.config.json)"
170
+ ts-release inspect "$prepared_ref"
463
171
  ```
464
172
 
465
- Trusted-publishing npm examples use provenance and `verifyPackageExists`. The
466
- `npm-first-publish` example intentionally stays token-based because npm trusted
467
- publishing can only be configured after the package already exists.
468
-
469
- ## Evidence
470
-
471
- Render, validation, execution, and verification evidence is written as JSON bundles. Failed commands still preserve partial evidence before the command failure is returned. Use `evidenceDirectory` such as `.release/evidence/{version}` when older local evidence should not collide with the current release version.
472
-
473
- ```json
474
- {
475
- "schemaVersion": "release-evidence/v1",
476
- "releaseName": "release",
477
- "releaseVersion": "0.1.0",
478
- "records": [
479
- {
480
- "id": "npm:npm-pack-dry-run:command",
481
- "operationId": "npm:npm-pack-dry-run",
482
- "operationFingerprint": "{\"_tag\":\"ValidateCommandOperation\",\"id\":\"npm:npm-pack-dry-run\",\"targetId\":\"npm\",\"approval\":{\"requiresExecute\":false,\"requiresIrreversibleApproval\":false},\"command\":{\"executable\":\"npm\",\"args\":[\"pack\",\"--dry-run\",\"--json\"],\"requiredEnv\":[],\"redactedEnv\":[]}}",
483
- "status": "passed",
484
- "severity": "info",
485
- "exitCode": 0
486
- }
487
- ]
488
- }
489
- ```
173
+ The value is a path-free `prepared:local:sha256-…` reference resolved against
174
+ the selected content-addressed store. `--store` selects another local store;
175
+ the reference itself never embeds a filesystem path. Publication accepts only
176
+ a complete reference and never rebuilds from source as a fallback.
490
177
 
491
- Non-strict mode records missing validators as visible skipped evidence instead of silently dropping them.
178
+ Local extension work uses two primitives. `CommandCheck` is a pass/fail gate.
179
+ `CommandArtifact` generates or transforms declared regular-file bytes. Data
180
+ flow uses declared input and output IDs. Generic preparation children receive
181
+ no authored host environment values, and the runner may retain only `PATH` as
182
+ argv execution plumbing. Trusted commands are not a sandbox or a generic
183
+ remote-effect mechanism.
492
184
 
493
- ## Readiness
185
+ ## Observe and recover
494
186
 
495
- Normal verification stays deterministic and does not require live external services:
187
+ Observation is read-only:
496
188
 
497
189
  ```sh
498
- bun run check:release
190
+ ts-release observe "$prepared_ref"
499
191
  ```
500
192
 
501
- CI runs the portable package checks on Linux, macOS, and Windows. The release
502
- gate runs the self-release config guard, the static self-release CI diagnostic,
503
- and then the portable checks.
504
-
505
- Real-tool integration checks are opt-in:
193
+ To resume a partial or response-lost release, publish the same reference:
506
194
 
507
195
  ```sh
508
- bun run test:integration:tools
509
- RELEASE_INTEGRATION_GITHUB=1 bun run test:integration:tools
196
+ ts-release publish "$prepared_ref"
510
197
  ```
511
198
 
512
- The first command validates npm adapter operations against the real `npm` CLI. The second also validates GitHub adapter readiness checks against the real `gh` CLI and requires `gh auth status` to succeed. GitHub release creation itself has no native dry-run; release validation is simulated from the deterministic plan before publish and verified against GitHub only after publish.
199
+ Every attempt verifies the manifest and blobs, then reobserves every subject.
200
+ Equivalent subjects are skipped. Conflict and pre-mutation uncertainty stop
201
+ without mutation. A post-dispatch unknown outcome stays uncertain until a new
202
+ exact observation converges. Publication is not an atomic transaction, so a
203
+ release may partially succeed and there is no universal rollback.
513
204
 
514
- Example configs and templates are checked through the TypeScript workflow path:
205
+ ## Provider-specific correction
515
206
 
516
- ```sh
517
- bun run check:examples
518
- ```
519
-
520
- This repository also includes a self-release config at `apps/release-ts/release.config.json` that targets both npm and GitHub for the scoped `@mannyc1/ts-release` package. The app-owned self-release scripts live under `apps/release-ts/scripts`, with root package scripts delegating to them. The self-release config must pass `bun run check:self-release-config`, and the workflow must pass `bun run check:self-release-ci`, before portable release checks proceed. It derives name and version from the root `package.json`, uses `{version}` artifact templates, and keeps `identity.commit` as `HEAD` for stored-config convenience. Generated plans resolve `HEAD` to the current short commit, and the self-release guard requires a committed Git checkout with clean tracked files.
207
+ Correction is deliberately separate from ordinary publication:
521
208
 
522
209
  ```sh
523
- bun run check:self-release-config
524
- bun run check:self-release-ci
210
+ ts-release correct "$prepared_ref" correction.json
525
211
  ```
526
212
 
527
- ### Self Release
528
-
529
- The local non-publish gates for this package are:
213
+ The command binds authored intent to the exact prepared provider subject. npm
214
+ and GitHub Release corrections remain canonical external operator proposals.
215
+ Catalog Git installs one conditional `forward-catalog-state` correction: it
216
+ requires a SemVer-newer replacement and changes both the consumer formula or
217
+ manifest and its managed-state record against the exact observed branch
218
+ generation. Deletion, arbitrary inverse operations, and announcements are not
219
+ release destinations.
220
+
221
+ ## Capability and platform boundary
222
+
223
+ A source checkout or accepted field is not support evidence. The generated
224
+ capability inventory must join each supported row to its strict decoder,
225
+ default-layer entrypoint, exact observation semantics, and vertical test, and
226
+ the release-candidate matrix must exercise every claimed execution host.
227
+
228
+ | Axis | Kernel candidate boundary |
229
+ | --- | --- |
230
+ | Local preparation | Bun compilation, prebuilt imports, command checks/artifacts, archives, and checksums are retained; final support requires the generated capability and clean-candidate gates to agree. |
231
+ | Remote publication | npm, prebuilt PyPI distributions, GitHub Releases, and typed Homebrew/Scoop catalog Git delivery are installed. npm uses explicit trusted-publishing or token authentication; PyPI token writes require a host-supplied shared terminal claim store, and its trusted-publishing strategy is external-host-owned. |
232
+ | Correction | npm and GitHub authored proposals are exact-bound; PyPI yanking is observation-only; catalog Git installs exact paired SemVer-forward correction. |
233
+ | Execution hosts | Linux is the only installed execution host. The checked-in Action is a native Node 24 launcher around a workflow-installed, pinned Bun runtime. macOS and Windows are not ts-release execution hosts. |
234
+ | Artifact targets | The Bun builder advertises Linux and macOS x64/arm64 targets. macOS binaries are cross-compiled artifacts, not host-execution evidence. The self-release does not distribute a Windows ts-release binary. |
235
+ | Native tools | Linux preparation requires an external Bun executable and `libseccomp.so.2`; network-denied commands record both identities. WSL, when used, is Linux. A standalone CLI binary is not a self-contained replacement for these tools. |
236
+
237
+ Installed Node consumers must satisfy the package engine
238
+ `^22.22.2 || ^24.15.0 || >=26.0.0`; Bun consumers require Bun 1.3.14 or newer.
239
+ The checked-in Action uses GitHub's native Node 24 Action handler so the runner
240
+ can inject its Actions-artifact transport credentials. Its tiny checked-in
241
+ launcher passes no credentials to the Bun 1.3.14 runtime preloader, then runs
242
+ the checked-in `dist/index.js` through the workflow-installed Bun runtime.
243
+ Preparation stays in Bun, while every Actions-artifact upload or download is
244
+ delegated to the checked-in Node 24 bridge so the official artifact client runs
245
+ on its native stream implementation. The Action does not change the Node
246
+ engine of the installed library or CLI package.
247
+
248
+ The current source tree is not a release certificate. A published support
249
+ claim exists only after the clean-candidate evidence records all required
250
+ gates green; skipped live facts remain `UNVERIFIED`.
251
+
252
+ ## Extension jobs and exclusions
253
+
254
+ The kernel translates extension requests to the owner that can enforce them:
255
+
256
+ | User job | Owner |
257
+ | --- | --- |
258
+ | Tests, policy checks, generated notes, and agent bundles | `CommandCheck` or declared `CommandArtifact` bytes |
259
+ | npm, prebuilt PyPI, GitHub Release, and catalog Git remote verification/publication | Installed provider modules; PyPI token mutation also requires the shared terminal claim boundary |
260
+ | Environment protection or human authorization | External workflow host |
261
+ | Downstream announcements | External workflow step after a complete report |
262
+
263
+ Homebrew and Scoop rendering/delivery use typed renderers and an exact paired
264
+ Git Data subject; arbitrary whole-file catalog templating remains excluded.
265
+ Wrapper wheels remain excluded from the prebuilt PyPI slice unless an explicit product decision reopens them. PyPI
266
+ support is contract-tested but has not been live-write-dogfooded in this wave.
267
+ Custom library applications may compose full provider subjects through the
268
+ [`provider-sdk`](https://github.com/mannyc2/ts-release/blob/main/docs/native-extensions.md)
269
+ subpath. The stock CLI and Action
270
+ do not discover packages or treat generic hooks as remote publishers.
271
+
272
+ ## Library API
273
+
274
+ The Promise API uses the same lifecycle as the CLI and Action:
530
275
 
531
- ```sh
532
- bun run check:release
533
- bun run release:artifacts
534
- bun run cli plan --config apps/release-ts/release.config.json --format text
535
- bun run --cwd apps/release-ts cli plan --root ../.. --config apps/release-ts/release.config.json --format text
536
- ```
537
-
538
- `release:artifacts` delegates to `apps/release-ts/scripts/build-release-artifacts.ts` and writes ignored files under `.release/artifacts`: the npm package tarball and standalone CLI executables for Linux, macOS, and Windows. GitHub Actions runs on protected `main` and checks release eligibility before the full release gate. When `should_release` is true, the plan job runs `check:release`, builds artifacts, records a Markdown release plan, uploads evidence, and does not execute release operations. The protected `execute` job uses the reviewed `.release/artifacts` download, grants `contents: write` and `id-token: write`, and runs approved execution with npm trusted publishing OIDC instead of an npm token.
539
-
540
- ### Local Release Auth
541
-
542
- Use `.env.example` as the local credential contract. Export `GH_TOKEN`, or copy
543
- `.env.example` to `.env` and fill in token values locally. `.env` and `.npmrc`
544
- are ignored intentionally; keep token values out of commits. `.npmrc.example`
545
- shows npm's `${NPM_TOKEN}` interpolation form for token-based npm targets.
546
- `TWINE_USERNAME` and `TWINE_PASSWORD` are only needed for PyPI/Twine examples.
547
-
548
- For npmjs releases from GitHub Actions, prefer structured `trustedPublishing` on
549
- the npm target:
276
+ ```ts
277
+ import {
278
+ defineRelease,
279
+ encodeCompletePreparedReleaseRef,
280
+ makeReleaseApi
281
+ } from "@mannyc1/ts-release"
282
+ import { NodeReleaseLayer } from "@mannyc1/ts-release/node"
283
+
284
+ const config = defineRelease({
285
+ project: { repository: "owner/repo" },
286
+ versionFrom: "manifest" as const,
287
+ npmPackage: { path: "." },
288
+ publish: {
289
+ npm: {
290
+ authentication: {
291
+ strategy: "trusted-publishing" as const,
292
+ attestation: {
293
+ provider: "github-actions" as const,
294
+ runner: "github-hosted" as const,
295
+ repository: "owner/repo",
296
+ workflow: "release.yml",
297
+ workflowRef: "refs/heads/main",
298
+ allowedAction: "npm-publish-direct" as const
299
+ }
300
+ }
301
+ },
302
+ github: {}
303
+ }
304
+ })
550
305
 
551
- ```json
552
- {
553
- "packageName": "@mannyc1/ts-release",
554
- "trustedPublishing": {
555
- "provider": "github-actions",
556
- "workflow": "release.yml",
557
- "packageExists": true,
558
- "verifyPackageExists": true
559
- },
560
- "access": "public",
561
- "provenance": true
306
+ const api = makeReleaseApi(NodeReleaseLayer)
307
+ try {
308
+ const result = await api.release({ config, workspace: process.cwd() })
309
+ console.log(encodeCompletePreparedReleaseRef(result.prepared))
310
+ console.log(result.report.status)
311
+ } finally {
312
+ await api.dispose()
562
313
  }
563
314
  ```
564
315
 
565
- Trusted publishing authenticates during `npm publish` with CI OIDC, so
566
- `ts-release` records that mode in validation evidence instead of running
567
- `npm whoami`, which does not validate OIDC publishing. Configure npmjs trusted
568
- publishing for an existing package and use a GitHub-hosted runner with
569
- `id-token: write`, Node 22.14+ and npm 11.5.1+. The `packageExists` field must be
570
- `true` as a precondition acknowledgement, not first-publish support. Setting
571
- `verifyPackageExists` to `true` adds a read-only `npm view <package>` validation
572
- check. Trusted publishing does not use `NPM_TOKEN` for `npm publish`; token-based
573
- npm targets may still use `.npmrc.example` and `NPM_TOKEN`.
316
+ The public operations are `inspect`, `prepare`, `observe`, `publish`,
317
+ `release`, and `correct`. Public inputs contain neither credential values nor
318
+ prepared paths. The derived graph is ephemeral; the verified prepared
319
+ manifest and blobs are the durable cross-process boundary.
320
+
321
+ ## Agent bundles and development
574
322
 
575
- Diagnostics stay static by default and report confidence instead of pretending
576
- local checks prove provider setup:
323
+ The single tracked agent source owner is `apps/ts-release-agents`. Generated
324
+ Codex and Claude layouts are ignored build output and are captured by the
325
+ self-release as declared `CommandArtifact` outputs. No root marketplace tree
326
+ is a second canonical owner.
577
327
 
578
328
  ```sh
579
- bun run cli check-auth --config release.config.json --format text
580
- bun run cli check-ci --config release.config.json --workflow .github/workflows/release.yml --format markdown
581
- bun run cli doctor --config release.config.json --format json
329
+ bun install --frozen-lockfile
330
+ bun run check:portable
331
+ bun test
582
332
  ```
583
333
 
584
- The reusable GitHub Actions trusted-publishing workflow template lives at
585
- `templates/github-actions/trusted-publishing.yml`. It uses
586
- `mannyc2/ts-release-action@v1` to record a Markdown plan, uploads review
587
- artifacts, and requires a protected `release` environment before running
588
- approved execution. npm trusted publishing uses OIDC, not `NPM_TOKEN`;
589
- `GH_TOKEN` is for GitHub Releases and API verification.
590
-
591
- ### First npm Publish Bootstrap
592
-
593
- Trusted publishing is the preferred steady state for GitHub Actions, but npm
594
- requires the package to exist before trusted publishing can be configured. For a
595
- new package, use a temporary token-based npm target with `tokenEnv: "NPM_TOKEN"`
596
- and no `trustedPublishing` object. After the first version exists on npm,
597
- configure npm trusted publishing for owner `mannyc2`, repository `ts-release`,
598
- and workflow filename `release.yml`, then switch the target to
599
- `trustedPublishing`.
600
-
601
- Do not commit token values. Keep `.env.example` and `.npmrc.example` as
602
- placeholder contracts only.
603
-
604
- The first-release GitHub target uses `GH_TOKEN` for both `gh` command authentication and read-only REST API verification. The release workflow sets up a current Node/npm toolchain for trusted publishing and enables npm provenance for CI-based publishes where the registry can generate provenance.
334
+ The durable model is documented in [ARCHITECTURE.md](ARCHITECTURE.md), and the
335
+ precise public contract is in [SPEC.md](SPEC.md). Both files are included with the npm
336
+ package; this README does not rely on an unpackaged relative document.