@treeseed/sdk 0.10.28 → 0.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (509) hide show
  1. package/README.md +213 -7
  2. package/dist/agent-capacity.d.ts +916 -0
  3. package/dist/agent-capacity.js +1600 -0
  4. package/dist/agent-tools.d.ts +37 -0
  5. package/dist/agent-tools.js +301 -0
  6. package/dist/api/app.d.ts +1 -1
  7. package/dist/api/auth/d1-database.d.ts +2 -2
  8. package/dist/api/auth/d1-provider.d.ts +4 -4
  9. package/dist/api/auth/d1-store.d.ts +2 -2
  10. package/dist/api/auth/memory-provider.d.ts +1 -1
  11. package/dist/api/auth/tokens.d.ts +1 -1
  12. package/dist/api/config.d.ts +3 -1
  13. package/dist/api/config.js +34 -10
  14. package/dist/api/http.d.ts +2 -2
  15. package/dist/api/index.d.ts +10 -10
  16. package/dist/api/index.js +4 -2
  17. package/dist/api/operations-routes.d.ts +3 -3
  18. package/dist/api/operations.d.ts +1 -1
  19. package/dist/api/providers.d.ts +1 -1
  20. package/dist/api/providers.js +21 -4
  21. package/dist/api/railway.d.ts +3 -2
  22. package/dist/api/sdk-dispatch.d.ts +4 -4
  23. package/dist/api/sdk-routes.d.ts +2 -2
  24. package/dist/api/templates.d.ts +2 -2
  25. package/dist/api/types.d.ts +3 -2
  26. package/dist/capacity-provider.d.ts +118 -59
  27. package/dist/capacity-provider.js +235 -43
  28. package/dist/capacity.d.ts +2 -2
  29. package/dist/cli-tools.d.ts +1 -1
  30. package/dist/content-operations.d.ts +97 -0
  31. package/dist/content-operations.js +250 -0
  32. package/dist/content-store.d.ts +4 -4
  33. package/dist/control-plane-client.d.ts +13 -18
  34. package/dist/control-plane-client.js +8 -86
  35. package/dist/control-plane.d.ts +3 -2
  36. package/dist/control-plane.js +38 -13
  37. package/dist/copilot.d.ts +3 -0
  38. package/dist/copilot.js +16 -1
  39. package/dist/d1-http.d.ts +1 -1
  40. package/dist/d1-store.d.ts +32 -57
  41. package/dist/d1-store.js +115 -318
  42. package/dist/db/d1.d.ts +1 -232
  43. package/dist/db/index.d.ts +3 -3
  44. package/dist/db/market-schema.d.ts +50900 -11018
  45. package/dist/db/market-schema.js +2313 -467
  46. package/dist/db/node-sqlite.d.ts +1 -232
  47. package/dist/db/node-sqlite.js +7 -2
  48. package/dist/db/schema.d.ts +0 -462
  49. package/dist/db/schema.js +2 -22
  50. package/dist/dispatch.d.ts +1 -1
  51. package/dist/dispatch.js +0 -11
  52. package/dist/fixture-support.js +52 -4
  53. package/dist/governance.d.ts +133 -0
  54. package/dist/governance.js +285 -0
  55. package/dist/graph/build.d.ts +2 -2
  56. package/dist/graph/context-query-contracts.d.ts +1 -1
  57. package/dist/graph/dsl.d.ts +1 -1
  58. package/dist/graph/query.d.ts +4 -4
  59. package/dist/graph/ranking.d.ts +1 -1
  60. package/dist/graph/schema.d.ts +1 -1
  61. package/dist/graph.d.ts +11 -11
  62. package/dist/guarantees/index.d.ts +425 -0
  63. package/dist/guarantees/index.js +1146 -0
  64. package/dist/hosting/apps.d.ts +12 -0
  65. package/dist/hosting/apps.js +107 -0
  66. package/dist/hosting/builtins.d.ts +25 -0
  67. package/dist/hosting/builtins.js +602 -0
  68. package/dist/hosting/contracts.d.ts +208 -0
  69. package/dist/hosting/contracts.js +0 -0
  70. package/dist/hosting/graph.d.ts +195 -0
  71. package/dist/hosting/graph.js +1092 -0
  72. package/dist/hosting/index.d.ts +4 -0
  73. package/dist/hosting/index.js +4 -0
  74. package/dist/index.d.ts +88 -67
  75. package/dist/index.js +142 -14
  76. package/dist/local-dev/managed-dev.d.ts +85 -0
  77. package/dist/local-dev/managed-dev.js +368 -0
  78. package/dist/managed-dependencies.d.ts +9 -0
  79. package/dist/managed-dependencies.js +10 -9
  80. package/dist/market-client.d.ts +327 -9
  81. package/dist/market-client.js +464 -20
  82. package/dist/model-registry.d.ts +1 -1
  83. package/dist/model-registry.js +19 -19
  84. package/dist/operations/agent-tools.d.ts +2 -11
  85. package/dist/operations/agent-tools.js +2 -14
  86. package/dist/operations/providers/default.d.ts +1 -1
  87. package/dist/operations/providers/default.js +20 -37
  88. package/dist/operations/repository-operations.d.ts +26 -2
  89. package/dist/operations/repository-operations.js +159 -1
  90. package/dist/operations/runtime.d.ts +3 -3
  91. package/dist/operations/services/bootstrap-runner.d.ts +4 -2
  92. package/dist/operations/services/bootstrap-runner.js +22 -2
  93. package/dist/operations/services/build-warning-policy.d.ts +34 -0
  94. package/dist/operations/services/build-warning-policy.js +81 -82
  95. package/dist/operations/services/commit-message-provider.js +4 -4
  96. package/dist/operations/services/config-runtime.d.ts +83 -24
  97. package/dist/operations/services/config-runtime.js +449 -130
  98. package/dist/operations/services/deploy.d.ts +106 -624
  99. package/dist/operations/services/deploy.js +746 -263
  100. package/dist/operations/services/deployment-readiness.d.ts +30 -0
  101. package/dist/operations/services/deployment-readiness.js +206 -0
  102. package/dist/operations/services/git-remote-policy.js +12 -4
  103. package/dist/operations/services/git-runner.d.ts +66 -0
  104. package/dist/operations/services/git-runner.js +479 -0
  105. package/dist/operations/services/git-workflow.d.ts +45 -6
  106. package/dist/operations/services/git-workflow.js +251 -23
  107. package/dist/operations/services/github-actions-verification.d.ts +4 -1
  108. package/dist/operations/services/github-actions-verification.js +12 -3
  109. package/dist/operations/services/github-api.js +22 -6
  110. package/dist/operations/services/github-automation.d.ts +4 -4
  111. package/dist/operations/services/github-automation.js +19 -21
  112. package/dist/operations/services/github-credentials.d.ts +13 -0
  113. package/dist/operations/services/github-credentials.js +59 -0
  114. package/dist/operations/services/hosted-service-checks.d.ts +81 -0
  115. package/dist/operations/services/hosted-service-checks.js +478 -0
  116. package/dist/operations/services/hosting-audit.d.ts +2 -2
  117. package/dist/operations/services/hosting-audit.js +7 -7
  118. package/dist/operations/services/hub-launch.d.ts +1 -1
  119. package/dist/operations/services/hub-provider-launch.d.ts +5 -5
  120. package/dist/operations/services/hub-provider-launch.js +22 -17
  121. package/dist/operations/services/live-hosted-service-checks.d.ts +26 -0
  122. package/dist/operations/services/live-hosted-service-checks.js +463 -0
  123. package/dist/operations/services/local-dev.js +0 -1
  124. package/dist/operations/services/managed-host-security.d.ts +1 -1
  125. package/dist/operations/services/managed-host-security.js +1 -1
  126. package/dist/operations/services/managed-repositories.d.ts +37 -0
  127. package/dist/operations/services/managed-repositories.js +177 -0
  128. package/dist/operations/services/operations-runner-smoke.d.ts +31 -0
  129. package/dist/operations/services/operations-runner-smoke.js +198 -0
  130. package/dist/operations/services/package-adapters.d.ts +170 -0
  131. package/dist/operations/services/package-adapters.js +859 -0
  132. package/dist/operations/services/package-reference-policy.d.ts +13 -88
  133. package/dist/operations/services/package-reference-policy.js +96 -215
  134. package/dist/operations/services/project-host-operations.d.ts +4 -4
  135. package/dist/operations/services/project-platform.d.ts +57 -173
  136. package/dist/operations/services/project-platform.js +80 -111
  137. package/dist/operations/services/project-web-monitor.d.ts +2 -2
  138. package/dist/operations/services/project-web-monitor.js +122 -5
  139. package/dist/operations/services/railway-api.d.ts +117 -5
  140. package/dist/operations/services/railway-api.js +915 -93
  141. package/dist/operations/services/railway-deploy.d.ts +30 -112
  142. package/dist/operations/services/railway-deploy.js +521 -961
  143. package/dist/operations/services/release-history.js +3 -4
  144. package/dist/operations/services/release-proof-ledger.d.ts +13 -0
  145. package/dist/operations/services/release-proof-ledger.js +81 -0
  146. package/dist/operations/services/release-proof-planner.d.ts +48 -0
  147. package/dist/operations/services/release-proof-planner.js +195 -0
  148. package/dist/operations/services/release-proof-runner.d.ts +16 -0
  149. package/dist/operations/services/release-proof-runner.js +169 -0
  150. package/dist/operations/services/release-proof.d.ts +81 -0
  151. package/dist/operations/services/release-proof.js +79 -0
  152. package/dist/operations/services/repository-save-orchestrator.d.ts +8 -7
  153. package/dist/operations/services/repository-save-orchestrator.js +604 -212
  154. package/dist/operations/services/runtime-paths.d.ts +1 -3
  155. package/dist/operations/services/runtime-paths.js +0 -4
  156. package/dist/operations/services/runtime-tools.d.ts +1 -191
  157. package/dist/operations/services/runtime-tools.js +4 -443
  158. package/dist/operations/services/save-deploy-preflight.js +9 -1
  159. package/dist/operations/services/template-host-bindings.d.ts +2 -2
  160. package/dist/operations/services/template-host-bindings.js +3 -2
  161. package/dist/operations/services/template-registry.d.ts +6 -6
  162. package/dist/operations/services/template-registry.js +33 -14
  163. package/dist/operations/services/template-secret-sync.d.ts +3 -3
  164. package/dist/operations/services/verification-cache.d.ts +25 -0
  165. package/dist/operations/services/verification-cache.js +71 -0
  166. package/dist/operations/services/workflow-timing.d.ts +25 -0
  167. package/dist/operations/services/workflow-timing.js +79 -0
  168. package/dist/operations/services/workspace-dependency-mode.js +50 -5
  169. package/dist/operations/services/workspace-preflight.js +8 -8
  170. package/dist/operations/services/workspace-save-script.d.ts +4 -4
  171. package/dist/operations/services/workspace-save.d.ts +1 -0
  172. package/dist/operations/services/workspace-save.js +42 -19
  173. package/dist/operations/services/workspace-tools.js +42 -7
  174. package/dist/operations-registry.d.ts +1 -1
  175. package/dist/operations-registry.js +5 -6
  176. package/dist/operations-types.d.ts +1 -1
  177. package/dist/operations.d.ts +17 -11
  178. package/dist/operations.js +57 -3
  179. package/dist/platform/book-export.js +2 -0
  180. package/dist/platform/books-data.d.ts +1 -1
  181. package/dist/platform/config.d.ts +27 -0
  182. package/dist/platform/config.js +100 -0
  183. package/dist/platform/content-runtime-source.d.ts +54 -0
  184. package/dist/platform/content-runtime-source.js +169 -0
  185. package/dist/platform/contracts.d.ts +38 -2
  186. package/dist/platform/deploy-config.d.ts +1 -1
  187. package/dist/platform/deploy-config.js +80 -9
  188. package/dist/platform/deploy-runtime.d.ts +1 -1
  189. package/dist/platform/desired-state.d.ts +63 -0
  190. package/dist/platform/desired-state.js +1021 -0
  191. package/dist/platform/env.yaml +568 -45
  192. package/dist/platform/environment.d.ts +3 -2
  193. package/dist/platform/environment.js +122 -21
  194. package/dist/platform/local-content-materialization.d.ts +9 -0
  195. package/dist/platform/local-content-materialization.js +212 -0
  196. package/dist/platform/plugin.d.ts +13 -4
  197. package/dist/platform/plugins/runtime.d.ts +3 -3
  198. package/dist/platform/plugins/runtime.js +62 -1
  199. package/dist/platform/plugins.d.ts +6 -6
  200. package/dist/platform/published-content-pipeline.d.ts +3 -3
  201. package/dist/platform/published-content-pipeline.js +5 -1
  202. package/dist/platform/published-content.d.ts +4 -3
  203. package/dist/platform/site-config-schema.d.ts +1 -0
  204. package/dist/platform/site-config-schema.js +4 -1
  205. package/dist/platform/tenant/runtime-config.d.ts +152 -2
  206. package/dist/platform/tenant-config.d.ts +1 -1
  207. package/dist/platform/utils/site-config-schema.d.ts +154 -0
  208. package/dist/platform/utils/site-config-schema.js +400 -461
  209. package/dist/platform-operation-store.d.ts +1 -1
  210. package/dist/platform-operation-store.js +2 -2
  211. package/dist/platform-operations.js +1 -1
  212. package/dist/plugin-default.d.ts +1 -1
  213. package/dist/plugin-default.js +27 -12
  214. package/dist/project-import.d.ts +91 -0
  215. package/dist/project-import.js +257 -0
  216. package/dist/project-workflow.d.ts +1 -1
  217. package/dist/reconcile/bootstrap-systems.d.ts +2 -2
  218. package/dist/reconcile/bootstrap-systems.js +5 -5
  219. package/dist/reconcile/builtin-adapters.d.ts +7 -1
  220. package/dist/reconcile/builtin-adapters.js +3190 -429
  221. package/dist/reconcile/contracts.d.ts +23 -6
  222. package/dist/reconcile/desired-state.d.ts +2 -192
  223. package/dist/reconcile/desired-state.js +29 -38
  224. package/dist/reconcile/engine.d.ts +61 -395
  225. package/dist/reconcile/engine.js +229 -44
  226. package/dist/reconcile/index.d.ts +10 -8
  227. package/dist/reconcile/index.js +2 -0
  228. package/dist/reconcile/live-acceptance.d.ts +100 -0
  229. package/dist/reconcile/live-acceptance.js +2027 -0
  230. package/dist/reconcile/platform.d.ts +104 -0
  231. package/dist/reconcile/platform.js +100 -0
  232. package/dist/reconcile/providers/docker-private.d.ts +54 -0
  233. package/dist/reconcile/providers/docker-private.js +101 -0
  234. package/dist/reconcile/providers/github-private.d.ts +65 -0
  235. package/dist/reconcile/providers/github-private.js +119 -0
  236. package/dist/reconcile/providers/local-private.d.ts +28 -0
  237. package/dist/reconcile/providers/local-private.js +75 -0
  238. package/dist/reconcile/providers/railway-iac.d.ts +66 -0
  239. package/dist/reconcile/providers/railway-iac.js +275 -0
  240. package/dist/reconcile/providers/release-private.d.ts +92 -0
  241. package/dist/reconcile/providers/release-private.js +152 -0
  242. package/dist/reconcile/registry.d.ts +2 -2
  243. package/dist/reconcile/registry.js +16 -1
  244. package/dist/reconcile/state.d.ts +1 -1
  245. package/dist/reconcile/state.js +7 -44
  246. package/dist/reconcile/units.d.ts +1 -1
  247. package/dist/reconcile/units.js +9 -3
  248. package/dist/remote.d.ts +6 -6
  249. package/dist/scenes/artifacts.d.ts +16 -0
  250. package/dist/scenes/artifacts.js +61 -0
  251. package/dist/scenes/auth.d.ts +2 -0
  252. package/dist/scenes/auth.js +28 -0
  253. package/dist/scenes/base-url.d.ts +12 -0
  254. package/dist/scenes/base-url.js +123 -0
  255. package/dist/scenes/builtin-plugins.d.ts +2 -0
  256. package/dist/scenes/builtin-plugins.js +447 -0
  257. package/dist/scenes/checkpoints.d.ts +14 -0
  258. package/dist/scenes/checkpoints.js +33 -0
  259. package/dist/scenes/device-matrix.d.ts +2 -0
  260. package/dist/scenes/device-matrix.js +97 -0
  261. package/dist/scenes/devices.d.ts +11 -0
  262. package/dist/scenes/devices.js +22 -0
  263. package/dist/scenes/diagnostics.d.ts +5 -0
  264. package/dist/scenes/diagnostics.js +22 -0
  265. package/dist/scenes/diagram-providers.d.ts +2 -0
  266. package/dist/scenes/diagram-providers.js +181 -0
  267. package/dist/scenes/diagram-validation.d.ts +22 -0
  268. package/dist/scenes/diagram-validation.js +74 -0
  269. package/dist/scenes/environment.d.ts +2 -0
  270. package/dist/scenes/environment.js +65 -0
  271. package/dist/scenes/evidence-bundle.d.ts +5 -0
  272. package/dist/scenes/evidence-bundle.js +42 -0
  273. package/dist/scenes/evidence-report.d.ts +10 -0
  274. package/dist/scenes/evidence-report.js +73 -0
  275. package/dist/scenes/evidence.d.ts +16 -0
  276. package/dist/scenes/evidence.js +277 -0
  277. package/dist/scenes/index.d.ts +48 -0
  278. package/dist/scenes/index.js +312 -0
  279. package/dist/scenes/inspect.d.ts +9 -0
  280. package/dist/scenes/inspect.js +64 -0
  281. package/dist/scenes/loader.d.ts +3 -0
  282. package/dist/scenes/loader.js +38 -0
  283. package/dist/scenes/logs.d.ts +2 -0
  284. package/dist/scenes/logs.js +47 -0
  285. package/dist/scenes/operations.d.ts +3 -0
  286. package/dist/scenes/operations.js +128 -0
  287. package/dist/scenes/phase0.d.ts +9 -0
  288. package/dist/scenes/phase0.js +637 -0
  289. package/dist/scenes/planner.d.ts +12 -0
  290. package/dist/scenes/planner.js +166 -0
  291. package/dist/scenes/playwright-adapter.d.ts +2 -0
  292. package/dist/scenes/playwright-adapter.js +63 -0
  293. package/dist/scenes/plugins.d.ts +5 -0
  294. package/dist/scenes/plugins.js +115 -0
  295. package/dist/scenes/progress.d.ts +17 -0
  296. package/dist/scenes/progress.js +24 -0
  297. package/dist/scenes/publish-destinations.d.ts +12 -0
  298. package/dist/scenes/publish-destinations.js +99 -0
  299. package/dist/scenes/publish-plan-report.d.ts +10 -0
  300. package/dist/scenes/publish-plan-report.js +70 -0
  301. package/dist/scenes/publish-plan.d.ts +15 -0
  302. package/dist/scenes/publish-plan.js +248 -0
  303. package/dist/scenes/publish-redaction.d.ts +16 -0
  304. package/dist/scenes/publish-redaction.js +148 -0
  305. package/dist/scenes/publish-release-record.d.ts +13 -0
  306. package/dist/scenes/publish-release-record.js +34 -0
  307. package/dist/scenes/publish-report.d.ts +10 -0
  308. package/dist/scenes/publish-report.js +67 -0
  309. package/dist/scenes/publish.d.ts +16 -0
  310. package/dist/scenes/publish.js +298 -0
  311. package/dist/scenes/registry.d.ts +12 -0
  312. package/dist/scenes/registry.js +65 -0
  313. package/dist/scenes/remotion-adapter.d.ts +3 -0
  314. package/dist/scenes/remotion-adapter.js +94 -0
  315. package/dist/scenes/remotion-composition-registry.d.ts +2 -0
  316. package/dist/scenes/remotion-composition-registry.js +12 -0
  317. package/dist/scenes/remotion-compositions.d.ts +15 -0
  318. package/dist/scenes/remotion-compositions.js +464 -0
  319. package/dist/scenes/remotion-diagrams.d.ts +9 -0
  320. package/dist/scenes/remotion-diagrams.js +188 -0
  321. package/dist/scenes/remotion-input.d.ts +13 -0
  322. package/dist/scenes/remotion-input.js +291 -0
  323. package/dist/scenes/remotion-visuals.d.ts +29 -0
  324. package/dist/scenes/remotion-visuals.js +198 -0
  325. package/dist/scenes/render-media-assets.d.ts +9 -0
  326. package/dist/scenes/render-media-assets.js +117 -0
  327. package/dist/scenes/render-report.d.ts +10 -0
  328. package/dist/scenes/render-report.js +27 -0
  329. package/dist/scenes/render.d.ts +2 -0
  330. package/dist/scenes/render.js +218 -0
  331. package/dist/scenes/reporter.d.ts +3 -0
  332. package/dist/scenes/reporter.js +101 -0
  333. package/dist/scenes/resume.d.ts +2 -0
  334. package/dist/scenes/resume.js +79 -0
  335. package/dist/scenes/runner.d.ts +2 -0
  336. package/dist/scenes/runner.js +674 -0
  337. package/dist/scenes/schema.d.ts +6 -0
  338. package/dist/scenes/schema.js +994 -0
  339. package/dist/scenes/seed.d.ts +2 -0
  340. package/dist/scenes/seed.js +83 -0
  341. package/dist/scenes/segments.d.ts +15 -0
  342. package/dist/scenes/segments.js +79 -0
  343. package/dist/scenes/selectors.d.ts +3 -0
  344. package/dist/scenes/selectors.js +21 -0
  345. package/dist/scenes/timeline.d.ts +11 -0
  346. package/dist/scenes/timeline.js +26 -0
  347. package/dist/scenes/timeouts.d.ts +6 -0
  348. package/dist/scenes/timeouts.js +17 -0
  349. package/dist/scenes/training-captions.d.ts +14 -0
  350. package/dist/scenes/training-captions.js +98 -0
  351. package/dist/scenes/training-report.d.ts +10 -0
  352. package/dist/scenes/training-report.js +78 -0
  353. package/dist/scenes/training-transcript.d.ts +24 -0
  354. package/dist/scenes/training-transcript.js +204 -0
  355. package/dist/scenes/training.d.ts +10 -0
  356. package/dist/scenes/training.js +134 -0
  357. package/dist/scenes/types.d.ts +1872 -0
  358. package/dist/scenes/types.js +8 -0
  359. package/dist/scenes/visual-audit-contact-sheets.d.ts +6 -0
  360. package/dist/scenes/visual-audit-contact-sheets.js +119 -0
  361. package/dist/scenes/visual-audit-fixtures.d.ts +25 -0
  362. package/dist/scenes/visual-audit-fixtures.js +210 -0
  363. package/dist/scenes/visual-audit-report.d.ts +11 -0
  364. package/dist/scenes/visual-audit-report.js +85 -0
  365. package/dist/scenes/visual-audit-review.d.ts +23 -0
  366. package/dist/scenes/visual-audit-review.js +829 -0
  367. package/dist/scenes/visual-audit-routes.d.ts +13 -0
  368. package/dist/scenes/visual-audit-routes.js +308 -0
  369. package/dist/scenes/visual-audit.d.ts +3 -0
  370. package/dist/scenes/visual-audit.js +596 -0
  371. package/dist/scripts/build-dist.js +154 -40
  372. package/dist/scripts/check-build-warnings.js +42 -53
  373. package/dist/scripts/cleanup-markdown.js +1 -1
  374. package/dist/scripts/cli-test-fixtures.js +24 -28
  375. package/dist/scripts/deployment-readiness.js +20 -0
  376. package/dist/scripts/generate-treedx-openapi-types.js +186 -0
  377. package/dist/scripts/migrate-journey-csv-to-guarantees.js +140 -0
  378. package/dist/scripts/operations-runner-smoke.js +16 -0
  379. package/dist/scripts/package-tools.js +12 -1
  380. package/dist/scripts/prepare.js +3 -7
  381. package/dist/scripts/release-verify.js +6 -6
  382. package/dist/scripts/run-fixture-astro-command.js +1 -1
  383. package/dist/scripts/template-catalog.test.js +68 -82
  384. package/dist/scripts/tenant-dev.js +0 -10
  385. package/dist/scripts/tenant-workflow-action.js +10 -1
  386. package/dist/scripts/test-cloudflare-local.js +1 -1
  387. package/dist/scripts/test-scaffold.js +0 -1
  388. package/dist/scripts/test-smoke.js +3 -3
  389. package/dist/scripts/treeseed-build-dist.js +4 -7
  390. package/dist/scripts/treeseed-release-verify.js +1 -1
  391. package/dist/scripts/verify-driver.js +30 -21
  392. package/dist/scripts/workflow-commands.test.js +18 -27
  393. package/dist/scripts/workspace-command-e2e.js +1 -1
  394. package/dist/scripts/workspace-lint.js +6 -0
  395. package/dist/scripts/workspace-release-test.js +90 -1
  396. package/dist/scripts/workspace-test.js +6 -0
  397. package/dist/sdk-dispatch.d.ts +1 -1
  398. package/dist/sdk-dispatch.js +0 -16
  399. package/dist/sdk-fields.d.ts +1 -1
  400. package/dist/sdk-filters.d.ts +1 -1
  401. package/dist/sdk-types.d.ts +1352 -116
  402. package/dist/sdk-types.js +413 -2
  403. package/dist/sdk.d.ts +106 -100
  404. package/dist/sdk.js +211 -51
  405. package/dist/secrets-capability.d.ts +421 -0
  406. package/dist/secrets-capability.js +530 -0
  407. package/dist/seeds/normalize.js +1 -0
  408. package/dist/seeds/planner.js +38 -0
  409. package/dist/seeds/schema.js +293 -4
  410. package/dist/seeds/types.d.ts +60 -0
  411. package/dist/seeds/types.js +9 -1
  412. package/dist/service-credentials.d.ts +54 -0
  413. package/dist/service-credentials.js +112 -0
  414. package/dist/stores/cursor-store.d.ts +2 -2
  415. package/dist/stores/envelopes.d.ts +1 -1
  416. package/dist/stores/helpers.d.ts +1 -1
  417. package/dist/stores/lease-store.d.ts +2 -2
  418. package/dist/stores/message-store.d.ts +2 -2
  419. package/dist/stores/operational-store.d.ts +3 -26
  420. package/dist/stores/operational-store.js +0 -225
  421. package/dist/stores/project-workflow-store.d.ts +2 -2
  422. package/dist/stores/run-store.d.ts +2 -3
  423. package/dist/stores/run-store.js +0 -98
  424. package/dist/stores/subscription-store.d.ts +2 -3
  425. package/dist/stores/subscription-store.js +0 -100
  426. package/dist/template-catalog.d.ts +1 -1
  427. package/dist/template-launch-requirements.d.ts +2 -2
  428. package/dist/template-launch-requirements.js +9 -0
  429. package/dist/template-launch-ui.d.ts +2 -2
  430. package/dist/treedx/adapters.d.ts +6 -0
  431. package/dist/treedx/adapters.js +36 -0
  432. package/dist/treedx/client.d.ts +222 -0
  433. package/dist/treedx/client.js +871 -0
  434. package/dist/treedx/errors.d.ts +13 -0
  435. package/dist/treedx/errors.js +17 -0
  436. package/dist/treedx/federated-client.d.ts +27 -0
  437. package/dist/treedx/federated-client.js +158 -0
  438. package/dist/treedx/generated/openapi-types.d.ts +3558 -0
  439. package/dist/treedx/generated/openapi-types.js +0 -0
  440. package/dist/treedx/graph-adapter.d.ts +33 -0
  441. package/dist/treedx/graph-adapter.js +156 -0
  442. package/dist/treedx/index.d.ts +14 -0
  443. package/dist/treedx/index.js +48 -0
  444. package/dist/treedx/market-integration.d.ts +27 -0
  445. package/dist/treedx/market-integration.js +131 -0
  446. package/dist/treedx/ports.d.ts +166 -0
  447. package/dist/treedx/ports.js +231 -0
  448. package/dist/treedx/query-adapter.d.ts +19 -0
  449. package/dist/treedx/query-adapter.js +62 -0
  450. package/dist/treedx/registry-client.d.ts +11 -0
  451. package/dist/treedx/registry-client.js +19 -0
  452. package/dist/treedx/repository-adapter.d.ts +45 -0
  453. package/dist/treedx/repository-adapter.js +319 -0
  454. package/dist/treedx/sdk-integration.d.ts +27 -0
  455. package/dist/treedx/sdk-integration.js +63 -0
  456. package/dist/treedx/types.d.ts +1084 -0
  457. package/dist/treedx/types.js +8 -0
  458. package/dist/treedx/workspace-adapter.d.ts +27 -0
  459. package/dist/treedx/workspace-adapter.js +65 -0
  460. package/dist/treedx-backends.d.ts +220 -0
  461. package/dist/treedx-backends.js +634 -0
  462. package/dist/treedx-client.d.ts +89 -0
  463. package/dist/treedx-client.js +184 -0
  464. package/dist/treeseed/services/compose.yml +2 -3
  465. package/dist/treeseed/template-catalog/catalog.fixture.json +27 -27
  466. package/dist/types/agents.d.ts +256 -0
  467. package/dist/types/agents.js +42 -1
  468. package/dist/verification.d.ts +1 -0
  469. package/dist/verification.js +143 -14
  470. package/dist/workflow/operations.d.ts +580 -523
  471. package/dist/workflow/operations.js +2084 -1279
  472. package/dist/workflow/policy.js +19 -7
  473. package/dist/workflow/runs.d.ts +9 -3
  474. package/dist/workflow/runs.js +66 -26
  475. package/dist/workflow/session.d.ts +4 -1
  476. package/dist/workflow/session.js +50 -10
  477. package/dist/workflow/worktrees.d.ts +6 -2
  478. package/dist/workflow/worktrees.js +98 -15
  479. package/dist/workflow-state.d.ts +17 -4
  480. package/dist/workflow-state.js +68 -41
  481. package/dist/workflow-support.d.ts +26 -17
  482. package/dist/workflow-support.js +84 -24
  483. package/dist/workflow.d.ts +51 -16
  484. package/dist/workflow.js +19 -7
  485. package/drizzle/d1/0000_treeseed_d1.sql +0 -18
  486. package/drizzle/market/0000_market_control_plane.sql +1793 -1499
  487. package/drizzle/market/0004_treedx_market_integration.sql +99 -0
  488. package/drizzle/market/0005_agent_capacity_coordination.sql +145 -0
  489. package/drizzle/market/0006_provider_assignment_lifecycle.sql +9 -0
  490. package/drizzle/market/0007_agent_architecture_gap_closure.sql +157 -0
  491. package/drizzle/market/0008_agent_capacity_operational_closure.sql +27 -0
  492. package/drizzle/market/0009_agent_capacity_runtime_hardening.sql +29 -0
  493. package/drizzle/market/0010_secrets_capability_persistence.sql +130 -0
  494. package/drizzle/market/0011_github_app_adapter.sql +47 -0
  495. package/drizzle/market/0012_workday_test_runs.sql +44 -0
  496. package/drizzle/market/0013_runtime_task_lifecycle.sql +39 -0
  497. package/drizzle/market/0014_governance_pipeline.sql +189 -0
  498. package/package.json +106 -18
  499. package/scripts/{verify-driver.mjs → verify-driver.ts} +19 -4
  500. package/templates/github/deploy-web.workflow.yml +49 -12
  501. package/dist/operations/services/mailpit-runtime.d.ts +0 -20
  502. package/dist/operations/services/mailpit-runtime.js +0 -67
  503. package/dist/operations/services/release-candidate.d.ts +0 -41
  504. package/dist/operations/services/release-candidate.js +0 -616
  505. package/dist/scripts/ensure-mailpit.js +0 -48
  506. package/dist/scripts/logs-mailpit.js +0 -2
  507. package/dist/scripts/run-ts.js +0 -45
  508. package/dist/scripts/stop-mailpit.js +0 -5
  509. package/dist/scripts/treeseed-run-ts.js +0 -45
