@treeseed/sdk 0.11.0 → 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 (473) hide show
  1. package/README.md +9 -4
  2. package/dist/agent-capacity.d.ts +916 -0
  3. package/dist/agent-capacity.js +1600 -0
  4. package/dist/agent-tools.d.ts +37 -0
  5. package/dist/agent-tools.js +301 -0
  6. package/dist/api/app.d.ts +1 -1
  7. package/dist/api/auth/d1-database.d.ts +2 -2
  8. package/dist/api/auth/d1-provider.d.ts +4 -4
  9. package/dist/api/auth/d1-store.d.ts +2 -2
  10. package/dist/api/auth/memory-provider.d.ts +1 -1
  11. package/dist/api/auth/tokens.d.ts +1 -1
  12. package/dist/api/config.d.ts +3 -1
  13. package/dist/api/config.js +34 -10
  14. package/dist/api/http.d.ts +2 -2
  15. package/dist/api/index.d.ts +10 -10
  16. package/dist/api/index.js +4 -2
  17. package/dist/api/operations-routes.d.ts +3 -3
  18. package/dist/api/operations.d.ts +1 -1
  19. package/dist/api/providers.d.ts +1 -1
  20. package/dist/api/providers.js +21 -4
  21. package/dist/api/railway.d.ts +3 -2
  22. package/dist/api/sdk-dispatch.d.ts +4 -4
  23. package/dist/api/sdk-routes.d.ts +2 -2
  24. package/dist/api/templates.d.ts +2 -2
  25. package/dist/api/types.d.ts +3 -2
  26. package/dist/capacity-provider.d.ts +117 -60
  27. package/dist/capacity-provider.js +215 -43
  28. package/dist/capacity.d.ts +2 -2
  29. package/dist/cli-tools.d.ts +1 -1
  30. package/dist/content-operations.d.ts +97 -0
  31. package/dist/content-operations.js +250 -0
  32. package/dist/content-store.d.ts +4 -4
  33. package/dist/control-plane-client.d.ts +13 -18
  34. package/dist/control-plane-client.js +8 -86
  35. package/dist/control-plane.d.ts +2 -2
  36. package/dist/copilot.d.ts +3 -0
  37. package/dist/copilot.js +16 -1
  38. package/dist/d1-http.d.ts +1 -1
  39. package/dist/d1-store.d.ts +32 -57
  40. package/dist/d1-store.js +115 -318
  41. package/dist/db/d1.d.ts +1 -232
  42. package/dist/db/index.d.ts +3 -3
  43. package/dist/db/market-schema.d.ts +49037 -11843
  44. package/dist/db/market-schema.js +1788 -50
  45. package/dist/db/node-sqlite.d.ts +1 -232
  46. package/dist/db/schema.d.ts +0 -462
  47. package/dist/db/schema.js +2 -22
  48. package/dist/dispatch.d.ts +1 -1
  49. package/dist/dispatch.js +0 -11
  50. package/dist/fixture-support.js +52 -4
  51. package/dist/governance.d.ts +133 -0
  52. package/dist/governance.js +285 -0
  53. package/dist/graph/build.d.ts +2 -2
  54. package/dist/graph/context-query-contracts.d.ts +1 -1
  55. package/dist/graph/dsl.d.ts +1 -1
  56. package/dist/graph/query.d.ts +4 -4
  57. package/dist/graph/ranking.d.ts +1 -1
  58. package/dist/graph/schema.d.ts +1 -1
  59. package/dist/graph.d.ts +11 -11
  60. package/dist/guarantees/index.d.ts +425 -0
  61. package/dist/guarantees/index.js +1146 -0
  62. package/dist/hosting/apps.d.ts +1 -1
  63. package/dist/hosting/builtins.d.ts +1 -1
  64. package/dist/hosting/builtins.js +9 -198
  65. package/dist/hosting/contracts.d.ts +3 -2
  66. package/dist/hosting/graph.d.ts +24 -21
  67. package/dist/hosting/graph.js +280 -294
  68. package/dist/hosting/index.d.ts +4 -4
  69. package/dist/index.d.ts +88 -74
  70. package/dist/index.js +81 -10
  71. package/dist/local-dev/managed-dev.d.ts +85 -0
  72. package/dist/local-dev/managed-dev.js +368 -0
  73. package/dist/managed-dependencies.d.ts +9 -0
  74. package/dist/managed-dependencies.js +10 -8
  75. package/dist/market-client.d.ts +265 -7
  76. package/dist/market-client.js +381 -9
  77. package/dist/model-registry.d.ts +1 -1
  78. package/dist/model-registry.js +19 -19
  79. package/dist/operations/agent-tools.d.ts +2 -11
  80. package/dist/operations/agent-tools.js +2 -14
  81. package/dist/operations/providers/default.d.ts +1 -1
  82. package/dist/operations/providers/default.js +20 -37
  83. package/dist/operations/repository-operations.d.ts +26 -2
  84. package/dist/operations/repository-operations.js +159 -1
  85. package/dist/operations/runtime.d.ts +3 -3
  86. package/dist/operations/services/bootstrap-runner.d.ts +1 -1
  87. package/dist/operations/services/build-warning-policy.d.ts +34 -0
  88. package/dist/operations/services/build-warning-policy.js +81 -82
  89. package/dist/operations/services/commit-message-provider.js +4 -4
  90. package/dist/operations/services/config-runtime.d.ts +73 -19
  91. package/dist/operations/services/config-runtime.js +276 -100
  92. package/dist/operations/services/deploy.d.ts +41 -622
  93. package/dist/operations/services/deploy.js +181 -213
  94. package/dist/operations/services/deployment-readiness.d.ts +1 -1
  95. package/dist/operations/services/deployment-readiness.js +38 -7
  96. package/dist/operations/services/git-remote-policy.js +12 -4
  97. package/dist/operations/services/git-runner.d.ts +66 -0
  98. package/dist/operations/services/git-runner.js +479 -0
  99. package/dist/operations/services/git-workflow.d.ts +43 -5
  100. package/dist/operations/services/git-workflow.js +242 -20
  101. package/dist/operations/services/github-actions-verification.d.ts +3 -1
  102. package/dist/operations/services/github-actions-verification.js +11 -3
  103. package/dist/operations/services/github-api.js +21 -5
  104. package/dist/operations/services/github-automation.d.ts +3 -3
  105. package/dist/operations/services/github-automation.js +15 -18
  106. package/dist/operations/services/github-credentials.js +2 -1
  107. package/dist/operations/services/hosted-service-checks.d.ts +19 -1
  108. package/dist/operations/services/hosted-service-checks.js +162 -11
  109. package/dist/operations/services/hosting-audit.d.ts +2 -2
  110. package/dist/operations/services/hosting-audit.js +7 -7
  111. package/dist/operations/services/hub-launch.d.ts +1 -1
  112. package/dist/operations/services/hub-provider-launch.d.ts +5 -5
  113. package/dist/operations/services/hub-provider-launch.js +19 -14
  114. package/dist/operations/services/live-hosted-service-checks.d.ts +2 -1
  115. package/dist/operations/services/live-hosted-service-checks.js +193 -80
  116. package/dist/operations/services/local-dev.js +0 -1
  117. package/dist/operations/services/managed-host-security.d.ts +1 -1
  118. package/dist/operations/services/managed-repositories.d.ts +37 -0
  119. package/dist/operations/services/managed-repositories.js +177 -0
  120. package/dist/operations/services/operations-runner-smoke.d.ts +3 -2
  121. package/dist/operations/services/operations-runner-smoke.js +22 -4
  122. package/dist/operations/services/package-adapters.d.ts +77 -2
  123. package/dist/operations/services/package-adapters.js +627 -56
  124. package/dist/operations/services/package-reference-policy.d.ts +12 -88
  125. package/dist/operations/services/package-reference-policy.js +81 -213
  126. package/dist/operations/services/project-host-operations.d.ts +4 -4
  127. package/dist/operations/services/project-platform.d.ts +19 -193
  128. package/dist/operations/services/project-platform.js +31 -103
  129. package/dist/operations/services/project-web-monitor.d.ts +2 -2
  130. package/dist/operations/services/project-web-monitor.js +97 -2
  131. package/dist/operations/services/railway-api.d.ts +36 -7
  132. package/dist/operations/services/railway-api.js +331 -100
  133. package/dist/operations/services/railway-deploy.d.ts +7 -95
  134. package/dist/operations/services/railway-deploy.js +334 -742
  135. package/dist/operations/services/release-history.js +3 -4
  136. package/dist/operations/services/release-proof-ledger.d.ts +13 -0
  137. package/dist/operations/services/release-proof-ledger.js +81 -0
  138. package/dist/operations/services/release-proof-planner.d.ts +48 -0
  139. package/dist/operations/services/release-proof-planner.js +195 -0
  140. package/dist/operations/services/release-proof-runner.d.ts +16 -0
  141. package/dist/operations/services/release-proof-runner.js +169 -0
  142. package/dist/operations/services/release-proof.d.ts +81 -0
  143. package/dist/operations/services/release-proof.js +79 -0
  144. package/dist/operations/services/repository-save-orchestrator.d.ts +6 -7
  145. package/dist/operations/services/repository-save-orchestrator.js +353 -174
  146. package/dist/operations/services/runtime-paths.d.ts +1 -3
  147. package/dist/operations/services/runtime-paths.js +0 -4
  148. package/dist/operations/services/runtime-tools.d.ts +1 -192
  149. package/dist/operations/services/runtime-tools.js +4 -444
  150. package/dist/operations/services/save-deploy-preflight.js +9 -1
  151. package/dist/operations/services/template-host-bindings.d.ts +2 -2
  152. package/dist/operations/services/template-host-bindings.js +3 -2
  153. package/dist/operations/services/template-registry.d.ts +6 -6
  154. package/dist/operations/services/template-registry.js +33 -14
  155. package/dist/operations/services/template-secret-sync.d.ts +3 -3
  156. package/dist/operations/services/workflow-timing.d.ts +25 -0
  157. package/dist/operations/services/workflow-timing.js +79 -0
  158. package/dist/operations/services/workspace-dependency-mode.js +41 -4
  159. package/dist/operations/services/workspace-preflight.js +8 -8
  160. package/dist/operations/services/workspace-save-script.d.ts +4 -4
  161. package/dist/operations/services/workspace-save.d.ts +1 -0
  162. package/dist/operations/services/workspace-save.js +41 -18
  163. package/dist/operations/services/workspace-tools.js +40 -6
  164. package/dist/operations-registry.d.ts +1 -1
  165. package/dist/operations-registry.js +5 -6
  166. package/dist/operations-types.d.ts +1 -1
  167. package/dist/operations.d.ts +17 -11
  168. package/dist/operations.js +57 -3
  169. package/dist/platform/book-export.js +2 -0
  170. package/dist/platform/books-data.d.ts +1 -1
  171. package/dist/platform/config.d.ts +27 -0
  172. package/dist/platform/config.js +100 -0
  173. package/dist/platform/content-runtime-source.d.ts +54 -0
  174. package/dist/platform/content-runtime-source.js +169 -0
  175. package/dist/platform/contracts.d.ts +6 -1
  176. package/dist/platform/deploy-config.d.ts +1 -1
  177. package/dist/platform/deploy-config.js +7 -1
  178. package/dist/platform/deploy-runtime.d.ts +1 -1
  179. package/dist/platform/desired-state.d.ts +63 -0
  180. package/dist/platform/desired-state.js +1021 -0
  181. package/dist/platform/env.yaml +414 -19
  182. package/dist/platform/environment.d.ts +2 -2
  183. package/dist/platform/environment.js +54 -22
  184. package/dist/platform/local-content-materialization.d.ts +9 -0
  185. package/dist/platform/local-content-materialization.js +212 -0
  186. package/dist/platform/plugin.d.ts +5 -5
  187. package/dist/platform/plugins/runtime.d.ts +3 -3
  188. package/dist/platform/plugins/runtime.js +62 -1
  189. package/dist/platform/plugins.d.ts +6 -6
  190. package/dist/platform/published-content-pipeline.d.ts +3 -3
  191. package/dist/platform/published-content-pipeline.js +5 -1
  192. package/dist/platform/published-content.d.ts +4 -3
  193. package/dist/platform/site-config-schema.d.ts +1 -0
  194. package/dist/platform/site-config-schema.js +4 -1
  195. package/dist/platform/tenant/runtime-config.d.ts +152 -2
  196. package/dist/platform/tenant-config.d.ts +1 -1
  197. package/dist/platform/utils/site-config-schema.d.ts +154 -0
  198. package/dist/platform/utils/site-config-schema.js +400 -461
  199. package/dist/platform-operation-store.d.ts +1 -1
  200. package/dist/plugin-default.d.ts +1 -1
  201. package/dist/plugin-default.js +27 -12
  202. package/dist/project-import.d.ts +91 -0
  203. package/dist/project-import.js +257 -0
  204. package/dist/project-workflow.d.ts +1 -1
  205. package/dist/reconcile/bootstrap-systems.d.ts +2 -2
  206. package/dist/reconcile/bootstrap-systems.js +3 -3
  207. package/dist/reconcile/builtin-adapters.d.ts +7 -1
  208. package/dist/reconcile/builtin-adapters.js +2924 -346
  209. package/dist/reconcile/contracts.d.ts +15 -2
  210. package/dist/reconcile/desired-state.d.ts +2 -193
  211. package/dist/reconcile/desired-state.js +24 -33
  212. package/dist/reconcile/engine.d.ts +60 -397
  213. package/dist/reconcile/engine.js +182 -18
  214. package/dist/reconcile/index.d.ts +10 -10
  215. package/dist/reconcile/live-acceptance.d.ts +22 -1
  216. package/dist/reconcile/live-acceptance.js +456 -44
  217. package/dist/reconcile/providers/docker-private.d.ts +54 -0
  218. package/dist/reconcile/providers/docker-private.js +101 -0
  219. package/dist/reconcile/providers/github-private.d.ts +65 -0
  220. package/dist/reconcile/providers/github-private.js +119 -0
  221. package/dist/reconcile/providers/local-private.d.ts +28 -0
  222. package/dist/reconcile/providers/local-private.js +75 -0
  223. package/dist/reconcile/providers/railway-iac.d.ts +66 -0
  224. package/dist/reconcile/providers/railway-iac.js +275 -0
  225. package/dist/reconcile/providers/release-private.d.ts +92 -0
  226. package/dist/reconcile/providers/release-private.js +152 -0
  227. package/dist/reconcile/registry.d.ts +2 -2
  228. package/dist/reconcile/registry.js +16 -1
  229. package/dist/reconcile/state.d.ts +1 -1
  230. package/dist/reconcile/state.js +3 -40
  231. package/dist/reconcile/units.d.ts +1 -1
  232. package/dist/reconcile/units.js +7 -1
  233. package/dist/remote.d.ts +6 -6
  234. package/dist/scenes/artifacts.d.ts +16 -0
  235. package/dist/scenes/artifacts.js +61 -0
  236. package/dist/scenes/auth.d.ts +2 -0
  237. package/dist/scenes/auth.js +28 -0
  238. package/dist/scenes/base-url.d.ts +12 -0
  239. package/dist/scenes/base-url.js +123 -0
  240. package/dist/scenes/builtin-plugins.d.ts +2 -0
  241. package/dist/scenes/builtin-plugins.js +447 -0
  242. package/dist/scenes/checkpoints.d.ts +14 -0
  243. package/dist/scenes/checkpoints.js +33 -0
  244. package/dist/scenes/device-matrix.d.ts +2 -0
  245. package/dist/scenes/device-matrix.js +97 -0
  246. package/dist/scenes/devices.d.ts +11 -0
  247. package/dist/scenes/devices.js +22 -0
  248. package/dist/scenes/diagnostics.d.ts +5 -0
  249. package/dist/scenes/diagnostics.js +22 -0
  250. package/dist/scenes/diagram-providers.d.ts +2 -0
  251. package/dist/scenes/diagram-providers.js +181 -0
  252. package/dist/scenes/diagram-validation.d.ts +22 -0
  253. package/dist/scenes/diagram-validation.js +74 -0
  254. package/dist/scenes/environment.d.ts +2 -0
  255. package/dist/scenes/environment.js +65 -0
  256. package/dist/scenes/evidence-bundle.d.ts +5 -0
  257. package/dist/scenes/evidence-bundle.js +42 -0
  258. package/dist/scenes/evidence-report.d.ts +10 -0
  259. package/dist/scenes/evidence-report.js +73 -0
  260. package/dist/scenes/evidence.d.ts +16 -0
  261. package/dist/scenes/evidence.js +277 -0
  262. package/dist/scenes/index.d.ts +48 -0
  263. package/dist/scenes/index.js +312 -0
  264. package/dist/scenes/inspect.d.ts +9 -0
  265. package/dist/scenes/inspect.js +64 -0
  266. package/dist/scenes/loader.d.ts +3 -0
  267. package/dist/scenes/loader.js +38 -0
  268. package/dist/scenes/logs.d.ts +2 -0
  269. package/dist/scenes/logs.js +47 -0
  270. package/dist/scenes/operations.d.ts +3 -0
  271. package/dist/scenes/operations.js +128 -0
  272. package/dist/scenes/phase0.d.ts +9 -0
  273. package/dist/scenes/phase0.js +637 -0
  274. package/dist/scenes/planner.d.ts +12 -0
  275. package/dist/scenes/planner.js +166 -0
  276. package/dist/scenes/playwright-adapter.d.ts +2 -0
  277. package/dist/scenes/playwright-adapter.js +63 -0
  278. package/dist/scenes/plugins.d.ts +5 -0
  279. package/dist/scenes/plugins.js +115 -0
  280. package/dist/scenes/progress.d.ts +17 -0
  281. package/dist/scenes/progress.js +24 -0
  282. package/dist/scenes/publish-destinations.d.ts +12 -0
  283. package/dist/scenes/publish-destinations.js +99 -0
  284. package/dist/scenes/publish-plan-report.d.ts +10 -0
  285. package/dist/scenes/publish-plan-report.js +70 -0
  286. package/dist/scenes/publish-plan.d.ts +15 -0
  287. package/dist/scenes/publish-plan.js +248 -0
  288. package/dist/scenes/publish-redaction.d.ts +16 -0
  289. package/dist/scenes/publish-redaction.js +148 -0
  290. package/dist/scenes/publish-release-record.d.ts +13 -0
  291. package/dist/scenes/publish-release-record.js +34 -0
  292. package/dist/scenes/publish-report.d.ts +10 -0
  293. package/dist/scenes/publish-report.js +67 -0
  294. package/dist/scenes/publish.d.ts +16 -0
  295. package/dist/scenes/publish.js +298 -0
  296. package/dist/scenes/registry.d.ts +12 -0
  297. package/dist/scenes/registry.js +65 -0
  298. package/dist/scenes/remotion-adapter.d.ts +3 -0
  299. package/dist/scenes/remotion-adapter.js +94 -0
  300. package/dist/scenes/remotion-composition-registry.d.ts +2 -0
  301. package/dist/scenes/remotion-composition-registry.js +12 -0
  302. package/dist/scenes/remotion-compositions.d.ts +15 -0
  303. package/dist/scenes/remotion-compositions.js +464 -0
  304. package/dist/scenes/remotion-diagrams.d.ts +9 -0
  305. package/dist/scenes/remotion-diagrams.js +188 -0
  306. package/dist/scenes/remotion-input.d.ts +13 -0
  307. package/dist/scenes/remotion-input.js +291 -0
  308. package/dist/scenes/remotion-visuals.d.ts +29 -0
  309. package/dist/scenes/remotion-visuals.js +198 -0
  310. package/dist/scenes/render-media-assets.d.ts +9 -0
  311. package/dist/scenes/render-media-assets.js +117 -0
  312. package/dist/scenes/render-report.d.ts +10 -0
  313. package/dist/scenes/render-report.js +27 -0
  314. package/dist/scenes/render.d.ts +2 -0
  315. package/dist/scenes/render.js +218 -0
  316. package/dist/scenes/reporter.d.ts +3 -0
  317. package/dist/scenes/reporter.js +101 -0
  318. package/dist/scenes/resume.d.ts +2 -0
  319. package/dist/scenes/resume.js +79 -0
  320. package/dist/scenes/runner.d.ts +2 -0
  321. package/dist/scenes/runner.js +674 -0
  322. package/dist/scenes/schema.d.ts +6 -0
  323. package/dist/scenes/schema.js +994 -0
  324. package/dist/scenes/seed.d.ts +2 -0
  325. package/dist/scenes/seed.js +83 -0
  326. package/dist/scenes/segments.d.ts +15 -0
  327. package/dist/scenes/segments.js +79 -0
  328. package/dist/scenes/selectors.d.ts +3 -0
  329. package/dist/scenes/selectors.js +21 -0
  330. package/dist/scenes/timeline.d.ts +11 -0
  331. package/dist/scenes/timeline.js +26 -0
  332. package/dist/scenes/timeouts.d.ts +6 -0
  333. package/dist/scenes/timeouts.js +17 -0
  334. package/dist/scenes/training-captions.d.ts +14 -0
  335. package/dist/scenes/training-captions.js +98 -0
  336. package/dist/scenes/training-report.d.ts +10 -0
  337. package/dist/scenes/training-report.js +78 -0
  338. package/dist/scenes/training-transcript.d.ts +24 -0
  339. package/dist/scenes/training-transcript.js +204 -0
  340. package/dist/scenes/training.d.ts +10 -0
  341. package/dist/scenes/training.js +134 -0
  342. package/dist/scenes/types.d.ts +1872 -0
  343. package/dist/scenes/types.js +8 -0
  344. package/dist/scenes/visual-audit-contact-sheets.d.ts +6 -0
  345. package/dist/scenes/visual-audit-contact-sheets.js +119 -0
  346. package/dist/scenes/visual-audit-fixtures.d.ts +25 -0
  347. package/dist/scenes/visual-audit-fixtures.js +210 -0
  348. package/dist/scenes/visual-audit-report.d.ts +11 -0
  349. package/dist/scenes/visual-audit-report.js +85 -0
  350. package/dist/scenes/visual-audit-review.d.ts +23 -0
  351. package/dist/scenes/visual-audit-review.js +829 -0
  352. package/dist/scenes/visual-audit-routes.d.ts +13 -0
  353. package/dist/scenes/visual-audit-routes.js +308 -0
  354. package/dist/scenes/visual-audit.d.ts +3 -0
  355. package/dist/scenes/visual-audit.js +596 -0
  356. package/dist/scripts/build-dist.js +154 -40
  357. package/dist/scripts/check-build-warnings.js +42 -53
  358. package/dist/scripts/cleanup-markdown.js +1 -1
  359. package/dist/scripts/cli-test-fixtures.js +24 -28
  360. package/dist/scripts/migrate-journey-csv-to-guarantees.js +140 -0
  361. package/dist/scripts/package-tools.js +12 -1
  362. package/dist/scripts/prepare.js +3 -7
  363. package/dist/scripts/release-verify.js +2 -5
  364. package/dist/scripts/run-fixture-astro-command.js +1 -1
  365. package/dist/scripts/template-catalog.test.js +68 -82
  366. package/dist/scripts/tenant-dev.js +0 -10
  367. package/dist/scripts/test-cloudflare-local.js +1 -1
  368. package/dist/scripts/test-scaffold.js +0 -1
  369. package/dist/scripts/test-smoke.js +3 -3
  370. package/dist/scripts/treeseed-build-dist.js +4 -7
  371. package/dist/scripts/treeseed-release-verify.js +1 -1
  372. package/dist/scripts/verify-driver.js +30 -21
  373. package/dist/scripts/workflow-commands.test.js +18 -27
  374. package/dist/scripts/workspace-command-e2e.js +1 -1
  375. package/dist/scripts/workspace-lint.js +6 -0
  376. package/dist/scripts/workspace-release-test.js +90 -1
  377. package/dist/scripts/workspace-test.js +6 -0
  378. package/dist/sdk-dispatch.d.ts +1 -1
  379. package/dist/sdk-dispatch.js +0 -16
  380. package/dist/sdk-fields.d.ts +1 -1
  381. package/dist/sdk-filters.d.ts +1 -1
  382. package/dist/sdk-types.d.ts +1184 -113
  383. package/dist/sdk-types.js +393 -0
  384. package/dist/sdk.d.ts +74 -79
  385. package/dist/sdk.js +27 -36
  386. package/dist/secrets-capability.d.ts +421 -0
  387. package/dist/secrets-capability.js +530 -0
  388. package/dist/seeds/normalize.js +1 -0
  389. package/dist/seeds/planner.js +38 -0
  390. package/dist/seeds/schema.js +293 -4
  391. package/dist/seeds/types.d.ts +60 -0
  392. package/dist/seeds/types.js +9 -1
  393. package/dist/service-credentials.d.ts +54 -0
  394. package/dist/service-credentials.js +112 -0
  395. package/dist/stores/cursor-store.d.ts +2 -2
  396. package/dist/stores/envelopes.d.ts +1 -1
  397. package/dist/stores/helpers.d.ts +1 -1
  398. package/dist/stores/lease-store.d.ts +2 -2
  399. package/dist/stores/message-store.d.ts +2 -2
  400. package/dist/stores/operational-store.d.ts +3 -26
  401. package/dist/stores/operational-store.js +0 -225
  402. package/dist/stores/project-workflow-store.d.ts +2 -2
  403. package/dist/stores/run-store.d.ts +2 -3
  404. package/dist/stores/run-store.js +0 -98
  405. package/dist/stores/subscription-store.d.ts +2 -3
  406. package/dist/stores/subscription-store.js +0 -100
  407. package/dist/template-catalog.d.ts +1 -1
  408. package/dist/template-launch-requirements.d.ts +2 -2
  409. package/dist/template-launch-ui.d.ts +2 -2
  410. package/dist/treedx/adapters.d.ts +6 -6
  411. package/dist/treedx/client.d.ts +1 -1
  412. package/dist/treedx/errors.d.ts +1 -1
  413. package/dist/treedx/federated-client.d.ts +3 -3
  414. package/dist/treedx/graph-adapter.d.ts +2 -2
  415. package/dist/treedx/index.d.ts +14 -14
  416. package/dist/treedx/market-integration.d.ts +1 -1
  417. package/dist/treedx/ports.d.ts +30 -30
  418. package/dist/treedx/query-adapter.d.ts +3 -3
  419. package/dist/treedx/registry-client.d.ts +2 -2
  420. package/dist/treedx/repository-adapter.d.ts +4 -4
  421. package/dist/treedx/repository-adapter.js +14 -3
  422. package/dist/treedx/sdk-integration.d.ts +3 -3
  423. package/dist/treedx/types.d.ts +2 -2
  424. package/dist/treedx/workspace-adapter.d.ts +2 -2
  425. package/dist/treedx-backends.d.ts +13 -11
  426. package/dist/treedx-backends.js +52 -50
  427. package/dist/treedx-client.d.ts +3 -0
  428. package/dist/treedx-client.js +10 -1
  429. package/dist/treeseed/services/compose.yml +2 -3
  430. package/dist/treeseed/template-catalog/catalog.fixture.json +4 -4
  431. package/dist/types/agents.d.ts +256 -0
  432. package/dist/types/agents.js +42 -1
  433. package/dist/verification.d.ts +1 -0
  434. package/dist/verification.js +143 -14
  435. package/dist/workflow/operations.d.ts +510 -559
  436. package/dist/workflow/operations.js +1891 -1342
  437. package/dist/workflow/policy.js +19 -7
  438. package/dist/workflow/runs.d.ts +9 -3
  439. package/dist/workflow/runs.js +66 -26
  440. package/dist/workflow/session.d.ts +4 -1
  441. package/dist/workflow/session.js +50 -10
  442. package/dist/workflow/worktrees.d.ts +6 -2
  443. package/dist/workflow/worktrees.js +98 -15
  444. package/dist/workflow-state.d.ts +5 -5
  445. package/dist/workflow-state.js +27 -17
  446. package/dist/workflow-support.d.ts +26 -25
  447. package/dist/workflow-support.js +27 -31
  448. package/dist/workflow.d.ts +46 -16
  449. package/dist/workflow.js +19 -7
  450. package/drizzle/d1/0000_treeseed_d1.sql +0 -18
  451. package/drizzle/market/0000_market_control_plane.sql +1793 -1499
  452. package/drizzle/market/0005_agent_capacity_coordination.sql +145 -0
  453. package/drizzle/market/0006_provider_assignment_lifecycle.sql +9 -0
  454. package/drizzle/market/0007_agent_architecture_gap_closure.sql +157 -0
  455. package/drizzle/market/0008_agent_capacity_operational_closure.sql +27 -0
  456. package/drizzle/market/0009_agent_capacity_runtime_hardening.sql +29 -0
  457. package/drizzle/market/0010_secrets_capability_persistence.sql +130 -0
  458. package/drizzle/market/0011_github_app_adapter.sql +47 -0
  459. package/drizzle/market/0012_workday_test_runs.sql +44 -0
  460. package/drizzle/market/0013_runtime_task_lifecycle.sql +39 -0
  461. package/drizzle/market/0014_governance_pipeline.sql +189 -0
  462. package/package.json +75 -18
  463. package/scripts/{verify-driver.mjs → verify-driver.ts} +19 -4
  464. package/templates/github/deploy-web.workflow.yml +12 -8
  465. package/dist/operations/services/mailpit-runtime.d.ts +0 -20
  466. package/dist/operations/services/mailpit-runtime.js +0 -67
  467. package/dist/operations/services/release-candidate.d.ts +0 -60
  468. package/dist/operations/services/release-candidate.js +0 -953
  469. package/dist/scripts/ensure-mailpit.js +0 -48
  470. package/dist/scripts/logs-mailpit.js +0 -2
  471. package/dist/scripts/run-ts.js +0 -45
  472. package/dist/scripts/stop-mailpit.js +0 -5
  473. package/dist/scripts/treeseed-run-ts.js +0 -45
