@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,13 @@
1
+ export type TreeseedGitHubCredentialResolution = {
2
+ repository: string;
3
+ envName: string;
4
+ configured: boolean;
5
+ fallbackUsed: boolean;
6
+ source: 'repository' | 'fallback' | 'missing';
7
+ token: string | null;
8
+ };
9
+ export declare function githubRepositoryCredentialEnvName(repository: string): string;
10
+ export declare function resolveGitHubCredentialForRepository(repository: string, { values, env, }?: {
11
+ values?: Record<string, string | undefined>;
12
+ env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
13
+ }): TreeseedGitHubCredentialResolution;
@@ -0,0 +1,59 @@
1
+ import { resolveTreeseedGitHubToken } from "../../service-credentials.js";
2
+ function cleanRepositorySlug(repository) {
3
+ const raw = String(repository ?? "").trim().replace(/^https?:\/\/github\.com\//iu, "").replace(/^git@github\.com:/iu, "").replace(/^ssh:\/\/git@github\.com\//iu, "").replace(/\.git$/iu, "").replace(/^\/+|\/+$/gu, "");
4
+ const [owner, repo, ...extra] = raw.split("/").filter(Boolean);
5
+ if (!owner || !repo || extra.length > 0) {
6
+ throw new Error(`Invalid GitHub repository "${repository}". Expected owner/name.`);
7
+ }
8
+ return `${owner}/${repo}`;
9
+ }
10
+ function githubRepositoryCredentialEnvName(repository) {
11
+ const slug = cleanRepositorySlug(repository);
12
+ const suffix = slug.toUpperCase().replace(/[^A-Z0-9]+/gu, "_").replace(/^_+|_+$/gu, "").replace(/_+/gu, "_");
13
+ return `TREESEED_GITHUB_TOKEN_${suffix}`;
14
+ }
15
+ function configuredValue(values, key) {
16
+ const value = values?.[key];
17
+ return typeof value === "string" && value.trim() ? value.trim() : "";
18
+ }
19
+ function resolveGitHubCredentialForRepository(repository, {
20
+ values,
21
+ env = process.env
22
+ } = {}) {
23
+ const normalizedRepository = cleanRepositorySlug(repository);
24
+ const envName = githubRepositoryCredentialEnvName(normalizedRepository);
25
+ const repositoryToken = configuredValue(values, envName) || configuredValue(env, envName);
26
+ if (repositoryToken) {
27
+ return {
28
+ repository: normalizedRepository,
29
+ envName,
30
+ configured: true,
31
+ fallbackUsed: false,
32
+ source: "repository",
33
+ token: repositoryToken
34
+ };
35
+ }
36
+ const fallbackToken = resolveTreeseedGitHubToken(values ?? {}) || resolveTreeseedGitHubToken(env);
37
+ if (fallbackToken) {
38
+ return {
39
+ repository: normalizedRepository,
40
+ envName,
41
+ configured: true,
42
+ fallbackUsed: true,
43
+ source: "fallback",
44
+ token: fallbackToken
45
+ };
46
+ }
47
+ return {
48
+ repository: normalizedRepository,
49
+ envName,
50
+ configured: false,
51
+ fallbackUsed: false,
52
+ source: "missing",
53
+ token: null
54
+ };
55
+ }
56
+ export {
57
+ githubRepositoryCredentialEnvName,
58
+ resolveGitHubCredentialForRepository
59
+ };
@@ -0,0 +1,81 @@
1
+ export type TreeseedHostedServiceCheckStatus = 'passed' | 'failed' | 'skipped' | 'warning';
2
+ export type TreeseedHostedServiceTarget = 'local' | 'staging' | 'prod';
3
+ export type TreeseedHostedServiceProvider = 'cloudflare' | 'railway' | 'http' | 'dns' | 'github';
4
+ export type TreeseedHostedServiceType = 'web' | 'api' | 'operationsRunner' | 'capacityProviderManager' | 'capacityProviderRunner' | 'treeseedDatabase' | 'customDomain' | 'dnsRecord' | 'githubWorkflow' | 'unknown';
5
+ export interface TreeseedHostedServiceCheck {
6
+ id: string;
7
+ provider: TreeseedHostedServiceProvider;
8
+ serviceKey?: string;
9
+ serviceType: TreeseedHostedServiceType;
10
+ target: TreeseedHostedServiceTarget;
11
+ description: string;
12
+ expected?: Record<string, unknown>;
13
+ observed?: Record<string, unknown>;
14
+ status: TreeseedHostedServiceCheckStatus;
15
+ issues: string[];
16
+ remediation?: string;
17
+ }
18
+ export interface TreeseedHostedServiceCheckReport {
19
+ target: TreeseedHostedServiceTarget;
20
+ tenantRoot: string;
21
+ generatedAt: string;
22
+ summary: {
23
+ passed: number;
24
+ failed: number;
25
+ skipped: number;
26
+ warning: number;
27
+ };
28
+ checks: TreeseedHostedServiceCheck[];
29
+ }
30
+ export interface TreeseedObservedRailwayServiceState {
31
+ projectName?: string | null;
32
+ environmentName?: string | null;
33
+ serviceName?: string | null;
34
+ serviceId?: string | null;
35
+ rootDirectory?: string | null;
36
+ buildCommand?: string | null;
37
+ dockerfilePath?: string | null;
38
+ startCommand?: string | null;
39
+ healthcheckPath?: string | null;
40
+ healthcheckTimeoutSeconds?: number | null;
41
+ runtimeMode?: string | null;
42
+ deploymentStatus?: string | null;
43
+ deploymentHealthy?: boolean | null;
44
+ deploymentBranch?: string | null;
45
+ deploymentRepo?: string | null;
46
+ deploymentRootDirectory?: string | null;
47
+ deploymentCommitHash?: string | null;
48
+ deploymentRequiredMountPath?: string | null;
49
+ deploymentVolumeMounts?: string[];
50
+ volumeName?: string | null;
51
+ volumeId?: string | null;
52
+ volumeMountPath?: string | null;
53
+ volumeServiceId?: string | null;
54
+ volumeEnvironmentId?: string | null;
55
+ volumeState?: string | null;
56
+ volumePendingDeletion?: boolean | null;
57
+ volumeDeletedAt?: string | null;
58
+ variables?: Record<string, unknown> | string[];
59
+ secrets?: Record<string, unknown> | string[];
60
+ health?: 'ready' | 'failed' | 'unknown' | string | null;
61
+ }
62
+ export interface TreeseedHostedServiceCheckOptions {
63
+ tenantRoot: string;
64
+ target?: TreeseedHostedServiceTarget;
65
+ appId?: string;
66
+ serviceKeys?: string[];
67
+ now?: Date;
68
+ valuesOverlay?: Record<string, string | undefined>;
69
+ observedRailwayServices?: Record<string, TreeseedObservedRailwayServiceState | undefined>;
70
+ httpChecks?: Record<string, {
71
+ status?: number;
72
+ ok?: boolean;
73
+ skipped?: boolean;
74
+ error?: string;
75
+ fallbackUrl?: string;
76
+ fallbackStatus?: number;
77
+ fallbackOk?: boolean;
78
+ fallbackError?: string;
79
+ } | undefined>;
80
+ }
81
+ export declare function collectTreeseedHostedServiceChecks(options: TreeseedHostedServiceCheckOptions): TreeseedHostedServiceCheckReport;
@@ -0,0 +1,478 @@
1
+ import { relative, resolve } from "node:path";
2
+ import { collectTreeseedEnvironmentContext, resolveTreeseedMachineEnvironmentValues } from "./config-runtime.js";
3
+ import { configuredRailwayServices } from "./railway-deploy.js";
4
+ import { loadTreeseedPlatformConfig } from "../../platform/config.js";
5
+ import { discoverTreeseedApplications } from "../../hosting/apps.js";
6
+ const RAILWAY_SECRET_KEYS_BY_SERVICE = {
7
+ api: [
8
+ "TREESEED_DATABASE_URL",
9
+ "TREESEED_WEB_SERVICE_SECRET",
10
+ "TREESEED_PLATFORM_RUNNER_SECRET",
11
+ "TREESEED_CREDENTIAL_SESSION_SECRET"
12
+ ],
13
+ operationsRunner: [
14
+ "TREESEED_DATABASE_URL",
15
+ "TREESEED_PLATFORM_RUNNER_SECRET",
16
+ "TREESEED_CREDENTIAL_SESSION_SECRET"
17
+ ],
18
+ capacityProviderManager: [
19
+ "TREESEED_CAPACITY_PROVIDER_API_KEY"
20
+ ],
21
+ capacityProviderRunner: [
22
+ "TREESEED_CAPACITY_PROVIDER_API_KEY"
23
+ ]
24
+ };
25
+ const RAILWAY_VARIABLE_KEYS_BY_SERVICE = {
26
+ operationsRunner: [
27
+ "TREESEED_PLATFORM_RUNNER_ID",
28
+ "TREESEED_PLATFORM_RUNNER_DATA_DIR",
29
+ "TREESEED_PLATFORM_RUNNER_ENVIRONMENT",
30
+ "TREESEED_MANAGER_ID"
31
+ ],
32
+ capacityProviderManager: [
33
+ "TREESEED_PROVIDER_ENVIRONMENT",
34
+ "TREESEED_PROVIDER_ROLE",
35
+ "TREESEED_MARKET_URL"
36
+ ],
37
+ capacityProviderRunner: [
38
+ "TREESEED_PROVIDER_ENVIRONMENT",
39
+ "TREESEED_PROVIDER_ROLE",
40
+ "TREESEED_MARKET_URL",
41
+ "TREESEED_PROVIDER_RUNNER_ID",
42
+ "TREESEED_PROVIDER_DATA_DIR"
43
+ ]
44
+ };
45
+ function check(input) {
46
+ return {
47
+ ...input,
48
+ issues: input.issues ?? []
49
+ };
50
+ }
51
+ function statusForMatch(observed, expected) {
52
+ return observed === expected ? "passed" : "failed";
53
+ }
54
+ function rootDirectory(tenantRoot, rootDir) {
55
+ const rel = relative(tenantRoot, rootDir).split("\\").join("/");
56
+ return rel || ".";
57
+ }
58
+ function railwayServiceRootDirectory(tenantRoot, service) {
59
+ const sourceRootDirectory = String(service.sourceRootDirectory ?? "").trim();
60
+ if (sourceRootDirectory) {
61
+ return sourceRootDirectory;
62
+ }
63
+ return rootDirectory(service.application?.root ?? tenantRoot, service.rootDir);
64
+ }
65
+ function railwayServiceUsesImageSource(service) {
66
+ return Boolean(service.imageRef || service.sourceMode === "image");
67
+ }
68
+ function hasConfiguredValue(values, key) {
69
+ return typeof values[key] === "string" && Boolean(values[key]?.trim());
70
+ }
71
+ function hasProviderKey(record, key) {
72
+ if (Array.isArray(record)) return record.includes(key);
73
+ if (record && typeof record === "object") return Object.prototype.hasOwnProperty.call(record, key);
74
+ return false;
75
+ }
76
+ function variableObserved(observed, key) {
77
+ return hasProviderKey(observed?.variables, key) || hasProviderKey(observed?.secrets, key);
78
+ }
79
+ function valuePresence(values, observed, key, serviceTarget) {
80
+ const providerPresent = variableObserved(observed, key);
81
+ const machinePresent = hasConfiguredValue(values, key);
82
+ return {
83
+ key,
84
+ serviceTarget,
85
+ present: providerPresent || machinePresent,
86
+ source: providerPresent ? "provider" : machinePresent ? "machine-config" : "missing",
87
+ observation: observed ? "provider-live" : "not-observed"
88
+ };
89
+ }
90
+ function serviceTypeFor(key) {
91
+ if (key === "api") return "api";
92
+ if (key === "operationsRunner") return "operationsRunner";
93
+ if (key === "capacityProviderManager") return "capacityProviderManager";
94
+ if (key === "capacityProviderRunner") return "capacityProviderRunner";
95
+ if (key === "treeseedDatabase") return "treeseedDatabase";
96
+ return "unknown";
97
+ }
98
+ function observedFor(options, serviceName) {
99
+ return serviceName ? options.observedRailwayServices?.[serviceName] : void 0;
100
+ }
101
+ function webCheckConfig(deployConfig, selectedApplication) {
102
+ const selectedConfig = selectedApplication?.roles.includes("web") ? selectedApplication.config : deployConfig;
103
+ return {
104
+ appId: selectedApplication?.roles.includes("web") ? selectedApplication.id : "web",
105
+ config: selectedConfig,
106
+ web: selectedConfig.surfaces?.web
107
+ };
108
+ }
109
+ function httpStatus(url, options) {
110
+ const observed = options.httpChecks?.[url];
111
+ if (!observed) {
112
+ return check({
113
+ id: `http:${url}`,
114
+ provider: "http",
115
+ serviceType: "unknown",
116
+ target: options.target ?? "prod",
117
+ description: `HTTP check ${url}`,
118
+ expected: { ok: true },
119
+ observed: { skipped: true },
120
+ status: "skipped",
121
+ issues: ["No live HTTP observation was provided."]
122
+ });
123
+ }
124
+ const ok = observed.ok === true || typeof observed.status === "number" && observed.status >= 200 && observed.status < 400;
125
+ const fallbackOk = observed.fallbackOk === true || typeof observed.fallbackStatus === "number" && observed.fallbackStatus >= 200 && observed.fallbackStatus < 400;
126
+ return check({
127
+ id: `http:${url}`,
128
+ provider: "http",
129
+ serviceType: "unknown",
130
+ target: options.target ?? "prod",
131
+ description: `HTTP check ${url}`,
132
+ expected: { ok: true },
133
+ observed: {
134
+ status: observed.status ?? null,
135
+ ok,
136
+ skipped: observed.skipped === true,
137
+ fallbackUrl: observed.fallbackUrl,
138
+ fallbackStatus: observed.fallbackStatus,
139
+ fallbackOk
140
+ },
141
+ status: observed.skipped ? "skipped" : ok ? "passed" : fallbackOk ? "warning" : "failed",
142
+ issues: ok ? [] : fallbackOk ? [observed.error ?? `HTTP check ${url} did not return a successful status yet; fallback ${observed.fallbackUrl} responded.`] : [observed.error ?? `HTTP check ${url} did not return a successful status.`]
143
+ });
144
+ }
145
+ function collectTreeseedHostedServiceChecks(options) {
146
+ const target = options.target ?? "prod";
147
+ const tenantRoot = options.tenantRoot;
148
+ const deployConfig = loadTreeseedPlatformConfig({ tenantRoot, environment: target, env: process.env }).deployConfig;
149
+ const registry = collectTreeseedEnvironmentContext(tenantRoot);
150
+ let machineValues = {};
151
+ try {
152
+ machineValues = resolveTreeseedMachineEnvironmentValues(tenantRoot, target);
153
+ } catch {
154
+ machineValues = {};
155
+ }
156
+ const values = { ...machineValues, ...options.valuesOverlay ?? {} };
157
+ const checks = [];
158
+ const selectedServiceKeys = new Set((options.serviceKeys ?? []).map((key) => key.trim()).filter(Boolean));
159
+ const selectedAppId = options.appId?.trim() || null;
160
+ const applications = discoverTreeseedApplications(tenantRoot);
161
+ const selectedApplication = selectedAppId ? applications.find((application) => application.id === selectedAppId || application.relativeRoot === selectedAppId) : null;
162
+ const workspaceHasApiApplication = applications.some(
163
+ (application) => application.roles.includes("api") || application.config.surfaces?.api?.enabled === true || application.config.services?.api?.enabled !== false && Boolean(application.config.services?.api)
164
+ );
165
+ const includeWeb = !selectedAppId || selectedAppId === "web" || selectedApplication?.roles.includes("web") === true;
166
+ const includeApi = !selectedAppId || selectedAppId === "api" || selectedApplication?.roles.includes("api") === true;
167
+ const selectedAppHasApi = Boolean(
168
+ selectedApplication?.roles.includes("api") || selectedApplication?.config.surfaces?.api?.enabled === true || selectedApplication?.config.services?.api?.enabled !== false && selectedApplication?.config.services?.api || selectedAppId === "web" && workspaceHasApiApplication || selectedAppId === "web" && (deployConfig.surfaces?.api?.enabled === true || deployConfig.services?.api?.enabled !== false && deployConfig.services?.api)
169
+ );
170
+ const selectedWeb = webCheckConfig(deployConfig, selectedApplication);
171
+ const web = selectedWeb.web;
172
+ if (includeWeb && web?.enabled !== false && web?.provider === "cloudflare") {
173
+ const domain = web.environments?.[target]?.domain ?? web.publicBaseUrl ?? selectedWeb.config.siteUrl ?? null;
174
+ checks.push(check({
175
+ id: `cloudflare:${selectedWeb.appId}:surface`,
176
+ provider: "cloudflare",
177
+ serviceKey: selectedWeb.appId,
178
+ serviceType: "web",
179
+ target,
180
+ description: "Cloudflare web surface is configured.",
181
+ expected: {
182
+ provider: "cloudflare",
183
+ domain,
184
+ pagesProjectName: selectedWeb.config.cloudflare?.pages?.projectName ?? null
185
+ },
186
+ observed: { configured: true },
187
+ status: "passed"
188
+ }));
189
+ if (domain) {
190
+ const url = String(domain).startsWith("http") ? String(domain) : `https://${domain}`;
191
+ checks.push({ ...httpStatus(url, options), id: `http:${selectedWeb.appId}`, serviceKey: selectedWeb.appId, serviceType: "web", description: "Web public URL responds." });
192
+ if (!selectedAppId || selectedAppHasApi) {
193
+ checks.push({ ...httpStatus(`${url.replace(/\/+$/u, "")}/v1/healthz`, options), id: `http:${selectedWeb.appId}:v1-healthz`, serviceKey: selectedWeb.appId, serviceType: "web", description: "Web proxy reaches API health." });
194
+ }
195
+ }
196
+ }
197
+ for (const [surfaceKey, surface] of Object.entries(deployConfig.surfaces ?? {})) {
198
+ if (selectedAppId === "api" && surfaceKey === "web") continue;
199
+ if (surface && typeof surface === "object" && surface.enabled !== false && surface.provider && !["cloudflare", "railway"].includes(surface.provider)) {
200
+ checks.push(check({
201
+ id: `surface-provider:${surfaceKey}:${surface.provider}`,
202
+ provider: surface.provider === "github" ? "github" : "http",
203
+ serviceKey: surfaceKey,
204
+ serviceType: surfaceKey === "web" ? "web" : surfaceKey === "api" ? "api" : "unknown",
205
+ target,
206
+ description: `Unsupported hosted surface provider ${surface.provider}.`,
207
+ expected: { supportedProviders: ["cloudflare", "railway"] },
208
+ observed: { provider: surface.provider },
209
+ status: "warning",
210
+ issues: [`Hosted service checker does not yet support provider ${surface.provider}.`]
211
+ }));
212
+ }
213
+ }
214
+ const configuredServices = configuredRailwayServices(tenantRoot, target).filter((service) => !selectedAppId || service.application?.id === selectedAppId).filter((service) => selectedServiceKeys.size === 0 || selectedServiceKeys.has(service.key));
215
+ for (const service of configuredServices) {
216
+ const serviceType = serviceTypeFor(service.key);
217
+ const observed = observedFor(options, service.serviceName);
218
+ const expectedRootDirectory = railwayServiceRootDirectory(tenantRoot, service);
219
+ checks.push(check({
220
+ id: `railway:${service.instanceKey}:service`,
221
+ provider: "railway",
222
+ serviceKey: service.key,
223
+ serviceType,
224
+ target,
225
+ description: `Railway service ${service.serviceName} is configured.`,
226
+ expected: { projectName: service.projectName, serviceName: service.serviceName, environmentName: service.railwayEnvironment },
227
+ observed: observed ? { projectName: observed.projectName ?? null, serviceName: observed.serviceName ?? null, environmentName: observed.environmentName ?? null } : { skipped: true },
228
+ status: observed ? "passed" : "skipped",
229
+ issues: observed ? [] : ["No live Railway observation was provided."]
230
+ }));
231
+ for (const [key, expected] of Object.entries({
232
+ rootDirectory: railwayServiceUsesImageSource(service) ? null : expectedRootDirectory,
233
+ buildCommand: service.buildCommand,
234
+ dockerfilePath: service.dockerfilePath,
235
+ startCommand: service.startCommand,
236
+ healthcheckPath: service.healthcheckPath,
237
+ healthcheckTimeoutSeconds: service.healthcheckTimeoutSeconds,
238
+ runtimeMode: service.runtimeMode
239
+ })) {
240
+ if (expected == null) continue;
241
+ const actual = observed?.[key] ?? null;
242
+ checks.push(check({
243
+ id: `railway:${service.instanceKey}:${key}`,
244
+ provider: "railway",
245
+ serviceKey: service.key,
246
+ serviceType,
247
+ target,
248
+ description: `Railway ${service.serviceName} ${key} matches config.`,
249
+ expected: { [key]: expected },
250
+ observed: observed ? { [key]: actual } : { skipped: true },
251
+ status: observed ? statusForMatch(actual, expected) : "skipped",
252
+ issues: !observed || actual === expected ? [] : [`Expected ${key}=${expected}, observed ${actual ?? "(unset)"}.`]
253
+ }));
254
+ }
255
+ if (!railwayServiceUsesImageSource(service) && service.sourceRepo) {
256
+ const actualRepo = observed?.deploymentRepo ?? null;
257
+ const actualBranch = observed?.deploymentBranch ?? null;
258
+ const actualRootDirectory = observed?.deploymentRootDirectory ?? null;
259
+ const sourceUploadDeployment = target === "staging" && actualRepo === null && actualBranch === null && observed?.deploymentHealthy === true;
260
+ checks.push(check({
261
+ id: `railway:${service.instanceKey}:deployment-repo`,
262
+ provider: "railway",
263
+ serviceKey: service.key,
264
+ serviceType,
265
+ target,
266
+ description: `Railway ${service.serviceName} latest deployment uses the desired Git repo.`,
267
+ expected: { repo: service.sourceRepo },
268
+ observed: observed ? { repo: actualRepo, sourceUpload: sourceUploadDeployment } : { skipped: true },
269
+ status: observed ? sourceUploadDeployment ? "passed" : statusForMatch(actualRepo, service.sourceRepo) : "skipped",
270
+ issues: !observed || sourceUploadDeployment || actualRepo === service.sourceRepo ? [] : [`Expected deployment repo=${service.sourceRepo}, observed ${actualRepo ?? "(unset)"}.`]
271
+ }));
272
+ if (service.sourceBranch) {
273
+ checks.push(check({
274
+ id: `railway:${service.instanceKey}:deployment-branch`,
275
+ provider: "railway",
276
+ serviceKey: service.key,
277
+ serviceType,
278
+ target,
279
+ description: `Railway ${service.serviceName} latest deployment uses the desired Git branch.`,
280
+ expected: { branch: service.sourceBranch },
281
+ observed: observed ? { branch: actualBranch, commitHash: observed.deploymentCommitHash ?? null, sourceUpload: sourceUploadDeployment } : { skipped: true },
282
+ status: observed ? sourceUploadDeployment ? "passed" : statusForMatch(actualBranch, service.sourceBranch) : "skipped",
283
+ issues: !observed || sourceUploadDeployment || actualBranch === service.sourceBranch ? [] : [`Expected deployment branch=${service.sourceBranch}, observed ${actualBranch ?? "(unset)"}.`]
284
+ }));
285
+ }
286
+ if (expectedRootDirectory) {
287
+ checks.push(check({
288
+ id: `railway:${service.instanceKey}:deployment-root-directory`,
289
+ provider: "railway",
290
+ serviceKey: service.key,
291
+ serviceType,
292
+ target,
293
+ description: `Railway ${service.serviceName} latest deployment uses the desired Git root directory.`,
294
+ expected: { rootDirectory: expectedRootDirectory },
295
+ observed: observed ? { rootDirectory: actualRootDirectory } : { skipped: true },
296
+ status: observed ? statusForMatch(actualRootDirectory, expectedRootDirectory) : "skipped",
297
+ issues: !observed || actualRootDirectory === expectedRootDirectory ? [] : [`Expected deployment rootDirectory=${expectedRootDirectory}, observed ${actualRootDirectory ?? "(unset)"}.`]
298
+ }));
299
+ }
300
+ }
301
+ if (observed && observed.deploymentHealthy === false) {
302
+ checks.push(check({
303
+ id: `railway:${service.instanceKey}:deployment`,
304
+ provider: "railway",
305
+ serviceKey: service.key,
306
+ serviceType,
307
+ target,
308
+ description: `Railway ${service.serviceName} latest deployment is healthy.`,
309
+ expected: { healthy: true },
310
+ observed: { healthy: false, status: observed.deploymentStatus ?? null },
311
+ status: "failed",
312
+ issues: [`Latest Railway deployment status is ${observed.deploymentStatus ?? "unknown"}.`]
313
+ }));
314
+ } else if (observed) {
315
+ checks.push(check({
316
+ id: `railway:${service.instanceKey}:deployment`,
317
+ provider: "railway",
318
+ serviceKey: service.key,
319
+ serviceType,
320
+ target,
321
+ description: `Railway ${service.serviceName} latest deployment is healthy.`,
322
+ expected: { healthy: true },
323
+ observed: { healthy: observed.deploymentHealthy ?? null, status: observed.deploymentStatus ?? null },
324
+ status: observed.deploymentHealthy === true ? "passed" : "skipped",
325
+ issues: observed.deploymentHealthy === true ? [] : ["No live Railway deployment health observation was provided."]
326
+ }));
327
+ }
328
+ if (service.volumeMountPath) {
329
+ const volumeAttached = Boolean(observed?.volumeId) && observed?.volumeMountPath === service.volumeMountPath && (!observed?.serviceName || !observed?.volumeServiceId || observed.volumeServiceId === observed.serviceId) && observed?.volumePendingDeletion !== true && !(typeof observed?.volumeDeletedAt === "string" && observed.volumeDeletedAt.trim()) && !["DELETING", "DELETED"].includes(String(observed?.volumeState ?? "").toUpperCase());
330
+ checks.push(check({
331
+ id: `railway:${service.instanceKey}:volume`,
332
+ provider: "railway",
333
+ serviceKey: service.key,
334
+ serviceType,
335
+ target,
336
+ description: `Railway ${service.serviceName} volume mount matches config.`,
337
+ expected: { volumeMountPath: service.volumeMountPath },
338
+ observed: observed ? {
339
+ volumeName: observed.volumeName ?? null,
340
+ volumeId: observed.volumeId ?? null,
341
+ volumeMountPath: observed.volumeMountPath ?? null,
342
+ volumeServiceId: observed.volumeServiceId ?? null,
343
+ volumeEnvironmentId: observed.volumeEnvironmentId ?? null,
344
+ volumeState: observed.volumeState ?? null,
345
+ volumePendingDeletion: observed.volumePendingDeletion ?? null,
346
+ volumeDeletedAt: observed.volumeDeletedAt ?? null
347
+ } : { skipped: true },
348
+ status: observed ? volumeAttached ? "passed" : "failed" : "skipped",
349
+ issues: !observed || volumeAttached ? [] : [`Expected an attached persistent volume mounted at ${service.volumeMountPath}, observed ${observed.volumeMountPath ?? "(unset)"} on volume ${observed.volumeName ?? "(none)"}.`]
350
+ }));
351
+ const volumeNotPendingDeletion = observed?.volumePendingDeletion === false && !["DELETING", "DELETED"].includes(String(observed?.volumeState ?? "").toUpperCase());
352
+ checks.push(check({
353
+ id: `railway:${service.instanceKey}:volume-retained`,
354
+ provider: "railway",
355
+ serviceKey: service.key,
356
+ serviceType,
357
+ target,
358
+ description: `Railway ${service.serviceName} volume is retained and active.`,
359
+ expected: { pendingDeletion: false },
360
+ observed: observed ? {
361
+ volumeName: observed.volumeName ?? null,
362
+ volumeId: observed.volumeId ?? null,
363
+ state: observed.volumeState ?? null,
364
+ pendingDeletion: observed.volumePendingDeletion ?? null,
365
+ deletedAt: observed.volumeDeletedAt ?? null
366
+ } : { skipped: true },
367
+ status: observed ? volumeNotPendingDeletion ? "passed" : "failed" : "skipped",
368
+ issues: !observed || volumeNotPendingDeletion ? [] : [`Expected an active retained volume, observed state=${observed.volumeState ?? "(unset)"} pendingDeletion=${String(observed.volumePendingDeletion ?? null)} deletedAt=${observed.volumeDeletedAt ?? "(unset)"}.`]
369
+ }));
370
+ const deploymentHasVolumeMount = observed?.deploymentRequiredMountPath === service.volumeMountPath || (observed?.deploymentVolumeMounts ?? []).includes(service.volumeMountPath);
371
+ checks.push(check({
372
+ id: `railway:${service.instanceKey}:deployment-required-mount`,
373
+ provider: "railway",
374
+ serviceKey: service.key,
375
+ serviceType,
376
+ target,
377
+ description: `Railway ${service.serviceName} deployment metadata includes the volume mount.`,
378
+ expected: { volumeMountPath: service.volumeMountPath },
379
+ observed: observed ? {
380
+ requiredMountPath: observed.deploymentRequiredMountPath ?? null,
381
+ volumeMounts: observed.deploymentVolumeMounts ?? []
382
+ } : { skipped: true },
383
+ status: observed ? deploymentHasVolumeMount ? "passed" : "failed" : "skipped",
384
+ issues: !observed || deploymentHasVolumeMount ? [] : [`Expected deployment metadata to include volume mount ${service.volumeMountPath}.`]
385
+ }));
386
+ }
387
+ for (const key of [...RAILWAY_SECRET_KEYS_BY_SERVICE[service.key] ?? [], ...RAILWAY_VARIABLE_KEYS_BY_SERVICE[service.key] ?? []]) {
388
+ const presence = valuePresence(values, observed, key, service.key);
389
+ const status = presence.present ? "passed" : observed ? "failed" : "skipped";
390
+ checks.push(check({
391
+ id: `railway:${service.instanceKey}:env:${key}`,
392
+ provider: "railway",
393
+ serviceKey: service.key,
394
+ serviceType,
395
+ target,
396
+ description: `Railway ${service.serviceName} has ${key}.`,
397
+ expected: { key, serviceTarget: service.key, present: true },
398
+ observed: presence,
399
+ status,
400
+ issues: presence.present ? [] : observed ? [`${key} is missing for ${service.key}.`] : ["No live Railway variable observation was provided."]
401
+ }));
402
+ }
403
+ if (service.publicBaseUrl) {
404
+ const baseUrl = service.publicBaseUrl.replace(/\/+$/u, "");
405
+ checks.push({ ...httpStatus(`${baseUrl}${service.healthcheckPath ?? "/healthz"}`, options), id: `http:${service.instanceKey}:healthz`, serviceKey: service.key, serviceType, description: `${service.serviceName} health endpoint responds.` });
406
+ if (service.key === "api") {
407
+ checks.push({ ...httpStatus(`${baseUrl}/healthz/deep`, options), id: `http:${service.instanceKey}:healthz-deep`, serviceKey: service.key, serviceType, description: `${service.serviceName} deep health endpoint responds.` });
408
+ }
409
+ }
410
+ }
411
+ const applicationConfigs = [
412
+ ...includeWeb ? [deployConfig] : [],
413
+ ...discoverTreeseedApplications(tenantRoot).filter((application) => application.root !== resolve(tenantRoot)).filter((application) => !selectedAppId || application.id === selectedAppId).map((application) => application.config)
414
+ ];
415
+ const treeseedDatabaseService = applicationConfigs.map((config) => config.services?.treeseedDatabase).find((service) => service?.enabled !== false);
416
+ if (includeApi && (selectedServiceKeys.size === 0 || selectedServiceKeys.has("treeseedDatabase")) && treeseedDatabaseService?.enabled !== false && treeseedDatabaseService?.provider === "railway") {
417
+ const targets = treeseedDatabaseService.railway?.serviceTargets ?? [];
418
+ checks.push(check({
419
+ id: "railway:treeseedDatabase:targets",
420
+ provider: "railway",
421
+ serviceKey: "treeseedDatabase",
422
+ serviceType: "treeseedDatabase",
423
+ target,
424
+ description: "Treeseed database targets API and runner services.",
425
+ expected: { serviceTargets: ["api", "operationsRunner"] },
426
+ observed: { serviceTargets: targets },
427
+ status: targets.includes("api") && targets.includes("operationsRunner") ? "passed" : "failed",
428
+ issues: targets.includes("api") && targets.includes("operationsRunner") ? [] : ["Treeseed database must target api and operationsRunner."]
429
+ }));
430
+ }
431
+ for (const service of Object.values(selectedAppId ? {} : deployConfig.services ?? {})) {
432
+ if (service && typeof service === "object" && service.enabled !== false && service.provider && !["railway"].includes(service.provider)) {
433
+ checks.push(check({
434
+ id: `provider:${service.provider}`,
435
+ provider: "railway",
436
+ serviceType: "unknown",
437
+ target,
438
+ description: `Unsupported hosted service provider ${service.provider}.`,
439
+ expected: { supportedProviders: ["railway"] },
440
+ observed: { provider: service.provider },
441
+ status: "warning",
442
+ issues: [`Hosted service checker does not yet support provider ${service.provider}.`]
443
+ }));
444
+ }
445
+ }
446
+ const entryIds = new Set(registry.entries.map((entry) => entry.id));
447
+ for (const key of includeApi ? ["TREESEED_DATABASE_URL", "TREESEED_WEB_SERVICE_SECRET", "TREESEED_PLATFORM_RUNNER_SECRET"] : []) {
448
+ if (!entryIds.has(key)) {
449
+ checks.push(check({
450
+ id: `registry:${key}`,
451
+ provider: "railway",
452
+ serviceType: "unknown",
453
+ target,
454
+ description: `Environment registry declares ${key}.`,
455
+ expected: { registryEntry: key },
456
+ observed: { registryEntry: null },
457
+ status: "failed",
458
+ issues: [`${key} is missing from the environment registry.`]
459
+ }));
460
+ }
461
+ }
462
+ const summary = {
463
+ passed: checks.filter((entry) => entry.status === "passed").length,
464
+ failed: checks.filter((entry) => entry.status === "failed").length,
465
+ skipped: checks.filter((entry) => entry.status === "skipped").length,
466
+ warning: checks.filter((entry) => entry.status === "warning").length
467
+ };
468
+ return {
469
+ target,
470
+ tenantRoot: resolve(tenantRoot),
471
+ generatedAt: (options.now ?? /* @__PURE__ */ new Date()).toISOString(),
472
+ summary,
473
+ checks
474
+ };
475
+ }
476
+ export {
477
+ collectTreeseedHostedServiceChecks
478
+ };
@@ -1,5 +1,5 @@
1
- import { type TreeseedEnvironmentScope } from '../../platform/environment.ts';
2
- import type { TreeseedReconcileTarget } from '../../reconcile/contracts.ts';
1
+ import { type TreeseedEnvironmentScope } from '../../platform/environment.js';
2
+ import type { TreeseedReconcileTarget } from '../../reconcile/contracts.js';
3
3
  export type TreeseedHostingAuditEnvironment = 'current' | 'local' | 'staging' | 'prod';
4
4
  export type TreeseedHostingAuditResolvedEnvironment = 'local' | 'staging' | 'prod' | 'preview';
5
5
  export type TreeseedHostingAuditHostKind = 'repository' | 'web' | 'email';