@treeseed/sdk 0.12.62 → 0.13.0-rc.10

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 (1108) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +33 -359
  3. package/dist/accounts/account-contracts.d.ts +170 -0
  4. package/dist/accounts/account-contracts.js +33 -0
  5. package/dist/agent-capacity/allocation.d.ts +186 -0
  6. package/dist/agent-capacity/allocation.js +226 -0
  7. package/dist/agent-capacity/artifact-mutation-receipt.d.ts +49 -0
  8. package/dist/agent-capacity/artifact-mutation-receipt.js +36 -0
  9. package/dist/agent-capacity/artifacts.d.ts +107 -0
  10. package/dist/agent-capacity/artifacts.js +39 -0
  11. package/dist/agent-capacity/authority/agent-authority-presets.d.ts +13 -0
  12. package/dist/agent-capacity/authority/agent-authority-presets.js +106 -0
  13. package/dist/agent-capacity/contracts/capacity/assignments/assignment-records.d.ts +269 -0
  14. package/dist/agent-capacity/contracts/capacity/assignments/assignment-records.js +10 -0
  15. package/dist/agent-capacity/contracts/capacity/communication/communication-records.d.ts +101 -0
  16. package/dist/agent-capacity/contracts/capacity/communication/communication-records.js +9 -0
  17. package/dist/agent-capacity/contracts/capacity/providers/supply-policy.d.ts +36 -0
  18. package/dist/agent-capacity/contracts/capacity/providers/supply-policy.js +4 -0
  19. package/dist/agent-capacity/contracts/capacity/workdays/workday-records.d.ts +188 -0
  20. package/dist/agent-capacity/contracts/configuration/configuration.d.ts +11 -0
  21. package/dist/agent-capacity/contracts/configuration/configuration.js +20 -0
  22. package/dist/agent-capacity/contracts/operations/research-workflow.d.ts +59 -0
  23. package/dist/agent-capacity/contracts/operations/research-workflow.js +16 -0
  24. package/dist/agent-capacity/contracts/operations/workflow-promotion.d.ts +24 -0
  25. package/dist/agent-capacity/contracts/projects/agents/project-agent-class.d.ts +37 -0
  26. package/dist/agent-capacity/contracts/runtime/runtime-observability.d.ts +335 -0
  27. package/dist/agent-capacity/contracts/support/agent-atlas.d.ts +185 -0
  28. package/dist/agent-capacity/contracts/support/agent-atlas.js +47 -0
  29. package/dist/agent-capacity/contracts/support/agent-lab-monitoring.d.ts +96 -0
  30. package/dist/agent-capacity/contracts/support/agent-lab-monitoring.js +14 -0
  31. package/dist/agent-capacity/contracts/support/authority/execution-mode.d.ts +10 -0
  32. package/dist/agent-capacity/contracts/support/authority/execution-mode.js +17 -0
  33. package/dist/agent-capacity/contracts/support/decision-work.d.ts +251 -0
  34. package/dist/agent-capacity/contracts/support/failure-records.d.ts +9 -0
  35. package/dist/agent-capacity/contracts/support/failure-records.js +0 -0
  36. package/dist/agent-capacity/contracts/support/financial-records.d.ts +124 -0
  37. package/dist/agent-capacity/contracts/support/financial-records.js +0 -0
  38. package/dist/agent-capacity/contracts/support/planning-records.d.ts +121 -0
  39. package/dist/agent-capacity/contracts/support/planning-records.js +0 -0
  40. package/dist/agent-capacity/contracts/support/research-citation.d.ts +15 -0
  41. package/dist/agent-capacity/contracts/support/research-citation.js +0 -0
  42. package/dist/agent-capacity/contracts/support/research-source-policy.d.ts +8 -0
  43. package/dist/agent-capacity/contracts/support/research-source-policy.js +0 -0
  44. package/dist/agent-capacity/contracts/support/time-capacity.d.ts +163 -0
  45. package/dist/agent-capacity/contracts/support/time-capacity.js +63 -0
  46. package/dist/agent-capacity/policy/capacity/allocations/allocation-hierarchy.d.ts +29 -0
  47. package/dist/agent-capacity/policy/capacity/allocations/allocation-hierarchy.js +110 -0
  48. package/dist/agent-capacity/validation/activity-profile.d.ts +12 -0
  49. package/dist/agent-capacity/validation/activity-profile.js +264 -0
  50. package/dist/agent-capacity/validation/agent-definition-schema.d.ts +9140 -0
  51. package/dist/agent-capacity/validation/agent-definition-schema.js +198 -0
  52. package/dist/agent-capacity/validation/agent-lab-forensics-schema.d.ts +234 -0
  53. package/dist/agent-capacity/validation/agent-lab-forensics-schema.js +104 -0
  54. package/dist/agent-capacity/validation/agent-signal.d.ts +30 -0
  55. package/dist/agent-capacity/validation/agent-signal.js +31 -0
  56. package/dist/agent-capacity/validation/allocation.d.ts +12 -0
  57. package/dist/agent-capacity/validation/allocation.js +115 -0
  58. package/dist/agent-capacity/validation/assignment-records.d.ts +16 -0
  59. package/dist/agent-capacity/validation/assignment-records.js +92 -0
  60. package/dist/agent-capacity/validation/configuration.d.ts +14 -0
  61. package/dist/agent-capacity/validation/configuration.js +23 -0
  62. package/dist/agent-capacity/validation/index.d.ts +11 -0
  63. package/dist/agent-capacity/validation/index.js +11 -0
  64. package/dist/agent-capacity/validation/proposal-type.d.ts +22 -0
  65. package/dist/agent-capacity/validation/proposal-type.js +21 -0
  66. package/dist/agent-capacity/validation/research/citation.d.ts +16 -0
  67. package/dist/agent-capacity/validation/research/citation.js +47 -0
  68. package/dist/agent-capacity/validation/research/source-policy.d.ts +11 -0
  69. package/dist/agent-capacity/validation/research/source-policy.js +26 -0
  70. package/dist/agent-capacity/validation/research/workflow.d.ts +10 -0
  71. package/dist/agent-capacity/validation/research/workflow.js +31 -0
  72. package/dist/agent-capacity/validation/workflow-promotion.d.ts +2 -0
  73. package/dist/agent-capacity/validation/workflow-promotion.js +34 -0
  74. package/dist/agent-capacity/workday.d.ts +52 -0
  75. package/dist/agent-capacity/workday.js +105 -0
  76. package/dist/ai-appliance/contracts.d.ts +90 -0
  77. package/dist/ai-appliance/contracts.js +16 -0
  78. package/dist/ai-appliance/validation.d.ts +4 -0
  79. package/dist/ai-appliance/validation.js +62 -0
  80. package/dist/capacity/agents/agent-capacity.d.ts +21 -0
  81. package/dist/capacity/agents/agent-capacity.js +20 -0
  82. package/dist/capacity/capacity-core/capacity-pagination.d.ts +18 -0
  83. package/dist/capacity/capacity-core/capacity-pagination.js +33 -0
  84. package/dist/capacity/providers/capacity-provider.d.ts +1 -0
  85. package/dist/capacity/providers/capacity-provider.js +1 -0
  86. package/dist/capacity-provider/client.d.ts +56 -0
  87. package/dist/capacity-provider/client.js +163 -0
  88. package/dist/capacity-provider/contracts/capacity-facts.d.ts +64 -0
  89. package/dist/capacity-provider/contracts/capacity-facts.js +0 -0
  90. package/dist/capacity-provider/contracts/governance.d.ts +399 -0
  91. package/dist/capacity-provider/contracts/governance.js +18 -0
  92. package/dist/capacity-provider/contracts/index.d.ts +2 -0
  93. package/dist/capacity-provider/contracts/index.js +2 -0
  94. package/dist/capacity-provider/index.d.ts +3 -0
  95. package/dist/capacity-provider/index.js +3 -0
  96. package/dist/capacity-provider/validation.d.ts +27 -0
  97. package/dist/capacity-provider/validation.js +184 -0
  98. package/dist/configuration/secrets-capability.d.ts +4 -0
  99. package/dist/configuration/secrets-capability.js +4 -0
  100. package/dist/content/contracts.d.ts +12 -0
  101. package/dist/content/contracts.js +0 -0
  102. package/dist/content/validation/agent-operational-content-schemas.d.ts +1351 -0
  103. package/dist/content/validation/agent-operational-content-schemas.js +146 -0
  104. package/dist/content/validation/auxiliary-content-schemas.d.ts +1715 -0
  105. package/dist/content/validation/auxiliary-content-schemas.js +173 -0
  106. package/dist/content/validation/content-model-schemas.d.ts +21728 -0
  107. package/dist/content/validation/content-model-schemas.js +271 -0
  108. package/dist/content/validation/index.d.ts +3 -0
  109. package/dist/content/validation/index.js +3 -0
  110. package/dist/content/validation/portable-content-data.d.ts +2101 -0
  111. package/dist/content/validation/portable-content-data.js +49 -0
  112. package/dist/entrypoints/clients/control-plane-client.d.ts +112 -0
  113. package/dist/entrypoints/clients/control-plane-client.js +180 -0
  114. package/dist/entrypoints/models/field-aliases.d.ts +11 -0
  115. package/dist/entrypoints/models/model-registry.d.ts +3 -0
  116. package/dist/entrypoints/models/model-registry.js +3 -0
  117. package/dist/entrypoints/models/sdk-fields.d.ts +11 -0
  118. package/dist/entrypoints/models/sdk-types.d.ts +10 -0
  119. package/dist/entrypoints/models/sdk-types.js +10 -0
  120. package/dist/feedback/contracts.d.ts +142 -0
  121. package/dist/feedback/contracts.js +18 -0
  122. package/dist/feedback/index.d.ts +1 -0
  123. package/dist/feedback/index.js +1 -0
  124. package/dist/governance/groups/contracts.d.ts +102 -0
  125. package/dist/governance/groups/contracts.js +6 -0
  126. package/dist/graph/context-query-contracts.d.ts +19 -1
  127. package/dist/graph/context-query-contracts.js +49 -8
  128. package/dist/knowledge/contracts.d.ts +173 -0
  129. package/dist/knowledge/contracts.js +16 -0
  130. package/dist/knowledge/index.d.ts +1 -0
  131. package/dist/knowledge/index.js +1 -0
  132. package/dist/model-registry/agent-operational-models.d.ts +4 -0
  133. package/dist/model-registry/agent-operational-models.js +38 -0
  134. package/dist/model-registry/build-builtin-model-registry.d.ts +2 -0
  135. package/dist/model-registry/build-builtin-model-registry.js +426 -0
  136. package/dist/model-registry/content-root.d.ts +9 -0
  137. package/dist/model-registry/content-root.js +33 -0
  138. package/dist/model-registry/discussion-models.d.ts +4 -0
  139. package/dist/model-registry/discussion-models.js +84 -0
  140. package/dist/model-registry/group-models.d.ts +2 -0
  141. package/dist/model-registry/group-models.js +52 -0
  142. package/dist/model-registry/knowledge-models.d.ts +2 -0
  143. package/dist/model-registry/knowledge-models.js +89 -0
  144. package/dist/model-registry/normalize-definition.d.ts +8 -0
  145. package/dist/model-registry/normalize-definition.js +69 -0
  146. package/dist/operator-contracts/canonical-command-tree.d.ts +3 -0
  147. package/dist/operator-contracts/canonical-command-tree.js +81 -0
  148. package/dist/operator-contracts/command-tree.d.ts +79 -0
  149. package/dist/operator-contracts/command-tree.js +53 -0
  150. package/dist/operator-contracts/control-plane-operation.d.ts +80 -0
  151. package/dist/operator-contracts/control-plane-operation.js +75 -0
  152. package/dist/operator-contracts/control-plane-operations.d.ts +546 -0
  153. package/dist/operator-contracts/control-plane-operations.js +352 -0
  154. package/dist/operator-contracts/index.d.ts +8 -0
  155. package/dist/operator-contracts/index.js +8 -0
  156. package/dist/operator-contracts/mcp.d.ts +78 -0
  157. package/dist/operator-contracts/mcp.js +23 -0
  158. package/dist/operator-contracts/oauth.d.ts +46 -0
  159. package/dist/operator-contracts/oauth.js +0 -0
  160. package/dist/operator-contracts/workday-lifecycle.d.ts +157 -0
  161. package/dist/operator-contracts/workday-lifecycle.js +65 -0
  162. package/dist/operator-contracts/workday-profile.d.ts +72 -0
  163. package/dist/operator-contracts/workday-profile.js +106 -0
  164. package/dist/projects/projects-core/project-workflow.d.ts +179 -0
  165. package/dist/projects/projects-core/project-workflow.js +66 -0
  166. package/dist/sdk-types/configuration/sdk-dispatch-credential-source.d.ts +201 -0
  167. package/dist/sdk-types/configuration/sdk-dispatch-credential-source.js +0 -0
  168. package/dist/sdk-types/control-plane/resource-requests.d.ts +124 -0
  169. package/dist/sdk-types/control-plane/resource-requests.js +0 -0
  170. package/dist/sdk-types/governance/commons/commons-question-input.d.ts +61 -0
  171. package/dist/sdk-types/governance/commons/commons-question-input.js +0 -0
  172. package/dist/sdk-types/support/planning-policy.d.ts +210 -0
  173. package/dist/sdk-types/support/planning-policy.js +0 -0
  174. package/dist/sdk-types/support/platform-contracts.d.ts +178 -0
  175. package/dist/sdk-types/support/platform-contracts.js +15 -0
  176. package/dist/sdk-types/support/sdk-model-names.d.ts +44 -0
  177. package/dist/sdk-types/support/sdk-model-names.js +80 -0
  178. package/dist/sdk-types/support/sdk-search-request.d.ts +182 -0
  179. package/dist/sdk-types/support/sdk-search-request.js +0 -0
  180. package/dist/sdk-types/support/task-planning.d.ts +189 -0
  181. package/dist/sdk-types/support/task-planning.js +0 -0
  182. package/dist/sdk-types/treedx/graph/sdk-graph-query-request.d.ts +157 -0
  183. package/dist/sdk-types/treedx/graph/sdk-graph-query-request.js +0 -0
  184. package/dist/secrets-capability/provider-operation-contracts.d.ts +90 -0
  185. package/dist/secrets-capability/provider-operation-contracts.js +10 -0
  186. package/dist/secrets-capability/service-provider-contracts.d.ts +92 -0
  187. package/dist/secrets-capability/service-provider-contracts.js +183 -0
  188. package/dist/secrets-capability/service-vault-contracts.d.ts +61 -0
  189. package/dist/secrets-capability/service-vault-contracts.js +39 -0
  190. package/dist/secrets-capability/workflow-operation-contracts.d.ts +95 -0
  191. package/dist/secrets-capability/workflow-operation-contracts.js +0 -0
  192. package/dist/standards/canonicalize.d.ts +10 -0
  193. package/dist/standards/canonicalize.js +43 -0
  194. package/dist/standards/compatibility-attestation.d.ts +23 -0
  195. package/dist/standards/compatibility-attestation.js +40 -0
  196. package/dist/standards/composition.d.ts +15 -0
  197. package/dist/standards/composition.js +14 -0
  198. package/dist/standards/contract-bundle.d.ts +8 -0
  199. package/dist/standards/contract-bundle.js +23 -0
  200. package/dist/standards/contracts.d.ts +39 -0
  201. package/dist/standards/contracts.js +0 -0
  202. package/dist/standards/errors.d.ts +6 -0
  203. package/dist/standards/errors.js +13 -0
  204. package/dist/standards/index.d.ts +8 -0
  205. package/dist/standards/index.js +8 -0
  206. package/dist/standards/mcp/compare.d.ts +2 -0
  207. package/dist/standards/mcp/compare.js +38 -0
  208. package/dist/standards/mcp/contracts.d.ts +34 -0
  209. package/dist/standards/mcp/contracts.js +0 -0
  210. package/dist/standards/mcp/index.d.ts +3 -0
  211. package/dist/standards/mcp/index.js +3 -0
  212. package/dist/standards/mcp/normalize.d.ts +4 -0
  213. package/dist/standards/mcp/normalize.js +30 -0
  214. package/dist/standards/openapi/compare.d.ts +2 -0
  215. package/dist/standards/openapi/compare.js +112 -0
  216. package/dist/standards/openapi/contracts.d.ts +24 -0
  217. package/dist/standards/openapi/contracts.js +0 -0
  218. package/dist/standards/openapi/index.d.ts +3 -0
  219. package/dist/standards/openapi/index.js +3 -0
  220. package/dist/standards/openapi/normalize.d.ts +2 -0
  221. package/dist/standards/openapi/normalize.js +57 -0
  222. package/dist/standards/package-manifest.d.ts +37 -0
  223. package/dist/standards/package-manifest.js +89 -0
  224. package/dist/standards/portfolio-entry.d.ts +12 -0
  225. package/dist/standards/portfolio-entry.js +11 -0
  226. package/dist/standards/typescript/compare.d.ts +2 -0
  227. package/dist/standards/typescript/compare.js +88 -0
  228. package/dist/standards/typescript/contracts.d.ts +44 -0
  229. package/dist/standards/typescript/contracts.js +0 -0
  230. package/dist/standards/typescript/extract.d.ts +10 -0
  231. package/dist/standards/typescript/extract.js +244 -0
  232. package/dist/standards/typescript/index.d.ts +3 -0
  233. package/dist/standards/typescript/index.js +3 -0
  234. package/dist/treedx/accounts/auth.d.ts +17 -0
  235. package/dist/treedx/accounts/auth.js +48 -0
  236. package/dist/treedx/client/accounts/contracts/auth-mode.d.ts +3 -0
  237. package/dist/treedx/client/accounts/contracts/auth-mode.js +6 -0
  238. package/dist/treedx/client/build/creation/build-context.d.ts +3 -0
  239. package/dist/treedx/client/build/creation/build-context.js +7 -0
  240. package/dist/treedx/client/build/creation/build-snapshot.d.ts +3 -0
  241. package/dist/treedx/client/build/creation/build-snapshot.js +8 -0
  242. package/dist/treedx/client/capacity/allocations/contracts/put-capability-grant.d.ts +3 -0
  243. package/dist/treedx/client/capacity/allocations/contracts/put-capability-grant.js +7 -0
  244. package/dist/treedx/client/capacity/allocations/queries/list-capability-grants.d.ts +6 -0
  245. package/dist/treedx/client/capacity/allocations/queries/list-capability-grants.js +10 -0
  246. package/dist/treedx/client/methods.d.ts +102 -0
  247. package/dist/treedx/client/methods.js +209 -0
  248. package/dist/treedx/client/persistence/contracts/restore-storage.d.ts +3 -0
  249. package/dist/treedx/client/persistence/contracts/restore-storage.js +6 -0
  250. package/dist/treedx/client/persistence/lifecycle/verify-storage-restore.d.ts +3 -0
  251. package/dist/treedx/client/persistence/lifecycle/verify-storage-restore.js +6 -0
  252. package/dist/treedx/client/repositories/creation/register-repository.d.ts +3 -0
  253. package/dist/treedx/client/repositories/creation/register-repository.js +7 -0
  254. package/dist/treedx/client/repositories/queries/get-repository.d.ts +3 -0
  255. package/dist/treedx/client/repositories/queries/get-repository.js +7 -0
  256. package/dist/treedx/client/repositories/queries/list-repository-paths.d.ts +3 -0
  257. package/dist/treedx/client/repositories/queries/list-repository-paths.js +7 -0
  258. package/dist/treedx/client/repositories/queries/list-repository-refs.d.ts +3 -0
  259. package/dist/treedx/client/repositories/queries/list-repository-refs.js +12 -0
  260. package/dist/treedx/client/repositories/queries/query-repository.d.ts +3 -0
  261. package/dist/treedx/client/repositories/queries/query-repository.js +7 -0
  262. package/dist/treedx/client/repositories/queries/read-repository-file.d.ts +3 -0
  263. package/dist/treedx/client/repositories/queries/read-repository-file.js +6 -0
  264. package/dist/treedx/client/repositories/queries/read-repository-files.d.ts +3 -0
  265. package/dist/treedx/client/repositories/queries/read-repository-files.js +7 -0
  266. package/dist/treedx/client/repositories/queries/search-repository-files.d.ts +3 -0
  267. package/dist/treedx/client/repositories/queries/search-repository-files.js +7 -0
  268. package/dist/treedx/client/support/contracts/treedx/artifacts/contracts/download-artifact.d.ts +3 -0
  269. package/dist/treedx/client/support/contracts/treedx/artifacts/contracts/download-artifact.js +9 -0
  270. package/dist/treedx/client/support/contracts/treedx/authorization/contracts/whoami.d.ts +3 -0
  271. package/dist/treedx/client/support/contracts/treedx/authorization/contracts/whoami.js +6 -0
  272. package/dist/treedx/client/support/contracts/treedx/graph/contracts/parse-context-dsl.d.ts +3 -0
  273. package/dist/treedx/client/support/contracts/treedx/graph/contracts/parse-context-dsl.js +7 -0
  274. package/dist/treedx/client/support/contracts/treedx/health/contracts/deep-health.d.ts +5 -0
  275. package/dist/treedx/client/support/contracts/treedx/health/contracts/deep-health.js +7 -0
  276. package/dist/treedx/client/support/contracts/treedx/health/contracts/health.d.ts +3 -0
  277. package/dist/treedx/client/support/contracts/treedx/health/contracts/health.js +6 -0
  278. package/dist/treedx/client/support/contracts/treedx/health/contracts/metrics.d.ts +3 -0
  279. package/dist/treedx/client/support/contracts/treedx/health/contracts/metrics.js +7 -0
  280. package/dist/treedx/client/support/contracts/treedx/health/contracts/prometheus-metrics.d.ts +2 -0
  281. package/dist/treedx/client/support/contracts/treedx/health/contracts/prometheus-metrics.js +19 -0
  282. package/dist/treedx/client/support/contracts/treedx/health/contracts/ready.d.ts +3 -0
  283. package/dist/treedx/client/support/contracts/treedx/health/contracts/ready.js +7 -0
  284. package/dist/treedx/client/support/contracts/treedx/health/contracts/status.d.ts +3 -0
  285. package/dist/treedx/client/support/contracts/treedx/health/contracts/status.js +6 -0
  286. package/dist/treedx/client/support/contracts/treedx/repositories/contracts/commit.d.ts +3 -0
  287. package/dist/treedx/client/support/contracts/treedx/repositories/contracts/commit.js +7 -0
  288. package/dist/treedx/client/support/contracts/treedx/repositories/contracts/diff.d.ts +3 -0
  289. package/dist/treedx/client/support/contracts/treedx/repositories/contracts/diff.js +6 -0
  290. package/dist/treedx/client/support/contracts/treedx/repositories/contracts/fetch-remote.d.ts +3 -0
  291. package/dist/treedx/client/support/contracts/treedx/repositories/contracts/fetch-remote.js +7 -0
  292. package/dist/treedx/client/support/contracts/treedx/repositories/contracts/push.d.ts +6 -0
  293. package/dist/treedx/client/support/contracts/treedx/repositories/contracts/push.js +23 -0
  294. package/dist/treedx/client/support/contracts/treedx/search/contracts/compact-search-index.d.ts +3 -0
  295. package/dist/treedx/client/support/contracts/treedx/search/contracts/compact-search-index.js +8 -0
  296. package/dist/treedx/client/support/contracts/treedx/search/contracts/search.d.ts +3 -0
  297. package/dist/treedx/client/support/contracts/treedx/search/contracts/search.js +7 -0
  298. package/dist/treedx/client/support/contracts/treedx/storage/contracts/backup-storage.d.ts +3 -0
  299. package/dist/treedx/client/support/contracts/treedx/storage/contracts/backup-storage.js +8 -0
  300. package/dist/treedx/client/support/contracts/treedx/storage/contracts/compact-storage.d.ts +3 -0
  301. package/dist/treedx/client/support/contracts/treedx/storage/contracts/compact-storage.js +8 -0
  302. package/dist/treedx/client/support/contracts/treedx/transport/contracts/assert-binary-ok.d.ts +2 -0
  303. package/dist/treedx/client/support/contracts/treedx/transport/contracts/assert-binary-ok.js +15 -0
  304. package/dist/treedx/client/support/contracts/treedx/transport/contracts/fetch-with-timeout.d.ts +2 -0
  305. package/dist/treedx/client/support/contracts/treedx/transport/contracts/fetch-with-timeout.js +38 -0
  306. package/dist/treedx/client/support/contracts/treedx/transport/contracts/headers.d.ts +2 -0
  307. package/dist/treedx/client/support/contracts/treedx/transport/contracts/headers.js +15 -0
  308. package/dist/treedx/client/support/contracts/treedx/transport/contracts/parse-json-response.d.ts +2 -0
  309. package/dist/treedx/client/support/contracts/treedx/transport/contracts/parse-json-response.js +15 -0
  310. package/dist/treedx/client/support/contracts/treedx/transport/contracts/query.d.ts +2 -0
  311. package/dist/treedx/client/support/contracts/treedx/transport/contracts/query.js +14 -0
  312. package/dist/treedx/client/support/contracts/treedx/transport/contracts/repo-id.d.ts +2 -0
  313. package/dist/treedx/client/support/contracts/treedx/transport/contracts/repo-id.js +14 -0
  314. package/dist/treedx/client/support/contracts/treedx/transport/contracts/request.d.ts +6 -0
  315. package/dist/treedx/client/support/contracts/treedx/transport/contracts/request.js +41 -0
  316. package/dist/treedx/client/support/contracts/treedx/transport/contracts/throw-api-error.d.ts +2 -0
  317. package/dist/treedx/client/support/contracts/treedx/transport/contracts/throw-api-error.js +14 -0
  318. package/dist/treedx/client/support/contracts/treedx/workspaces/contracts/exec.d.ts +3 -0
  319. package/dist/treedx/client/support/contracts/treedx/workspaces/contracts/exec.js +7 -0
  320. package/dist/treedx/client/support/creation/apply-changeset.d.ts +3 -0
  321. package/dist/treedx/client/support/creation/apply-changeset.js +10 -0
  322. package/dist/treedx/client/support/creation/apply-storage-migration.d.ts +3 -0
  323. package/dist/treedx/client/support/creation/apply-storage-migration.js +7 -0
  324. package/dist/treedx/client/support/creation/create-migration.d.ts +6 -0
  325. package/dist/treedx/client/support/creation/create-migration.js +7 -0
  326. package/dist/treedx/client/support/creation/export-artifact.d.ts +3 -0
  327. package/dist/treedx/client/support/creation/export-artifact.js +8 -0
  328. package/dist/treedx/client/support/creation/plan-storage-migration.d.ts +3 -0
  329. package/dist/treedx/client/support/creation/plan-storage-migration.js +7 -0
  330. package/dist/treedx/client/support/creation/request-binary.d.ts +6 -0
  331. package/dist/treedx/client/support/creation/request-binary.js +42 -0
  332. package/dist/treedx/client/support/creation/write-file.d.ts +3 -0
  333. package/dist/treedx/client/support/creation/write-file.js +10 -0
  334. package/dist/treedx/client/support/creation/write-files.d.ts +3 -0
  335. package/dist/treedx/client/support/creation/write-files.js +12 -0
  336. package/dist/treedx/client/support/queries/treedx/artifacts/queries/get-artifact.d.ts +3 -0
  337. package/dist/treedx/client/support/queries/treedx/artifacts/queries/get-artifact.js +7 -0
  338. package/dist/treedx/client/support/queries/treedx/artifacts/queries/list-artifacts.d.ts +3 -0
  339. package/dist/treedx/client/support/queries/treedx/artifacts/queries/list-artifacts.js +7 -0
  340. package/dist/treedx/client/support/queries/treedx/authorization/queries/effective-scope.d.ts +3 -0
  341. package/dist/treedx/client/support/queries/treedx/authorization/queries/effective-scope.js +9 -0
  342. package/dist/treedx/client/support/queries/treedx/authorization/queries/list-capabilities.d.ts +4 -0
  343. package/dist/treedx/client/support/queries/treedx/authorization/queries/list-capabilities.js +6 -0
  344. package/dist/treedx/client/support/queries/treedx/federation/queries/get-placement.d.ts +3 -0
  345. package/dist/treedx/client/support/queries/treedx/federation/queries/get-placement.js +7 -0
  346. package/dist/treedx/client/support/queries/treedx/graph/queries/get-node.d.ts +3 -0
  347. package/dist/treedx/client/support/queries/treedx/graph/queries/get-node.js +7 -0
  348. package/dist/treedx/client/support/queries/treedx/graph/queries/get-related.d.ts +3 -0
  349. package/dist/treedx/client/support/queries/treedx/graph/queries/get-related.js +7 -0
  350. package/dist/treedx/client/support/queries/treedx/graph/queries/list-nodes.d.ts +3 -0
  351. package/dist/treedx/client/support/queries/treedx/graph/queries/list-nodes.js +7 -0
  352. package/dist/treedx/client/support/queries/treedx/repositories/queries/list-tree.d.ts +3 -0
  353. package/dist/treedx/client/support/queries/treedx/repositories/queries/list-tree.js +10 -0
  354. package/dist/treedx/client/support/queries/treedx/repositories/queries/read-file.d.ts +3 -0
  355. package/dist/treedx/client/support/queries/treedx/repositories/queries/read-file.js +9 -0
  356. package/dist/treedx/client/support/queries/treedx/search/queries/get-search-index-status.d.ts +3 -0
  357. package/dist/treedx/client/support/queries/treedx/search/queries/get-search-index-status.js +7 -0
  358. package/dist/treedx/client/support/queries/treedx/storage/queries/get-migration.d.ts +6 -0
  359. package/dist/treedx/client/support/queries/treedx/storage/queries/get-migration.js +7 -0
  360. package/dist/treedx/client/support/queries/treedx/storage/queries/get-snapshot.d.ts +6 -0
  361. package/dist/treedx/client/support/queries/treedx/storage/queries/get-snapshot.js +7 -0
  362. package/dist/treedx/client/support/queries/treedx/storage/queries/list-storage-migrations.d.ts +6 -0
  363. package/dist/treedx/client/support/queries/treedx/storage/queries/list-storage-migrations.js +6 -0
  364. package/dist/treedx/client/support/queries/treedx/transport/queries/list-audit-events.d.ts +15 -0
  365. package/dist/treedx/client/support/queries/treedx/transport/queries/list-audit-events.js +6 -0
  366. package/dist/treedx/client/support/queries/treedx/transport/queries/list-repositories.d.ts +3 -0
  367. package/dist/treedx/client/support/queries/treedx/transport/queries/list-repositories.js +7 -0
  368. package/dist/treedx/client/support/retirement/cleanup-artifacts.d.ts +3 -0
  369. package/dist/treedx/client/support/retirement/cleanup-artifacts.js +7 -0
  370. package/dist/treedx/client/support/retirement/delete-artifact.d.ts +3 -0
  371. package/dist/treedx/client/support/retirement/delete-artifact.js +7 -0
  372. package/dist/treedx/client/support/retirement/delete-file.d.ts +3 -0
  373. package/dist/treedx/client/support/retirement/delete-file.js +10 -0
  374. package/dist/treedx/client/support/retirement/rollback-storage-migration.d.ts +3 -0
  375. package/dist/treedx/client/support/retirement/rollback-storage-migration.js +7 -0
  376. package/dist/treedx/client/support/updates/patch-file.d.ts +3 -0
  377. package/dist/treedx/client/support/updates/patch-file.js +10 -0
  378. package/dist/treedx/client/support/updates/refresh-search-index.d.ts +3 -0
  379. package/dist/treedx/client/support/updates/refresh-search-index.js +8 -0
  380. package/dist/treedx/client/treedx/blobs/contracts/download-blob.d.ts +3 -0
  381. package/dist/treedx/client/treedx/blobs/contracts/download-blob.js +6 -0
  382. package/dist/treedx/client/treedx/blobs/creation/create-blob-upload.d.ts +3 -0
  383. package/dist/treedx/client/treedx/blobs/creation/create-blob-upload.js +8 -0
  384. package/dist/treedx/client/treedx/blobs/creation/request-blob-download.d.ts +3 -0
  385. package/dist/treedx/client/treedx/blobs/creation/request-blob-download.js +27 -0
  386. package/dist/treedx/client/treedx/blobs/creation/request-blob-upload.d.ts +3 -0
  387. package/dist/treedx/client/treedx/blobs/creation/request-blob-upload.js +41 -0
  388. package/dist/treedx/client/treedx/blobs/creation/upload-blob-part.d.ts +3 -0
  389. package/dist/treedx/client/treedx/blobs/creation/upload-blob-part.js +27 -0
  390. package/dist/treedx/client/treedx/blobs/creation/upload-blob.d.ts +3 -0
  391. package/dist/treedx/client/treedx/blobs/creation/upload-blob.js +6 -0
  392. package/dist/treedx/client/treedx/blobs/creation/write-blob.d.ts +3 -0
  393. package/dist/treedx/client/treedx/blobs/creation/write-blob.js +8 -0
  394. package/dist/treedx/client/treedx/blobs/lifecycle/complete-blob-upload.d.ts +3 -0
  395. package/dist/treedx/client/treedx/blobs/lifecycle/complete-blob-upload.js +8 -0
  396. package/dist/treedx/client/treedx/blobs/queries/read-blob.d.ts +3 -0
  397. package/dist/treedx/client/treedx/blobs/queries/read-blob.js +10 -0
  398. package/dist/treedx/client/treedx/blobs/retirement/abort-blob-upload.d.ts +3 -0
  399. package/dist/treedx/client/treedx/blobs/retirement/abort-blob-upload.js +7 -0
  400. package/dist/treedx/client/treedx/blobs/retirement/delete-blob.d.ts +3 -0
  401. package/dist/treedx/client/treedx/blobs/retirement/delete-blob.js +8 -0
  402. package/dist/treedx/client/treedx/federation/contracts/federated-query.d.ts +3 -0
  403. package/dist/treedx/client/treedx/federation/contracts/federated-query.js +7 -0
  404. package/dist/treedx/client/treedx/federation/creation/plan-federated-query.d.ts +3 -0
  405. package/dist/treedx/client/treedx/federation/creation/plan-federated-query.js +6 -0
  406. package/dist/treedx/client/treedx/federation/queries/check-mirror-health.d.ts +3 -0
  407. package/dist/treedx/client/treedx/federation/queries/check-mirror-health.js +7 -0
  408. package/dist/treedx/client/treedx/federation/updates/promote-mirror.d.ts +3 -0
  409. package/dist/treedx/client/treedx/federation/updates/promote-mirror.js +7 -0
  410. package/dist/treedx/client/treedx/federation/updates/sync-mirror.d.ts +3 -0
  411. package/dist/treedx/client/treedx/federation/updates/sync-mirror.js +7 -0
  412. package/dist/treedx/client/treedx/graph/contracts/federated-context.d.ts +3 -0
  413. package/dist/treedx/client/treedx/graph/contracts/federated-context.js +7 -0
  414. package/dist/treedx/client/treedx/graph/contracts/federated-graph.d.ts +3 -0
  415. package/dist/treedx/client/treedx/graph/contracts/federated-graph.js +7 -0
  416. package/dist/treedx/client/treedx/graph/contracts/graph-search.d.ts +3 -0
  417. package/dist/treedx/client/treedx/graph/contracts/graph-search.js +8 -0
  418. package/dist/treedx/client/treedx/graph/queries/get-graph-node.d.ts +3 -0
  419. package/dist/treedx/client/treedx/graph/queries/get-graph-node.js +10 -0
  420. package/dist/treedx/client/treedx/graph/queries/get-graph-refresh-job.d.ts +3 -0
  421. package/dist/treedx/client/treedx/graph/queries/get-graph-refresh-job.js +7 -0
  422. package/dist/treedx/client/treedx/graph/queries/get-subgraph.d.ts +3 -0
  423. package/dist/treedx/client/treedx/graph/queries/get-subgraph.js +7 -0
  424. package/dist/treedx/client/treedx/graph/queries/query-graph.d.ts +3 -0
  425. package/dist/treedx/client/treedx/graph/queries/query-graph.js +7 -0
  426. package/dist/treedx/client/treedx/graph/queries/search-graph-entities.d.ts +3 -0
  427. package/dist/treedx/client/treedx/graph/queries/search-graph-entities.js +6 -0
  428. package/dist/treedx/client/treedx/graph/queries/search-graph-files.d.ts +3 -0
  429. package/dist/treedx/client/treedx/graph/queries/search-graph-files.js +6 -0
  430. package/dist/treedx/client/treedx/graph/queries/search-graph-sections.d.ts +3 -0
  431. package/dist/treedx/client/treedx/graph/queries/search-graph-sections.js +6 -0
  432. package/dist/treedx/client/treedx/graph/updates/refresh-graph.d.ts +3 -0
  433. package/dist/treedx/client/treedx/graph/updates/refresh-graph.js +7 -0
  434. package/dist/treedx/client/treedx/search/contracts/federated-search.d.ts +3 -0
  435. package/dist/treedx/client/treedx/search/contracts/federated-search.js +7 -0
  436. package/dist/treedx/client/treedx/workspaces/creation/create-workspace.d.ts +3 -0
  437. package/dist/treedx/client/treedx/workspaces/creation/create-workspace.js +7 -0
  438. package/dist/treedx/client/treedx/workspaces/retirement/abandon-workspace.d.ts +3 -0
  439. package/dist/treedx/client/treedx/workspaces/retirement/abandon-workspace.js +12 -0
  440. package/dist/treedx/client/treedx/workspaces/retirement/close-workspace.d.ts +2 -0
  441. package/dist/treedx/client/treedx/workspaces/retirement/close-workspace.js +6 -0
  442. package/dist/treedx/generated/openapi-types.d.ts +104 -0
  443. package/dist/treedx/support/client.d.ts +251 -0
  444. package/dist/treedx/support/client.js +252 -0
  445. package/dist/treedx/support/errors.d.ts +13 -0
  446. package/dist/treedx/types/tree-dx-actor.d.ts +209 -0
  447. package/dist/treedx/types/tree-dx-actor.js +8 -0
  448. package/dist/treedx/types/tree-dx-artifact-list-response.d.ts +13 -0
  449. package/dist/treedx/types/tree-dx-artifact-list-response.js +0 -0
  450. package/dist/treedx/types/tree-dx-changeset.d.ts +51 -0
  451. package/dist/treedx/types/tree-dx-changeset.js +6 -0
  452. package/dist/treedx/types/tree-dx-context-request.d.ts +245 -0
  453. package/dist/treedx/types/tree-dx-context-request.js +0 -0
  454. package/dist/treedx/types/tree-dx-exec-result.d.ts +249 -0
  455. package/dist/treedx/types/tree-dx-exec-result.js +0 -0
  456. package/dist/treedx/types/tree-dx-list-tree-request.d.ts +222 -0
  457. package/dist/treedx/types/tree-dx-list-tree-request.js +0 -0
  458. package/dist/treedx/types/tree-dx-push-request.d.ts +229 -0
  459. package/dist/treedx/types/tree-dx-push-request.js +0 -0
  460. package/dist/treedx/types.d.ts +7 -1084
  461. package/dist/treedx/types.js +7 -8
  462. package/dist/types/agents/agent-activity-profile.d.ts +267 -0
  463. package/dist/types/agents/agent-activity-profile.js +0 -0
  464. package/dist/types/agents/agent-trigger-kinds.d.ts +189 -0
  465. package/dist/types/agents/agent-trigger-kinds.js +107 -0
  466. package/dist/types/agents/execution-run-ref.d.ts +136 -0
  467. package/dist/types/agents/execution-run-ref.js +0 -0
  468. package/dist/types/agents.d.ts +3 -493
  469. package/dist/types/agents.js +3 -95
  470. package/package.json +77 -362
  471. package/dist/agent-capacity.d.ts +0 -1100
  472. package/dist/agent-capacity.js +0 -1822
  473. package/dist/agent-tools.d.ts +0 -37
  474. package/dist/agent-tools.js +0 -301
  475. package/dist/api/app.d.ts +0 -8
  476. package/dist/api/app.js +0 -404
  477. package/dist/api/auth/d1-database.d.ts +0 -3
  478. package/dist/api/auth/d1-database.js +0 -20
  479. package/dist/api/auth/d1-provider.d.ts +0 -85
  480. package/dist/api/auth/d1-provider.js +0 -95
  481. package/dist/api/auth/d1-store.d.ts +0 -121
  482. package/dist/api/auth/d1-store.js +0 -990
  483. package/dist/api/auth/memory-provider.d.ts +0 -82
  484. package/dist/api/auth/memory-provider.js +0 -297
  485. package/dist/api/auth/rbac.d.ts +0 -22
  486. package/dist/api/auth/rbac.js +0 -162
  487. package/dist/api/auth/tokens.d.ts +0 -18
  488. package/dist/api/auth/tokens.js +0 -56
  489. package/dist/api/config.d.ts +0 -4
  490. package/dist/api/config.js +0 -149
  491. package/dist/api/http.d.ts +0 -28
  492. package/dist/api/http.js +0 -51
  493. package/dist/api/index.d.ts +0 -10
  494. package/dist/api/index.js +0 -29
  495. package/dist/api/operations-routes.d.ts +0 -11
  496. package/dist/api/operations-routes.js +0 -39
  497. package/dist/api/operations.d.ts +0 -3
  498. package/dist/api/operations.js +0 -26
  499. package/dist/api/providers.d.ts +0 -2
  500. package/dist/api/providers.js +0 -85
  501. package/dist/api/railway.d.ts +0 -53
  502. package/dist/api/railway.js +0 -71
  503. package/dist/api/sdk-dispatch.d.ts +0 -6
  504. package/dist/api/sdk-dispatch.js +0 -14
  505. package/dist/api/sdk-routes.d.ts +0 -11
  506. package/dist/api/sdk-routes.js +0 -29
  507. package/dist/api/templates.d.ts +0 -3
  508. package/dist/api/templates.js +0 -31
  509. package/dist/api/types.d.ts +0 -238
  510. package/dist/capacity-provider.d.ts +0 -494
  511. package/dist/capacity-provider.js +0 -727
  512. package/dist/capacity.d.ts +0 -483
  513. package/dist/capacity.js +0 -2331
  514. package/dist/cli-tools.d.ts +0 -3
  515. package/dist/cli-tools.js +0 -46
  516. package/dist/content-operations.d.ts +0 -97
  517. package/dist/content-operations.js +0 -250
  518. package/dist/content-store.d.ts +0 -25
  519. package/dist/content-store.js +0 -269
  520. package/dist/control-plane-client.d.ts +0 -203
  521. package/dist/control-plane-client.js +0 -540
  522. package/dist/control-plane.d.ts +0 -101
  523. package/dist/control-plane.js +0 -201
  524. package/dist/copilot.d.ts +0 -18
  525. package/dist/copilot.js +0 -90
  526. package/dist/d1-http.d.ts +0 -38
  527. package/dist/d1-http.js +0 -95
  528. package/dist/d1-store.d.ts +0 -336
  529. package/dist/d1-store.js +0 -1431
  530. package/dist/db/d1.d.ts +0 -246
  531. package/dist/db/d1.js +0 -8
  532. package/dist/db/index.d.ts +0 -3
  533. package/dist/db/index.js +0 -3
  534. package/dist/db/market-schema.d.ts +0 -83651
  535. package/dist/db/market-schema.js +0 -3725
  536. package/dist/db/node-sqlite.d.ts +0 -297
  537. package/dist/db/node-sqlite.js +0 -133
  538. package/dist/db/schema.d.ts +0 -483
  539. package/dist/db/schema.js +0 -29
  540. package/dist/dispatch.d.ts +0 -4
  541. package/dist/dispatch.js +0 -174
  542. package/dist/field-aliases.d.ts +0 -11
  543. package/dist/fixture-support.d.ts +0 -24
  544. package/dist/fixture-support.js +0 -385
  545. package/dist/frontmatter.d.ts +0 -6
  546. package/dist/frontmatter.js +0 -33
  547. package/dist/git-runtime.d.ts +0 -16
  548. package/dist/git-runtime.js +0 -69
  549. package/dist/governance.d.ts +0 -133
  550. package/dist/governance.js +0 -285
  551. package/dist/graph/build.d.ts +0 -19
  552. package/dist/graph/build.js +0 -949
  553. package/dist/graph/dsl.d.ts +0 -2
  554. package/dist/graph/dsl.js +0 -243
  555. package/dist/graph/query.d.ts +0 -47
  556. package/dist/graph/query.js +0 -447
  557. package/dist/graph/ranking.d.ts +0 -3
  558. package/dist/graph/ranking.js +0 -483
  559. package/dist/graph/schema.d.ts +0 -142
  560. package/dist/graph/schema.js +0 -137
  561. package/dist/graph.d.ts +0 -52
  562. package/dist/graph.js +0 -133
  563. package/dist/guarantees/index.d.ts +0 -512
  564. package/dist/guarantees/index.js +0 -1782
  565. package/dist/hosting/apps.d.ts +0 -12
  566. package/dist/hosting/apps.js +0 -107
  567. package/dist/hosting/builtins.d.ts +0 -25
  568. package/dist/hosting/builtins.js +0 -685
  569. package/dist/hosting/contracts.d.ts +0 -190
  570. package/dist/hosting/graph.d.ts +0 -110
  571. package/dist/hosting/graph.js +0 -993
  572. package/dist/hosting/index.d.ts +0 -4
  573. package/dist/hosting/index.js +0 -4
  574. package/dist/index.d.ts +0 -88
  575. package/dist/index.js +0 -757
  576. package/dist/local-dev/managed-dev.d.ts +0 -85
  577. package/dist/local-dev/managed-dev.js +0 -431
  578. package/dist/managed-dependencies.d.ts +0 -91
  579. package/dist/managed-dependencies.js +0 -1186
  580. package/dist/market-client.d.ts +0 -831
  581. package/dist/market-client.js +0 -1219
  582. package/dist/model-registry.d.ts +0 -8
  583. package/dist/model-registry.js +0 -674
  584. package/dist/operations/agent-tools.d.ts +0 -105
  585. package/dist/operations/agent-tools.js +0 -171
  586. package/dist/operations/providers/default.d.ts +0 -10
  587. package/dist/operations/providers/default.js +0 -1245
  588. package/dist/operations/repository-operations.d.ts +0 -158
  589. package/dist/operations/repository-operations.js +0 -851
  590. package/dist/operations/runtime.d.ts +0 -7
  591. package/dist/operations/runtime.js +0 -61
  592. package/dist/operations/services/bootstrap-runner.d.ts +0 -39
  593. package/dist/operations/services/bootstrap-runner.js +0 -191
  594. package/dist/operations/services/build-warning-policy.d.ts +0 -34
  595. package/dist/operations/services/build-warning-policy.js +0 -91
  596. package/dist/operations/services/commit-message-provider.d.ts +0 -65
  597. package/dist/operations/services/commit-message-provider.js +0 -496
  598. package/dist/operations/services/config-runtime.d.ts +0 -558
  599. package/dist/operations/services/config-runtime.js +0 -3494
  600. package/dist/operations/services/d1-migration.d.ts +0 -6
  601. package/dist/operations/services/d1-migration.js +0 -120
  602. package/dist/operations/services/deploy.d.ts +0 -645
  603. package/dist/operations/services/deploy.js +0 -3826
  604. package/dist/operations/services/deployment-readiness.d.ts +0 -30
  605. package/dist/operations/services/deployment-readiness.js +0 -217
  606. package/dist/operations/services/export-runtime.d.ts +0 -18
  607. package/dist/operations/services/export-runtime.js +0 -140
  608. package/dist/operations/services/git-remote-policy.d.ts +0 -9
  609. package/dist/operations/services/git-remote-policy.js +0 -63
  610. package/dist/operations/services/git-runner.d.ts +0 -68
  611. package/dist/operations/services/git-runner.js +0 -500
  612. package/dist/operations/services/git-workflow.d.ts +0 -255
  613. package/dist/operations/services/git-workflow.js +0 -845
  614. package/dist/operations/services/github-actions-verification.d.ts +0 -148
  615. package/dist/operations/services/github-actions-verification.js +0 -589
  616. package/dist/operations/services/github-api.d.ts +0 -279
  617. package/dist/operations/services/github-api.js +0 -936
  618. package/dist/operations/services/github-automation.d.ts +0 -230
  619. package/dist/operations/services/github-automation.js +0 -520
  620. package/dist/operations/services/github-credentials.d.ts +0 -13
  621. package/dist/operations/services/github-credentials.js +0 -59
  622. package/dist/operations/services/hosted-service-checks.d.ts +0 -82
  623. package/dist/operations/services/hosted-service-checks.js +0 -527
  624. package/dist/operations/services/hosting-audit.d.ts +0 -69
  625. package/dist/operations/services/hosting-audit.js +0 -638
  626. package/dist/operations/services/hub-launch.d.ts +0 -182
  627. package/dist/operations/services/hub-launch.js +0 -309
  628. package/dist/operations/services/hub-provider-launch.d.ts +0 -160
  629. package/dist/operations/services/hub-provider-launch.js +0 -1056
  630. package/dist/operations/services/key-agent.d.ts +0 -137
  631. package/dist/operations/services/key-agent.js +0 -641
  632. package/dist/operations/services/live-hosted-service-checks.d.ts +0 -30
  633. package/dist/operations/services/live-hosted-service-checks.js +0 -611
  634. package/dist/operations/services/local-cleanup.d.ts +0 -30
  635. package/dist/operations/services/local-cleanup.js +0 -77
  636. package/dist/operations/services/local-dev.d.ts +0 -8
  637. package/dist/operations/services/local-dev.js +0 -97
  638. package/dist/operations/services/managed-host-security.d.ts +0 -13
  639. package/dist/operations/services/managed-host-security.js +0 -56
  640. package/dist/operations/services/managed-repositories.d.ts +0 -37
  641. package/dist/operations/services/managed-repositories.js +0 -177
  642. package/dist/operations/services/market-packaging.d.ts +0 -59
  643. package/dist/operations/services/market-packaging.js +0 -234
  644. package/dist/operations/services/operations-runner-smoke.d.ts +0 -31
  645. package/dist/operations/services/operations-runner-smoke.js +0 -212
  646. package/dist/operations/services/package-adapters.d.ts +0 -184
  647. package/dist/operations/services/package-adapters.js +0 -912
  648. package/dist/operations/services/package-artifacts.d.ts +0 -37
  649. package/dist/operations/services/package-artifacts.js +0 -99
  650. package/dist/operations/services/package-reference-policy.d.ts +0 -64
  651. package/dist/operations/services/package-reference-policy.js +0 -364
  652. package/dist/operations/services/project-host-operations.d.ts +0 -153
  653. package/dist/operations/services/project-host-operations.js +0 -365
  654. package/dist/operations/services/project-platform.d.ts +0 -727
  655. package/dist/operations/services/project-platform.js +0 -1603
  656. package/dist/operations/services/project-web-monitor.d.ts +0 -15
  657. package/dist/operations/services/project-web-monitor.js +0 -377
  658. package/dist/operations/services/railway-api.d.ts +0 -494
  659. package/dist/operations/services/railway-api.js +0 -1874
  660. package/dist/operations/services/railway-cli.d.ts +0 -47
  661. package/dist/operations/services/railway-cli.js +0 -142
  662. package/dist/operations/services/railway-deploy.d.ts +0 -161
  663. package/dist/operations/services/railway-deploy.js +0 -1808
  664. package/dist/operations/services/railway-source-policy.d.ts +0 -25
  665. package/dist/operations/services/railway-source-policy.js +0 -111
  666. package/dist/operations/services/release-history.d.ts +0 -59
  667. package/dist/operations/services/release-history.js +0 -158
  668. package/dist/operations/services/release-proof-ledger.d.ts +0 -13
  669. package/dist/operations/services/release-proof-ledger.js +0 -81
  670. package/dist/operations/services/release-proof-planner.d.ts +0 -48
  671. package/dist/operations/services/release-proof-planner.js +0 -195
  672. package/dist/operations/services/release-proof-runner.d.ts +0 -16
  673. package/dist/operations/services/release-proof-runner.js +0 -169
  674. package/dist/operations/services/release-proof.d.ts +0 -81
  675. package/dist/operations/services/release-proof.js +0 -79
  676. package/dist/operations/services/repository-save-orchestrator.d.ts +0 -193
  677. package/dist/operations/services/repository-save-orchestrator.js +0 -2110
  678. package/dist/operations/services/runtime-paths.d.ts +0 -19
  679. package/dist/operations/services/runtime-paths.js +0 -54
  680. package/dist/operations/services/runtime-tools.d.ts +0 -35
  681. package/dist/operations/services/runtime-tools.js +0 -212
  682. package/dist/operations/services/save-deploy-preflight.d.ts +0 -32
  683. package/dist/operations/services/save-deploy-preflight.js +0 -82
  684. package/dist/operations/services/template-host-bindings.d.ts +0 -68
  685. package/dist/operations/services/template-host-bindings.js +0 -401
  686. package/dist/operations/services/template-registry.d.ts +0 -110
  687. package/dist/operations/services/template-registry.js +0 -595
  688. package/dist/operations/services/template-secret-sync.d.ts +0 -97
  689. package/dist/operations/services/template-secret-sync.js +0 -292
  690. package/dist/operations/services/verification-cache.d.ts +0 -25
  691. package/dist/operations/services/verification-cache.js +0 -71
  692. package/dist/operations/services/watch-dev.d.ts +0 -21
  693. package/dist/operations/services/watch-dev.js +0 -282
  694. package/dist/operations/services/workflow-timing.d.ts +0 -25
  695. package/dist/operations/services/workflow-timing.js +0 -79
  696. package/dist/operations/services/workspace-dependency-mode.d.ts +0 -74
  697. package/dist/operations/services/workspace-dependency-mode.js +0 -478
  698. package/dist/operations/services/workspace-preflight.d.ts +0 -40
  699. package/dist/operations/services/workspace-preflight.js +0 -172
  700. package/dist/operations/services/workspace-save-script.d.ts +0 -26
  701. package/dist/operations/services/workspace-save-script.js +0 -50
  702. package/dist/operations/services/workspace-save.d.ts +0 -76
  703. package/dist/operations/services/workspace-save.js +0 -453
  704. package/dist/operations/services/workspace-tools.d.ts +0 -17
  705. package/dist/operations/services/workspace-tools.js +0 -320
  706. package/dist/operations-registry.d.ts +0 -5
  707. package/dist/operations-registry.js +0 -98
  708. package/dist/operations-types.d.ts +0 -75
  709. package/dist/operations-types.js +0 -17
  710. package/dist/operations.d.ts +0 -17
  711. package/dist/operations.js +0 -114
  712. package/dist/platform/book-export.d.ts +0 -78
  713. package/dist/platform/book-export.js +0 -451
  714. package/dist/platform/books-data.d.ts +0 -28
  715. package/dist/platform/books-data.js +0 -111
  716. package/dist/platform/config.d.ts +0 -27
  717. package/dist/platform/config.js +0 -100
  718. package/dist/platform/content-runtime-source.d.ts +0 -54
  719. package/dist/platform/content-runtime-source.js +0 -169
  720. package/dist/platform/contracts.d.ts +0 -361
  721. package/dist/platform/deploy-config.d.ts +0 -17
  722. package/dist/platform/deploy-config.js +0 -731
  723. package/dist/platform/deploy-runtime.d.ts +0 -22
  724. package/dist/platform/deploy-runtime.js +0 -93
  725. package/dist/platform/desired-state.d.ts +0 -66
  726. package/dist/platform/desired-state.js +0 -1071
  727. package/dist/platform/env.yaml +0 -1126
  728. package/dist/platform/environment.d.ts +0 -159
  729. package/dist/platform/environment.js +0 -778
  730. package/dist/platform/local-content-materialization.d.ts +0 -9
  731. package/dist/platform/local-content-materialization.js +0 -212
  732. package/dist/platform/plugin.d.ts +0 -103
  733. package/dist/platform/plugin.js +0 -6
  734. package/dist/platform/plugins/constants.d.ts +0 -26
  735. package/dist/platform/plugins/constants.js +0 -33
  736. package/dist/platform/plugins/runtime.d.ts +0 -41
  737. package/dist/platform/plugins/runtime.js +0 -257
  738. package/dist/platform/plugins.d.ts +0 -6
  739. package/dist/platform/plugins.js +0 -42
  740. package/dist/platform/published-content-pipeline.d.ts +0 -84
  741. package/dist/platform/published-content-pipeline.js +0 -547
  742. package/dist/platform/published-content.d.ts +0 -224
  743. package/dist/platform/published-content.js +0 -611
  744. package/dist/platform/site-config-schema.d.ts +0 -1
  745. package/dist/platform/site-config-schema.js +0 -4
  746. package/dist/platform/tenant/runtime-config.d.ts +0 -154
  747. package/dist/platform/tenant/runtime-config.js +0 -69
  748. package/dist/platform/tenant-config.d.ts +0 -8
  749. package/dist/platform/tenant-config.js +0 -207
  750. package/dist/platform/utils/site-config-schema.d.ts +0 -154
  751. package/dist/platform/utils/site-config-schema.js +0 -450
  752. package/dist/platform-operation-store.d.ts +0 -94
  753. package/dist/platform-operation-store.js +0 -531
  754. package/dist/platform-operations.d.ts +0 -273
  755. package/dist/platform-operations.js +0 -440
  756. package/dist/plugin-default.d.ts +0 -28
  757. package/dist/plugin-default.js +0 -55
  758. package/dist/project-import.d.ts +0 -91
  759. package/dist/project-import.js +0 -257
  760. package/dist/project-workflow.d.ts +0 -233
  761. package/dist/project-workflow.js +0 -82
  762. package/dist/reconcile/bootstrap-systems.d.ts +0 -32
  763. package/dist/reconcile/bootstrap-systems.js +0 -175
  764. package/dist/reconcile/builtin-adapters.d.ts +0 -9
  765. package/dist/reconcile/builtin-adapters.js +0 -5545
  766. package/dist/reconcile/contracts.d.ts +0 -172
  767. package/dist/reconcile/desired-state.d.ts +0 -10
  768. package/dist/reconcile/desired-state.js +0 -322
  769. package/dist/reconcile/engine.d.ts +0 -118
  770. package/dist/reconcile/engine.js +0 -645
  771. package/dist/reconcile/errors.d.ts +0 -5
  772. package/dist/reconcile/errors.js +0 -13
  773. package/dist/reconcile/index.d.ts +0 -10
  774. package/dist/reconcile/index.js +0 -10
  775. package/dist/reconcile/live-acceptance.d.ts +0 -100
  776. package/dist/reconcile/live-acceptance.js +0 -2018
  777. package/dist/reconcile/platform.d.ts +0 -104
  778. package/dist/reconcile/platform.js +0 -100
  779. package/dist/reconcile/providers/docker-private.d.ts +0 -54
  780. package/dist/reconcile/providers/docker-private.js +0 -101
  781. package/dist/reconcile/providers/github-private.d.ts +0 -69
  782. package/dist/reconcile/providers/github-private.js +0 -145
  783. package/dist/reconcile/providers/local-private.d.ts +0 -28
  784. package/dist/reconcile/providers/local-private.js +0 -75
  785. package/dist/reconcile/providers/railway-iac.d.ts +0 -220
  786. package/dist/reconcile/providers/railway-iac.js +0 -621
  787. package/dist/reconcile/providers/release-private.d.ts +0 -89
  788. package/dist/reconcile/providers/release-private.js +0 -140
  789. package/dist/reconcile/registry.d.ts +0 -7
  790. package/dist/reconcile/registry.js +0 -79
  791. package/dist/reconcile/state.d.ts +0 -7
  792. package/dist/reconcile/state.js +0 -270
  793. package/dist/reconcile/units.d.ts +0 -6
  794. package/dist/reconcile/units.js +0 -72
  795. package/dist/remote.d.ts +0 -244
  796. package/dist/remote.js +0 -284
  797. package/dist/scenes/artifacts.d.ts +0 -16
  798. package/dist/scenes/artifacts.js +0 -61
  799. package/dist/scenes/auth.d.ts +0 -2
  800. package/dist/scenes/auth.js +0 -28
  801. package/dist/scenes/base-url.d.ts +0 -12
  802. package/dist/scenes/base-url.js +0 -123
  803. package/dist/scenes/builtin-plugins.d.ts +0 -2
  804. package/dist/scenes/builtin-plugins.js +0 -499
  805. package/dist/scenes/checkpoints.d.ts +0 -14
  806. package/dist/scenes/checkpoints.js +0 -33
  807. package/dist/scenes/device-matrix.d.ts +0 -2
  808. package/dist/scenes/device-matrix.js +0 -100
  809. package/dist/scenes/devices.d.ts +0 -11
  810. package/dist/scenes/devices.js +0 -40
  811. package/dist/scenes/diagnostics.d.ts +0 -5
  812. package/dist/scenes/diagnostics.js +0 -22
  813. package/dist/scenes/diagram-providers.d.ts +0 -2
  814. package/dist/scenes/diagram-providers.js +0 -181
  815. package/dist/scenes/diagram-validation.d.ts +0 -22
  816. package/dist/scenes/diagram-validation.js +0 -74
  817. package/dist/scenes/environment.d.ts +0 -2
  818. package/dist/scenes/environment.js +0 -65
  819. package/dist/scenes/evidence-bundle.d.ts +0 -5
  820. package/dist/scenes/evidence-bundle.js +0 -42
  821. package/dist/scenes/evidence-report.d.ts +0 -10
  822. package/dist/scenes/evidence-report.js +0 -73
  823. package/dist/scenes/evidence.d.ts +0 -16
  824. package/dist/scenes/evidence.js +0 -277
  825. package/dist/scenes/index.d.ts +0 -48
  826. package/dist/scenes/index.js +0 -312
  827. package/dist/scenes/inspect.d.ts +0 -9
  828. package/dist/scenes/inspect.js +0 -64
  829. package/dist/scenes/loader.d.ts +0 -3
  830. package/dist/scenes/loader.js +0 -38
  831. package/dist/scenes/logs.d.ts +0 -2
  832. package/dist/scenes/logs.js +0 -47
  833. package/dist/scenes/operations.d.ts +0 -3
  834. package/dist/scenes/operations.js +0 -128
  835. package/dist/scenes/phase0.d.ts +0 -9
  836. package/dist/scenes/phase0.js +0 -637
  837. package/dist/scenes/planner.d.ts +0 -12
  838. package/dist/scenes/planner.js +0 -166
  839. package/dist/scenes/playwright-adapter.d.ts +0 -2
  840. package/dist/scenes/playwright-adapter.js +0 -63
  841. package/dist/scenes/plugins.d.ts +0 -5
  842. package/dist/scenes/plugins.js +0 -115
  843. package/dist/scenes/progress.d.ts +0 -17
  844. package/dist/scenes/progress.js +0 -24
  845. package/dist/scenes/publish-destinations.d.ts +0 -12
  846. package/dist/scenes/publish-destinations.js +0 -99
  847. package/dist/scenes/publish-plan-report.d.ts +0 -10
  848. package/dist/scenes/publish-plan-report.js +0 -70
  849. package/dist/scenes/publish-plan.d.ts +0 -15
  850. package/dist/scenes/publish-plan.js +0 -248
  851. package/dist/scenes/publish-redaction.d.ts +0 -16
  852. package/dist/scenes/publish-redaction.js +0 -148
  853. package/dist/scenes/publish-release-record.d.ts +0 -13
  854. package/dist/scenes/publish-release-record.js +0 -34
  855. package/dist/scenes/publish-report.d.ts +0 -10
  856. package/dist/scenes/publish-report.js +0 -67
  857. package/dist/scenes/publish.d.ts +0 -16
  858. package/dist/scenes/publish.js +0 -298
  859. package/dist/scenes/registry.d.ts +0 -12
  860. package/dist/scenes/registry.js +0 -65
  861. package/dist/scenes/remotion-adapter.d.ts +0 -3
  862. package/dist/scenes/remotion-adapter.js +0 -94
  863. package/dist/scenes/remotion-composition-registry.d.ts +0 -2
  864. package/dist/scenes/remotion-composition-registry.js +0 -12
  865. package/dist/scenes/remotion-compositions.d.ts +0 -15
  866. package/dist/scenes/remotion-compositions.js +0 -464
  867. package/dist/scenes/remotion-diagrams.d.ts +0 -9
  868. package/dist/scenes/remotion-diagrams.js +0 -188
  869. package/dist/scenes/remotion-input.d.ts +0 -13
  870. package/dist/scenes/remotion-input.js +0 -291
  871. package/dist/scenes/remotion-visuals.d.ts +0 -29
  872. package/dist/scenes/remotion-visuals.js +0 -198
  873. package/dist/scenes/render-media-assets.d.ts +0 -9
  874. package/dist/scenes/render-media-assets.js +0 -117
  875. package/dist/scenes/render-report.d.ts +0 -10
  876. package/dist/scenes/render-report.js +0 -27
  877. package/dist/scenes/render.d.ts +0 -2
  878. package/dist/scenes/render.js +0 -218
  879. package/dist/scenes/reporter.d.ts +0 -3
  880. package/dist/scenes/reporter.js +0 -101
  881. package/dist/scenes/resume.d.ts +0 -2
  882. package/dist/scenes/resume.js +0 -79
  883. package/dist/scenes/runner.d.ts +0 -2
  884. package/dist/scenes/runner.js +0 -687
  885. package/dist/scenes/schema.d.ts +0 -6
  886. package/dist/scenes/schema.js +0 -1023
  887. package/dist/scenes/seed.d.ts +0 -2
  888. package/dist/scenes/seed.js +0 -83
  889. package/dist/scenes/segments.d.ts +0 -15
  890. package/dist/scenes/segments.js +0 -79
  891. package/dist/scenes/selectors.d.ts +0 -3
  892. package/dist/scenes/selectors.js +0 -21
  893. package/dist/scenes/timeline.d.ts +0 -11
  894. package/dist/scenes/timeline.js +0 -26
  895. package/dist/scenes/timeouts.d.ts +0 -6
  896. package/dist/scenes/timeouts.js +0 -17
  897. package/dist/scenes/training-captions.d.ts +0 -14
  898. package/dist/scenes/training-captions.js +0 -98
  899. package/dist/scenes/training-report.d.ts +0 -10
  900. package/dist/scenes/training-report.js +0 -78
  901. package/dist/scenes/training-transcript.d.ts +0 -24
  902. package/dist/scenes/training-transcript.js +0 -204
  903. package/dist/scenes/training.d.ts +0 -10
  904. package/dist/scenes/training.js +0 -134
  905. package/dist/scenes/types.d.ts +0 -1900
  906. package/dist/scenes/types.js +0 -8
  907. package/dist/scenes/visual-audit-contact-sheets.d.ts +0 -6
  908. package/dist/scenes/visual-audit-contact-sheets.js +0 -119
  909. package/dist/scenes/visual-audit-fixtures.d.ts +0 -25
  910. package/dist/scenes/visual-audit-fixtures.js +0 -247
  911. package/dist/scenes/visual-audit-report.d.ts +0 -11
  912. package/dist/scenes/visual-audit-report.js +0 -85
  913. package/dist/scenes/visual-audit-review.d.ts +0 -23
  914. package/dist/scenes/visual-audit-review.js +0 -829
  915. package/dist/scenes/visual-audit-routes.d.ts +0 -13
  916. package/dist/scenes/visual-audit-routes.js +0 -308
  917. package/dist/scenes/visual-audit.d.ts +0 -3
  918. package/dist/scenes/visual-audit.js +0 -596
  919. package/dist/scripts/aggregate-book.js +0 -16
  920. package/dist/scripts/assert-release-tag-version.js +0 -23
  921. package/dist/scripts/build-dist.js +0 -294
  922. package/dist/scripts/build-tenant-worker.js +0 -36
  923. package/dist/scripts/check-build-warnings.js +0 -51
  924. package/dist/scripts/cleanup-markdown.js +0 -377
  925. package/dist/scripts/cli-test-fixtures.js +0 -44
  926. package/dist/scripts/config-treeseed.js +0 -131
  927. package/dist/scripts/deployment-readiness.js +0 -20
  928. package/dist/scripts/generate-treedx-openapi-types.js +0 -186
  929. package/dist/scripts/install-managed-dependencies.js +0 -12
  930. package/dist/scripts/key-agent.js +0 -165
  931. package/dist/scripts/local-dev.js +0 -129
  932. package/dist/scripts/migrate-journey-csv-to-guarantees.js +0 -140
  933. package/dist/scripts/operations-runner-smoke.js +0 -16
  934. package/dist/scripts/package-tools.js +0 -85
  935. package/dist/scripts/patch-starlight-content-path.js +0 -173
  936. package/dist/scripts/prepare.js +0 -10
  937. package/dist/scripts/publish-package.js +0 -29
  938. package/dist/scripts/release-verify.js +0 -105
  939. package/dist/scripts/run-fixture-astro-command.js +0 -18
  940. package/dist/scripts/scaffold-site.js +0 -66
  941. package/dist/scripts/sync-template.js +0 -20
  942. package/dist/scripts/template-catalog.test.js +0 -86
  943. package/dist/scripts/template-command.js +0 -31
  944. package/dist/scripts/tenant-astro-command.js +0 -3
  945. package/dist/scripts/tenant-build.js +0 -48
  946. package/dist/scripts/tenant-check.js +0 -10
  947. package/dist/scripts/tenant-d1-migrate-local.js +0 -15
  948. package/dist/scripts/tenant-deploy.js +0 -220
  949. package/dist/scripts/tenant-destroy.js +0 -112
  950. package/dist/scripts/tenant-dev.js +0 -160
  951. package/dist/scripts/tenant-lint.js +0 -4
  952. package/dist/scripts/tenant-test.js +0 -4
  953. package/dist/scripts/tenant-workflow-action.js +0 -101
  954. package/dist/scripts/test-cloudflare-local.js +0 -209
  955. package/dist/scripts/test-scaffold.js +0 -300
  956. package/dist/scripts/test-smoke.js +0 -137
  957. package/dist/scripts/treeseed-assert-release-tag-version.js +0 -21
  958. package/dist/scripts/treeseed-build-dist.js +0 -131
  959. package/dist/scripts/treeseed-publish-package.js +0 -19
  960. package/dist/scripts/treeseed-release-verify.js +0 -131
  961. package/dist/scripts/validate-templates.js +0 -6
  962. package/dist/scripts/verify-driver.js +0 -45
  963. package/dist/scripts/workflow-commands.test.js +0 -31
  964. package/dist/scripts/workspace-command-e2e.js +0 -718
  965. package/dist/scripts/workspace-lint.js +0 -15
  966. package/dist/scripts/workspace-preflight.js +0 -22
  967. package/dist/scripts/workspace-publish-changed-packages.js +0 -16
  968. package/dist/scripts/workspace-release-test.js +0 -104
  969. package/dist/scripts/workspace-release-verify.js +0 -81
  970. package/dist/scripts/workspace-save.js +0 -64
  971. package/dist/scripts/workspace-start-warning.js +0 -3
  972. package/dist/scripts/workspace-test-unit.js +0 -4
  973. package/dist/scripts/workspace-test.js +0 -17
  974. package/dist/sdk-dispatch.d.ts +0 -12
  975. package/dist/sdk-dispatch.js +0 -126
  976. package/dist/sdk-fields.d.ts +0 -11
  977. package/dist/sdk-filters.d.ts +0 -4
  978. package/dist/sdk-filters.js +0 -74
  979. package/dist/sdk-types.d.ts +0 -3868
  980. package/dist/sdk-types.js +0 -542
  981. package/dist/sdk-version.d.ts +0 -2
  982. package/dist/sdk-version.js +0 -42
  983. package/dist/sdk.d.ts +0 -266
  984. package/dist/sdk.js +0 -825
  985. package/dist/secrets-capability.d.ts +0 -421
  986. package/dist/secrets-capability.js +0 -530
  987. package/dist/seeds/errors.d.ts +0 -5
  988. package/dist/seeds/errors.js +0 -22
  989. package/dist/seeds/index.d.ts +0 -20
  990. package/dist/seeds/index.js +0 -53
  991. package/dist/seeds/loader.d.ts +0 -8
  992. package/dist/seeds/loader.js +0 -32
  993. package/dist/seeds/normalize.d.ts +0 -13
  994. package/dist/seeds/normalize.js +0 -282
  995. package/dist/seeds/planner.d.ts +0 -10
  996. package/dist/seeds/planner.js +0 -149
  997. package/dist/seeds/schema.d.ts +0 -2
  998. package/dist/seeds/schema.js +0 -893
  999. package/dist/seeds/types.d.ts +0 -312
  1000. package/dist/seeds/types.js +0 -12
  1001. package/dist/service-credentials.d.ts +0 -54
  1002. package/dist/service-credentials.js +0 -112
  1003. package/dist/stores/cursor-store.d.ts +0 -10
  1004. package/dist/stores/cursor-store.js +0 -164
  1005. package/dist/stores/envelopes.d.ts +0 -116
  1006. package/dist/stores/envelopes.js +0 -219
  1007. package/dist/stores/helpers.d.ts +0 -12
  1008. package/dist/stores/helpers.js +0 -42
  1009. package/dist/stores/lease-store.d.ts +0 -18
  1010. package/dist/stores/lease-store.js +0 -189
  1011. package/dist/stores/message-store.d.ts +0 -12
  1012. package/dist/stores/message-store.js +0 -273
  1013. package/dist/stores/operational-store.d.ts +0 -55
  1014. package/dist/stores/operational-store.js +0 -861
  1015. package/dist/stores/project-workflow-store.d.ts +0 -56
  1016. package/dist/stores/project-workflow-store.js +0 -482
  1017. package/dist/stores/run-store.d.ts +0 -9
  1018. package/dist/stores/run-store.js +0 -75
  1019. package/dist/stores/subscription-store.d.ts +0 -8
  1020. package/dist/stores/subscription-store.js +0 -73
  1021. package/dist/template-catalog.d.ts +0 -13
  1022. package/dist/template-catalog.js +0 -151
  1023. package/dist/template-launch-requirements.d.ts +0 -118
  1024. package/dist/template-launch-requirements.js +0 -768
  1025. package/dist/template-launch-ui.d.ts +0 -85
  1026. package/dist/template-launch-ui.js +0 -189
  1027. package/dist/timing.d.ts +0 -20
  1028. package/dist/timing.js +0 -73
  1029. package/dist/treedx/adapters.d.ts +0 -6
  1030. package/dist/treedx/adapters.js +0 -36
  1031. package/dist/treedx/client.d.ts +0 -222
  1032. package/dist/treedx/client.js +0 -871
  1033. package/dist/treedx/errors.d.ts +0 -13
  1034. package/dist/treedx/federated-client.d.ts +0 -27
  1035. package/dist/treedx/federated-client.js +0 -158
  1036. package/dist/treedx/graph-adapter.d.ts +0 -33
  1037. package/dist/treedx/graph-adapter.js +0 -156
  1038. package/dist/treedx/index.d.ts +0 -14
  1039. package/dist/treedx/index.js +0 -48
  1040. package/dist/treedx/market-integration.d.ts +0 -27
  1041. package/dist/treedx/market-integration.js +0 -131
  1042. package/dist/treedx/ports.d.ts +0 -166
  1043. package/dist/treedx/ports.js +0 -231
  1044. package/dist/treedx/query-adapter.d.ts +0 -19
  1045. package/dist/treedx/query-adapter.js +0 -62
  1046. package/dist/treedx/registry-client.d.ts +0 -11
  1047. package/dist/treedx/registry-client.js +0 -19
  1048. package/dist/treedx/repository-adapter.d.ts +0 -45
  1049. package/dist/treedx/repository-adapter.js +0 -319
  1050. package/dist/treedx/sdk-integration.d.ts +0 -27
  1051. package/dist/treedx/sdk-integration.js +0 -63
  1052. package/dist/treedx/workspace-adapter.d.ts +0 -27
  1053. package/dist/treedx/workspace-adapter.js +0 -65
  1054. package/dist/treedx-backends.d.ts +0 -220
  1055. package/dist/treedx-backends.js +0 -634
  1056. package/dist/treedx-client.d.ts +0 -89
  1057. package/dist/treedx-client.js +0 -184
  1058. package/dist/treeseed/services/compose.yml +0 -6
  1059. package/dist/treeseed/template-catalog/catalog.fixture.json +0 -707
  1060. package/dist/types/cloudflare.d.ts +0 -54
  1061. package/dist/verification.d.ts +0 -31
  1062. package/dist/verification.js +0 -430
  1063. package/dist/workflow/operations.d.ts +0 -1516
  1064. package/dist/workflow/operations.js +0 -7001
  1065. package/dist/workflow/policy.d.ts +0 -12
  1066. package/dist/workflow/policy.js +0 -70
  1067. package/dist/workflow/runs.d.ts +0 -143
  1068. package/dist/workflow/runs.js +0 -720
  1069. package/dist/workflow/session.d.ts +0 -34
  1070. package/dist/workflow/session.js +0 -160
  1071. package/dist/workflow/worktrees.d.ts +0 -43
  1072. package/dist/workflow/worktrees.js +0 -307
  1073. package/dist/workflow-state.d.ts +0 -250
  1074. package/dist/workflow-state.js +0 -844
  1075. package/dist/workflow-support.d.ts +0 -28
  1076. package/dist/workflow-support.js +0 -390
  1077. package/dist/workflow.d.ts +0 -327
  1078. package/dist/workflow.js +0 -140
  1079. package/drizzle/d1/0000_treeseed_d1.sql +0 -19
  1080. package/drizzle/market/0000_market_control_plane.sql +0 -3223
  1081. package/drizzle/market/0001_capacity_budget_mode_default.sql +0 -4
  1082. package/drizzle/market/0002_user_email_addresses.sql +0 -26
  1083. package/drizzle/market/0003_project_team_slug_unique.sql +0 -4
  1084. package/drizzle/market/0004_treedx_market_integration.sql +0 -99
  1085. package/drizzle/market/0005_agent_capacity_coordination.sql +0 -145
  1086. package/drizzle/market/0006_provider_assignment_lifecycle.sql +0 -9
  1087. package/drizzle/market/0007_agent_architecture_gap_closure.sql +0 -157
  1088. package/drizzle/market/0008_agent_capacity_operational_closure.sql +0 -27
  1089. package/drizzle/market/0009_agent_capacity_runtime_hardening.sql +0 -29
  1090. package/drizzle/market/0010_secrets_capability_persistence.sql +0 -130
  1091. package/drizzle/market/0011_github_app_adapter.sql +0 -47
  1092. package/drizzle/market/0012_workday_test_runs.sql +0 -44
  1093. package/drizzle/market/0013_runtime_task_lifecycle.sql +0 -39
  1094. package/drizzle/market/0014_governance_pipeline.sql +0 -189
  1095. package/drizzle/market/0015_agent_decision_assignment_graphs.sql +0 -60
  1096. package/scripts/verify-driver.ts +0 -51
  1097. package/templates/github/deploy-web.workflow.yml +0 -168
  1098. package/templates/github/hosted-project.workflow.yml +0 -76
  1099. /package/dist/{api/types.js → agent-capacity/contracts/capacity/workdays/workday-records.js} +0 -0
  1100. /package/dist/{hosting/contracts.js → agent-capacity/contracts/operations/workflow-promotion.js} +0 -0
  1101. /package/dist/{platform/contracts.js → agent-capacity/contracts/projects/agents/project-agent-class.js} +0 -0
  1102. /package/dist/{reconcile/contracts.js → agent-capacity/contracts/runtime/runtime-observability.js} +0 -0
  1103. /package/dist/{types/cloudflare.js → agent-capacity/contracts/support/decision-work.js} +0 -0
  1104. /package/dist/{field-aliases.js → entrypoints/models/field-aliases.js} +0 -0
  1105. /package/dist/{sdk-fields.js → entrypoints/models/sdk-fields.js} +0 -0
  1106. /package/dist/{runtime.d.ts → runtime/runtime.d.ts} +0 -0
  1107. /package/dist/{runtime.js → runtime/runtime.js} +0 -0
  1108. /package/dist/treedx/{errors.js → support/errors.js} +0 -0
