@treeseed/sdk 0.10.28 → 0.12.4

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 (509) hide show
  1. package/README.md +213 -7
  2. package/dist/agent-capacity.d.ts +916 -0
  3. package/dist/agent-capacity.js +1600 -0
  4. package/dist/agent-tools.d.ts +37 -0
  5. package/dist/agent-tools.js +301 -0
  6. package/dist/api/app.d.ts +1 -1
  7. package/dist/api/auth/d1-database.d.ts +2 -2
  8. package/dist/api/auth/d1-provider.d.ts +4 -4
  9. package/dist/api/auth/d1-store.d.ts +2 -2
  10. package/dist/api/auth/memory-provider.d.ts +1 -1
  11. package/dist/api/auth/tokens.d.ts +1 -1
  12. package/dist/api/config.d.ts +3 -1
  13. package/dist/api/config.js +34 -10
  14. package/dist/api/http.d.ts +2 -2
  15. package/dist/api/index.d.ts +10 -10
  16. package/dist/api/index.js +4 -2
  17. package/dist/api/operations-routes.d.ts +3 -3
  18. package/dist/api/operations.d.ts +1 -1
  19. package/dist/api/providers.d.ts +1 -1
  20. package/dist/api/providers.js +21 -4
  21. package/dist/api/railway.d.ts +3 -2
  22. package/dist/api/sdk-dispatch.d.ts +4 -4
  23. package/dist/api/sdk-routes.d.ts +2 -2
  24. package/dist/api/templates.d.ts +2 -2
  25. package/dist/api/types.d.ts +3 -2
  26. package/dist/capacity-provider.d.ts +118 -59
  27. package/dist/capacity-provider.js +235 -43
  28. package/dist/capacity.d.ts +2 -2
  29. package/dist/cli-tools.d.ts +1 -1
  30. package/dist/content-operations.d.ts +97 -0
  31. package/dist/content-operations.js +250 -0
  32. package/dist/content-store.d.ts +4 -4
  33. package/dist/control-plane-client.d.ts +13 -18
  34. package/dist/control-plane-client.js +8 -86
  35. package/dist/control-plane.d.ts +3 -2
  36. package/dist/control-plane.js +38 -13
  37. package/dist/copilot.d.ts +3 -0
  38. package/dist/copilot.js +16 -1
  39. package/dist/d1-http.d.ts +1 -1
  40. package/dist/d1-store.d.ts +32 -57
  41. package/dist/d1-store.js +115 -318
  42. package/dist/db/d1.d.ts +1 -232
  43. package/dist/db/index.d.ts +3 -3
  44. package/dist/db/market-schema.d.ts +50900 -11018
  45. package/dist/db/market-schema.js +2313 -467
  46. package/dist/db/node-sqlite.d.ts +1 -232
  47. package/dist/db/node-sqlite.js +7 -2
  48. package/dist/db/schema.d.ts +0 -462
  49. package/dist/db/schema.js +2 -22
  50. package/dist/dispatch.d.ts +1 -1
  51. package/dist/dispatch.js +0 -11
  52. package/dist/fixture-support.js +52 -4
  53. package/dist/governance.d.ts +133 -0
  54. package/dist/governance.js +285 -0
  55. package/dist/graph/build.d.ts +2 -2
  56. package/dist/graph/context-query-contracts.d.ts +1 -1
  57. package/dist/graph/dsl.d.ts +1 -1
  58. package/dist/graph/query.d.ts +4 -4
  59. package/dist/graph/ranking.d.ts +1 -1
  60. package/dist/graph/schema.d.ts +1 -1
  61. package/dist/graph.d.ts +11 -11
  62. package/dist/guarantees/index.d.ts +425 -0
  63. package/dist/guarantees/index.js +1146 -0
  64. package/dist/hosting/apps.d.ts +12 -0
  65. package/dist/hosting/apps.js +107 -0
  66. package/dist/hosting/builtins.d.ts +25 -0
  67. package/dist/hosting/builtins.js +602 -0
  68. package/dist/hosting/contracts.d.ts +208 -0
  69. package/dist/hosting/contracts.js +0 -0
  70. package/dist/hosting/graph.d.ts +195 -0
  71. package/dist/hosting/graph.js +1092 -0
  72. package/dist/hosting/index.d.ts +4 -0
  73. package/dist/hosting/index.js +4 -0
  74. package/dist/index.d.ts +88 -67
  75. package/dist/index.js +142 -14
  76. package/dist/local-dev/managed-dev.d.ts +85 -0
  77. package/dist/local-dev/managed-dev.js +368 -0
  78. package/dist/managed-dependencies.d.ts +9 -0
  79. package/dist/managed-dependencies.js +10 -9
  80. package/dist/market-client.d.ts +327 -9
  81. package/dist/market-client.js +464 -20
  82. package/dist/model-registry.d.ts +1 -1
  83. package/dist/model-registry.js +19 -19
  84. package/dist/operations/agent-tools.d.ts +2 -11
  85. package/dist/operations/agent-tools.js +2 -14
  86. package/dist/operations/providers/default.d.ts +1 -1
  87. package/dist/operations/providers/default.js +20 -37
  88. package/dist/operations/repository-operations.d.ts +26 -2
  89. package/dist/operations/repository-operations.js +159 -1
  90. package/dist/operations/runtime.d.ts +3 -3
  91. package/dist/operations/services/bootstrap-runner.d.ts +4 -2
  92. package/dist/operations/services/bootstrap-runner.js +22 -2
  93. package/dist/operations/services/build-warning-policy.d.ts +34 -0
  94. package/dist/operations/services/build-warning-policy.js +81 -82
  95. package/dist/operations/services/commit-message-provider.js +4 -4
  96. package/dist/operations/services/config-runtime.d.ts +83 -24
  97. package/dist/operations/services/config-runtime.js +449 -130
  98. package/dist/operations/services/deploy.d.ts +106 -624
  99. package/dist/operations/services/deploy.js +746 -263
  100. package/dist/operations/services/deployment-readiness.d.ts +30 -0
  101. package/dist/operations/services/deployment-readiness.js +206 -0
  102. package/dist/operations/services/git-remote-policy.js +12 -4
  103. package/dist/operations/services/git-runner.d.ts +66 -0
  104. package/dist/operations/services/git-runner.js +479 -0
  105. package/dist/operations/services/git-workflow.d.ts +45 -6
  106. package/dist/operations/services/git-workflow.js +251 -23
  107. package/dist/operations/services/github-actions-verification.d.ts +4 -1
  108. package/dist/operations/services/github-actions-verification.js +12 -3
  109. package/dist/operations/services/github-api.js +22 -6
  110. package/dist/operations/services/github-automation.d.ts +4 -4
  111. package/dist/operations/services/github-automation.js +19 -21
  112. package/dist/operations/services/github-credentials.d.ts +13 -0
  113. package/dist/operations/services/github-credentials.js +59 -0
  114. package/dist/operations/services/hosted-service-checks.d.ts +81 -0
  115. package/dist/operations/services/hosted-service-checks.js +478 -0
  116. package/dist/operations/services/hosting-audit.d.ts +2 -2
  117. package/dist/operations/services/hosting-audit.js +7 -7
  118. package/dist/operations/services/hub-launch.d.ts +1 -1
  119. package/dist/operations/services/hub-provider-launch.d.ts +5 -5
  120. package/dist/operations/services/hub-provider-launch.js +22 -17
  121. package/dist/operations/services/live-hosted-service-checks.d.ts +26 -0
  122. package/dist/operations/services/live-hosted-service-checks.js +463 -0
  123. package/dist/operations/services/local-dev.js +0 -1
  124. package/dist/operations/services/managed-host-security.d.ts +1 -1
  125. package/dist/operations/services/managed-host-security.js +1 -1
  126. package/dist/operations/services/managed-repositories.d.ts +37 -0
  127. package/dist/operations/services/managed-repositories.js +177 -0
  128. package/dist/operations/services/operations-runner-smoke.d.ts +31 -0
  129. package/dist/operations/services/operations-runner-smoke.js +198 -0
  130. package/dist/operations/services/package-adapters.d.ts +170 -0
  131. package/dist/operations/services/package-adapters.js +859 -0
  132. package/dist/operations/services/package-reference-policy.d.ts +13 -88
  133. package/dist/operations/services/package-reference-policy.js +96 -215
  134. package/dist/operations/services/project-host-operations.d.ts +4 -4
  135. package/dist/operations/services/project-platform.d.ts +57 -173
  136. package/dist/operations/services/project-platform.js +80 -111
  137. package/dist/operations/services/project-web-monitor.d.ts +2 -2
  138. package/dist/operations/services/project-web-monitor.js +122 -5
  139. package/dist/operations/services/railway-api.d.ts +117 -5
  140. package/dist/operations/services/railway-api.js +915 -93
  141. package/dist/operations/services/railway-deploy.d.ts +30 -112
  142. package/dist/operations/services/railway-deploy.js +521 -961
  143. package/dist/operations/services/release-history.js +3 -4
  144. package/dist/operations/services/release-proof-ledger.d.ts +13 -0
  145. package/dist/operations/services/release-proof-ledger.js +81 -0
  146. package/dist/operations/services/release-proof-planner.d.ts +48 -0
  147. package/dist/operations/services/release-proof-planner.js +195 -0
  148. package/dist/operations/services/release-proof-runner.d.ts +16 -0
  149. package/dist/operations/services/release-proof-runner.js +169 -0
  150. package/dist/operations/services/release-proof.d.ts +81 -0
  151. package/dist/operations/services/release-proof.js +79 -0
  152. package/dist/operations/services/repository-save-orchestrator.d.ts +8 -7
  153. package/dist/operations/services/repository-save-orchestrator.js +604 -212
  154. package/dist/operations/services/runtime-paths.d.ts +1 -3
  155. package/dist/operations/services/runtime-paths.js +0 -4
  156. package/dist/operations/services/runtime-tools.d.ts +1 -191
  157. package/dist/operations/services/runtime-tools.js +4 -443
  158. package/dist/operations/services/save-deploy-preflight.js +9 -1
  159. package/dist/operations/services/template-host-bindings.d.ts +2 -2
  160. package/dist/operations/services/template-host-bindings.js +3 -2
  161. package/dist/operations/services/template-registry.d.ts +6 -6
  162. package/dist/operations/services/template-registry.js +33 -14
  163. package/dist/operations/services/template-secret-sync.d.ts +3 -3
  164. package/dist/operations/services/verification-cache.d.ts +25 -0
  165. package/dist/operations/services/verification-cache.js +71 -0
  166. package/dist/operations/services/workflow-timing.d.ts +25 -0
  167. package/dist/operations/services/workflow-timing.js +79 -0
  168. package/dist/operations/services/workspace-dependency-mode.js +50 -5
  169. package/dist/operations/services/workspace-preflight.js +8 -8
  170. package/dist/operations/services/workspace-save-script.d.ts +4 -4
  171. package/dist/operations/services/workspace-save.d.ts +1 -0
  172. package/dist/operations/services/workspace-save.js +42 -19
  173. package/dist/operations/services/workspace-tools.js +42 -7
  174. package/dist/operations-registry.d.ts +1 -1
  175. package/dist/operations-registry.js +5 -6
  176. package/dist/operations-types.d.ts +1 -1
  177. package/dist/operations.d.ts +17 -11
  178. package/dist/operations.js +57 -3
  179. package/dist/platform/book-export.js +2 -0
  180. package/dist/platform/books-data.d.ts +1 -1
  181. package/dist/platform/config.d.ts +27 -0
  182. package/dist/platform/config.js +100 -0
  183. package/dist/platform/content-runtime-source.d.ts +54 -0
  184. package/dist/platform/content-runtime-source.js +169 -0
  185. package/dist/platform/contracts.d.ts +38 -2
  186. package/dist/platform/deploy-config.d.ts +1 -1
  187. package/dist/platform/deploy-config.js +80 -9
  188. package/dist/platform/deploy-runtime.d.ts +1 -1
  189. package/dist/platform/desired-state.d.ts +63 -0
  190. package/dist/platform/desired-state.js +1021 -0
  191. package/dist/platform/env.yaml +568 -45
  192. package/dist/platform/environment.d.ts +3 -2
  193. package/dist/platform/environment.js +122 -21
  194. package/dist/platform/local-content-materialization.d.ts +9 -0
  195. package/dist/platform/local-content-materialization.js +212 -0
  196. package/dist/platform/plugin.d.ts +13 -4
  197. package/dist/platform/plugins/runtime.d.ts +3 -3
  198. package/dist/platform/plugins/runtime.js +62 -1
  199. package/dist/platform/plugins.d.ts +6 -6
  200. package/dist/platform/published-content-pipeline.d.ts +3 -3
  201. package/dist/platform/published-content-pipeline.js +5 -1
  202. package/dist/platform/published-content.d.ts +4 -3
  203. package/dist/platform/site-config-schema.d.ts +1 -0
  204. package/dist/platform/site-config-schema.js +4 -1
  205. package/dist/platform/tenant/runtime-config.d.ts +152 -2
  206. package/dist/platform/tenant-config.d.ts +1 -1
  207. package/dist/platform/utils/site-config-schema.d.ts +154 -0
  208. package/dist/platform/utils/site-config-schema.js +400 -461
  209. package/dist/platform-operation-store.d.ts +1 -1
  210. package/dist/platform-operation-store.js +2 -2
  211. package/dist/platform-operations.js +1 -1
  212. package/dist/plugin-default.d.ts +1 -1
  213. package/dist/plugin-default.js +27 -12
  214. package/dist/project-import.d.ts +91 -0
  215. package/dist/project-import.js +257 -0
  216. package/dist/project-workflow.d.ts +1 -1
  217. package/dist/reconcile/bootstrap-systems.d.ts +2 -2
  218. package/dist/reconcile/bootstrap-systems.js +5 -5
  219. package/dist/reconcile/builtin-adapters.d.ts +7 -1
  220. package/dist/reconcile/builtin-adapters.js +3190 -429
  221. package/dist/reconcile/contracts.d.ts +23 -6
  222. package/dist/reconcile/desired-state.d.ts +2 -192
  223. package/dist/reconcile/desired-state.js +29 -38
  224. package/dist/reconcile/engine.d.ts +61 -395
  225. package/dist/reconcile/engine.js +229 -44
  226. package/dist/reconcile/index.d.ts +10 -8
  227. package/dist/reconcile/index.js +2 -0
  228. package/dist/reconcile/live-acceptance.d.ts +100 -0
  229. package/dist/reconcile/live-acceptance.js +2027 -0
  230. package/dist/reconcile/platform.d.ts +104 -0
  231. package/dist/reconcile/platform.js +100 -0
  232. package/dist/reconcile/providers/docker-private.d.ts +54 -0
  233. package/dist/reconcile/providers/docker-private.js +101 -0
  234. package/dist/reconcile/providers/github-private.d.ts +65 -0
  235. package/dist/reconcile/providers/github-private.js +119 -0
  236. package/dist/reconcile/providers/local-private.d.ts +28 -0
  237. package/dist/reconcile/providers/local-private.js +75 -0
  238. package/dist/reconcile/providers/railway-iac.d.ts +66 -0
  239. package/dist/reconcile/providers/railway-iac.js +275 -0
  240. package/dist/reconcile/providers/release-private.d.ts +92 -0
  241. package/dist/reconcile/providers/release-private.js +152 -0
  242. package/dist/reconcile/registry.d.ts +2 -2
  243. package/dist/reconcile/registry.js +16 -1
  244. package/dist/reconcile/state.d.ts +1 -1
  245. package/dist/reconcile/state.js +7 -44
  246. package/dist/reconcile/units.d.ts +1 -1
  247. package/dist/reconcile/units.js +9 -3
  248. package/dist/remote.d.ts +6 -6
  249. package/dist/scenes/artifacts.d.ts +16 -0
  250. package/dist/scenes/artifacts.js +61 -0
  251. package/dist/scenes/auth.d.ts +2 -0
  252. package/dist/scenes/auth.js +28 -0
  253. package/dist/scenes/base-url.d.ts +12 -0
  254. package/dist/scenes/base-url.js +123 -0
  255. package/dist/scenes/builtin-plugins.d.ts +2 -0
  256. package/dist/scenes/builtin-plugins.js +447 -0
  257. package/dist/scenes/checkpoints.d.ts +14 -0
  258. package/dist/scenes/checkpoints.js +33 -0
  259. package/dist/scenes/device-matrix.d.ts +2 -0
  260. package/dist/scenes/device-matrix.js +97 -0
  261. package/dist/scenes/devices.d.ts +11 -0
  262. package/dist/scenes/devices.js +22 -0
  263. package/dist/scenes/diagnostics.d.ts +5 -0
  264. package/dist/scenes/diagnostics.js +22 -0
  265. package/dist/scenes/diagram-providers.d.ts +2 -0
  266. package/dist/scenes/diagram-providers.js +181 -0
  267. package/dist/scenes/diagram-validation.d.ts +22 -0
  268. package/dist/scenes/diagram-validation.js +74 -0
  269. package/dist/scenes/environment.d.ts +2 -0
  270. package/dist/scenes/environment.js +65 -0
  271. package/dist/scenes/evidence-bundle.d.ts +5 -0
  272. package/dist/scenes/evidence-bundle.js +42 -0
  273. package/dist/scenes/evidence-report.d.ts +10 -0
  274. package/dist/scenes/evidence-report.js +73 -0
  275. package/dist/scenes/evidence.d.ts +16 -0
  276. package/dist/scenes/evidence.js +277 -0
  277. package/dist/scenes/index.d.ts +48 -0
  278. package/dist/scenes/index.js +312 -0
  279. package/dist/scenes/inspect.d.ts +9 -0
  280. package/dist/scenes/inspect.js +64 -0
  281. package/dist/scenes/loader.d.ts +3 -0
  282. package/dist/scenes/loader.js +38 -0
  283. package/dist/scenes/logs.d.ts +2 -0
  284. package/dist/scenes/logs.js +47 -0
  285. package/dist/scenes/operations.d.ts +3 -0
  286. package/dist/scenes/operations.js +128 -0
  287. package/dist/scenes/phase0.d.ts +9 -0
  288. package/dist/scenes/phase0.js +637 -0
  289. package/dist/scenes/planner.d.ts +12 -0
  290. package/dist/scenes/planner.js +166 -0
  291. package/dist/scenes/playwright-adapter.d.ts +2 -0
  292. package/dist/scenes/playwright-adapter.js +63 -0
  293. package/dist/scenes/plugins.d.ts +5 -0
  294. package/dist/scenes/plugins.js +115 -0
  295. package/dist/scenes/progress.d.ts +17 -0
  296. package/dist/scenes/progress.js +24 -0
  297. package/dist/scenes/publish-destinations.d.ts +12 -0
  298. package/dist/scenes/publish-destinations.js +99 -0
  299. package/dist/scenes/publish-plan-report.d.ts +10 -0
  300. package/dist/scenes/publish-plan-report.js +70 -0
  301. package/dist/scenes/publish-plan.d.ts +15 -0
  302. package/dist/scenes/publish-plan.js +248 -0
  303. package/dist/scenes/publish-redaction.d.ts +16 -0
  304. package/dist/scenes/publish-redaction.js +148 -0
  305. package/dist/scenes/publish-release-record.d.ts +13 -0
  306. package/dist/scenes/publish-release-record.js +34 -0
  307. package/dist/scenes/publish-report.d.ts +10 -0
  308. package/dist/scenes/publish-report.js +67 -0
  309. package/dist/scenes/publish.d.ts +16 -0
  310. package/dist/scenes/publish.js +298 -0
  311. package/dist/scenes/registry.d.ts +12 -0
  312. package/dist/scenes/registry.js +65 -0
  313. package/dist/scenes/remotion-adapter.d.ts +3 -0
  314. package/dist/scenes/remotion-adapter.js +94 -0
  315. package/dist/scenes/remotion-composition-registry.d.ts +2 -0
  316. package/dist/scenes/remotion-composition-registry.js +12 -0
  317. package/dist/scenes/remotion-compositions.d.ts +15 -0
  318. package/dist/scenes/remotion-compositions.js +464 -0
  319. package/dist/scenes/remotion-diagrams.d.ts +9 -0
  320. package/dist/scenes/remotion-diagrams.js +188 -0
  321. package/dist/scenes/remotion-input.d.ts +13 -0
  322. package/dist/scenes/remotion-input.js +291 -0
  323. package/dist/scenes/remotion-visuals.d.ts +29 -0
  324. package/dist/scenes/remotion-visuals.js +198 -0
  325. package/dist/scenes/render-media-assets.d.ts +9 -0
  326. package/dist/scenes/render-media-assets.js +117 -0
  327. package/dist/scenes/render-report.d.ts +10 -0
  328. package/dist/scenes/render-report.js +27 -0
  329. package/dist/scenes/render.d.ts +2 -0
  330. package/dist/scenes/render.js +218 -0
  331. package/dist/scenes/reporter.d.ts +3 -0
  332. package/dist/scenes/reporter.js +101 -0
  333. package/dist/scenes/resume.d.ts +2 -0
  334. package/dist/scenes/resume.js +79 -0
  335. package/dist/scenes/runner.d.ts +2 -0
  336. package/dist/scenes/runner.js +674 -0
  337. package/dist/scenes/schema.d.ts +6 -0
  338. package/dist/scenes/schema.js +994 -0
  339. package/dist/scenes/seed.d.ts +2 -0
  340. package/dist/scenes/seed.js +83 -0
  341. package/dist/scenes/segments.d.ts +15 -0
  342. package/dist/scenes/segments.js +79 -0
  343. package/dist/scenes/selectors.d.ts +3 -0
  344. package/dist/scenes/selectors.js +21 -0
  345. package/dist/scenes/timeline.d.ts +11 -0
  346. package/dist/scenes/timeline.js +26 -0
  347. package/dist/scenes/timeouts.d.ts +6 -0
  348. package/dist/scenes/timeouts.js +17 -0
  349. package/dist/scenes/training-captions.d.ts +14 -0
  350. package/dist/scenes/training-captions.js +98 -0
  351. package/dist/scenes/training-report.d.ts +10 -0
  352. package/dist/scenes/training-report.js +78 -0
  353. package/dist/scenes/training-transcript.d.ts +24 -0
  354. package/dist/scenes/training-transcript.js +204 -0
  355. package/dist/scenes/training.d.ts +10 -0
  356. package/dist/scenes/training.js +134 -0
  357. package/dist/scenes/types.d.ts +1872 -0
  358. package/dist/scenes/types.js +8 -0
  359. package/dist/scenes/visual-audit-contact-sheets.d.ts +6 -0
  360. package/dist/scenes/visual-audit-contact-sheets.js +119 -0
  361. package/dist/scenes/visual-audit-fixtures.d.ts +25 -0
  362. package/dist/scenes/visual-audit-fixtures.js +210 -0
  363. package/dist/scenes/visual-audit-report.d.ts +11 -0
  364. package/dist/scenes/visual-audit-report.js +85 -0
  365. package/dist/scenes/visual-audit-review.d.ts +23 -0
  366. package/dist/scenes/visual-audit-review.js +829 -0
  367. package/dist/scenes/visual-audit-routes.d.ts +13 -0
  368. package/dist/scenes/visual-audit-routes.js +308 -0
  369. package/dist/scenes/visual-audit.d.ts +3 -0
  370. package/dist/scenes/visual-audit.js +596 -0
  371. package/dist/scripts/build-dist.js +154 -40
  372. package/dist/scripts/check-build-warnings.js +42 -53
  373. package/dist/scripts/cleanup-markdown.js +1 -1
  374. package/dist/scripts/cli-test-fixtures.js +24 -28
  375. package/dist/scripts/deployment-readiness.js +20 -0
  376. package/dist/scripts/generate-treedx-openapi-types.js +186 -0
  377. package/dist/scripts/migrate-journey-csv-to-guarantees.js +140 -0
  378. package/dist/scripts/operations-runner-smoke.js +16 -0
  379. package/dist/scripts/package-tools.js +12 -1
  380. package/dist/scripts/prepare.js +3 -7
  381. package/dist/scripts/release-verify.js +6 -6
  382. package/dist/scripts/run-fixture-astro-command.js +1 -1
  383. package/dist/scripts/template-catalog.test.js +68 -82
  384. package/dist/scripts/tenant-dev.js +0 -10
  385. package/dist/scripts/tenant-workflow-action.js +10 -1
  386. package/dist/scripts/test-cloudflare-local.js +1 -1
  387. package/dist/scripts/test-scaffold.js +0 -1
  388. package/dist/scripts/test-smoke.js +3 -3
  389. package/dist/scripts/treeseed-build-dist.js +4 -7
  390. package/dist/scripts/treeseed-release-verify.js +1 -1
  391. package/dist/scripts/verify-driver.js +30 -21
  392. package/dist/scripts/workflow-commands.test.js +18 -27
  393. package/dist/scripts/workspace-command-e2e.js +1 -1
  394. package/dist/scripts/workspace-lint.js +6 -0
  395. package/dist/scripts/workspace-release-test.js +90 -1
  396. package/dist/scripts/workspace-test.js +6 -0
  397. package/dist/sdk-dispatch.d.ts +1 -1
  398. package/dist/sdk-dispatch.js +0 -16
  399. package/dist/sdk-fields.d.ts +1 -1
  400. package/dist/sdk-filters.d.ts +1 -1
  401. package/dist/sdk-types.d.ts +1352 -116
  402. package/dist/sdk-types.js +413 -2
  403. package/dist/sdk.d.ts +106 -100
  404. package/dist/sdk.js +211 -51
  405. package/dist/secrets-capability.d.ts +421 -0
  406. package/dist/secrets-capability.js +530 -0
  407. package/dist/seeds/normalize.js +1 -0
  408. package/dist/seeds/planner.js +38 -0
  409. package/dist/seeds/schema.js +293 -4
  410. package/dist/seeds/types.d.ts +60 -0
  411. package/dist/seeds/types.js +9 -1
  412. package/dist/service-credentials.d.ts +54 -0
  413. package/dist/service-credentials.js +112 -0
  414. package/dist/stores/cursor-store.d.ts +2 -2
  415. package/dist/stores/envelopes.d.ts +1 -1
  416. package/dist/stores/helpers.d.ts +1 -1
  417. package/dist/stores/lease-store.d.ts +2 -2
  418. package/dist/stores/message-store.d.ts +2 -2
  419. package/dist/stores/operational-store.d.ts +3 -26
  420. package/dist/stores/operational-store.js +0 -225
  421. package/dist/stores/project-workflow-store.d.ts +2 -2
  422. package/dist/stores/run-store.d.ts +2 -3
  423. package/dist/stores/run-store.js +0 -98
  424. package/dist/stores/subscription-store.d.ts +2 -3
  425. package/dist/stores/subscription-store.js +0 -100
  426. package/dist/template-catalog.d.ts +1 -1
  427. package/dist/template-launch-requirements.d.ts +2 -2
  428. package/dist/template-launch-requirements.js +9 -0
  429. package/dist/template-launch-ui.d.ts +2 -2
  430. package/dist/treedx/adapters.d.ts +6 -0
  431. package/dist/treedx/adapters.js +36 -0
  432. package/dist/treedx/client.d.ts +222 -0
  433. package/dist/treedx/client.js +871 -0
  434. package/dist/treedx/errors.d.ts +13 -0
  435. package/dist/treedx/errors.js +17 -0
  436. package/dist/treedx/federated-client.d.ts +27 -0
  437. package/dist/treedx/federated-client.js +158 -0
  438. package/dist/treedx/generated/openapi-types.d.ts +3558 -0
  439. package/dist/treedx/generated/openapi-types.js +0 -0
  440. package/dist/treedx/graph-adapter.d.ts +33 -0
  441. package/dist/treedx/graph-adapter.js +156 -0
  442. package/dist/treedx/index.d.ts +14 -0
  443. package/dist/treedx/index.js +48 -0
  444. package/dist/treedx/market-integration.d.ts +27 -0
  445. package/dist/treedx/market-integration.js +131 -0
  446. package/dist/treedx/ports.d.ts +166 -0
  447. package/dist/treedx/ports.js +231 -0
  448. package/dist/treedx/query-adapter.d.ts +19 -0
  449. package/dist/treedx/query-adapter.js +62 -0
  450. package/dist/treedx/registry-client.d.ts +11 -0
  451. package/dist/treedx/registry-client.js +19 -0
  452. package/dist/treedx/repository-adapter.d.ts +45 -0
  453. package/dist/treedx/repository-adapter.js +319 -0
  454. package/dist/treedx/sdk-integration.d.ts +27 -0
  455. package/dist/treedx/sdk-integration.js +63 -0
  456. package/dist/treedx/types.d.ts +1084 -0
  457. package/dist/treedx/types.js +8 -0
  458. package/dist/treedx/workspace-adapter.d.ts +27 -0
  459. package/dist/treedx/workspace-adapter.js +65 -0
  460. package/dist/treedx-backends.d.ts +220 -0
  461. package/dist/treedx-backends.js +634 -0
  462. package/dist/treedx-client.d.ts +89 -0
  463. package/dist/treedx-client.js +184 -0
  464. package/dist/treeseed/services/compose.yml +2 -3
  465. package/dist/treeseed/template-catalog/catalog.fixture.json +27 -27
  466. package/dist/types/agents.d.ts +256 -0
  467. package/dist/types/agents.js +42 -1
  468. package/dist/verification.d.ts +1 -0
  469. package/dist/verification.js +143 -14
  470. package/dist/workflow/operations.d.ts +580 -523
  471. package/dist/workflow/operations.js +2084 -1279
  472. package/dist/workflow/policy.js +19 -7
  473. package/dist/workflow/runs.d.ts +9 -3
  474. package/dist/workflow/runs.js +66 -26
  475. package/dist/workflow/session.d.ts +4 -1
  476. package/dist/workflow/session.js +50 -10
  477. package/dist/workflow/worktrees.d.ts +6 -2
  478. package/dist/workflow/worktrees.js +98 -15
  479. package/dist/workflow-state.d.ts +17 -4
  480. package/dist/workflow-state.js +68 -41
  481. package/dist/workflow-support.d.ts +26 -17
  482. package/dist/workflow-support.js +84 -24
  483. package/dist/workflow.d.ts +51 -16
  484. package/dist/workflow.js +19 -7
  485. package/drizzle/d1/0000_treeseed_d1.sql +0 -18
  486. package/drizzle/market/0000_market_control_plane.sql +1793 -1499
  487. package/drizzle/market/0004_treedx_market_integration.sql +99 -0
  488. package/drizzle/market/0005_agent_capacity_coordination.sql +145 -0
  489. package/drizzle/market/0006_provider_assignment_lifecycle.sql +9 -0
  490. package/drizzle/market/0007_agent_architecture_gap_closure.sql +157 -0
  491. package/drizzle/market/0008_agent_capacity_operational_closure.sql +27 -0
  492. package/drizzle/market/0009_agent_capacity_runtime_hardening.sql +29 -0
  493. package/drizzle/market/0010_secrets_capability_persistence.sql +130 -0
  494. package/drizzle/market/0011_github_app_adapter.sql +47 -0
  495. package/drizzle/market/0012_workday_test_runs.sql +44 -0
  496. package/drizzle/market/0013_runtime_task_lifecycle.sql +39 -0
  497. package/drizzle/market/0014_governance_pipeline.sql +189 -0
  498. package/package.json +106 -18
  499. package/scripts/{verify-driver.mjs → verify-driver.ts} +19 -4
  500. package/templates/github/deploy-web.workflow.yml +49 -12
  501. package/dist/operations/services/mailpit-runtime.d.ts +0 -20
  502. package/dist/operations/services/mailpit-runtime.js +0 -67
  503. package/dist/operations/services/release-candidate.d.ts +0 -41
  504. package/dist/operations/services/release-candidate.js +0 -616
  505. package/dist/scripts/ensure-mailpit.js +0 -48
  506. package/dist/scripts/logs-mailpit.js +0 -2
  507. package/dist/scripts/run-ts.js +0 -45
  508. package/dist/scripts/stop-mailpit.js +0 -5
  509. package/dist/scripts/treeseed-run-ts.js +0 -45