@@ -0,0 +1,994 @@
1
+ import { sceneErrorDiagnostic, sceneWarningDiagnostic } from "./diagnostics.js";
2
+ import { findBuiltInTreeseedSceneAction, findBuiltInTreeseedSceneAssertion } from "./registry.js";
3
+ import {
4
+ TREESEED_SCENE_BROWSERS,
5
+ TREESEED_SCENE_ENVIRONMENTS,
6
+ TREESEED_SCENE_SCHEMA_VERSION
7
+ } from "./types.js";
8
+ const FILESYSTEM_SAFE_SCENE_ID = /^[a-z0-9][a-z0-9._-]*$/u;
9
+ const TOP_LEVEL_FIELDS = /* @__PURE__ */ new Set(["schemaVersion", "id", "title", "description", "audience", "mode", "target", "devices", "setup", "artifacts", "workflow", "chapters", "overlays", "diagrams", "render", "runtime", "training", "visualAudit", "xScenario"]);
10
+ const FILESYSTEM_SAFE_CHECKPOINT_ID = /^[a-z0-9][a-z0-9._-]*$/u;
11
+ const DIAGRAM_PLACEMENTS = ["overlay", "interstitial", "standalone"];
12
+ const CAPTION_FORMATS = ["vtt", "srt"];
13
+ const TRANSCRIPT_FORMATS = ["json", "markdown"];
14
+ const NARRATION_STYLES = ["concise", "instructional", "operator"];
15
+ const EVIDENCE_FITS = ["fixed-browser", "contain", "cover"];
16
+ const DEVICE_ORIENTATIONS = ["landscape", "portrait"];
17
+ const DEVICE_BROWSER_CHROME = ["desktop", "tablet", "mobile"];
18
+ const VISUAL_UNITS = ["px", "percent"];
19
+ const VISUAL_REGIONS = ["top-left", "top", "top-right", "left", "center", "right", "bottom-left", "bottom", "bottom-right"];
20
+ const VISUAL_TONES = ["neutral", "info", "success", "warning", "danger", "brand"];
21
+ const VISUAL_SHADOWS = ["none", "soft", "medium", "strong"];
22
+ const MOTION_UNITS = ["seconds", "progress"];
23
+ const MOTION_EASINGS = ["linear", "ease", "ease-in", "ease-out", "ease-in-out"];
24
+ const VISUAL_OBJECT_TYPES = ["text", "box", "circle", "line", "arrow", "badge", "cursor", "spotlight"];
25
+ const OVERLAY_VARIANTS = ["callout", "spotlight", "label", "panel", "lower-third", "badge", "cursor", "custom"];
26
+ function isRecord(value) {
27
+ return typeof value === "object" && value !== null && !Array.isArray(value);
28
+ }
29
+ function asString(value) {
30
+ return typeof value === "string" ? value.trim() : "";
31
+ }
32
+ function requireString(record, field, path, diagnostics) {
33
+ const value = asString(record[field]);
34
+ if (!value) {
35
+ diagnostics.push(sceneErrorDiagnostic("scene.missing_field", `Missing required field: ${field}.`, `${path}.${field}`));
36
+ }
37
+ return value;
38
+ }
39
+ function optionalString(record, field) {
40
+ return asString(record[field]) || void 0;
41
+ }
42
+ function booleanField(record, field, defaultValue, path, diagnostics) {
43
+ const value = record[field];
44
+ if (value === void 0) return defaultValue;
45
+ if (typeof value !== "boolean") {
46
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_boolean", `Expected ${field} to be a boolean.`, `${path}.${field}`));
47
+ return defaultValue;
48
+ }
49
+ return value;
50
+ }
51
+ function positiveNumberField(record, field, defaultValue, path, diagnostics) {
52
+ const value = record[field];
53
+ if (value === void 0) return defaultValue;
54
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
55
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_number", `Expected ${field} to be a positive finite number.`, `${path}.${field}`));
56
+ return defaultValue;
57
+ }
58
+ return value;
59
+ }
60
+ function finiteNumberField(record, field, defaultValue, path, diagnostics) {
61
+ const value = record[field];
62
+ if (value === void 0) return defaultValue;
63
+ if (typeof value !== "number" || !Number.isFinite(value)) {
64
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_number", `Expected ${field} to be a finite number.`, `${path}.${field}`));
65
+ return defaultValue;
66
+ }
67
+ return value;
68
+ }
69
+ function nullablePositiveNumberField(record, field, defaultValue, path, diagnostics) {
70
+ const value = record[field];
71
+ if (value === void 0) return defaultValue;
72
+ if (value === null) return null;
73
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
74
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_number", `Expected ${field} to be a positive finite number or null.`, `${path}.${field}`));
75
+ return defaultValue;
76
+ }
77
+ return value;
78
+ }
79
+ function objectField(record, field, path, diagnostics) {
80
+ const value = record[field];
81
+ if (value === void 0) return void 0;
82
+ if (!isRecord(value)) {
83
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_object", `Expected ${field} to be an object.`, `${path}.${field}`));
84
+ return void 0;
85
+ }
86
+ return value;
87
+ }
88
+ function arrayField(record, field, path, diagnostics) {
89
+ const value = record[field];
90
+ if (value === void 0) return void 0;
91
+ if (!Array.isArray(value)) {
92
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_array", `Expected ${field} to be an array.`, `${path}.${field}`));
93
+ return void 0;
94
+ }
95
+ return value;
96
+ }
97
+ function stringArrayField(record, field, path, diagnostics) {
98
+ const value = arrayField(record, field, path, diagnostics);
99
+ if (!value) return [];
100
+ const strings = [];
101
+ value.forEach((entry, index) => {
102
+ const text = asString(entry);
103
+ if (!text) {
104
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_string", `Expected ${field} entry to be a non-empty string.`, `${path}.${field}[${index}]`));
105
+ return;
106
+ }
107
+ strings.push(text);
108
+ });
109
+ return strings;
110
+ }
111
+ function enumArrayField(record, field, allowed, defaultValue, path, diagnostics) {
112
+ const value = record[field];
113
+ if (value === void 0) return defaultValue;
114
+ if (!Array.isArray(value)) {
115
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_array", `Expected ${field} to be an array.`, `${path}.${field}`));
116
+ return defaultValue;
117
+ }
118
+ const result = [];
119
+ value.forEach((entry, index) => {
120
+ const text = asString(entry);
121
+ if (!allowed.includes(text)) {
122
+ diagnostics.push(sceneErrorDiagnostic("scene.training_invalid_config", `Unsupported ${field} entry: ${text}.`, `${path}.${field}[${index}]`));
123
+ return;
124
+ }
125
+ result.push(text);
126
+ });
127
+ return result.length > 0 ? [...new Set(result)] : defaultValue;
128
+ }
129
+ function parseEnvironment(value, path, diagnostics, defaultValue) {
130
+ const environment = asString(value) || defaultValue;
131
+ if (!TREESEED_SCENE_ENVIRONMENTS.includes(environment)) {
132
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_environment", `Unknown environment: ${environment}.`, path));
133
+ return defaultValue;
134
+ }
135
+ return environment;
136
+ }
137
+ function parseBrowser(value, path, diagnostics) {
138
+ const browser = asString(value) || "chromium";
139
+ if (!TREESEED_SCENE_BROWSERS.includes(browser)) {
140
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_browser", `Unknown browser: ${browser}.`, path));
141
+ return "chromium";
142
+ }
143
+ return browser;
144
+ }
145
+ function parseSelector(value, path, diagnostics) {
146
+ if (!isRecord(value)) {
147
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_selector", "Expected selector to be an object.", path));
148
+ return null;
149
+ }
150
+ const keys = ["scene", "testId", "role", "text", "css"].filter((key) => value[key] !== void 0);
151
+ if (keys.length !== 1) {
152
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_selector", "Expected selector to define exactly one of scene, testId, role, text, or css.", path));
153
+ return null;
154
+ }
155
+ if (value.scene !== void 0) return { scene: requireString(value, "scene", path, diagnostics) };
156
+ if (value.testId !== void 0) return { testId: requireString(value, "testId", path, diagnostics) };
157
+ if (value.role !== void 0) return { role: requireString(value, "role", path, diagnostics), ...optionalString(value, "name") ? { name: optionalString(value, "name") } : {} };
158
+ if (value.text !== void 0) return { text: requireString(value, "text", path, diagnostics) };
159
+ const css = requireString(value, "css", path, diagnostics);
160
+ const brittle = booleanField(value, "brittle", false, path, diagnostics);
161
+ const internal = booleanField(value, "internal", false, path, diagnostics);
162
+ if (!brittle && !internal) {
163
+ diagnostics.push(sceneWarningDiagnostic("scene.raw_css_selector", "CSS selector should be marked brittle or internal.", `${path}.css`));
164
+ }
165
+ return { css, ...brittle ? { brittle } : {}, ...internal ? { internal } : {} };
166
+ }
167
+ function parseAction(value, path, diagnostics) {
168
+ if (!isRecord(value)) {
169
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_action", "Expected action to be an object.", path));
170
+ return null;
171
+ }
172
+ const keys = Object.keys(value).filter((key2) => value[key2] !== void 0);
173
+ const supported = keys.filter((key2) => findBuiltInTreeseedSceneAction(key2));
174
+ if (keys.length !== 1 || supported.length !== 1) {
175
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_action", `Expected exactly one supported action key. Supported actions: goto, click, fill, select, keyboard, pause, mailpitConfirmLatest, apiRequest, waitForOperation.`, path));
176
+ return null;
177
+ }
178
+ const key = supported[0];
179
+ if (key === "goto") return { goto: asString(value.goto) || "" };
180
+ if (key === "keyboard") return { keyboard: asString(value.keyboard) || "" };
181
+ if (key === "apiRequest") return { apiRequest: isRecord(value.apiRequest) ? value.apiRequest : {} };
182
+ if (key === "waitForOperation") {
183
+ const operation = isRecord(value.waitForOperation) ? value.waitForOperation : {};
184
+ const status = stringArrayField(operation, "status", `${path}.waitForOperation`, diagnostics);
185
+ return {
186
+ waitForOperation: {
187
+ ...optionalString(operation, "id") ? { id: optionalString(operation, "id") } : {},
188
+ ...optionalString(operation, "kind") ? { kind: optionalString(operation, "kind") } : {},
189
+ status,
190
+ timeoutSeconds: positiveNumberField(operation, "timeoutSeconds", void 0, `${path}.waitForOperation`, diagnostics),
191
+ pollIntervalSeconds: positiveNumberField(operation, "pollIntervalSeconds", void 0, `${path}.waitForOperation`, diagnostics),
192
+ ...asString(operation.source) ? { source: asString(operation.source) } : {}
193
+ }
194
+ };
195
+ }
196
+ if (key === "pause") {
197
+ const pause = isRecord(value.pause) ? value.pause : {};
198
+ const mode = asString(pause.mode) === "timed" ? "timed" : "manual";
199
+ const durationSeconds = positiveNumberField(pause, "durationSeconds", void 0, `${path}.pause`, diagnostics);
200
+ if (mode === "timed" && durationSeconds === void 0) diagnostics.push(sceneErrorDiagnostic("scene.missing_field", "Timed pause actions must define durationSeconds.", `${path}.pause.durationSeconds`));
201
+ return { pause: { mode, ...optionalString(pause, "prompt") ? { prompt: optionalString(pause, "prompt") } : {}, ...durationSeconds ? { durationSeconds } : {} } };
202
+ }
203
+ if (key === "mailpitConfirmLatest") {
204
+ const spec = isRecord(value.mailpitConfirmLatest) ? value.mailpitConfirmLatest : {};
205
+ return {
206
+ mailpitConfirmLatest: {
207
+ mailpitUrl: requireString(spec, "mailpitUrl", `${path}.mailpitConfirmLatest`, diagnostics),
208
+ email: requireString(spec, "email", `${path}.mailpitConfirmLatest`, diagnostics),
209
+ ...optionalString(spec, "subjectIncludes") ? { subjectIncludes: optionalString(spec, "subjectIncludes") } : {},
210
+ ...spec.displayInboxSeconds !== void 0 ? { displayInboxSeconds: positiveNumberField(spec, "displayInboxSeconds", void 0, `${path}.mailpitConfirmLatest`, diagnostics) } : {},
211
+ ...spec.displayMessageSeconds !== void 0 ? { displayMessageSeconds: positiveNumberField(spec, "displayMessageSeconds", void 0, `${path}.mailpitConfirmLatest`, diagnostics) } : {}
212
+ }
213
+ };
214
+ }
215
+ if (key === "click") {
216
+ const selector2 = parseSelector(value.click, `${path}.click`, diagnostics);
217
+ return selector2 ? { click: selector2 } : null;
218
+ }
219
+ if (key === "select") {
220
+ const selectValue = isRecord(value.select) ? value.select : {};
221
+ const selector2 = parseSelector(selectValue, `${path}.select`, diagnostics);
222
+ const optionValue = asString(selectValue.value);
223
+ const optionLabel = asString(selectValue.label);
224
+ if (!optionValue && !optionLabel) diagnostics.push(sceneErrorDiagnostic("scene.missing_field", "Select actions must define value or label.", `${path}.select.value`));
225
+ return selector2 ? { select: { ...selector2, ...optionValue ? { value: optionValue } : {}, ...optionLabel ? { label: optionLabel } : {} } } : null;
226
+ }
227
+ const fillValue = isRecord(value.fill) ? value.fill : {};
228
+ const selector = parseSelector(fillValue, `${path}.fill`, diagnostics);
229
+ const fillText = asString(fillValue.value);
230
+ if (!fillText) diagnostics.push(sceneErrorDiagnostic("scene.missing_field", "Missing required field: value.", `${path}.fill.value`));
231
+ return selector ? { fill: { ...selector, value: fillText } } : null;
232
+ }
233
+ function parseExpectation(value, path, diagnostics) {
234
+ if (value === void 0) return void 0;
235
+ if (!isRecord(value)) {
236
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_expectation", "Expected expect to be an object.", path));
237
+ return void 0;
238
+ }
239
+ const expectation = {};
240
+ for (const key of Object.keys(value)) {
241
+ if (!findBuiltInTreeseedSceneAssertion(key)) {
242
+ diagnostics.push(sceneWarningDiagnostic("scene.unknown_expectation", `Unknown expectation key: ${key}.`, `${path}.${key}`));
243
+ }
244
+ }
245
+ if (value.visible !== void 0) {
246
+ const visible = arrayField(value, "visible", path, diagnostics) ?? [];
247
+ expectation.visible = visible.map((entry, index) => parseSelector(entry, `${path}.visible[${index}]`, diagnostics)).filter((entry) => Boolean(entry));
248
+ }
249
+ if (value.text !== void 0) expectation.text = asString(value.text);
250
+ if (value.urlIncludes !== void 0) expectation.urlIncludes = asString(value.urlIncludes);
251
+ if (value.operation !== void 0) {
252
+ if (!isRecord(value.operation)) {
253
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_operation_expectation", "Expected operation expectation to be an object.", `${path}.operation`));
254
+ } else {
255
+ expectation.operation = {
256
+ ...optionalString(value.operation, "id") ? { id: optionalString(value.operation, "id") } : {},
257
+ kind: requireString(value.operation, "kind", `${path}.operation`, diagnostics),
258
+ status: stringArrayField(value.operation, "status", `${path}.operation`, diagnostics),
259
+ timeoutSeconds: positiveNumberField(value.operation, "timeoutSeconds", void 0, `${path}.operation`, diagnostics),
260
+ pollIntervalSeconds: positiveNumberField(value.operation, "pollIntervalSeconds", void 0, `${path}.operation`, diagnostics),
261
+ ...asString(value.operation.source) ? { source: asString(value.operation.source) } : {}
262
+ };
263
+ }
264
+ }
265
+ return expectation;
266
+ }
267
+ function expectationKeys(expectation) {
268
+ if (!expectation) return [];
269
+ return ["visible", "text", "urlIncludes", "operation"].filter((key) => expectation[key] !== void 0);
270
+ }
271
+ function actionCanOmitExpectation(action) {
272
+ return Boolean(action && ("fill" in action || "select" in action || "keyboard" in action));
273
+ }
274
+ function parseMode(value, diagnostics) {
275
+ const record = isRecord(value) ? value : {};
276
+ return {
277
+ test: booleanField(record, "test", true, "mode", diagnostics),
278
+ demo: booleanField(record, "demo", false, "mode", diagnostics),
279
+ training: booleanField(record, "training", false, "mode", diagnostics)
280
+ };
281
+ }
282
+ function parseTarget(value, diagnostics) {
283
+ const record = isRecord(value) ? value : {};
284
+ if (!isRecord(value)) diagnostics.push(sceneErrorDiagnostic("scene.missing_field", "Missing required field: target.", "target"));
285
+ const viewport = isRecord(record.viewport) ? record.viewport : {};
286
+ return {
287
+ app: requireString(record, "app", "target", diagnostics),
288
+ environment: parseEnvironment(record.environment, "target.environment", diagnostics, "local"),
289
+ baseUrl: asString(record.baseUrl) || "auto",
290
+ viewport: {
291
+ width: positiveNumberField(viewport, "width", 1440, "target.viewport", diagnostics) ?? 1440,
292
+ height: positiveNumberField(viewport, "height", 1e3, "target.viewport", diagnostics) ?? 1e3
293
+ },
294
+ browser: parseBrowser(record.browser, "target.browser", diagnostics)
295
+ };
296
+ }
297
+ function parseDimensionPair(value, path, diagnostics, defaults) {
298
+ const record = isRecord(value) ? value : {};
299
+ if (value !== void 0 && !isRecord(value)) diagnostics.push(sceneErrorDiagnostic("scene.invalid_object", `Expected ${path} to be an object.`, path));
300
+ return {
301
+ width: positiveNumberField(record, "width", defaults.width, path, diagnostics) ?? defaults.width,
302
+ height: positiveNumberField(record, "height", defaults.height, path, diagnostics) ?? defaults.height
303
+ };
304
+ }
305
+ function defaultTreeseedSceneDeviceConfig() {
306
+ return {
307
+ defaultProfile: "desktop",
308
+ profiles: [
309
+ {
310
+ id: "desktop",
311
+ title: "Desktop",
312
+ orientation: "landscape",
313
+ viewport: { width: 1600, height: 900 },
314
+ video: { width: 1600, height: 900 },
315
+ output: { width: 1920, height: 1080 },
316
+ deviceScaleFactor: 1,
317
+ isMobile: false,
318
+ hasTouch: false
319
+ }
320
+ ]
321
+ };
322
+ }
323
+ function parseDevices(value, target, diagnostics) {
324
+ const defaults = defaultTreeseedSceneDeviceConfig();
325
+ if (value === void 0) return defaults;
326
+ if (!isRecord(value)) {
327
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_object", "Expected devices to be an object.", "devices"));
328
+ return defaults;
329
+ }
330
+ for (const key of Object.keys(value)) {
331
+ if (!["defaultProfile", "profiles"].includes(key)) diagnostics.push(sceneWarningDiagnostic("scene.unknown_device_field", `Unknown devices field: ${key}.`, `devices.${key}`));
332
+ }
333
+ const entries = arrayField(value, "profiles", "devices", diagnostics) ?? [];
334
+ const profiles = [];
335
+ const seen = /* @__PURE__ */ new Set();
336
+ entries.forEach((entry, index) => {
337
+ const path = `devices.profiles[${index}]`;
338
+ if (!isRecord(entry)) {
339
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_device_profile", "Expected device profile to be an object.", path));
340
+ return;
341
+ }
342
+ for (const key of Object.keys(entry)) {
343
+ if (!["id", "title", "orientation", "viewport", "video", "output", "userAgent", "deviceScaleFactor", "isMobile", "hasTouch", "browserFrame"].includes(key)) diagnostics.push(sceneWarningDiagnostic("scene.unknown_device_field", `Unknown device profile field: ${key}.`, `${path}.${key}`));
344
+ }
345
+ const id = requireString(entry, "id", path, diagnostics);
346
+ if (id && !FILESYSTEM_SAFE_SCENE_ID.test(id)) diagnostics.push(sceneErrorDiagnostic("scene.invalid_id", `Invalid device profile id: ${id}.`, `${path}.id`));
347
+ if (id && seen.has(id)) diagnostics.push(sceneErrorDiagnostic("scene.device_duplicate", `Duplicate device profile id: ${id}.`, `${path}.id`));
348
+ seen.add(id);
349
+ const orientationValue = optionalString(entry, "orientation");
350
+ const orientation = orientationValue && DEVICE_ORIENTATIONS.includes(orientationValue) ? orientationValue : void 0;
351
+ if (orientationValue && !orientation) diagnostics.push(sceneErrorDiagnostic("scene.device_orientation_invalid", `Unknown device orientation: ${orientationValue}.`, `${path}.orientation`));
352
+ const browserFrame = objectField(entry, "browserFrame", path, diagnostics);
353
+ const chromeValue = browserFrame ? optionalString(browserFrame, "chrome") : void 0;
354
+ const chrome = chromeValue && DEVICE_BROWSER_CHROME.includes(chromeValue) ? chromeValue : void 0;
355
+ if (chromeValue && !chrome) diagnostics.push(sceneErrorDiagnostic("scene.device_browser_chrome_invalid", `Unknown browser frame chrome: ${chromeValue}.`, `${path}.browserFrame.chrome`));
356
+ const profile = {
357
+ id,
358
+ ...optionalString(entry, "title") ? { title: optionalString(entry, "title") } : {},
359
+ ...orientation ? { orientation } : {},
360
+ viewport: parseDimensionPair(entry.viewport, `${path}.viewport`, diagnostics, target.viewport),
361
+ ...entry.video !== void 0 ? { video: parseDimensionPair(entry.video, `${path}.video`, diagnostics, target.viewport) } : {},
362
+ ...entry.output !== void 0 ? { output: parseDimensionPair(entry.output, `${path}.output`, diagnostics, { width: 1920, height: 1080 }) } : {},
363
+ ...optionalString(entry, "userAgent") ? { userAgent: optionalString(entry, "userAgent") } : {},
364
+ ...entry.deviceScaleFactor !== void 0 ? { deviceScaleFactor: positiveNumberField(entry, "deviceScaleFactor", 1, path, diagnostics) ?? 1 } : {},
365
+ ...entry.isMobile !== void 0 ? { isMobile: booleanField(entry, "isMobile", false, path, diagnostics) } : {},
366
+ ...entry.hasTouch !== void 0 ? { hasTouch: booleanField(entry, "hasTouch", false, path, diagnostics) } : {},
367
+ ...browserFrame ? { browserFrame: { enabled: booleanField(browserFrame, "enabled", false, `${path}.browserFrame`, diagnostics), ...optionalString(browserFrame, "title") ? { title: optionalString(browserFrame, "title") } : {}, ...chrome ? { chrome } : {} } } : {}
368
+ };
369
+ profiles.push(profile);
370
+ });
371
+ if (profiles.length === 0) return defaults;
372
+ const defaultProfile = optionalString(value, "defaultProfile") ?? profiles[0].id;
373
+ if (!profiles.some((profile) => profile.id === defaultProfile)) diagnostics.push(sceneErrorDiagnostic("scene.device_unknown", `Default device profile not found: ${defaultProfile}.`, "devices.defaultProfile"));
374
+ return { defaultProfile, profiles };
375
+ }
376
+ function parseSetup(value, targetEnvironment, diagnostics) {
377
+ const record = isRecord(value) ? value : {};
378
+ const setup = {};
379
+ const dev = objectField(record, "dev", "setup", diagnostics);
380
+ if (dev) setup.dev = { required: booleanField(dev, "required", false, "setup.dev", diagnostics), command: optionalString(dev, "command"), reuseExisting: booleanField(dev, "reuseExisting", true, "setup.dev", diagnostics) };
381
+ const auth = objectField(record, "auth", "setup", diagnostics);
382
+ if (auth) setup.auth = { profile: optionalString(auth, "profile"), required: booleanField(auth, "required", false, "setup.auth", diagnostics), ...optionalString(auth, "role") ? { role: optionalString(auth, "role") } : {} };
383
+ const seed = objectField(record, "seed", "setup", diagnostics);
384
+ if (seed) {
385
+ const environments = (arrayField(seed, "environments", "setup.seed", diagnostics) ?? [targetEnvironment]).map((entry, index) => parseEnvironment(entry, `setup.seed.environments[${index}]`, diagnostics, targetEnvironment));
386
+ setup.seed = { name: optionalString(seed, "name"), environments: [...new Set(environments)], apply: booleanField(seed, "apply", false, "setup.seed", diagnostics) };
387
+ }
388
+ return setup;
389
+ }
390
+ function parseArtifacts(value, diagnostics) {
391
+ const record = isRecord(value) ? value : {};
392
+ return {
393
+ trace: booleanField(record, "trace", true, "artifacts", diagnostics),
394
+ video: booleanField(record, "video", false, "artifacts", diagnostics),
395
+ screenshots: booleanField(record, "screenshots", true, "artifacts", diagnostics),
396
+ console: booleanField(record, "console", true, "artifacts", diagnostics),
397
+ network: booleanField(record, "network", true, "artifacts", diagnostics),
398
+ timeline: booleanField(record, "timeline", true, "artifacts", diagnostics),
399
+ appLogs: booleanField(record, "appLogs", true, "artifacts", diagnostics)
400
+ };
401
+ }
402
+ function parseWorkflow(value, diagnostics) {
403
+ if (!Array.isArray(value)) {
404
+ diagnostics.push(sceneErrorDiagnostic("scene.missing_field", "Missing required field: workflow.", "workflow"));
405
+ return [];
406
+ }
407
+ const steps = [];
408
+ const seen = /* @__PURE__ */ new Set();
409
+ const checkpointIds = /* @__PURE__ */ new Set();
410
+ value.forEach((entry, index) => {
411
+ const path = `workflow[${index}]`;
412
+ if (!isRecord(entry)) {
413
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_workflow_step", "Expected workflow step to be an object.", path));
414
+ return;
415
+ }
416
+ const id = requireString(entry, "id", path, diagnostics);
417
+ if (id && !FILESYSTEM_SAFE_SCENE_ID.test(id)) diagnostics.push(sceneErrorDiagnostic("scene.invalid_id", `Invalid workflow step id: ${id}.`, `${path}.id`));
418
+ if (id && seen.has(id)) diagnostics.push(sceneErrorDiagnostic("scene.duplicate_step_id", `Duplicate workflow step id: ${id}.`, `${path}.id`));
419
+ seen.add(id);
420
+ const action = parseAction(entry.action, `${path}.action`, diagnostics);
421
+ const expect = parseExpectation(entry.expect, `${path}.expect`, diagnostics);
422
+ const demoOnly = booleanField(entry, "demoOnly", false, path, diagnostics);
423
+ const timeoutSeconds = positiveNumberField(entry, "timeoutSeconds", void 0, path, diagnostics);
424
+ const continueOnFailure = entry.continueOnFailure === void 0 ? void 0 : booleanField(entry, "continueOnFailure", false, path, diagnostics);
425
+ const checkpointRecord = objectField(entry, "checkpoint", path, diagnostics);
426
+ const checkpoint = checkpointRecord ? {
427
+ ...optionalString(checkpointRecord, "id") ? { id: optionalString(checkpointRecord, "id") } : {},
428
+ ...checkpointRecord.resumable === void 0 ? {} : { resumable: booleanField(checkpointRecord, "resumable", false, `${path}.checkpoint`, diagnostics) }
429
+ } : void 0;
430
+ const checkpointId = checkpoint?.id ?? id;
431
+ if (checkpoint?.id && !FILESYSTEM_SAFE_CHECKPOINT_ID.test(checkpoint.id)) diagnostics.push(sceneErrorDiagnostic("scene.invalid_id", `Invalid checkpoint id: ${checkpoint.id}.`, `${path}.checkpoint.id`));
432
+ if (checkpointIds.has(checkpointId)) diagnostics.push(sceneErrorDiagnostic("scene.duplicate_checkpoint_id", `Duplicate checkpoint id: ${checkpointId}.`, `${path}.checkpoint.id`));
433
+ checkpointIds.add(checkpointId);
434
+ if ("pause" in (action ?? {}) && action.pause?.mode === "manual" && !demoOnly && !expectationKeys(expect).length) {
435
+ diagnostics.push(sceneErrorDiagnostic("scene.manual_pause_requires_demo_only", "Manual pause steps must be demoOnly or define explicit expectations.", path));
436
+ }
437
+ if (!expectationKeys(expect).length && !demoOnly && !actionCanOmitExpectation(action)) diagnostics.push(sceneErrorDiagnostic("scene.missing_assertion", "Workflow step must define expect or set demoOnly: true.", path));
438
+ if (action) steps.push({
439
+ id,
440
+ title: requireString(entry, "title", path, diagnostics),
441
+ action,
442
+ ...expect ? { expect } : {},
443
+ demoOnly,
444
+ ...timeoutSeconds ? { timeoutSeconds } : {},
445
+ ...continueOnFailure !== void 0 ? { continueOnFailure } : {},
446
+ ...checkpoint ? { checkpoint } : {}
447
+ });
448
+ });
449
+ return steps;
450
+ }
451
+ function parseChapters(value, stepIds, diagnostics) {
452
+ const chapters = [];
453
+ const entries = Array.isArray(value) ? value : [];
454
+ entries.forEach((entry, index) => {
455
+ const path = `chapters[${index}]`;
456
+ if (!isRecord(entry)) {
457
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_chapter", "Expected chapter to be an object.", path));
458
+ return;
459
+ }
460
+ const id = requireString(entry, "id", path, diagnostics);
461
+ const startsAt = requireString(entry, "startsAt", path, diagnostics);
462
+ if (id && !FILESYSTEM_SAFE_SCENE_ID.test(id)) diagnostics.push(sceneErrorDiagnostic("scene.invalid_id", `Invalid chapter id: ${id}.`, `${path}.id`));
463
+ if (startsAt && !stepIds.has(startsAt)) diagnostics.push(sceneErrorDiagnostic("scene.unknown_step_reference", `Unknown workflow step reference: ${startsAt}.`, `${path}.startsAt`));
464
+ chapters.push({ id, title: requireString(entry, "title", path, diagnostics), startsAt });
465
+ });
466
+ return chapters;
467
+ }
468
+ function enumValue(value, allowed, defaultValue, path, code, diagnostics) {
469
+ const text = asString(value);
470
+ if (!text) return defaultValue;
471
+ if (allowed.includes(text)) return text;
472
+ diagnostics.push(sceneErrorDiagnostic(code, `Unsupported value: ${text}.`, path));
473
+ return defaultValue;
474
+ }
475
+ function parseVisualPoint(value, path, diagnostics) {
476
+ if (value === void 0) return void 0;
477
+ if (!isRecord(value)) {
478
+ diagnostics.push(sceneErrorDiagnostic("scene.visual_invalid_point", "Expected visual point to be an object.", path));
479
+ return void 0;
480
+ }
481
+ const unit = enumValue(value.unit, VISUAL_UNITS, "px", `${path}.unit`, "scene.visual_invalid_unit", diagnostics);
482
+ const x = typeof value.x === "number" && Number.isFinite(value.x) ? value.x : null;
483
+ const y = typeof value.y === "number" && Number.isFinite(value.y) ? value.y : null;
484
+ if (x === null) diagnostics.push(sceneErrorDiagnostic("scene.visual_invalid_point", "Expected x to be a finite number.", `${path}.x`));
485
+ if (y === null) diagnostics.push(sceneErrorDiagnostic("scene.visual_invalid_point", "Expected y to be a finite number.", `${path}.y`));
486
+ if (unit === "percent") {
487
+ if (typeof x === "number" && (x < 0 || x > 100)) diagnostics.push(sceneWarningDiagnostic("scene.visual_percent_out_of_range", "Percent x is outside 0..100.", `${path}.x`));
488
+ if (typeof y === "number" && (y < 0 || y > 100)) diagnostics.push(sceneWarningDiagnostic("scene.visual_percent_out_of_range", "Percent y is outside 0..100.", `${path}.y`));
489
+ }
490
+ if (x === null || y === null) return void 0;
491
+ return { x, y, ...unit ? { unit } : {} };
492
+ }
493
+ function parseVisualSize(value, path, diagnostics) {
494
+ if (value === void 0) return void 0;
495
+ if (!isRecord(value)) {
496
+ diagnostics.push(sceneErrorDiagnostic("scene.visual_invalid_size", "Expected visual size to be an object.", path));
497
+ return void 0;
498
+ }
499
+ const unit = enumValue(value.unit, VISUAL_UNITS, "px", `${path}.unit`, "scene.visual_invalid_unit", diagnostics);
500
+ const width = typeof value.width === "number" && Number.isFinite(value.width) && value.width > 0 ? value.width : null;
501
+ const height = typeof value.height === "number" && Number.isFinite(value.height) && value.height > 0 ? value.height : null;
502
+ if (width === null) diagnostics.push(sceneErrorDiagnostic("scene.visual_invalid_size", "Expected width to be a positive finite number.", `${path}.width`));
503
+ if (height === null) diagnostics.push(sceneErrorDiagnostic("scene.visual_invalid_size", "Expected height to be a positive finite number.", `${path}.height`));
504
+ if (unit === "percent") {
505
+ if (typeof width === "number" && width > 100) diagnostics.push(sceneWarningDiagnostic("scene.visual_percent_out_of_range", "Percent width is greater than 100.", `${path}.width`));
506
+ if (typeof height === "number" && height > 100) diagnostics.push(sceneWarningDiagnostic("scene.visual_percent_out_of_range", "Percent height is greater than 100.", `${path}.height`));
507
+ }
508
+ if (width === null || height === null) return void 0;
509
+ return { width, height, ...unit ? { unit } : {} };
510
+ }
511
+ function parseVisualStyle(value, path, diagnostics) {
512
+ if (value === void 0) return void 0;
513
+ if (!isRecord(value)) {
514
+ diagnostics.push(sceneErrorDiagnostic("scene.visual_invalid_style", "Expected visual style to be an object.", path));
515
+ return void 0;
516
+ }
517
+ for (const key of Object.keys(value)) {
518
+ if (!["tone", "background", "color", "borderColor", "borderWidth", "radius", "shadow", "opacity"].includes(key)) diagnostics.push(sceneWarningDiagnostic("scene.visual_unknown_style_field", `Unknown visual style field: ${key}.`, `${path}.${key}`));
519
+ }
520
+ const opacity = value.opacity === void 0 ? void 0 : finiteNumberField(value, "opacity", void 0, path, diagnostics);
521
+ if (opacity !== void 0 && opacity > 1) diagnostics.push(sceneErrorDiagnostic("scene.visual_invalid_opacity", "Opacity must be between 0 and 1.", `${path}.opacity`));
522
+ const tone = enumValue(value.tone, VISUAL_TONES, void 0, `${path}.tone`, "scene.visual_invalid_tone", diagnostics);
523
+ const shadow = enumValue(value.shadow, VISUAL_SHADOWS, void 0, `${path}.shadow`, "scene.visual_invalid_shadow", diagnostics);
524
+ return {
525
+ ...tone ? { tone } : {},
526
+ ...optionalString(value, "background") ? { background: optionalString(value, "background") } : {},
527
+ ...optionalString(value, "color") ? { color: optionalString(value, "color") } : {},
528
+ ...optionalString(value, "borderColor") ? { borderColor: optionalString(value, "borderColor") } : {},
529
+ ...value.borderWidth !== void 0 ? { borderWidth: positiveNumberField(value, "borderWidth", void 0, path, diagnostics) ?? 0 } : {},
530
+ ...value.radius !== void 0 ? { radius: positiveNumberField(value, "radius", void 0, path, diagnostics) ?? 0 } : {},
531
+ ...shadow ? { shadow } : {},
532
+ ...opacity !== void 0 ? { opacity } : {}
533
+ };
534
+ }
535
+ function parseMotion(value, path, diagnostics) {
536
+ if (value === void 0) return void 0;
537
+ if (!isRecord(value)) {
538
+ diagnostics.push(sceneErrorDiagnostic("scene.motion_invalid", "Expected motion to be an object.", path));
539
+ return void 0;
540
+ }
541
+ const entries = arrayField(value, "keyframes", path, diagnostics) ?? [];
542
+ let previous = -Infinity;
543
+ const keyframes = entries.map((entry, index) => {
544
+ const framePath = `${path}.keyframes[${index}]`;
545
+ if (!isRecord(entry)) {
546
+ diagnostics.push(sceneErrorDiagnostic("scene.motion_invalid_keyframe", "Expected keyframe to be an object.", framePath));
547
+ return null;
548
+ }
549
+ const at = typeof entry.at === "number" && Number.isFinite(entry.at) ? entry.at : null;
550
+ if (at === null) diagnostics.push(sceneErrorDiagnostic("scene.motion_invalid_keyframe", "Expected at to be a finite number.", `${framePath}.at`));
551
+ if (at !== null && at < previous) diagnostics.push(sceneErrorDiagnostic("scene.motion_keyframes_unsorted", "Motion keyframes must be sorted by at.", `${framePath}.at`));
552
+ if (at !== null) previous = at;
553
+ const unit = enumValue(entry.unit, MOTION_UNITS, "seconds", `${framePath}.unit`, "scene.motion_invalid_unit", diagnostics);
554
+ if (unit === "progress" && at !== null && (at < 0 || at > 1)) diagnostics.push(sceneErrorDiagnostic("scene.motion_invalid_progress", "Progress keyframes must use at between 0 and 1.", `${framePath}.at`));
555
+ const opacity = entry.opacity === void 0 ? void 0 : finiteNumberField(entry, "opacity", void 0, framePath, diagnostics);
556
+ if (opacity !== void 0 && opacity > 1) diagnostics.push(sceneErrorDiagnostic("scene.visual_invalid_opacity", "Opacity must be between 0 and 1.", `${framePath}.opacity`));
557
+ const scale = entry.scale === void 0 ? void 0 : positiveNumberField(entry, "scale", void 0, framePath, diagnostics);
558
+ if (at === null) return null;
559
+ const position = parseVisualPoint(entry.position, `${framePath}.position`, diagnostics);
560
+ const size = parseVisualSize(entry.size, `${framePath}.size`, diagnostics);
561
+ const motionEasing = enumValue(entry.easing, MOTION_EASINGS, void 0, `${framePath}.easing`, "scene.motion_invalid_easing", diagnostics);
562
+ return {
563
+ at,
564
+ ...unit ? { unit } : {},
565
+ ...position ? { position } : {},
566
+ ...size ? { size } : {},
567
+ ...opacity !== void 0 ? { opacity } : {},
568
+ ...scale !== void 0 ? { scale } : {},
569
+ ...typeof entry.rotateDeg === "number" && Number.isFinite(entry.rotateDeg) ? { rotateDeg: entry.rotateDeg } : {},
570
+ ...motionEasing ? { easing: motionEasing } : {}
571
+ };
572
+ }).filter((entry) => Boolean(entry));
573
+ if (keyframes.length === 0) diagnostics.push(sceneErrorDiagnostic("scene.motion_invalid", "Motion must define at least one keyframe.", `${path}.keyframes`));
574
+ return { keyframes, ...value.loop !== void 0 ? { loop: booleanField(value, "loop", false, path, diagnostics) } : {} };
575
+ }
576
+ function parseVisualObjects(value, path, diagnostics) {
577
+ if (value === void 0) return void 0;
578
+ const entries = arrayField({ objects: value }, "objects", path.replace(/\.objects$/u, ""), diagnostics) ?? [];
579
+ const objects = [];
580
+ const seen = /* @__PURE__ */ new Set();
581
+ entries.forEach((entry, index) => {
582
+ const objectPath = `${path}[${index}]`;
583
+ if (!isRecord(entry)) {
584
+ diagnostics.push(sceneErrorDiagnostic("scene.visual_invalid_object", "Expected visual object to be an object.", objectPath));
585
+ return;
586
+ }
587
+ const id = requireString(entry, "id", objectPath, diagnostics);
588
+ if (id && seen.has(id)) diagnostics.push(sceneErrorDiagnostic("scene.visual_duplicate_object", `Duplicate visual object id: ${id}.`, `${objectPath}.id`));
589
+ seen.add(id);
590
+ const type = enumValue(entry.type, VISUAL_OBJECT_TYPES, void 0, `${objectPath}.type`, "scene.visual_invalid_object_type", diagnostics);
591
+ if (!type) return;
592
+ const region = enumValue(entry.region, VISUAL_REGIONS, void 0, `${objectPath}.region`, "scene.visual_invalid_region", diagnostics);
593
+ const position = parseVisualPoint(entry.position, `${objectPath}.position`, diagnostics);
594
+ const size = parseVisualSize(entry.size, `${objectPath}.size`, diagnostics);
595
+ const style = parseVisualStyle(entry.style, `${objectPath}.style`, diagnostics);
596
+ const motion = parseMotion(entry.motion, `${objectPath}.motion`, diagnostics);
597
+ const from = parseVisualPoint(entry.from, `${objectPath}.from`, diagnostics);
598
+ const to = parseVisualPoint(entry.to, `${objectPath}.to`, diagnostics);
599
+ objects.push({
600
+ id,
601
+ type,
602
+ ...optionalString(entry, "text") ? { text: optionalString(entry, "text") } : {},
603
+ ...position ? { position } : {},
604
+ ...size ? { size } : {},
605
+ ...region ? { region } : {},
606
+ ...style ? { style } : {},
607
+ ...motion ? { motion } : {},
608
+ ...from ? { from } : {},
609
+ ...to ? { to } : {}
610
+ });
611
+ });
612
+ return objects;
613
+ }
614
+ function parseOverlays(value, stepIds, diagnostics) {
615
+ const overlays = [];
616
+ const entries = Array.isArray(value) ? value : [];
617
+ entries.forEach((entry, index) => {
618
+ const path = `overlays[${index}]`;
619
+ if (!isRecord(entry)) {
620
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_overlay", "Expected overlay to be an object.", path));
621
+ return;
622
+ }
623
+ const id = requireString(entry, "id", path, diagnostics);
624
+ const at = requireString(entry, "at", path, diagnostics);
625
+ if (id && !FILESYSTEM_SAFE_SCENE_ID.test(id)) diagnostics.push(sceneErrorDiagnostic("scene.invalid_id", `Invalid overlay id: ${id}.`, `${path}.id`));
626
+ if (at && !stepIds.has(at)) diagnostics.push(sceneErrorDiagnostic("scene.unknown_step_reference", `Unknown workflow step reference: ${at}.`, `${path}.at`));
627
+ const anchor = entry.anchor === void 0 ? null : parseSelector(entry.anchor, `${path}.anchor`, diagnostics);
628
+ const variant = enumValue(entry.variant, OVERLAY_VARIANTS, void 0, `${path}.variant`, "scene.overlay_invalid_variant", diagnostics);
629
+ const region = enumValue(entry.region, VISUAL_REGIONS, void 0, `${path}.region`, "scene.visual_invalid_region", diagnostics);
630
+ const position = parseVisualPoint(entry.position, `${path}.position`, diagnostics);
631
+ const size = parseVisualSize(entry.size, `${path}.size`, diagnostics);
632
+ const style = parseVisualStyle(entry.style, `${path}.style`, diagnostics);
633
+ const motion = parseMotion(entry.motion, `${path}.motion`, diagnostics);
634
+ const objects = parseVisualObjects(entry.objects, `${path}.objects`, diagnostics);
635
+ overlays.push({
636
+ id,
637
+ at,
638
+ renderer: requireString(entry, "renderer", path, diagnostics),
639
+ type: requireString(entry, "type", path, diagnostics),
640
+ ...optionalString(entry, "text") ? { text: optionalString(entry, "text") } : {},
641
+ ...anchor ? { anchor } : {},
642
+ ...variant ? { variant } : {},
643
+ ...region ? { region } : {},
644
+ ...position ? { position } : {},
645
+ ...size ? { size } : {},
646
+ ...style ? { style } : {},
647
+ ...motion ? { motion } : {},
648
+ ...objects ? { objects } : {},
649
+ ...entry.durationSeconds !== void 0 ? { durationSeconds: positiveNumberField(entry, "durationSeconds", void 0, path, diagnostics) } : {}
650
+ });
651
+ });
652
+ return overlays;
653
+ }
654
+ function parseDiagrams(value, stepIds, diagnostics) {
655
+ const diagrams = [];
656
+ const entries = Array.isArray(value) ? value : [];
657
+ entries.forEach((entry, index) => {
658
+ const path = `diagrams[${index}]`;
659
+ if (!isRecord(entry)) {
660
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_diagram", "Expected diagram to be an object.", path));
661
+ return;
662
+ }
663
+ const id = requireString(entry, "id", path, diagnostics);
664
+ const at = requireString(entry, "at", path, diagnostics);
665
+ if (id && !FILESYSTEM_SAFE_SCENE_ID.test(id)) diagnostics.push(sceneErrorDiagnostic("scene.invalid_id", `Invalid diagram id: ${id}.`, `${path}.id`));
666
+ if (at && !stepIds.has(at)) diagnostics.push(sceneErrorDiagnostic("scene.unknown_step_reference", `Unknown workflow step reference: ${at}.`, `${path}.at`));
667
+ const placementValue = optionalString(entry, "placement") ?? "interstitial";
668
+ const placement = DIAGRAM_PLACEMENTS.includes(placementValue) ? placementValue : "interstitial";
669
+ if (placementValue && placementValue !== placement) diagnostics.push(sceneErrorDiagnostic("scene.diagram_invalid_placement", `Unknown diagram placement: ${placementValue}.`, `${path}.placement`));
670
+ const objects = parseVisualObjects(entry.objects, `${path}.objects`, diagnostics);
671
+ const motion = parseMotion(entry.motion, `${path}.motion`, diagnostics);
672
+ const style = parseVisualStyle(entry.style, `${path}.style`, diagnostics);
673
+ diagrams.push({
674
+ id,
675
+ at,
676
+ renderer: requireString(entry, "renderer", path, diagnostics),
677
+ component: requireString(entry, "component", path, diagnostics),
678
+ durationSeconds: positiveNumberField(entry, "durationSeconds", void 0, path, diagnostics),
679
+ placement,
680
+ props: objectField(entry, "props", path, diagnostics),
681
+ ...objects ? { objects } : {},
682
+ ...motion ? { motion } : {},
683
+ ...style ? { style } : {}
684
+ });
685
+ });
686
+ return diagrams;
687
+ }
688
+ function parseRender(value, diagnostics) {
689
+ const record = isRecord(value) ? value : {};
690
+ const remotion = objectField(record, "remotion", "render", diagnostics);
691
+ if (!remotion) return {};
692
+ const output = objectField(remotion, "output", "render.remotion", diagnostics);
693
+ const resolution = output ? objectField(output, "resolution", "render.remotion.output", diagnostics) : void 0;
694
+ const capture = objectField(remotion, "capture", "render.remotion", diagnostics);
695
+ const captureViewport = capture ? objectField(capture, "viewport", "render.remotion.capture", diagnostics) : void 0;
696
+ const captureVideo = capture ? objectField(capture, "video", "render.remotion.capture", diagnostics) : void 0;
697
+ const evidenceFitValue = capture ? optionalString(capture, "evidenceFit") ?? "fixed-browser" : "fixed-browser";
698
+ const evidenceFit = EVIDENCE_FITS.includes(evidenceFitValue) ? evidenceFitValue : "fixed-browser";
699
+ if (capture && evidenceFitValue !== evidenceFit) diagnostics.push(sceneErrorDiagnostic("scene.render_capture_fit_invalid", `Unknown scene render evidence fit: ${evidenceFitValue}.`, "render.remotion.capture.evidenceFit"));
700
+ const browserFrame = objectField(remotion, "browserFrame", "render.remotion", diagnostics);
701
+ return {
702
+ remotion: {
703
+ composition: optionalString(remotion, "composition"),
704
+ ...output ? {
705
+ output: {
706
+ format: optionalString(output, "format"),
707
+ fps: positiveNumberField(output, "fps", void 0, "render.remotion.output", diagnostics),
708
+ ...resolution ? { resolution: { width: positiveNumberField(resolution, "width", 1920, "render.remotion.output.resolution", diagnostics) ?? 1920, height: positiveNumberField(resolution, "height", 1080, "render.remotion.output.resolution", diagnostics) ?? 1080 } } : {}
709
+ }
710
+ } : {},
711
+ ...capture ? {
712
+ capture: {
713
+ ...captureViewport ? { viewport: { width: positiveNumberField(captureViewport, "width", 1600, "render.remotion.capture.viewport", diagnostics) ?? 1600, height: positiveNumberField(captureViewport, "height", 900, "render.remotion.capture.viewport", diagnostics) ?? 900 } } : {},
714
+ ...captureVideo ? { video: { width: positiveNumberField(captureVideo, "width", 1600, "render.remotion.capture.video", diagnostics) ?? 1600, height: positiveNumberField(captureVideo, "height", 900, "render.remotion.capture.video", diagnostics) ?? 900 } } : {},
715
+ evidenceFit
716
+ }
717
+ } : {},
718
+ ...browserFrame ? {
719
+ browserFrame: {
720
+ enabled: booleanField(browserFrame, "enabled", false, "render.remotion.browserFrame", diagnostics),
721
+ ...optionalString(browserFrame, "title") ? { title: optionalString(browserFrame, "title") } : {}
722
+ }
723
+ } : {}
724
+ }
725
+ };
726
+ }
727
+ function parseRuntime(value, mode, diagnostics) {
728
+ const record = isRecord(value) ? value : {};
729
+ const modeValue = asString(record.mode);
730
+ let runtimeMode = modeValue || (mode.test ? "acceptance" : mode.training ? "training" : mode.demo ? "demo" : "acceptance");
731
+ if (!["acceptance", "demo", "training", "record-only"].includes(runtimeMode)) {
732
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_runtime_mode", `Unknown runtime mode: ${runtimeMode}.`, "runtime.mode"));
733
+ runtimeMode = "acceptance";
734
+ }
735
+ const timeouts = objectField(record, "timeouts", "runtime", diagnostics) ?? {};
736
+ const checkpoints = objectField(record, "checkpoints", "runtime", diagnostics) ?? {};
737
+ const progress = objectField(record, "progress", "runtime", diagnostics) ?? {};
738
+ const failure = objectField(record, "failure", "runtime", diagnostics) ?? {};
739
+ return {
740
+ mode: runtimeMode,
741
+ timeouts: {
742
+ sceneSeconds: nullablePositiveNumberField(timeouts, "sceneSeconds", null, "runtime.timeouts", diagnostics),
743
+ chapterSeconds: nullablePositiveNumberField(timeouts, "chapterSeconds", null, "runtime.timeouts", diagnostics),
744
+ stepSeconds: positiveNumberField(timeouts, "stepSeconds", 120, "runtime.timeouts", diagnostics) ?? 120
745
+ },
746
+ checkpoints: {
747
+ enabled: booleanField(checkpoints, "enabled", true, "runtime.checkpoints", diagnostics),
748
+ defaultResumable: booleanField(checkpoints, "defaultResumable", false, "runtime.checkpoints", diagnostics),
749
+ everyStep: booleanField(checkpoints, "everyStep", true, "runtime.checkpoints", diagnostics)
750
+ },
751
+ progress: {
752
+ heartbeatSeconds: positiveNumberField(progress, "heartbeatSeconds", 15, "runtime.progress", diagnostics) ?? 15
753
+ },
754
+ failure: {
755
+ continueOnFailure: booleanField(failure, "continueOnFailure", false, "runtime.failure", diagnostics)
756
+ }
757
+ };
758
+ }
759
+ function defaultTreeseedSceneTrainingConfig() {
760
+ return {
761
+ enabled: true,
762
+ captions: {
763
+ enabled: true,
764
+ formats: ["vtt", "srt"],
765
+ maxCueSeconds: 6,
766
+ renderInTrainingVideo: true
767
+ },
768
+ transcript: {
769
+ enabled: true,
770
+ formats: ["json", "markdown"]
771
+ },
772
+ narration: {
773
+ enabled: true,
774
+ style: "instructional",
775
+ includeDiagnostics: true
776
+ },
777
+ glossary: {
778
+ enabled: true,
779
+ terms: []
780
+ },
781
+ chapterClips: {
782
+ enabled: true,
783
+ format: "manifest"
784
+ }
785
+ };
786
+ }
787
+ function parseTraining(value, stepIds, diagnostics) {
788
+ const record = isRecord(value) ? value : {};
789
+ for (const key of Object.keys(record)) {
790
+ if (!["enabled", "captions", "transcript", "narration", "glossary", "chapterClips"].includes(key)) diagnostics.push(sceneWarningDiagnostic("scene.unknown_training_field", `Unknown training field: ${key}.`, `training.${key}`));
791
+ }
792
+ const captions = objectField(record, "captions", "training", diagnostics) ?? {};
793
+ const transcript = objectField(record, "transcript", "training", diagnostics) ?? {};
794
+ const narration = objectField(record, "narration", "training", diagnostics) ?? {};
795
+ const glossary = objectField(record, "glossary", "training", diagnostics) ?? {};
796
+ const chapterClips = objectField(record, "chapterClips", "training", diagnostics) ?? {};
797
+ const styleValue = asString(narration.style) || "instructional";
798
+ const style = NARRATION_STYLES.includes(styleValue) ? styleValue : "instructional";
799
+ if (styleValue !== style) diagnostics.push(sceneErrorDiagnostic("scene.training_invalid_config", `Unknown narration style: ${styleValue}.`, "training.narration.style"));
800
+ const terms = (arrayField(glossary, "terms", "training.glossary", diagnostics) ?? []).map((entry, index) => {
801
+ const path = `training.glossary.terms[${index}]`;
802
+ if (!isRecord(entry)) {
803
+ diagnostics.push(sceneErrorDiagnostic("scene.training_invalid_config", "Glossary term entries must be objects.", path));
804
+ return null;
805
+ }
806
+ const term = requireString(entry, "term", path, diagnostics);
807
+ const sourceStep = optionalString(entry, "sourceStep");
808
+ if (sourceStep && !stepIds.has(sourceStep)) diagnostics.push(sceneErrorDiagnostic("scene.unknown_step_reference", `Unknown workflow step reference: ${sourceStep}.`, `${path}.sourceStep`));
809
+ const tags = stringArrayField(entry, "tags", path, diagnostics);
810
+ return {
811
+ term,
812
+ ...optionalString(entry, "definition") ? { definition: optionalString(entry, "definition") } : {},
813
+ ...sourceStep ? { sourceStep } : {},
814
+ ...tags.length > 0 ? { tags } : {}
815
+ };
816
+ }).filter((entry) => Boolean(entry));
817
+ const clipFormat = asString(chapterClips.format) || "manifest";
818
+ if (clipFormat !== "manifest") diagnostics.push(sceneErrorDiagnostic("scene.training_invalid_config", `Unsupported chapter clip format: ${clipFormat}.`, "training.chapterClips.format"));
819
+ return {
820
+ enabled: booleanField(record, "enabled", true, "training", diagnostics),
821
+ captions: {
822
+ enabled: booleanField(captions, "enabled", true, "training.captions", diagnostics),
823
+ formats: enumArrayField(captions, "formats", CAPTION_FORMATS, ["vtt", "srt"], "training.captions", diagnostics),
824
+ maxCueSeconds: positiveNumberField(captions, "maxCueSeconds", 6, "training.captions", diagnostics) ?? 6,
825
+ renderInTrainingVideo: booleanField(captions, "renderInTrainingVideo", true, "training.captions", diagnostics)
826
+ },
827
+ transcript: {
828
+ enabled: booleanField(transcript, "enabled", true, "training.transcript", diagnostics),
829
+ formats: enumArrayField(transcript, "formats", TRANSCRIPT_FORMATS, ["json", "markdown"], "training.transcript", diagnostics)
830
+ },
831
+ narration: {
832
+ enabled: booleanField(narration, "enabled", true, "training.narration", diagnostics),
833
+ style,
834
+ includeDiagnostics: booleanField(narration, "includeDiagnostics", true, "training.narration", diagnostics)
835
+ },
836
+ glossary: {
837
+ enabled: booleanField(glossary, "enabled", true, "training.glossary", diagnostics),
838
+ terms
839
+ },
840
+ chapterClips: {
841
+ enabled: booleanField(chapterClips, "enabled", true, "training.chapterClips", diagnostics),
842
+ format: "manifest"
843
+ }
844
+ };
845
+ }
846
+ function defaultTreeseedSceneVisualAuditConfig() {
847
+ return {
848
+ enabled: true,
849
+ roles: ["anonymous", "owner", "admin", "member"],
850
+ pathRoots: [],
851
+ pathGlobs: [],
852
+ excludePathGlobs: [],
853
+ includeFullPage: false,
854
+ review: {
855
+ enabled: true,
856
+ detail: "standard",
857
+ maxFindings: 250,
858
+ contactSheets: true
859
+ },
860
+ routeDiscovery: {
861
+ core: true,
862
+ admin: true,
863
+ tenantOverrides: true,
864
+ contentCollections: true
865
+ }
866
+ };
867
+ }
868
+ function parseVisualAudit(value, diagnostics) {
869
+ const defaults = defaultTreeseedSceneVisualAuditConfig();
870
+ if (value === void 0) return defaults;
871
+ if (!isRecord(value)) {
872
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_object", "Expected visualAudit to be an object.", "visualAudit"));
873
+ return defaults;
874
+ }
875
+ for (const key of Object.keys(value)) {
876
+ if (!["enabled", "roles", "pathRoots", "pathGlobs", "excludePathGlobs", "includeFullPage", "review", "routeDiscovery"].includes(key)) {
877
+ diagnostics.push(sceneWarningDiagnostic("scene.visual_audit_unknown_field", `Unknown visual audit field: ${key}.`, `visualAudit.${key}`));
878
+ }
879
+ }
880
+ const roles = stringArrayField(value, "roles", "visualAudit", diagnostics);
881
+ if (value.roles !== void 0 && roles.length === 0) {
882
+ diagnostics.push(sceneErrorDiagnostic("scene.visual_audit_invalid_roles", "Visual audit roles must include at least one role.", "visualAudit.roles"));
883
+ }
884
+ const rawPathRoots = stringArrayField(value, "pathRoots", "visualAudit", diagnostics);
885
+ const pathRoots = rawPathRoots.filter((entry, index) => {
886
+ const ok = entry.startsWith("/");
887
+ if (!ok) diagnostics.push(sceneErrorDiagnostic("scene.visual_audit_invalid_path_root", `Visual audit path root must start with "/": ${entry}.`, `visualAudit.pathRoots[${index}]`));
888
+ return ok;
889
+ });
890
+ const pathGlobs = stringArrayField(value, "pathGlobs", "visualAudit", diagnostics).filter(Boolean);
891
+ const excludePathGlobs = stringArrayField(value, "excludePathGlobs", "visualAudit", diagnostics).filter(Boolean);
892
+ const routeDiscovery = objectField(value, "routeDiscovery", "visualAudit", diagnostics);
893
+ if (routeDiscovery) {
894
+ for (const key of Object.keys(routeDiscovery)) {
895
+ if (!["core", "admin", "tenantOverrides", "contentCollections"].includes(key)) {
896
+ diagnostics.push(sceneWarningDiagnostic("scene.visual_audit_unknown_field", `Unknown visual audit routeDiscovery field: ${key}.`, `visualAudit.routeDiscovery.${key}`));
897
+ }
898
+ }
899
+ }
900
+ const review = objectField(value, "review", "visualAudit", diagnostics);
901
+ if (review) {
902
+ for (const key of Object.keys(review)) {
903
+ if (!["enabled", "detail", "maxFindings", "contactSheets"].includes(key)) {
904
+ diagnostics.push(sceneWarningDiagnostic("scene.visual_audit_unknown_field", `Unknown visual audit review field: ${key}.`, `visualAudit.review.${key}`));
905
+ }
906
+ }
907
+ }
908
+ const rawReviewDetail = review && typeof review.detail === "string" ? review.detail : defaults.review.detail;
909
+ const reviewDetail = ["summary", "standard", "full"].includes(rawReviewDetail) ? rawReviewDetail : defaults.review.detail;
910
+ if (review && review.detail !== void 0 && reviewDetail !== review.detail) {
911
+ diagnostics.push(sceneErrorDiagnostic("scene.visual_audit_invalid_review_detail", "Visual audit review detail must be summary, standard, or full.", "visualAudit.review.detail"));
912
+ }
913
+ const rawMaxFindings = review?.maxFindings;
914
+ const maxFindings = typeof rawMaxFindings === "number" && Number.isInteger(rawMaxFindings) && rawMaxFindings > 0 ? rawMaxFindings : defaults.review.maxFindings;
915
+ if (rawMaxFindings !== void 0 && maxFindings !== rawMaxFindings) {
916
+ diagnostics.push(sceneErrorDiagnostic("scene.visual_audit_invalid_max_findings", "Visual audit review maxFindings must be a positive integer.", "visualAudit.review.maxFindings"));
917
+ }
918
+ return {
919
+ enabled: booleanField(value, "enabled", defaults.enabled, "visualAudit", diagnostics),
920
+ roles: value.roles === void 0 ? defaults.roles : roles,
921
+ pathRoots: value.pathRoots === void 0 ? defaults.pathRoots : pathRoots,
922
+ pathGlobs: value.pathGlobs === void 0 ? defaults.pathGlobs : pathGlobs,
923
+ excludePathGlobs: value.excludePathGlobs === void 0 ? defaults.excludePathGlobs : excludePathGlobs,
924
+ includeFullPage: booleanField(value, "includeFullPage", defaults.includeFullPage, "visualAudit", diagnostics),
925
+ review: {
926
+ enabled: review ? booleanField(review, "enabled", defaults.review.enabled, "visualAudit.review", diagnostics) : defaults.review.enabled,
927
+ detail: reviewDetail,
928
+ maxFindings,
929
+ contactSheets: review ? booleanField(review, "contactSheets", defaults.review.contactSheets, "visualAudit.review", diagnostics) : defaults.review.contactSheets
930
+ },
931
+ routeDiscovery: {
932
+ core: routeDiscovery ? booleanField(routeDiscovery, "core", true, "visualAudit.routeDiscovery", diagnostics) : defaults.routeDiscovery.core,
933
+ admin: routeDiscovery ? booleanField(routeDiscovery, "admin", true, "visualAudit.routeDiscovery", diagnostics) : defaults.routeDiscovery.admin,
934
+ tenantOverrides: routeDiscovery ? booleanField(routeDiscovery, "tenantOverrides", true, "visualAudit.routeDiscovery", diagnostics) : defaults.routeDiscovery.tenantOverrides,
935
+ contentCollections: routeDiscovery ? booleanField(routeDiscovery, "contentCollections", true, "visualAudit.routeDiscovery", diagnostics) : defaults.routeDiscovery.contentCollections
936
+ }
937
+ };
938
+ }
939
+ function actionKind(action) {
940
+ return Object.keys(action)[0] ?? "";
941
+ }
942
+ function sceneActionKind(action) {
943
+ return actionKind(action);
944
+ }
945
+ function sceneExpectationKinds(expectation) {
946
+ return expectationKeys(expectation);
947
+ }
948
+ function parseTreeseedSceneManifest(value, diagnostics) {
949
+ if (!isRecord(value)) {
950
+ diagnostics.push(sceneErrorDiagnostic("scene.invalid_manifest", "Expected scene manifest to be an object.", "manifest"));
951
+ return null;
952
+ }
953
+ for (const key of Object.keys(value)) {
954
+ if (!TOP_LEVEL_FIELDS.has(key)) diagnostics.push(sceneWarningDiagnostic("scene.unknown_field", `Unknown top-level field: ${key}.`, key));
955
+ }
956
+ const schemaVersion = requireString(value, "schemaVersion", "manifest", diagnostics);
957
+ if (schemaVersion && schemaVersion !== TREESEED_SCENE_SCHEMA_VERSION) diagnostics.push(sceneErrorDiagnostic("scene.unsupported_schema_version", `Unsupported scene schema version: ${schemaVersion}.`, "schemaVersion"));
958
+ const id = requireString(value, "id", "manifest", diagnostics);
959
+ if (id && !FILESYSTEM_SAFE_SCENE_ID.test(id)) diagnostics.push(sceneErrorDiagnostic("scene.invalid_id", `Invalid scene id: ${id}.`, "id"));
960
+ const title = requireString(value, "title", "manifest", diagnostics);
961
+ const target = parseTarget(value.target, diagnostics);
962
+ const devices = parseDevices(value.devices, target, diagnostics);
963
+ const mode = parseMode(value.mode, diagnostics);
964
+ const workflow = parseWorkflow(value.workflow, diagnostics);
965
+ if (workflow.length > 10 && !Array.isArray(value.chapters)) diagnostics.push(sceneErrorDiagnostic("scene.missing_chapters", "Scenes with more than 10 workflow steps must define chapters.", "chapters"));
966
+ const stepIds = new Set(workflow.map((step) => step.id));
967
+ return {
968
+ schemaVersion: TREESEED_SCENE_SCHEMA_VERSION,
969
+ id,
970
+ title,
971
+ description: optionalString(value, "description"),
972
+ audience: stringArrayField(value, "audience", "manifest", diagnostics),
973
+ mode,
974
+ target,
975
+ devices,
976
+ setup: parseSetup(value.setup, target.environment, diagnostics),
977
+ artifacts: parseArtifacts(value.artifacts, diagnostics),
978
+ workflow,
979
+ chapters: parseChapters(value.chapters, stepIds, diagnostics),
980
+ overlays: parseOverlays(value.overlays, stepIds, diagnostics),
981
+ diagrams: parseDiagrams(value.diagrams, stepIds, diagnostics),
982
+ render: parseRender(value.render, diagnostics),
983
+ runtime: parseRuntime(value.runtime, mode, diagnostics),
984
+ training: parseTraining(value.training, stepIds, diagnostics),
985
+ visualAudit: parseVisualAudit(value.visualAudit, diagnostics)
986
+ };
987
+ }
988
+ export {
989
+ defaultTreeseedSceneDeviceConfig,
990
+ defaultTreeseedSceneTrainingConfig,
991
+ parseTreeseedSceneManifest,
992
+ sceneActionKind,
993
+ sceneExpectationKinds
994
+ };