@@ -1,3494 +0,0 @@
1
- import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
2
- import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3
- import { homedir } from "node:os";
4
- import { dirname, resolve } from "node:path";
5
- import { spawn, spawnSync } from "node:child_process";
6
- import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
7
- import {
8
- getTreeseedEnvironmentSuggestedValues,
9
- isTreeseedEnvironmentEntryRelevant,
10
- isTreeseedEnvironmentEntryRequired,
11
- resolveTreeseedEnvironmentRegistry,
12
- TREESEED_ENVIRONMENT_SCOPES,
13
- validateTreeseedEnvironmentValues
14
- } from "../../platform/environment.js";
15
- import { loadTreeseedManifest } from "../../platform/tenant-config.js";
16
- import {
17
- buildProvisioningSummary,
18
- createPersistentDeployTarget,
19
- ensureGeneratedWranglerConfig,
20
- loadDeployState,
21
- syncCloudflareSecrets
22
- } from "./deploy.js";
23
- import {
24
- collectTreeseedReconcileStatus,
25
- reconcileTreeseedTarget,
26
- resolveTreeseedBootstrapSelection
27
- } from "../../reconcile/index.js";
28
- import {
29
- ensureGitHubBootstrapRepository,
30
- maybeResolveGitHubRepositorySlug
31
- } from "./github-automation.js";
32
- import {
33
- buildRailwayCommandEnv,
34
- configuredRailwayServices
35
- } from "./railway-deploy.js";
36
- import {
37
- ensureRailwayEnvironment,
38
- ensureRailwayProject,
39
- ensureRailwayService,
40
- normalizeRailwayEnvironmentName,
41
- resolveRailwayWorkspace,
42
- resolveRailwayWorkspaceContext,
43
- upsertRailwayVariables
44
- } from "./railway-api.js";
45
- import { discoverTreeseedApplications } from "../../hosting/apps.js";
46
- import {
47
- createGitHubApiClient,
48
- ensureGitHubBranchFromBase
49
- } from "./github-api.js";
50
- import { resolveGitHubCredentialForRepository } from "./github-credentials.js";
51
- import { loadCliDeployConfig, packageDistScriptRoot, packageScriptPath, resolveWranglerBin, withProcessCwd } from "./runtime-tools.js";
52
- import { PRODUCTION_BRANCH, STAGING_BRANCH } from "./git-workflow.js";
53
- import {
54
- createTreeseedManagedToolEnv,
55
- resolveTreeseedToolBinary,
56
- resolveTreeseedToolCommand
57
- } from "../../managed-dependencies.js";
58
- import { resolveTreeseedGitHubToken, withTreeseedServiceCredentialEnv } from "../../service-credentials.js";
59
- import {
60
- filterManagedHostGitHubEnvironment,
61
- usesManagedHostOperationRequests
62
- } from "./managed-host-security.js";
63
- import {
64
- assertTreeseedKeyAgentResponse,
65
- getTreeseedKeyAgentPaths,
66
- inspectTreeseedKeyAgentDiagnostics,
67
- readWrappedMachineKeyFile,
68
- replaceWrappedMachineKey,
69
- rotateWrappedMachineKeyPassphrase,
70
- TREESEED_KEY_AGENT_IDLE_TIMEOUT_MS,
71
- TREESEED_MACHINE_KEY_PASSPHRASE_ENV,
72
- TreeseedKeyAgentError,
73
- unwrapMachineKey
74
- } from "./key-agent.js";
75
- import { TREESEED_MACHINE_KEY_PASSPHRASE_ENV as TREESEED_MACHINE_KEY_PASSPHRASE_ENV2, TreeseedKeyAgentError as TreeseedKeyAgentError2 } from "./key-agent.js";
76
- const MACHINE_CONFIG_RELATIVE_PATH = ".treeseed/config/machine.yaml";
77
- const MACHINE_KEY_HOME_RELATIVE_PATH = ".treeseed/config/machine.key";
78
- const LEGACY_MACHINE_KEY_RELATIVE_PATH = ".treeseed/config/machine.key";
79
- const REMOTE_AUTH_RELATIVE_PATH = ".treeseed/config/remote-auth.json";
80
- const WORKTREE_METADATA_RELATIVE_PATH = ".treeseed/worktree.json";
81
- const TEMPLATE_CATALOG_CACHE_RELATIVE_PATH = "treeseed/cache/template-catalog.json";
82
- const TENANT_ENVIRONMENT_OVERLAY_PATH = "src/env.yaml";
83
- const CLOUDFLARE_ACCOUNT_ID_PLACEHOLDER = "replace-with-cloudflare-account-id";
84
- const TREESEED_KEY_AGENT_AUTOPROMPT_ENV = "TREESEED_KEY_AGENT_AUTOPROMPT";
85
- const KEY_AGENT_COMMAND_TIMEOUT_MS = 1e4;
86
- const DEFAULT_TREESEED_API_BASE_URL = "https://api.treeseed.dev";
87
- const DEFAULT_TEMPLATE_CATALOG_URL = "https://api.treeseed.dev/search/templates";
88
- const TREESEED_TEMPLATE_CATALOG_URL_ENV = "TREESEED_TEMPLATE_CATALOG_URL";
89
- const TREESEED_API_BASE_URL_ENV = "TREESEED_API_BASE_URL";
90
- const CLI_CHECK_TIMEOUT_MS = 5e3;
91
- const DEPRECATED_LOCAL_ENV_FILES = [".env.local", ".dev.vars"];
92
- const PROVIDER_CONTROL_ENV_KEYS = [
93
- "TREESEED_GITHUB_TOKEN",
94
- "TREESEED_CLOUDFLARE_API_TOKEN",
95
- "TREESEED_CLOUDFLARE_ACCOUNT_ID",
96
- "CLOUDFLARE_ZONE_ID",
97
- "TREESEED_RAILWAY_API_TOKEN",
98
- "TREESEED_RAILWAY_WORKSPACE"
99
- ];
100
- const warnedDeprecatedLocalEnvRoots = /* @__PURE__ */ new Set();
101
- const inlineTreeseedSecretSessions = /* @__PURE__ */ new Map();
102
- const machineKeyHomeRootsByConfigRoot = /* @__PURE__ */ new Map();
103
- const railwayConnectionCheckCache = /* @__PURE__ */ new Map();
104
- function filterEnvironmentValuesByRegistry(values, registry, scope, purpose = "config") {
105
- const registeredKeys = new Set(registry.entries.filter((entry) => isTreeseedEnvironmentEntryRelevant(entry, registry.context, scope, purpose)).map((entry) => entry.id));
106
- return Object.fromEntries(
107
- Object.entries(values).filter(([key]) => registeredKeys.has(key))
108
- );
109
- }
110
- function inspectTreeseedPassphraseEnvDiagnostic(env = process.env) {
111
- const configured = typeof env[TREESEED_MACHINE_KEY_PASSPHRASE_ENV] === "string" && env[TREESEED_MACHINE_KEY_PASSPHRASE_ENV].trim().length > 0;
112
- return {
113
- envVar: TREESEED_MACHINE_KEY_PASSPHRASE_ENV,
114
- configured,
115
- recommendedLaunch: `Export ${TREESEED_MACHINE_KEY_PASSPHRASE_ENV} in a shell and launch \`code .\` from that shell before starting the Codex session.`
116
- };
117
- }
118
- async function inspectTreeseedKeyAgentTransportDiagnostic() {
119
- const { socketPath, pidPath } = getTreeseedKeyAgentPaths();
120
- const diagnostics = await inspectTreeseedKeyAgentDiagnostics(socketPath);
121
- return {
122
- socketPath,
123
- pidPath,
124
- ...diagnostics
125
- };
126
- }
127
- function createDefaultRemoteHost() {
128
- return {
129
- id: "official",
130
- label: "TreeSeed Official API",
131
- baseUrl: DEFAULT_TREESEED_API_BASE_URL,
132
- official: true
133
- };
134
- }
135
- function createDefaultRemoteSettings() {
136
- return {
137
- activeHostId: "official",
138
- executionMode: "prefer-local",
139
- hosts: [createDefaultRemoteHost()]
140
- };
141
- }
142
- function normalizeRemoteSettings(value) {
143
- const record = value && typeof value === "object" ? value : {};
144
- const hosts = Array.isArray(record.hosts) ? record.hosts.filter((entry) => entry && typeof entry === "object").map((entry) => ({
145
- id: typeof entry.id === "string" && entry.id.trim() ? entry.id.trim() : "official",
146
- label: typeof entry.label === "string" && entry.label.trim() ? entry.label.trim() : void 0,
147
- baseUrl: typeof entry.baseUrl === "string" && entry.baseUrl.trim() ? entry.baseUrl.trim().replace(/\/$/u, "") : DEFAULT_TREESEED_API_BASE_URL,
148
- official: entry.official === true
149
- })) : [createDefaultRemoteHost()];
150
- return {
151
- activeHostId: typeof record.activeHostId === "string" && record.activeHostId.trim() ? record.activeHostId.trim() : hosts[0]?.id ?? "official",
152
- executionMode: record.executionMode === "prefer-remote" || record.executionMode === "remote-only" ? record.executionMode : "prefer-local",
153
- hosts
154
- };
155
- }
156
- function createDefaultServiceSettings() {
157
- return {
158
- railway: {
159
- projectId: "",
160
- projectName: "",
161
- apiServiceId: "",
162
- apiServiceName: ""
163
- }
164
- };
165
- }
166
- function normalizeServiceSettings(value) {
167
- const record = value && typeof value === "object" ? value : {};
168
- const railway = record.railway && typeof record.railway === "object" ? record.railway : {};
169
- return {
170
- railway: {
171
- projectId: typeof railway.projectId === "string" ? railway.projectId : "",
172
- projectName: typeof railway.projectName === "string" ? railway.projectName : "",
173
- apiServiceId: typeof railway.apiServiceId === "string" ? railway.apiServiceId : "",
174
- apiServiceName: typeof railway.apiServiceName === "string" ? railway.apiServiceName : ""
175
- }
176
- };
177
- }
178
- function ensureParent(filePath) {
179
- mkdirSync(dirname(filePath), { recursive: true });
180
- }
181
- function listDeprecatedTreeseedLocalEnvFiles(tenantRoot) {
182
- return DEPRECATED_LOCAL_ENV_FILES.map((fileName) => resolve(tenantRoot, fileName)).filter((filePath) => existsSync(filePath));
183
- }
184
- function warnDeprecatedTreeseedLocalEnvFiles(tenantRoot, write = (line) => console.warn(line)) {
185
- const existing = listDeprecatedTreeseedLocalEnvFiles(tenantRoot);
186
- if (existing.length === 0 || warnedDeprecatedLocalEnvRoots.has(tenantRoot)) {
187
- return existing;
188
- }
189
- warnedDeprecatedLocalEnvRoots.add(tenantRoot);
190
- write(
191
- `Treeseed ignores deprecated local env files: ${existing.map((filePath) => filePath.replace(`${tenantRoot}/`, "")).join(", ")}. Delete them and rely on .treeseed/config/machine.yaml plus Treeseed-launched commands.`
192
- );
193
- return existing;
194
- }
195
- function maskValue(value) {
196
- if (!value) {
197
- return "(unset)";
198
- }
199
- if (value.length <= 8) {
200
- return "********";
201
- }
202
- return `${value.slice(0, 3)}...${value.slice(-3)}`;
203
- }
204
- function writeDeploySummary(write, summary) {
205
- write("Treeseed deployment summary");
206
- write(` Target: ${summary.target}`);
207
- write(` Worker: ${summary.workerName}`);
208
- write(` Site URL: ${summary.siteUrl}`);
209
- write(` Account ID: ${summary.accountId}`);
210
- write(` D1: ${summary.siteDataDb.databaseName} (${summary.siteDataDb.databaseId})`);
211
- write(` KV FORM_GUARD_KV: ${summary.formGuardKv.id}`);
212
- }
213
- function syncManagedServiceSettingsFromDeployConfig(tenantRoot) {
214
- const config = loadTreeseedMachineConfig(tenantRoot);
215
- const deployConfig = loadTenantDeployConfig(tenantRoot);
216
- const railway = config.settings.services.railway;
217
- railway.projectId = deployConfig.services?.api?.railway?.projectId ?? railway.projectId;
218
- railway.projectName = deployConfig.services?.api?.railway?.projectName ?? railway.projectName;
219
- railway.apiServiceId = deployConfig.services?.api?.railway?.serviceId ?? railway.apiServiceId;
220
- railway.apiServiceName = deployConfig.services?.api?.railway?.serviceName ?? railway.apiServiceName;
221
- const remote = normalizeRemoteSettings(config.settings.remote);
222
- const defaultHostBaseUrl = process.env[TREESEED_API_BASE_URL_ENV] ?? deployConfig.services?.api?.environments?.prod?.baseUrl ?? deployConfig.services?.api?.publicBaseUrl ?? remote.hosts[0]?.baseUrl ?? DEFAULT_TREESEED_API_BASE_URL;
223
- const officialHost = remote.hosts.find((entry) => entry.id === "official");
224
- if (officialHost) {
225
- officialHost.baseUrl = defaultHostBaseUrl.replace(/\/$/u, "");
226
- } else {
227
- remote.hosts.unshift({
228
- id: "official",
229
- label: "TreeSeed Official API",
230
- baseUrl: defaultHostBaseUrl.replace(/\/$/u, ""),
231
- official: true
232
- });
233
- }
234
- config.settings.remote = remote;
235
- writeTreeseedMachineConfig(tenantRoot, config);
236
- return config;
237
- }
238
- function loadTenantDeployConfig(tenantRoot) {
239
- try {
240
- return loadCliDeployConfig(tenantRoot);
241
- } catch (error) {
242
- const packageJsonPath = resolve(tenantRoot, "package.json");
243
- if (!existsSync(packageJsonPath)) {
244
- throw error;
245
- }
246
- try {
247
- const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
248
- if (packageJson?.name !== "@treeseed/agent") {
249
- throw error;
250
- }
251
- const deployConfig = {
252
- name: "TreeSeed Agent Capacity Provider",
253
- slug: "treeseed-agent-capacity-provider",
254
- siteUrl: "http://127.0.0.1:3100",
255
- contactEmail: "hello@treeseed.ai",
256
- hosting: { kind: "self_hosted_project", registration: "none" },
257
- hub: { mode: "treeseed_hosted" },
258
- runtime: { mode: "byo_attached", registration: "none" },
259
- surfaces: {
260
- web: { enabled: false },
261
- api: { enabled: true, provider: "local", rootDir: ".", localBaseUrl: "http://127.0.0.1:3100" }
262
- },
263
- services: {
264
- api: { enabled: true, provider: "local", rootDir: "." }
265
- },
266
- processing: { mode: "local" },
267
- providers: {
268
- agents: {
269
- execution: "codex",
270
- mutation: "local_branch",
271
- repository: "git",
272
- verification: "local",
273
- notification: "sdk_message",
274
- research: "project_graph"
275
- }
276
- },
277
- plugins: []
278
- };
279
- Object.defineProperty(deployConfig, "__tenantRoot", {
280
- value: tenantRoot,
281
- enumerable: false
282
- });
283
- return deployConfig;
284
- } catch (fallbackError) {
285
- if (fallbackError === error) throw error;
286
- throw fallbackError;
287
- }
288
- }
289
- }
290
- function loadOptionalTenantManifest(tenantRoot) {
291
- try {
292
- return withProcessCwd(tenantRoot, () => loadTreeseedManifest());
293
- } catch {
294
- return void 0;
295
- }
296
- }
297
- function findNearestTreeseedMachineConfig(startRoot = process.cwd()) {
298
- let current = resolve(startRoot);
299
- while (true) {
300
- const configPath = resolve(current, MACHINE_CONFIG_RELATIVE_PATH);
301
- if (existsSync(configPath)) {
302
- return configPath;
303
- }
304
- const parent = resolve(current, "..");
305
- if (parent === current) {
306
- break;
307
- }
308
- current = parent;
309
- }
310
- return null;
311
- }
312
- function getTreeseedMachineConfigPaths(tenantRoot) {
313
- const configRoot = resolveManagedWorktreeMachineConfigRoot(tenantRoot);
314
- const defaultHomeRoot = process.env.VITEST === "true" ? configRoot : process.env.HOME && process.env.HOME.trim().length > 0 ? process.env.HOME : homedir();
315
- const homeRoot = machineKeyHomeRootsByConfigRoot.get(configRoot) ?? defaultHomeRoot;
316
- machineKeyHomeRootsByConfigRoot.set(configRoot, homeRoot);
317
- return {
318
- configPath: resolve(configRoot, MACHINE_CONFIG_RELATIVE_PATH),
319
- authPath: resolve(configRoot, REMOTE_AUTH_RELATIVE_PATH),
320
- keyPath: resolve(homeRoot, MACHINE_KEY_HOME_RELATIVE_PATH),
321
- legacyKeyPath: resolve(configRoot, LEGACY_MACHINE_KEY_RELATIVE_PATH)
322
- };
323
- }
324
- function resolveManagedWorktreeMachineConfigRoot(tenantRoot) {
325
- if (existsSync(resolve(tenantRoot, MACHINE_CONFIG_RELATIVE_PATH))) {
326
- return tenantRoot;
327
- }
328
- const metadataPath = resolve(tenantRoot, WORKTREE_METADATA_RELATIVE_PATH);
329
- if (!existsSync(metadataPath)) return tenantRoot;
330
- try {
331
- const metadata = JSON.parse(readFileSync(metadataPath, "utf8")) ?? {};
332
- const primaryRoot = metadata.kind === "treeseed.workflow.worktree" && typeof metadata.primaryRoot === "string" ? metadata.primaryRoot : null;
333
- return primaryRoot && existsSync(resolve(primaryRoot, MACHINE_CONFIG_RELATIVE_PATH)) ? primaryRoot : tenantRoot;
334
- } catch {
335
- return tenantRoot;
336
- }
337
- }
338
- function keyAgentScriptPath() {
339
- const distScriptPath = resolve(packageDistScriptRoot, "key-agent.js");
340
- return existsSync(distScriptPath) ? distScriptPath : packageScriptPath("key-agent.ts");
341
- }
342
- function keyAgentNodeArgs() {
343
- const scriptPath = keyAgentScriptPath();
344
- return scriptPath.endsWith(".ts") ? ["--import", "tsx", scriptPath] : [scriptPath];
345
- }
346
- function keyAgentScriptCwd() {
347
- return dirname(dirname(keyAgentScriptPath()));
348
- }
349
- function sleepMs(milliseconds) {
350
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
351
- }
352
- function shellQuote(value) {
353
- return `'${value.replace(/'/gu, `'\\''`)}'`;
354
- }
355
- function keyAgentAutoPromptEnabled() {
356
- const value = String(process.env[TREESEED_KEY_AGENT_AUTOPROMPT_ENV] ?? "").trim().toLowerCase();
357
- if (value === "0" || value === "false" || value === "off") {
358
- return false;
359
- }
360
- return process.stdin.isTTY && process.stdout.isTTY;
361
- }
362
- function useInlineKeyAgentTransport() {
363
- return process.env.VITEST === "true" || process.env.TREESEED_KEY_AGENT_TRANSPORT === "inline";
364
- }
365
- function withTreeseedKeyAgentAutopromptDisabled(action) {
366
- const previous = process.env[TREESEED_KEY_AGENT_AUTOPROMPT_ENV];
367
- process.env[TREESEED_KEY_AGENT_AUTOPROMPT_ENV] = "0";
368
- try {
369
- return action();
370
- } finally {
371
- if (previous === void 0) {
372
- delete process.env[TREESEED_KEY_AGENT_AUTOPROMPT_ENV];
373
- } else {
374
- process.env[TREESEED_KEY_AGENT_AUTOPROMPT_ENV] = previous;
375
- }
376
- }
377
- }
378
- function startTreeseedKeyAgentDaemon(tenantRoot) {
379
- const { keyPath } = getTreeseedMachineConfigPaths(tenantRoot);
380
- const { socketPath } = getTreeseedKeyAgentPaths();
381
- const scriptArgs = keyAgentNodeArgs();
382
- const command = [
383
- shellQuote(process.execPath),
384
- ...scriptArgs.map((arg) => shellQuote(arg)),
385
- "serve",
386
- "--key-path",
387
- shellQuote(keyPath),
388
- "--socket-path",
389
- shellQuote(socketPath),
390
- "--idle-timeout-ms",
391
- shellQuote(String(TREESEED_KEY_AGENT_IDLE_TIMEOUT_MS)),
392
- ">/dev/null",
393
- "2>/dev/null",
394
- "&"
395
- ].join(" ");
396
- const child = spawn("bash", ["-lc", command], {
397
- cwd: keyAgentScriptCwd(),
398
- stdio: "ignore"
399
- });
400
- child.unref();
401
- }
402
- function runTreeseedKeyAgentCommand(args, options = {}) {
403
- const result = spawnSync(process.execPath, [
404
- ...keyAgentNodeArgs(),
405
- ...args
406
- ], {
407
- cwd: keyAgentScriptCwd(),
408
- encoding: "utf8",
409
- env: {
410
- ...process.env,
411
- ...options.env ?? {}
412
- },
413
- stdio: options.input !== void 0 ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"],
414
- input: options.input,
415
- timeout: KEY_AGENT_COMMAND_TIMEOUT_MS,
416
- killSignal: "SIGTERM"
417
- });
418
- if (result.error) {
419
- const timedOut = result.error.code === "ETIMEDOUT";
420
- return {
421
- ok: false,
422
- code: "daemon_unavailable",
423
- message: timedOut ? `Treeseed key-agent command timed out after ${KEY_AGENT_COMMAND_TIMEOUT_MS}ms.` : result.error.message || "Treeseed key-agent command failed."
424
- };
425
- }
426
- if (result.status !== 0 && (!result.stdout || result.stdout.trim().length === 0)) {
427
- return {
428
- ok: false,
429
- code: "daemon_unavailable",
430
- message: result.stderr?.trim() || "Treeseed key-agent command failed."
431
- };
432
- }
433
- try {
434
- return JSON.parse(result.stdout.trim() || "{}");
435
- } catch {
436
- throw new TreeseedKeyAgentError(
437
- "daemon_unavailable",
438
- result.stderr?.trim() || "Treeseed key-agent command returned an invalid response."
439
- );
440
- }
441
- }
442
- function requestTreeseedKeyAgent(tenantRoot, payload, { ensureRunning = false, env } = {}) {
443
- const invoke = () => runTreeseedKeyAgentCommand([
444
- "request",
445
- JSON.stringify(payload)
446
- ], { env });
447
- let response = invoke();
448
- if (response.code !== "daemon_unavailable" || !ensureRunning) {
449
- return response;
450
- }
451
- startTreeseedKeyAgentDaemon(tenantRoot);
452
- for (let attempt = 0; attempt < 20; attempt += 1) {
453
- response = invoke();
454
- if (response.code !== "daemon_unavailable") {
455
- return response;
456
- }
457
- sleepMs(25);
458
- }
459
- return response;
460
- }
461
- function inspectTreeseedKeyAgentStatus(tenantRoot) {
462
- const { keyPath } = getTreeseedMachineConfigPaths(tenantRoot);
463
- const { socketPath } = getTreeseedKeyAgentPaths();
464
- const wrapped = readWrappedMachineKeyFile(keyPath);
465
- if (useInlineKeyAgentTransport()) {
466
- const session = inlineTreeseedSecretSessions.get(keyPath) ?? { machineKey: null, lastTouchedAt: 0, idleTimeoutMs: TREESEED_KEY_AGENT_IDLE_TIMEOUT_MS };
467
- const idleRemainingMs = session.machineKey ? Math.max(0, session.idleTimeoutMs - (Date.now() - session.lastTouchedAt)) : 0;
468
- if (idleRemainingMs === 0) {
469
- session.machineKey = null;
470
- }
471
- inlineTreeseedSecretSessions.set(keyPath, session);
472
- return {
473
- running: true,
474
- unlocked: Boolean(session.machineKey) && idleRemainingMs > 0,
475
- wrappedKeyPresent: wrapped.exists && Boolean(wrapped.wrapped),
476
- migrationRequired: wrapped.migrationRequired,
477
- keyPath,
478
- socketPath,
479
- idleTimeoutMs: session.idleTimeoutMs,
480
- idleRemainingMs
481
- };
482
- }
483
- const response = requestTreeseedKeyAgent(tenantRoot, {
484
- command: "status",
485
- keyPath,
486
- socketPath,
487
- idleTimeoutMs: TREESEED_KEY_AGENT_IDLE_TIMEOUT_MS
488
- });
489
- if (response.ok && response.status) {
490
- return response.status;
491
- }
492
- return {
493
- running: false,
494
- unlocked: false,
495
- wrappedKeyPresent: wrapped.exists && Boolean(wrapped.wrapped),
496
- migrationRequired: wrapped.migrationRequired,
497
- keyPath,
498
- socketPath,
499
- idleTimeoutMs: TREESEED_KEY_AGENT_IDLE_TIMEOUT_MS,
500
- idleRemainingMs: 0
501
- };
502
- }
503
- function unlockTreeseedSecretSessionInteractive(tenantRoot) {
504
- if (useInlineKeyAgentTransport()) {
505
- throw new TreeseedKeyAgentError("interactive_required", "Inline test transport does not support interactive unlock.");
506
- }
507
- const { keyPath } = getTreeseedMachineConfigPaths(tenantRoot);
508
- const { socketPath } = getTreeseedKeyAgentPaths();
509
- startTreeseedKeyAgentDaemon(tenantRoot);
510
- let response = { ok: false, code: "daemon_unavailable", message: "Treeseed key agent is unavailable." };
511
- for (let attempt = 0; attempt < 20; attempt += 1) {
512
- response = runTreeseedKeyAgentCommand([
513
- "unlock-interactive",
514
- "--key-path",
515
- keyPath,
516
- "--socket-path",
517
- socketPath,
518
- "--idle-timeout-ms",
519
- String(TREESEED_KEY_AGENT_IDLE_TIMEOUT_MS),
520
- "--allow-migration",
521
- "--create-if-missing"
522
- ]);
523
- if (response.code !== "daemon_unavailable") {
524
- break;
525
- }
526
- sleepMs(25);
527
- }
528
- assertTreeseedKeyAgentResponse(response, "Unable to unlock the Treeseed secret session.");
529
- return response.status;
530
- }
531
- function unlockTreeseedSecretSessionFromEnv(tenantRoot, options = {}) {
532
- const { keyPath } = getTreeseedMachineConfigPaths(tenantRoot);
533
- const { socketPath } = getTreeseedKeyAgentPaths();
534
- if (useInlineKeyAgentTransport()) {
535
- const passphrase = String(process.env[TREESEED_MACHINE_KEY_PASSPHRASE_ENV] ?? "").trim();
536
- if (!passphrase) {
537
- throw new TreeseedKeyAgentError(
538
- "interactive_required",
539
- `Set ${TREESEED_MACHINE_KEY_PASSPHRASE_ENV} before unlocking the Treeseed secret session.`
540
- );
541
- }
542
- const wrapped = readWrappedMachineKeyFile(keyPath);
543
- const machineKey = wrapped.wrapped ? (() => {
544
- try {
545
- return unwrapMachineKey(wrapped.wrapped, passphrase);
546
- } catch (error) {
547
- if (process.env.VITEST === "true" && options.createIfMissing !== false) {
548
- const createdKey = randomBytes(32);
549
- replaceWrappedMachineKey(keyPath, createdKey, passphrase);
550
- return createdKey;
551
- }
552
- throw error;
553
- }
554
- })() : wrapped.plaintextLegacy ? (() => {
555
- if (options.allowMigration === false) {
556
- throw new TreeseedKeyAgentError("wrapped_key_migration_required", "Wrap the legacy machine key before unlocking it.");
557
- }
558
- replaceWrappedMachineKey(keyPath, wrapped.plaintextLegacy, passphrase);
559
- return wrapped.plaintextLegacy;
560
- })() : (() => {
561
- if (options.createIfMissing === false) {
562
- throw new TreeseedKeyAgentError("wrapped_key_missing", "No wrapped Treeseed machine key exists yet.");
563
- }
564
- const createdKey = randomBytes(32);
565
- replaceWrappedMachineKey(keyPath, createdKey, passphrase);
566
- return createdKey;
567
- })();
568
- inlineTreeseedSecretSessions.set(keyPath, {
569
- machineKey,
570
- lastTouchedAt: Date.now(),
571
- idleTimeoutMs: TREESEED_KEY_AGENT_IDLE_TIMEOUT_MS
572
- });
573
- return inspectTreeseedKeyAgentStatus(tenantRoot);
574
- }
575
- startTreeseedKeyAgentDaemon(tenantRoot);
576
- let response = { ok: false, code: "daemon_unavailable", message: "Treeseed key agent is unavailable." };
577
- for (let attempt = 0; attempt < 20; attempt += 1) {
578
- try {
579
- const parsed = runTreeseedKeyAgentCommand([
580
- "unlock-from-env",
581
- "--key-path",
582
- keyPath,
583
- "--socket-path",
584
- socketPath,
585
- "--idle-timeout-ms",
586
- String(TREESEED_KEY_AGENT_IDLE_TIMEOUT_MS),
587
- ...options.allowMigration === false ? [] : ["--allow-migration"],
588
- ...options.createIfMissing === false ? [] : ["--create-if-missing"]
589
- ]);
590
- assertTreeseedKeyAgentResponse(parsed, `Unable to unlock the Treeseed secret session from ${TREESEED_MACHINE_KEY_PASSPHRASE_ENV}.`);
591
- return parsed.status;
592
- } catch (error) {
593
- if (attempt === 19) {
594
- throw error;
595
- }
596
- sleepMs(25);
597
- }
598
- }
599
- assertTreeseedKeyAgentResponse(
600
- response,
601
- `Unable to unlock the Treeseed secret session from ${TREESEED_MACHINE_KEY_PASSPHRASE_ENV}.`
602
- );
603
- return response.status;
604
- }
605
- function unlockTreeseedSecretSessionWithPassphrase(tenantRoot, passphrase, options = {}) {
606
- const normalizedPassphrase = String(passphrase ?? "").trim();
607
- if (!normalizedPassphrase) {
608
- throw new TreeseedKeyAgentError(
609
- "interactive_required",
610
- `Set ${TREESEED_MACHINE_KEY_PASSPHRASE_ENV} before unlocking the Treeseed secret session.`
611
- );
612
- }
613
- const previousPassphrase = process.env[TREESEED_MACHINE_KEY_PASSPHRASE_ENV];
614
- process.env[TREESEED_MACHINE_KEY_PASSPHRASE_ENV] = normalizedPassphrase;
615
- try {
616
- if (useInlineKeyAgentTransport()) {
617
- return unlockTreeseedSecretSessionFromEnv(tenantRoot, options);
618
- }
619
- const { keyPath } = getTreeseedMachineConfigPaths(tenantRoot);
620
- const { socketPath } = getTreeseedKeyAgentPaths();
621
- startTreeseedKeyAgentDaemon(tenantRoot);
622
- let response = { ok: false, code: "daemon_unavailable", message: "Treeseed key agent is unavailable." };
623
- for (let attempt = 0; attempt < 20; attempt += 1) {
624
- response = runTreeseedKeyAgentCommand([
625
- "unlock-from-env",
626
- "--key-path",
627
- keyPath,
628
- "--socket-path",
629
- socketPath,
630
- "--idle-timeout-ms",
631
- String(TREESEED_KEY_AGENT_IDLE_TIMEOUT_MS),
632
- ...options.allowMigration === false ? [] : ["--allow-migration"],
633
- ...options.createIfMissing === false ? [] : ["--create-if-missing"]
634
- ], {
635
- env: {
636
- [TREESEED_MACHINE_KEY_PASSPHRASE_ENV]: normalizedPassphrase
637
- }
638
- });
639
- if (response.code !== "daemon_unavailable") {
640
- break;
641
- }
642
- sleepMs(25);
643
- }
644
- assertTreeseedKeyAgentResponse(
645
- response,
646
- `Unable to unlock the Treeseed secret session from ${TREESEED_MACHINE_KEY_PASSPHRASE_ENV}.`
647
- );
648
- return response.status;
649
- } finally {
650
- if (previousPassphrase === void 0) {
651
- delete process.env[TREESEED_MACHINE_KEY_PASSPHRASE_ENV];
652
- } else {
653
- process.env[TREESEED_MACHINE_KEY_PASSPHRASE_ENV] = previousPassphrase;
654
- }
655
- }
656
- }
657
- async function ensureTreeseedSecretSessionForConfig({
658
- tenantRoot,
659
- interactive = false,
660
- env = process.env,
661
- createIfMissing = true,
662
- allowMigration = true,
663
- promptForPassphrase,
664
- promptForNewPassphrase
665
- }) {
666
- const status = inspectTreeseedKeyAgentStatus(tenantRoot);
667
- if (status.unlocked) {
668
- return {
669
- status,
670
- createdWrappedKey: false,
671
- migratedWrappedKey: false,
672
- unlockSource: "existing-session"
673
- };
674
- }
675
- const wrappedBefore = readWrappedMachineKeyFile(status.keyPath);
676
- const envPassphrase = String(env[TREESEED_MACHINE_KEY_PASSPHRASE_ENV] ?? "").trim();
677
- let unlockSource = "existing-session";
678
- let nextStatus;
679
- if (envPassphrase) {
680
- nextStatus = unlockTreeseedSecretSessionWithPassphrase(tenantRoot, envPassphrase, {
681
- createIfMissing,
682
- allowMigration
683
- });
684
- unlockSource = "env";
685
- } else if (interactive && status.migrationRequired) {
686
- if (!promptForNewPassphrase) {
687
- throw new TreeseedKeyAgentError("interactive_required", "A passphrase prompt is required to migrate the Treeseed machine key.");
688
- }
689
- nextStatus = unlockTreeseedSecretSessionWithPassphrase(tenantRoot, await promptForNewPassphrase(), {
690
- createIfMissing: false,
691
- allowMigration: true
692
- });
693
- unlockSource = "interactive";
694
- } else if (interactive && !status.wrappedKeyPresent) {
695
- if (!promptForNewPassphrase) {
696
- throw new TreeseedKeyAgentError("interactive_required", "A passphrase prompt is required to create the Treeseed machine key.");
697
- }
698
- nextStatus = unlockTreeseedSecretSessionWithPassphrase(tenantRoot, await promptForNewPassphrase(), {
699
- createIfMissing: true,
700
- allowMigration: false
701
- });
702
- unlockSource = "interactive";
703
- } else if (interactive) {
704
- if (!promptForPassphrase) {
705
- throw new TreeseedKeyAgentError("interactive_required", "A passphrase prompt is required to unlock the Treeseed machine key.");
706
- }
707
- nextStatus = unlockTreeseedSecretSessionWithPassphrase(tenantRoot, await promptForPassphrase(), {
708
- createIfMissing: false,
709
- allowMigration: false
710
- });
711
- unlockSource = "interactive";
712
- } else if (status.migrationRequired) {
713
- throw new TreeseedKeyAgentError(
714
- "wrapped_key_migration_required",
715
- `Set ${TREESEED_MACHINE_KEY_PASSPHRASE_ENV} before running treeseed config non-interactively so Treeseed can wrap the legacy machine key.`,
716
- { keyPath: status.keyPath }
717
- );
718
- } else if (!status.wrappedKeyPresent) {
719
- throw new TreeseedKeyAgentError(
720
- "wrapped_key_missing",
721
- `Set ${TREESEED_MACHINE_KEY_PASSPHRASE_ENV} before running treeseed config non-interactively so Treeseed can create the wrapped machine key.`,
722
- { keyPath: status.keyPath }
723
- );
724
- } else {
725
- throw new TreeseedKeyAgentError(
726
- "locked",
727
- `Set ${TREESEED_MACHINE_KEY_PASSPHRASE_ENV} before running treeseed config non-interactively so Treeseed can unlock the wrapped machine key.`,
728
- { keyPath: status.keyPath }
729
- );
730
- }
731
- const wrappedAfter = readWrappedMachineKeyFile(status.keyPath);
732
- return {
733
- status: nextStatus,
734
- createdWrappedKey: !wrappedBefore.wrapped && Boolean(wrappedAfter.wrapped) && !wrappedBefore.migrationRequired,
735
- migratedWrappedKey: wrappedBefore.migrationRequired && Boolean(wrappedAfter.wrapped),
736
- unlockSource
737
- };
738
- }
739
- function lockTreeseedSecretSession(tenantRoot) {
740
- const { keyPath } = getTreeseedMachineConfigPaths(tenantRoot);
741
- if (useInlineKeyAgentTransport()) {
742
- inlineTreeseedSecretSessions.set(keyPath, {
743
- machineKey: null,
744
- lastTouchedAt: 0,
745
- idleTimeoutMs: TREESEED_KEY_AGENT_IDLE_TIMEOUT_MS
746
- });
747
- return inspectTreeseedKeyAgentStatus(tenantRoot);
748
- }
749
- const status = inspectTreeseedKeyAgentStatus(tenantRoot);
750
- if (!status.running) {
751
- return status;
752
- }
753
- const response = requestTreeseedKeyAgent(tenantRoot, {
754
- command: "lock",
755
- keyPath: status.keyPath,
756
- socketPath: status.socketPath,
757
- idleTimeoutMs: status.idleTimeoutMs
758
- });
759
- assertTreeseedKeyAgentResponse(response, "Unable to lock the Treeseed secret session.");
760
- return response.status;
761
- }
762
- function resolveUnlockedMachineKey(tenantRoot) {
763
- const status = inspectTreeseedKeyAgentStatus(tenantRoot);
764
- if (!status.unlocked) {
765
- const envPassphrase = String(process.env[TREESEED_MACHINE_KEY_PASSPHRASE_ENV] ?? "").trim();
766
- if (envPassphrase) {
767
- unlockTreeseedSecretSessionFromEnv(tenantRoot);
768
- } else if (keyAgentAutoPromptEnabled()) {
769
- unlockTreeseedSecretSessionInteractive(tenantRoot);
770
- } else if (status.migrationRequired) {
771
- throw new TreeseedKeyAgentError(
772
- "wrapped_key_migration_required",
773
- "The Treeseed machine key is still stored in the legacy plaintext format. Run `treeseed secrets:migrate-key` or unlock it from an interactive session first.",
774
- { keyPath: status.keyPath }
775
- );
776
- } else if (!status.wrappedKeyPresent) {
777
- throw new TreeseedKeyAgentError(
778
- "wrapped_key_missing",
779
- `No wrapped Treeseed machine key exists yet. Run \`treeseed config\` or \`treeseed secrets:unlock\` from an interactive shell, or set ${TREESEED_MACHINE_KEY_PASSPHRASE_ENV} for the startup unlock path.`,
780
- { keyPath: status.keyPath }
781
- );
782
- } else {
783
- throw new TreeseedKeyAgentError(
784
- "locked",
785
- `Treeseed secrets are locked. Run \`treeseed secrets:unlock\`, unlock from an interactive session, or set ${TREESEED_MACHINE_KEY_PASSPHRASE_ENV} for the startup unlock path before using secret-backed commands.`,
786
- { keyPath: status.keyPath }
787
- );
788
- }
789
- }
790
- if (useInlineKeyAgentTransport()) {
791
- const session = inlineTreeseedSecretSessions.get(status.keyPath);
792
- if (!session?.machineKey) {
793
- throw new TreeseedKeyAgentError("locked", "Treeseed secrets are locked.");
794
- }
795
- session.lastTouchedAt = Date.now();
796
- return session.machineKey;
797
- }
798
- const response = requestTreeseedKeyAgent(tenantRoot, {
799
- command: "get-machine-key",
800
- keyPath: status.keyPath,
801
- socketPath: status.socketPath,
802
- idleTimeoutMs: status.idleTimeoutMs
803
- });
804
- assertTreeseedKeyAgentResponse(response, "Unable to resolve the Treeseed machine key from the local key agent.");
805
- return Buffer.from(String(response.machineKey ?? ""), "base64");
806
- }
807
- function getTreeseedRemoteAuthPaths(tenantRoot) {
808
- return {
809
- authPath: getTreeseedMachineConfigPaths(tenantRoot).authPath
810
- };
811
- }
812
- function createDefaultTreeseedMachineConfig({ tenantRoot, deployConfig, tenantConfig }) {
813
- return {
814
- version: 1,
815
- project: {
816
- tenantRoot,
817
- tenantId: tenantConfig?.id ?? deployConfig.slug,
818
- slug: deployConfig.slug,
819
- name: deployConfig.name,
820
- siteUrl: deployConfig.siteUrl,
821
- overlayPath: resolve(tenantRoot, TENANT_ENVIRONMENT_OVERLAY_PATH)
822
- },
823
- settings: {
824
- sync: {
825
- github: true,
826
- cloudflare: true
827
- },
828
- templates: {
829
- catalogEndpoint: DEFAULT_TEMPLATE_CATALOG_URL
830
- },
831
- remote: createDefaultRemoteSettings(),
832
- services: createDefaultServiceSettings()
833
- },
834
- shared: {
835
- values: {},
836
- secrets: {}
837
- },
838
- environments: Object.fromEntries(
839
- TREESEED_ENVIRONMENT_SCOPES.map((scope) => [
840
- scope,
841
- {
842
- values: {},
843
- secrets: {}
844
- }
845
- ])
846
- )
847
- };
848
- }
849
- function loadLegacyMachineKey(tenantRoot) {
850
- const { legacyKeyPath } = getTreeseedMachineConfigPaths(tenantRoot);
851
- if (!existsSync(legacyKeyPath)) {
852
- return null;
853
- }
854
- try {
855
- const raw = readFileSync(legacyKeyPath, "utf8").trim();
856
- if (!raw || raw.startsWith("{")) {
857
- return null;
858
- }
859
- const key = Buffer.from(raw, "base64");
860
- return key.length === 32 ? key : null;
861
- } catch {
862
- return null;
863
- }
864
- }
865
- function createDefaultRemoteAuthState() {
866
- return {
867
- version: 1,
868
- sessions: {}
869
- };
870
- }
871
- function encryptValue(value, key) {
872
- const iv = randomBytes(12);
873
- const cipher = createCipheriv("aes-256-gcm", key, iv);
874
- const ciphertext = Buffer.concat([cipher.update(value, "utf8"), cipher.final()]);
875
- const tag = cipher.getAuthTag();
876
- return {
877
- algorithm: "aes-256-gcm",
878
- iv: iv.toString("base64"),
879
- tag: tag.toString("base64"),
880
- ciphertext: ciphertext.toString("base64")
881
- };
882
- }
883
- function decryptValue(payload, key) {
884
- if (!payload || typeof payload !== "object") {
885
- return "";
886
- }
887
- if (!Buffer.isBuffer(key) || key.length !== 32) {
888
- throw new TreeseedKeyAgentError(
889
- "invalid_machine_key",
890
- "The Treeseed machine key is invalid or corrupt."
891
- );
892
- }
893
- const decipher = createDecipheriv(
894
- "aes-256-gcm",
895
- key,
896
- Buffer.from(String(payload.iv ?? ""), "base64")
897
- );
898
- decipher.setAuthTag(Buffer.from(String(payload.tag ?? ""), "base64"));
899
- const decrypted = Buffer.concat([
900
- decipher.update(Buffer.from(String(payload.ciphertext ?? ""), "base64")),
901
- decipher.final()
902
- ]);
903
- return decrypted.toString("utf8");
904
- }
905
- function decryptMachineConfigSecrets(config, key) {
906
- const secrets = {
907
- shared: {}
908
- };
909
- for (const [entryId, payload] of Object.entries(config.shared?.secrets ?? {})) {
910
- secrets.shared[entryId] = decryptValue(payload, key);
911
- }
912
- for (const scope of TREESEED_ENVIRONMENT_SCOPES) {
913
- secrets[scope] = {};
914
- for (const [entryId, payload] of Object.entries(config.environments?.[scope]?.secrets ?? {})) {
915
- secrets[scope][entryId] = decryptValue(payload, key);
916
- }
917
- }
918
- return secrets;
919
- }
920
- function applyMachineConfigSecrets(config, secrets, key) {
921
- for (const [entryId, value] of Object.entries(secrets.shared ?? {})) {
922
- config.shared.secrets[entryId] = encryptValue(value, key);
923
- }
924
- for (const scope of TREESEED_ENVIRONMENT_SCOPES) {
925
- const scoped = config.environments?.[scope];
926
- if (!scoped) {
927
- continue;
928
- }
929
- for (const [entryId, value] of Object.entries(secrets[scope] ?? {})) {
930
- scoped.secrets[entryId] = encryptValue(value, key);
931
- }
932
- }
933
- return config;
934
- }
935
- function decryptRemoteAuthSessions(payload, key) {
936
- return Object.fromEntries(
937
- Object.entries(payload.sessions ?? {}).map(([hostId, entry]) => [
938
- hostId,
939
- {
940
- accessToken: decryptValue(entry.accessToken, key),
941
- refreshToken: decryptValue(entry.refreshToken, key),
942
- expiresAt: typeof entry.expiresAt === "string" ? entry.expiresAt : "",
943
- principal: entry.principal ?? null
944
- }
945
- ])
946
- );
947
- }
948
- function encryptRemoteAuthSessions(sessions, key) {
949
- return Object.fromEntries(
950
- Object.entries(sessions ?? {}).map(([hostId, entry]) => [
951
- hostId,
952
- {
953
- accessToken: entry.accessToken ? encryptValue(entry.accessToken, key) : null,
954
- refreshToken: entry.refreshToken ? encryptValue(entry.refreshToken, key) : null,
955
- expiresAt: entry.expiresAt ?? "",
956
- principal: entry.principal ?? null
957
- }
958
- ])
959
- );
960
- }
961
- function loadRemoteAuthPayload(tenantRoot) {
962
- const { authPath } = getTreeseedRemoteAuthPaths(tenantRoot);
963
- if (!existsSync(authPath)) {
964
- return createDefaultRemoteAuthState();
965
- }
966
- try {
967
- const raw = JSON.parse(readFileSync(authPath, "utf8"));
968
- return raw && typeof raw === "object" ? raw : createDefaultRemoteAuthState();
969
- } catch {
970
- return createDefaultRemoteAuthState();
971
- }
972
- }
973
- function writeRemoteAuthPayload(tenantRoot, payload) {
974
- const { authPath } = getTreeseedRemoteAuthPaths(tenantRoot);
975
- ensureParent(authPath);
976
- writeFileSync(authPath, `${JSON.stringify(payload, null, 2)}
977
- `, "utf8");
978
- }
979
- function removeLegacyMachineKeyIfSafe(tenantRoot) {
980
- const { legacyKeyPath, keyPath } = getTreeseedMachineConfigPaths(tenantRoot);
981
- if (legacyKeyPath !== keyPath && existsSync(legacyKeyPath)) {
982
- rmSync(legacyKeyPath, { force: true });
983
- }
984
- }
985
- function reencryptTreeseedEncryptedState(tenantRoot, oldKey, newKey) {
986
- const machineConfig = loadTreeseedMachineConfig(tenantRoot);
987
- const machineSecrets = decryptMachineConfigSecrets(machineConfig, oldKey);
988
- const { authPath } = getTreeseedRemoteAuthPaths(tenantRoot);
989
- const remoteAuthExists = existsSync(authPath);
990
- const remoteAuthPayload = loadRemoteAuthPayload(tenantRoot);
991
- const remoteSessions = decryptRemoteAuthSessions(remoteAuthPayload, oldKey);
992
- writeTreeseedMachineConfig(tenantRoot, applyMachineConfigSecrets(machineConfig, machineSecrets, newKey));
993
- if (remoteAuthExists || Object.keys(remoteSessions).length > 0) {
994
- writeRemoteAuthPayload(tenantRoot, {
995
- version: 1,
996
- sessions: encryptRemoteAuthSessions(remoteSessions, newKey)
997
- });
998
- }
999
- }
1000
- function loadMachineKey(tenantRoot) {
1001
- return resolveUnlockedMachineKey(tenantRoot);
1002
- }
1003
- function decryptValueWithMachineKey(tenantRoot, payload, key) {
1004
- try {
1005
- return decryptValue(payload, key);
1006
- } catch (error) {
1007
- const legacyKey = loadLegacyMachineKey(tenantRoot);
1008
- if (!legacyKey) {
1009
- throw error;
1010
- }
1011
- const value = decryptValue(payload, legacyKey);
1012
- reencryptTreeseedEncryptedState(tenantRoot, legacyKey, key);
1013
- removeLegacyMachineKeyIfSafe(tenantRoot);
1014
- return value;
1015
- }
1016
- }
1017
- function rotateTreeseedMachineKey(tenantRoot) {
1018
- const { keyPath } = getTreeseedMachineConfigPaths(tenantRoot);
1019
- const oldKey = loadMachineKey(tenantRoot);
1020
- const newKey = randomBytes(32);
1021
- reencryptTreeseedEncryptedState(tenantRoot, oldKey, newKey);
1022
- const status = inspectTreeseedKeyAgentStatus(tenantRoot);
1023
- if (!status.unlocked) {
1024
- throw new TreeseedKeyAgentError("locked", "Treeseed secrets must be unlocked before rotating the machine key.", { keyPath });
1025
- }
1026
- const wrapped = readWrappedMachineKeyFile(keyPath);
1027
- if (!wrapped.wrapped) {
1028
- throw new TreeseedKeyAgentError(
1029
- wrapped.migrationRequired ? "wrapped_key_migration_required" : "wrapped_key_missing",
1030
- wrapped.migrationRequired ? "Wrap the Treeseed machine key before rotating it." : "Create and unlock the Treeseed machine key before rotating it.",
1031
- { keyPath }
1032
- );
1033
- }
1034
- const passphrase = String(process.env[TREESEED_MACHINE_KEY_PASSPHRASE_ENV] ?? "").trim();
1035
- if (!passphrase) {
1036
- throw new TreeseedKeyAgentError(
1037
- "interactive_required",
1038
- `Set ${TREESEED_MACHINE_KEY_PASSPHRASE_ENV} when rotating the machine key non-interactively, or use \`treeseed secrets:rotate-machine-key\` from an interactive shell.`,
1039
- { keyPath }
1040
- );
1041
- }
1042
- replaceWrappedMachineKey(keyPath, newKey, passphrase);
1043
- unlockTreeseedSecretSessionFromEnv(tenantRoot, { allowMigration: false, createIfMissing: false });
1044
- removeLegacyMachineKeyIfSafe(tenantRoot);
1045
- return {
1046
- keyPath,
1047
- rotated: true
1048
- };
1049
- }
1050
- function rotateTreeseedMachineKeyPassphrase(tenantRoot, passphrase) {
1051
- const { keyPath } = getTreeseedMachineConfigPaths(tenantRoot);
1052
- const machineKey = loadMachineKey(tenantRoot);
1053
- rotateWrappedMachineKeyPassphrase(keyPath, machineKey, passphrase);
1054
- return {
1055
- keyPath,
1056
- rotated: true
1057
- };
1058
- }
1059
- function migrateTreeseedMachineKeyToWrapped(tenantRoot, passphrase) {
1060
- const { keyPath } = getTreeseedMachineConfigPaths(tenantRoot);
1061
- const wrapped = readWrappedMachineKeyFile(keyPath);
1062
- if (wrapped.wrapped) {
1063
- return {
1064
- keyPath,
1065
- migrated: false,
1066
- alreadyWrapped: true
1067
- };
1068
- }
1069
- if (wrapped.plaintextLegacy) {
1070
- replaceWrappedMachineKey(keyPath, wrapped.plaintextLegacy, passphrase);
1071
- } else {
1072
- const legacyKey = loadLegacyMachineKey(tenantRoot);
1073
- if (!legacyKey) {
1074
- throw new TreeseedKeyAgentError(
1075
- "wrapped_key_missing",
1076
- "No existing machine key was found to migrate.",
1077
- { keyPath }
1078
- );
1079
- }
1080
- replaceWrappedMachineKey(keyPath, legacyKey, passphrase);
1081
- removeLegacyMachineKeyIfSafe(tenantRoot);
1082
- }
1083
- return {
1084
- keyPath,
1085
- migrated: true,
1086
- alreadyWrapped: false
1087
- };
1088
- }
1089
- function loadTreeseedRemoteAuthState(tenantRoot) {
1090
- const key = loadMachineKey(tenantRoot);
1091
- const payload = loadRemoteAuthPayload(tenantRoot);
1092
- let sessions;
1093
- try {
1094
- sessions = decryptRemoteAuthSessions(payload, key);
1095
- } catch (error) {
1096
- const legacyKey = loadLegacyMachineKey(tenantRoot);
1097
- if (!legacyKey) {
1098
- throw error;
1099
- }
1100
- sessions = decryptRemoteAuthSessions(payload, legacyKey);
1101
- reencryptTreeseedEncryptedState(tenantRoot, legacyKey, key);
1102
- removeLegacyMachineKeyIfSafe(tenantRoot);
1103
- }
1104
- return {
1105
- version: 1,
1106
- sessions
1107
- };
1108
- }
1109
- function writeTreeseedRemoteAuthState(tenantRoot, state) {
1110
- const key = loadMachineKey(tenantRoot);
1111
- writeRemoteAuthPayload(tenantRoot, {
1112
- version: 1,
1113
- sessions: encryptRemoteAuthSessions(state.sessions, key)
1114
- });
1115
- }
1116
- function setTreeseedRemoteSession(tenantRoot, { hostId, accessToken, refreshToken, expiresAt, principal }) {
1117
- const state = loadTreeseedRemoteAuthState(tenantRoot);
1118
- state.sessions[hostId] = {
1119
- accessToken,
1120
- refreshToken,
1121
- expiresAt,
1122
- principal: principal ?? null
1123
- };
1124
- writeTreeseedRemoteAuthState(tenantRoot, state);
1125
- return state.sessions[hostId];
1126
- }
1127
- function clearTreeseedRemoteSession(tenantRoot, hostId) {
1128
- const state = loadTreeseedRemoteAuthState(tenantRoot);
1129
- if (hostId) {
1130
- delete state.sessions[hostId];
1131
- } else {
1132
- state.sessions = {};
1133
- }
1134
- writeTreeseedRemoteAuthState(tenantRoot, state);
1135
- return state;
1136
- }
1137
- function resolveTreeseedRemoteSession(tenantRoot, hostId) {
1138
- const { authPath } = getTreeseedRemoteAuthPaths(tenantRoot);
1139
- if (!existsSync(authPath)) {
1140
- return null;
1141
- }
1142
- const sessionState = loadTreeseedRemoteAuthState(tenantRoot);
1143
- const { configPath } = getTreeseedMachineConfigPaths(tenantRoot);
1144
- const selectedHostId = hostId ?? (existsSync(configPath) ? loadTreeseedMachineConfig(tenantRoot).settings?.remote?.activeHostId : "official") ?? "official";
1145
- return sessionState.sessions?.[selectedHostId] ?? null;
1146
- }
1147
- function loadTreeseedMachineConfig(tenantRoot) {
1148
- const deployConfig = loadTenantDeployConfig(tenantRoot);
1149
- const tenantConfig = loadOptionalTenantManifest(tenantRoot);
1150
- const defaults = createDefaultTreeseedMachineConfig({ tenantRoot, deployConfig, tenantConfig });
1151
- const { configPath } = getTreeseedMachineConfigPaths(tenantRoot);
1152
- if (!existsSync(configPath)) {
1153
- return defaults;
1154
- }
1155
- const raw = parseYaml(readFileSync(configPath, "utf8")) ?? {};
1156
- const parsed = raw && typeof raw === "object" ? raw : {};
1157
- return {
1158
- ...defaults,
1159
- ...parsed,
1160
- project: {
1161
- ...defaults.project,
1162
- ...parsed.project ?? {}
1163
- },
1164
- settings: {
1165
- ...defaults.settings,
1166
- ...parsed.settings ?? {},
1167
- sync: {
1168
- ...defaults.settings.sync,
1169
- ...parsed.settings?.sync ?? {}
1170
- },
1171
- templates: {
1172
- ...defaults.settings.templates ?? {},
1173
- ...parsed.settings?.templates ?? {}
1174
- },
1175
- remote: normalizeRemoteSettings({
1176
- ...defaults.settings.remote ?? {},
1177
- ...parsed.settings?.remote ?? {}
1178
- }),
1179
- services: normalizeServiceSettings({
1180
- ...defaults.settings.services ?? {},
1181
- ...parsed.settings?.services ?? {}
1182
- })
1183
- },
1184
- shared: {
1185
- values: {
1186
- ...defaults.shared?.values ?? {},
1187
- ...parsed.shared?.values ?? {}
1188
- },
1189
- secrets: {
1190
- ...defaults.shared?.secrets ?? {},
1191
- ...parsed.shared?.secrets ?? {}
1192
- }
1193
- },
1194
- environments: Object.fromEntries(
1195
- TREESEED_ENVIRONMENT_SCOPES.map((scope) => [
1196
- scope,
1197
- {
1198
- values: {
1199
- ...defaults.environments?.[scope]?.values ?? {},
1200
- ...parsed.environments?.[scope]?.values ?? {}
1201
- },
1202
- secrets: {
1203
- ...defaults.environments?.[scope]?.secrets ?? {},
1204
- ...parsed.environments?.[scope]?.secrets ?? {}
1205
- }
1206
- }
1207
- ])
1208
- )
1209
- };
1210
- }
1211
- function writeTreeseedMachineConfig(tenantRoot, config) {
1212
- const { configPath } = getTreeseedMachineConfigPaths(tenantRoot);
1213
- ensureParent(configPath);
1214
- writeFileSync(configPath, stringifyYaml(config), "utf8");
1215
- }
1216
- function updateTreeseedDeployConfigFeatureToggles(tenantRoot, toggles) {
1217
- const configPath = resolve(tenantRoot, "treeseed.site.yaml");
1218
- const current = parseYaml(readFileSync(configPath, "utf8")) ?? {};
1219
- const next = { ...current };
1220
- if ("smtp" in toggles) {
1221
- next.smtp = {
1222
- ...current.smtp ?? {},
1223
- enabled: toggles.smtp === true
1224
- };
1225
- }
1226
- if ("turnstile" in toggles) {
1227
- next.turnstile = {
1228
- ...current.turnstile ?? {},
1229
- enabled: toggles.turnstile === true
1230
- };
1231
- }
1232
- writeFileSync(configPath, stringifyYaml(next), "utf8");
1233
- }
1234
- function resolveTreeseedRemoteConfig(startRoot = process.cwd(), env = process.env) {
1235
- const machineConfigPath = findNearestTreeseedMachineConfig(startRoot);
1236
- const tenantRoot = machineConfigPath ? resolve(dirname(dirname(machineConfigPath)), "..") : startRoot;
1237
- const deployConfig = existsSync(resolve(tenantRoot, "treeseed.site.yaml")) ? loadTenantDeployConfig(tenantRoot) : null;
1238
- const machineConfig = machineConfigPath ? loadTreeseedMachineConfig(tenantRoot) : createDefaultTreeseedMachineConfig({
1239
- tenantRoot: startRoot,
1240
- deployConfig: {
1241
- name: "TreeSeed",
1242
- slug: "treeseed",
1243
- siteUrl: DEFAULT_TREESEED_API_BASE_URL,
1244
- contactEmail: "hello@treeseed.ai"
1245
- },
1246
- tenantConfig: void 0
1247
- });
1248
- const settings = normalizeRemoteSettings(machineConfig.settings?.remote);
1249
- const deployBaseUrl = env[TREESEED_API_BASE_URL_ENV] ?? deployConfig?.services?.api?.environments?.prod?.baseUrl ?? deployConfig?.services?.api?.publicBaseUrl ?? null;
1250
- if (deployBaseUrl) {
1251
- const officialHost = settings.hosts.find((entry) => entry.id === "official");
1252
- if (officialHost) {
1253
- officialHost.baseUrl = deployBaseUrl.replace(/\/$/u, "");
1254
- }
1255
- }
1256
- const envBaseUrl = env[TREESEED_API_BASE_URL_ENV];
1257
- const hosts = envBaseUrl && envBaseUrl.trim().length > 0 ? [
1258
- {
1259
- id: "env",
1260
- label: "Environment override",
1261
- baseUrl: envBaseUrl.trim().replace(/\/$/u, "")
1262
- },
1263
- ...settings.hosts.filter((entry) => entry.id !== "env")
1264
- ] : settings.hosts;
1265
- const activeHostId = envBaseUrl && envBaseUrl.trim().length > 0 ? "env" : settings.activeHostId;
1266
- const auth = resolveTreeseedRemoteSession(tenantRoot, activeHostId);
1267
- return {
1268
- hosts,
1269
- activeHostId,
1270
- executionMode: settings.executionMode,
1271
- auth: auth ? {
1272
- accessToken: auth.accessToken,
1273
- refreshToken: auth.refreshToken,
1274
- expiresAt: auth.expiresAt,
1275
- principal: auth.principal ?? null
1276
- } : void 0
1277
- };
1278
- }
1279
- function resolveTreeseedTemplateCatalogEndpoint(startRoot = process.cwd(), env = process.env) {
1280
- const envValue = env[TREESEED_TEMPLATE_CATALOG_URL_ENV];
1281
- if (typeof envValue === "string" && envValue.trim().length > 0) {
1282
- return envValue.trim();
1283
- }
1284
- const machineConfigPath = findNearestTreeseedMachineConfig(startRoot);
1285
- if (!machineConfigPath) {
1286
- return DEFAULT_TEMPLATE_CATALOG_URL;
1287
- }
1288
- const raw = parseYaml(readFileSync(machineConfigPath, "utf8")) ?? {};
1289
- const parsed = raw && typeof raw === "object" ? raw : {};
1290
- const configuredEndpoint = parsed.settings?.templates?.catalogEndpoint;
1291
- return typeof configuredEndpoint === "string" && configuredEndpoint.trim().length > 0 ? configuredEndpoint.trim() : DEFAULT_TEMPLATE_CATALOG_URL;
1292
- }
1293
- function resolveTreeseedTemplateCatalogCachePath(startRoot = process.cwd()) {
1294
- const machineConfigPath = findNearestTreeseedMachineConfig(startRoot);
1295
- if (machineConfigPath) {
1296
- return resolve(dirname(dirname(machineConfigPath)), "cache", "template-catalog.json");
1297
- }
1298
- return resolve(startRoot, ".treeseed", "cache", TEMPLATE_CATALOG_CACHE_RELATIVE_PATH);
1299
- }
1300
- function ensureTreeseedGitignoreEntries(tenantRoot) {
1301
- const gitignorePath = resolve(tenantRoot, ".gitignore");
1302
- const requiredEntries = [".treeseed/"];
1303
- const current = existsSync(gitignorePath) ? readFileSync(gitignorePath, "utf8") : "";
1304
- const lines = current.split(/\r?\n/);
1305
- let changed = false;
1306
- for (const entry of requiredEntries) {
1307
- if (!lines.includes(entry)) {
1308
- lines.push(entry);
1309
- changed = true;
1310
- }
1311
- }
1312
- if (changed || !existsSync(gitignorePath)) {
1313
- writeFileSync(gitignorePath, `${lines.filter(Boolean).join("\n")}
1314
- `, "utf8");
1315
- }
1316
- return gitignorePath;
1317
- }
1318
- function ensureTreeseedRailwayIgnoreEntries(tenantRoot) {
1319
- const railwayIgnorePath = resolve(tenantRoot, ".railwayignore");
1320
- const requiredEntries = [
1321
- ".astro/",
1322
- ".codex/",
1323
- ".dev.vars",
1324
- ".env.local",
1325
- ".git/",
1326
- ".treeseed/",
1327
- ".wrangler/",
1328
- "coverage/",
1329
- "node_modules/",
1330
- "npm-debug.log*",
1331
- "packages/*/.git/",
1332
- "packages/*/node_modules/",
1333
- "public/__treeseed/*.json",
1334
- "public/books/*.json",
1335
- "public/books/*.md",
1336
- "scripts/.ts-run-*.mjs",
1337
- "tmp/",
1338
- "*.log",
1339
- "*.tgz"
1340
- ];
1341
- const removedEntries = /* @__PURE__ */ new Set([
1342
- "dist/",
1343
- "**/dist/",
1344
- "packages/*/dist/"
1345
- ]);
1346
- const current = existsSync(railwayIgnorePath) ? readFileSync(railwayIgnorePath, "utf8") : "";
1347
- let changed = false;
1348
- const lines = current.split(/\r?\n/).filter((line) => {
1349
- const keep = !removedEntries.has(line.trim());
1350
- if (!keep) {
1351
- changed = true;
1352
- }
1353
- return keep;
1354
- });
1355
- for (const entry of requiredEntries) {
1356
- if (!lines.includes(entry)) {
1357
- lines.push(entry);
1358
- changed = true;
1359
- }
1360
- }
1361
- if (changed || !existsSync(railwayIgnorePath)) {
1362
- writeFileSync(railwayIgnorePath, `${lines.filter(Boolean).join("\n")}
1363
- `, "utf8");
1364
- }
1365
- return railwayIgnorePath;
1366
- }
1367
- function dedupeRepairActions(actions) {
1368
- const seen = /* @__PURE__ */ new Set();
1369
- return actions.filter((action) => {
1370
- if (seen.has(action.id)) {
1371
- return false;
1372
- }
1373
- seen.add(action.id);
1374
- return true;
1375
- });
1376
- }
1377
- function applyTreeseedSafeRepairs(tenantRoot) {
1378
- const actions = [];
1379
- ensureTreeseedGitignoreEntries(tenantRoot);
1380
- actions.push({ id: "gitignore", detail: "Ensured Treeseed gitignore entries are present." });
1381
- ensureTreeseedRailwayIgnoreEntries(tenantRoot);
1382
- actions.push({ id: "railwayignore", detail: "Ensured Railway deploy ignore entries are present." });
1383
- const deprecatedFiles = warnDeprecatedTreeseedLocalEnvFiles(tenantRoot);
1384
- if (deprecatedFiles.length > 0) {
1385
- actions.push({ id: "deprecated-local-env", detail: "Detected deprecated .env.local/.dev.vars files that Treeseed now ignores." });
1386
- }
1387
- const deployConfig = loadTenantDeployConfig(tenantRoot);
1388
- const { configPath } = getTreeseedMachineConfigPaths(tenantRoot);
1389
- if (!existsSync(configPath)) {
1390
- const machineConfig2 = createDefaultTreeseedMachineConfig({
1391
- tenantRoot,
1392
- deployConfig,
1393
- tenantConfig: void 0
1394
- });
1395
- writeTreeseedMachineConfig(tenantRoot, machineConfig2);
1396
- actions.push({ id: "machine-config", detail: "Created the default Treeseed machine config." });
1397
- }
1398
- const keyStatus = inspectTreeseedKeyAgentStatus(tenantRoot);
1399
- if (!keyStatus.wrappedKeyPresent && !keyStatus.migrationRequired) {
1400
- actions.push({ id: "machine-key", detail: "Treeseed will create a wrapped machine key the first time the secret session is unlocked." });
1401
- } else if (keyStatus.migrationRequired) {
1402
- actions.push({ id: "machine-key-migration", detail: "Detected a legacy plaintext machine key that must be wrapped on the next unlock." });
1403
- }
1404
- const machineConfig = loadTreeseedMachineConfig(tenantRoot);
1405
- writeTreeseedMachineConfig(tenantRoot, machineConfig);
1406
- for (const scope of TREESEED_ENVIRONMENT_SCOPES) {
1407
- const target = createPersistentDeployTarget(scope);
1408
- const state = loadDeployState(tenantRoot, deployConfig, { target });
1409
- if (state.readiness?.initialized || scope === "local") {
1410
- ensureGeneratedWranglerConfig(tenantRoot, { target });
1411
- actions.push({ id: `wrangler-${scope}`, detail: `Regenerated the ${scope} generated Wrangler config.` });
1412
- }
1413
- }
1414
- return dedupeRepairActions(actions);
1415
- }
1416
- function decryptMachineEnvironmentBucket(tenantRoot, config, key, bucket) {
1417
- const values = {
1418
- ...bucket?.values ?? {}
1419
- };
1420
- for (const [entryId, payload] of Object.entries(bucket?.secrets ?? {})) {
1421
- if (!key) {
1422
- continue;
1423
- }
1424
- values[entryId] = decryptValueWithMachineKey(tenantRoot, payload, key);
1425
- }
1426
- return values;
1427
- }
1428
- function readMachineBucketEntryValue(tenantRoot, key, bucket, entry) {
1429
- if (entry.sensitivity === "secret") {
1430
- const payload = bucket?.secrets?.[entry.id];
1431
- return typeof payload === "string" && payload.length > 0 ? decryptValueWithMachineKey(tenantRoot, payload, key) : "";
1432
- }
1433
- return typeof bucket?.values?.[entry.id] === "string" ? bucket.values[entry.id] : "";
1434
- }
1435
- function writeMachineBucketEntryValue(target, entry, value, key) {
1436
- if (entry.sensitivity === "secret") {
1437
- delete target.values[entry.id];
1438
- if (value) {
1439
- target.secrets[entry.id] = encryptValue(value, key);
1440
- } else {
1441
- delete target.secrets[entry.id];
1442
- }
1443
- return;
1444
- }
1445
- delete target.secrets[entry.id];
1446
- if (value) {
1447
- target.values[entry.id] = value;
1448
- } else {
1449
- delete target.values[entry.id];
1450
- }
1451
- }
1452
- function migrateLegacyScopedSharedEntries(tenantRoot, config, registryEntries, key) {
1453
- const notices = [];
1454
- let changed = false;
1455
- for (const entry of registryEntries) {
1456
- if (entry.storage !== "shared") {
1457
- continue;
1458
- }
1459
- const sharedValue = readMachineBucketEntryValue(tenantRoot, key, config.shared, entry);
1460
- if (sharedValue.length > 0) {
1461
- continue;
1462
- }
1463
- const scopedValues = TREESEED_ENVIRONMENT_SCOPES.map((scope) => ({
1464
- scope,
1465
- value: readMachineBucketEntryValue(tenantRoot, key, config.environments?.[scope], entry)
1466
- })).filter((candidate) => candidate.value.length > 0);
1467
- if (scopedValues.length === 0) {
1468
- continue;
1469
- }
1470
- const promotedFrom = (scopedValues.find((candidate) => candidate.scope === "staging") ?? scopedValues.find((candidate) => candidate.scope === "prod") ?? scopedValues[0]).scope;
1471
- const promotedValue = scopedValues.find((candidate) => candidate.scope === promotedFrom)?.value ?? "";
1472
- const hadConflicts = new Set(scopedValues.map((candidate) => candidate.value)).size > 1;
1473
- writeMachineBucketEntryValue(config.shared, entry, promotedValue, key);
1474
- for (const candidateScope of TREESEED_ENVIRONMENT_SCOPES) {
1475
- delete config.environments[candidateScope].values[entry.id];
1476
- delete config.environments[candidateScope].secrets[entry.id];
1477
- }
1478
- notices.push({
1479
- entryId: entry.id,
1480
- label: entry.label,
1481
- promotedFrom,
1482
- consolidatedScopes: scopedValues.map((candidate) => candidate.scope),
1483
- hadConflicts
1484
- });
1485
- changed = true;
1486
- }
1487
- if (changed) {
1488
- writeTreeseedMachineConfig(tenantRoot, config);
1489
- }
1490
- return notices;
1491
- }
1492
- function resolveEntryValueFromBuckets(entry, entryId, scope, bucketValuesByScope) {
1493
- if (!entry) {
1494
- return bucketValuesByScope[scope]?.[entryId] ?? bucketValuesByScope.shared?.[entryId] ?? "";
1495
- }
1496
- if (entry?.storage === "shared") {
1497
- const sharedValue = bucketValuesByScope.shared?.[entryId];
1498
- if (typeof sharedValue === "string" && sharedValue.length > 0) {
1499
- return sharedValue;
1500
- }
1501
- const searchScopes = [scope, ...TREESEED_ENVIRONMENT_SCOPES.filter((candidate) => candidate !== scope)];
1502
- for (const candidateScope of searchScopes) {
1503
- const candidateValue = bucketValuesByScope[candidateScope]?.[entryId];
1504
- if (typeof candidateValue === "string" && candidateValue.length > 0) {
1505
- return candidateValue;
1506
- }
1507
- }
1508
- return "";
1509
- }
1510
- return bucketValuesByScope[scope]?.[entryId] ?? "";
1511
- }
1512
- const LEGACY_ENV_KEY_ALIASES = {
1513
- TREESEED_RAILWAY_API_TOKEN: ["RAILWAY_API_TOKEN"],
1514
- TREESEED_CLOUDFLARE_API_TOKEN: ["CLOUDFLARE_API_TOKEN"],
1515
- TREESEED_DOCKERHUB_TOKEN: ["DOCKERHUB_TOKEN"],
1516
- TREESEED_DOCKERHUB_USERNAME: ["DOCKERHUB_USERNAME"],
1517
- TREESEED_GITHUB_TOKEN: ["GH_TOKEN", "GITHUB_TOKEN", "TREESEED_HOSTED_HUBS_GITHUB_TOKEN"]
1518
- };
1519
- function resolveLegacyEntryValueFromBuckets(entryId, scope, bucketValuesByScope) {
1520
- const aliases = LEGACY_ENV_KEY_ALIASES[entryId] ?? [];
1521
- for (const alias of aliases) {
1522
- const resolved = resolveEntryValueFromBuckets(null, alias, scope, bucketValuesByScope);
1523
- if (typeof resolved === "string" && resolved.length > 0) {
1524
- return resolved;
1525
- }
1526
- }
1527
- return "";
1528
- }
1529
- function resolveTreeseedMachineEnvironmentValues(tenantRoot, scope, additionalKeys = []) {
1530
- const config = loadTreeseedMachineConfig(tenantRoot);
1531
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
1532
- let key = null;
1533
- try {
1534
- key = loadMachineKey(tenantRoot);
1535
- } catch {
1536
- key = null;
1537
- }
1538
- const bucketValuesByScope = {
1539
- shared: decryptMachineEnvironmentBucket(tenantRoot, config, key, config.shared),
1540
- ...Object.fromEntries(
1541
- TREESEED_ENVIRONMENT_SCOPES.map((candidateScope) => [
1542
- candidateScope,
1543
- decryptMachineEnvironmentBucket(tenantRoot, config, key, config.environments?.[candidateScope])
1544
- ])
1545
- )
1546
- };
1547
- const entryById = new Map(registry.entries.map((entry) => [entry.id, entry]));
1548
- const values = {};
1549
- const knownKeys = /* @__PURE__ */ new Set([
1550
- ...registry.entries.map((entry) => entry.id),
1551
- ...additionalKeys
1552
- ]);
1553
- for (const entryId of knownKeys) {
1554
- const resolved = resolveEntryValueFromBuckets(entryById.get(entryId), entryId, scope, bucketValuesByScope) || resolveLegacyEntryValueFromBuckets(entryId, scope, bucketValuesByScope);
1555
- if (typeof resolved === "string" && resolved.length > 0) {
1556
- values[entryId] = resolved;
1557
- }
1558
- }
1559
- return values;
1560
- }
1561
- function setTreeseedMachineEnvironmentValue(tenantRoot, scope, entry, value) {
1562
- const key = loadMachineKey(tenantRoot);
1563
- const config = loadTreeseedMachineConfig(tenantRoot);
1564
- const target = entry.storage === "shared" ? config.shared : config.environments[scope];
1565
- if (entry.storage === "shared") {
1566
- for (const candidateScope of TREESEED_ENVIRONMENT_SCOPES) {
1567
- delete config.environments[candidateScope].values[entry.id];
1568
- delete config.environments[candidateScope].secrets[entry.id];
1569
- }
1570
- }
1571
- if (entry.sensitivity === "secret") {
1572
- delete target.values[entry.id];
1573
- if (value) {
1574
- target.secrets[entry.id] = encryptValue(value, key);
1575
- } else {
1576
- delete target.secrets[entry.id];
1577
- }
1578
- } else {
1579
- delete target.secrets[entry.id];
1580
- if (value) {
1581
- target.values[entry.id] = value;
1582
- } else {
1583
- delete target.values[entry.id];
1584
- }
1585
- }
1586
- writeTreeseedMachineConfig(tenantRoot, config);
1587
- return config;
1588
- }
1589
- function collectTreeseedEnvironmentContext(tenantRoot) {
1590
- const deployConfig = loadTenantDeployConfig(tenantRoot);
1591
- const tenantConfig = loadOptionalTenantManifest(tenantRoot);
1592
- return resolveTreeseedEnvironmentRegistry({
1593
- deployConfig,
1594
- tenantConfig
1595
- });
1596
- }
1597
- function collectTreeseedConfigSeedValues(tenantRoot, scope, env = process.env, valuesOverlay = {}) {
1598
- warnDeprecatedTreeseedLocalEnvFiles(tenantRoot);
1599
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
1600
- let machineValues = {};
1601
- let localMachineValues = {};
1602
- try {
1603
- machineValues = resolveTreeseedMachineEnvironmentValues(tenantRoot, scope);
1604
- if (scope !== "local") {
1605
- localMachineValues = resolveTreeseedMachineEnvironmentValues(tenantRoot, "local");
1606
- }
1607
- } catch (error) {
1608
- if (!(error instanceof TreeseedKeyAgentError)) {
1609
- throw error;
1610
- }
1611
- }
1612
- const providerCredentialFallbacks = Object.fromEntries(
1613
- PROVIDER_CONTROL_ENV_KEYS.map((key) => [key, localMachineValues[key]]).filter(([, value]) => typeof value === "string" && value.length > 0)
1614
- );
1615
- const values = {
1616
- ...providerCredentialFallbacks,
1617
- ...machineValues,
1618
- ...nonEmptyEnvironmentValues(env),
1619
- ...nonEmptyEnvironmentValues(valuesOverlay)
1620
- };
1621
- const providerControlValues = Object.fromEntries(
1622
- PROVIDER_CONTROL_ENV_KEYS.map((key) => [key, values[key]]).filter(([, value]) => typeof value === "string" && value.length > 0)
1623
- );
1624
- return {
1625
- ...providerControlValues,
1626
- ...filterEnvironmentValuesByRegistry(values, registry, scope)
1627
- };
1628
- }
1629
- function workspaceBootstrapDeployConfig(tenantRoot, deployConfig) {
1630
- const appConfigs = discoverTreeseedApplications(tenantRoot).map((application) => application.config).filter((config) => config && config !== deployConfig);
1631
- if (appConfigs.length === 0) {
1632
- return deployConfig;
1633
- }
1634
- const merged = {
1635
- ...deployConfig,
1636
- runtime: { ...deployConfig.runtime ?? {} },
1637
- surfaces: { ...deployConfig.surfaces ?? {} },
1638
- services: { ...deployConfig.services ?? {} }
1639
- };
1640
- for (const config of appConfigs) {
1641
- if (config.runtime?.mode && merged.runtime?.mode !== "treeseed_managed") {
1642
- merged.runtime = { ...merged.runtime, ...config.runtime };
1643
- }
1644
- merged.surfaces = { ...merged.surfaces, ...config.surfaces ?? {} };
1645
- merged.services = { ...merged.services, ...config.services ?? {} };
1646
- }
1647
- return merged;
1648
- }
1649
- function configuredMarketDatabaseService(tenantRoot, deployConfig) {
1650
- if (deployConfig.services?.treeseedDatabase) {
1651
- return treeseedDatabaseDescriptor(deployConfig.services.treeseedDatabase, deployConfig.slug);
1652
- }
1653
- for (const application of discoverTreeseedApplications(tenantRoot)) {
1654
- const service = application.config.services?.treeseedDatabase;
1655
- if (service) {
1656
- return treeseedDatabaseDescriptor(service, application.config.slug);
1657
- }
1658
- }
1659
- return null;
1660
- }
1661
- function treeseedDatabaseDescriptor(service, slug) {
1662
- return {
1663
- service,
1664
- serviceName: typeof service.railway?.serviceName === "string" && service.railway.serviceName.trim() ? service.railway.serviceName.trim() : `${slug ?? "treeseed-api"}-postgres`
1665
- };
1666
- }
1667
- function nonEmptyEnvironmentValues(env = process.env) {
1668
- return Object.fromEntries(
1669
- Object.entries(env).filter(([, value]) => typeof value === "string" && value.length > 0)
1670
- );
1671
- }
1672
- function collectTreeseedConfigSeedValueSources(tenantRoot, scope, env = process.env) {
1673
- warnDeprecatedTreeseedLocalEnvFiles(tenantRoot);
1674
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
1675
- const registeredKeys = new Set(registry.entries.filter((entry) => isTreeseedEnvironmentEntryRelevant(entry, registry.context, scope, "config")).map((entry) => entry.id));
1676
- const values = {};
1677
- const sources = {};
1678
- const merge = (source, entries) => {
1679
- for (const [key, value] of Object.entries(entries)) {
1680
- if (!registeredKeys.has(key)) {
1681
- continue;
1682
- }
1683
- if (typeof value !== "string" || value.length === 0) {
1684
- continue;
1685
- }
1686
- values[key] = value;
1687
- sources[key] = source;
1688
- }
1689
- };
1690
- try {
1691
- merge("machine-config", resolveTreeseedMachineEnvironmentValues(tenantRoot, scope));
1692
- } catch (error) {
1693
- if (!(error instanceof TreeseedKeyAgentError)) {
1694
- throw error;
1695
- }
1696
- }
1697
- const processValues = Object.fromEntries(Object.entries(env).map(([key, value]) => [key, value ?? void 0]));
1698
- merge("process.env", processValues);
1699
- return { values, sources };
1700
- }
1701
- function resolveTreeseedLaunchEnvironment({
1702
- tenantRoot,
1703
- scope,
1704
- baseEnv = process.env,
1705
- overrides = {}
1706
- }) {
1707
- warnDeprecatedTreeseedLocalEnvFiles(tenantRoot);
1708
- let machineValues = {};
1709
- try {
1710
- machineValues = resolveTreeseedMachineEnvironmentValues(tenantRoot, scope);
1711
- } catch (error) {
1712
- if (!(error instanceof TreeseedKeyAgentError)) {
1713
- throw error;
1714
- }
1715
- }
1716
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
1717
- const baseValues = nonEmptyEnvironmentValues(baseEnv);
1718
- const seedValues = scope === "local" ? { ...baseValues, ...machineValues } : { ...machineValues, ...baseValues };
1719
- const suggestedValues = getTreeseedEnvironmentSuggestedValues({
1720
- scope,
1721
- purpose: "deploy",
1722
- deployConfig: registry.context.deployConfig,
1723
- tenantConfig: registry.context.tenantConfig,
1724
- plugins: registry.context.plugins,
1725
- values: seedValues
1726
- });
1727
- const nonSecretSuggestedValues = Object.fromEntries(
1728
- registry.entries.filter((entry) => entry.sensitivity !== "secret" && typeof suggestedValues[entry.id] === "string" && suggestedValues[entry.id].length > 0).map((entry) => [entry.id, suggestedValues[entry.id]])
1729
- );
1730
- const systemSecretSuggestedValues = Object.fromEntries(
1731
- registry.entries.filter(
1732
- (entry) => entry.sensitivity === "secret" && entry.visibility === "system" && typeof entry.defaultValue === "function" && typeof suggestedValues[entry.id] === "string" && suggestedValues[entry.id].length > 0
1733
- ).map((entry) => [entry.id, suggestedValues[entry.id]])
1734
- );
1735
- const scopedValues = scope === "local" ? { ...nonSecretSuggestedValues, ...systemSecretSuggestedValues, ...baseValues, ...machineValues } : { ...nonSecretSuggestedValues, ...systemSecretSuggestedValues, ...machineValues, ...baseValues };
1736
- return withTreeseedServiceCredentialEnv({
1737
- ...scopedValues,
1738
- ...overrides
1739
- });
1740
- }
1741
- function formatTreeseedConfigEnvironmentReport({ tenantRoot, scope, env = process.env, revealSecrets = false }) {
1742
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
1743
- const { values, sources } = collectTreeseedConfigSeedValueSources(tenantRoot, scope, env);
1744
- const lines = [
1745
- formatConfigSectionTitle(`Resolved environment values for ${scope}`),
1746
- revealSecrets ? "Secrets are shown because --show-secrets was provided." : "Secret values are masked. Re-run with --show-secrets to print full values."
1747
- ];
1748
- for (const entry of listRelevantTreeseedConfigEntries(registry, scope)) {
1749
- const value = values[entry.id];
1750
- const displayValue = typeof value === "string" && value.length > 0 ? entry.sensitivity === "secret" && !revealSecrets ? maskValue(value) : value : "(unset)";
1751
- lines.push(`${entry.id}=${displayValue} (${sources[entry.id] ?? "unset"})`);
1752
- }
1753
- return lines.join("\n");
1754
- }
1755
- function applyTreeseedEnvironmentToProcess({ tenantRoot, scope, override = false }) {
1756
- let resolvedValues = {};
1757
- try {
1758
- resolvedValues = resolveTreeseedLaunchEnvironment({ tenantRoot, scope });
1759
- } catch (error) {
1760
- if (!(error instanceof TreeseedKeyAgentError)) {
1761
- throw error;
1762
- }
1763
- }
1764
- for (const [key, value] of Object.entries(resolvedValues)) {
1765
- const currentValue = process.env[key] ?? "";
1766
- const shouldReplacePlaceholder = key === "CLOUDFLARE_ACCOUNT_ID" && currentValue === CLOUDFLARE_ACCOUNT_ID_PLACEHOLDER;
1767
- if ((override || currentValue.length === 0 || shouldReplacePlaceholder) && typeof value === "string" && value.length > 0) {
1768
- process.env[key] = value;
1769
- }
1770
- }
1771
- return resolvedValues;
1772
- }
1773
- function validateTreeseedCommandEnvironment({ tenantRoot, scope, purpose }) {
1774
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
1775
- const values = resolveTreeseedLaunchEnvironment({ tenantRoot, scope });
1776
- const validation = filterValidationByWorkflowPlane(validateTreeseedEnvironmentValues({
1777
- values,
1778
- scope,
1779
- purpose,
1780
- deployConfig: registry.context.deployConfig,
1781
- tenantConfig: registry.context.tenantConfig,
1782
- plugins: registry.context.plugins
1783
- }));
1784
- return {
1785
- registry,
1786
- values,
1787
- validation
1788
- };
1789
- }
1790
- function filterValidationByWorkflowPlane(validation) {
1791
- const plane = process.env.TREESEED_WORKFLOW_PLANE;
1792
- if (plane !== "web" && plane !== "processing") {
1793
- return validation;
1794
- }
1795
- const problemApplies = (problem) => doesEntryApplyToWorkflowPlane(problem.entry, plane);
1796
- const missing = validation.missing.filter(problemApplies);
1797
- const invalid = validation.invalid.filter(problemApplies);
1798
- const entries = validation.entries.filter((entry) => doesEntryApplyToWorkflowPlane(entry, plane));
1799
- const required = validation.required.filter((entry) => doesEntryApplyToWorkflowPlane(entry, plane));
1800
- return {
1801
- ...validation,
1802
- ok: missing.length === 0 && invalid.length === 0,
1803
- entries,
1804
- required,
1805
- missing,
1806
- invalid
1807
- };
1808
- }
1809
- function doesEntryApplyToWorkflowPlane(entry, plane) {
1810
- const targets = new Set(entry.targets ?? []);
1811
- const hasProcessingTarget = targets.has("railway-secret") || targets.has("railway-var");
1812
- const hasWebTarget = targets.has("cloudflare-secret") || targets.has("cloudflare-var") || targets.has("local-cloudflare");
1813
- const hasWorkflowTarget = targets.has("github-secret") || targets.has("github-variable");
1814
- if (plane === "web") {
1815
- return !hasProcessingTarget || hasWebTarget || hasWorkflowTarget;
1816
- }
1817
- if (plane === "processing") {
1818
- return !hasWebTarget || hasProcessingTarget || hasWorkflowTarget;
1819
- }
1820
- return true;
1821
- }
1822
- function assertTreeseedCommandEnvironment({ tenantRoot, scope, purpose }) {
1823
- const report = validateTreeseedCommandEnvironment({ tenantRoot, scope, purpose });
1824
- if (report.validation.ok) {
1825
- return report;
1826
- }
1827
- const lines = [
1828
- `Treeseed environment is not ready for ${purpose} (${scope}).`,
1829
- "Run `treeseed config` to fill in the missing values, or export them in the current shell."
1830
- ];
1831
- for (const problem of [...report.validation.missing, ...report.validation.invalid]) {
1832
- lines.push(`- ${problem.message}`);
1833
- }
1834
- const error = new Error(lines.join("\n"));
1835
- error.kind = report.validation.missing.length > 0 ? "missing_config" : "invalid_config";
1836
- error.details = report.validation;
1837
- throw error;
1838
- }
1839
- function runGh(args, { cwd, planOnly = false, input, env } = {}) {
1840
- if (planOnly) {
1841
- return { status: 0, stdout: "", stderr: "" };
1842
- }
1843
- const gh = resolveTreeseedToolBinary("gh", { env });
1844
- if (!gh) {
1845
- throw new Error("GitHub CLI `gh` is not installed.");
1846
- }
1847
- const result = spawnSync(gh, args, {
1848
- cwd,
1849
- stdio: input !== void 0 ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"],
1850
- encoding: "utf8",
1851
- input,
1852
- timeout: 15e3,
1853
- env: createTreeseedManagedToolEnv({ ...process.env, ...env ?? {} })
1854
- });
1855
- if (result.error?.code === "ETIMEDOUT") {
1856
- throw new Error(`gh ${args.join(" ")} timed out`);
1857
- }
1858
- if (result.status !== 0) {
1859
- throw new Error(result.stderr?.trim() || result.stdout?.trim() || `gh ${args.join(" ")} failed`);
1860
- }
1861
- return result;
1862
- }
1863
- function commandAvailable(command) {
1864
- if (command === "gh" || command === "wrangler" || command === "railway" || command === "copilot") {
1865
- return Boolean(resolveTreeseedToolBinary(command));
1866
- }
1867
- const result = spawnSync("bash", ["-lc", `command -v ${command}`], {
1868
- stdio: "pipe",
1869
- encoding: "utf8"
1870
- });
1871
- return result.status === 0;
1872
- }
1873
- function checkCommand(command, args, { cwd, env } = {}) {
1874
- const result = spawnSync(command, args, {
1875
- cwd,
1876
- stdio: "pipe",
1877
- encoding: "utf8",
1878
- env: { ...process.env, ...env ?? {} },
1879
- timeout: CLI_CHECK_TIMEOUT_MS
1880
- });
1881
- const timedOut = result.error && "code" in result.error && result.error.code === "ETIMEDOUT";
1882
- const detail = timedOut ? `Command timed out after ${CLI_CHECK_TIMEOUT_MS}ms: ${command} ${args.join(" ")}` : `${result.stderr ?? ""}
1883
- ${result.stdout ?? ""}`.trim();
1884
- return {
1885
- ok: result.status === 0,
1886
- status: result.status ?? 1,
1887
- stdout: result.stdout?.trim() ?? "",
1888
- stderr: result.stderr?.trim() ?? "",
1889
- detail
1890
- };
1891
- }
1892
- function toolStatus(name, available, detail, extra = {}) {
1893
- return {
1894
- name,
1895
- available,
1896
- detail,
1897
- ...extra
1898
- };
1899
- }
1900
- function ensureTreeseedActVerificationTooling({ tenantRoot = process.cwd(), installIfMissing = true, env = process.env, write } = {}) {
1901
- const managedEnv = createTreeseedManagedToolEnv(env);
1902
- const ghBinary = resolveTreeseedToolBinary("gh", { env: managedEnv });
1903
- const githubCli = !ghBinary ? toolStatus("githubCli", false, "GitHub CLI `gh` is not installed.") : (() => {
1904
- const check = checkCommand(ghBinary, ["--version"], { cwd: tenantRoot, env: managedEnv });
1905
- return toolStatus("githubCli", check.ok, check.ok ? check.stdout.split("\n")[0] ?? "GitHub CLI detected." : check.detail || "GitHub CLI check failed.");
1906
- })();
1907
- let ghActExtension = toolStatus("ghActExtension", false, "GitHub CLI extension `gh-act` is not installed.", {
1908
- attemptedInstall: false,
1909
- installedDuringConfig: false
1910
- });
1911
- const wranglerCli = (() => {
1912
- try {
1913
- const wranglerCheck = checkCommand(process.execPath, [resolveWranglerBin(), "--version"], { cwd: tenantRoot, env });
1914
- return toolStatus(
1915
- "wranglerCli",
1916
- wranglerCheck.ok,
1917
- wranglerCheck.ok ? wranglerCheck.stdout.split("\n")[0] ?? "Wrangler CLI detected." : wranglerCheck.detail || "Wrangler CLI is unavailable."
1918
- );
1919
- } catch (error) {
1920
- return toolStatus(
1921
- "wranglerCli",
1922
- false,
1923
- error instanceof Error && error.message ? error.message : "Wrangler CLI is unavailable."
1924
- );
1925
- }
1926
- })();
1927
- const railwayCommand = resolveTreeseedToolCommand("railway", { env });
1928
- const railwayCheck = railwayCommand ? checkCommand(railwayCommand.command, [...railwayCommand.argsPrefix, "--version"], { cwd: tenantRoot, env }) : { ok: false, stdout: "", detail: "Railway CLI is unavailable." };
1929
- const railwayCli = toolStatus(
1930
- "railwayCli",
1931
- railwayCheck.ok,
1932
- railwayCheck.ok ? railwayCheck.stdout.split("\n")[0] ?? "Railway CLI detected." : railwayCheck.detail || "Railway CLI is unavailable."
1933
- );
1934
- if (githubCli.available && ghBinary) {
1935
- const check = checkCommand(ghBinary, ["act", "--version"], { cwd: tenantRoot, env: managedEnv });
1936
- if (check.ok) {
1937
- ghActExtension = toolStatus("ghActExtension", true, check.stdout.split("\n")[0] ?? "gh-act is installed.", {
1938
- attemptedInstall: false,
1939
- installedDuringConfig: false
1940
- });
1941
- } else if (installIfMissing && commandAvailable("docker")) {
1942
- write?.("Installing GitHub CLI extension `gh-act`...");
1943
- const install = checkCommand(ghBinary, ["extension", "install", "https://github.com/nektos/gh-act"], { cwd: tenantRoot, env: managedEnv });
1944
- const postInstall = checkCommand(ghBinary, ["act", "--version"], { cwd: tenantRoot, env: managedEnv });
1945
- ghActExtension = toolStatus(
1946
- "ghActExtension",
1947
- postInstall.ok,
1948
- postInstall.ok ? postInstall.stdout.split("\n")[0] ?? "gh-act is installed." : install.detail || postInstall.detail || "Unable to install the gh-act extension.",
1949
- {
1950
- attemptedInstall: true,
1951
- installedDuringConfig: postInstall.ok,
1952
- installStatus: install.status
1953
- }
1954
- );
1955
- } else if (installIfMissing) {
1956
- ghActExtension = toolStatus("ghActExtension", false, "Docker is not on PATH, so gh-act installation was skipped.", {
1957
- attemptedInstall: false,
1958
- installedDuringConfig: false
1959
- });
1960
- } else {
1961
- ghActExtension = toolStatus("ghActExtension", false, check.detail || "GitHub CLI extension `gh-act` is not installed.", {
1962
- attemptedInstall: false,
1963
- installedDuringConfig: false
1964
- });
1965
- }
1966
- }
1967
- const dockerCheck = checkCommand("docker", ["info"], { cwd: tenantRoot, env });
1968
- const dockerDaemon = toolStatus(
1969
- "dockerDaemon",
1970
- dockerCheck.ok,
1971
- dockerCheck.ok ? dockerCheck.stdout.split("\n")[0] ?? "Docker daemon is available." : dockerCheck.detail || "Docker daemon is unavailable."
1972
- );
1973
- const remediation = [];
1974
- if (!githubCli.available) {
1975
- remediation.push("Install GitHub CLI from https://cli.github.com/ and rerun `treeseed config`.");
1976
- }
1977
- if (githubCli.available && !ghActExtension.available) {
1978
- remediation.push("Run `gh extension install https://github.com/nektos/gh-act` and rerun `treeseed config`.");
1979
- }
1980
- if (!dockerDaemon.available) {
1981
- remediation.push("Start Docker Desktop or another local Docker daemon, then rerun `treeseed config`.");
1982
- }
1983
- if (!wranglerCli.available) {
1984
- remediation.push("Install Wrangler or ensure the packaged Wrangler dependency is runnable, then rerun `treeseed config`.");
1985
- }
1986
- if (!railwayCli.available) {
1987
- remediation.push("Install Railway CLI if you plan to manage Railway services from this machine.");
1988
- }
1989
- return {
1990
- githubCli,
1991
- ghActExtension,
1992
- dockerDaemon,
1993
- wranglerCli,
1994
- railwayCli,
1995
- actVerificationReady: githubCli.available && ghActExtension.available && dockerDaemon.available,
1996
- remediation
1997
- };
1998
- }
1999
- function formatCheckOutput(result) {
2000
- return `${result.stderr ?? ""}
2001
- ${result.stdout ?? ""}`.trim();
2002
- }
2003
- function providerConnectionResult(provider, ready, detail, extra = {}) {
2004
- return {
2005
- provider,
2006
- ready,
2007
- detail,
2008
- ...extra
2009
- };
2010
- }
2011
- function isTransientProviderConnectionError(detail) {
2012
- return /fetch failed|failed to fetch|timed out|etimedout|econnreset|enetunreach|temporarily unavailable|aborted|api check failed|rate.?limit|too many requests|429/iu.test(detail || "");
2013
- }
2014
- function checkGitHubConnection({ tenantRoot, env }) {
2015
- const identityMode = env.TREESEED_GITHUB_IDENTITY_MODE === "account" ? "account" : "repository";
2016
- const repository = identityMode === "repository" ? maybeResolveGitHubRepositorySlug(tenantRoot) : null;
2017
- const credential = repository ? resolveGitHubCredentialForRepository(repository, { values: env, env }) : null;
2018
- const token = credential?.token ?? resolveTreeseedGitHubToken(env);
2019
- if (!token) {
2020
- return providerConnectionResult(
2021
- "github",
2022
- false,
2023
- credential ? `${credential.envName} or TREESEED_GITHUB_TOKEN is not configured.` : "TREESEED_GITHUB_TOKEN is not configured.",
2024
- { skipped: true }
2025
- );
2026
- }
2027
- const gh = resolveTreeseedToolBinary("gh", { env });
2028
- if (!gh) {
2029
- return providerConnectionResult("github", false, "GitHub CLI `gh` is not installed.");
2030
- }
2031
- const owner = typeof env.TREESEED_HOSTED_HUBS_GITHUB_OWNER === "string" ? env.TREESEED_HOSTED_HUBS_GITHUB_OWNER.trim() : "";
2032
- const toolEnv = createTreeseedManagedToolEnv({ ...process.env, ...env, TREESEED_GITHUB_TOKEN: token });
2033
- const commandCandidates = repository ? [{
2034
- args: ["repo", "view", repository, "--json", "nameWithOwner", "--jq", ".nameWithOwner"],
2035
- successMessage: (resolved) => `GitHub token can access ${resolved || repository}.`
2036
- }] : owner ? [
2037
- {
2038
- args: ["api", `orgs/${owner}`, "--jq", ".login"],
2039
- successMessage: (resolved) => `GitHub token can access organization ${resolved || owner}.`,
2040
- optional: true
2041
- },
2042
- {
2043
- args: ["api", `users/${owner}`, "--jq", ".login"],
2044
- successMessage: (resolved) => `GitHub token can access user ${resolved || owner}.`,
2045
- optional: true
2046
- }
2047
- ] : [
2048
- {
2049
- args: ["api", "user", "--jq", ".login"],
2050
- successMessage: (resolved) => resolved ? `Authenticated as ${resolved}.` : "GitHub API check succeeded."
2051
- }
2052
- ];
2053
- let lastDetail = "";
2054
- for (let attempt = 0; attempt < 3; attempt += 1) {
2055
- for (const candidate of commandCandidates) {
2056
- const result = spawnSync(gh, candidate.args, {
2057
- cwd: tenantRoot,
2058
- stdio: "pipe",
2059
- encoding: "utf8",
2060
- env: toolEnv,
2061
- timeout: CLI_CHECK_TIMEOUT_MS
2062
- });
2063
- if (result.status === 0) {
2064
- return providerConnectionResult("github", true, candidate.successMessage(result.stdout.trim()));
2065
- }
2066
- lastDetail = formatCheckOutput(result) || "GitHub API check failed.";
2067
- if (candidate.optional && !isTransientProviderConnectionError(lastDetail)) {
2068
- continue;
2069
- }
2070
- break;
2071
- }
2072
- if (attempt >= 2 || !isTransientProviderConnectionError(lastDetail)) {
2073
- return providerConnectionResult("github", false, lastDetail || "GitHub API check failed.");
2074
- }
2075
- }
2076
- return providerConnectionResult("github", false, lastDetail || "GitHub API check failed.");
2077
- }
2078
- function checkCloudflareConnection({ tenantRoot, env }) {
2079
- if (!env.TREESEED_CLOUDFLARE_API_TOKEN) {
2080
- return providerConnectionResult("cloudflare", false, "TREESEED_CLOUDFLARE_API_TOKEN is not configured.", { skipped: true });
2081
- }
2082
- for (let attempt = 0; attempt < 3; attempt += 1) {
2083
- try {
2084
- const result = spawnSync(process.execPath, [resolveWranglerBin(), "whoami"], {
2085
- cwd: tenantRoot,
2086
- stdio: "pipe",
2087
- encoding: "utf8",
2088
- env: createTreeseedManagedToolEnv({ ...process.env, ...env }),
2089
- timeout: CLI_CHECK_TIMEOUT_MS
2090
- });
2091
- if (result.status === 0) {
2092
- return providerConnectionResult("cloudflare", true, "Wrangler authenticated with TREESEED_CLOUDFLARE_API_TOKEN.");
2093
- }
2094
- const detail = formatCheckOutput(result) || "Cloudflare Wrangler check failed.";
2095
- if (attempt >= 2 || !isTransientProviderConnectionError(detail)) {
2096
- return providerConnectionResult("cloudflare", false, detail);
2097
- }
2098
- } catch (error) {
2099
- const detail = error instanceof Error ? error.message : "Cloudflare Wrangler check failed.";
2100
- if (attempt >= 2 || !isTransientProviderConnectionError(detail)) {
2101
- return providerConnectionResult("cloudflare", false, detail);
2102
- }
2103
- }
2104
- }
2105
- return providerConnectionResult(
2106
- "cloudflare",
2107
- false,
2108
- "Cloudflare connectivity preflight hit transient fetch failures; bootstrap will continue and rely on live reconcile verification.",
2109
- { skipped: true, warning: true, transient: true }
2110
- );
2111
- }
2112
- async function checkRailwayConnection({ tenantRoot, env }) {
2113
- if (!env.TREESEED_RAILWAY_API_TOKEN) {
2114
- return providerConnectionResult("railway", false, "TREESEED_RAILWAY_API_TOKEN is not configured.", { skipped: true });
2115
- }
2116
- const workspaceName = env.TREESEED_RAILWAY_WORKSPACE || resolveRailwayWorkspace(env);
2117
- const cacheKey = JSON.stringify({
2118
- tenantRoot,
2119
- token: env.TREESEED_RAILWAY_API_TOKEN,
2120
- workspaceName
2121
- });
2122
- const cached = railwayConnectionCheckCache.get(cacheKey);
2123
- if (cached) {
2124
- return await cached;
2125
- }
2126
- const checkPromise = (async () => {
2127
- for (let attempt = 0; attempt < 3; attempt += 1) {
2128
- try {
2129
- const workspace = await resolveRailwayWorkspaceContext({ env, workspace: workspaceName });
2130
- return providerConnectionResult("railway", true, `Railway API token can access workspace ${workspace.name}. Project and service existence will be reconciled during bootstrap.`);
2131
- } catch (error) {
2132
- const detail = error instanceof Error ? error.message : "Railway API check failed.";
2133
- if (/rate.?limit|too many requests|429/iu.test(detail || "")) {
2134
- return providerConnectionResult(
2135
- "railway",
2136
- false,
2137
- "Railway connectivity preflight was rate-limited; bootstrap will continue and rely on API-backed reconcile verification.",
2138
- { skipped: true, warning: true, rateLimited: true }
2139
- );
2140
- }
2141
- if (attempt >= 2 && isTransientProviderConnectionError(detail)) {
2142
- return providerConnectionResult(
2143
- "railway",
2144
- false,
2145
- "Railway connectivity preflight hit transient API failures; bootstrap will continue and rely on API-backed reconcile verification.",
2146
- { skipped: true, warning: true, transient: true }
2147
- );
2148
- }
2149
- if (attempt >= 2 || !isTransientProviderConnectionError(detail)) {
2150
- return providerConnectionResult("railway", false, detail);
2151
- }
2152
- }
2153
- }
2154
- return providerConnectionResult("railway", false, "Railway API check failed.");
2155
- })();
2156
- railwayConnectionCheckCache.set(cacheKey, checkPromise);
2157
- try {
2158
- return await checkPromise;
2159
- } catch (error) {
2160
- railwayConnectionCheckCache.delete(cacheKey);
2161
- throw error;
2162
- }
2163
- }
2164
- async function checkTreeseedProviderConnections({ tenantRoot, scope = "prod", env = process.env, valuesOverlay = {} } = {}) {
2165
- const values = collectTreeseedConfigSeedValues(tenantRoot, scope, env, valuesOverlay);
2166
- const passthroughValue = (key) => {
2167
- const overlayValue = valuesOverlay?.[key];
2168
- if (typeof overlayValue === "string" && overlayValue.trim()) {
2169
- return overlayValue.trim();
2170
- }
2171
- const envValue = env?.[key];
2172
- if (typeof envValue === "string" && envValue.trim()) {
2173
- return envValue.trim();
2174
- }
2175
- const resolvedValue = values?.[key];
2176
- return typeof resolvedValue === "string" && resolvedValue.trim() ? resolvedValue.trim() : void 0;
2177
- };
2178
- const githubCredentialValues = Object.fromEntries(
2179
- Object.entries(values).filter(([key, value]) => key.startsWith("TREESEED_GITHUB_TOKEN_") && typeof value === "string" && value.trim())
2180
- );
2181
- const rawCommandEnv = {
2182
- ...githubCredentialValues,
2183
- TREESEED_GITHUB_TOKEN: resolveTreeseedGitHubToken(values),
2184
- TREESEED_GITHUB_IDENTITY_MODE: passthroughValue("TREESEED_GITHUB_IDENTITY_MODE"),
2185
- TREESEED_HOSTED_HUBS_GITHUB_OWNER: passthroughValue("TREESEED_HOSTED_HUBS_GITHUB_OWNER"),
2186
- TREESEED_CLOUDFLARE_API_TOKEN: values.TREESEED_CLOUDFLARE_API_TOKEN,
2187
- TREESEED_CLOUDFLARE_ACCOUNT_ID: values.TREESEED_CLOUDFLARE_ACCOUNT_ID,
2188
- TREESEED_RAILWAY_API_TOKEN: values.TREESEED_RAILWAY_API_TOKEN,
2189
- TREESEED_RAILWAY_WORKSPACE: values.TREESEED_RAILWAY_WORKSPACE || resolveRailwayWorkspace(values)
2190
- };
2191
- const commandEnv = buildRailwayCommandEnv(createTreeseedManagedToolEnv(rawCommandEnv));
2192
- const checks = [
2193
- checkGitHubConnection({ tenantRoot, env: commandEnv }),
2194
- checkCloudflareConnection({ tenantRoot, env: commandEnv })
2195
- ];
2196
- const railwayCheck = await checkRailwayConnection({ tenantRoot, env: commandEnv });
2197
- checks.push(railwayCheck);
2198
- return {
2199
- scope,
2200
- ok: checks.every((check) => check.ready || check.skipped),
2201
- checks,
2202
- issues: checks.filter((check) => !check.ready && !check.skipped).map((check) => check.detail)
2203
- };
2204
- }
2205
- function formatTreeseedProviderConnectionReport(report) {
2206
- const lines = [formatConfigSectionTitle(`Provider connection checks for ${report.scope}`)];
2207
- for (const check of report.checks) {
2208
- const label = check.provider[0].toUpperCase() + check.provider.slice(1);
2209
- const status = check.ready ? colorize("ready", "32") : check.skipped ? colorize("skipped", "33") : colorize("failed", "31");
2210
- lines.push(`${label}: ${status} - ${check.detail}`);
2211
- }
2212
- return lines.join("\n");
2213
- }
2214
- function formatTreeseedProviderConnectionFailures(reports) {
2215
- const failing = reports.filter((report) => report.checks.some((check) => !check.ready && !check.skipped));
2216
- if (failing.length === 0) {
2217
- return "";
2218
- }
2219
- return [
2220
- "Treeseed provider connection checks failed.",
2221
- ...failing.map((report) => formatTreeseedProviderConnectionReport(report))
2222
- ].join("\n");
2223
- }
2224
- function writeProviderConnectionReport(write, report) {
2225
- write(formatTreeseedProviderConnectionReport(report));
2226
- }
2227
- async function runBounded(items, limit, worker) {
2228
- const concurrency = Math.max(1, Math.min(limit, items.length || 1));
2229
- let nextIndex = 0;
2230
- const workers = Array.from({ length: concurrency }, async () => {
2231
- for (; ; ) {
2232
- const index = nextIndex;
2233
- nextIndex += 1;
2234
- if (index >= items.length) {
2235
- return;
2236
- }
2237
- await worker(items[index], index);
2238
- }
2239
- });
2240
- await Promise.all(workers);
2241
- }
2242
- function repositorySlugFromPackageJson(root) {
2243
- try {
2244
- const packageJson = JSON.parse(readFileSync(resolve(root, "package.json"), "utf8"));
2245
- const repository = packageJson.repository;
2246
- const raw = typeof repository === "string" ? repository : repository && typeof repository === "object" && !Array.isArray(repository) ? repository.url : null;
2247
- if (typeof raw !== "string") return null;
2248
- const normalized = raw.trim().replace(/^git\+/u, "").replace(/^ssh:\/\/git@github\.com[:/]/u, "").replace(/^git@github\.com:/u, "").replace(/^https:\/\/github\.com\//u, "").replace(/\.git$/u, "").replace(/\/$/u, "");
2249
- return /^[^/\s]+\/[^/\s]+$/u.test(normalized) ? normalized : null;
2250
- } catch {
2251
- return null;
2252
- }
2253
- }
2254
- function resolveGitHubRepositorySlugForPath(root) {
2255
- try {
2256
- return maybeResolveGitHubRepositorySlug(root);
2257
- } catch {
2258
- return null;
2259
- }
2260
- }
2261
- function discoverGitHubEnvironmentSyncTargets(tenantRoot, explicitRepository) {
2262
- const targets = /* @__PURE__ */ new Map();
2263
- const add = (repository, managedHostMode) => {
2264
- if (!repository || !repository.trim()) return;
2265
- const normalized = repository.trim();
2266
- const existing = targets.get(normalized);
2267
- if (!existing || existing.managedHostMode === "managed" && managedHostMode === "direct") {
2268
- targets.set(normalized, { repository: normalized, managedHostMode });
2269
- }
2270
- };
2271
- add(explicitRepository ?? resolveGitHubRepositorySlugForPath(tenantRoot), "auto");
2272
- for (const application of discoverTreeseedApplications(tenantRoot)) {
2273
- const repository = resolveGitHubRepositorySlugForPath(application.root) ?? repositorySlugFromPackageJson(application.root);
2274
- const managedHostMode = usesManagedHostOperationRequests(application.config) ? "managed" : "direct";
2275
- add(repository, managedHostMode);
2276
- }
2277
- return [...targets.values()];
2278
- }
2279
- function withGitHubEnvironmentCredentialContext(error, repository, credential) {
2280
- const message = error instanceof Error && error.message.trim() ? error.message.trim() : String(error ?? "GitHub environment sync failed.");
2281
- if (credential.fallbackUsed && /authentication failed|resource not accessible|403/iu.test(message)) {
2282
- return new Error(`${message} Configure ${credential.envName} with Actions environment secrets and variables permissions for ${repository}; the fallback TREESEED_GITHUB_TOKEN is not sufficient for this repository.`);
2283
- }
2284
- return error;
2285
- }
2286
- function githubConfigSyncUnitId(value) {
2287
- return String(value || "unknown").replace(/[^A-Za-z0-9:._/-]+/gu, "-");
2288
- }
2289
- function createGitHubConfigSyncUnits({
2290
- scope,
2291
- repository,
2292
- environment,
2293
- items
2294
- }) {
2295
- const identity = {
2296
- teamId: "config",
2297
- projectId: "config",
2298
- slug: "config",
2299
- environment: scope,
2300
- deploymentKey: `config:${scope}`,
2301
- environmentKey: scope
2302
- };
2303
- const repositoryId = githubConfigSyncUnitId(repository);
2304
- const environmentId = githubConfigSyncUnitId(environment);
2305
- const environmentUnitId = `github-environment:config:${scope}:${repositoryId}:${environmentId}`;
2306
- const target = { kind: "persistent", scope };
2307
- const environmentUnit = {
2308
- unitId: environmentUnitId,
2309
- unitType: "github-environment",
2310
- provider: "github",
2311
- identity,
2312
- target,
2313
- logicalName: `${repository} ${environment}`,
2314
- dependencies: [],
2315
- spec: {
2316
- repository,
2317
- environment
2318
- },
2319
- secrets: {},
2320
- metadata: {
2321
- source: { type: "config-sync" },
2322
- resourceKind: "github-environment"
2323
- }
2324
- };
2325
- const bindingUnits = items.flatMap((item) => {
2326
- if (item.kind === "secret") {
2327
- return [{
2328
- unitId: `github-secret-binding:config:${scope}:${repositoryId}:${environmentId}:${githubConfigSyncUnitId(item.name)}`,
2329
- unitType: "github-secret-binding",
2330
- provider: "github",
2331
- identity,
2332
- target,
2333
- logicalName: `${repository} ${environment} ${item.name}`,
2334
- dependencies: [environmentUnitId],
2335
- spec: {
2336
- repository,
2337
- environment,
2338
- secretName: item.name,
2339
- envName: item.name
2340
- },
2341
- secrets: {},
2342
- metadata: {
2343
- source: { type: "config-sync" },
2344
- resourceKind: "github-secret-binding"
2345
- }
2346
- }];
2347
- }
2348
- if (item.kind === "variable") {
2349
- return [{
2350
- unitId: `github-variable-binding:config:${scope}:${repositoryId}:${environmentId}:${githubConfigSyncUnitId(item.name)}`,
2351
- unitType: "github-variable-binding",
2352
- provider: "github",
2353
- identity,
2354
- target,
2355
- logicalName: `${repository} ${environment} ${item.name}`,
2356
- dependencies: [environmentUnitId],
2357
- spec: {
2358
- repository,
2359
- environment,
2360
- variableName: item.name,
2361
- envName: item.name
2362
- },
2363
- secrets: {},
2364
- metadata: {
2365
- source: { type: "config-sync" },
2366
- resourceKind: "github-variable-binding"
2367
- }
2368
- }];
2369
- }
2370
- return [];
2371
- });
2372
- return bindingUnits.length > 0 ? [environmentUnit, ...bindingUnits] : [];
2373
- }
2374
- async function syncTreeseedGitHubEnvironment({
2375
- tenantRoot,
2376
- scope = "prod",
2377
- planOnly = false,
2378
- repository: repositoryInput,
2379
- valuesOverlay = {},
2380
- entryIds,
2381
- managedHostMode = "auto",
2382
- execution = "parallel",
2383
- concurrency = 4,
2384
- onProgress
2385
- }) {
2386
- const repository = repositoryInput ?? maybeResolveGitHubRepositorySlug(tenantRoot);
2387
- if (!repository) {
2388
- throw new Error("Unable to determine the GitHub repository from the origin remote.");
2389
- }
2390
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
2391
- const values = {
2392
- ...resolveTreeseedMachineEnvironmentValues(tenantRoot, scope),
2393
- ...nonEmptyEnvironmentValues(valuesOverlay)
2394
- };
2395
- const deployConfig = loadCliDeployConfig(tenantRoot);
2396
- const managedBoundary = managedHostMode === "managed" || managedHostMode === "auto" && usesManagedHostOperationRequests(deployConfig);
2397
- const allowed = managedBoundary ? filterManagedHostGitHubEnvironment({
2398
- secrets: registry.entries.filter((entry) => entry.scopes.includes(scope) && entry.targets.includes("github-secret")).map((entry) => entry.id),
2399
- variables: registry.entries.filter((entry) => entry.scopes.includes(scope) && entry.targets.includes("github-variable")).map((entry) => entry.id)
2400
- }) : null;
2401
- const allowedSecrets = allowed ? new Set(allowed.secrets) : null;
2402
- const allowedVariables = allowed ? new Set(allowed.variables) : null;
2403
- const entryFilter = Array.isArray(entryIds) && entryIds.length > 0 ? new Set(entryIds) : null;
2404
- const relevant = registry.entries.filter((entry) => {
2405
- if (!entry.scopes.includes(scope)) return false;
2406
- if (entryFilter && !entryFilter.has(entry.id)) return false;
2407
- if (!managedBoundary) return true;
2408
- if (entry.sensitivity === "secret") {
2409
- return Boolean(entry.targets.includes("github-secret") && allowedSecrets?.has(entry.id));
2410
- }
2411
- return Boolean(entry.targets.includes("github-variable") && allowedVariables?.has(entry.id));
2412
- });
2413
- const credential = resolveGitHubCredentialForRepository(repository, { values, env: process.env });
2414
- const environment = scope === "prod" ? "production" : scope;
2415
- const progress = (message, stream = "stdout") => onProgress?.(message, stream);
2416
- progress(`[${scope}][github][sync] Loading existing GitHub secrets and variables...`);
2417
- const [secretNames, variableNames] = [/* @__PURE__ */ new Set(), /* @__PURE__ */ new Set()];
2418
- const synced = {
2419
- secrets: [],
2420
- variables: []
2421
- };
2422
- const items = [];
2423
- for (const entry of relevant) {
2424
- const value = values[entry.id];
2425
- if (!value) {
2426
- continue;
2427
- }
2428
- if (entry.sensitivity === "secret") {
2429
- items.push({ kind: "secret", name: entry.id, value, existed: secretNames.has(entry.id) });
2430
- } else {
2431
- items.push({ kind: "variable", name: entry.id, value, existed: variableNames.has(entry.id) });
2432
- }
2433
- }
2434
- let completed = 0;
2435
- const total = items.length;
2436
- if (!planOnly) {
2437
- const units = createGitHubConfigSyncUnits({ scope, repository, environment, items });
2438
- if (units.length === 0) {
2439
- progress(`[${scope}][github][sync] Complete: 0 secrets, 0 variables, 0 total.`);
2440
- return {
2441
- repository,
2442
- scope,
2443
- environment,
2444
- secrets: synced.secrets,
2445
- variables: synced.variables
2446
- };
2447
- }
2448
- try {
2449
- const result = await reconcileTreeseedTarget({
2450
- tenantRoot,
2451
- target: createPersistentDeployTarget(scope),
2452
- env: {
2453
- ...process.env,
2454
- ...values,
2455
- ...valuesOverlay
2456
- },
2457
- units,
2458
- write: (line) => progress(`[${scope}][github][reconcile] ${line}`)
2459
- });
2460
- const plansById = new Map(result.plans.map((entry) => [entry.unit.unitId, entry]));
2461
- for (const unit of units) {
2462
- if (unit.unitType !== "github-secret-binding" && unit.unitType !== "github-variable-binding") continue;
2463
- const planEntry = plansById.get(unit.unitId);
2464
- const name = String(unit.spec.secretName ?? unit.spec.variableName ?? unit.spec.envName ?? "");
2465
- if (!name) continue;
2466
- const existed = Boolean(planEntry?.observed.exists);
2467
- if (unit.unitType === "github-secret-binding") {
2468
- synced.secrets.push({ name, existed });
2469
- } else {
2470
- synced.variables.push({ name, existed });
2471
- }
2472
- completed += 1;
2473
- progress(`[${scope}][github][${unit.unitType === "github-secret-binding" ? "secret" : "variable"}] reconciled ${name} (${completed}/${total})`);
2474
- }
2475
- } catch (error) {
2476
- throw withGitHubEnvironmentCredentialContext(error, repository, credential);
2477
- }
2478
- progress(`[${scope}][github][sync] Complete: ${synced.secrets.length} secrets, ${synced.variables.length} variables, ${total} total.`);
2479
- return {
2480
- repository,
2481
- scope,
2482
- environment,
2483
- secrets: synced.secrets,
2484
- variables: synced.variables
2485
- };
2486
- }
2487
- progress(`[${scope}][github][sync] Syncing GitHub environment ${environment}: 0/${total} items...`);
2488
- const limit = execution === "sequential" ? 1 : concurrency;
2489
- await runBounded(items, limit, async (item) => {
2490
- completed += 1;
2491
- const action = item.existed ? "would update" : "would create";
2492
- progress(`[${scope}][github][${item.kind}] ${action} ${item.name} (${completed}/${total})`);
2493
- if (item.kind === "secret") {
2494
- synced.secrets.push({ name: item.name, existed: item.existed });
2495
- } else {
2496
- synced.variables.push({ name: item.name, existed: item.existed });
2497
- }
2498
- });
2499
- progress(`[${scope}][github][sync] Complete: ${synced.secrets.length} secrets, ${synced.variables.length} variables, ${total} total.`);
2500
- return {
2501
- repository,
2502
- scope,
2503
- environment,
2504
- credential: {
2505
- repository: credential.repository,
2506
- envName: credential.envName,
2507
- configured: credential.configured,
2508
- source: credential.source,
2509
- fallbackUsed: credential.fallbackUsed
2510
- },
2511
- entryIds: entryFilter ? [...entryFilter] : void 0,
2512
- ...synced
2513
- };
2514
- }
2515
- function syncTreeseedCloudflareEnvironment({
2516
- tenantRoot,
2517
- scope = "prod",
2518
- planOnly = false,
2519
- valuesOverlay = {},
2520
- entryIds,
2521
- onProgress
2522
- }) {
2523
- const values = {
2524
- ...resolveTreeseedMachineEnvironmentValues(tenantRoot, scope),
2525
- ...nonEmptyEnvironmentValues(valuesOverlay)
2526
- };
2527
- const target = createPersistentDeployTarget(scope);
2528
- const progress = (message, stream = "stdout") => onProgress?.(message, stream);
2529
- for (const [key, value] of Object.entries(values)) {
2530
- if (typeof value === "string" && value.length > 0) {
2531
- process.env[key] = value;
2532
- }
2533
- }
2534
- progress(`[${scope}][cloudflare][config] Generating Wrangler config...`);
2535
- const { wranglerPath } = ensureGeneratedWranglerConfig(tenantRoot, { target });
2536
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
2537
- const entryFilter = Array.isArray(entryIds) && entryIds.length > 0 ? new Set(entryIds) : null;
2538
- const cloudflareSecrets = Object.fromEntries(registry.entries.filter((entry) => entry.scopes.includes(scope) && entry.targets.includes("cloudflare-secret") && (!entryFilter || entryFilter.has(entry.id))).map((entry) => [entry.id, values[entry.id]]).filter(([, value]) => typeof value === "string" && value.length > 0));
2539
- progress(`[${scope}][cloudflare][sync] Syncing Cloudflare secrets...`);
2540
- const syncedSecrets = syncCloudflareSecrets(tenantRoot, {
2541
- planOnly,
2542
- target,
2543
- extraSecrets: cloudflareSecrets,
2544
- entryIds
2545
- });
2546
- const cloudflareVars = registry.entries.filter((entry) => entry.scopes.includes(scope) && entry.targets.includes("cloudflare-var") && (!entryFilter || entryFilter.has(entry.id))).map((entry) => entry.id).filter((key) => typeof values[key] === "string" && values[key].length > 0);
2547
- progress(`[${scope}][cloudflare][sync] Complete: ${syncedSecrets.length} secrets, ${cloudflareVars.length} vars.`);
2548
- return {
2549
- scope,
2550
- target,
2551
- wranglerPath,
2552
- entryIds: entryFilter ? [...entryFilter] : void 0,
2553
- secrets: syncedSecrets,
2554
- varsManagedByWranglerConfig: cloudflareVars
2555
- };
2556
- }
2557
- function environmentEntryTargetsService(entry, serviceKey) {
2558
- const targets = Array.isArray(entry.serviceTargets) ? entry.serviceTargets.map((value) => String(value).trim()).filter(Boolean) : [];
2559
- return targets.length === 0 || targets.includes(serviceKey);
2560
- }
2561
- function railwayEnvironmentEntryIdsForService(registry, values, scope, target, serviceKey, entryFilter = null) {
2562
- return registry.entries.filter((entry) => entry.scopes.includes(scope) && entry.targets.includes(target) && (!entryFilter || entryFilter.has(entry.id)) && environmentEntryTargetsService(entry, serviceKey)).map((entry) => entry.id).filter((key) => typeof values[key] === "string" && values[key].length > 0);
2563
- }
2564
- async function syncTreeseedRailwayEnvironment({
2565
- tenantRoot,
2566
- scope = "prod",
2567
- planOnly = false,
2568
- valuesOverlay = {},
2569
- entryIds,
2570
- onProgress
2571
- }) {
2572
- const config = syncManagedServiceSettingsFromDeployConfig(tenantRoot);
2573
- const values = {
2574
- ...resolveTreeseedMachineEnvironmentValues(tenantRoot, scope),
2575
- ...nonEmptyEnvironmentValues(valuesOverlay)
2576
- };
2577
- const deployConfig = loadCliDeployConfig(tenantRoot);
2578
- const treeseedDatabase = configuredMarketDatabaseService(tenantRoot, deployConfig);
2579
- const treeseedDatabaseService = treeseedDatabase?.service;
2580
- const treeseedDatabaseServiceName = treeseedDatabase?.serviceName ?? "";
2581
- const treeseedDatabaseUrl = typeof values.TREESEED_DATABASE_URL === "string" && values.TREESEED_DATABASE_URL.length > 0 ? values.TREESEED_DATABASE_URL : treeseedDatabaseService?.enabled !== false && treeseedDatabaseService?.provider === "railway" ? `\${{${treeseedDatabaseServiceName}.DATABASE_URL}}` : "";
2582
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
2583
- const entryFilter = Array.isArray(entryIds) && entryIds.length > 0 ? new Set(entryIds) : null;
2584
- const progress = (message, stream = "stdout") => onProgress?.(message, stream);
2585
- const serviceValuesByName = /* @__PURE__ */ new Map();
2586
- const services = configuredRailwayServices(tenantRoot, scope).map((service) => {
2587
- const fallbackServiceName = service.key === "api" ? config.settings.services.railway.apiServiceName : service.serviceName;
2588
- const environmentName = normalizeRailwayEnvironmentName(service.railwayEnvironment ?? scope);
2589
- const serviceValues = {
2590
- ...values,
2591
- ...service.key === "operationsRunner" ? {
2592
- TREESEED_PLATFORM_RUNNER_ID: service.runnerId ?? service.serviceName,
2593
- TREESEED_PLATFORM_RUNNER_DATA_DIR: service.volumeMountPath ?? values.TREESEED_PLATFORM_RUNNER_DATA_DIR,
2594
- TREESEED_PLATFORM_RUNNER_ENVIRONMENT: scope === "prod" ? "production" : scope
2595
- } : {},
2596
- ...treeseedDatabaseUrl && ["api", "operationsRunner"].includes(service.key) ? { TREESEED_DATABASE_URL: treeseedDatabaseUrl } : {}
2597
- };
2598
- const serviceName = service.serviceName ?? fallbackServiceName;
2599
- serviceValuesByName.set(serviceName || service.serviceId || service.instanceKey || service.key, serviceValues);
2600
- return {
2601
- service: service.key,
2602
- instanceKey: service.instanceKey ?? service.key,
2603
- projectName: service.projectName ?? config.settings.services.railway.projectName,
2604
- serviceName,
2605
- serviceId: service.serviceId ?? "",
2606
- rootDir: service.rootDir,
2607
- baseUrl: service.publicBaseUrl ?? "(unset)",
2608
- environmentName,
2609
- secrets: railwayEnvironmentEntryIdsForService(registry, serviceValues, scope, "railway-secret", service.key, entryFilter),
2610
- variables: railwayEnvironmentEntryIdsForService(registry, serviceValues, scope, "railway-var", service.key, entryFilter),
2611
- planOnly
2612
- };
2613
- }).filter(Boolean);
2614
- for (const service of services) {
2615
- const serviceValues = serviceValuesByName.get(service.serviceName || service.serviceId || service.instanceKey || service.service) ?? values;
2616
- progress(`[${scope}][railway][${service.service}] Syncing ${service.secrets.length} secrets and ${service.variables.length} variables...`);
2617
- if (!planOnly) {
2618
- const railwayEnv = { ...process.env, ...values };
2619
- const project = (await ensureRailwayProject({
2620
- projectId: "",
2621
- projectName: service.projectName,
2622
- env: railwayEnv
2623
- })).project;
2624
- const environment = (await ensureRailwayEnvironment({
2625
- projectId: project.id,
2626
- environmentName: service.environmentName,
2627
- env: railwayEnv
2628
- })).environment;
2629
- const railwayService = (await ensureRailwayService({
2630
- projectId: project.id,
2631
- serviceId: service.serviceId,
2632
- serviceName: service.serviceName,
2633
- env: railwayEnv
2634
- })).service;
2635
- const variableValues = Object.fromEntries(
2636
- [...service.secrets, ...service.variables].map((key) => [key, serviceValues[key]]).filter(([, value]) => typeof value === "string" && value.length > 0)
2637
- );
2638
- if (Object.keys(variableValues).length > 0) {
2639
- await upsertRailwayVariables({
2640
- projectId: project.id,
2641
- environmentId: environment.id,
2642
- serviceId: railwayService.id,
2643
- variables: variableValues,
2644
- env: railwayEnv
2645
- });
2646
- }
2647
- }
2648
- progress(`[${scope}][railway][${service.service}] Complete.`);
2649
- }
2650
- return {
2651
- scope,
2652
- entryIds: entryFilter ? [...entryFilter] : void 0,
2653
- services
2654
- };
2655
- }
2656
- async function initializeTreeseedPersistentEnvironment({ tenantRoot, scope = "prod", planOnly = false } = {}) {
2657
- const normalizedScope = scope === "prod" ? "prod" : scope;
2658
- const target = createPersistentDeployTarget(normalizedScope);
2659
- const summary = await reconcileTreeseedTarget({
2660
- tenantRoot,
2661
- target,
2662
- env: process.env
2663
- });
2664
- return {
2665
- scope: normalizedScope,
2666
- target,
2667
- summary,
2668
- secrets: summary.results.filter((result) => result.unit.provider === "cloudflare").flatMap((result) => Object.keys(result.resourceLocators ?? {}))
2669
- };
2670
- }
2671
- async function summarizePersistentReadiness(tenantRoot, scope, validation, connectionChecks, env = process.env, { includeReconcileStatus = true, systems } = {}) {
2672
- const validationProblems = [...validation.missing, ...validation.invalid];
2673
- const validationBlockers = validationProblems.map((problem) => problem.message);
2674
- const connectionReady = connectionChecks.every((check) => check.ready || check.skipped);
2675
- const connectionIssues = connectionChecks.filter((check) => !check.ready && !check.skipped).map((check) => `${check.provider}: ${check.detail}`);
2676
- const connectionWarnings = connectionChecks.filter((check) => check.skipped).map((check) => `${check.provider}: ${check.detail}`);
2677
- if (scope === "local") {
2678
- return {
2679
- configured: validation.ok,
2680
- provisioned: true,
2681
- deployable: validation.ok && connectionReady,
2682
- phase: validation.ok ? "code_ready" : "config_incomplete",
2683
- blockers: [
2684
- ...validationBlockers,
2685
- ...connectionIssues
2686
- ],
2687
- warnings: connectionWarnings,
2688
- checks: {
2689
- validation: validation.ok,
2690
- connections: connectionReady
2691
- }
2692
- };
2693
- }
2694
- if (!validation.ok) {
2695
- return {
2696
- configured: false,
2697
- provisioned: false,
2698
- deployable: false,
2699
- phase: "config_incomplete",
2700
- blockers: [
2701
- ...validationBlockers,
2702
- ...connectionIssues
2703
- ],
2704
- warnings: connectionWarnings,
2705
- checks: {
2706
- validation: false,
2707
- connections: connectionReady,
2708
- cloudflare: null,
2709
- railway: false
2710
- }
2711
- };
2712
- }
2713
- const configured = validation.ok;
2714
- if (!includeReconcileStatus) {
2715
- return {
2716
- configured,
2717
- provisioned: false,
2718
- deployable: false,
2719
- phase: "config_complete",
2720
- blockers: [...connectionIssues],
2721
- warnings: connectionWarnings,
2722
- checks: {
2723
- validation: validation.ok,
2724
- connections: connectionReady,
2725
- reconcile: "deferred"
2726
- }
2727
- };
2728
- }
2729
- const reconcile = await collectTreeseedReconcileStatus({
2730
- tenantRoot,
2731
- target: createPersistentDeployTarget(scope),
2732
- env,
2733
- systems
2734
- });
2735
- const provisioned = reconcile.ready;
2736
- const deployable = configured && provisioned && connectionReady;
2737
- const blockers = [...connectionIssues, ...reconcile.blockers];
2738
- return {
2739
- configured,
2740
- provisioned,
2741
- deployable,
2742
- phase: provisioned ? "provisioned" : "config_complete",
2743
- blockers,
2744
- warnings: [...connectionWarnings, ...reconcile.warnings],
2745
- checks: {
2746
- validation: validation.ok,
2747
- connections: connectionReady,
2748
- reconcile: reconcile.units
2749
- }
2750
- };
2751
- }
2752
- function summarizeReconciledPersistentReadiness(scope, validation, connectionChecks, reconciled) {
2753
- const validationProblems = [...validation.missing, ...validation.invalid];
2754
- const validationBlockers = validationProblems.map((problem) => problem.message);
2755
- const connectionReady = connectionChecks.every((check) => check.ready || check.skipped);
2756
- const connectionIssues = connectionChecks.filter((check) => !check.ready && !check.skipped).map((check) => `${check.provider}: ${check.detail}`);
2757
- const connectionWarnings = connectionChecks.filter((check) => check.skipped).map((check) => `${check.provider}: ${check.detail}`);
2758
- if (scope === "local") {
2759
- return {
2760
- configured: validation.ok,
2761
- provisioned: true,
2762
- deployable: validation.ok && connectionReady,
2763
- phase: validation.ok ? "code_ready" : "config_incomplete",
2764
- blockers: [
2765
- ...validationBlockers,
2766
- ...connectionIssues
2767
- ],
2768
- warnings: connectionWarnings,
2769
- checks: {
2770
- validation: validation.ok,
2771
- connections: connectionReady
2772
- }
2773
- };
2774
- }
2775
- if (!validation.ok) {
2776
- return {
2777
- configured: false,
2778
- provisioned: false,
2779
- deployable: false,
2780
- phase: "config_incomplete",
2781
- blockers: [
2782
- ...validationBlockers,
2783
- ...connectionIssues
2784
- ],
2785
- warnings: connectionWarnings,
2786
- checks: {
2787
- validation: false,
2788
- connections: connectionReady,
2789
- reconcile: []
2790
- }
2791
- };
2792
- }
2793
- const actions = reconciled?.actions ?? [];
2794
- const blockers = actions.filter((action) => action.verified !== true).flatMap((action) => [
2795
- ...action.missing.map((entry) => `${action.provider}:${action.unitType}: ${entry}`),
2796
- ...action.drifted.map((entry) => `${action.provider}:${action.unitType}: ${entry}`)
2797
- ]);
2798
- const provisioned = blockers.length === 0 && actions.length > 0;
2799
- return {
2800
- configured: true,
2801
- provisioned,
2802
- deployable: provisioned && connectionReady,
2803
- phase: provisioned ? "provisioned" : "config_complete",
2804
- blockers: [
2805
- ...connectionIssues,
2806
- ...blockers
2807
- ],
2808
- warnings: connectionWarnings,
2809
- checks: {
2810
- validation: true,
2811
- connections: connectionReady,
2812
- reconcile: actions
2813
- }
2814
- };
2815
- }
2816
- function formatTreeseedConfigValidationFailure(validations, scopes) {
2817
- const lines = ["Treeseed config validation failed."];
2818
- for (const scope of scopes) {
2819
- const validation = validations[scope];
2820
- if (!validation || validation.ok) {
2821
- continue;
2822
- }
2823
- lines.push("");
2824
- lines.push(`${scope}:`);
2825
- for (const problem of [...validation.missing, ...validation.invalid]) {
2826
- const targets = problem.entry.targets.length > 0 ? ` Targets: ${problem.entry.targets.join(", ")}.` : "";
2827
- const source = problem.entry.sourceRequirement ? ` Source: ${problem.entry.sourceRequirement}${problem.entry.sourceProvider ? ` (${problem.entry.sourceProvider})` : ""}.` : "";
2828
- lines.push(`- ${problem.id}: ${problem.message}${targets}${source}`);
2829
- }
2830
- }
2831
- return lines.join("\n");
2832
- }
2833
- function colorize(value, code) {
2834
- return `\x1B[${code}m${value}\x1B[0m`;
2835
- }
2836
- function formatConfigSectionTitle(label) {
2837
- return colorize(`
2838
- == ${label}`, "1;36");
2839
- }
2840
- function hasConfigValue(values, key) {
2841
- return typeof values[key] === "string" && values[key].trim().length > 0;
2842
- }
2843
- function createConfigReadiness(values, validation) {
2844
- const invalidIds = /* @__PURE__ */ new Set([
2845
- ...(validation?.invalid ?? []).map((problem) => problem.id)
2846
- ]);
2847
- const validConfigValue = (key) => hasConfigValue(values, key) && !invalidIds.has(key);
2848
- const configProblems = [
2849
- ...validation?.missing ?? [],
2850
- ...validation?.invalid ?? []
2851
- ];
2852
- const providerIssues = (provider) => configProblems.filter((problem) => {
2853
- if (provider === "github") {
2854
- return problem.id === "TREESEED_GITHUB_TOKEN" || problem.entry.group === "github";
2855
- }
2856
- if (provider === "cloudflare") {
2857
- return problem.id.startsWith("TREESEED_CLOUDFLARE_") || problem.id.startsWith("CLOUDFLARE_") || problem.id.includes("TURNSTILE") || problem.entry.group === "cloudflare";
2858
- }
2859
- return problem.id.startsWith("TREESEED_RAILWAY_") || problem.entry.group === "railway";
2860
- });
2861
- const localDevelopmentIssues = [
2862
- ...configProblems
2863
- ].filter((problem) => problem.entry.group === "local-development");
2864
- return {
2865
- github: {
2866
- configured: Boolean(resolveTreeseedGitHubToken(values)) && providerIssues("github").length === 0
2867
- },
2868
- cloudflare: {
2869
- configured: providerIssues("cloudflare").length === 0
2870
- },
2871
- railway: {
2872
- configured: validConfigValue("TREESEED_RAILWAY_API_TOKEN") && providerIssues("railway").length === 0
2873
- },
2874
- localDevelopment: {
2875
- configured: localDevelopmentIssues.length === 0
2876
- }
2877
- };
2878
- }
2879
- const CONFIG_GROUP_ORDER = ["auth", "github", "cloudflare", "railway", "local-development", "forms", "smtp"];
2880
- function configGroupRank(group) {
2881
- const index = CONFIG_GROUP_ORDER.indexOf(group);
2882
- return index === -1 ? CONFIG_GROUP_ORDER.length : index;
2883
- }
2884
- function listRelevantTreeseedConfigEntries(registry, scope) {
2885
- return registry.entries.filter(
2886
- (entry) => entry.visibility !== "system" && entry.scopes.includes(scope) && (!entry.isRelevant || entry.isRelevant(registry.context, scope, "config") || Boolean(entry.onboardingFeature))
2887
- ).sort((left, right) => {
2888
- const leftRequired = isTreeseedEnvironmentEntryRequired(left, registry.context, scope, "config");
2889
- const rightRequired = isTreeseedEnvironmentEntryRequired(right, registry.context, scope, "config");
2890
- if (leftRequired !== rightRequired) {
2891
- return leftRequired ? -1 : 1;
2892
- }
2893
- if (left.purposes.length !== right.purposes.length) {
2894
- return right.purposes.length - left.purposes.length;
2895
- }
2896
- if (configGroupRank(left.group) !== configGroupRank(right.group)) {
2897
- return configGroupRank(left.group) - configGroupRank(right.group);
2898
- }
2899
- return left.label.localeCompare(right.label);
2900
- });
2901
- }
2902
- function buildConfigEntrySnapshot(scope, entry, currentValue, suggestedValue) {
2903
- const currentValueValid = (() => {
2904
- if (!currentValue || !entry.validation) {
2905
- return currentValue.length > 0;
2906
- }
2907
- switch (entry.validation.kind) {
2908
- case "string":
2909
- case "nonempty":
2910
- return currentValue.trim().length > 0 && (typeof entry.validation.minLength !== "number" || currentValue.trim().length >= entry.validation.minLength);
2911
- case "boolean":
2912
- return /^(true|false|1|0)$/i.test(currentValue);
2913
- case "number":
2914
- return Number.isFinite(Number(currentValue));
2915
- case "url":
2916
- try {
2917
- new URL(currentValue);
2918
- return true;
2919
- } catch {
2920
- return false;
2921
- }
2922
- case "email":
2923
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(currentValue);
2924
- case "enum":
2925
- return entry.validation.values.includes(currentValue);
2926
- default:
2927
- return true;
2928
- }
2929
- })();
2930
- const allowGeneratedSecretDefault = ["TREESEED_PLATFORM_RUNNER_SECRET", "TREESEED_WEB_SERVICE_SECRET", "TREESEED_API_WEB_SERVICE_SECRET", "TREESEED_CREDENTIAL_SESSION_SECRET"].includes(entry.id);
2931
- const allowSuggestedDefault = allowGeneratedSecretDefault || !(entry.sensitivity === "secret" && entry.requirement !== "optional");
2932
- const effectiveValue = currentValueValid ? currentValue || (allowSuggestedDefault ? suggestedValue : "") || "" : (allowSuggestedDefault ? suggestedValue : "") || currentValue || "";
2933
- return {
2934
- id: entry.id,
2935
- label: entry.label,
2936
- group: entry.group,
2937
- cluster: entry.cluster ?? `${entry.group}:${entry.id}`,
2938
- startupProfile: entry.startupProfile ?? "advanced",
2939
- requirement: entry.requirement,
2940
- description: entry.description,
2941
- howToGet: entry.howToGet,
2942
- sensitivity: entry.sensitivity,
2943
- targets: [...entry.targets],
2944
- purposes: [...entry.purposes],
2945
- storage: entry.storage ?? "scoped",
2946
- validation: entry.validation,
2947
- sourceRequirement: entry.sourceRequirement,
2948
- sourceHostType: entry.sourceHostType ?? null,
2949
- sourceProvider: entry.sourceProvider ?? null,
2950
- scope,
2951
- sharedScopes: entry.storage === "shared" ? [...entry.scopes] : [scope],
2952
- required: false,
2953
- currentValue,
2954
- suggestedValue,
2955
- effectiveValue
2956
- };
2957
- }
2958
- function collectTreeseedConfigContext({
2959
- tenantRoot,
2960
- scopes = [...TREESEED_ENVIRONMENT_SCOPES],
2961
- env = process.env
2962
- }) {
2963
- ensureTreeseedGitignoreEntries(tenantRoot);
2964
- ensureTreeseedRailwayIgnoreEntries(tenantRoot);
2965
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
2966
- const { configPath, keyPath } = getTreeseedMachineConfigPaths(tenantRoot);
2967
- const valuesByScope = Object.fromEntries(
2968
- scopes.map((scope) => [scope, collectTreeseedConfigSeedValues(tenantRoot, scope, env)])
2969
- );
2970
- const suggestedValuesByScope = Object.fromEntries(
2971
- scopes.map((scope) => [scope, getTreeseedEnvironmentSuggestedValues({
2972
- scope,
2973
- purpose: "config",
2974
- deployConfig: registry.context.deployConfig,
2975
- tenantConfig: registry.context.tenantConfig,
2976
- plugins: registry.context.plugins,
2977
- values: valuesByScope[scope]
2978
- })])
2979
- );
2980
- const validationByScope = Object.fromEntries(
2981
- scopes.map((scope) => [scope, validateTreeseedEnvironmentValues({
2982
- values: {
2983
- ...suggestedValuesByScope[scope],
2984
- ...valuesByScope[scope]
2985
- },
2986
- scope,
2987
- purpose: "config",
2988
- deployConfig: registry.context.deployConfig,
2989
- tenantConfig: registry.context.tenantConfig,
2990
- plugins: registry.context.plugins
2991
- })])
2992
- );
2993
- const configReadinessByScope = Object.fromEntries(
2994
- scopes.map((scope) => [scope, createConfigReadiness(valuesByScope[scope], validationByScope[scope])])
2995
- );
2996
- const entriesByScope = Object.fromEntries(
2997
- scopes.map((scope) => [scope, listRelevantTreeseedConfigEntries(registry, scope).map((entry) => ({
2998
- ...buildConfigEntrySnapshot(
2999
- scope,
3000
- entry,
3001
- valuesByScope[scope][entry.id] ?? "",
3002
- suggestedValuesByScope[scope][entry.id] ?? ""
3003
- ),
3004
- required: isTreeseedEnvironmentEntryRequired(entry, registry.context, scope, "config")
3005
- }))])
3006
- );
3007
- return {
3008
- tenantRoot,
3009
- scopes,
3010
- project: {
3011
- name: registry.context.deployConfig.name,
3012
- slug: registry.context.deployConfig.slug,
3013
- siteUrl: registry.context.deployConfig.siteUrl
3014
- },
3015
- configPath,
3016
- keyPath,
3017
- entriesByScope,
3018
- valuesByScope,
3019
- suggestedValuesByScope,
3020
- configReadinessByScope,
3021
- validationByScope,
3022
- sharedStorageMigrations: [],
3023
- registry
3024
- };
3025
- }
3026
- function applyTreeseedConfigValues({
3027
- tenantRoot,
3028
- updates,
3029
- applyLocalEnvironment = true
3030
- }) {
3031
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
3032
- const key = loadMachineKey(tenantRoot);
3033
- const machineConfig = loadTreeseedMachineConfig(tenantRoot);
3034
- const sharedStorageMigrations = migrateLegacyScopedSharedEntries(tenantRoot, machineConfig, registry.entries, key);
3035
- const entryById = new Map(registry.entries.map((entry) => [entry.id, entry]));
3036
- const applied = [];
3037
- for (const update of updates) {
3038
- const entry = entryById.get(update.entryId);
3039
- if (!entry) {
3040
- throw new Error(`Unknown Treeseed config entry "${update.entryId}".`);
3041
- }
3042
- if (!entry.scopes.includes(update.scope)) {
3043
- throw new Error(`Treeseed config entry "${update.entryId}" does not apply to ${update.scope}.`);
3044
- }
3045
- setTreeseedMachineEnvironmentValue(tenantRoot, update.scope, entry, update.value);
3046
- applied.push({
3047
- scope: entry.storage === "shared" ? "shared" : update.scope,
3048
- id: entry.id,
3049
- reused: update.reused === true,
3050
- cleared: update.value.length === 0
3051
- });
3052
- }
3053
- if (applyLocalEnvironment) {
3054
- applyTreeseedEnvironmentToProcess({ tenantRoot, scope: "local", override: true });
3055
- }
3056
- return {
3057
- updated: applied,
3058
- sharedStorageMigrations
3059
- };
3060
- }
3061
- function configProblemBootstrapSystems(problem) {
3062
- switch (problem?.id) {
3063
- case "TREESEED_GITHUB_TOKEN":
3064
- return ["github"];
3065
- case "TREESEED_CLOUDFLARE_API_TOKEN":
3066
- case "TREESEED_CLOUDFLARE_ACCOUNT_ID":
3067
- case "CLOUDFLARE_ZONE_ID":
3068
- return ["data", "web"];
3069
- case "TREESEED_RAILWAY_API_TOKEN":
3070
- case "TREESEED_RAILWAY_WORKSPACE":
3071
- return ["api", "agents"];
3072
- default:
3073
- return null;
3074
- }
3075
- }
3076
- function filterValidationForBootstrapSystems(validation, runnableSystems) {
3077
- const runnable = new Set(runnableSystems);
3078
- const keepProblem = (problem) => {
3079
- const systems = configProblemBootstrapSystems(problem);
3080
- return !systems || systems.some((system) => runnable.has(system));
3081
- };
3082
- const missing = validation.missing.filter(keepProblem);
3083
- const invalid = validation.invalid.filter(keepProblem);
3084
- return {
3085
- ...validation,
3086
- ok: missing.length === 0 && invalid.length === 0,
3087
- missing,
3088
- invalid
3089
- };
3090
- }
3091
- async function finalizeTreeseedConfig({
3092
- tenantRoot,
3093
- scopes = [...TREESEED_ENVIRONMENT_SCOPES],
3094
- sync = "all",
3095
- env = process.env,
3096
- checkConnections = true,
3097
- initializePersistent = true,
3098
- systems,
3099
- skipUnavailable,
3100
- bootstrapExecution = "parallel",
3101
- onProgress
3102
- }) {
3103
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
3104
- const summary = {
3105
- scopes,
3106
- synced: {},
3107
- reconciled: [],
3108
- deployed: [],
3109
- resourceInventoryByScope: {},
3110
- connectionChecks: [],
3111
- validationByScope: {},
3112
- bootstrapSystemsByScope: {},
3113
- githubRepository: null,
3114
- readinessByScope: {},
3115
- bootstrapExecution
3116
- };
3117
- const progress = (message, stream = "stdout") => {
3118
- if (typeof onProgress === "function") {
3119
- onProgress(message, stream);
3120
- }
3121
- };
3122
- progress(`Validating configuration for ${scopes.join(", ")}...`);
3123
- const rawScopeSeedValues = Object.fromEntries(
3124
- scopes.map((scope) => [scope, collectTreeseedConfigSeedValues(tenantRoot, scope, env)])
3125
- );
3126
- const scopeSeedValues = Object.fromEntries(
3127
- scopes.map((scope) => {
3128
- const suggestedValues = getTreeseedEnvironmentSuggestedValues({
3129
- scope,
3130
- purpose: "config",
3131
- deployConfig: registry.context.deployConfig,
3132
- tenantConfig: registry.context.tenantConfig,
3133
- plugins: registry.context.plugins,
3134
- values: rawScopeSeedValues[scope]
3135
- });
3136
- return [scope, {
3137
- ...suggestedValues,
3138
- ...rawScopeSeedValues[scope]
3139
- }];
3140
- })
3141
- );
3142
- for (const scope of scopes) {
3143
- const selection = resolveTreeseedBootstrapSelection({
3144
- deployConfig: workspaceBootstrapDeployConfig(tenantRoot, registry.context.deployConfig),
3145
- env: scopeSeedValues[scope],
3146
- systems: scope === "local" ? ["github"] : systems,
3147
- skipUnavailable: scope === "local" ? true : skipUnavailable
3148
- });
3149
- summary.bootstrapSystemsByScope[scope] = selection;
3150
- const strictUnavailable = selection.unavailable.filter(
3151
- (status) => !selection.skipped.some((skipped) => skipped.system === status.system && skipped.reason === status.reason)
3152
- );
3153
- if (initializePersistent && strictUnavailable.length > 0) {
3154
- throw new Error(`Treeseed bootstrap cannot run the selected systems for ${scope}:
3155
- - ${strictUnavailable.map((status) => `${status.system}: ${status.reason}`).join("\n- ")}`);
3156
- }
3157
- for (const skipped of selection.skipped) {
3158
- progress(`[${scope}][${skipped.system}][skip] ${skipped.reason}`);
3159
- }
3160
- }
3161
- for (const scope of scopes) {
3162
- const seedValues = scopeSeedValues[scope];
3163
- const suggestedValues = getTreeseedEnvironmentSuggestedValues({
3164
- scope,
3165
- purpose: "config",
3166
- deployConfig: registry.context.deployConfig,
3167
- tenantConfig: registry.context.tenantConfig,
3168
- plugins: registry.context.plugins,
3169
- values: seedValues
3170
- });
3171
- const validation = validateTreeseedEnvironmentValues({
3172
- values: {
3173
- ...suggestedValues,
3174
- ...seedValues
3175
- },
3176
- scope,
3177
- purpose: "config",
3178
- deployConfig: registry.context.deployConfig,
3179
- tenantConfig: registry.context.tenantConfig,
3180
- plugins: registry.context.plugins
3181
- });
3182
- summary.validationByScope[scope] = initializePersistent ? filterValidationForBootstrapSystems(validation, summary.bootstrapSystemsByScope[scope].runnable) : validation;
3183
- if (checkConnections) {
3184
- progress(`Checking provider connectivity for ${scope}...`);
3185
- summary.connectionChecks.push(await checkTreeseedProviderConnections({ tenantRoot, scope, env: seedValues }));
3186
- }
3187
- }
3188
- for (const scope of scopes) {
3189
- if (scope !== "local") {
3190
- const target = createPersistentDeployTarget(scope);
3191
- const deployState = loadDeployState(tenantRoot, registry.context.deployConfig, { target });
3192
- const inventory = buildProvisioningSummary(registry.context.deployConfig, deployState, target);
3193
- const railwayWorkspace = resolveRailwayWorkspace(scopeSeedValues[scope]);
3194
- summary.resourceInventoryByScope[scope] = inventory;
3195
- progress(
3196
- `Resolved ${scope} resources: deployment=${inventory.identity?.deploymentKey}, pages=${inventory.resources?.pagesProject}, web-domain=${inventory.resources?.webDomain ?? "(none)"}, api-domain=${inventory.resources?.apiDomain ?? "(none)"}, r2=${inventory.resources?.contentBucket}, queue=${inventory.resources?.queue}, d1=${inventory.resources?.database}, railway=${inventory.resources?.railwayProject}, workspace=${railwayWorkspace}.`
3197
- );
3198
- }
3199
- summary.readinessByScope[scope] = await summarizePersistentReadiness(
3200
- tenantRoot,
3201
- scope,
3202
- summary.validationByScope[scope],
3203
- summary.connectionChecks.find((report) => report.scope === scope)?.checks ?? [],
3204
- scopeSeedValues[scope],
3205
- {
3206
- includeReconcileStatus: initializePersistent && summary.bootstrapSystemsByScope[scope].runnable.some((system) => system !== "github"),
3207
- systems: summary.bootstrapSystemsByScope[scope].runnable.filter((system) => system !== "github")
3208
- }
3209
- );
3210
- }
3211
- const invalidScopes = scopes.filter((scope) => summary.validationByScope[scope]?.ok !== true);
3212
- if (invalidScopes.length > 0) {
3213
- throw new Error(formatTreeseedConfigValidationFailure(summary.validationByScope, scopes));
3214
- }
3215
- const failingConnectionReports = summary.connectionChecks.filter((report) => report.ok !== true);
3216
- if (failingConnectionReports.length > 0) {
3217
- throw new Error(formatTreeseedProviderConnectionFailures(failingConnectionReports));
3218
- }
3219
- progress("Syncing managed service settings from treeseed.site.yaml...");
3220
- syncManagedServiceSettingsFromDeployConfig(tenantRoot);
3221
- const githubSelected = scopes.some((scope) => scope !== "local" && summary.bootstrapSystemsByScope[scope].runnable.includes("github"));
3222
- let githubRepository = maybeResolveGitHubRepositorySlug(tenantRoot);
3223
- if (githubSelected && initializePersistent) {
3224
- const localSeedValues = collectTreeseedConfigSeedValues(tenantRoot, "local", env);
3225
- const localSuggestedValues = getTreeseedEnvironmentSuggestedValues({
3226
- scope: "local",
3227
- purpose: "config",
3228
- deployConfig: registry.context.deployConfig,
3229
- tenantConfig: registry.context.tenantConfig,
3230
- plugins: registry.context.plugins,
3231
- values: localSeedValues
3232
- });
3233
- const repositoryBootstrap = await ensureGitHubBootstrapRepository(tenantRoot, {
3234
- values: {
3235
- ...localSuggestedValues,
3236
- ...localSeedValues
3237
- },
3238
- defaultName: registry.context.deployConfig.slug,
3239
- onProgress: (line) => progress(line)
3240
- });
3241
- summary.githubRepository = repositoryBootstrap;
3242
- githubRepository = repositoryBootstrap.repository;
3243
- }
3244
- if (initializePersistent) {
3245
- for (const scope of scopes) {
3246
- if (scope === "local") {
3247
- continue;
3248
- }
3249
- const selection = summary.bootstrapSystemsByScope[scope];
3250
- const reconcileSystems = selection.runnable.filter((system) => system !== "github");
3251
- if (reconcileSystems.length > 0) {
3252
- progress(`[${scope}][bootstrap][plan] Deriving desired units for ${reconcileSystems.join(", ")}...`);
3253
- const initialized = await reconcileTreeseedTarget({
3254
- tenantRoot,
3255
- target: createPersistentDeployTarget(scope),
3256
- env: scopeSeedValues[scope],
3257
- systems: reconcileSystems,
3258
- write: (line) => progress(`[${scope}][reconcile] ${line}`)
3259
- });
3260
- summary.reconciled.push({
3261
- scope,
3262
- target: scope,
3263
- units: initialized.units.length,
3264
- actions: initialized.results.map((result) => ({
3265
- unitId: result.unit.unitId,
3266
- unitType: result.unit.unitType,
3267
- provider: result.unit.provider,
3268
- action: result.action,
3269
- verified: result.verification?.verified === true,
3270
- missing: result.verification?.missing ?? [],
3271
- drifted: result.verification?.drifted ?? []
3272
- }))
3273
- });
3274
- }
3275
- if (scope === "staging" && selection.runnable.includes("github")) {
3276
- progress(`[${scope}][github][branch] Ensuring ${STAGING_BRANCH} exists on origin from ${PRODUCTION_BRANCH}...`);
3277
- if (!githubRepository) {
3278
- throw new Error("Unable to determine the GitHub repository from the origin remote for staging branch bootstrap.");
3279
- }
3280
- const branchBootstrap = await ensureGitHubBranchFromBase(githubRepository, STAGING_BRANCH, {
3281
- baseBranch: PRODUCTION_BRANCH,
3282
- client: createGitHubApiClient({
3283
- env: scopeSeedValues[scope]
3284
- })
3285
- });
3286
- summary.deployed.push({
3287
- scope,
3288
- branchBootstrap,
3289
- result: {}
3290
- });
3291
- }
3292
- const deploySystems = selection.runnable.filter((system) => system === "data" || system === "web" || system === "api" || system === "agents");
3293
- if (deploySystems.length > 0) {
3294
- progress(`[${scope}][bootstrap][deploy] Deploying ${deploySystems.join(", ")}...`);
3295
- applyTreeseedEnvironmentToProcess({ tenantRoot, scope, override: true });
3296
- process.env.TREESEED_RAILWAY_WORKSPACE = process.env.TREESEED_RAILWAY_WORKSPACE || scopeSeedValues[scope].TREESEED_RAILWAY_WORKSPACE || resolveRailwayWorkspace(scopeSeedValues[scope]);
3297
- const { deployProjectPlatform } = await import("./project-platform.js");
3298
- const deployResult = await deployProjectPlatform({
3299
- tenantRoot,
3300
- scope,
3301
- skipProvision: true,
3302
- bootstrapSystems: deploySystems,
3303
- bootstrapExecution,
3304
- env: scopeSeedValues[scope],
3305
- write: (line, stream) => progress(line, stream)
3306
- });
3307
- const deployEntry = summary.deployed.find((entry) => entry.scope === scope);
3308
- if (deployEntry) {
3309
- deployEntry.result = deployResult;
3310
- } else {
3311
- summary.deployed.push({
3312
- scope,
3313
- branchBootstrap: null,
3314
- result: deployResult
3315
- });
3316
- }
3317
- progress(`[${scope}][bootstrap][verify] Re-verifying after deployment...`);
3318
- const finalized = await reconcileTreeseedTarget({
3319
- tenantRoot,
3320
- target: createPersistentDeployTarget(scope),
3321
- env: scopeSeedValues[scope],
3322
- systems: reconcileSystems,
3323
- write: (line) => progress(`[${scope}][verify] ${line}`)
3324
- });
3325
- const index = summary.reconciled.findIndex((entry) => entry.scope === scope);
3326
- const nextSummary = {
3327
- scope,
3328
- target: scope,
3329
- units: finalized.units.length,
3330
- actions: finalized.results.map((result) => ({
3331
- unitId: result.unit.unitId,
3332
- unitType: result.unit.unitType,
3333
- provider: result.unit.provider,
3334
- action: result.action,
3335
- verified: result.verification?.verified === true,
3336
- missing: result.verification?.missing ?? [],
3337
- drifted: result.verification?.drifted ?? []
3338
- }))
3339
- };
3340
- if (index >= 0) {
3341
- summary.reconciled[index] = nextSummary;
3342
- } else {
3343
- summary.reconciled.push(nextSummary);
3344
- }
3345
- }
3346
- }
3347
- }
3348
- if (sync === "github" || sync === "all") {
3349
- const githubScopes = scopes.filter((scope) => scope !== "local" && summary.bootstrapSystemsByScope[scope].runnable.includes("github"));
3350
- const githubTargets = discoverGitHubEnvironmentSyncTargets(tenantRoot, githubRepository);
3351
- if (githubTargets.length === 0 && githubScopes.length > 0) {
3352
- throw new Error("Unable to determine the GitHub repository from the origin remote.");
3353
- }
3354
- const syncScope = async (scope, target) => {
3355
- progress(`[${scope}][github][sync] Syncing GitHub environment for ${target.repository}...`);
3356
- return await syncTreeseedGitHubEnvironment({
3357
- tenantRoot,
3358
- scope,
3359
- repository: target.repository,
3360
- managedHostMode: target.managedHostMode,
3361
- execution: bootstrapExecution,
3362
- onProgress: progress
3363
- });
3364
- };
3365
- const githubResults = [];
3366
- if (bootstrapExecution === "sequential") {
3367
- for (const target of githubTargets) {
3368
- for (const scope of githubScopes) {
3369
- githubResults.push(await syncScope(scope, target));
3370
- }
3371
- }
3372
- } else {
3373
- githubResults.push(...await Promise.all(githubTargets.flatMap(
3374
- (target) => githubScopes.map((scope) => syncScope(scope, target))
3375
- )));
3376
- }
3377
- summary.synced.github = {
3378
- scopes: githubResults,
3379
- repository: githubResults[0]?.repository ?? githubRepository ?? maybeResolveGitHubRepositorySlug(tenantRoot),
3380
- repositories: githubResults.map((entry) => entry.repository).filter((repository, index, all) => all.indexOf(repository) === index),
3381
- secrets: githubResults.flatMap((entry) => entry.secrets),
3382
- variables: githubResults.flatMap((entry) => entry.variables)
3383
- };
3384
- }
3385
- for (const scope of scopes) {
3386
- const reconciled = summary.reconciled.find((entry) => entry.scope === scope) ?? null;
3387
- summary.readinessByScope[scope] = initializePersistent && reconciled ? summarizeReconciledPersistentReadiness(
3388
- scope,
3389
- summary.validationByScope[scope],
3390
- summary.connectionChecks.find((report) => report.scope === scope)?.checks ?? [],
3391
- reconciled
3392
- ) : await summarizePersistentReadiness(
3393
- tenantRoot,
3394
- scope,
3395
- summary.validationByScope[scope],
3396
- summary.connectionChecks.find((report) => report.scope === scope)?.checks ?? [],
3397
- scopeSeedValues[scope],
3398
- {
3399
- includeReconcileStatus: initializePersistent && summary.bootstrapSystemsByScope[scope].runnable.some((system) => system !== "github"),
3400
- systems: summary.bootstrapSystemsByScope[scope].runnable.filter((system) => system !== "github")
3401
- }
3402
- );
3403
- }
3404
- return summary;
3405
- }
3406
- function collectTreeseedPrintEnvReport({
3407
- tenantRoot,
3408
- scope,
3409
- env = process.env,
3410
- revealSecrets = false
3411
- }) {
3412
- const registry = collectTreeseedEnvironmentContext(tenantRoot);
3413
- const { values, sources } = collectTreeseedConfigSeedValueSources(tenantRoot, scope, env);
3414
- return {
3415
- scope,
3416
- revealSecrets,
3417
- entries: listRelevantTreeseedConfigEntries(registry, scope).map((entry) => {
3418
- const rawValue = values[entry.id] ?? "";
3419
- const canRevealValue = entry.sensitivity !== "secret" || revealSecrets;
3420
- return {
3421
- id: entry.id,
3422
- label: entry.label,
3423
- sensitivity: entry.sensitivity,
3424
- value: canRevealValue ? rawValue : "",
3425
- displayValue: rawValue ? entry.sensitivity === "secret" && !revealSecrets ? maskValue(rawValue) : rawValue : "(unset)",
3426
- source: sources[entry.id] ?? "unset",
3427
- sourceRequirement: entry.sourceRequirement,
3428
- sourceHostType: entry.sourceHostType ?? null,
3429
- sourceProvider: entry.sourceProvider ?? null
3430
- };
3431
- })
3432
- };
3433
- }
3434
- export {
3435
- DEFAULT_TEMPLATE_CATALOG_URL,
3436
- DEFAULT_TREESEED_API_BASE_URL,
3437
- TREESEED_API_BASE_URL_ENV,
3438
- TREESEED_MACHINE_KEY_PASSPHRASE_ENV2 as TREESEED_MACHINE_KEY_PASSPHRASE_ENV,
3439
- TREESEED_TEMPLATE_CATALOG_URL_ENV,
3440
- TreeseedKeyAgentError2 as TreeseedKeyAgentError,
3441
- applyTreeseedConfigValues,
3442
- applyTreeseedEnvironmentToProcess,
3443
- applyTreeseedSafeRepairs,
3444
- assertTreeseedCommandEnvironment,
3445
- checkTreeseedProviderConnections,
3446
- clearTreeseedRemoteSession,
3447
- collectTreeseedConfigContext,
3448
- collectTreeseedConfigSeedValues,
3449
- collectTreeseedEnvironmentContext,
3450
- collectTreeseedPrintEnvReport,
3451
- configGroupRank,
3452
- createDefaultTreeseedMachineConfig,
3453
- ensureTreeseedActVerificationTooling,
3454
- ensureTreeseedGitignoreEntries,
3455
- ensureTreeseedRailwayIgnoreEntries,
3456
- ensureTreeseedSecretSessionForConfig,
3457
- finalizeTreeseedConfig,
3458
- formatTreeseedConfigEnvironmentReport,
3459
- formatTreeseedProviderConnectionReport,
3460
- getTreeseedMachineConfigPaths,
3461
- getTreeseedRemoteAuthPaths,
3462
- initializeTreeseedPersistentEnvironment,
3463
- inspectTreeseedKeyAgentStatus,
3464
- inspectTreeseedKeyAgentTransportDiagnostic,
3465
- inspectTreeseedPassphraseEnvDiagnostic,
3466
- listDeprecatedTreeseedLocalEnvFiles,
3467
- listRelevantTreeseedConfigEntries,
3468
- loadTreeseedMachineConfig,
3469
- loadTreeseedRemoteAuthState,
3470
- lockTreeseedSecretSession,
3471
- migrateTreeseedMachineKeyToWrapped,
3472
- resolveTreeseedLaunchEnvironment,
3473
- resolveTreeseedMachineEnvironmentValues,
3474
- resolveTreeseedRemoteConfig,
3475
- resolveTreeseedRemoteSession,
3476
- resolveTreeseedTemplateCatalogCachePath,
3477
- resolveTreeseedTemplateCatalogEndpoint,
3478
- rotateTreeseedMachineKey,
3479
- rotateTreeseedMachineKeyPassphrase,
3480
- setTreeseedMachineEnvironmentValue,
3481
- setTreeseedRemoteSession,
3482
- syncTreeseedCloudflareEnvironment,
3483
- syncTreeseedGitHubEnvironment,
3484
- syncTreeseedRailwayEnvironment,
3485
- unlockTreeseedSecretSessionFromEnv,
3486
- unlockTreeseedSecretSessionInteractive,
3487
- unlockTreeseedSecretSessionWithPassphrase,
3488
- updateTreeseedDeployConfigFeatureToggles,
3489
- validateTreeseedCommandEnvironment,
3490
- warnDeprecatedTreeseedLocalEnvFiles,
3491
- withTreeseedKeyAgentAutopromptDisabled,
3492
- writeTreeseedMachineConfig,
3493
- writeTreeseedRemoteAuthState
3494
- };