@@ -0,0 +1,859 @@
1
+ import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
2
+ import { dirname, relative, resolve } from "node:path";
3
+ import { parse as parseYaml } from "yaml";
4
+ import { workspacePackages, workspaceRoot } from "./workspace-tools.js";
5
+ import { runTreeseedGit } from "./git-runner.js";
6
+ import { resolveTreeseedLaunchEnvironment } from "./config-runtime.js";
7
+ import { resolveGitHubCredentialForRepository } from "./github-credentials.js";
8
+ import {
9
+ createGitHubApiClient,
10
+ getLatestGitHubWorkflowRun
11
+ } from "./github-api.js";
12
+ import { resolveTreeseedDockerhubToken, resolveTreeseedDockerhubUsername } from "../../service-credentials.js";
13
+ import { inspectTreeseedContentStructure } from "../../platform/content-runtime-source.js";
14
+ import {
15
+ SEED_CONTENT_PUBLISH_TARGETS,
16
+ SEED_CONTENT_RUNTIME_SOURCES,
17
+ SEED_LOCAL_CONTENT_MATERIALIZATIONS,
18
+ SEED_PROJECT_TOPOLOGIES
19
+ } from "../../seeds/types.js";
20
+ function readJsonFile(filePath) {
21
+ try {
22
+ return JSON.parse(readFileSync(filePath, "utf8"));
23
+ } catch {
24
+ return null;
25
+ }
26
+ }
27
+ function readStructuredFile(filePath) {
28
+ try {
29
+ const raw = readFileSync(filePath, "utf8");
30
+ return filePath.endsWith(".yaml") || filePath.endsWith(".yml") ? parseYaml(raw) : JSON.parse(raw);
31
+ } catch {
32
+ return null;
33
+ }
34
+ }
35
+ function readPackageJsonVersion(filePath) {
36
+ const packageJson = readJsonFile(filePath);
37
+ return typeof packageJson?.version === "string" ? packageJson.version : null;
38
+ }
39
+ function normalizeGitHubRepositorySlug(value) {
40
+ const raw = typeof value === "string" ? value : value && typeof value === "object" && !Array.isArray(value) ? value.url : null;
41
+ if (typeof raw !== "string" || !raw.trim()) return null;
42
+ const normalized = raw.trim().replace(/^git\+/u, "").replace(/^ssh:\/\/git@github\.com[:/]/u, "").replace(/^git@github\.com:/u, "").replace(/^https:\/\/github\.com\//u, "").replace(/\.git$/u, "").replace(/\/$/u, "");
43
+ return /^[^/\s]+\/[^/\s]+$/u.test(normalized) ? normalized : null;
44
+ }
45
+ function readMixProjectVersion(filePath) {
46
+ if (!existsSync(filePath)) return null;
47
+ const source = readFileSync(filePath, "utf8");
48
+ const match = source.match(/\bversion:\s*"([^"]+)"/u);
49
+ return match?.[1] ?? null;
50
+ }
51
+ function commandFromScript(dir, script, label) {
52
+ if (typeof script !== "string" || !script.trim()) return null;
53
+ const trimmed = script.trim();
54
+ if (trimmed.startsWith("scripts/")) {
55
+ return { label, command: "bash", args: [trimmed], cwd: dir };
56
+ }
57
+ return { label, command: "bash", args: ["-lc", trimmed], cwd: dir };
58
+ }
59
+ function normalizePackageSlug(id) {
60
+ const raw = id.startsWith("@treeseed/") ? id.slice("@treeseed/".length) : id;
61
+ return raw.toLowerCase().replace(/^treeseed-/u, "").replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "") || "package";
62
+ }
63
+ function enumValue(value, allowed, fallback) {
64
+ return typeof value === "string" && allowed.includes(value) ? value : fallback;
65
+ }
66
+ function normalizeTreeseedPackageProjectArchitecture(value, packageId) {
67
+ const record = stringRecord(value);
68
+ if (Object.keys(record).length === 0) return null;
69
+ const publishTarget = stringRecord(record.contentPublishTarget);
70
+ const packageSlug = normalizePackageSlug(packageId);
71
+ const targetKind = enumValue(publishTarget.kind, SEED_CONTENT_PUBLISH_TARGETS, "cloudflare_r2");
72
+ return {
73
+ topology: enumValue(record.topology, SEED_PROJECT_TOPOLOGIES, "single_repository_site"),
74
+ rootPath: stringValue(record.rootPath) ?? ".",
75
+ sitePath: stringValue(record.sitePath) ?? "docs",
76
+ contentPath: stringValue(record.contentPath) ?? "docs",
77
+ contentRuntimeSource: enumValue(record.contentRuntimeSource, SEED_CONTENT_RUNTIME_SOURCES, "r2_published_manifest"),
78
+ localContentMaterialization: enumValue(record.localContentMaterialization, SEED_LOCAL_CONTENT_MATERIALIZATIONS, "none"),
79
+ contentPublishTarget: {
80
+ kind: targetKind,
81
+ ...stringValue(publishTarget.bucket) ? { bucket: stringValue(publishTarget.bucket) } : {},
82
+ prefix: stringValue(publishTarget.prefix) ?? `packages/${packageSlug}`,
83
+ ...stringValue(publishTarget.manifestPath) ? { manifestPath: stringValue(publishTarget.manifestPath) } : {}
84
+ }
85
+ };
86
+ }
87
+ function docsSiteReadiness(dir, architecture) {
88
+ if (!architecture) return null;
89
+ const diagnostic = inspectTreeseedContentStructure({ projectRoot: dir, architecture });
90
+ const readiness = diagnostic.status === "ready" ? "ready" : diagnostic.status === "unsupported_structure" ? "unsupported_structure" : "site_not_prepared";
91
+ return {
92
+ status: readiness,
93
+ diagnostic
94
+ };
95
+ }
96
+ function deploymentSourceModeForBranch(metadata, branch) {
97
+ const source = stringRecord(metadata.deploymentSource);
98
+ const normalizedBranch = branch === "prod" || branch === "production" || branch === "main" ? "prod" : branch === "staging" ? "staging" : "local";
99
+ const configured = stringValue(source[normalizedBranch]);
100
+ return configured === "git" || configured === "image" ? configured : normalizedBranch === "prod" ? "image" : stringValue(source.staging) === "git" ? "git" : null;
101
+ }
102
+ function nodeTypeScriptAdapter(pkg) {
103
+ const manifest = readTreeseedPackageManifest(pkg.dir);
104
+ const scripts = pkg.packageJson?.scripts && typeof pkg.packageJson.scripts === "object" && !Array.isArray(pkg.packageJson.scripts) ? pkg.packageJson.scripts : {};
105
+ const manifestVerify = manifest?.verify && typeof manifest.verify === "object" && !Array.isArray(manifest.verify) ? manifest.verify : {};
106
+ const repository = stringValue(manifest?.repository) ?? normalizeGitHubRepositorySlug(pkg.packageJson?.repository);
107
+ const id = stringValue(manifest?.id) ?? String(pkg.name);
108
+ const name = stringValue(manifest?.name) ?? String(pkg.name);
109
+ const dockerArtifacts = manifestDockerArtifacts(manifest?.artifacts);
110
+ const dockerImages = stringRecord(manifest?.dockerImages);
111
+ const dockerImageReleaseWorkflow = stringValue(dockerImages.releaseWorkflow);
112
+ const dockerImageArchitectures = stringArray(dockerImages.architectures);
113
+ const publishTargetRaw = stringValue(manifest?.publishTarget);
114
+ const publishTarget = dockerArtifacts.length > 0 && publishTargetRaw === "docker" ? dockerArtifacts[0].name : publishTargetRaw ?? "npm";
115
+ const hostedVerifyWorkflow = stringValue(manifest?.hostedVerifyWorkflow) ?? stringValue(stringRecord(manifest?.releaseGate).workflow) ?? (existsSync(resolve(pkg.dir, ".github/workflows/deploy.yml")) ? "deploy.yml" : null);
116
+ const projectArchitecture = normalizeTreeseedPackageProjectArchitecture(manifest?.projectArchitecture, id);
117
+ const docsReadiness = docsSiteReadiness(pkg.dir, projectArchitecture);
118
+ const verifyLocal = typeof scripts["verify:local"] === "string" ? "verify:local" : typeof scripts.verify === "string" ? "verify" : typeof scripts["verify:action"] === "string" ? "verify:action" : null;
119
+ return {
120
+ id,
121
+ name,
122
+ kind: "node-typescript",
123
+ dir: pkg.dir,
124
+ relativeDir: pkg.relativeDir,
125
+ version: typeof pkg.packageJson?.version === "string" ? pkg.packageJson.version : null,
126
+ publishTarget,
127
+ manifestPath: treeseedPackageManifestPath(pkg.dir) ?? resolve(pkg.dir, "package.json"),
128
+ versionSource: resolve(pkg.dir, "package.json"),
129
+ verifyCommands: {
130
+ fast: commandFromScript(pkg.dir, manifestVerify.fast, "fast") ?? (typeof scripts.verify === "string" ? { label: "verify", command: "npm", args: ["run", "verify"], cwd: pkg.dir } : null),
131
+ local: commandFromScript(pkg.dir, manifestVerify.local, "local") ?? (verifyLocal ? { label: verifyLocal, command: "npm", args: ["run", verifyLocal], cwd: pkg.dir } : null),
132
+ release: commandFromScript(pkg.dir, manifestVerify.release, "release") ?? (typeof scripts["release:publish"] === "string" ? { label: "release:publish", command: "npm", args: ["run", "release:publish"], cwd: pkg.dir } : null)
133
+ },
134
+ artifacts: dockerArtifacts.length > 0 ? dockerArtifacts.map((artifact) => ({
135
+ provider: "docker",
136
+ name: artifact.name,
137
+ dockerfile: artifact.dockerfile,
138
+ context: artifact.context,
139
+ target: artifact.target,
140
+ role: artifact.role,
141
+ architectures: artifact.architectures
142
+ })) : [{ provider: "npm", name: String(pkg.name) }],
143
+ releaseChecks: [
144
+ { kind: "github-workflow", name: "publish workflow", detail: dockerImageReleaseWorkflow ? `.github/workflows/${dockerImageReleaseWorkflow}` : ".github/workflows/publish.yml" },
145
+ ...dockerArtifacts.length > 0 ? dockerArtifacts.map((artifact) => ({ kind: "docker-manifest", name: `${artifact.name} Docker image manifest`, detail: `${artifact.name}:<version>` })) : [{ kind: "npm-pack-dry-run", name: "npm pack", detail: "npm pack --dry-run" }]
146
+ ],
147
+ metadata: {
148
+ ...repository ? { repository } : {},
149
+ deploymentSource: stringRecord(manifest?.deploymentSource),
150
+ ...dockerArtifacts.length > 0 ? {
151
+ dockerArtifacts,
152
+ dockerImageReleaseWorkflow: dockerImageReleaseWorkflow ? `.github/workflows/${dockerImageReleaseWorkflow}` : ".github/workflows/publish.yml",
153
+ dockerImageArchitectures,
154
+ imageHosting: stringRecord(dockerImages.hosting)
155
+ } : {},
156
+ type: stringValue(manifest?.type) ?? null,
157
+ githubEnvironments: stringArray(manifest?.githubEnvironments),
158
+ requiredSecrets: stringArray(manifest?.requiredSecrets),
159
+ workflowTemplateVersion: stringValue(manifest?.workflowTemplateVersion) ?? null,
160
+ localDev: stringRecord(manifest?.localDev),
161
+ capacityProvider: stringRecord(manifest?.capacityProvider),
162
+ ...projectArchitecture ? {
163
+ projectArchitecture,
164
+ docsSiteReadiness: docsReadiness?.status ?? "site_not_prepared",
165
+ docsSiteDiagnostic: docsReadiness?.diagnostic ?? null
166
+ } : {},
167
+ ...hostedVerifyWorkflow ? {
168
+ hostedVerifyWorkflow: hostedVerifyWorkflow.startsWith(".github/workflows/") ? hostedVerifyWorkflow : `.github/workflows/${hostedVerifyWorkflow}`
169
+ } : {},
170
+ scripts
171
+ }
172
+ };
173
+ }
174
+ function treeseedPackageManifestPath(dir) {
175
+ for (const fileName of ["treeseed.package.yaml", "treeseed.package.yml", "treeseed.package.json", ".treeseed-package.json"]) {
176
+ const filePath = resolve(dir, fileName);
177
+ if (existsSync(filePath)) return filePath;
178
+ }
179
+ return null;
180
+ }
181
+ function readTreeseedPackageManifest(dir) {
182
+ const filePath = treeseedPackageManifestPath(dir);
183
+ return filePath ? readStructuredFile(filePath) : null;
184
+ }
185
+ function stringRecord(value) {
186
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
187
+ }
188
+ function stringValue(value) {
189
+ return typeof value === "string" && value.trim() ? value.trim() : null;
190
+ }
191
+ function stringArray(value) {
192
+ return Array.isArray(value) ? value.map((entry) => stringValue(entry)).filter((entry) => Boolean(entry)) : [];
193
+ }
194
+ function manifestDockerArtifacts(value) {
195
+ if (!Array.isArray(value)) return [];
196
+ return value.map((entry) => {
197
+ const record = stringRecord(entry);
198
+ if (stringValue(record.provider) !== "docker") return null;
199
+ const name = stringValue(record.name);
200
+ if (!name) return null;
201
+ return {
202
+ provider: "docker",
203
+ name,
204
+ dockerfile: stringValue(record.dockerfile),
205
+ context: stringValue(record.context),
206
+ target: stringValue(record.target),
207
+ role: stringValue(record.role),
208
+ architectures: stringArray(record.architectures)
209
+ };
210
+ }).filter((entry) => Boolean(entry));
211
+ }
212
+ function beamPackageAdapter(root, dir) {
213
+ const manifest = readTreeseedPackageManifest(dir);
214
+ const hasMixProject = existsSync(resolve(dir, "apps/api/mix.exs")) || existsSync(resolve(dir, "mix.exs"));
215
+ if (!manifest && !hasMixProject) return null;
216
+ const kind = typeof manifest?.kind === "string" ? manifest.kind : "beam-elixir-rust";
217
+ if (kind !== "beam-elixir-rust") return null;
218
+ const id = typeof manifest?.id === "string" && manifest.id.trim() ? manifest.id.trim() : relative(resolve(root, "packages"), dir).replaceAll("\\", "/");
219
+ const name = typeof manifest?.name === "string" && manifest.name.trim() ? manifest.name.trim() : id;
220
+ const versionSourceRel = typeof manifest?.versionSource === "string" && manifest.versionSource.trim() ? manifest.versionSource.trim() : existsSync(resolve(dir, "apps/api/mix.exs")) ? "apps/api/mix.exs" : "mix.exs";
221
+ const versionSource = resolve(dir, versionSourceRel);
222
+ const image = typeof manifest?.image === "string" && manifest.image.trim() ? manifest.image.trim() : id === "treedx" ? "treeseed/treedx" : null;
223
+ const repository = stringValue(manifest?.repository) ?? (id === "treedx" ? "treeseed-ai/treedx" : null);
224
+ const hostedVerifyWorkflow = stringValue(manifest?.hostedVerifyWorkflow) ?? stringValue(stringRecord(manifest?.releaseGate).workflow) ?? (existsSync(resolve(dir, ".github/workflows/release-gate.yml")) ? "release-gate.yml" : null);
225
+ const projectArchitecture = normalizeTreeseedPackageProjectArchitecture(manifest?.projectArchitecture, id);
226
+ const docsReadiness = docsSiteReadiness(dir, projectArchitecture);
227
+ const verify = manifest?.verify && typeof manifest.verify === "object" && !Array.isArray(manifest.verify) ? manifest.verify : {};
228
+ const fast = verify.fast ?? (existsSync(resolve(dir, "scripts/test-treedx-fast.sh")) ? "scripts/test-treedx-fast.sh" : null);
229
+ const local = verify.local ?? (existsSync(resolve(dir, "scripts/test-all.sh")) ? "scripts/test-all.sh" : null);
230
+ const releaseGate = stringValue(manifest?.releaseGate) ?? verify.release ?? (existsSync(resolve(dir, "scripts/release-gate.sh")) ? "scripts/release-gate.sh" : null);
231
+ const version = readMixProjectVersion(versionSource);
232
+ const shaTag = "sha-<short-sha>";
233
+ return {
234
+ id,
235
+ name,
236
+ kind: "beam-elixir-rust",
237
+ dir,
238
+ relativeDir: relative(root, dir).replaceAll("\\", "/"),
239
+ version,
240
+ publishTarget: image,
241
+ manifestPath: treeseedPackageManifestPath(dir),
242
+ versionSource,
243
+ verifyCommands: {
244
+ fast: commandFromScript(dir, fast, "fast"),
245
+ local: commandFromScript(dir, local, "local"),
246
+ release: commandFromScript(dir, releaseGate, "release")
247
+ },
248
+ artifacts: image ? [{
249
+ provider: "docker",
250
+ name: image,
251
+ tags: version ? [version, shaTag] : [shaTag],
252
+ dockerfile: "Dockerfile",
253
+ context: ".",
254
+ target: null,
255
+ role: id,
256
+ architectures: stringArray(stringRecord(manifest?.dockerImages).architectures)
257
+ }] : [],
258
+ releaseChecks: image ? [{ kind: "docker-manifest", name: "Docker image manifest", detail: `${image}:${version ?? "<version>"}` }] : [],
259
+ metadata: {
260
+ hasCargo: existsSync(resolve(dir, "Cargo.toml")),
261
+ hasDockerfile: existsSync(resolve(dir, "Dockerfile")),
262
+ repository,
263
+ deploymentSource: stringRecord(manifest?.deploymentSource),
264
+ imageHosting: stringRecord(stringRecord(manifest?.dockerImages).hosting),
265
+ versionSource: versionSourceRel,
266
+ ...hostedVerifyWorkflow ? {
267
+ hostedVerifyWorkflow: hostedVerifyWorkflow.startsWith(".github/workflows/") ? hostedVerifyWorkflow : `.github/workflows/${hostedVerifyWorkflow}`
268
+ } : {},
269
+ type: stringValue(manifest?.type) ?? null,
270
+ githubEnvironments: stringArray(manifest?.githubEnvironments),
271
+ requiredSecrets: stringArray(manifest?.requiredSecrets),
272
+ workflowTemplateVersion: stringValue(manifest?.workflowTemplateVersion) ?? null,
273
+ ...projectArchitecture ? {
274
+ projectArchitecture,
275
+ docsSiteReadiness: docsReadiness?.status ?? "site_not_prepared",
276
+ docsSiteDiagnostic: docsReadiness?.diagnostic ?? null
277
+ } : {}
278
+ }
279
+ };
280
+ }
281
+ function gitOutput(cwd, args) {
282
+ const result = runTreeseedGit(args, { cwd, mode: "read" });
283
+ return result.stdout.trim();
284
+ }
285
+ function gitRevisionSha(cwd, revision) {
286
+ try {
287
+ return gitOutput(cwd, ["rev-parse", revision]);
288
+ } catch (error) {
289
+ if (/^[A-Za-z0-9._/-]+$/u.test(revision) && !revision.startsWith("origin/")) {
290
+ try {
291
+ return gitOutput(cwd, ["rev-parse", `origin/${revision}`]);
292
+ } catch {
293
+ }
294
+ }
295
+ throw error;
296
+ }
297
+ }
298
+ function branchSlug(value) {
299
+ const normalized = value.toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "").slice(0, 40);
300
+ return normalized || "branch";
301
+ }
302
+ function planTreeseedPackageDevelopmentImage(root = workspaceRoot(), idOrName, { branch } = {}) {
303
+ const adapter = findTreeseedPackageAdapter(root, idOrName);
304
+ if (!adapter) {
305
+ throw new Error(`Treeseed package adapter ${idOrName} was not discovered.`);
306
+ }
307
+ const firstDockerArtifact = adapter.artifacts.find((artifact) => artifact.provider === "docker") ?? null;
308
+ const imageName = typeof adapter.publishTarget === "string" && adapter.publishTarget.trim() ? adapter.publishTarget.trim() : firstDockerArtifact?.name ?? null;
309
+ if (!imageName) {
310
+ throw new Error(`${adapter.id} does not declare a publish image target.`);
311
+ }
312
+ const metadata = adapter.metadata;
313
+ const selectedBranch = branch ?? "staging";
314
+ const deploymentSourceMode = deploymentSourceModeForBranch(metadata, selectedBranch);
315
+ const sha = gitRevisionSha(adapter.dir, selectedBranch);
316
+ const shortSha = sha.slice(0, 12);
317
+ const deploymentEnvironment = selectedBranch === "main" ? "prod" : selectedBranch;
318
+ const imagePublicationRequired = (deploymentSourceMode ?? "image") === "image";
319
+ if (deploymentEnvironment !== "prod" && imagePublicationRequired) {
320
+ throw new Error(`${adapter.id} non-production package image planning is tagless and must use deploymentSource git.`);
321
+ }
322
+ const workflow = imagePublicationRequired ? stringValue(metadata.dockerImageReleaseWorkflow)?.replace(/^\.github\/workflows\//u, "") ?? "publish.yml" : "source-build";
323
+ const productionImageTag = deploymentEnvironment === "prod" ? adapter.version : null;
324
+ if (deploymentEnvironment === "prod" && (!productionImageTag || !/^\d+\.\d+\.\d+$/u.test(productionImageTag))) {
325
+ throw new Error(`${adapter.id} production image publication requires a stable semantic package version.`);
326
+ }
327
+ const immutableTag = productionImageTag;
328
+ const movingTag = null;
329
+ const architectures = stringArray(metadata.dockerImageArchitectures);
330
+ const dockerArtifacts = Array.isArray(metadata.dockerArtifacts) ? metadata.dockerArtifacts.map((entry) => {
331
+ const record = stringRecord(entry);
332
+ const artifactImageName = stringValue(record.name);
333
+ if (!artifactImageName) return null;
334
+ return {
335
+ role: stringValue(record.role) ?? artifactImageName.split("/").at(-1)?.replace(/^agent-/u, "") ?? artifactImageName,
336
+ imageName: artifactImageName,
337
+ target: stringValue(record.target),
338
+ architectures: stringArray(record.architectures)
339
+ };
340
+ }).filter((entry) => Boolean(entry)) : [];
341
+ const imageHosting = stringRecord(metadata.imageHosting);
342
+ const app = stringValue(imageHosting.app);
343
+ const overrideEnvVar = stringValue(imageHosting.envVar);
344
+ const environment = deploymentEnvironment === "prod" ? "prod" : stringValue(imageHosting.environment) ?? selectedBranch;
345
+ const imageRef = immutableTag ? `${imageName}:${immutableTag}` : null;
346
+ const movingImageRef = null;
347
+ const hostingImageRef = movingImageRef ?? imageRef;
348
+ const roleImages = dockerArtifacts.length > 0 ? dockerArtifacts.map((artifact) => {
349
+ const artifactArchitectures = artifact.architectures.length > 0 ? artifact.architectures : architectures;
350
+ return {
351
+ role: artifact.role,
352
+ imageName: artifact.imageName,
353
+ target: artifact.target,
354
+ immutableRef: immutableTag ? `${artifact.imageName}:${immutableTag}` : null,
355
+ movingRef: null,
356
+ archImageRefs: immutableTag ? artifactArchitectures.map((arch) => `${artifact.imageName}:${immutableTag}-${arch}`) : []
357
+ };
358
+ }) : void 0;
359
+ return {
360
+ package: {
361
+ id: adapter.id,
362
+ name: adapter.name,
363
+ path: adapter.relativeDir,
364
+ kind: adapter.kind,
365
+ version: adapter.version,
366
+ publishTarget: adapter.publishTarget,
367
+ metadata: adapter.metadata
368
+ },
369
+ repository: stringValue(metadata.repository) ?? `${adapter.id}`,
370
+ workflow,
371
+ branch: selectedBranch,
372
+ refs: {
373
+ imageName,
374
+ branch: selectedBranch,
375
+ branchSlug: branchSlug(selectedBranch),
376
+ sha,
377
+ shortSha,
378
+ immutableTag,
379
+ movingTag,
380
+ imageRef,
381
+ movingImageRef,
382
+ archImageRefs: immutableTag ? architectures.map((arch) => `${imageName}:${immutableTag}-${arch}`) : [],
383
+ ...roleImages ? { roleImages } : {}
384
+ },
385
+ deploymentSource: {
386
+ environment: deploymentEnvironment,
387
+ mode: deploymentSourceMode ?? "image",
388
+ repository: stringValue(metadata.repository) ?? `${adapter.id}`,
389
+ commitSha: sha,
390
+ imagePublicationRequired
391
+ },
392
+ hosting: imagePublicationRequired && app && overrideEnvVar && hostingImageRef ? {
393
+ app,
394
+ environment,
395
+ overrideEnvVar,
396
+ override: { [overrideEnvVar]: hostingImageRef },
397
+ command: `${overrideEnvVar}=${hostingImageRef} npx trsd hosting apply --environment ${environment} --app ${app} --execute --json`
398
+ } : null
399
+ };
400
+ }
401
+ function discoverTreeseedPackageAdapters(root = workspaceRoot()) {
402
+ const adapters = /* @__PURE__ */ new Map();
403
+ for (const pkg of workspacePackages(root)) {
404
+ if (typeof pkg.name === "string" && pkg.name.startsWith("@treeseed/")) {
405
+ adapters.set(pkg.name, nodeTypeScriptAdapter(pkg));
406
+ }
407
+ }
408
+ const packagesDir = resolve(root, "packages");
409
+ const packageDirs = existsSync(packagesDir) ? readdirSync(packagesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => resolve(packagesDir, entry.name)) : [];
410
+ for (const dir of packageDirs) {
411
+ if (!existsSync(dir)) continue;
412
+ const adapter = beamPackageAdapter(root, dir);
413
+ if (adapter) adapters.set(adapter.id, adapter);
414
+ }
415
+ return [...adapters.values()].sort((left, right) => {
416
+ if (left.kind !== right.kind) return left.kind === "node-typescript" ? -1 : 1;
417
+ return left.id.localeCompare(right.id);
418
+ });
419
+ }
420
+ function findTreeseedPackageAdapter(root, idOrName) {
421
+ const normalized = idOrName.trim();
422
+ return discoverTreeseedPackageAdapters(root).find((adapter) => {
423
+ const scopedId = adapter.id.startsWith("@treeseed/") ? adapter.id.slice("@treeseed/".length) : null;
424
+ const scopedName = adapter.name.startsWith("@treeseed/") ? adapter.name.slice("@treeseed/".length) : null;
425
+ const directoryName = adapter.relativeDir.split("/").at(-1);
426
+ return adapter.id === normalized || adapter.name === normalized || scopedId === normalized || scopedName === normalized || directoryName === normalized;
427
+ }) ?? null;
428
+ }
429
+ function packageAdapterPlanSummary(root = workspaceRoot()) {
430
+ return discoverTreeseedPackageAdapters(root).map((adapter) => ({
431
+ id: adapter.id,
432
+ name: adapter.name,
433
+ kind: adapter.kind,
434
+ path: adapter.relativeDir,
435
+ version: adapter.version,
436
+ publishTarget: adapter.publishTarget,
437
+ verify: Object.fromEntries(Object.entries(adapter.verifyCommands).map(([key, command]) => [
438
+ key,
439
+ command ? `${command.command} ${command.args.join(" ")}` : null
440
+ ])),
441
+ artifacts: adapter.artifacts,
442
+ releaseChecks: adapter.releaseChecks,
443
+ metadata: adapter.metadata
444
+ }));
445
+ }
446
+ async function runTreeseedPackageImageWorkflow(options) {
447
+ const root = options.root ?? workspaceRoot();
448
+ const branch = options.branch ?? "staging";
449
+ const imagePlan = planTreeseedPackageDevelopmentImage(root, options.packageId, { branch });
450
+ const selectedWorkflow = options.workflow ?? imagePlan.workflow;
451
+ const execute = options.execute === true;
452
+ const syncConfig = options.syncConfig === true;
453
+ const configEnv = resolveTreeseedLaunchEnvironment({
454
+ tenantRoot: root,
455
+ scope: "staging",
456
+ baseEnv: options.env ?? process.env
457
+ });
458
+ const dockerHubUsername = resolveTreeseedDockerhubUsername(configEnv);
459
+ const dockerHubToken = resolveTreeseedDockerhubToken(configEnv);
460
+ const dockerHub = {
461
+ usernameConfigured: Boolean(dockerHubUsername),
462
+ tokenConfigured: Boolean(dockerHubToken),
463
+ requiredSecrets: imagePlan.deploymentSource?.imagePublicationRequired === false ? [] : ["TREESEED_DOCKERHUB_TOKEN"],
464
+ requiredVariables: imagePlan.deploymentSource?.imagePublicationRequired === false ? [] : ["TREESEED_DOCKERHUB_USERNAME"]
465
+ };
466
+ const credential = resolveGitHubCredentialForRepository(imagePlan.repository, { values: configEnv, env: options.env ?? process.env });
467
+ const githubClientEnv = credential.token ? { ...configEnv, TREESEED_GITHUB_TOKEN: credential.token, GH_TOKEN: credential.token, GITHUB_TOKEN: credential.token } : configEnv;
468
+ const report = {
469
+ ok: true,
470
+ action: execute ? "dispatch" : "plan",
471
+ package: imagePlan.package,
472
+ repository: imagePlan.repository,
473
+ workflow: selectedWorkflow,
474
+ branch: imagePlan.branch,
475
+ refs: imagePlan.refs,
476
+ deploymentSource: imagePlan.deploymentSource,
477
+ credential: {
478
+ repository: credential.repository,
479
+ envName: credential.envName,
480
+ configured: credential.configured,
481
+ source: credential.source,
482
+ fallbackUsed: credential.fallbackUsed
483
+ },
484
+ dockerHub,
485
+ hosting: imagePlan.hosting,
486
+ reconcile: {
487
+ lifecycle: syncConfig || execute ? ["refresh", "diff", "plan", "validate", "apply", "refresh", "verify", "persist"] : ["refresh", "diff", "plan"],
488
+ resources: [
489
+ `package-workflow:${imagePlan.package.id}`,
490
+ ...imagePlan.deploymentSource?.imagePublicationRequired === false ? [`source-build:${imagePlan.repository}#${imagePlan.deploymentSource.commitSha}`] : imagePlan.refs.roleImages ? imagePlan.refs.roleImages.map((entry) => `package-image:${entry.imageName}`) : [`package-image:${imagePlan.refs.imageName}`]
491
+ ]
492
+ }
493
+ };
494
+ if (syncConfig) {
495
+ const environment = imagePlan.hosting?.environment ?? "staging";
496
+ report.syncedConfig = {
497
+ environment,
498
+ blocked: true,
499
+ reason: imagePlan.deploymentSource?.imagePublicationRequired === false ? "Staging source-build policy does not sync Docker image credentials or image override variables." : "Package image config sync is reconciler-owned. Use trsd package image --sync-config so github-secret-binding and github-variable-binding resources apply through adapters.",
500
+ secrets: dockerHubToken ? [{ name: "TREESEED_DOCKERHUB_TOKEN", existed: null }] : [],
501
+ variables: dockerHubUsername ? [{ name: "TREESEED_DOCKERHUB_USERNAME", existed: null }] : []
502
+ };
503
+ }
504
+ if (execute) {
505
+ const client = createGitHubApiClient({ env: githubClientEnv });
506
+ report.dispatch = {
507
+ blocked: true,
508
+ reason: imagePlan.deploymentSource?.imagePublicationRequired === false ? "Staging deployment source is GitHub source build; routine development Docker image publication is disabled." : "Package image workflow dispatch is reconciler-owned. Use trsd package image --execute so github-workflow-dispatch/package-image resources apply through adapters."
509
+ };
510
+ if (imagePlan.deploymentSource?.imagePublicationRequired !== false) {
511
+ report.latestWorkflowRun = await getLatestGitHubWorkflowRun(imagePlan.repository, {
512
+ client,
513
+ workflow: selectedWorkflow,
514
+ branch: imagePlan.branch
515
+ });
516
+ }
517
+ }
518
+ return { imagePlan, selectedWorkflow, dockerHub, credential, report };
519
+ }
520
+ function validateTreeseedPackageManifests(root = workspaceRoot()) {
521
+ return discoverTreeseedPackageAdapters(root).map((adapter) => {
522
+ const errors = [];
523
+ const warnings = [];
524
+ if (!adapter.manifestPath || adapter.manifestPath.endsWith("package.json")) {
525
+ errors.push("missing treeseed.package.yaml");
526
+ }
527
+ if (!adapter.id.trim()) errors.push("missing package id");
528
+ if (!adapter.name.trim()) errors.push("missing package name");
529
+ if (!["node-typescript", "beam-elixir-rust"].includes(adapter.kind)) {
530
+ errors.push(`unsupported package kind ${adapter.kind}`);
531
+ }
532
+ if (adapter.verifyCommands.local == null) {
533
+ errors.push("missing local verification command");
534
+ }
535
+ if (!adapter.metadata.projectArchitecture) {
536
+ warnings.push("package does not declare projectArchitecture metadata");
537
+ }
538
+ if (adapter.releaseChecks.length === 0) {
539
+ warnings.push("package declares no release checks");
540
+ }
541
+ const hasDockerArtifact = adapter.artifacts.some((artifact) => artifact.provider === "docker");
542
+ if (hasDockerArtifact) {
543
+ const deploymentSource = stringRecord(adapter.metadata.deploymentSource);
544
+ if (stringValue(deploymentSource.staging) !== "git") {
545
+ errors.push("docker package must declare deploymentSource.staging: git");
546
+ }
547
+ if (stringValue(deploymentSource.prod) !== "image") {
548
+ errors.push("docker package must declare deploymentSource.prod: image");
549
+ }
550
+ const architectures = stringArray(adapter.metadata.dockerImageArchitectures);
551
+ if (!architectures.includes("amd64") || !architectures.includes("arm64")) {
552
+ errors.push("docker package must declare amd64 and arm64 architectures");
553
+ }
554
+ }
555
+ for (const artifact of adapter.artifacts) {
556
+ if (artifact.provider === "docker" && !artifact.name.startsWith("treeseed/")) {
557
+ errors.push(`docker artifact ${artifact.name} must publish under treeseed/*`);
558
+ }
559
+ }
560
+ return {
561
+ packageId: adapter.id,
562
+ path: adapter.relativeDir,
563
+ manifestPath: adapter.manifestPath,
564
+ ok: errors.length === 0,
565
+ errors,
566
+ warnings
567
+ };
568
+ });
569
+ }
570
+ function deriveTreeseedPackageProjectResources(root = workspaceRoot(), options = {}) {
571
+ const team = options.team ?? "team:treeseed";
572
+ return discoverTreeseedPackageAdapters(root).map((adapter) => {
573
+ const architecture = adapter.metadata.projectArchitecture;
574
+ const repository = stringValue(adapter.metadata.repository);
575
+ if (!architecture || !repository) return null;
576
+ const [owner, name] = repository.split("/");
577
+ if (!owner || !name) return null;
578
+ const slug = normalizePackageSlug(adapter.id);
579
+ return {
580
+ key: `project:treeseed/${slug}`,
581
+ team,
582
+ slug,
583
+ name: adapter.name,
584
+ description: `${adapter.name} first-party package project.`,
585
+ kind: "package",
586
+ repository: {
587
+ role: "primary",
588
+ provider: "github",
589
+ owner,
590
+ name,
591
+ gitUrl: `https://github.com/${owner}/${name}.git`,
592
+ defaultBranch: "main",
593
+ checkoutPath: adapter.relativeDir
594
+ },
595
+ architecture,
596
+ metadata: {
597
+ packageId: adapter.id,
598
+ packagePath: adapter.relativeDir,
599
+ visibility: "public",
600
+ docsSiteReadiness: stringValue(adapter.metadata.docsSiteReadiness) ?? "site_not_prepared",
601
+ releaseOwnership: "treeseed.package.yaml"
602
+ }
603
+ };
604
+ }).filter((entry) => Boolean(entry));
605
+ }
606
+ function workflowNameForTemplate(adapter, template) {
607
+ const publishWorkflow = "publish.yml";
608
+ const configuredReleaseGate = stringValue(adapter.metadata.hostedVerifyWorkflow)?.replace(/^\.github\/workflows\//u, "") ?? "verify.yml";
609
+ if (template === "docker-image") return publishWorkflow;
610
+ if (template === "release-gate") {
611
+ return configuredReleaseGate === publishWorkflow ? "release-gate.yml" : configuredReleaseGate;
612
+ }
613
+ return publishWorkflow;
614
+ }
615
+ function renderTreeseedPackageWorkflow(adapter, template) {
616
+ const verifyCommand = template === "release-gate" ? adapter.verifyCommands.release ?? adapter.verifyCommands.local : adapter.verifyCommands.local;
617
+ const verify = verifyCommand ? formatWorkflowRunCommand(verifyCommand.command, verifyCommand.args) : "npm run verify:local";
618
+ const setup = resolveWorkflowSetupCommand(adapter);
619
+ const dockerArtifacts = adapter.artifacts.filter((artifact) => artifact.provider === "docker");
620
+ if (template === "npm-publish") {
621
+ return `name: Publish ${adapter.name}
622
+
623
+ on:
624
+ push:
625
+ tags:
626
+ - "*.*.*"
627
+ workflow_dispatch:
628
+
629
+ jobs:
630
+ publish:
631
+ if: startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, '-')
632
+ runs-on: ubuntu-latest
633
+ permissions:
634
+ contents: write
635
+ environment: production
636
+ steps:
637
+ - uses: actions/checkout@v4
638
+ with:
639
+ submodules: recursive
640
+ - uses: actions/setup-node@v4
641
+ with:
642
+ node-version: 22
643
+ registry-url: https://registry.npmjs.org
644
+ - run: ${setup}
645
+ - run: ${verify}
646
+ - run: npm publish --access public
647
+ env:
648
+ NODE_AUTH_TOKEN: \${{ secrets.NPM_TOKEN }}
649
+ - name: Create GitHub release
650
+ env:
651
+ GH_TOKEN: \${{ secrets.GITHUB_TOKEN }}
652
+ run: gh release create "\${GITHUB_REF_NAME}" --generate-notes --verify-tag
653
+ `;
654
+ }
655
+ if (template === "docker-image") {
656
+ const environment = "production";
657
+ const imageSetup = adapter.kind === "node-typescript" ? resolveDockerImageWorkflowSetupCommand() : null;
658
+ const anyTarget = dockerArtifacts.some((artifact) => typeof artifact.target === "string" && artifact.target.trim().length > 0);
659
+ const dockerContextPrepareCommand = isRecord(adapter.metadata.scripts) && typeof adapter.metadata.scripts["capacity-provider:build"] === "string" ? "npm run capacity-provider:build -- --prepare-only" : null;
660
+ const trigger = ` tags:
661
+ - "*.*.*"`;
662
+ const jobCondition = "startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, '-')";
663
+ const computeTagsStep = ` - name: Compute image tags
664
+ id: tags
665
+ run: |
666
+ version="\${GITHUB_REF_NAME#v}"
667
+ echo "base=\${version}" >> "$GITHUB_OUTPUT"
668
+ echo "moving=" >> "$GITHUB_OUTPUT"
669
+ `;
670
+ const releaseStep = ` release:
671
+ needs: manifest
672
+ if: ${jobCondition}
673
+ runs-on: ubuntu-24.04
674
+ permissions:
675
+ contents: write
676
+ steps:
677
+ - uses: actions/checkout@v4
678
+ - name: Create GitHub release
679
+ env:
680
+ GH_TOKEN: \${{ secrets.GITHUB_TOKEN }}
681
+ run: gh release create "\${GITHUB_REF_NAME}" --generate-notes --verify-tag
682
+ `;
683
+ return `name: Publish Image ${adapter.name}
684
+
685
+ on:
686
+ workflow_dispatch:
687
+ push:
688
+ ${trigger}
689
+
690
+ jobs:
691
+ build:
692
+ if: ${jobCondition}
693
+ runs-on: \${{ matrix.runner }}
694
+ permissions:
695
+ contents: write
696
+ packages: write
697
+ environment: ${environment}
698
+ strategy:
699
+ matrix:
700
+ include:
701
+ ${dockerArtifacts.flatMap((artifact) => [
702
+ ` - image: ${artifact.name}${anyTarget ? `
703
+ target: ${artifact.target ?? ""}` : ""}
704
+ arch: amd64
705
+ platform: linux/amd64
706
+ runner: ubuntu-24.04`,
707
+ ` - image: ${artifact.name}${anyTarget ? `
708
+ target: ${artifact.target ?? ""}` : ""}
709
+ arch: arm64
710
+ platform: linux/arm64
711
+ runner: ubuntu-24.04-arm`
712
+ ]).join("\n") || ` - image: treeseed/unknown
713
+ arch: amd64
714
+ platform: linux/amd64
715
+ runner: ubuntu-24.04`}
716
+ steps:
717
+ - uses: actions/checkout@v4
718
+ with:
719
+ submodules: recursive
720
+ ${imageSetup ? ` - run: ${imageSetup}
721
+ ` : ""}${dockerContextPrepareCommand ? ` - run: ${dockerContextPrepareCommand}
722
+ ` : ""}${computeTagsStep} - uses: docker/setup-buildx-action@v3
723
+ - uses: docker/login-action@v3
724
+ with:
725
+ username: \${{ vars.TREESEED_DOCKERHUB_USERNAME }}
726
+ password: \${{ secrets.TREESEED_DOCKERHUB_TOKEN }}
727
+ - uses: docker/build-push-action@v6
728
+ with:
729
+ context: .
730
+ ${anyTarget ? " target: ${{ matrix.target }}\n" : ""} platforms: \${{ matrix.platform }}
731
+ push: true
732
+ tags: \${{ matrix.image }}:\${{ steps.tags.outputs.base }}-\${{ matrix.arch }}
733
+
734
+ manifest:
735
+ needs: build
736
+ if: ${jobCondition}
737
+ runs-on: ubuntu-24.04
738
+ permissions:
739
+ contents: read
740
+ packages: write
741
+ environment: ${environment}
742
+ strategy:
743
+ matrix:
744
+ include:
745
+ ${dockerArtifacts.map((artifact) => ` - image: ${artifact.name}`).join("\n") || " - image: treeseed/unknown"}
746
+ steps:
747
+ - uses: docker/setup-buildx-action@v3
748
+ - uses: docker/login-action@v3
749
+ with:
750
+ username: \${{ vars.TREESEED_DOCKERHUB_USERNAME }}
751
+ password: \${{ secrets.TREESEED_DOCKERHUB_TOKEN }}
752
+ ${computeTagsStep} - name: Publish multi-architecture manifest
753
+ run: |
754
+ docker buildx imagetools create \\
755
+ -t "\${{ matrix.image }}:\${{ steps.tags.outputs.base }}" \\
756
+ "\${{ matrix.image }}:\${{ steps.tags.outputs.base }}-amd64" \\
757
+ "\${{ matrix.image }}:\${{ steps.tags.outputs.base }}-arm64"
758
+ ${releaseStep}`;
759
+ }
760
+ const needsNodeSetup = adapter.kind === "node-typescript";
761
+ const needsBeamSetup = adapter.kind === "beam-elixir-rust";
762
+ return `name: Verify ${adapter.name}
763
+
764
+ on:
765
+ push:
766
+ pull_request:
767
+ workflow_dispatch:
768
+
769
+ jobs:
770
+ verify:
771
+ runs-on: ubuntu-latest
772
+ steps:
773
+ - uses: actions/checkout@v4
774
+ with:
775
+ submodules: recursive
776
+ ${needsNodeSetup ? ` - uses: actions/setup-node@v4
777
+ with:
778
+ node-version: 22
779
+ - run: ${setup}
780
+ ` : ""}${needsBeamSetup ? ` - uses: erlef/setup-beam@v1
781
+ with:
782
+ otp-version: "27"
783
+ elixir-version: "1.17.3"
784
+ - run: mix local.hex --force && mix local.rebar --force
785
+ ` : ""} - run: ${verify}
786
+ `;
787
+ }
788
+ function resolveWorkflowSetupCommand(adapter) {
789
+ const scripts = adapter.metadata.scripts;
790
+ if (isRecord(scripts) && typeof scripts["release:setup"] === "string") {
791
+ return 'npm run release:setup || (echo "dependency install failed; retrying" && npm run release:setup)';
792
+ }
793
+ return 'npm ci || (echo "dependency install failed; retrying" && npm ci)';
794
+ }
795
+ function resolveDockerImageWorkflowSetupCommand() {
796
+ return 'npm ci --ignore-scripts || (echo "dependency install failed; retrying" && npm ci --ignore-scripts)';
797
+ }
798
+ function isRecord(value) {
799
+ return value != null && typeof value === "object" && !Array.isArray(value);
800
+ }
801
+ function formatWorkflowRunCommand(command, args) {
802
+ return [command, ...args].map(shellQuoteWorkflowArg).join(" ");
803
+ }
804
+ function shellQuoteWorkflowArg(value) {
805
+ if (/^[A-Za-z0-9_./:@%+=,-]+$/u.test(value)) return value;
806
+ return `'${value.replace(/'/gu, `'\\''`)}'`;
807
+ }
808
+ function workflowTemplatesForAdapter(adapter) {
809
+ const hasDocker = adapter.artifacts.some((artifact) => artifact.provider === "docker");
810
+ const hasNpm = adapter.artifacts.some((artifact) => artifact.provider === "npm");
811
+ return [
812
+ ...hasNpm ? ["npm-publish"] : [],
813
+ ...hasDocker ? ["docker-image"] : [],
814
+ "release-gate"
815
+ ];
816
+ }
817
+ function syncTreeseedPackageWorkflows({
818
+ root = workspaceRoot(),
819
+ packageId,
820
+ execute = false
821
+ } = {}) {
822
+ const adapters = packageId && packageId !== "all" ? [findTreeseedPackageAdapter(root, packageId)].filter((entry) => Boolean(entry)) : discoverTreeseedPackageAdapters(root);
823
+ const results = [];
824
+ for (const adapter of adapters) {
825
+ for (const template of workflowTemplatesForAdapter(adapter)) {
826
+ const workflow = workflowNameForTemplate(adapter, template);
827
+ const path = resolve(adapter.dir, ".github", "workflows", workflow);
828
+ const rendered = renderTreeseedPackageWorkflow(adapter, template);
829
+ const current = existsSync(path) ? readFileSync(path, "utf8") : null;
830
+ const changed = current !== rendered;
831
+ if (execute && changed) {
832
+ mkdirSync(dirname(path), { recursive: true });
833
+ writeFileSync(path, rendered, "utf8");
834
+ }
835
+ results.push({
836
+ packageId: adapter.id,
837
+ path,
838
+ workflow,
839
+ template,
840
+ exists: current != null,
841
+ changed,
842
+ written: execute && changed
843
+ });
844
+ }
845
+ }
846
+ return results;
847
+ }
848
+ export {
849
+ deriveTreeseedPackageProjectResources,
850
+ discoverTreeseedPackageAdapters,
851
+ findTreeseedPackageAdapter,
852
+ packageAdapterPlanSummary,
853
+ planTreeseedPackageDevelopmentImage,
854
+ readMixProjectVersion,
855
+ renderTreeseedPackageWorkflow,
856
+ runTreeseedPackageImageWorkflow,
857
+ syncTreeseedPackageWorkflows,
858
+ validateTreeseedPackageManifests
859
+ };