@@ -0,0 +1,829 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { relative } from "node:path";
3
+ import { writeTreeseedSceneVisualAuditContactSheets } from "./visual-audit-contact-sheets.js";
4
+ const SEVERITIES = ["blocking", "high", "medium", "low", "info"];
5
+ const CATEGORIES = ["functional", "client-error", "display", "content", "architecture"];
6
+ const OWNERS = ["@treeseed/ui", "@treeseed/admin", "@treeseed/core", "@treeseed/market", "@treeseed/api", "@treeseed/sdk", "@treeseed/cli", "unknown"];
7
+ function md(value) {
8
+ return String(value ?? "").replace(/\|/gu, "\\|").replace(/\n/gu, " ");
9
+ }
10
+ function rel(root, path) {
11
+ return path ? relative(root, path) : "";
12
+ }
13
+ function isTreeseedSceneVisualAuditIgnoredClientError(error) {
14
+ const url = error.url ?? "";
15
+ const message = error.message ?? "";
16
+ if (/^chrome-extension:/iu.test(url) || /^devtools:/iu.test(url)) return true;
17
+ if (/favicon\.ico/iu.test(url) && /404|failed to load resource|ERR_ABORTED/iu.test(message)) return true;
18
+ if (/\.map(?:\?|$)/iu.test(url) && /404|failed to load resource|ERR_ABORTED/iu.test(message)) return true;
19
+ if (url.includes("/@fs/") && url.includes("/astro/dist/runtime/client/dev-toolbar/")) return true;
20
+ if (url.includes("/node_modules/astro/dist/runtime/client/dev-toolbar/")) return true;
21
+ if (/dev-toolbar\/entrypoint\.js/iu.test(url)) return true;
22
+ if (/dev-toolbar\/entrypoint\.js/iu.test(message) && /403|ERR_ABORTED|failed to load resource/iu.test(message)) return true;
23
+ return false;
24
+ }
25
+ function countMap(keys) {
26
+ return Object.fromEntries(keys.map((key) => [key, 0]));
27
+ }
28
+ function priorityBand(score) {
29
+ if (score >= 1100) return "critical";
30
+ if (score >= 800) return "high";
31
+ if (score >= 450) return "medium";
32
+ return "low";
33
+ }
34
+ function priorityScore(input) {
35
+ const severityWeight = {
36
+ blocking: 1e3,
37
+ high: 700,
38
+ medium: 350,
39
+ low: 100,
40
+ info: 25
41
+ };
42
+ const categoryWeight = {
43
+ "client-error": 150,
44
+ functional: 125,
45
+ display: 75,
46
+ content: 40,
47
+ architecture: 200
48
+ };
49
+ let ownerWeight = 0;
50
+ if (input.owner === "@treeseed/api" && /seeded|fixture|access/iu.test(input.code)) ownerWeight = 80;
51
+ else if (input.owner === "@treeseed/admin") ownerWeight = 60;
52
+ else if (input.owner === "@treeseed/core") ownerWeight = 50;
53
+ else if (input.owner === "@treeseed/ui") ownerWeight = 50;
54
+ return severityWeight[input.severity] + Math.min(input.count, 100) * 4 + input.pathCount * 20 + input.roleCount * 30 + input.deviceCount * 25 + categoryWeight[input.category] + ownerWeight;
55
+ }
56
+ function pathOwner(path) {
57
+ if (path === "/" || path.startsWith("/market")) return "@treeseed/market";
58
+ if (path.startsWith("/auth") || path.startsWith("/app") || path.startsWith("/t/") || path.startsWith("/u/") || path.startsWith("/team-invites")) return "@treeseed/admin";
59
+ if (path.startsWith("/books") || path.startsWith("/notes") || path.startsWith("/questions") || path.startsWith("/objectives") || path.startsWith("/proposals") || path.startsWith("/decisions") || path.startsWith("/people") || path.startsWith("/agents") || path.startsWith("/contact") || path.startsWith("/knowledge")) return "@treeseed/core";
60
+ return "unknown";
61
+ }
62
+ function ownerFor(input) {
63
+ if (input.code.includes("fixture") || input.code.includes("seeded_entity")) return "@treeseed/api";
64
+ if (input.code.includes("default_link") || input.code.includes("default_button") || input.code.includes("horizontal_overflow") || input.code.includes("mobile_desktop")) return "@treeseed/ui";
65
+ if (input.category === "client-error" && input.capture.path.startsWith("/app")) return "@treeseed/admin";
66
+ return pathOwner(input.capture.path);
67
+ }
68
+ function guidance(owner, code) {
69
+ if (owner === "@treeseed/ui") return "Start with shared @treeseed/ui components and CSS tokens/classes. Avoid route-local CSS unless the issue is genuinely route-specific.";
70
+ if (owner === "@treeseed/admin") return "Inspect admin route composition, client initialization, session handling, and use of shared UI components before patching individual markup.";
71
+ if (owner === "@treeseed/core") return "Inspect core public/book layout style loading and reusable public layout integration before adding page-local styles.";
72
+ if (owner === "@treeseed/market") return "Inspect root tenant overrides and market branding styles while keeping shared reusable controls in @treeseed/ui.";
73
+ if (owner === "@treeseed/api") return "Fix fixture, session, authorization, or PostgreSQL-backed data behavior in @treeseed/api; do not add SDK-side database writes.";
74
+ if (owner === "@treeseed/sdk") return "Inspect the scene visual-audit capture/review implementation and artifact contract.";
75
+ return `Investigate the owning package for ${code}, then prefer a reusable architectural fix over divergent local patches.`;
76
+ }
77
+ function recommendedAction(owner, code) {
78
+ if (code.includes("client") || code.includes("http_error") || code.includes("visible_error")) {
79
+ if (owner === "@treeseed/core") return "Reproduce the route locally, inspect the server stack trace and route build/runtime dependency, then fix the shared core route or package build contract.";
80
+ if (owner === "@treeseed/admin") return "Fix the route handler, client initializer, or session/data dependency at the admin shell/view-model boundary before styling the page.";
81
+ return "Resolve the runtime error first, then rerun visual audit before doing visual polish on the affected route.";
82
+ }
83
+ if (code.includes("default_link") || code.includes("default_button")) return "Add or repair the reusable UI component/class in @treeseed/ui, then update route markup to use that shared primitive instead of browser-default controls.";
84
+ if (code.includes("seeded_entity")) return "Verify visual-audit seed data, role membership, API lookup keys, and admin view-model access before changing page markup.";
85
+ if (code.includes("final_url_mismatch")) return "Declare intentional redirects in route expectations or fix unexpected redirects at the owning route boundary.";
86
+ if (code.includes("blank_or_low_content")) return "Treat this as a route rendering failure unless the route is intentionally empty; inspect data loading and responsive layout.";
87
+ if (code.includes("architecture")) return "Fix this as a shared architectural issue and avoid route-local patches that create divergent UI or data behavior.";
88
+ return "Inspect the examples in this cluster and prefer a reusable package-level fix over a local patch.";
89
+ }
90
+ function finding(input) {
91
+ const suspectedOwner = input.owner ?? ownerFor({ capture: input.capture, category: input.category, code: input.code });
92
+ return {
93
+ id: `finding-${String(input.index).padStart(4, "0")}`,
94
+ severity: input.severity,
95
+ category: input.category,
96
+ code: input.code,
97
+ title: input.title,
98
+ message: input.message,
99
+ path: input.capture.path,
100
+ pathRoot: input.capture.pathRoot,
101
+ role: input.capture.role,
102
+ device: input.capture.device,
103
+ captureId: input.capture.id,
104
+ screenshotPath: input.capture.screenshotPath,
105
+ finalUrl: input.capture.finalUrl,
106
+ suspectedOwner,
107
+ architectureGuidance: guidance(suspectedOwner, input.code),
108
+ evidence: input.evidence ?? {}
109
+ };
110
+ }
111
+ function finalPath(capture) {
112
+ if (!capture.finalUrl) return null;
113
+ try {
114
+ return new URL(capture.finalUrl).pathname;
115
+ } catch {
116
+ return capture.finalUrl;
117
+ }
118
+ }
119
+ function isProtected(path) {
120
+ return path.startsWith("/app") || path.startsWith("/t/") || path.startsWith("/u/") || path.startsWith("/team-invites");
121
+ }
122
+ function includesSignIn(path) {
123
+ return !!path && (path.includes("/auth/sign-in") || path.includes("/auth/register"));
124
+ }
125
+ function statusExpected(status, expected) {
126
+ if (!expected) return status < 400;
127
+ return Array.isArray(expected) ? expected.includes(status) : status === expected;
128
+ }
129
+ function captureFindings(capture, indexStart, route) {
130
+ const findings = [];
131
+ let index = indexStart;
132
+ const push = (input) => findings.push(finding({ ...input, index: index += 1, capture }));
133
+ const final = finalPath(capture);
134
+ if (capture.status === "failed") {
135
+ push({ severity: "high", category: "functional", code: "visual.functional.capture_failed", title: "Capture failed", message: `Visual audit could not capture ${capture.path}.`, evidence: { diagnostics: capture.diagnostics } });
136
+ }
137
+ if (capture.status === "skipped") {
138
+ push({ severity: "medium", category: "functional", code: "visual.functional.capture_skipped", title: "Capture skipped", message: `Visual audit skipped ${capture.path}.`, evidence: { diagnostics: capture.diagnostics } });
139
+ }
140
+ if (capture.httpStatus && capture.httpStatus >= 400 && !statusExpected(capture.httpStatus, route?.expectedStatus)) {
141
+ push({ severity: capture.httpStatus >= 500 ? "high" : "medium", category: "functional", code: "visual.functional.http_error", title: "HTTP error", message: `Route returned HTTP ${capture.httpStatus}.`, evidence: { httpStatus: capture.httpStatus } });
142
+ }
143
+ if (capture.role !== "anonymous" && isProtected(capture.path) && includesSignIn(final)) {
144
+ push({ severity: "high", category: "functional", code: "visual.functional.auth_redirect_unexpected", title: "Authenticated route redirected to auth", message: `${capture.role} was redirected from ${capture.path} to ${final}.`, evidence: { finalUrl: capture.finalUrl } });
145
+ }
146
+ if (capture.role === "anonymous" && isProtected(capture.path) && capture.status === "captured" && capture.httpStatus === 200 && !includesSignIn(final) && route?.expectedAuthRedirect !== true) {
147
+ push({ severity: "high", category: "functional", code: "visual.functional.anonymous_protected_access", title: "Anonymous protected access", message: `Anonymous role reached protected route ${capture.path}.`, evidence: { finalUrl: capture.finalUrl } });
148
+ }
149
+ if (capture.status === "captured" && final && !includesSignIn(final) && final !== capture.path && !capture.path.endsWith("/") && final.replace(/\/$/u, "") !== capture.path.replace(/\/$/u, "") && (!route?.expectedFinalPath || final !== route.expectedFinalPath)) {
150
+ push({ severity: "medium", category: "functional", code: "visual.functional.final_url_mismatch", title: "Final URL differs from requested path", message: `Requested ${capture.path} but ended at ${final}.`, evidence: { finalUrl: capture.finalUrl } });
151
+ }
152
+ const dom = capture.dom;
153
+ if (dom) {
154
+ const seededEntityTexts = dom.seededEntityTexts ?? [];
155
+ const defaultStyledLinks = dom.defaultStyledLinks ?? [];
156
+ const defaultStyledButtons = dom.defaultStyledButtons ?? [];
157
+ const visibleErrorTexts = dom.visibleErrorTexts ?? [];
158
+ if (capture.role !== "anonymous" && (capture.path.startsWith("/app/teams") || capture.path.startsWith("/app/projects") || capture.path === "/app") && seededEntityTexts.length === 0) {
159
+ push({ severity: "medium", category: "functional", code: "visual.functional.seeded_entity_missing", title: "Seeded visual-audit entity not visible", message: `Expected visual-audit seeded team or project text was not visible on ${capture.path}.`, evidence: { seededEntityTexts } });
160
+ }
161
+ if (defaultStyledLinks.length > 0) {
162
+ push({ severity: capture.path.startsWith("/app") ? "high" : "medium", category: "display", code: "visual.display.default_link_style", title: "Default-styled command link detected", message: `${defaultStyledLinks.length} visible link(s) look like browser-default links.`, evidence: { links: defaultStyledLinks.slice(0, 6) } });
163
+ }
164
+ if (defaultStyledButtons.length > 0) {
165
+ push({ severity: capture.path.startsWith("/app") ? "high" : "medium", category: "display", code: "visual.display.default_button_style", title: "Default-styled button detected", message: `${defaultStyledButtons.length} visible button(s) look unstyled.`, evidence: { buttons: defaultStyledButtons.slice(0, 6) } });
166
+ }
167
+ if (dom.horizontalOverflow) {
168
+ push({ severity: capture.device === "mobile" || capture.device === "tablet" ? "high" : "medium", category: "display", code: "visual.display.horizontal_overflow", title: "Horizontal overflow detected", message: `Document scroll width ${dom.scrollWidth} exceeds viewport ${dom.viewportWidth}.`, evidence: { scrollWidth: dom.scrollWidth, viewportWidth: dom.viewportWidth } });
169
+ }
170
+ if (visibleErrorTexts.length > 0 && route?.expectedEmpty !== true) {
171
+ push({ severity: "high", category: "display", code: "visual.display.visible_error_text", title: "Visible error text", message: "The page contains visible error or runtime failure text.", evidence: { visibleErrorTexts: visibleErrorTexts.slice(0, 8) } });
172
+ }
173
+ if (capture.status === "captured" && dom.bodyTextLength < 40 && dom.visibleLinkCount + dom.visibleButtonCount + dom.visibleInputCount < 3 && route?.expectedEmpty !== true) {
174
+ push({ severity: capture.path.startsWith("/app") || capture.path.startsWith("/auth") ? "high" : "medium", category: "display", code: "visual.display.blank_or_low_content", title: "Blank or low-content page", message: "The captured page has very little visible text or interactive content.", evidence: { bodyTextLength: dom.bodyTextLength } });
175
+ }
176
+ if (capture.device === "mobile" && dom.horizontalOverflow) {
177
+ push({ severity: "high", category: "display", code: "visual.display.mobile_desktop_layout", title: "Mobile layout appears to overflow", message: "Mobile viewport appears to be rendering a desktop-width layout.", evidence: { scrollWidth: dom.scrollWidth, viewportWidth: dom.viewportWidth } });
178
+ }
179
+ }
180
+ return findings;
181
+ }
182
+ function normalizedErrorMessage(error) {
183
+ const message = error.message.replace(/\bhttps?:\/\/\S+/giu, "<url>").replace(/\s+/gu, " ").trim();
184
+ if (/Failed to load resource.+status of 500|server responded with a status of 500|HTTP\s+500/iu.test(message)) return "http-500";
185
+ if (/Failed to load resource.+status of 404|server responded with a status of 404|HTTP\s+404/iu.test(message)) return "http-404";
186
+ if (/ERR_ABORTED|Request failed/iu.test(message)) return "request-aborted";
187
+ if (/hydration|runtime|react|astro|vite/iu.test(message)) return "client-runtime";
188
+ return message.slice(0, 140);
189
+ }
190
+ function errorIncidentCode(error) {
191
+ const normalized = normalizedErrorMessage(error);
192
+ if (normalized === "http-500") return "visual.client.http_500";
193
+ if (normalized === "http-404") return "visual.client.http_404";
194
+ if (normalized === "request-aborted") return "visual.client.request_aborted";
195
+ if (normalized === "client-runtime") return "visual.client.runtime_error";
196
+ if (error.kind === "pageerror" || error.kind === "uncaught-exception") return "visual.client.page_error";
197
+ if (error.kind === "http-error") return "visual.client.http_subresource_error";
198
+ if (error.kind === "requestfailed") return "visual.client.request_failed";
199
+ return "visual.client.console_error";
200
+ }
201
+ function incidentTitle(code) {
202
+ if (code === "visual.client.http_500") return "Routes return HTTP 500";
203
+ if (code === "visual.client.http_404") return "Routes reference missing HTTP 404 resources";
204
+ if (code === "visual.client.request_aborted") return "Requests abort during navigation";
205
+ if (code === "visual.client.runtime_error") return "Client runtime errors occur";
206
+ if (code === "visual.client.page_error") return "Uncaught page errors occur";
207
+ return "Client-side errors occur";
208
+ }
209
+ function incidentSeverity(error) {
210
+ if (error.kind === "pageerror" || error.kind === "uncaught-exception") return "blocking";
211
+ if ((error.status ?? 0) >= 500 || normalizedErrorMessage(error) === "http-500") return "high";
212
+ if ((error.status ?? 0) >= 400 || normalizedErrorMessage(error) === "http-404") return "medium";
213
+ if (normalizedErrorMessage(error) === "request-aborted") return "medium";
214
+ return error.severity === "error" ? "high" : "medium";
215
+ }
216
+ function incidentKey(error) {
217
+ return [
218
+ errorIncidentCode(error),
219
+ pathOwner(error.path),
220
+ error.pathRoot,
221
+ normalizedErrorMessage(error)
222
+ ].join("|");
223
+ }
224
+ function buildClientErrorIncidents(errors) {
225
+ const grouped = /* @__PURE__ */ new Map();
226
+ for (const error of errors) {
227
+ if (normalizedErrorMessage(error) === "request-aborted" && error.finalUrl) continue;
228
+ const list = grouped.get(incidentKey(error)) ?? [];
229
+ list.push(error);
230
+ grouped.set(incidentKey(error), list);
231
+ }
232
+ const output = [];
233
+ let index = 0;
234
+ for (const list of grouped.values()) {
235
+ const first = list[0];
236
+ if (!first) continue;
237
+ const code = errorIncidentCode(first);
238
+ const owner = pathOwner(first.path);
239
+ const paths = compactList(list.map((entry) => entry.path));
240
+ const pathRoots = compactList(list.map((entry) => entry.pathRoot));
241
+ const roles = compactList(list.map((entry) => entry.role));
242
+ const devices = compactList(list.map((entry) => entry.device));
243
+ const captureIds = compactList(list.map((entry) => entry.captureId));
244
+ const severity = list.reduce((best, entry) => severityRank(incidentSeverity(entry)) < severityRank(best) ? incidentSeverity(entry) : best, incidentSeverity(first));
245
+ const score = priorityScore({
246
+ severity,
247
+ category: "client-error",
248
+ owner,
249
+ count: list.length,
250
+ pathCount: paths.length,
251
+ roleCount: roles.length,
252
+ deviceCount: devices.length,
253
+ code
254
+ });
255
+ output.push({
256
+ id: `incident-${String(index += 1).padStart(3, "0")}`,
257
+ severity,
258
+ primaryKind: first.kind,
259
+ code,
260
+ title: incidentTitle(code),
261
+ message: `${first.message} Seen ${list.length} raw event(s) across ${paths.length} path(s), ${roles.length} role(s), and ${devices.length} device profile(s).`,
262
+ normalizedMessage: normalizedErrorMessage(first),
263
+ suspectedOwner: owner,
264
+ count: list.length,
265
+ pathRoots,
266
+ paths,
267
+ roles,
268
+ devices,
269
+ captureIds,
270
+ errorIds: list.map((entry) => entry.id),
271
+ exampleScreenshotPath: list.find((entry) => entry.screenshotPath)?.screenshotPath ?? null,
272
+ exampleFinalUrl: first.finalUrl,
273
+ status: first.status ?? null,
274
+ url: first.url,
275
+ priorityScore: score,
276
+ priorityRank: 0,
277
+ recommendedAction: recommendedAction(owner, code),
278
+ architectureGuidance: guidance(owner, code)
279
+ });
280
+ }
281
+ return output.sort((a, b) => b.priorityScore - a.priorityScore || severityRank(a.severity) - severityRank(b.severity) || b.count - a.count).map((entry, priorityRank) => ({ ...entry, priorityRank: priorityRank + 1 }));
282
+ }
283
+ function incidentFindings(incidents, captures, indexStart) {
284
+ const byId = new Map(captures.map((capture) => [capture.id, capture]));
285
+ const output = [];
286
+ let index = indexStart;
287
+ for (const incident of incidents) {
288
+ const capture = incident.captureIds.map((id) => byId.get(id)).find(Boolean);
289
+ if (!capture) continue;
290
+ output.push(finding({
291
+ index: index += 1,
292
+ capture,
293
+ severity: incident.severity,
294
+ category: "client-error",
295
+ code: incident.code,
296
+ title: incident.title,
297
+ message: incident.message,
298
+ owner: incident.suspectedOwner,
299
+ evidence: { incidentId: incident.id, rawErrorCount: incident.count, errorIds: incident.errorIds.slice(0, 20) }
300
+ }));
301
+ }
302
+ return output;
303
+ }
304
+ function architectureFindings(captures, findings, indexStart) {
305
+ const output = [];
306
+ let index = indexStart;
307
+ const sample = captures.find((capture) => capture.path.startsWith("/app")) ?? captures[0];
308
+ if (!sample) return output;
309
+ const repeated = (code) => findings.filter((entry) => entry.code === code);
310
+ const push = (code, title, message, owner, evidence) => {
311
+ output.push(finding({ index: index += 1, capture: sample, severity: "high", category: "architecture", code, title, message, owner, evidence }));
312
+ };
313
+ if (new Set(repeated("visual.display.default_link_style").map((entry) => entry.path)).size >= 2 || new Set(repeated("visual.display.default_button_style").map((entry) => entry.path)).size >= 2) {
314
+ push("visual.architecture.shared_ui_control_regression", "Repeated shared UI control styling regression", "Default-looking links or buttons repeat across multiple routes. Treat this as a shared UI package styling/component contract issue first.", "@treeseed/ui", { findingCodes: ["visual.display.default_link_style", "visual.display.default_button_style"] });
315
+ }
316
+ if (new Set(findings.filter((entry) => entry.code === "visual.functional.auth_redirect_unexpected").map((entry) => entry.path)).size >= 3) {
317
+ push("visual.architecture.admin_shell_regression", "Repeated authenticated route redirect regression", "Multiple authenticated app routes redirected to auth. Inspect admin session/shell behavior before fixing individual pages.", "@treeseed/admin", {});
318
+ }
319
+ if (new Set(findings.filter((entry) => entry.code === "visual.functional.seeded_entity_missing").map((entry) => entry.path)).size >= 3) {
320
+ push("visual.architecture.api_fixture_or_access_regression", "Repeated seeded entity visibility regression", "Seeded fixture entities are missing on multiple app routes. Verify API fixture/session/data behavior before page-local fixes.", "@treeseed/api", {});
321
+ }
322
+ return output;
323
+ }
324
+ function severityRank(value) {
325
+ return SEVERITIES.indexOf(value);
326
+ }
327
+ function filteredFindings(findings, detail, maxFindings) {
328
+ const sorted = [...findings].sort((a, b) => severityRank(a.severity) - severityRank(b.severity) || a.path.localeCompare(b.path) || a.code.localeCompare(b.code));
329
+ const byDetail = detail === "summary" ? sorted.filter((entry) => entry.severity === "blocking" || entry.severity === "high") : sorted;
330
+ return byDetail.slice(0, maxFindings);
331
+ }
332
+ function expectedFindingNoise(findingEntry) {
333
+ if (findingEntry.pathRoot !== "/404") return false;
334
+ if (findingEntry.code === "visual.functional.http_error") return true;
335
+ if (findingEntry.code === "visual.display.visible_error_text") return true;
336
+ if (findingEntry.code === "visual.client.console_error" && /404|not found/iu.test(findingEntry.message)) return true;
337
+ return false;
338
+ }
339
+ function messageSignature(findingEntry) {
340
+ const evidence = JSON.stringify(findingEntry.evidence);
341
+ if (/ENOENT.+starlight\/routes\/ssr/isu.test(findingEntry.message) || /starlight\/routes\/ssr/iu.test(evidence)) return "missing-starlight-ssr-vendor";
342
+ if (/HTTP\s+500/iu.test(findingEntry.message) || findingEntry.message.includes("Internal Server Error")) return "http-500";
343
+ if (/HTTP\s+404|status of 404|not found/iu.test(findingEntry.message)) return "http-404";
344
+ if (/ERR_ABORTED/iu.test(findingEntry.message)) return "request-aborted";
345
+ if (/hydration|runtime|react|astro|vite/iu.test(findingEntry.message)) return "client-runtime";
346
+ return findingEntry.message.replace(/\bhttps?:\/\/\S+/giu, "<url>").replace(/\s+/gu, " ").slice(0, 90);
347
+ }
348
+ function rootCauseKey(findingEntry) {
349
+ if (findingEntry.category === "architecture") return `${findingEntry.code}|${findingEntry.suspectedOwner}`;
350
+ if (findingEntry.code === "visual.display.default_link_style" || findingEntry.code === "visual.display.default_button_style") return `${findingEntry.code}|${findingEntry.suspectedOwner}|shared-controls`;
351
+ if (findingEntry.code === "visual.functional.seeded_entity_missing") return `${findingEntry.code}|${findingEntry.suspectedOwner}|${findingEntry.pathRoot}`;
352
+ if (findingEntry.code === "visual.functional.final_url_mismatch") return `${findingEntry.code}|${findingEntry.suspectedOwner}|${findingEntry.pathRoot}`;
353
+ if (findingEntry.category === "client-error" || findingEntry.code === "visual.functional.http_error" || findingEntry.code === "visual.display.visible_error_text" || findingEntry.code === "visual.display.blank_or_low_content") {
354
+ return `visual.runtime_or_empty_route|${findingEntry.suspectedOwner}|${findingEntry.pathRoot}|${messageSignature(findingEntry)}`;
355
+ }
356
+ return `${findingEntry.code}|${findingEntry.suspectedOwner}|${findingEntry.pathRoot}`;
357
+ }
358
+ function compactList(values) {
359
+ return [...new Set(values)].sort();
360
+ }
361
+ function rootCauseTitle(findings) {
362
+ const first = findings[0];
363
+ if (!first) return "Visual audit finding cluster";
364
+ if (first.code === "visual.display.default_link_style" || first.code === "visual.display.default_button_style") return "Shared UI controls are falling back to browser-default styling";
365
+ if (first.code === "visual.functional.seeded_entity_missing") return "Seeded visual-audit entities are missing from app routes";
366
+ if (first.code === "visual.functional.final_url_mismatch") return "Routes end at unexpected final URLs";
367
+ if (messageSignature(first) === "missing-starlight-ssr-vendor") return "Routes fail because the Core/Starlight SSR vendor file is missing";
368
+ if (messageSignature(first) === "http-500") return "Routes return HTTP 500";
369
+ if (messageSignature(first) === "http-404") return "Routes return HTTP 404";
370
+ if (messageSignature(first) === "request-aborted") return "Requests abort during navigation";
371
+ if (messageSignature(first) === "client-runtime") return "Client runtime errors are visible in the browser";
372
+ if (first.code === "visual.display.blank_or_low_content") return "Routes render blank or very low-content pages";
373
+ return first.title;
374
+ }
375
+ function rootCauseMessage(findings) {
376
+ const first = findings[0];
377
+ if (!first) return "";
378
+ const paths = compactList(findings.map((entry) => entry.path));
379
+ const roles = compactList(findings.map((entry) => entry.role));
380
+ const devices = compactList(findings.map((entry) => entry.device));
381
+ return `${first.message} Seen ${findings.length} time(s) across ${paths.length} path(s), ${roles.length} role(s), and ${devices.length} device profile(s).`;
382
+ }
383
+ function buildRootCauses(findings) {
384
+ const grouped = /* @__PURE__ */ new Map();
385
+ for (const findingEntry of findings) {
386
+ const key = rootCauseKey(findingEntry);
387
+ const list = grouped.get(key) ?? [];
388
+ list.push(findingEntry);
389
+ grouped.set(key, list);
390
+ }
391
+ const output = [];
392
+ let index = 0;
393
+ for (const list of grouped.values()) {
394
+ const sorted = [...list].sort((a, b) => severityRank(a.severity) - severityRank(b.severity) || a.path.localeCompare(b.path));
395
+ const first = sorted[0];
396
+ if (!first) continue;
397
+ const pathRoots = compactList(sorted.map((entry) => entry.pathRoot));
398
+ const paths = compactList(sorted.map((entry) => entry.path));
399
+ const roles = compactList(sorted.map((entry) => entry.role));
400
+ const devices = compactList(sorted.map((entry) => entry.device));
401
+ const captureIds = compactList(sorted.map((entry) => entry.captureId));
402
+ const severity = sorted.reduce((best, entry) => severityRank(entry.severity) < severityRank(best) ? entry.severity : best, first.severity);
403
+ const score = priorityScore({
404
+ severity,
405
+ category: first.category,
406
+ owner: first.suspectedOwner,
407
+ count: sorted.length,
408
+ pathCount: paths.length,
409
+ roleCount: roles.length,
410
+ deviceCount: devices.length,
411
+ code: first.code
412
+ });
413
+ output.push({
414
+ id: `root-cause-${String(index += 1).padStart(3, "0")}`,
415
+ severity,
416
+ category: first.category,
417
+ code: first.code,
418
+ title: rootCauseTitle(sorted),
419
+ message: rootCauseMessage(sorted),
420
+ suspectedOwner: first.suspectedOwner,
421
+ count: sorted.length,
422
+ pathRoots,
423
+ paths,
424
+ roles,
425
+ devices,
426
+ findingIds: sorted.map((entry) => entry.id),
427
+ captureIds,
428
+ exampleScreenshotPath: sorted.find((entry) => entry.screenshotPath)?.screenshotPath ?? null,
429
+ architectureGuidance: first.architectureGuidance,
430
+ recommendedAction: recommendedAction(first.suspectedOwner, first.code),
431
+ priorityScore: score,
432
+ priorityRank: 0,
433
+ impact: {
434
+ pathCount: paths.length,
435
+ roleCount: roles.length,
436
+ deviceCount: devices.length,
437
+ captureCount: captureIds.length
438
+ },
439
+ query: {
440
+ owner: first.suspectedOwner,
441
+ severity,
442
+ code: first.code,
443
+ pathRoots
444
+ }
445
+ });
446
+ }
447
+ return output.sort((a, b) => b.priorityScore - a.priorityScore || severityRank(a.severity) - severityRank(b.severity) || b.count - a.count || a.title.localeCompare(b.title)).map((entry, priorityRank) => ({ ...entry, priorityRank: priorityRank + 1 }));
448
+ }
449
+ function enrichClientErrors(captures) {
450
+ return captures.flatMap((capture) => (capture.clientErrors ?? []).filter((entry) => !isTreeseedSceneVisualAuditIgnoredClientError(entry)).map((entry) => ({
451
+ ...entry,
452
+ path: capture.path,
453
+ pathRoot: capture.pathRoot,
454
+ role: capture.role,
455
+ device: capture.device,
456
+ screenshotPath: capture.screenshotPath,
457
+ finalUrl: capture.finalUrl
458
+ })));
459
+ }
460
+ function buildTreeseedSceneVisualAuditReview(input) {
461
+ const detail = input.detail ?? "standard";
462
+ const allFindings = [];
463
+ const routesById = new Map(input.manifest.routes.map((route) => [route.id, route]));
464
+ for (const capture of input.manifest.captures) allFindings.push(...captureFindings(capture, allFindings.length, routesById.get(capture.routeId)));
465
+ const clientErrors = enrichClientErrors(input.manifest.captures);
466
+ const incidents = buildClientErrorIncidents(clientErrors);
467
+ allFindings.push(...incidentFindings(incidents, input.manifest.captures, allFindings.length));
468
+ allFindings.push(...architectureFindings(input.manifest.captures, allFindings, allFindings.length));
469
+ const findings = filteredFindings(allFindings, detail, input.maxFindings ?? 250);
470
+ const rootCauses = buildRootCauses(allFindings.filter((entry) => !expectedFindingNoise(entry)));
471
+ const bySeverity = countMap(SEVERITIES);
472
+ const byCategory = countMap(CATEGORIES);
473
+ const byOwner = countMap(OWNERS);
474
+ const byPriorityBand = { critical: 0, high: 0, medium: 0, low: 0 };
475
+ const byPathRoot = {};
476
+ for (const entry of allFindings) {
477
+ bySeverity[entry.severity] += 1;
478
+ byCategory[entry.category] += 1;
479
+ byOwner[entry.suspectedOwner] += 1;
480
+ byPathRoot[entry.pathRoot] = (byPathRoot[entry.pathRoot] ?? 0) + 1;
481
+ }
482
+ for (const entry of rootCauses) byPriorityBand[priorityBand(entry.priorityScore)] += 1;
483
+ const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
484
+ const diagnostics = [];
485
+ return {
486
+ schemaVersion: "treeseed.scene.visual-audit-review/v1",
487
+ generatedAt,
488
+ auditId: input.manifest.auditId,
489
+ sceneId: input.manifest.sceneId,
490
+ summary: {
491
+ generatedAt,
492
+ detail,
493
+ routeCount: input.manifest.routes.length,
494
+ captureCount: input.manifest.captures.length,
495
+ findingCount: allFindings.length,
496
+ rootCauseCount: rootCauses.length,
497
+ incidentCount: incidents.length,
498
+ clientErrorCount: clientErrors.length,
499
+ highestPriorityScore: rootCauses[0]?.priorityScore ?? incidents[0]?.priorityScore ?? 0,
500
+ byPriorityBand,
501
+ bySeverity,
502
+ byCategory,
503
+ byOwner,
504
+ byPathRoot
505
+ },
506
+ findings,
507
+ rootCauses,
508
+ incidents,
509
+ clientErrors,
510
+ diagnostics
511
+ };
512
+ }
513
+ function rootCauseTable(input) {
514
+ const lines = [
515
+ "| Rank | Score | Severity | Owner | Count | Root cause | Examples | Screenshot |",
516
+ "| ---: | ---: | --- | --- | ---: | --- | --- | --- |"
517
+ ];
518
+ for (const entry of input.rootCauses) {
519
+ const screenshot = entry.exampleScreenshotPath ? `[view](${md(rel(input.paths.auditRoot, entry.exampleScreenshotPath))})` : "";
520
+ lines.push(`| ${entry.priorityRank} | ${entry.priorityScore} | ${entry.severity} | ${md(entry.suspectedOwner)} | ${entry.count} | ${md(entry.title)} | ${md(entry.paths.slice(0, 4).join(", "))} | ${screenshot} |`);
521
+ }
522
+ return lines;
523
+ }
524
+ function issueSummary(entry) {
525
+ return {
526
+ id: entry.id,
527
+ priorityRank: entry.priorityRank,
528
+ priorityScore: entry.priorityScore,
529
+ severity: entry.severity,
530
+ owner: entry.suspectedOwner,
531
+ category: "category" in entry ? entry.category : "client-error",
532
+ code: entry.code,
533
+ title: entry.title,
534
+ count: entry.count,
535
+ pathRoots: entry.pathRoots,
536
+ paths: entry.paths,
537
+ roles: entry.roles,
538
+ devices: entry.devices,
539
+ exampleScreenshotPath: entry.exampleScreenshotPath,
540
+ recommendedAction: entry.recommendedAction
541
+ };
542
+ }
543
+ function combinedPriorityQueue(review) {
544
+ return [...review.rootCauses.map(issueSummary), ...review.incidents.map(issueSummary)].sort((a, b) => b.priorityScore - a.priorityScore || a.priorityRank - b.priorityRank);
545
+ }
546
+ function groupBy(items, key) {
547
+ const groups = {};
548
+ for (const item of items) {
549
+ const keys = key(item);
550
+ for (const entry of Array.isArray(keys) ? keys : [keys]) {
551
+ groups[entry] = [...groups[entry] ?? [], item];
552
+ }
553
+ }
554
+ return groups;
555
+ }
556
+ function jsonl(items) {
557
+ return items.map((entry) => JSON.stringify(entry)).join("\n") + (items.length ? "\n" : "");
558
+ }
559
+ function formatTreeseedSceneVisualAuditFindingsMarkdown(input) {
560
+ const lines = [
561
+ "# TreeSeed Visual Audit Findings",
562
+ "",
563
+ `Scene: ${input.manifest.sceneId ?? "(unknown)"}`,
564
+ `Audit: ${input.manifest.auditId}`,
565
+ `Generated: ${input.review.generatedAt}`,
566
+ "",
567
+ "## Summary",
568
+ "",
569
+ `- Findings: ${input.review.summary.findingCount}`,
570
+ `- Root causes: ${input.review.summary.rootCauseCount}`,
571
+ `- Incidents: ${input.review.summary.incidentCount}`,
572
+ `- Included findings: ${input.review.findings.length}`,
573
+ `- Raw client errors: ${input.review.summary.clientErrorCount}`,
574
+ "",
575
+ "## Root Causes",
576
+ "",
577
+ ...rootCauseTable({ paths: input.paths, rootCauses: input.review.rootCauses }),
578
+ "",
579
+ "## Findings",
580
+ "",
581
+ "| Severity | Category | Code | Owner | Role | Device | Path | Screenshot |",
582
+ "| --- | --- | --- | --- | --- | --- | --- | --- |"
583
+ ];
584
+ for (const entry of input.review.findings) {
585
+ const screenshot = entry.screenshotPath ? `[view](${md(rel(input.paths.auditRoot, entry.screenshotPath))})` : "";
586
+ lines.push(`| ${entry.severity} | ${entry.category} | ${md(entry.code)} | ${md(entry.suspectedOwner)} | ${md(entry.role)} | ${md(entry.device)} | ${md(entry.path)} | ${screenshot} |`);
587
+ lines.push(`| | | | | | | ${md(entry.message)} ${md(entry.architectureGuidance)} | |`);
588
+ }
589
+ lines.push("");
590
+ return `${lines.join("\n")}
591
+ `;
592
+ }
593
+ function formatTreeseedSceneVisualAuditAgentBrief(input) {
594
+ const high = input.review.findings.filter((entry) => entry.severity === "blocking" || entry.severity === "high");
595
+ const client = input.review.findings.filter((entry) => entry.category === "client-error" && !expectedFindingNoise(entry));
596
+ const architecture = input.review.findings.filter((entry) => entry.category === "architecture");
597
+ const priorityQueue = combinedPriorityQueue(input.review).slice(0, 50);
598
+ const lines = [
599
+ "# Visual Audit Agent Brief",
600
+ "",
601
+ "## Mission",
602
+ "",
603
+ "Repair TreeSeed UI and functionality issues found by visual audit. Prefer reusable architecture fixes over route-local patches. Client-side browser/runtime errors are the first priority because the admin application is moving toward a progressively client-dominant architecture and reusable UI package foundation.",
604
+ "",
605
+ "## Priority Queue",
606
+ "",
607
+ "| Rank | Score | Severity | Owner | Count | Issue | Roots | Evidence |",
608
+ "| ---: | ---: | --- | --- | ---: | --- | --- | --- |"
609
+ ];
610
+ for (const entry of priorityQueue) {
611
+ const screenshot = entry.exampleScreenshotPath ? rel(input.paths.auditRoot, entry.exampleScreenshotPath) : "";
612
+ lines.push(`| ${entry.priorityRank} | ${entry.priorityScore} | ${entry.severity} | ${md(entry.owner)} | ${entry.count} | ${md(entry.title)} | ${md(entry.pathRoots.join(", "))} | ${screenshot ? `[view](${md(screenshot)})` : ""} |`);
613
+ }
614
+ lines.push(
615
+ "",
616
+ "## Raw Client Error Interpretation",
617
+ "",
618
+ "Raw client errors are preserved in `client-errors.jsonl`, but prioritized work should start from `incidents.json` and `root-causes.json` because browser console/resource events can duplicate the same route failure.",
619
+ "",
620
+ "## Root Causes To Assign First",
621
+ ""
622
+ );
623
+ for (const entry of input.review.rootCauses.slice(0, 25)) {
624
+ const screenshot = entry.exampleScreenshotPath ? rel(input.paths.auditRoot, entry.exampleScreenshotPath) : "(none)";
625
+ lines.push(`- **#${entry.priorityRank} score ${entry.priorityScore} ${entry.severity} ${entry.suspectedOwner}** ${entry.title}`);
626
+ lines.push(` - Count: ${entry.count}; roots: ${entry.pathRoots.join(", ")}; roles: ${entry.roles.join(", ")}; devices: ${entry.devices.join(", ")}`);
627
+ lines.push(` - Example: ${entry.paths[0] ?? "(none)"}`);
628
+ lines.push(` - Screenshot: ${screenshot}`);
629
+ lines.push(` - Action: ${entry.recommendedAction}`);
630
+ }
631
+ lines.push(
632
+ "",
633
+ "## Critical Client-Side Errors",
634
+ ""
635
+ );
636
+ if (client.length === 0) lines.push("No client-side errors were detected in the included findings.", "");
637
+ for (const entry of client.slice(0, 50)) lines.push(`- **${entry.severity}** ${entry.path} ${entry.role}/${entry.device}: ${entry.message}`);
638
+ lines.push("", "## Client Error Incidents", "");
639
+ if (input.review.incidents.length === 0) lines.push("No client-error incidents were detected.", "");
640
+ for (const entry of input.review.incidents.slice(0, 50)) lines.push(`- **#${entry.priorityRank} score ${entry.priorityScore} ${entry.severity} ${entry.suspectedOwner}** ${entry.title}: ${entry.count} raw event(s), roots ${entry.pathRoots.join(", ")}`);
641
+ lines.push("", "## Highest Priority Findings", "");
642
+ for (const entry of high.filter((entry2) => !expectedFindingNoise(entry2)).slice(0, 75)) lines.push(`- **${entry.severity} ${entry.code}** ${entry.path} ${entry.role}/${entry.device} (${entry.suspectedOwner}): ${entry.message}`);
643
+ lines.push(
644
+ "",
645
+ "## Architecture Guidance",
646
+ "",
647
+ "- Fix shared controls/styles in `@treeseed/ui` when repeated across routes.",
648
+ "- Fix admin composition, client initialization, state, auth, and access in `@treeseed/admin`.",
649
+ "- Fix public/book style loading in `@treeseed/core`.",
650
+ "- Fix tenant branding only in `@treeseed/market`.",
651
+ "- Fix API/database fixture/access issues in `@treeseed/api`.",
652
+ "- Do not add divergent one-off CSS unless the route is genuinely unique.",
653
+ "",
654
+ "## Architecture Findings",
655
+ ""
656
+ );
657
+ if (architecture.length === 0) lines.push("No aggregate architecture findings were generated.", "");
658
+ for (const entry of architecture) lines.push(`- **${entry.code}** (${entry.suspectedOwner}): ${entry.message}`);
659
+ lines.push(
660
+ "",
661
+ "## Suggested Work Batches",
662
+ "",
663
+ "### Batch 1: Client Runtime Errors",
664
+ "Fix console, page, request, hydration, and visible runtime errors before visual polish.",
665
+ "",
666
+ "### Batch 2: Shared UI Control Regressions",
667
+ "Resolve repeated default link/button/form/control issues in `@treeseed/ui`.",
668
+ "",
669
+ "### Batch 3: Admin Access And Seeded Data Visibility",
670
+ "Verify app shell routing, team/project membership, and seeded visual-audit entities.",
671
+ "",
672
+ "### Batch 4: Responsive And Mobile Issues",
673
+ "Fix overflow, desktop layout leakage, and cramped mobile/tablet surfaces.",
674
+ "",
675
+ "### Batch 5: Public, Book, And Market Polish",
676
+ "Restore public shell, book page, and tenant branding consistency.",
677
+ "",
678
+ "## Findings",
679
+ ""
680
+ );
681
+ for (const entry of input.review.findings) {
682
+ const screenshot = entry.screenshotPath ? rel(input.paths.auditRoot, entry.screenshotPath) : "(none)";
683
+ lines.push(`- **${entry.severity} ${entry.code}** ${entry.path} ${entry.role}/${entry.device} -> ${entry.suspectedOwner}`);
684
+ lines.push(` - ${entry.message}`);
685
+ lines.push(` - Screenshot: ${screenshot}`);
686
+ lines.push(` - Guidance: ${entry.architectureGuidance}`);
687
+ }
688
+ lines.push("");
689
+ return `${lines.join("\n")}
690
+ `;
691
+ }
692
+ function formatOwnerBrief(input) {
693
+ const rootCauses = input.review.rootCauses.filter((entry) => entry.suspectedOwner === input.owner);
694
+ const incidents = input.review.incidents.filter((entry) => entry.suspectedOwner === input.owner);
695
+ const priorityQueue = combinedPriorityQueue(input.review).filter((entry) => entry.owner === input.owner).slice(0, 50);
696
+ const findings = input.review.findings.filter((entry) => entry.suspectedOwner === input.owner && !expectedFindingNoise(entry));
697
+ const lines = [
698
+ `# Visual Audit Brief: ${input.owner}`,
699
+ "",
700
+ `Scene: ${input.manifest.sceneId ?? "(unknown)"}`,
701
+ `Audit: ${input.manifest.auditId}`,
702
+ "",
703
+ "## Package Boundary",
704
+ "",
705
+ guidance(input.owner, "visual.audit"),
706
+ "",
707
+ "## Priority Queue",
708
+ "",
709
+ "| Rank | Score | Severity | Count | Issue | Roots | Evidence |",
710
+ "| ---: | ---: | --- | ---: | --- | --- | --- |"
711
+ ];
712
+ for (const entry of priorityQueue) {
713
+ const screenshot = entry.exampleScreenshotPath ? rel(input.paths.auditRoot, entry.exampleScreenshotPath) : "";
714
+ lines.push(`| ${entry.priorityRank} | ${entry.priorityScore} | ${entry.severity} | ${entry.count} | ${md(entry.title)} | ${md(entry.pathRoots.join(", "))} | ${screenshot ? `[view](${md(screenshot)})` : ""} |`);
715
+ }
716
+ if (priorityQueue.length === 0) lines.push("| | | | | No prioritized issues were assigned to this owner. | | |");
717
+ lines.push(
718
+ "",
719
+ "## Root Causes",
720
+ ""
721
+ );
722
+ if (rootCauses.length === 0) lines.push("No root causes were assigned to this owner.", "");
723
+ for (const entry of rootCauses) {
724
+ const screenshot = entry.exampleScreenshotPath ? rel(input.paths.auditRoot, entry.exampleScreenshotPath) : "(none)";
725
+ lines.push(`- **#${entry.priorityRank} score ${entry.priorityScore} ${entry.severity}** ${entry.title}`);
726
+ lines.push(` - Count: ${entry.count}`);
727
+ lines.push(` - Path roots: ${entry.pathRoots.join(", ")}`);
728
+ lines.push(` - Roles/devices: ${entry.roles.join(", ")} / ${entry.devices.join(", ")}`);
729
+ lines.push(` - Example screenshot: ${screenshot}`);
730
+ lines.push(` - Recommended action: ${entry.recommendedAction}`);
731
+ }
732
+ lines.push("", "## Client Error Incidents", "");
733
+ if (incidents.length === 0) lines.push("No client-error incidents were assigned to this owner.", "");
734
+ for (const entry of incidents.slice(0, 80)) {
735
+ const screenshot = entry.exampleScreenshotPath ? rel(input.paths.auditRoot, entry.exampleScreenshotPath) : "(none)";
736
+ lines.push(`- **#${entry.priorityRank} score ${entry.priorityScore} ${entry.severity} ${entry.code}** ${entry.title}`);
737
+ lines.push(` - Count: ${entry.count}`);
738
+ lines.push(` - Path roots: ${entry.pathRoots.join(", ")}`);
739
+ lines.push(` - Example screenshot: ${screenshot}`);
740
+ lines.push(` - Recommended action: ${entry.recommendedAction}`);
741
+ }
742
+ lines.push("", "## Representative Findings", "");
743
+ for (const entry of findings.slice(0, 80)) {
744
+ const screenshot = entry.screenshotPath ? rel(input.paths.auditRoot, entry.screenshotPath) : "(none)";
745
+ lines.push(`- **${entry.severity} ${entry.code}** ${entry.path} ${entry.role}/${entry.device}`);
746
+ lines.push(` - ${entry.message}`);
747
+ lines.push(` - Screenshot: ${screenshot}`);
748
+ }
749
+ lines.push("");
750
+ return `${lines.join("\n")}
751
+ `;
752
+ }
753
+ function writeTreeseedSceneVisualAuditReview(input) {
754
+ if (!input.paths.reviewRoot || !input.paths.reviewSummaryPath || !input.paths.reviewFindingsPath || !input.paths.reviewAgentBriefPath) return;
755
+ mkdirSync(input.paths.reviewRoot, { recursive: true });
756
+ const priorityQueue = combinedPriorityQueue(input.review);
757
+ const issueIndex = {
758
+ schemaVersion: "treeseed.scene.visual-audit-issue-index/v1",
759
+ generatedAt: input.review.generatedAt,
760
+ auditId: input.manifest.auditId,
761
+ rootCauses: input.review.rootCauses.map(issueSummary),
762
+ files: {
763
+ rootCauses: "root-causes.json",
764
+ incidents: "incidents.json",
765
+ findings: "findings.json",
766
+ clientErrors: "client-errors.jsonl",
767
+ contactSheets: "contact-sheets/index.html",
768
+ flaggedContactSheet: "contact-sheets/flagged.html",
769
+ rootCauseContactSheet: "contact-sheets/root-causes.html"
770
+ }
771
+ };
772
+ writeFileSync(input.paths.reviewSummaryPath, `${JSON.stringify(input.review.summary, null, 2)}
773
+ `, "utf8");
774
+ writeFileSync(input.paths.reviewFindingsPath, `${JSON.stringify(input.review.findings, null, 2)}
775
+ `, "utf8");
776
+ writeFileSync(`${input.paths.reviewRoot}/findings.jsonl`, jsonl(input.review.findings), "utf8");
777
+ writeFileSync(`${input.paths.reviewRoot}/root-causes.json`, `${JSON.stringify(input.review.rootCauses, null, 2)}
778
+ `, "utf8");
779
+ writeFileSync(`${input.paths.reviewRoot}/root-causes.jsonl`, jsonl(input.review.rootCauses), "utf8");
780
+ writeFileSync(`${input.paths.reviewRoot}/incidents.json`, `${JSON.stringify(input.review.incidents, null, 2)}
781
+ `, "utf8");
782
+ writeFileSync(`${input.paths.reviewRoot}/incidents.jsonl`, jsonl(input.review.incidents), "utf8");
783
+ writeFileSync(`${input.paths.reviewRoot}/issue-index.json`, `${JSON.stringify(issueIndex, null, 2)}
784
+ `, "utf8");
785
+ writeFileSync(input.paths.reviewAgentBriefPath, formatTreeseedSceneVisualAuditAgentBrief(input), "utf8");
786
+ writeFileSync(`${input.paths.reviewRoot}/findings.md`, formatTreeseedSceneVisualAuditFindingsMarkdown(input), "utf8");
787
+ writeFileSync(`${input.paths.reviewRoot}/client-errors.jsonl`, input.review.clientErrors.map((entry) => JSON.stringify(entry)).join("\n") + (input.review.clientErrors.length ? "\n" : ""), "utf8");
788
+ const queryRoot = `${input.paths.reviewRoot}/query`;
789
+ mkdirSync(queryRoot, { recursive: true });
790
+ writeFileSync(`${queryRoot}/top-priority.json`, `${JSON.stringify(priorityQueue.slice(0, 50), null, 2)}
791
+ `, "utf8");
792
+ writeFileSync(`${queryRoot}/by-owner.json`, `${JSON.stringify(groupBy(priorityQueue, (entry) => entry.owner), null, 2)}
793
+ `, "utf8");
794
+ writeFileSync(`${queryRoot}/by-path-root.json`, `${JSON.stringify(groupBy(priorityQueue, (entry) => entry.pathRoots), null, 2)}
795
+ `, "utf8");
796
+ writeFileSync(`${queryRoot}/by-route.json`, `${JSON.stringify(groupBy(priorityQueue, (entry) => entry.paths), null, 2)}
797
+ `, "utf8");
798
+ writeFileSync(`${queryRoot}/by-role.json`, `${JSON.stringify(groupBy(priorityQueue, (entry) => entry.roles), null, 2)}
799
+ `, "utf8");
800
+ writeFileSync(`${queryRoot}/by-device.json`, `${JSON.stringify(groupBy(priorityQueue, (entry) => entry.devices), null, 2)}
801
+ `, "utf8");
802
+ writeFileSync(`${queryRoot}/by-code.json`, `${JSON.stringify(groupBy(priorityQueue, (entry) => entry.code), null, 2)}
803
+ `, "utf8");
804
+ writeFileSync(`${queryRoot}/by-priority.json`, `${JSON.stringify(groupBy(priorityQueue, (entry) => priorityBand(entry.priorityScore)), null, 2)}
805
+ `, "utf8");
806
+ const ownerRoot = `${input.paths.reviewRoot}/owner-briefs`;
807
+ mkdirSync(ownerRoot, { recursive: true });
808
+ for (const owner of OWNERS) {
809
+ const filename = owner.replace(/^@/u, "").replace(/[^a-z0-9-]+/giu, "-").toLowerCase();
810
+ writeFileSync(`${ownerRoot}/${filename}.md`, formatOwnerBrief({ ...input, owner }), "utf8");
811
+ }
812
+ writeFileSync(`${input.paths.reviewRoot}/routes.json`, `${JSON.stringify(input.manifest.routes.map((route) => ({
813
+ id: route.id,
814
+ path: route.path,
815
+ pathRoot: route.pathRoot,
816
+ roles: route.roles,
817
+ source: route.source,
818
+ findings: input.review.findings.filter((finding2) => finding2.path === route.path).length
819
+ })), null, 2)}
820
+ `, "utf8");
821
+ writeTreeseedSceneVisualAuditContactSheets(input);
822
+ }
823
+ export {
824
+ buildTreeseedSceneVisualAuditReview,
825
+ formatTreeseedSceneVisualAuditAgentBrief,
826
+ formatTreeseedSceneVisualAuditFindingsMarkdown,
827
+ isTreeseedSceneVisualAuditIgnoredClientError,
828
+ writeTreeseedSceneVisualAuditReview
829
+ };