@treeseed/sdk 0.11.0 → 0.12.5

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 (473) hide show
  1. package/README.md +9 -4
  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 +117 -60
  27. package/dist/capacity-provider.js +215 -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 +2 -2
  36. package/dist/copilot.d.ts +3 -0
  37. package/dist/copilot.js +16 -1
  38. package/dist/d1-http.d.ts +1 -1
  39. package/dist/d1-store.d.ts +32 -57
  40. package/dist/d1-store.js +115 -318
  41. package/dist/db/d1.d.ts +1 -232
  42. package/dist/db/index.d.ts +3 -3
  43. package/dist/db/market-schema.d.ts +49037 -11843
  44. package/dist/db/market-schema.js +1788 -50
  45. package/dist/db/node-sqlite.d.ts +1 -232
  46. package/dist/db/schema.d.ts +0 -462
  47. package/dist/db/schema.js +2 -22
  48. package/dist/dispatch.d.ts +1 -1
  49. package/dist/dispatch.js +0 -11
  50. package/dist/fixture-support.js +52 -4
  51. package/dist/governance.d.ts +133 -0
  52. package/dist/governance.js +285 -0
  53. package/dist/graph/build.d.ts +2 -2
  54. package/dist/graph/context-query-contracts.d.ts +1 -1
  55. package/dist/graph/dsl.d.ts +1 -1
  56. package/dist/graph/query.d.ts +4 -4
  57. package/dist/graph/ranking.d.ts +1 -1
  58. package/dist/graph/schema.d.ts +1 -1
  59. package/dist/graph.d.ts +11 -11
  60. package/dist/guarantees/index.d.ts +425 -0
  61. package/dist/guarantees/index.js +1146 -0
  62. package/dist/hosting/apps.d.ts +1 -1
  63. package/dist/hosting/builtins.d.ts +1 -1
  64. package/dist/hosting/builtins.js +9 -198
  65. package/dist/hosting/contracts.d.ts +3 -2
  66. package/dist/hosting/graph.d.ts +24 -21
  67. package/dist/hosting/graph.js +280 -294
  68. package/dist/hosting/index.d.ts +4 -4
  69. package/dist/index.d.ts +88 -74
  70. package/dist/index.js +81 -10
  71. package/dist/local-dev/managed-dev.d.ts +85 -0
  72. package/dist/local-dev/managed-dev.js +368 -0
  73. package/dist/managed-dependencies.d.ts +9 -0
  74. package/dist/managed-dependencies.js +10 -8
  75. package/dist/market-client.d.ts +265 -7
  76. package/dist/market-client.js +381 -9
  77. package/dist/model-registry.d.ts +1 -1
  78. package/dist/model-registry.js +19 -19
  79. package/dist/operations/agent-tools.d.ts +2 -11
  80. package/dist/operations/agent-tools.js +2 -14
  81. package/dist/operations/providers/default.d.ts +1 -1
  82. package/dist/operations/providers/default.js +20 -37
  83. package/dist/operations/repository-operations.d.ts +26 -2
  84. package/dist/operations/repository-operations.js +159 -1
  85. package/dist/operations/runtime.d.ts +3 -3
  86. package/dist/operations/services/bootstrap-runner.d.ts +1 -1
  87. package/dist/operations/services/build-warning-policy.d.ts +34 -0
  88. package/dist/operations/services/build-warning-policy.js +81 -82
  89. package/dist/operations/services/commit-message-provider.js +4 -4
  90. package/dist/operations/services/config-runtime.d.ts +73 -19
  91. package/dist/operations/services/config-runtime.js +276 -100
  92. package/dist/operations/services/deploy.d.ts +41 -622
  93. package/dist/operations/services/deploy.js +181 -213
  94. package/dist/operations/services/deployment-readiness.d.ts +1 -1
  95. package/dist/operations/services/deployment-readiness.js +38 -7
  96. package/dist/operations/services/git-remote-policy.js +12 -4
  97. package/dist/operations/services/git-runner.d.ts +66 -0
  98. package/dist/operations/services/git-runner.js +479 -0
  99. package/dist/operations/services/git-workflow.d.ts +43 -5
  100. package/dist/operations/services/git-workflow.js +242 -20
  101. package/dist/operations/services/github-actions-verification.d.ts +3 -1
  102. package/dist/operations/services/github-actions-verification.js +11 -3
  103. package/dist/operations/services/github-api.js +21 -5
  104. package/dist/operations/services/github-automation.d.ts +3 -3
  105. package/dist/operations/services/github-automation.js +15 -18
  106. package/dist/operations/services/github-credentials.js +2 -1
  107. package/dist/operations/services/hosted-service-checks.d.ts +19 -1
  108. package/dist/operations/services/hosted-service-checks.js +162 -11
  109. package/dist/operations/services/hosting-audit.d.ts +2 -2
  110. package/dist/operations/services/hosting-audit.js +7 -7
  111. package/dist/operations/services/hub-launch.d.ts +1 -1
  112. package/dist/operations/services/hub-provider-launch.d.ts +5 -5
  113. package/dist/operations/services/hub-provider-launch.js +19 -14
  114. package/dist/operations/services/live-hosted-service-checks.d.ts +2 -1
  115. package/dist/operations/services/live-hosted-service-checks.js +193 -80
  116. package/dist/operations/services/local-dev.js +0 -1
  117. package/dist/operations/services/managed-host-security.d.ts +1 -1
  118. package/dist/operations/services/managed-repositories.d.ts +37 -0
  119. package/dist/operations/services/managed-repositories.js +177 -0
  120. package/dist/operations/services/operations-runner-smoke.d.ts +3 -2
  121. package/dist/operations/services/operations-runner-smoke.js +22 -4
  122. package/dist/operations/services/package-adapters.d.ts +77 -2
  123. package/dist/operations/services/package-adapters.js +629 -56
  124. package/dist/operations/services/package-reference-policy.d.ts +12 -88
  125. package/dist/operations/services/package-reference-policy.js +81 -213
  126. package/dist/operations/services/project-host-operations.d.ts +4 -4
  127. package/dist/operations/services/project-platform.d.ts +19 -193
  128. package/dist/operations/services/project-platform.js +31 -103
  129. package/dist/operations/services/project-web-monitor.d.ts +2 -2
  130. package/dist/operations/services/project-web-monitor.js +97 -2
  131. package/dist/operations/services/railway-api.d.ts +36 -7
  132. package/dist/operations/services/railway-api.js +331 -100
  133. package/dist/operations/services/railway-deploy.d.ts +7 -95
  134. package/dist/operations/services/railway-deploy.js +334 -742
  135. package/dist/operations/services/release-history.js +3 -4
  136. package/dist/operations/services/release-proof-ledger.d.ts +13 -0
  137. package/dist/operations/services/release-proof-ledger.js +81 -0
  138. package/dist/operations/services/release-proof-planner.d.ts +48 -0
  139. package/dist/operations/services/release-proof-planner.js +195 -0
  140. package/dist/operations/services/release-proof-runner.d.ts +16 -0
  141. package/dist/operations/services/release-proof-runner.js +169 -0
  142. package/dist/operations/services/release-proof.d.ts +81 -0
  143. package/dist/operations/services/release-proof.js +79 -0
  144. package/dist/operations/services/repository-save-orchestrator.d.ts +6 -7
  145. package/dist/operations/services/repository-save-orchestrator.js +353 -174
  146. package/dist/operations/services/runtime-paths.d.ts +1 -3
  147. package/dist/operations/services/runtime-paths.js +0 -4
  148. package/dist/operations/services/runtime-tools.d.ts +1 -192
  149. package/dist/operations/services/runtime-tools.js +4 -444
  150. package/dist/operations/services/save-deploy-preflight.js +9 -1
  151. package/dist/operations/services/template-host-bindings.d.ts +2 -2
  152. package/dist/operations/services/template-host-bindings.js +3 -2
  153. package/dist/operations/services/template-registry.d.ts +6 -6
  154. package/dist/operations/services/template-registry.js +33 -14
  155. package/dist/operations/services/template-secret-sync.d.ts +3 -3
  156. package/dist/operations/services/workflow-timing.d.ts +25 -0
  157. package/dist/operations/services/workflow-timing.js +79 -0
  158. package/dist/operations/services/workspace-dependency-mode.js +41 -4
  159. package/dist/operations/services/workspace-preflight.js +8 -8
  160. package/dist/operations/services/workspace-save-script.d.ts +4 -4
  161. package/dist/operations/services/workspace-save.d.ts +1 -0
  162. package/dist/operations/services/workspace-save.js +41 -18
  163. package/dist/operations/services/workspace-tools.js +40 -6
  164. package/dist/operations-registry.d.ts +1 -1
  165. package/dist/operations-registry.js +5 -6
  166. package/dist/operations-types.d.ts +1 -1
  167. package/dist/operations.d.ts +17 -11
  168. package/dist/operations.js +57 -3
  169. package/dist/platform/book-export.js +2 -0
  170. package/dist/platform/books-data.d.ts +1 -1
  171. package/dist/platform/config.d.ts +27 -0
  172. package/dist/platform/config.js +100 -0
  173. package/dist/platform/content-runtime-source.d.ts +54 -0
  174. package/dist/platform/content-runtime-source.js +169 -0
  175. package/dist/platform/contracts.d.ts +6 -1
  176. package/dist/platform/deploy-config.d.ts +1 -1
  177. package/dist/platform/deploy-config.js +7 -1
  178. package/dist/platform/deploy-runtime.d.ts +1 -1
  179. package/dist/platform/desired-state.d.ts +66 -0
  180. package/dist/platform/desired-state.js +1052 -0
  181. package/dist/platform/env.yaml +414 -19
  182. package/dist/platform/environment.d.ts +2 -2
  183. package/dist/platform/environment.js +54 -22
  184. package/dist/platform/local-content-materialization.d.ts +9 -0
  185. package/dist/platform/local-content-materialization.js +212 -0
  186. package/dist/platform/plugin.d.ts +5 -5
  187. package/dist/platform/plugins/runtime.d.ts +3 -3
  188. package/dist/platform/plugins/runtime.js +62 -1
  189. package/dist/platform/plugins.d.ts +6 -6
  190. package/dist/platform/published-content-pipeline.d.ts +3 -3
  191. package/dist/platform/published-content-pipeline.js +5 -1
  192. package/dist/platform/published-content.d.ts +4 -3
  193. package/dist/platform/site-config-schema.d.ts +1 -0
  194. package/dist/platform/site-config-schema.js +4 -1
  195. package/dist/platform/tenant/runtime-config.d.ts +152 -2
  196. package/dist/platform/tenant-config.d.ts +1 -1
  197. package/dist/platform/utils/site-config-schema.d.ts +154 -0
  198. package/dist/platform/utils/site-config-schema.js +400 -461
  199. package/dist/platform-operation-store.d.ts +1 -1
  200. package/dist/plugin-default.d.ts +1 -1
  201. package/dist/plugin-default.js +27 -12
  202. package/dist/project-import.d.ts +91 -0
  203. package/dist/project-import.js +257 -0
  204. package/dist/project-workflow.d.ts +1 -1
  205. package/dist/reconcile/bootstrap-systems.d.ts +2 -2
  206. package/dist/reconcile/bootstrap-systems.js +3 -3
  207. package/dist/reconcile/builtin-adapters.d.ts +7 -1
  208. package/dist/reconcile/builtin-adapters.js +2924 -346
  209. package/dist/reconcile/contracts.d.ts +15 -2
  210. package/dist/reconcile/desired-state.d.ts +2 -193
  211. package/dist/reconcile/desired-state.js +24 -33
  212. package/dist/reconcile/engine.d.ts +60 -397
  213. package/dist/reconcile/engine.js +182 -18
  214. package/dist/reconcile/index.d.ts +10 -10
  215. package/dist/reconcile/live-acceptance.d.ts +22 -1
  216. package/dist/reconcile/live-acceptance.js +456 -44
  217. package/dist/reconcile/providers/docker-private.d.ts +54 -0
  218. package/dist/reconcile/providers/docker-private.js +101 -0
  219. package/dist/reconcile/providers/github-private.d.ts +65 -0
  220. package/dist/reconcile/providers/github-private.js +119 -0
  221. package/dist/reconcile/providers/local-private.d.ts +28 -0
  222. package/dist/reconcile/providers/local-private.js +75 -0
  223. package/dist/reconcile/providers/railway-iac.d.ts +66 -0
  224. package/dist/reconcile/providers/railway-iac.js +275 -0
  225. package/dist/reconcile/providers/release-private.d.ts +92 -0
  226. package/dist/reconcile/providers/release-private.js +152 -0
  227. package/dist/reconcile/registry.d.ts +2 -2
  228. package/dist/reconcile/registry.js +16 -1
  229. package/dist/reconcile/state.d.ts +1 -1
  230. package/dist/reconcile/state.js +3 -40
  231. package/dist/reconcile/units.d.ts +1 -1
  232. package/dist/reconcile/units.js +7 -1
  233. package/dist/remote.d.ts +6 -6
  234. package/dist/scenes/artifacts.d.ts +16 -0
  235. package/dist/scenes/artifacts.js +61 -0
  236. package/dist/scenes/auth.d.ts +2 -0
  237. package/dist/scenes/auth.js +28 -0
  238. package/dist/scenes/base-url.d.ts +12 -0
  239. package/dist/scenes/base-url.js +123 -0
  240. package/dist/scenes/builtin-plugins.d.ts +2 -0
  241. package/dist/scenes/builtin-plugins.js +447 -0
  242. package/dist/scenes/checkpoints.d.ts +14 -0
  243. package/dist/scenes/checkpoints.js +33 -0
  244. package/dist/scenes/device-matrix.d.ts +2 -0
  245. package/dist/scenes/device-matrix.js +97 -0
  246. package/dist/scenes/devices.d.ts +11 -0
  247. package/dist/scenes/devices.js +22 -0
  248. package/dist/scenes/diagnostics.d.ts +5 -0
  249. package/dist/scenes/diagnostics.js +22 -0
  250. package/dist/scenes/diagram-providers.d.ts +2 -0
  251. package/dist/scenes/diagram-providers.js +181 -0
  252. package/dist/scenes/diagram-validation.d.ts +22 -0
  253. package/dist/scenes/diagram-validation.js +74 -0
  254. package/dist/scenes/environment.d.ts +2 -0
  255. package/dist/scenes/environment.js +65 -0
  256. package/dist/scenes/evidence-bundle.d.ts +5 -0
  257. package/dist/scenes/evidence-bundle.js +42 -0
  258. package/dist/scenes/evidence-report.d.ts +10 -0
  259. package/dist/scenes/evidence-report.js +73 -0
  260. package/dist/scenes/evidence.d.ts +16 -0
  261. package/dist/scenes/evidence.js +277 -0
  262. package/dist/scenes/index.d.ts +48 -0
  263. package/dist/scenes/index.js +312 -0
  264. package/dist/scenes/inspect.d.ts +9 -0
  265. package/dist/scenes/inspect.js +64 -0
  266. package/dist/scenes/loader.d.ts +3 -0
  267. package/dist/scenes/loader.js +38 -0
  268. package/dist/scenes/logs.d.ts +2 -0
  269. package/dist/scenes/logs.js +47 -0
  270. package/dist/scenes/operations.d.ts +3 -0
  271. package/dist/scenes/operations.js +128 -0
  272. package/dist/scenes/phase0.d.ts +9 -0
  273. package/dist/scenes/phase0.js +637 -0
  274. package/dist/scenes/planner.d.ts +12 -0
  275. package/dist/scenes/planner.js +166 -0
  276. package/dist/scenes/playwright-adapter.d.ts +2 -0
  277. package/dist/scenes/playwright-adapter.js +63 -0
  278. package/dist/scenes/plugins.d.ts +5 -0
  279. package/dist/scenes/plugins.js +115 -0
  280. package/dist/scenes/progress.d.ts +17 -0
  281. package/dist/scenes/progress.js +24 -0
  282. package/dist/scenes/publish-destinations.d.ts +12 -0
  283. package/dist/scenes/publish-destinations.js +99 -0
  284. package/dist/scenes/publish-plan-report.d.ts +10 -0
  285. package/dist/scenes/publish-plan-report.js +70 -0
  286. package/dist/scenes/publish-plan.d.ts +15 -0
  287. package/dist/scenes/publish-plan.js +248 -0
  288. package/dist/scenes/publish-redaction.d.ts +16 -0
  289. package/dist/scenes/publish-redaction.js +148 -0
  290. package/dist/scenes/publish-release-record.d.ts +13 -0
  291. package/dist/scenes/publish-release-record.js +34 -0
  292. package/dist/scenes/publish-report.d.ts +10 -0
  293. package/dist/scenes/publish-report.js +67 -0
  294. package/dist/scenes/publish.d.ts +16 -0
  295. package/dist/scenes/publish.js +298 -0
  296. package/dist/scenes/registry.d.ts +12 -0
  297. package/dist/scenes/registry.js +65 -0
  298. package/dist/scenes/remotion-adapter.d.ts +3 -0
  299. package/dist/scenes/remotion-adapter.js +94 -0
  300. package/dist/scenes/remotion-composition-registry.d.ts +2 -0
  301. package/dist/scenes/remotion-composition-registry.js +12 -0
  302. package/dist/scenes/remotion-compositions.d.ts +15 -0
  303. package/dist/scenes/remotion-compositions.js +464 -0
  304. package/dist/scenes/remotion-diagrams.d.ts +9 -0
  305. package/dist/scenes/remotion-diagrams.js +188 -0
  306. package/dist/scenes/remotion-input.d.ts +13 -0
  307. package/dist/scenes/remotion-input.js +291 -0
  308. package/dist/scenes/remotion-visuals.d.ts +29 -0
  309. package/dist/scenes/remotion-visuals.js +198 -0
  310. package/dist/scenes/render-media-assets.d.ts +9 -0
  311. package/dist/scenes/render-media-assets.js +117 -0
  312. package/dist/scenes/render-report.d.ts +10 -0
  313. package/dist/scenes/render-report.js +27 -0
  314. package/dist/scenes/render.d.ts +2 -0
  315. package/dist/scenes/render.js +218 -0
  316. package/dist/scenes/reporter.d.ts +3 -0
  317. package/dist/scenes/reporter.js +101 -0
  318. package/dist/scenes/resume.d.ts +2 -0
  319. package/dist/scenes/resume.js +79 -0
  320. package/dist/scenes/runner.d.ts +2 -0
  321. package/dist/scenes/runner.js +674 -0
  322. package/dist/scenes/schema.d.ts +6 -0
  323. package/dist/scenes/schema.js +994 -0
  324. package/dist/scenes/seed.d.ts +2 -0
  325. package/dist/scenes/seed.js +83 -0
  326. package/dist/scenes/segments.d.ts +15 -0
  327. package/dist/scenes/segments.js +79 -0
  328. package/dist/scenes/selectors.d.ts +3 -0
  329. package/dist/scenes/selectors.js +21 -0
  330. package/dist/scenes/timeline.d.ts +11 -0
  331. package/dist/scenes/timeline.js +26 -0
  332. package/dist/scenes/timeouts.d.ts +6 -0
  333. package/dist/scenes/timeouts.js +17 -0
  334. package/dist/scenes/training-captions.d.ts +14 -0
  335. package/dist/scenes/training-captions.js +98 -0
  336. package/dist/scenes/training-report.d.ts +10 -0
  337. package/dist/scenes/training-report.js +78 -0
  338. package/dist/scenes/training-transcript.d.ts +24 -0
  339. package/dist/scenes/training-transcript.js +204 -0
  340. package/dist/scenes/training.d.ts +10 -0
  341. package/dist/scenes/training.js +134 -0
  342. package/dist/scenes/types.d.ts +1872 -0
  343. package/dist/scenes/types.js +8 -0
  344. package/dist/scenes/visual-audit-contact-sheets.d.ts +6 -0
  345. package/dist/scenes/visual-audit-contact-sheets.js +119 -0
  346. package/dist/scenes/visual-audit-fixtures.d.ts +25 -0
  347. package/dist/scenes/visual-audit-fixtures.js +210 -0
  348. package/dist/scenes/visual-audit-report.d.ts +11 -0
  349. package/dist/scenes/visual-audit-report.js +85 -0
  350. package/dist/scenes/visual-audit-review.d.ts +23 -0
  351. package/dist/scenes/visual-audit-review.js +829 -0
  352. package/dist/scenes/visual-audit-routes.d.ts +13 -0
  353. package/dist/scenes/visual-audit-routes.js +308 -0
  354. package/dist/scenes/visual-audit.d.ts +3 -0
  355. package/dist/scenes/visual-audit.js +596 -0
  356. package/dist/scripts/build-dist.js +154 -40
  357. package/dist/scripts/check-build-warnings.js +42 -53
  358. package/dist/scripts/cleanup-markdown.js +1 -1
  359. package/dist/scripts/cli-test-fixtures.js +24 -28
  360. package/dist/scripts/migrate-journey-csv-to-guarantees.js +140 -0
  361. package/dist/scripts/package-tools.js +12 -1
  362. package/dist/scripts/prepare.js +3 -7
  363. package/dist/scripts/release-verify.js +2 -5
  364. package/dist/scripts/run-fixture-astro-command.js +1 -1
  365. package/dist/scripts/template-catalog.test.js +68 -82
  366. package/dist/scripts/tenant-dev.js +0 -10
  367. package/dist/scripts/test-cloudflare-local.js +1 -1
  368. package/dist/scripts/test-scaffold.js +0 -1
  369. package/dist/scripts/test-smoke.js +3 -3
  370. package/dist/scripts/treeseed-build-dist.js +4 -7
  371. package/dist/scripts/treeseed-release-verify.js +1 -1
  372. package/dist/scripts/verify-driver.js +30 -21
  373. package/dist/scripts/workflow-commands.test.js +18 -27
  374. package/dist/scripts/workspace-command-e2e.js +1 -1
  375. package/dist/scripts/workspace-lint.js +6 -0
  376. package/dist/scripts/workspace-release-test.js +90 -1
  377. package/dist/scripts/workspace-test.js +6 -0
  378. package/dist/sdk-dispatch.d.ts +1 -1
  379. package/dist/sdk-dispatch.js +0 -16
  380. package/dist/sdk-fields.d.ts +1 -1
  381. package/dist/sdk-filters.d.ts +1 -1
  382. package/dist/sdk-types.d.ts +1184 -113
  383. package/dist/sdk-types.js +393 -0
  384. package/dist/sdk.d.ts +74 -79
  385. package/dist/sdk.js +27 -36
  386. package/dist/secrets-capability.d.ts +421 -0
  387. package/dist/secrets-capability.js +530 -0
  388. package/dist/seeds/normalize.js +1 -0
  389. package/dist/seeds/planner.js +38 -0
  390. package/dist/seeds/schema.js +293 -4
  391. package/dist/seeds/types.d.ts +60 -0
  392. package/dist/seeds/types.js +9 -1
  393. package/dist/service-credentials.d.ts +54 -0
  394. package/dist/service-credentials.js +112 -0
  395. package/dist/stores/cursor-store.d.ts +2 -2
  396. package/dist/stores/envelopes.d.ts +1 -1
  397. package/dist/stores/helpers.d.ts +1 -1
  398. package/dist/stores/lease-store.d.ts +2 -2
  399. package/dist/stores/message-store.d.ts +2 -2
  400. package/dist/stores/operational-store.d.ts +3 -26
  401. package/dist/stores/operational-store.js +0 -225
  402. package/dist/stores/project-workflow-store.d.ts +2 -2
  403. package/dist/stores/run-store.d.ts +2 -3
  404. package/dist/stores/run-store.js +0 -98
  405. package/dist/stores/subscription-store.d.ts +2 -3
  406. package/dist/stores/subscription-store.js +0 -100
  407. package/dist/template-catalog.d.ts +1 -1
  408. package/dist/template-launch-requirements.d.ts +2 -2
  409. package/dist/template-launch-ui.d.ts +2 -2
  410. package/dist/treedx/adapters.d.ts +6 -6
  411. package/dist/treedx/client.d.ts +1 -1
  412. package/dist/treedx/errors.d.ts +1 -1
  413. package/dist/treedx/federated-client.d.ts +3 -3
  414. package/dist/treedx/graph-adapter.d.ts +2 -2
  415. package/dist/treedx/index.d.ts +14 -14
  416. package/dist/treedx/market-integration.d.ts +1 -1
  417. package/dist/treedx/ports.d.ts +30 -30
  418. package/dist/treedx/query-adapter.d.ts +3 -3
  419. package/dist/treedx/registry-client.d.ts +2 -2
  420. package/dist/treedx/repository-adapter.d.ts +4 -4
  421. package/dist/treedx/repository-adapter.js +14 -3
  422. package/dist/treedx/sdk-integration.d.ts +3 -3
  423. package/dist/treedx/types.d.ts +2 -2
  424. package/dist/treedx/workspace-adapter.d.ts +2 -2
  425. package/dist/treedx-backends.d.ts +13 -11
  426. package/dist/treedx-backends.js +52 -50
  427. package/dist/treedx-client.d.ts +3 -0
  428. package/dist/treedx-client.js +10 -1
  429. package/dist/treeseed/services/compose.yml +2 -3
  430. package/dist/treeseed/template-catalog/catalog.fixture.json +4 -4
  431. package/dist/types/agents.d.ts +256 -0
  432. package/dist/types/agents.js +42 -1
  433. package/dist/verification.d.ts +1 -0
  434. package/dist/verification.js +143 -14
  435. package/dist/workflow/operations.d.ts +510 -559
  436. package/dist/workflow/operations.js +1891 -1342
  437. package/dist/workflow/policy.js +19 -7
  438. package/dist/workflow/runs.d.ts +9 -3
  439. package/dist/workflow/runs.js +66 -26
  440. package/dist/workflow/session.d.ts +4 -1
  441. package/dist/workflow/session.js +50 -10
  442. package/dist/workflow/worktrees.d.ts +6 -2
  443. package/dist/workflow/worktrees.js +98 -15
  444. package/dist/workflow-state.d.ts +5 -5
  445. package/dist/workflow-state.js +27 -17
  446. package/dist/workflow-support.d.ts +26 -25
  447. package/dist/workflow-support.js +27 -31
  448. package/dist/workflow.d.ts +46 -16
  449. package/dist/workflow.js +19 -7
  450. package/drizzle/d1/0000_treeseed_d1.sql +0 -18
  451. package/drizzle/market/0000_market_control_plane.sql +1793 -1499
  452. package/drizzle/market/0005_agent_capacity_coordination.sql +145 -0
  453. package/drizzle/market/0006_provider_assignment_lifecycle.sql +9 -0
  454. package/drizzle/market/0007_agent_architecture_gap_closure.sql +157 -0
  455. package/drizzle/market/0008_agent_capacity_operational_closure.sql +27 -0
  456. package/drizzle/market/0009_agent_capacity_runtime_hardening.sql +29 -0
  457. package/drizzle/market/0010_secrets_capability_persistence.sql +130 -0
  458. package/drizzle/market/0011_github_app_adapter.sql +47 -0
  459. package/drizzle/market/0012_workday_test_runs.sql +44 -0
  460. package/drizzle/market/0013_runtime_task_lifecycle.sql +39 -0
  461. package/drizzle/market/0014_governance_pipeline.sql +189 -0
  462. package/package.json +75 -18
  463. package/scripts/{verify-driver.mjs → verify-driver.ts} +19 -4
  464. package/templates/github/deploy-web.workflow.yml +12 -8
  465. package/dist/operations/services/mailpit-runtime.d.ts +0 -20
  466. package/dist/operations/services/mailpit-runtime.js +0 -67
  467. package/dist/operations/services/release-candidate.d.ts +0 -60
  468. package/dist/operations/services/release-candidate.js +0 -953
  469. package/dist/scripts/ensure-mailpit.js +0 -48
  470. package/dist/scripts/logs-mailpit.js +0 -2
  471. package/dist/scripts/run-ts.js +0 -45
  472. package/dist/scripts/stop-mailpit.js +0 -5
  473. package/dist/scripts/treeseed-run-ts.js +0 -45
