@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,48 @@
1
+ ---
2
+ name: release
3
+ description: Operate ts-release through its automatic inspect, prepare, publish, release, and correction APIs.
4
+ ---
5
+
6
+ # ts-release release skill
7
+
8
+ Use the installed package and repository evidence as the authority. Read the
9
+ workspace package manifest and release configuration before suggesting edits.
10
+
11
+ ## Lifecycle
12
+
13
+ - `inspect` reports authored configuration or an existing prepared bundle.
14
+ - `prepare` observes a clean source tree, runs only declared native
15
+ preparations, and stores exact `prepared-release/v1` bytes plus blobs.
16
+ - `publish` accepts only that prepared bundle and observes each destination
17
+ before and after provider mutation.
18
+ - `release` is the normal automatic path: it composes preparation and
19
+ publication in one process.
20
+ - `correct` consumes a prepared bundle and one canonical provider-specific
21
+ correction intent.
22
+
23
+ The derived graph is ephemeral. Exact prepared bytes are the cross-process
24
+ boundary. Never invent a second authority format, generic rollback, provider
25
+ hook, or host review protocol.
26
+
27
+ ## Safety
28
+
29
+ Read the local schema before writing configuration. Keep paths relative and
30
+ contained. Credentials are environment names or Action inputs, never secret
31
+ values. Treat conflicts and inconclusive destination observations as blocked;
32
+ do not retry an unknown remote mutation blindly. Report typed errors and the
33
+ exact prepared bundle path.
34
+
35
+ ## CLI
36
+
37
+ ```sh
38
+ ts-release inspect --config release.config.json
39
+ ts-release prepare --config release.config.json
40
+ ts-release publish .release/ts-release/prepared/<manifest-digest>
41
+ ts-release release --config release.config.json
42
+ ts-release correct <prepared-bundle> <correction-intent.json>
43
+ ```
44
+
45
+ Read `references/configuration.md`, `references/recovery.md`, and
46
+ `references/verification.md` when the task needs those details. A release
47
+ host may add review or environment protection outside the engine; do not place
48
+ that policy into configuration or prepared bytes.
@@ -0,0 +1,18 @@
1
+ # Configuration
2
+
3
+ The authored JSON shape is validated strictly. Unknown keys, absolute paths,
4
+ parent traversal, non-JSON values, and raw secret values are rejected.
5
+
6
+ Minimal configuration:
7
+
8
+ ```json
9
+ {
10
+ "project": { "name": "my-tool", "version": "1.2.3", "tag": "v1.2.3" },
11
+ "artifacts": [{ "id": "cli", "path": "dist/cli", "format": "executable" }]
12
+ }
13
+ ```
14
+
15
+ Use `builds` for Bun or configured native builders, `preparations` for typed
16
+ native command artifacts, `archives` and `checksum` for local outputs, and
17
+ `publish.npm` or `publish.github` for provider subjects. A preparation declares
18
+ every output and its argv; it is trusted local code, not a sandbox.
@@ -0,0 +1,10 @@
1
+ # Recovery
2
+
3
+ The prepared bundle is the recovery boundary. Re-run `publish` with the same
4
+ bundle; it does not rebuild or reinterpret authored configuration. A lost
5
+ provider response is resolved only by observing the destination again.
6
+
7
+ Conflicts and inconclusive observations remain blocked. If a provider-specific
8
+ correction is needed, create a canonical correction intent bound to the bundle
9
+ digest and run `correct`. Corrections move forward through provider semantics;
10
+ they are not generic rollback.
@@ -0,0 +1,12 @@
1
+ # Prepared workflow
2
+
3
+ The normal workflow is:
4
+
5
+ ```text
6
+ inspect → prepare → publish
7
+ ```
8
+
9
+ `release` composes the last two steps automatically. Use `prepare` followed by
10
+ `publish` when a host deliberately transfers exact prepared bytes between
11
+ processes. The host may insert its own review or environment gate between those
12
+ steps without changing the bundle or adding a second lifecycle protocol.
@@ -0,0 +1,13 @@
1
+ # Target selection
2
+
3
+ Choose only configuration supported by the installed schema:
4
+
5
+ - Bun-compiled executables use `builds[]` with `builder: "bun"`.
6
+ - Imported files use `artifacts[]`; archives and checksums are local
7
+ preparations.
8
+ - npm and GitHub Releases use their typed publication sections.
9
+ - Homebrew, Scoop, and generic catalog files are rendered as managed local
10
+ bytes; repository delivery requires its typed transport.
11
+ - Unsupported provider correction is reported as an explicit typed outcome.
12
+
13
+ Do not invent profiles, custom providers, hooks, or marketplace submissions.
@@ -0,0 +1,14 @@
1
+ # Verification
2
+
3
+ Inside the ts-release repository run:
4
+
5
+ ```sh
6
+ bun run check
7
+ bun test
8
+ bun run check:portable
9
+ bun run check:agents
10
+ ```
11
+
12
+ For a prepared boundary, inspect the bundle and verify that publication uses
13
+ the exact directory returned by `prepare`. Do not claim a provider write unless
14
+ the destination observation proves it.
@@ -0,0 +1,105 @@
1
+ import { mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs"
2
+ import { dirname, join, resolve } from "node:path"
3
+ import { fileURLToPath } from "node:url"
4
+
5
+ type ArchiveEntry = { readonly path: string, readonly data: Uint8Array, readonly mode: number }
6
+ const encoder = new TextEncoder()
7
+ const text = (value: string): Uint8Array => encoder.encode(value)
8
+ const concat = (parts: ReadonlyArray<Uint8Array>): Uint8Array => {
9
+ const result = new Uint8Array(parts.reduce((size, part) => size + part.length, 0))
10
+ let offset = 0
11
+ for (const part of parts) { result.set(part, offset); offset += part.length }
12
+ return result
13
+ }
14
+ const integer = (bytes: number, value: number): Uint8Array => {
15
+ const result = new Uint8Array(bytes)
16
+ const view = new DataView(result.buffer)
17
+ if (bytes === 2) view.setUint16(0, value, true)
18
+ else view.setUint32(0, value, true)
19
+ return result
20
+ }
21
+ const crcTable = Array.from({ length: 256 }, (_, value) => {
22
+ let crc = value
23
+ for (let bit = 0; bit < 8; bit += 1) crc = (crc & 1) === 1 ? 0xedb88320 ^ (crc >>> 1) : crc >>> 1
24
+ return crc >>> 0
25
+ })
26
+ const crc32 = (data: Uint8Array): number => {
27
+ let crc = 0xffffffff
28
+ for (const byte of data) crc = (crc >>> 8) ^ crcTable[(crc ^ byte) & 0xff]!
29
+ return (crc ^ 0xffffffff) >>> 0
30
+ }
31
+ const zip = (entries: ReadonlyArray<ArchiveEntry>): Uint8Array => {
32
+ const bodies: Uint8Array[] = [], central: Uint8Array[] = []
33
+ let offset = 0
34
+ for (const entry of [...entries].sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0)) {
35
+ const name = text(entry.path), crc = crc32(entry.data)
36
+ const local = concat([integer(4, 0x04034b50), integer(2, 20), integer(2, 0x0800), integer(2, 0), integer(2, 0), integer(2, 0), integer(4, crc), integer(4, entry.data.length), integer(4, entry.data.length), integer(2, name.length), integer(2, 0), name])
37
+ bodies.push(local, entry.data)
38
+ central.push(concat([integer(4, 0x02014b50), integer(2, 0x0314), integer(2, 20), integer(2, 0x0800), integer(2, 0), integer(2, 0), integer(2, 0), integer(4, crc), integer(4, entry.data.length), integer(4, entry.data.length), integer(2, name.length), integer(2, 0), integer(2, 0), integer(2, 0), integer(2, 0), integer(4, entry.mode << 16), integer(4, offset), name]))
39
+ offset += local.length + entry.data.length
40
+ }
41
+ const directory = concat(central)
42
+ return concat([...bodies, directory, integer(4, 0x06054b50), integer(2, 0), integer(2, 0), integer(2, entries.length), integer(2, entries.length), integer(4, directory.length), integer(4, offset), integer(2, 0)])
43
+ }
44
+
45
+ const root = resolve(dirname(fileURLToPath(import.meta.url)), "../../..")
46
+ const app = join(root, "apps", "ts-release-agents")
47
+ const output = join(root, ".release", "agents")
48
+ const version = (): string => {
49
+ const value = JSON.parse(readFileSync(join(root, "package.json"), "utf8")) as { version?: unknown }
50
+ if (typeof value.version !== "string" || value.version.length === 0) throw new Error("Root package version is missing.")
51
+ return value.version
52
+ }
53
+ const write = (path: string, contents: string | Uint8Array): void => {
54
+ mkdirSync(dirname(path), { recursive: true, mode: 0o755 })
55
+ writeFileSync(path, contents, { mode: 0o644 })
56
+ }
57
+ const copyTree = (source: string, target: string, entries: ReadonlyArray<string>): void => {
58
+ for (const entry of entries) write(join(target, entry), readFileSync(join(source, entry)))
59
+ }
60
+ const filesUnder = (directory: string): string[] => readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
61
+ const path = join(directory, entry.name)
62
+ return entry.isDirectory() ? filesUnder(path).map((child) => join(entry.name, child)) : [entry.name]
63
+ })
64
+ const generatedManifest = (provider: "codex" | "claude", packageVersion: string): Record<string, unknown> => {
65
+ const authored = JSON.parse(readFileSync(join(app, "manifests", `${provider}.json`), "utf8")) as Record<string, unknown>
66
+ return provider === "codex"
67
+ ? { ...authored, version: packageVersion }
68
+ : { ...authored, version: packageVersion, author: { name: "mannyc2", url: "https://github.com/mannyc2/ts-release" }, repository: "https://github.com/mannyc2/ts-release" }
69
+ }
70
+ const packageFiles = (provider: "codex" | "claude", packageRoot: string, packageVersion: string): void => {
71
+ const native = provider === "codex" ? ".codex-plugin" : ".claude-plugin"
72
+ write(join(packageRoot, native, "plugin.json"), `${JSON.stringify(generatedManifest(provider, packageVersion), null, 2)}\n`)
73
+ write(join(packageRoot, "README.md"), readFileSync(join(app, "README.md")))
74
+ write(join(packageRoot, "LICENSE"), readFileSync(join(app, "LICENSE")))
75
+ write(join(packageRoot, "evals", "cases.json"), readFileSync(join(app, "evals", "cases.json")))
76
+ copyTree(join(app, "skills"), join(packageRoot, "skills"), filesUnder(join(app, "skills")))
77
+ }
78
+
79
+ export interface BuildAgentsOptions {
80
+ /** Release preparation captures archives only; standalone checks retain installable layouts. */
81
+ readonly archivesOnly?: true
82
+ }
83
+
84
+ export const buildAgents = (options: BuildAgentsOptions = {}): ReadonlyArray<string> => {
85
+ const packageVersion = version()
86
+ rmSync(output, { recursive: true, force: true })
87
+ const created: string[] = []
88
+ for (const provider of ["codex", "claude"] as const) {
89
+ const packageRoot = join(output, provider, "ts-release")
90
+ packageFiles(provider, packageRoot, packageVersion)
91
+ const entries = filesUnder(packageRoot).map((path): ArchiveEntry => ({
92
+ path: join("ts-release", path).replaceAll("\\", "/"), data: new Uint8Array(readFileSync(join(packageRoot, path))), mode: 0o100644
93
+ }))
94
+ const archive = join(output, "archives", `ts-release-${provider}.zip`)
95
+ write(archive, zip(entries))
96
+ created.push(archive)
97
+ if (options.archivesOnly === true) rmSync(join(output, provider), { recursive: true, force: true })
98
+ }
99
+ return created
100
+ }
101
+
102
+ if (import.meta.main) {
103
+ const archivesOnly = process.argv.slice(2).includes("--archives-only")
104
+ for (const path of buildAgents(archivesOnly ? { archivesOnly: true } : {})) console.log(path.slice(root.length + 1))
105
+ }
@@ -0,0 +1,117 @@
1
+ import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync } from "node:fs"
2
+ import { dirname, join, relative, resolve } from "node:path"
3
+ import { tmpdir } from "node:os"
4
+ import { fileURLToPath } from "node:url"
5
+ import { spawnSync } from "node:child_process"
6
+ import { buildAgents } from "./build.js"
7
+ import { installAgentArchive } from "./install.js"
8
+
9
+ const root = resolve(dirname(fileURLToPath(import.meta.url)), "../../..")
10
+ const output = join(root, ".release", "agents")
11
+ const app = join(root, "apps", "ts-release-agents")
12
+ const fail = (reason: string): never => { throw new Error(reason) }
13
+ const bytes = (path: string): Uint8Array => new Uint8Array(readFileSync(path))
14
+ const same = (left: Uint8Array, right: Uint8Array): boolean => left.length === right.length && left.every((byte, index) => byte === right[index])
15
+ const json = (path: string): Record<string, unknown> => {
16
+ const value: unknown = JSON.parse(readFileSync(path, "utf8"))
17
+ if (typeof value !== "object" || value === null || Array.isArray(value)) fail(`${path} must be an object.`)
18
+ return value as Record<string, unknown>
19
+ }
20
+ const rootVersion = String((json(join(root, "package.json")).version ?? ""))
21
+ const generatedFiles = (directory: string): string[] => readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
22
+ const path = join(directory, entry.name)
23
+ return entry.isDirectory() ? generatedFiles(path) : [path]
24
+ })
25
+ const containsFiles = (directory: string): boolean => readdirSync(directory, { withFileTypes: true }).some((entry) => {
26
+ return entry.isDirectory() ? containsFiles(join(directory, entry.name)) : true
27
+ })
28
+
29
+ const firstPaths = buildAgents()
30
+ const first = firstPaths.map((path) => bytes(path))
31
+ const secondPaths = buildAgents()
32
+ const second = secondPaths.map((path) => bytes(path))
33
+ if (first.length !== second.length || first.some((value, index) => !same(value, second[index]!))) fail("Agent archives are not deterministic.")
34
+ for (const provider of ["codex", "claude"] as const) {
35
+ const packageRoot = join(output, provider, "ts-release")
36
+ const manifestPath = join(packageRoot, provider === "codex" ? ".codex-plugin" : ".claude-plugin", "plugin.json")
37
+ if (!existsSync(manifestPath)) fail(`Generated ${provider} manifest is missing.`)
38
+ if (json(manifestPath).version !== rootVersion) fail(`Generated ${provider} manifest version diverges from the root package.`)
39
+ if (!existsSync(join(packageRoot, "skills", "release", "SKILL.md"))) fail(`Generated ${provider} skill is missing.`)
40
+ }
41
+ const codex = json(join(output, "codex", "ts-release", ".codex-plugin", "plugin.json"))
42
+ if (codex.skills !== "./skills/") fail("Codex manifest must point to ./skills/.")
43
+ const evals = json(join(app, "evals", "cases.json"))
44
+ if (!Array.isArray(evals.cases) || evals.cases.length < 6) fail("Agent eval coverage is incomplete.")
45
+ for (const path of generatedFiles(join(output, "codex", "ts-release"))) {
46
+ const text = readFileSync(path, "utf8")
47
+ if (/npm_[A-Z0-9_]{6,}/u.test(text)) fail(`Generated agent content resembles a raw secret: ${path}`)
48
+ if (text.includes("../")) fail(`Generated agent content contains parent traversal: ${path}`)
49
+ }
50
+ for (const forbidden of [".agents", ".claude-plugin", ".codex-plugin", "ts-release-plugin"]) {
51
+ if (existsSync(join(root, forbidden)) && containsFiles(join(root, forbidden))) fail(`Obsolete root agent owner remains: ${forbidden}`)
52
+ }
53
+ for (const path of ["SKILL.md", join("skills", "release", "SKILL.md")]) {
54
+ if (existsSync(join(root, path))) fail(`Root canonical agent owner remains: ${path}`)
55
+ }
56
+ const tracked = spawnSync("git", ["ls-files", "-z"], { cwd: root, encoding: "utf8", stdio: "pipe" })
57
+ if (tracked.status !== 0) fail(`Could not inspect tracked agent owners: ${tracked.stderr.trim() || tracked.stdout.trim()}`)
58
+ const trackedFiles = tracked.stdout.split("\0").filter((path) => path.length > 0)
59
+ const canonicalRootOwners = trackedFiles.filter((path) =>
60
+ path === ".codex-plugin/plugin.json" ||
61
+ path === ".claude-plugin/plugin.json" ||
62
+ path === "skills/release/SKILL.md" ||
63
+ path === "SKILL.md" ||
64
+ path.startsWith("ts-release-plugin/"))
65
+ if (canonicalRootOwners.length !== 0) fail(`Tracked root canonical agent owners remain: ${canonicalRootOwners.join(", ")}`)
66
+ const skillOwners = trackedFiles.filter((path) => path.endsWith("/skills/release/SKILL.md"))
67
+ if (skillOwners.length !== 1 || skillOwners[0] !== "apps/ts-release-agents/skills/release/SKILL.md") {
68
+ fail(`Agent skill source ownership diverged: ${skillOwners.join(", ") || "none"}`)
69
+ }
70
+
71
+ const disposableRoot = mkdtempSync(join(tmpdir(), "ts-release-agent-installs-"))
72
+ let installed = 0
73
+ const providerLayouts: string[] = []
74
+ try {
75
+ for (const provider of ["codex", "claude"] as const) {
76
+ const archive = secondPaths.find((path) => path.endsWith(`ts-release-${provider}.zip`)) ??
77
+ fail(`Generated ${provider} archive is missing.`)
78
+ const installation = installAgentArchive(provider, archive, disposableRoot)
79
+ const native = provider === "codex" ? ".codex-plugin" : ".claude-plugin"
80
+ const manifest = join(installation.packageRoot, native, "plugin.json")
81
+ if (!existsSync(manifest)) fail(`Installed ${provider} native manifest is missing.`)
82
+ if (!existsSync(join(installation.packageRoot, "skills", "release", "SKILL.md"))) {
83
+ fail(`Installed ${provider} skill is missing.`)
84
+ }
85
+ if (provider === "codex" && json(manifest).skills !== "./skills/") {
86
+ fail("Installed Codex manifest must point to ./skills/.")
87
+ }
88
+ if (provider === "claude") {
89
+ const validated = spawnSync("claude", ["plugin", "validate", "--strict", installation.packageRoot], {
90
+ encoding: "utf8",
91
+ env: {
92
+ ...process.env,
93
+ CLAUDE_CONFIG_DIR: join(disposableRoot, ".claude")
94
+ },
95
+ stdio: "pipe"
96
+ })
97
+ if (validated.status !== 0) {
98
+ fail(`Installed Claude plugin validator failed: ${validated.stderr.trim() || validated.stdout.trim()}`)
99
+ }
100
+ }
101
+ providerLayouts.push(relative(disposableRoot, installation.packageRoot).replaceAll("\\", "/"))
102
+ installed += 1
103
+ }
104
+ } finally {
105
+ rmSync(disposableRoot, { recursive: true, force: true })
106
+ }
107
+
108
+ console.log(JSON.stringify({
109
+ schemaVersion: "ts-release-agents-check/v2",
110
+ providers: 2,
111
+ archives: second.length,
112
+ disposableInstalls: installed,
113
+ providerLayouts,
114
+ claudeValidation: "strict",
115
+ rootCanonicalOwners: canonicalRootOwners.length,
116
+ status: "ready"
117
+ }))
@@ -0,0 +1,121 @@
1
+ import {
2
+ existsSync,
3
+ lstatSync,
4
+ mkdirSync,
5
+ mkdtempSync,
6
+ readFileSync,
7
+ readdirSync,
8
+ realpathSync,
9
+ renameSync,
10
+ rmSync
11
+ } from "node:fs"
12
+ import { join, sep } from "node:path"
13
+ import { spawnSync } from "node:child_process"
14
+
15
+ export type AgentProvider = "codex" | "claude"
16
+
17
+ export interface InstalledAgentArchive {
18
+ readonly provider: AgentProvider
19
+ /** Disposable stand-in for the user's home directory. */
20
+ readonly userRoot: string
21
+ /** Provider-native cache owner below the disposable user root. */
22
+ readonly providerRoot: string
23
+ readonly packageRoot: string
24
+ readonly version: string
25
+ readonly entries: ReadonlyArray<string>
26
+ }
27
+
28
+ const fail = (reason: string): never => { throw new Error(reason) }
29
+
30
+ const archiveEntries = (archive: string): ReadonlyArray<string> => {
31
+ const listed = spawnSync("unzip", ["-Z1", archive], { encoding: "utf8", stdio: "pipe" })
32
+ if (listed.status !== 0) {
33
+ fail(`Could not inspect agent archive ${archive}: ${listed.stderr.trim() || listed.stdout.trim()}`)
34
+ }
35
+ const entries = listed.stdout.split("\n").filter((entry) => entry.length > 0)
36
+ if (entries.length === 0) fail(`Agent archive ${archive} is empty.`)
37
+ if (new Set(entries).size !== entries.length) fail(`Agent archive ${archive} contains duplicate paths.`)
38
+ for (const entry of entries) {
39
+ const segments = entry.split("/")
40
+ if (
41
+ !entry.startsWith("ts-release/") ||
42
+ entry.startsWith("/") ||
43
+ entry.includes("\\") ||
44
+ entry.includes("\0") ||
45
+ segments.some((segment) => segment === "" || segment === "." || segment === "..")
46
+ ) fail(`Agent archive ${archive} contains unsafe path ${JSON.stringify(entry)}.`)
47
+ }
48
+ return entries
49
+ }
50
+
51
+ const verifyContainedTree = (directory: string): void => {
52
+ const root = realpathSync(directory)
53
+ const prefix = `${root}${sep}`
54
+ const visit = (current: string): void => {
55
+ for (const entry of readdirSync(current)) {
56
+ const path = join(current, entry)
57
+ const status = lstatSync(path)
58
+ if (status.isSymbolicLink()) fail(`Installed agent package contains a symlink: ${path}`)
59
+ if (!status.isDirectory() && !status.isFile()) fail(`Installed agent package contains a special file: ${path}`)
60
+ const canonical = realpathSync(path)
61
+ if (canonical !== root && !canonical.startsWith(prefix)) fail(`Installed agent path escapes its package: ${path}`)
62
+ if (status.isDirectory()) visit(path)
63
+ }
64
+ }
65
+ visit(directory)
66
+ }
67
+
68
+ /**
69
+ * Installs one generated archive into a disposable provider-owned plugin
70
+ * directory. This performs local ZIP inspection and extraction only.
71
+ */
72
+ export const installAgentArchive = (
73
+ provider: AgentProvider,
74
+ archive: string,
75
+ userRoot: string
76
+ ): InstalledAgentArchive => {
77
+ const entries = archiveEntries(archive)
78
+ mkdirSync(userRoot, { recursive: true, mode: 0o700 })
79
+ const stage = mkdtempSync(join(userRoot, `.ts-release-${provider}-stage-`))
80
+ try {
81
+ const extracted = spawnSync("unzip", ["-qq", archive, "-d", stage], {
82
+ encoding: "utf8",
83
+ stdio: "pipe"
84
+ })
85
+ if (extracted.status !== 0) {
86
+ fail(`Could not install ${provider} agent archive: ${extracted.stderr.trim() || extracted.stdout.trim()}`)
87
+ }
88
+ const stagedPackage = join(stage, "ts-release")
89
+ if (!existsSync(stagedPackage) || !lstatSync(stagedPackage).isDirectory()) {
90
+ fail(`Installed ${provider} package root is missing.`)
91
+ }
92
+ verifyContainedTree(stagedPackage)
93
+ const native = provider === "codex" ? ".codex-plugin" : ".claude-plugin"
94
+ const manifestPath = join(stagedPackage, native, "plugin.json")
95
+ if (!existsSync(manifestPath)) fail(`Installed ${provider} native manifest is missing.`)
96
+ const manifest: unknown = JSON.parse(readFileSync(manifestPath, "utf8"))
97
+ const version = typeof manifest === "object" && manifest !== null &&
98
+ "version" in manifest && typeof manifest.version === "string"
99
+ ? manifest.version
100
+ : fail(`Installed ${provider} native manifest version is missing.`)
101
+ if (!/^[0-9A-Za-z][0-9A-Za-z._+-]*$/u.test(version)) {
102
+ fail(`Installed ${provider} native manifest version is not a safe cache key.`)
103
+ }
104
+ const providerRoot = join(
105
+ userRoot,
106
+ provider === "codex" ? ".codex" : ".claude",
107
+ "plugins",
108
+ "cache",
109
+ "local-archive",
110
+ "ts-release"
111
+ )
112
+ const packageRoot = join(providerRoot, version)
113
+ if (existsSync(packageRoot)) fail(`Disposable ${provider} package root already exists: ${packageRoot}`)
114
+ mkdirSync(providerRoot, { recursive: true, mode: 0o700 })
115
+ renameSync(stagedPackage, packageRoot)
116
+ verifyContainedTree(packageRoot)
117
+ return { provider, userRoot, providerRoot, packageRoot, version, entries }
118
+ } finally {
119
+ rmSync(stage, { recursive: true, force: true })
120
+ }
121
+ }
@@ -0,0 +1,56 @@
1
+ import { describe, expect, test } from "bun:test"
2
+ import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs"
3
+ import { join } from "node:path"
4
+ import { tmpdir } from "node:os"
5
+ import { buildAgents } from "../src/build.js"
6
+ import { installAgentArchive } from "../src/install.js"
7
+
8
+ const root = process.cwd()
9
+ const equal = (left: Uint8Array, right: Uint8Array): boolean => left.length === right.length && left.every((byte, index) => byte === right[index])
10
+
11
+ describe("agent distribution contract", () => {
12
+ test("two identical projections are byte-identical", () => {
13
+ const first = buildAgents().map((path) => new Uint8Array(readFileSync(path)))
14
+ const second = buildAgents().map((path) => new Uint8Array(readFileSync(path)))
15
+ expect(first.length).toBe(2)
16
+ expect(first.every((value, index) => equal(value, second[index]!))).toBe(true)
17
+ })
18
+
19
+ test("provider-native generated layouts are contained and versioned", () => {
20
+ for (const provider of ["codex", "claude"]) {
21
+ const native = provider === "codex" ? ".codex-plugin" : ".claude-plugin"
22
+ const manifest = join(root, ".release", "agents", provider, "ts-release", native, "plugin.json")
23
+ expect(existsSync(manifest)).toBe(true)
24
+ expect(JSON.parse(readFileSync(manifest, "utf8")).version).toBe("0.2.2")
25
+ }
26
+ })
27
+
28
+ test("archives install into disposable provider-owned layouts", () => {
29
+ const archives = buildAgents({ archivesOnly: true })
30
+ expect(existsSync(join(root, ".release", "agents", "codex"))).toBe(false)
31
+ expect(existsSync(join(root, ".release", "agents", "claude"))).toBe(false)
32
+ const disposableRoot = mkdtempSync(join(tmpdir(), "ts-release-agent-contract-"))
33
+ try {
34
+ for (const provider of ["codex", "claude"] as const) {
35
+ const archive = archives.find((path) => path.endsWith(`ts-release-${provider}.zip`))
36
+ expect(archive).toBeDefined()
37
+ const installed = installAgentArchive(provider, archive!, disposableRoot)
38
+ expect(installed.providerRoot).toBe(join(
39
+ disposableRoot,
40
+ provider === "codex" ? ".codex" : ".claude",
41
+ "plugins",
42
+ "cache",
43
+ "local-archive",
44
+ "ts-release"
45
+ ))
46
+ expect(installed.version).toBe("0.2.2")
47
+ expect(installed.packageRoot).toBe(join(installed.providerRoot, installed.version))
48
+ expect(existsSync(join(installed.packageRoot, provider === "codex" ? ".codex-plugin" : ".claude-plugin", "plugin.json"))).toBe(true)
49
+ expect(existsSync(join(installed.packageRoot, "skills", "release", "SKILL.md"))).toBe(true)
50
+ expect(installed.entries.every((entry) => entry.startsWith("ts-release/"))).toBe(true)
51
+ }
52
+ } finally {
53
+ rmSync(disposableRoot, { recursive: true, force: true })
54
+ }
55
+ })
56
+ })
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": { "noEmit": true },
4
+ "include": ["src/**/*.ts", "test/**/*.ts"]
5
+ }
@@ -0,0 +1,15 @@
1
+ import type { CompletePreparedReleaseRef } from "../release/prepared-ref.js";
2
+ import { CorrectionReport, type CorrectInput, type InspectInput, type ObserveInput, type PrepareInput, type PublishInput, type ReleaseApi, type ReleaseApiLayer, type ReleaseApiOptions, type ReleaseInput } from "./types.js";
3
+ export type { CorrectInput, InspectInput, ObserveInput, PrepareInput, PublishInput, ReleaseApi, ReleaseApiLayer, ReleaseApiOptions, ReleaseInput } from "./types.js";
4
+ export { CorrectionReport } from "./types.js";
5
+ export { ReleaseInputError } from "./errors.js";
6
+ export { ReleaseRuntime } from "./runtime.js";
7
+ export declare const makeReleaseApi: (layer: ReleaseApiLayer, options?: ReleaseApiOptions) => ReleaseApi;
8
+ export declare const makeDefaultReleaseApi: (layer: ReleaseApiLayer) => ReleaseApi;
9
+ export declare const inspect: (input: InspectInput) => Promise<import("./types.js").InspectOutput>;
10
+ export declare const prepare: (input: PrepareInput) => Promise<CompletePreparedReleaseRef>;
11
+ export declare const observe: (input: ObserveInput) => Promise<import("../publication/report.js").ObservationReport>;
12
+ export declare const publish: (input: PublishInput) => Promise<import("../publication/report.js").ReleaseReport>;
13
+ export declare const release: (input: ReleaseInput) => Promise<import("./types.js").ReleaseResult>;
14
+ export declare const correct: (input: CorrectInput) => Promise<CorrectionReport>;
15
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api/api.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAA;AAsB5E,OAAO,EACL,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAEtB,KAAK,YAAY,EAClB,MAAM,YAAY,CAAA;AAEnB,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,YAAY,EACb,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAmO7C,eAAO,MAAM,cAAc,GAAI,OAAO,eAAe,EAAE,UAAS,iBAAsB,KAAG,UAwDxF,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,OAAO,eAAe,KAAG,UACxC,CAAA;AAIvB,eAAO,MAAM,OAAO,sEAAqB,CAAA;AACzC,eAAO,MAAM,OAAO,8DAAqB,CAAA;AACzC,eAAO,MAAM,OAAO,wFAAqB,CAAA;AACzC,eAAO,MAAM,OAAO,oFAAqB,CAAA;AACzC,eAAO,MAAM,OAAO,sEAAqB,CAAA;AACzC,eAAO,MAAM,OAAO,oDAAqB,CAAA"}