@@ -0,0 +1,1052 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, readFileSync, statSync } from "node:fs";
3
+ import { basename, dirname, resolve as resolvePath } from "node:path";
4
+ import { parse as parseYaml } from "yaml";
5
+ import {
6
+ discoverTreeseedPackageAdapters
7
+ } from "../operations/services/package-adapters.js";
8
+ import { resolveCapacityProviderLaunchPlan } from "../capacity-provider.js";
9
+ import { workspaceRoot } from "../operations/services/workspace-tools.js";
10
+ import {
11
+ checkedOutTemplateRepositories
12
+ } from "../operations/services/managed-repositories.js";
13
+ import { deriveTreeseedDesiredUnits } from "../reconcile/desired-state.js";
14
+ import {
15
+ buildProjectLocalContentResources
16
+ } from "./local-content-materialization.js";
17
+ function resolveLocalGitCommonDir(tenantRoot) {
18
+ const dotGitPath = resolvePath(tenantRoot, ".git");
19
+ if (!existsSync(dotGitPath)) return "";
20
+ try {
21
+ if (statSync(dotGitPath).isDirectory()) return dotGitPath;
22
+ const stat = readFileSync(dotGitPath, "utf8");
23
+ const match = /^gitdir:\s*(.+)\s*$/imu.exec(stat);
24
+ if (!match?.[1]) return dotGitPath;
25
+ const gitDir = resolvePath(tenantRoot, match[1].trim());
26
+ const commonDirPath = resolvePath(gitDir, "commondir");
27
+ if (existsSync(commonDirPath)) {
28
+ const commonDir = readFileSync(commonDirPath, "utf8").trim();
29
+ if (commonDir) return resolvePath(gitDir, commonDir);
30
+ }
31
+ const marker = `${resolvePath("/").replace(/\/$/u, "")}.git/worktrees/`;
32
+ const normalized = gitDir.replace(/\\/gu, "/");
33
+ const markerIndex = normalized.indexOf("/.git/worktrees/");
34
+ if (markerIndex >= 0) return normalized.slice(0, markerIndex + "/.git".length);
35
+ if (normalized.includes(marker)) return normalized.slice(0, normalized.indexOf(marker) + "/.git".length);
36
+ return dirname(gitDir);
37
+ } catch {
38
+ return "";
39
+ }
40
+ }
41
+ const INTERNAL_PACKAGE_DEPENDENCY_FIELDS = [
42
+ "dependencies",
43
+ "optionalDependencies",
44
+ "peerDependencies",
45
+ "devDependencies"
46
+ ];
47
+ function hashJson(value) {
48
+ return createHash("sha256").update(JSON.stringify(value)).digest("hex");
49
+ }
50
+ function reconcileIdentityForGraph(workspaceId, environment) {
51
+ return {
52
+ teamId: workspaceId,
53
+ projectId: workspaceId,
54
+ slug: workspaceId,
55
+ environment,
56
+ deploymentKey: `${workspaceId}:${environment}`,
57
+ environmentKey: environment
58
+ };
59
+ }
60
+ function environmentFromTarget(target) {
61
+ if (target.kind === "persistent") return target.scope;
62
+ return "staging";
63
+ }
64
+ function packageReleaseCapability(adapter) {
65
+ if (adapter.artifacts.some((artifact) => artifact.provider === "docker")) return "image";
66
+ if (adapter.artifacts.some((artifact) => artifact.provider === "npm")) return "npm";
67
+ if (adapter.releaseChecks.length > 0) return "deploy-only";
68
+ return "none";
69
+ }
70
+ function packageUnitFromAdapter(adapter) {
71
+ return {
72
+ id: adapter.id,
73
+ name: adapter.name,
74
+ kind: adapter.kind,
75
+ path: adapter.relativeDir,
76
+ version: adapter.version,
77
+ publishTarget: adapter.publishTarget,
78
+ manifestPath: adapter.manifestPath,
79
+ repository: typeof adapter.metadata.repository === "string" ? adapter.metadata.repository : null,
80
+ releaseCapability: packageReleaseCapability(adapter),
81
+ requiredSecrets: Array.isArray(adapter.metadata.requiredSecrets) ? adapter.metadata.requiredSecrets : [],
82
+ requiredVariables: Array.isArray(adapter.metadata.requiredVariables) ? adapter.metadata.requiredVariables : [],
83
+ githubEnvironments: Array.isArray(adapter.metadata.githubEnvironments) ? adapter.metadata.githubEnvironments : []
84
+ };
85
+ }
86
+ function templateReleaseTag(manifest) {
87
+ return manifest.version ? `${manifest.release.tagPrefix}${manifest.id}/v${manifest.version}` : null;
88
+ }
89
+ function templateUnitFromRepository(repo) {
90
+ const manifest = repo.templateManifest;
91
+ return {
92
+ id: manifest.id,
93
+ name: manifest.name,
94
+ category: manifest.category,
95
+ path: repo.relativeDir,
96
+ version: manifest.version,
97
+ repository: manifest.repository,
98
+ manifestPath: manifest.manifestPath,
99
+ releaseTag: templateReleaseTag(manifest),
100
+ recordPath: manifest.release.recordPath
101
+ };
102
+ }
103
+ function stringRecord(value) {
104
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
105
+ }
106
+ function stringArray(value) {
107
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
108
+ }
109
+ function workflowName(value, fallback) {
110
+ return (typeof value === "string" && value.trim() ? value.trim() : fallback).replace(/^\.github\/workflows\//u, "");
111
+ }
112
+ function packageShortSha(adapter) {
113
+ const envSha = process.env.GITHUB_SHA;
114
+ if (typeof envSha === "string" && /^[a-f0-9]{7,40}$/iu.test(envSha)) return envSha.slice(0, 12).toLowerCase();
115
+ return createHash("sha256").update(`${adapter.id}:${adapter.dir}:${adapter.version ?? ""}`).digest("hex").slice(0, 12);
116
+ }
117
+ function materializeDockerImageTags(tags, adapter, branch) {
118
+ const shortSha = packageShortSha(adapter);
119
+ const branchSlug = branch.replace(/[^A-Za-z0-9_.-]+/gu, "-").replace(/^-+|-+$/gu, "") || "branch";
120
+ return tags.map((tag) => tag.replace(/<short-sha>/gu, shortSha).replace(/<branch-slug>/gu, branchSlug).replace(/<branch>/gu, branchSlug).replace(/<version>/gu, String(adapter.version ?? "latest").replace(/[^A-Za-z0-9_.-]+/gu, "-")));
121
+ }
122
+ function dockerPlatforms(artifactArchitectures, adapterArchitectures) {
123
+ const architectures = stringArray(artifactArchitectures).length > 0 ? stringArray(artifactArchitectures) : stringArray(adapterArchitectures);
124
+ const normalized = architectures.length > 0 ? architectures : ["amd64", "arm64"];
125
+ return normalized.map((arch) => arch.startsWith("linux/") ? arch : `linux/${arch}`);
126
+ }
127
+ function localDockerPlatform() {
128
+ if (process.arch === "arm64") return "linux/arm64";
129
+ if (process.arch === "arm") return "linux/arm/v7";
130
+ return "linux/amd64";
131
+ }
132
+ function safeTreeDxRepositoryName(value) {
133
+ return value.trim().toLowerCase().replace(/[^a-z0-9_.-]+/gu, "-").replace(/^-+|-+$/gu, "") || "project";
134
+ }
135
+ function localTreeDxContentProjects(tenantRoot) {
136
+ const seedPath = resolvePath(tenantRoot, "seeds", "treeseed.yaml");
137
+ if (!existsSync(seedPath)) return [];
138
+ const parsed = parseYaml(readFileSync(seedPath, "utf8"));
139
+ const resources = stringRecord(parsed?.resources);
140
+ const projects = Array.isArray(resources.projects) ? resources.projects : [];
141
+ return projects.flatMap((entry) => {
142
+ const project = stringRecord(entry);
143
+ const slug = typeof project.slug === "string" && project.slug.trim() ? project.slug.trim() : "";
144
+ const repository = stringRecord(project.repository);
145
+ const architecture = stringRecord(project.architecture);
146
+ const contentPath = typeof architecture.contentPath === "string" && architecture.contentPath.trim() ? architecture.contentPath.trim() : null;
147
+ if (!slug || !contentPath) return [];
148
+ const checkoutPath = typeof repository.checkoutPath === "string" && repository.checkoutPath.trim() ? repository.checkoutPath.trim() : ".";
149
+ return [{
150
+ projectKey: typeof project.key === "string" ? project.key : `project:treeseed/${slug}`,
151
+ slug,
152
+ repositoryName: safeTreeDxRepositoryName(`treeseed-${slug}`),
153
+ repositoryId: safeTreeDxRepositoryName(`treeseed-${slug}`),
154
+ localRoot: checkoutPath === "." ? tenantRoot : resolvePath(tenantRoot, checkoutPath),
155
+ contentPath,
156
+ defaultRef: "refs/heads/main",
157
+ seedPaths: [
158
+ `${contentPath.replace(/\/+$/u, "")}/objectives`,
159
+ `${contentPath.replace(/\/+$/u, "")}/agents`
160
+ ]
161
+ }];
162
+ });
163
+ }
164
+ function releasePhaseForEnvironment(environment) {
165
+ return environment === "prod" ? "release" : "stage";
166
+ }
167
+ function internalPackageDependencies(packages, pkg) {
168
+ const packageIds = new Set(packages.map((entry) => entry.id));
169
+ const packageJsonPath = resolvePath(pkg.path, "package.json");
170
+ if (!existsSync(packageJsonPath)) return [];
171
+ try {
172
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
173
+ const dependencies = /* @__PURE__ */ new Set();
174
+ for (const field of INTERNAL_PACKAGE_DEPENDENCY_FIELDS) {
175
+ const entries = packageJson[field];
176
+ if (!entries || typeof entries !== "object" || Array.isArray(entries)) continue;
177
+ for (const dependencyName of Object.keys(entries)) {
178
+ if (dependencyName !== pkg.id && packageIds.has(dependencyName)) {
179
+ dependencies.add(dependencyName);
180
+ }
181
+ }
182
+ }
183
+ return [...dependencies].sort();
184
+ } catch {
185
+ return [];
186
+ }
187
+ }
188
+ function resourceKindForUnit(unit) {
189
+ if (unit.provider === "railway") {
190
+ if (unit.unitType.startsWith("railway-service:")) return "railway-service";
191
+ if (unit.unitType === "custom-domain:api") return "railway-domain";
192
+ }
193
+ if (unit.provider === "cloudflare" || unit.provider === "cloudflare-dns") return "cloudflare-resource";
194
+ if (unit.provider === "treeseed" && /runtime$/u.test(unit.unitType)) return "release-gate";
195
+ return "cloudflare-resource";
196
+ }
197
+ function serviceIdForUnit(unit) {
198
+ const serviceKey = unit.metadata.serviceKey;
199
+ if (typeof serviceKey === "string" && serviceKey.trim()) return serviceKey;
200
+ if (unit.unitType.startsWith("railway-service:")) return unit.unitType.slice("railway-service:".length);
201
+ return null;
202
+ }
203
+ function packageIdForUnit(unit) {
204
+ const app = unit.metadata.applicationId ?? unit.metadata.packageId;
205
+ return typeof app === "string" && app.trim() ? app : null;
206
+ }
207
+ function resourceFromUnit(unit, environment) {
208
+ return {
209
+ id: unit.unitId,
210
+ kind: resourceKindForUnit(unit),
211
+ provider: unit.provider,
212
+ environment,
213
+ packageId: packageIdForUnit(unit),
214
+ serviceId: serviceIdForUnit(unit),
215
+ logicalName: unit.logicalName,
216
+ dependencies: unit.dependencies,
217
+ spec: {
218
+ unitType: unit.unitType,
219
+ identity: unit.identity,
220
+ target: unit.target,
221
+ spec: unit.spec,
222
+ secrets: Object.keys(unit.secrets),
223
+ metadata: unit.metadata
224
+ },
225
+ source: {
226
+ type: "reconcile-unit",
227
+ id: unit.unitId
228
+ }
229
+ };
230
+ }
231
+ function packageResources(adapter, environment) {
232
+ const resources = [];
233
+ const packageId = adapter.id;
234
+ const repository = typeof adapter.metadata.repository === "string" ? adapter.metadata.repository : null;
235
+ const dockerImageConfig = stringRecord(adapter.metadata.dockerImages);
236
+ const dockerWorkflow = workflowName(
237
+ environment === "prod" ? dockerImageConfig.releaseWorkflow : null,
238
+ environment === "prod" ? "publish.yml" : "source-build"
239
+ );
240
+ resources.push({
241
+ id: `package-manifest:${packageId}`,
242
+ kind: "package-manifest",
243
+ provider: "treeseed",
244
+ environment,
245
+ packageId,
246
+ serviceId: null,
247
+ logicalName: `${packageId} manifest`,
248
+ dependencies: [],
249
+ spec: {
250
+ packageId,
251
+ packageRoot: adapter.dir,
252
+ manifestPath: adapter.manifestPath,
253
+ kind: adapter.kind,
254
+ type: adapter.metadata.type ?? null,
255
+ releaseCapability: packageReleaseCapability(adapter),
256
+ requiredSecrets: adapter.metadata.requiredSecrets ?? [],
257
+ requiredVariables: adapter.metadata.requiredVariables ?? [],
258
+ githubEnvironments: adapter.metadata.githubEnvironments ?? []
259
+ },
260
+ source: { type: "package-adapter", id: packageId }
261
+ });
262
+ if (adapter.releaseChecks.length > 0) {
263
+ resources.push({
264
+ id: `package-workflow:${packageId}`,
265
+ kind: "package-workflow",
266
+ provider: "github",
267
+ environment,
268
+ packageId,
269
+ serviceId: null,
270
+ logicalName: `${packageId} workflows`,
271
+ dependencies: [`package-manifest:${packageId}`],
272
+ spec: {
273
+ packageId,
274
+ packageRoot: adapter.dir,
275
+ repository,
276
+ releaseChecks: adapter.releaseChecks,
277
+ verifyCommands: adapter.verifyCommands,
278
+ githubEnvironments: adapter.metadata.githubEnvironments ?? [],
279
+ workflowTemplateVersion: adapter.metadata.workflowTemplateVersion ?? 1
280
+ },
281
+ source: { type: "package-adapter", id: packageId }
282
+ });
283
+ for (const environmentName of Array.isArray(adapter.metadata.githubEnvironments) ? adapter.metadata.githubEnvironments : []) {
284
+ if (typeof environmentName !== "string" || !environmentName.trim()) continue;
285
+ resources.push({
286
+ id: `github-environment:${packageId}:${environmentName}`,
287
+ kind: "github-environment",
288
+ provider: "github",
289
+ environment,
290
+ packageId,
291
+ serviceId: null,
292
+ logicalName: `${packageId} ${environmentName}`,
293
+ dependencies: [`package-workflow:${packageId}`],
294
+ spec: {
295
+ packageId,
296
+ packageRoot: adapter.dir,
297
+ repository,
298
+ environment: environmentName
299
+ },
300
+ source: { type: "package-adapter", id: packageId }
301
+ });
302
+ for (const secretName of Array.isArray(adapter.metadata.requiredSecrets) ? adapter.metadata.requiredSecrets : []) {
303
+ if (typeof secretName !== "string" || !secretName.trim()) continue;
304
+ resources.push({
305
+ id: `github-secret-binding:${packageId}:${environmentName}:${secretName}`,
306
+ kind: "github-secret-binding",
307
+ provider: "github",
308
+ environment,
309
+ packageId,
310
+ serviceId: null,
311
+ logicalName: `${packageId} ${environmentName} ${secretName}`,
312
+ dependencies: [`github-environment:${packageId}:${environmentName}`],
313
+ spec: {
314
+ packageId,
315
+ packageRoot: adapter.dir,
316
+ repository,
317
+ environment: environmentName,
318
+ secretName,
319
+ envName: secretName
320
+ },
321
+ source: { type: "package-adapter", id: packageId }
322
+ });
323
+ }
324
+ for (const variableName of Array.isArray(adapter.metadata.requiredVariables) ? adapter.metadata.requiredVariables : []) {
325
+ if (typeof variableName !== "string" || !variableName.trim()) continue;
326
+ resources.push({
327
+ id: `github-variable-binding:${packageId}:${environmentName}:${variableName}`,
328
+ kind: "github-variable-binding",
329
+ provider: "github",
330
+ environment,
331
+ packageId,
332
+ serviceId: null,
333
+ logicalName: `${packageId} ${environmentName} ${variableName}`,
334
+ dependencies: [`github-environment:${packageId}:${environmentName}`],
335
+ spec: {
336
+ packageId,
337
+ packageRoot: adapter.dir,
338
+ repository,
339
+ environment: environmentName,
340
+ variableName,
341
+ envName: variableName
342
+ },
343
+ source: { type: "package-adapter", id: packageId }
344
+ });
345
+ }
346
+ }
347
+ }
348
+ for (const artifact of adapter.artifacts) {
349
+ if (artifact.provider !== "docker") continue;
350
+ const dockerfile = artifact.dockerfile ?? "Dockerfile";
351
+ const context = artifact.context ?? ".";
352
+ const platforms = dockerPlatforms(artifact.architectures, adapter.metadata.dockerImageArchitectures);
353
+ const localBuildPlatforms = environment === "local" ? [localDockerPlatform()] : platforms;
354
+ const branch = environment === "prod" ? "main" : "staging";
355
+ const configuredTags = stringRecord(dockerImageConfig.tags);
356
+ const imageTagTemplates = environment === "prod" ? stringArray(configuredTags.release).length > 0 ? stringArray(configuredTags.release) : ["<version>"] : [];
357
+ const imageTags = materializeDockerImageTags(imageTagTemplates, adapter, branch);
358
+ const workflowSpec = repository ? {
359
+ packageId,
360
+ repository,
361
+ workflow: dockerWorkflow,
362
+ branch,
363
+ inputs: {
364
+ image: artifact.name,
365
+ ...artifact.target ? { target: artifact.target } : {}
366
+ },
367
+ wait: environment === "prod"
368
+ } : null;
369
+ resources.push({
370
+ id: `package-image:${artifact.name}`,
371
+ kind: "package-image",
372
+ provider: "dockerhub",
373
+ environment,
374
+ packageId,
375
+ serviceId: null,
376
+ logicalName: artifact.name,
377
+ dependencies: [`package-workflow:${packageId}`],
378
+ spec: {
379
+ packageId,
380
+ packageRoot: adapter.dir,
381
+ repository,
382
+ image: artifact.name,
383
+ role: artifact.role ?? null,
384
+ tags: imageTags,
385
+ architectures: platforms,
386
+ workflow: dockerWorkflow,
387
+ workflowDispatch: workflowSpec,
388
+ requiredSecrets: ["TREESEED_DOCKERHUB_TOKEN"],
389
+ requiredVariables: ["TREESEED_DOCKERHUB_USERNAME"]
390
+ },
391
+ source: { type: "package-adapter", id: packageId }
392
+ });
393
+ resources.push({
394
+ id: `docker-image-build:${artifact.name}`,
395
+ kind: "docker-image-build",
396
+ provider: "docker",
397
+ environment,
398
+ packageId,
399
+ serviceId: null,
400
+ logicalName: artifact.name,
401
+ dependencies: [`package-manifest:${packageId}`],
402
+ spec: {
403
+ packageId,
404
+ packageRoot: adapter.dir,
405
+ image: artifact.name,
406
+ dockerfile,
407
+ context,
408
+ prepareCommand: packageId === "@treeseed/agent" ? {
409
+ command: "bash",
410
+ args: ["-lc", "ulimit -n 65535 2>/dev/null || true; npm run capacity-provider:build -- --prepare-only"]
411
+ } : null,
412
+ target: artifact.target ?? null,
413
+ role: artifact.role ?? null,
414
+ platforms: localBuildPlatforms,
415
+ tags: imageTags.map((tag) => `${artifact.name}:${tag}`),
416
+ labels: {
417
+ "org.opencontainers.image.source": repository ? `https://github.com/${repository}` : adapter.relativeDir,
418
+ "org.treeseed.package": packageId
419
+ },
420
+ buildArgs: {},
421
+ push: false,
422
+ load: true,
423
+ provenance: false,
424
+ workflow: dockerWorkflow
425
+ },
426
+ source: { type: "package-adapter", id: packageId }
427
+ });
428
+ }
429
+ return resources;
430
+ }
431
+ function templateResources(templates, environment) {
432
+ return templates.map((template) => ({
433
+ id: `template-manifest:${template.id}`,
434
+ kind: "template-manifest",
435
+ provider: "treeseed",
436
+ environment,
437
+ packageId: template.id,
438
+ serviceId: null,
439
+ logicalName: `${template.name} template manifest`,
440
+ dependencies: [],
441
+ spec: {
442
+ templateId: template.id,
443
+ templateName: template.name,
444
+ category: template.category,
445
+ templateRoot: template.path,
446
+ manifestPath: template.manifestPath,
447
+ version: template.version,
448
+ repository: template.repository,
449
+ releaseTag: template.releaseTag,
450
+ recordPath: template.recordPath
451
+ },
452
+ source: { type: "package-adapter", id: `template:${template.id}` }
453
+ }));
454
+ }
455
+ function localDevelopmentResources(tenantRoot, environment, localContent) {
456
+ if (environment !== "local") return [];
457
+ const composeId = "local-docker-compose:agent-capacity-provider";
458
+ const treeDxComposeId = "local-docker-compose:treedx";
459
+ const apiPostgresComposeId = "local-docker-compose:api-postgres";
460
+ const mailpitComposeId = "local-docker-compose:mailpit";
461
+ const capacityProviderDataDir = resolvePath(tenantRoot, ".treeseed/local-capacity-provider/data");
462
+ const localGitCommonDir = resolveLocalGitCommonDir(tenantRoot);
463
+ const hostCodexAuthFile = [
464
+ process.env.TREESEED_CODEX_AUTH_FILE,
465
+ process.env.CODEX_AUTH_FILE,
466
+ process.env.HOME ? resolvePath(process.env.HOME, ".codex/auth.json") : ""
467
+ ].find((candidate) => candidate && existsSync(candidate)) ?? "";
468
+ const capacityPlan = resolveCapacityProviderLaunchPlan({
469
+ schemaVersion: 1,
470
+ provider: {
471
+ dataDir: capacityProviderDataDir,
472
+ environment: "local",
473
+ market: {
474
+ url: "http://host.docker.internal:3000",
475
+ id: "local"
476
+ }
477
+ },
478
+ runtime: {
479
+ images: {
480
+ roles: {
481
+ manager: { image: "treeseed/agent-manager", tag: "latest" },
482
+ runner: { image: "treeseed/agent-runner", tag: "latest" }
483
+ }
484
+ }
485
+ }
486
+ });
487
+ const localTreeDxApiEnv = {
488
+ TREESEED_TREEDX_JWT_ISSUER: "https://api.treeseed.local/treedx",
489
+ TREESEED_TREEDX_JWT_AUDIENCE: "treedx-local",
490
+ TREESEED_TREEDX_JWT_HS256_SECRET: "treeseed-local-treedx-jwt-secret",
491
+ TREESEED_TREEDX_PROXY_ACTOR_ID: "treeseed-api",
492
+ TREESEED_TREEDX_PROXY_TENANT_ID: "treeseed-control-plane"
493
+ };
494
+ const localCapacityProviderTreeDxEnv = {
495
+ TREESEED_TREEDX_BASE_URL: "http://host.docker.internal:4000",
496
+ TREESEED_TREEDX_URL: "http://host.docker.internal:4000",
497
+ ...localTreeDxApiEnv
498
+ };
499
+ const localCapacityProviderEnv = {
500
+ ...capacityPlan.composeEnv,
501
+ ...localCapacityProviderTreeDxEnv,
502
+ TREESEED_PROVIDER_HOST_DATA_DIR: capacityProviderDataDir,
503
+ ...hostCodexAuthFile ? {
504
+ TREESEED_HOST_CODEX_AUTH_FILE: hostCodexAuthFile,
505
+ TREESEED_CODEX_AUTH_FILE: "/data/codex/auth.json"
506
+ } : {},
507
+ ...localGitCommonDir ? {
508
+ TREESEED_PROVIDER_WORKSPACE_ABSOLUTE_CONTAINER: tenantRoot,
509
+ TREESEED_PROVIDER_WORKSPACE_GITDIR_CONTAINER: `/.treeseed/worktrees/${basename(tenantRoot)}`,
510
+ TREESEED_MARKET_GIT_COMMON_DIR_HOST: localGitCommonDir,
511
+ TREESEED_MARKET_GIT_COMMON_DIR_ABSOLUTE_CONTAINER: localGitCommonDir,
512
+ TREESEED_MARKET_GIT_COMMON_DIR_ROOT_CONTAINER: "/.git"
513
+ } : {},
514
+ TREESEED_PROVIDER_CONTAINER_UID: String(process.getuid?.() ?? 1e3),
515
+ TREESEED_PROVIDER_CONTAINER_GID: String(process.getgid?.() ?? 1e3),
516
+ TREESEED_CAPACITY_PROVIDER_API_KEY: "tsp_local_treeseed_demo_capacity_provider",
517
+ TREESEED_CAPACITY_PROVIDER_ID: "treeseed-local-dev",
518
+ TREESEED_CAPACITY_PROVIDER_TEAM_ID: "treeseed",
519
+ TREESEED_MANAGEMENT_API_URL: "http://host.docker.internal:3000"
520
+ };
521
+ return [
522
+ {
523
+ id: apiPostgresComposeId,
524
+ kind: "local-docker-compose",
525
+ provider: "local",
526
+ environment,
527
+ packageId: "@treeseed/api",
528
+ serviceId: "api-postgres",
529
+ logicalName: "local API PostgreSQL compose",
530
+ dependencies: [],
531
+ spec: {
532
+ composeFile: "packages/api/compose.postgres.yml",
533
+ projectName: "treeseed-local-api-postgres",
534
+ cwd: ".",
535
+ dataDir: ".treeseed/local-api-postgres/data",
536
+ env: {
537
+ TREESEED_LOCAL_POSTGRES_PASSWORD: "treeseed-local-dev",
538
+ TREESEED_LOCAL_POSTGRES_PORT: "54329"
539
+ },
540
+ ports: [{ host: 54329, container: 5432 }],
541
+ volumes: [{ name: "treeseed-api-postgres-volume", mountPath: "/var/lib/postgresql/data", sharedLocalOnly: true }],
542
+ healthChecks: [
543
+ { id: "api-postgres-compose", kind: "container", service: "treeseed-api-postgres" }
544
+ ]
545
+ },
546
+ source: { type: "package-adapter", id: "@treeseed/api" }
547
+ },
548
+ {
549
+ id: mailpitComposeId,
550
+ kind: "local-docker-compose",
551
+ provider: "local",
552
+ environment,
553
+ packageId: "@treeseed/sdk",
554
+ serviceId: "mailpit",
555
+ logicalName: "local Mailpit email capture compose",
556
+ dependencies: [],
557
+ spec: {
558
+ composeFile: "packages/sdk/src/treeseed/services/compose.yml",
559
+ projectName: "treeseed-local-mailpit",
560
+ cwd: ".",
561
+ env: {
562
+ TREESEED_MAILPIT_SMTP_BIND: "127.0.0.1",
563
+ TREESEED_MAILPIT_SMTP_PORT: "1025",
564
+ TREESEED_MAILPIT_UI_BIND: "127.0.0.1",
565
+ TREESEED_MAILPIT_UI_PORT: "8025"
566
+ },
567
+ ports: [
568
+ { host: 1025, container: 1025 },
569
+ { host: 8025, container: 8025 }
570
+ ],
571
+ healthChecks: [
572
+ { id: "mailpit-ui", kind: "http", url: "http://127.0.0.1:8025" }
573
+ ]
574
+ },
575
+ source: { type: "package-adapter", id: "@treeseed/sdk" }
576
+ },
577
+ {
578
+ id: "local-treedx:team-primary",
579
+ kind: "local-treedx",
580
+ provider: "local",
581
+ environment,
582
+ packageId: "treedx",
583
+ serviceId: "treedx",
584
+ logicalName: "local TreeDX team content repository plane",
585
+ dependencies: [treeDxComposeId],
586
+ spec: {
587
+ mode: "private-team",
588
+ contentRepositoryAccessMode: "treedx",
589
+ siteRepositoryAccessMode: "filesystem",
590
+ projectRepositoryAccessMode: "filesystem",
591
+ baseUrl: "http://127.0.0.1:4000",
592
+ dataDir: ".treeseed/local-treedx/data",
593
+ healthEndpoint: "http://127.0.0.1:4000/api/v1/health",
594
+ auth: localTreeDxApiEnv,
595
+ projects: localTreeDxContentProjects(tenantRoot)
596
+ },
597
+ source: { type: "package-adapter", id: "treedx" }
598
+ },
599
+ {
600
+ id: treeDxComposeId,
601
+ kind: "local-docker-compose",
602
+ provider: "local",
603
+ environment,
604
+ packageId: "treedx",
605
+ serviceId: "treedx",
606
+ logicalName: "local TreeDX compose",
607
+ dependencies: [],
608
+ spec: {
609
+ composeFile: "packages/treedx/compose.yaml",
610
+ projectName: "treeseed-local-treedx",
611
+ cwd: "packages/treedx",
612
+ dataDir: ".treeseed/local-treedx/data",
613
+ ports: [{ host: 4e3, container: 4e3 }],
614
+ env: {
615
+ TREEDX_ALLOW_DEV_VERIFIER_IN_PROD: "true",
616
+ ...localTreeDxApiEnv
617
+ },
618
+ volumes: [{ name: "treeseed-local-treedx-data", mountPath: "/data", sharedLocalOnly: true }],
619
+ healthChecks: [
620
+ { id: "treedx-api", kind: "http", url: "http://127.0.0.1:4000/api/v1/health" }
621
+ ]
622
+ },
623
+ source: { type: "package-adapter", id: "treedx" }
624
+ },
625
+ {
626
+ id: "capacity-provider:local",
627
+ kind: "capacity-provider",
628
+ provider: "local",
629
+ environment,
630
+ packageId: "@treeseed/agent",
631
+ serviceId: "capacity-provider",
632
+ logicalName: "local capacity provider",
633
+ dependencies: [composeId],
634
+ spec: {
635
+ mode: "local",
636
+ roles: ["api", "manager", "runner"],
637
+ volumePolicy: "shared-local",
638
+ healthEndpoint: "http://127.0.0.1:4783/healthz"
639
+ },
640
+ source: { type: "package-adapter", id: "@treeseed/agent" }
641
+ },
642
+ {
643
+ id: composeId,
644
+ kind: "local-docker-compose",
645
+ provider: "local",
646
+ environment,
647
+ packageId: "@treeseed/agent",
648
+ serviceId: "agent-capacity-provider",
649
+ logicalName: "agent capacity provider compose",
650
+ dependencies: ["local-process:api", treeDxComposeId],
651
+ spec: {
652
+ composeFile: "packages/agent/compose.capacity-provider.yml",
653
+ composeFiles: [
654
+ "packages/agent/compose.capacity-provider.yml",
655
+ "packages/agent/compose.capacity-provider.dev.yml"
656
+ ],
657
+ projectName: "treeseed-capacity-provider",
658
+ cwd: ".",
659
+ dataDir: ".treeseed/local-capacity-provider/data",
660
+ buildPolicy: "missing",
661
+ devMode: "typescript",
662
+ redactedEnv: capacityPlan.redactedEnv,
663
+ envKeys: Object.keys(localCapacityProviderEnv).sort(),
664
+ env: localCapacityProviderEnv,
665
+ services: ["agent-manager", "agent-runner"],
666
+ volumes: [{ name: "treeseed-capacity-provider-data", mountPath: "/data", sharedLocalOnly: true }],
667
+ healthChecks: [
668
+ { id: "compose-services", kind: "container", service: "agent-manager" }
669
+ ]
670
+ },
671
+ source: { type: "package-adapter", id: "@treeseed/agent" }
672
+ },
673
+ ...[
674
+ ["market-web", "Market web dev process"],
675
+ ["api", "API dev process"],
676
+ ["operations-runner", "Operations runner dev process"]
677
+ ].map(([id, label]) => ({
678
+ id: `local-process:${id}`,
679
+ kind: "local-process",
680
+ provider: "local",
681
+ environment,
682
+ packageId: id === "market-web" ? "@treeseed/market" : "@treeseed/api",
683
+ serviceId: id,
684
+ logicalName: label,
685
+ dependencies: id === "market-web" ? ["local-process:api", mailpitComposeId] : id === "api" ? [apiPostgresComposeId, mailpitComposeId] : ["local-process:api"],
686
+ spec: {
687
+ processId: id,
688
+ surfaces: id === "market-web" ? ["web"] : id === "api" ? ["api"] : ["operations-runner"],
689
+ supervisor: "sdk-managed-dev",
690
+ action: "start",
691
+ options: {
692
+ apiPort: 3e3
693
+ },
694
+ stateDir: ".treeseed/dev",
695
+ logDir: ".treeseed/logs",
696
+ cwd: id === "market-web" ? "." : "packages/api"
697
+ },
698
+ source: { type: "package-adapter", id }
699
+ })),
700
+ ...buildProjectLocalContentResources({ tenantRoot, environment, localContent })
701
+ ];
702
+ }
703
+ function releaseGateResources(packages, templates, environment) {
704
+ const phase = releasePhaseForEnvironment(environment);
705
+ const hostedEnvironment = environment === "prod" ? "prod" : "staging";
706
+ const packageGates = packages.flatMap((pkg) => {
707
+ const fingerprint = hashJson({ packageId: pkg.id, version: pkg.version, capability: pkg.releaseCapability, environment, phase });
708
+ const verifyDependencies = [
709
+ `package-manifest:${pkg.id}`,
710
+ ...internalPackageDependencies(packages, pkg).map((dependencyId) => `release-gate:verify:${dependencyId}`)
711
+ ];
712
+ const verifyGate = {
713
+ id: `release-gate:verify:${pkg.id}`,
714
+ kind: "release-gate",
715
+ provider: "treeseed",
716
+ environment,
717
+ packageId: pkg.id,
718
+ serviceId: null,
719
+ logicalName: `${pkg.id} verify gate`,
720
+ dependencies: verifyDependencies,
721
+ spec: {
722
+ gateKind: "release-gate:verify",
723
+ phase,
724
+ packageId: pkg.id,
725
+ environment: hostedEnvironment,
726
+ fingerprint,
727
+ capability: pkg.releaseCapability,
728
+ command: "verify.release"
729
+ },
730
+ source: { type: "package-adapter", id: pkg.id }
731
+ };
732
+ const publishGateKind = pkg.releaseCapability === "npm" ? "release-gate:npm-publish" : pkg.releaseCapability === "image" ? "release-gate:image-publish" : null;
733
+ const imageCredentialDependencies = publishGateKind === "release-gate:image-publish" && pkg.githubEnvironments.includes(hostedEnvironment) ? [
734
+ ...pkg.requiredSecrets.map((secretName) => `github-secret-binding:${pkg.id}:${hostedEnvironment}:${secretName}`),
735
+ ...pkg.requiredVariables.map((variableName) => `github-variable-binding:${pkg.id}:${hostedEnvironment}:${variableName}`)
736
+ ] : [];
737
+ const publishDependencies = publishGateKind === "release-gate:image-publish" ? [verifyGate.id, ...imageCredentialDependencies] : [verifyGate.id];
738
+ return [
739
+ verifyGate,
740
+ ...publishGateKind ? [{
741
+ id: `${publishGateKind}:${pkg.id}`,
742
+ kind: "release-gate",
743
+ provider: "treeseed",
744
+ environment,
745
+ packageId: pkg.id,
746
+ serviceId: null,
747
+ logicalName: `${pkg.id} publish gate`,
748
+ dependencies: publishDependencies,
749
+ spec: {
750
+ gateKind: publishGateKind,
751
+ phase,
752
+ packageId: pkg.id,
753
+ environment: hostedEnvironment,
754
+ repository: pkg.repository,
755
+ fingerprint: hashJson({ publishGateKind, packageId: pkg.id, version: pkg.version, environment, phase }),
756
+ capability: pkg.releaseCapability
757
+ },
758
+ source: { type: "package-adapter", id: pkg.id }
759
+ }] : []
760
+ ];
761
+ });
762
+ const templateGates = templates.flatMap((template) => {
763
+ const verifyGate = {
764
+ id: `release-gate:template-verify:${template.id}`,
765
+ kind: "release-gate",
766
+ provider: "treeseed",
767
+ environment,
768
+ packageId: template.id,
769
+ serviceId: null,
770
+ logicalName: `${template.name} template verify gate`,
771
+ dependencies: [`template-manifest:${template.id}`],
772
+ spec: {
773
+ gateKind: "release-gate:template-verify",
774
+ phase,
775
+ templateId: template.id,
776
+ environment: hostedEnvironment,
777
+ fingerprint: hashJson({ templateId: template.id, version: template.version, repository: template.repository, environment, phase }),
778
+ releaseTag: template.releaseTag,
779
+ recordPath: template.recordPath
780
+ },
781
+ source: { type: "package-adapter", id: `template:${template.id}` }
782
+ };
783
+ return [
784
+ verifyGate,
785
+ {
786
+ id: `release-gate:template-release-record:${template.id}`,
787
+ kind: "release-gate",
788
+ provider: "treeseed",
789
+ environment,
790
+ packageId: template.id,
791
+ serviceId: null,
792
+ logicalName: `${template.name} template release record`,
793
+ dependencies: [verifyGate.id],
794
+ spec: {
795
+ gateKind: "release-gate:template-release-record",
796
+ phase,
797
+ templateId: template.id,
798
+ environment: hostedEnvironment,
799
+ fingerprint: hashJson({ gate: "template-release-record", templateId: template.id, version: template.version, releaseTag: template.releaseTag, environment, phase }),
800
+ releaseTag: template.releaseTag,
801
+ recordPath: template.recordPath
802
+ },
803
+ source: { type: "package-adapter", id: `template:${template.id}` }
804
+ }
805
+ ];
806
+ });
807
+ const releaseDependencies = [...packageGates.map((gate) => gate.id), ...templateGates.map((gate) => gate.id)];
808
+ return [
809
+ ...packageGates,
810
+ ...templateGates,
811
+ {
812
+ id: `release-gate:hosted-reconcile:${hostedEnvironment}:all`,
813
+ kind: "release-gate",
814
+ provider: "treeseed",
815
+ environment,
816
+ packageId: null,
817
+ serviceId: "hosted-reconcile",
818
+ logicalName: `${hostedEnvironment} hosted reconciliation gate`,
819
+ dependencies: releaseDependencies,
820
+ spec: {
821
+ gateKind: "release-gate:hosted-reconcile",
822
+ phase,
823
+ environment: hostedEnvironment,
824
+ appId: "all",
825
+ fingerprint: hashJson({ gate: "hosted-reconcile", environment: hostedEnvironment, packages, templates }),
826
+ hostedSelector: {
827
+ environment: hostedEnvironment,
828
+ provider: ["cloudflare", "cloudflare-dns", "railway"]
829
+ }
830
+ },
831
+ source: { type: "package-adapter", id: "release" }
832
+ },
833
+ {
834
+ id: `release-gate:live-verify:${hostedEnvironment}:all`,
835
+ kind: "release-gate",
836
+ provider: "treeseed",
837
+ environment,
838
+ packageId: null,
839
+ serviceId: "live-verify",
840
+ logicalName: `${hostedEnvironment} live verification gate`,
841
+ dependencies: [`release-gate:hosted-reconcile:${hostedEnvironment}:all`],
842
+ spec: {
843
+ gateKind: "release-gate:live-verify",
844
+ phase,
845
+ environment: hostedEnvironment,
846
+ appId: "all",
847
+ fingerprint: hashJson({ gate: "live-verify", environment: hostedEnvironment, packages, templates }),
848
+ hostedSelector: {
849
+ environment: hostedEnvironment,
850
+ provider: ["cloudflare", "cloudflare-dns", "railway"]
851
+ }
852
+ },
853
+ source: { type: "package-adapter", id: "release" }
854
+ },
855
+ {
856
+ id: environment === "prod" ? "release-gate:production-record:prod" : "release-gate:candidate-record:staging",
857
+ kind: "release-gate",
858
+ provider: "treeseed",
859
+ environment,
860
+ packageId: null,
861
+ serviceId: environment === "prod" ? "production-record" : "candidate-record",
862
+ logicalName: environment === "prod" ? "production release record" : "staging candidate record",
863
+ dependencies: [`release-gate:live-verify:${hostedEnvironment}:all`],
864
+ spec: {
865
+ gateKind: environment === "prod" ? "release-gate:production-record" : "release-gate:candidate-record",
866
+ phase,
867
+ environment,
868
+ fingerprint: hashJson({ gate: environment === "prod" ? "production-record" : "candidate-record", packages, templates }),
869
+ recordPath: environment === "prod" ? ".treeseed/workflow/releases/latest-production.json" : ".treeseed/workflow/release-candidates/latest-staging.json"
870
+ },
871
+ source: { type: "package-adapter", id: "release" }
872
+ }
873
+ ];
874
+ }
875
+ function slugBranchName(branchName) {
876
+ return branchName.toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "").slice(0, 48) || "preview";
877
+ }
878
+ function branchPreviewResources(target, environment) {
879
+ if (target.kind !== "branch") return [];
880
+ const branchSlug = slugBranchName(target.branchName);
881
+ const previewId = `branch-preview:${branchSlug}:web`;
882
+ return [
883
+ {
884
+ id: previewId,
885
+ kind: "branch-preview",
886
+ provider: "treeseed",
887
+ environment,
888
+ packageId: "@treeseed/market",
889
+ serviceId: "market-web",
890
+ logicalName: `Branch preview for ${target.branchName}`,
891
+ dependencies: [],
892
+ spec: {
893
+ branch: target.branchName,
894
+ branchSlug,
895
+ environment: "staging",
896
+ appId: "web",
897
+ host: "cloudflare",
898
+ ttlHours: 72,
899
+ resources: {
900
+ environment: "staging",
901
+ appId: ["web"],
902
+ provider: ["cloudflare", "cloudflare-dns"]
903
+ }
904
+ },
905
+ source: { type: "package-adapter", id: "branch-preview" }
906
+ },
907
+ {
908
+ id: `branch-preview-cleanup:${branchSlug}:web`,
909
+ kind: "branch-preview-cleanup",
910
+ provider: "treeseed",
911
+ environment,
912
+ packageId: "@treeseed/market",
913
+ serviceId: "market-web",
914
+ logicalName: `Branch preview cleanup for ${target.branchName}`,
915
+ dependencies: [previewId],
916
+ spec: {
917
+ branch: target.branchName,
918
+ branchSlug,
919
+ environment: "staging",
920
+ reason: "manual",
921
+ selector: {
922
+ environment: "staging",
923
+ unitId: [previewId]
924
+ }
925
+ },
926
+ source: { type: "package-adapter", id: "branch-preview-cleanup" }
927
+ }
928
+ ];
929
+ }
930
+ function resourceMatchesSelector(resource, selector) {
931
+ if (!selector) return true;
932
+ const has = (values, candidates) => {
933
+ const normalized = new Set((values ?? []).map((value) => value.trim()).filter(Boolean));
934
+ return normalized.size === 0 || candidates.some((candidate) => candidate != null && normalized.has(candidate));
935
+ };
936
+ return has(selector.host ?? selector.provider, [resource.provider]) && has(selector.packageId, [resource.packageId]) && has(selector.serviceId, [resource.serviceId, resource.logicalName]) && has(selector.resourceKind, [resource.kind]) && has(selector.unitId, [resource.id, resource.source.type === "reconcile-unit" ? resource.source.id : null]) && has(selector.serviceType, [typeof resource.spec.unitType === "string" ? resource.spec.unitType : null]);
937
+ }
938
+ function compileTreeseedDesiredResourceGraph({
939
+ tenantRoot = workspaceRoot(),
940
+ target,
941
+ localContent = "auto"
942
+ }) {
943
+ const environment = environmentFromTarget(target);
944
+ const derived = deriveTreeseedDesiredUnits({ tenantRoot, target });
945
+ const packageAdapters = discoverTreeseedPackageAdapters(tenantRoot);
946
+ const packages = packageAdapters.map(packageUnitFromAdapter);
947
+ const templates = checkedOutTemplateRepositories(tenantRoot).map(templateUnitFromRepository);
948
+ const resources = [
949
+ ...derived.units.map((unit) => resourceFromUnit(unit, environment)),
950
+ ...packageAdapters.flatMap((adapter) => packageResources(adapter, environment)),
951
+ ...templateResources(templates, environment),
952
+ ...localDevelopmentResources(tenantRoot, environment, localContent),
953
+ ...branchPreviewResources(target, environment),
954
+ ...releaseGateResources(packages, templates, environment)
955
+ ];
956
+ const edges = resources.flatMap((resource) => resource.dependencies.map((dependency) => ({
957
+ from: dependency,
958
+ to: resource.id,
959
+ reason: "depends-on"
960
+ })));
961
+ const fingerprints = Object.fromEntries(resources.map((resource) => [resource.id, hashJson(resource)]));
962
+ return {
963
+ workspaceId: derived.deployConfig.slug,
964
+ environment,
965
+ packages,
966
+ templates,
967
+ resources,
968
+ edges,
969
+ fingerprints
970
+ };
971
+ }
972
+ function selectTreeseedDesiredResources(graph, selector) {
973
+ if (!selector) return graph;
974
+ const selected = graph.resources.filter((resource) => resourceMatchesSelector(resource, selector));
975
+ const selectedIds = new Set(selected.map((resource) => resource.id));
976
+ const include = new Map(selected.map((resource) => [resource.id, resource]));
977
+ const byId = new Map(graph.resources.map((resource) => [resource.id, resource]));
978
+ const visit = (resource) => {
979
+ for (const dependencyId of resource.dependencies) {
980
+ const dependency = byId.get(dependencyId);
981
+ if (!dependency || include.has(dependency.id)) continue;
982
+ include.set(dependency.id, dependency);
983
+ visit(dependency);
984
+ }
985
+ };
986
+ for (const resource of selected) visit(resource);
987
+ const resources = graph.resources.filter((resource) => include.has(resource.id));
988
+ const resourceIds = new Set(resources.map((resource) => resource.id));
989
+ return {
990
+ ...graph,
991
+ resources,
992
+ edges: graph.edges.filter((edge) => resourceIds.has(edge.from) && resourceIds.has(edge.to)),
993
+ fingerprints: Object.fromEntries(Object.entries(graph.fingerprints).filter(([id]) => resourceIds.has(id))),
994
+ packages: graph.packages.filter((pkg) => resources.some((resource) => resource.packageId === pkg.id) || selectedIds.size === 0),
995
+ templates: graph.templates.filter((template) => resources.some((resource) => resource.packageId === template.id) || selectedIds.size === 0)
996
+ };
997
+ }
998
+ function convertDesiredResourceToReconcileUnit(graph, resource) {
999
+ const identity = reconcileIdentityForGraph(graph.workspaceId, graph.environment);
1000
+ if (resource.source.type !== "reconcile-unit") {
1001
+ const unitType2 = (() => {
1002
+ if (resource.kind === "release-gate") return String(resource.spec.gateKind ?? "release-gate:verify");
1003
+ if (resource.kind === "save-gate") return String(resource.spec.gateKind ?? "save-gate:promotion-readiness");
1004
+ return resource.kind;
1005
+ })();
1006
+ return {
1007
+ unitId: resource.id,
1008
+ unitType: unitType2,
1009
+ provider: resource.provider,
1010
+ identity,
1011
+ target: { kind: "persistent", scope: graph.environment },
1012
+ logicalName: resource.logicalName,
1013
+ dependencies: resource.dependencies,
1014
+ spec: resource.spec,
1015
+ secrets: {},
1016
+ metadata: {
1017
+ resourceKind: resource.kind,
1018
+ packageId: resource.packageId,
1019
+ serviceId: resource.serviceId,
1020
+ source: resource.source
1021
+ }
1022
+ };
1023
+ }
1024
+ const spec = resource.spec;
1025
+ const unitType = typeof spec.unitType === "string" ? spec.unitType : null;
1026
+ const resourceIdentity = spec.identity && typeof spec.identity === "object" ? spec.identity : null;
1027
+ const target = spec.target && typeof spec.target === "object" ? spec.target : { kind: "persistent", scope: graph.environment };
1028
+ const unitSpec = spec.spec && typeof spec.spec === "object" ? spec.spec : {};
1029
+ const metadata = spec.metadata && typeof spec.metadata === "object" ? spec.metadata : {};
1030
+ if (!unitType || !resourceIdentity) return null;
1031
+ return {
1032
+ unitId: resource.source.id,
1033
+ unitType,
1034
+ provider: resource.provider,
1035
+ identity: resourceIdentity,
1036
+ target,
1037
+ logicalName: resource.logicalName,
1038
+ dependencies: resource.dependencies,
1039
+ spec: unitSpec,
1040
+ secrets: {},
1041
+ metadata
1042
+ };
1043
+ }
1044
+ function compileTreeseedDesiredUnitsFromGraph(graph, selector) {
1045
+ return selectTreeseedDesiredResources(graph, selector).resources.map((resource) => convertDesiredResourceToReconcileUnit(graph, resource)).filter((unit) => Boolean(unit));
1046
+ }
1047
+ export {
1048
+ compileTreeseedDesiredResourceGraph,
1049
+ compileTreeseedDesiredUnitsFromGraph,
1050
+ convertDesiredResourceToReconcileUnit,
1051
+ selectTreeseedDesiredResources
1052
+ };