spine-framework 0.3.145 → 0.4.0

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 (451) hide show
  1. package/.env.example +76 -0
  2. package/.framework/.spine-manifest.json +19 -0
  3. package/.framework/cli/commands/agents.ts +61 -33
  4. package/.framework/cli/commands/auth.ts +60 -28
  5. package/.framework/cli/commands/create-app.ts +212 -80
  6. package/.framework/cli/commands/dev.ts +184 -68
  7. package/.framework/cli/commands/doctor.ts +324 -152
  8. package/.framework/cli/commands/generate.ts +119 -68
  9. package/.framework/cli/commands/init.ts +141 -242
  10. package/.framework/cli/commands/install-app.ts +1336 -314
  11. package/.framework/cli/commands/items.ts +31 -29
  12. package/.framework/cli/commands/migrate.ts +299 -156
  13. package/.framework/cli/commands/migrations.ts +62 -30
  14. package/.framework/cli/commands/pipelines.ts +31 -29
  15. package/.framework/cli/commands/status.ts +105 -45
  16. package/.framework/cli/commands/system.ts +47 -42
  17. package/.framework/cli/commands/test.ts +161 -102
  18. package/.framework/cli/commands/upgrade.ts +260 -0
  19. package/.framework/cli/commands/validate-app.ts +517 -161
  20. package/.framework/cli/context.ts +117 -85
  21. package/.framework/cli/env-loader.ts +74 -43
  22. package/.framework/cli/index.ts +70 -46
  23. package/.framework/cli/lib/project-files.ts +404 -0
  24. package/.framework/docs/guides/testing-guide.md +1 -1
  25. package/.framework/docs/runtime-types.md +72 -72
  26. package/.framework/functions/_shared/access.ts +84 -0
  27. package/.framework/functions/_shared/agent-runner.ts +5051 -1026
  28. package/.framework/functions/_shared/app-manifest.ts +214 -94
  29. package/.framework/functions/_shared/ast.ts +214 -0
  30. package/.framework/functions/_shared/audit.ts +91 -55
  31. package/.framework/functions/_shared/cil.ts +368 -127
  32. package/.framework/functions/_shared/db.ts +337 -68
  33. package/.framework/functions/_shared/funnel.ts +228 -0
  34. package/.framework/functions/_shared/geo.ts +105 -0
  35. package/.framework/functions/_shared/hash-api-key.ts +94 -17
  36. package/.framework/functions/_shared/index.ts +22 -224
  37. package/.framework/functions/_shared/kb.ts +832 -58
  38. package/.framework/functions/_shared/llm.ts +118 -18
  39. package/.framework/functions/_shared/logging.ts +317 -19
  40. package/.framework/functions/_shared/middleware.ts +701 -131
  41. package/.framework/functions/_shared/notify.ts +70 -0
  42. package/.framework/functions/_shared/outcomes.ts +34 -19
  43. package/.framework/functions/_shared/permissions.ts +501 -315
  44. package/.framework/functions/_shared/pipeline-runner.ts +704 -155
  45. package/.framework/functions/_shared/principal.ts +436 -263
  46. package/.framework/functions/_shared/rate-limit.ts +233 -0
  47. package/.framework/functions/_shared/resolve-credentials.ts +86 -19
  48. package/.framework/functions/_shared/resolve-ids.ts +203 -139
  49. package/.framework/functions/_shared/retry-deliveries.ts +51 -16
  50. package/.framework/functions/_shared/schema-utils.ts +602 -521
  51. package/.framework/functions/_shared/security.ts +345 -0
  52. package/.framework/functions/_shared/testing.ts +197 -172
  53. package/.framework/functions/_shared/tracing.ts +351 -21
  54. package/.framework/functions/_shared/trigger-engine.ts +425 -136
  55. package/.framework/functions/_shared/webhook-registration.ts +71 -70
  56. package/.framework/functions/_shared/webhook-registry.ts +126 -83
  57. package/.framework/functions/account-nodes.ts +30 -30
  58. package/.framework/functions/adapters/generic-webhook-inbound.ts +49 -16
  59. package/.framework/functions/adapters/generic-webhook-outbound.ts +17 -17
  60. package/.framework/functions/adapters/openai-outbound.ts +15 -16
  61. package/.framework/functions/admin-data.ts +596 -173
  62. package/.framework/functions/admin-funnel.ts +64 -60
  63. package/.framework/functions/admin-install-funnel.ts +84 -66
  64. package/.framework/functions/admin-signals.ts +69 -51
  65. package/.framework/functions/ai-agents.ts +431 -106
  66. package/.framework/functions/ai-interactions.ts +186 -112
  67. package/.framework/functions/api-keys.ts +107 -107
  68. package/.framework/functions/apps.ts +154 -136
  69. package/.framework/functions/auth.ts +83 -65
  70. package/.framework/functions/cil-agent-ingest.ts +189 -232
  71. package/.framework/functions/cil-agent.ts +433 -177
  72. package/.framework/functions/cil-callmap.ts +642 -430
  73. package/.framework/functions/cil-config.ts +139 -135
  74. package/.framework/functions/cil-context.ts +214 -127
  75. package/.framework/functions/cil-doc.ts +587 -458
  76. package/.framework/functions/cil-embeddings.ts +453 -364
  77. package/.framework/functions/cil-graph.ts +427 -142
  78. package/.framework/functions/cil-ingest.ts +1418 -1154
  79. package/.framework/functions/cil-pipeline.ts +276 -21
  80. package/.framework/functions/cil-project.ts +659 -132
  81. package/.framework/functions/cil-validate.ts +198 -164
  82. package/.framework/functions/debug-auth.ts +57 -55
  83. package/.framework/functions/deliveries.ts +80 -21
  84. package/.framework/functions/embeddings.ts +1023 -318
  85. package/.framework/functions/eval-harness.ts +146 -108
  86. package/.framework/functions/integration-outbound.ts +205 -75
  87. package/.framework/functions/integration-routes.ts +128 -23
  88. package/.framework/functions/integrations.ts +125 -100
  89. package/.framework/functions/invites.ts +1095 -460
  90. package/.framework/functions/item-progress.ts +158 -102
  91. package/.framework/functions/kb.ts +34 -10
  92. package/.framework/functions/logs.ts +133 -133
  93. package/.framework/functions/observability.ts +152 -122
  94. package/.framework/functions/pipeline-executions.ts +147 -132
  95. package/.framework/functions/pipelines.ts +134 -119
  96. package/.framework/functions/prompt-configs.ts +96 -80
  97. package/.framework/functions/roles.ts +112 -82
  98. package/.framework/functions/security.ts +450 -0
  99. package/.framework/functions/system-cron.ts +117 -80
  100. package/.framework/functions/system.ts +158 -98
  101. package/.framework/functions/tests.ts +29 -29
  102. package/.framework/functions/timers.ts +94 -95
  103. package/.framework/functions/trigger-scheduler.ts +10 -0
  104. package/.framework/functions/triggers.ts +179 -149
  105. package/.framework/functions/types.ts +137 -125
  106. package/.framework/mcp/index.ts +133 -0
  107. package/.framework/mcp/load-env.ts +60 -0
  108. package/.framework/mcp/shared/app-manifest.ts +275 -0
  109. package/.framework/mcp/shared/db.ts +477 -0
  110. package/.framework/mcp/shared/kb.ts +118 -0
  111. package/.framework/mcp/tools/architect.ts +431 -0
  112. package/.framework/mcp/tools/cil/context.ts +345 -0
  113. package/.framework/mcp/tools/cil/graph.ts +242 -0
  114. package/.framework/mcp/tools/cil/ingest.ts +1217 -0
  115. package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +693 -0
  116. package/.framework/mcp/tools/cil/pipeline.ts +767 -0
  117. package/.framework/mcp/tools/cil/project.ts +791 -0
  118. package/.framework/mcp/tools/cil/retrieval.ts +336 -0
  119. package/.framework/mcp/tools/cil/search-core.ts +454 -0
  120. package/.framework/mcp/tools/cil/search.ts +97 -0
  121. package/.framework/mcp/tools/cil/suggest.ts +186 -0
  122. package/.framework/mcp/tools/cil/validate.ts +1369 -0
  123. package/.framework/mcp/tools/kb/delete.ts +139 -0
  124. package/.framework/mcp/tools/kb/index.ts +52 -0
  125. package/.framework/mcp/tools/kb/ingest.ts +84 -0
  126. package/.framework/mcp/tools/kb/list-types.ts +102 -0
  127. package/.framework/mcp/tools/kb/publish.ts +100 -0
  128. package/.framework/mcp/tools/kb/reindex.ts +86 -0
  129. package/.framework/mcp/tools/kb/revoke.ts +85 -0
  130. package/.framework/mcp/tools/kb/search.ts +101 -0
  131. package/.framework/mcp/tools/kb/upsert.ts +125 -0
  132. package/.framework/mcp/tools/observability.ts +510 -0
  133. package/.framework/migrations/001_core_schema.sql +15 -0
  134. package/.framework/migrations/002_core_rls_and_functions.sql +15 -0
  135. package/.framework/migrations/003_core_system_data.sql +16 -1
  136. package/.framework/migrations/004_core_rpc_and_broker.sql +17 -1
  137. package/.framework/migrations/005_core_observability.sql +17 -1
  138. package/.framework/migrations/006_security_hardening_rls.sql +15 -0
  139. package/.framework/migrations/007_kb_article_list.sql +17 -1
  140. package/.framework/migrations/008_items_target.sql +15 -0
  141. package/.framework/migrations/009_roles_slug_unique.sql +15 -0
  142. package/.framework/migrations/010_auth_user_trigger.sql +15 -0
  143. package/.framework/migrations/011_spine_system_account.sql +16 -0
  144. package/.framework/migrations/012_service_role_grants.sql +16 -0
  145. package/.framework/migrations/013_get_account_apps_role_filter.sql +15 -0
  146. package/.framework/migrations/014_apps_required_roles.sql +16 -0
  147. package/.framework/migrations/015_types_kind_slug_unique.sql +15 -0
  148. package/.framework/migrations/016_cil_types.sql +281 -0
  149. package/.framework/migrations/017_cil_stable_ids.sql +37 -0
  150. package/.framework/migrations/018_runtime_tables.sql +129 -0
  151. package/.framework/migrations/019_agent_prompt_columns.sql +56 -0
  152. package/.framework/migrations/020_schema_reconciliation.sql +67 -0
  153. package/.framework/migrations/021_kb_embedding_lifecycle.sql +31 -0
  154. package/.framework/migrations/032_cil_status_migration.sql +73 -0
  155. package/.framework/migrations/033_cil_versioning.sql +73 -0
  156. package/.framework/migrations/034_match_embeddings_knn.sql +115 -0
  157. package/.framework/migrations/035_rate_limits.sql +55 -0
  158. package/.framework/migrations/036_demo_record_flags.sql +72 -0
  159. package/.framework/migrations/037_kb_types_canonical.sql +244 -0
  160. package/.framework/migrations/038_drop_demo_record_flags.sql +38 -0
  161. package/.framework/migrations/042_registration_hierarchy.sql +309 -0
  162. package/.framework/migrations/043_policy_actor_cleanup.sql +39 -0
  163. package/.framework/migrations/044_match_embeddings_filtered_knn.sql +151 -0
  164. package/.framework/migrations/045_security_critical_rls.sql +139 -0
  165. package/.framework/migrations/046_security_missing_rls.sql +79 -0
  166. package/.framework/migrations/047_people_updated_by.sql +27 -0
  167. package/.framework/migrations/048_watcher_last_seen_at.sql +24 -0
  168. package/.framework/migrations/049_security_blocklist.sql +148 -0
  169. package/.framework/migrations/050_notifications.sql +49 -0
  170. package/.framework/migrations/051_message_agent_fields.sql +74 -0
  171. package/.framework/migrations/052_registration_security.sql +421 -0
  172. package/.framework/migrations/053_builtin_action_seeds.sql +66 -0
  173. package/.framework/migrations/054_kb_ingest_lease.sql +157 -0
  174. package/.framework/migrations/055_type_id_drift_reconciliation.sql +33 -0
  175. package/.framework/migrations/056_slug_column_reconciliation.sql +38 -0
  176. package/.framework/migrations/057_pipelines_slug_identity.sql +14 -0
  177. package/.framework/migrations/058_account_data_field_declarations.sql +53 -0
  178. package/.framework/migrations/059_registration_placement_fixes.sql +269 -0
  179. package/.framework/migrations/060_account_person_record_permissions.sql +38 -0
  180. package/.framework/migrations/061_fk_dedup.sql +32 -0
  181. package/.framework/public/spine-logo.svg +10 -3
  182. package/.framework/scripts/app-install-cli.ts +190 -93
  183. package/.framework/scripts/assemble-frontend.sh +127 -44
  184. package/.framework/scripts/assemble-functions.sh +128 -30
  185. package/.framework/scripts/boundary-check.sh +6 -2
  186. package/.framework/scripts/build-manifest.sh +24 -68
  187. package/.framework/scripts/check-core-integrity.sh +15 -76
  188. package/.framework/scripts/checksum-manifest.mts +343 -0
  189. package/.framework/scripts/cil-migrate-markers.ts +403 -0
  190. package/.framework/scripts/fix-cil-markers.mjs +176 -0
  191. package/.framework/scripts/verify-integrity.sh +21 -57
  192. package/.framework/scripts/verify-manifest.mts +305 -0
  193. package/.framework/seeds/types/funnel_signal_use.json +74 -21
  194. package/.framework/seeds/types/spine_instance.json +73 -21
  195. package/.framework/src/App.tsx +118 -72
  196. package/.framework/src/apps/admin/index.tsx +855 -58
  197. package/.framework/src/components/AppWrapper.tsx +43 -45
  198. package/.framework/src/components/CustomAppLoader.tsx +160 -116
  199. package/.framework/src/components/admin/AdminListPage.tsx +46 -44
  200. package/.framework/src/components/admin/AdminSidebar.tsx +57 -47
  201. package/.framework/src/components/admin/AdminStatsCard.tsx +46 -44
  202. package/.framework/src/components/admin/PageInstructions.tsx +98 -2
  203. package/.framework/src/components/admin/SortableTableHeader.tsx +44 -45
  204. package/.framework/src/components/app-shell/GenericAppShell.tsx +64 -65
  205. package/.framework/src/components/app-shell/GenericDetailPage.tsx +44 -47
  206. package/.framework/src/components/app-shell/GenericListPage.tsx +45 -49
  207. package/.framework/src/components/app-sidebar.tsx +42 -45
  208. package/.framework/src/components/auth/ProtectedRoute.tsx +48 -41
  209. package/.framework/src/components/auth/TurnstileWidget.tsx +27 -0
  210. package/.framework/src/components/kb/KBArticleEditor.tsx +231 -22
  211. package/.framework/src/components/kb/KBArticleList.tsx +251 -10
  212. package/.framework/src/components/layout/AppShell.tsx +51 -45
  213. package/.framework/src/components/layout/Header.tsx +42 -43
  214. package/.framework/src/components/layout/Layout.tsx +46 -46
  215. package/.framework/src/components/layout/Sidebar.tsx +196 -96
  216. package/.framework/src/components/runtime/DataDetailHeader.tsx +55 -30
  217. package/.framework/src/components/runtime/DataDetailPage.tsx +31 -269
  218. package/.framework/src/components/runtime/DataFilters.tsx +49 -74
  219. package/.framework/src/components/runtime/DataHeader.tsx +53 -32
  220. package/.framework/src/components/runtime/DataListPage.tsx +51 -155
  221. package/.framework/src/components/runtime/DataStats.tsx +66 -44
  222. package/.framework/src/components/runtime/DataTable.tsx +49 -149
  223. package/.framework/src/components/runtime/SchemaDetailForm.tsx +45 -75
  224. package/.framework/src/components/runtime/index.ts +119 -16
  225. package/.framework/src/components/search-form.tsx +46 -29
  226. package/.framework/src/components/shared/AgentView.tsx +65 -48
  227. package/.framework/src/components/shared/FieldRenderer.tsx +144 -50
  228. package/.framework/src/components/shared/InviteManager.tsx +207 -97
  229. package/.framework/src/components/shared/MemberList.tsx +97 -0
  230. package/.framework/src/components/shared/SchemaFields.tsx +107 -86
  231. package/.framework/src/components/ui/DataTable.tsx +80 -68
  232. package/.framework/src/components/ui/Form.tsx +157 -146
  233. package/.framework/src/components/ui/ItemCard.tsx +74 -67
  234. package/.framework/src/components/ui/ItemListView.tsx +73 -68
  235. package/.framework/src/components/ui/LoadingSpinner.tsx +43 -48
  236. package/.framework/src/components/ui/Modal.tsx +78 -68
  237. package/.framework/src/components/ui/RichTextEditor.tsx +89 -69
  238. package/.framework/src/components/ui/accordion.tsx +85 -86
  239. package/.framework/src/components/ui/alert-dialog.tsx +197 -184
  240. package/.framework/src/components/ui/alert.tsx +105 -94
  241. package/.framework/src/components/ui/aspect-ratio.tsx +57 -43
  242. package/.framework/src/components/ui/avatar.tsx +122 -107
  243. package/.framework/src/components/ui/badge.tsx +60 -55
  244. package/.framework/src/components/ui/breadcrumb.tsx +127 -128
  245. package/.framework/src/components/ui/button-group.tsx +86 -72
  246. package/.framework/src/components/ui/button.tsx +71 -50
  247. package/.framework/src/components/ui/calendar.tsx +72 -57
  248. package/.framework/src/components/ui/card.tsx +136 -129
  249. package/.framework/src/components/ui/carousel.tsx +226 -107
  250. package/.framework/src/components/ui/chart.tsx +252 -147
  251. package/.framework/src/components/ui/checkbox.tsx +43 -44
  252. package/.framework/src/components/ui/collapsible.tsx +86 -71
  253. package/.framework/src/components/ui/combobox.tsx +282 -249
  254. package/.framework/src/components/ui/command.tsx +158 -146
  255. package/.framework/src/components/ui/context-menu.tsx +239 -240
  256. package/.framework/src/components/ui/dialog.tsx +174 -157
  257. package/.framework/src/components/ui/direction.tsx +72 -56
  258. package/.framework/src/components/ui/drawer.tsx +168 -169
  259. package/.framework/src/components/ui/dropdown-menu.tsx +254 -223
  260. package/.framework/src/components/ui/empty.tsx +131 -120
  261. package/.framework/src/components/ui/field.tsx +205 -173
  262. package/.framework/src/components/ui/hover-card.tsx +71 -72
  263. package/.framework/src/components/ui/input-group.tsx +148 -133
  264. package/.framework/src/components/ui/input-otp.tsx +99 -86
  265. package/.framework/src/components/ui/input.tsx +43 -41
  266. package/.framework/src/components/ui/item.tsx +207 -185
  267. package/.framework/src/components/ui/kbd.tsx +57 -56
  268. package/.framework/src/components/ui/label.tsx +45 -41
  269. package/.framework/src/components/ui/menubar.tsx +268 -236
  270. package/.framework/src/components/ui/native-select.tsx +85 -86
  271. package/.framework/src/components/ui/navigation-menu.tsx +166 -156
  272. package/.framework/src/components/ui/pagination.tsx +131 -141
  273. package/.framework/src/components/ui/popover.tsx +125 -128
  274. package/.framework/src/components/ui/progress.tsx +47 -44
  275. package/.framework/src/components/ui/radio-group.tsx +60 -55
  276. package/.framework/src/components/ui/resizable.tsx +85 -72
  277. package/.framework/src/components/ui/scroll-area.tsx +57 -58
  278. package/.framework/src/components/ui/select.tsx +182 -169
  279. package/.framework/src/components/ui/separator.tsx +42 -43
  280. package/.framework/src/components/ui/sheet.tsx +170 -159
  281. package/.framework/src/components/ui/sidebar.tsx +395 -398
  282. package/.framework/src/components/ui/skeleton.tsx +42 -43
  283. package/.framework/src/components/ui/slider.tsx +61 -44
  284. package/.framework/src/components/ui/sonner.tsx +44 -44
  285. package/.framework/src/components/ui/spinner.tsx +47 -42
  286. package/.framework/src/components/ui/switch.tsx +56 -42
  287. package/.framework/src/components/ui/table-primitives.tsx +272 -132
  288. package/.framework/src/components/ui/table.tsx +140 -142
  289. package/.framework/src/components/ui/tabs.tsx +110 -93
  290. package/.framework/src/components/ui/textarea.tsx +43 -44
  291. package/.framework/src/components/ui/toggle-group.tsx +87 -71
  292. package/.framework/src/components/ui/toggle.tsx +56 -56
  293. package/.framework/src/components/ui/tooltip.tsx +99 -85
  294. package/.framework/src/contexts/AppContext.tsx +166 -114
  295. package/.framework/src/contexts/AuthContext.tsx +232 -137
  296. package/.framework/src/hooks/use-mobile.ts +43 -44
  297. package/.framework/src/hooks/useApi.ts +185 -172
  298. package/.framework/src/hooks/useAppPath.ts +31 -29
  299. package/.framework/src/hooks/useApps.ts +77 -42
  300. package/.framework/src/hooks/useEntityList.ts +66 -29
  301. package/.framework/src/hooks/useEntityRecord.ts +76 -32
  302. package/.framework/src/hooks/useForm.ts +62 -30
  303. package/.framework/src/hooks/useListSchema.ts +60 -43
  304. package/.framework/src/hooks/useSchemaRecord.ts +115 -95
  305. package/.framework/src/lib/api.ts +258 -134
  306. package/.framework/src/lib/registration.ts +181 -0
  307. package/.framework/src/lib/supabase.ts +118 -81
  308. package/.framework/src/lib/utils.ts +266 -266
  309. package/.framework/src/main.tsx +43 -44
  310. package/.framework/src/pages/DashboardPage.tsx +44 -43
  311. package/.framework/src/pages/NoAppPage.tsx +50 -0
  312. package/.framework/src/pages/NotFoundPage.tsx +32 -29
  313. package/.framework/src/pages/SetupPage.tsx +34 -33
  314. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +69 -58
  315. package/.framework/src/pages/admin/AIAgentsPage.tsx +43 -40
  316. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +63 -55
  317. package/.framework/src/pages/admin/APIKeysPage.tsx +44 -42
  318. package/.framework/src/pages/admin/AlertsConfigPage.tsx +117 -94
  319. package/.framework/src/pages/admin/AppDetailPage.tsx +48 -42
  320. package/.framework/src/pages/admin/AppsPage.tsx +45 -42
  321. package/.framework/src/pages/admin/DeliveriesPage.tsx +49 -17
  322. package/.framework/src/pages/admin/DesignedPage.tsx +31 -30
  323. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +58 -0
  324. package/.framework/src/pages/admin/EmbeddingsPage.tsx +49 -0
  325. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +31 -29
  326. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +46 -29
  327. package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -29
  328. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +68 -55
  329. package/.framework/src/pages/admin/IntegrationsPage.tsx +45 -42
  330. package/.framework/src/pages/admin/InvitesPage.tsx +60 -44
  331. package/.framework/src/pages/admin/LogsPage.tsx +87 -137
  332. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +31 -29
  333. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +150 -89
  334. package/.framework/src/pages/admin/PipelineDetailPage.tsx +77 -104
  335. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +44 -43
  336. package/.framework/src/pages/admin/PipelinesPage.tsx +59 -145
  337. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +53 -42
  338. package/.framework/src/pages/admin/PromptConfigsPage.tsx +47 -117
  339. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +31 -44
  340. package/.framework/src/pages/admin/RoleDetailPage.tsx +49 -92
  341. package/.framework/src/pages/admin/RolesPage.tsx +47 -164
  342. package/.framework/src/pages/admin/SecurityPage.tsx +310 -0
  343. package/.framework/src/pages/admin/SelectTestPage.tsx +30 -32
  344. package/.framework/src/pages/admin/ShadcnTestPage.tsx +37 -44
  345. package/.framework/src/pages/admin/SimpleDashboard.tsx +32 -44
  346. package/.framework/src/pages/admin/TestRunDetailPage.tsx +97 -44
  347. package/.framework/src/pages/admin/TestingDashboard.tsx +126 -71
  348. package/.framework/src/pages/admin/TimerDetailPage.tsx +67 -55
  349. package/.framework/src/pages/admin/TimersPage.tsx +44 -42
  350. package/.framework/src/pages/admin/TriggerDetailPage.tsx +47 -42
  351. package/.framework/src/pages/admin/TriggersPage.tsx +58 -57
  352. package/.framework/src/pages/admin/TypeDetailPage.tsx +91 -55
  353. package/.framework/src/pages/admin/TypesPage.tsx +45 -42
  354. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +258 -128
  355. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +127 -123
  356. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +308 -235
  357. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +159 -110
  358. package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +432 -0
  359. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +200 -178
  360. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +286 -239
  361. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +211 -90
  362. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +156 -143
  363. package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +379 -0
  364. package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +337 -0
  365. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +219 -214
  366. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
  367. package/.framework/src/pages/auth/AuthConfirmPage.tsx +135 -65
  368. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +39 -31
  369. package/.framework/src/pages/auth/LoginPage.tsx +38 -32
  370. package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -28
  371. package/.framework/src/pages/auth/RegisterPage.tsx +429 -155
  372. package/.framework/src/pages/spine-framework/APIPage.tsx +33 -30
  373. package/.framework/src/pages/spine-framework/CLIPage.tsx +32 -30
  374. package/.framework/src/types/auth.ts +101 -93
  375. package/.framework/src/types/types.ts +283 -262
  376. package/.framework/templates/project.json +87 -0
  377. package/.framework/templates/spine.config.neutral.json +7 -0
  378. package/.framework/tests/api/api-surface.test.ts +381 -0
  379. package/.framework/tests/fixtures/seed.ts +427 -0
  380. package/.framework/tests/fixtures/teardown.ts +228 -0
  381. package/.framework/tests/reporter.ts +351 -0
  382. package/.framework/tests/setup.ts +135 -0
  383. package/.framework/tests/ui/ui-sweep.ts +278 -0
  384. package/.framework/tests/unit/admin-data-logger.test.ts +310 -0
  385. package/.framework/tests/unit/agent-runner.test.ts +2389 -0
  386. package/.framework/tests/unit/ai-interactions.test.ts +81 -0
  387. package/.framework/tests/unit/app-manifest.test.ts +359 -0
  388. package/.framework/tests/unit/assembly-scripts.test.ts +172 -0
  389. package/.framework/tests/unit/cil-determinism.test.ts +85 -0
  390. package/.framework/tests/unit/core-isolation.test.ts +153 -0
  391. package/.framework/tests/unit/funnel-signals.test.ts +135 -0
  392. package/.framework/tests/unit/install-app.test.ts +1759 -0
  393. package/.framework/tests/unit/invites-security.test.ts +572 -0
  394. package/.framework/tests/unit/kb-ingest-lease.test.ts +287 -0
  395. package/.framework/tests/unit/kb-search.test.ts +119 -0
  396. package/.framework/tests/unit/migrate.test.ts +509 -0
  397. package/.framework/tests/unit/notify.test.ts +136 -0
  398. package/.framework/tests/unit/permissions.test.ts +269 -0
  399. package/.framework/tests/unit/pipeline-runner.test.ts +755 -0
  400. package/.framework/tests/unit/principal-cache.test.ts +138 -0
  401. package/.framework/tests/unit/retrieval-golden.test.ts +520 -0
  402. package/.framework/tests/unit/runtime-isolation.test.ts +642 -0
  403. package/.framework/tests/unit/schema-utils.test.ts +225 -0
  404. package/.framework/tests/unit/trigger-engine.test.ts +513 -0
  405. package/.framework/tests/unit/validate-app.test.ts +527 -0
  406. package/README.md +34 -3
  407. package/bin/spine-framework.cjs +1 -0
  408. package/config/tailwind.config.cjs +7 -0
  409. package/config/tsconfig.functions.json +42 -0
  410. package/config/tsconfig.json +37 -9
  411. package/config/vite.config.ts +31 -2
  412. package/netlify.toml +31 -3
  413. package/package.json +46 -29
  414. package/scripts/assemble-frontend.sh +127 -44
  415. package/scripts/assemble-functions.sh +127 -29
  416. package/scripts/boundary-check.sh +6 -2
  417. package/scripts/build-manifest.sh +24 -68
  418. package/scripts/checksum-manifest.mts +345 -0
  419. package/scripts/dev-clean.sh +86 -0
  420. package/scripts/dev-netlify.sh +49 -0
  421. package/scripts/netlify-dev-wrapper.sh +2 -0
  422. package/scripts/verify-install.ts +358 -0
  423. package/scripts/verify-integrity.sh +21 -57
  424. package/scripts/verify-manifest.mts +305 -0
  425. package/templates/project/gitignore +45 -0
  426. package/{config → templates/project}/package-lock.json +22335 -9366
  427. package/vitest.config.ts +46 -0
  428. package/.framework/public/spine.config.json +0 -91
  429. package/config/deno.lock +0 -108
  430. package/config/tsconfig.node.tsbuildinfo +0 -1
  431. package/config/tsconfig.tsbuildinfo +0 -1
  432. package/config/vite.config.d.ts +0 -2
  433. package/custom/.devin/AGENT.md +0 -357
  434. package/custom/.devin/skills/install-app/SKILL.md +0 -39
  435. package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +0 -39
  436. package/custom/.devin/skills/spine-workbench-idea/SKILL.md +0 -36
  437. package/custom/.devin/skills/spine-workbench-implement/SKILL.md +0 -46
  438. package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +0 -28
  439. package/custom/.devin/skills/spine-workbench-plan/SKILL.md +0 -38
  440. package/custom/.devin/workflows/app-install.yaml +0 -83
  441. package/custom/README.md +0 -79
  442. package/docs/README.md +0 -15
  443. package/scripts/app-install-cli.ts +0 -286
  444. package/scripts/check-core-integrity.sh +0 -82
  445. package/scripts/ingest-chunks.cjs +0 -202
  446. package/scripts/kb-chunk-parser.cjs +0 -312
  447. package/scripts/kb-chunk-parser.ts +0 -330
  448. package/scripts/kb-ingest-docs.ts +0 -203
  449. package/scripts/load-test-app-install.ts +0 -484
  450. package/scripts/test-login.js +0 -33
  451. package/spine.config.json +0 -91
@@ -0,0 +1,228 @@
1
+ // CIL[BEGIN stable_id="~/.framework/tests/fixtures/teardown.ts:file_header:constant" type="constant" identity="file_header" parent="~/.framework/tests/fixtures/teardown.ts"]
2
+ // CIL[DOC-MACRO purpose="File header for the teardown test fixture script"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide JSDoc metadata and reference the node types module"]
4
+ // CIL[DOC-CONTEXT module=".framework/tests/fixtures/teardown" layer="test-infrastructure" related_files=".framework/tests/fixtures/teardown.ts"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Triple-slash node reference and module-level JSDoc" notable_decisions="[]"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ // CIL[DOC-STABILITY stable]
9
+ /// <reference types="node" />
10
+ /**
11
+ * @module tests/fixtures/teardown
12
+ * @audience core-contributor
13
+ * @layer test-infrastructure
14
+ * @stability stable
15
+ *
16
+ * Deletes all test fixtures from the public schema. Removes every row whose
17
+ * slug starts with `test-` under SPINE_TEST_ACCOUNT_ID, in FK-safe order.
18
+ *
19
+ * Run after integration tests: `tsx v2-core/tests/fixtures/teardown.ts`
20
+ *
21
+ * @seeAlso tests/fixtures/seed.ts
22
+ */
23
+ // CIL[DOC-VECTOR type="context" content="purpose='File header for the teardown test fixture script'; No verified external callers; imports: none"]
24
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
25
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
26
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
27
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
28
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
29
+ // CIL[END stable_id="~/.framework/tests/fixtures/teardown.ts:file_header:constant"]
30
+
31
+ // CIL[BEGIN stable_id="~/.framework/tests/fixtures/teardown.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/tests/fixtures/teardown.ts"]
32
+ // CIL[DOC-AUDIENCE audience="core-contributor"]
33
+ // CIL[DOC-MACRO purpose="Load environment variables and import dependencies for test fixture teardown"]
34
+ // CIL[DOC-CONTEXT module=".framework/tests/fixtures/teardown" layer="test-infrastructure" related_files=".framework/tests/fixtures/teardown.ts"]
35
+ // CIL[DOC-CONTRACT inputs="none" outputs="loaded process.env and imports" errors="none" side_effects="Reads .xenv files and mutates process.env"]
36
+ // CIL[DOC-MICRO logic_summary="Derives __filename and __dirname, loads dotenv-style files, then imports @supabase/supabase-js" notable_decisions="[]"]
37
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
38
+ // CIL[DOC-STABILITY stable]
39
+ import { readFileSync, existsSync } from 'fs'
40
+ import { resolve, dirname } from 'path'
41
+ import { fileURLToPath } from 'url'
42
+
43
+ const __filename = fileURLToPath(import.meta.url)
44
+ const __dirname = dirname(__filename)
45
+
46
+ function loadEnv() {
47
+ for (const name of ['.xenv.test', '.xenv']) {
48
+ const p = resolve(__dirname, '../../', name)
49
+ if (existsSync(p)) {
50
+ const lines = readFileSync(p, 'utf8').split('\n')
51
+ for (const line of lines) {
52
+ const t = line.trim()
53
+ if (!t || t.startsWith('#')) continue
54
+ const eq = t.indexOf('=')
55
+ if (eq === -1) continue
56
+ const k = t.slice(0, eq).trim()
57
+ const v = t.slice(eq + 1).trim().replace(/^["']|["']$/g, '')
58
+ if (!process.env[k]) process.env[k] = v
59
+ }
60
+ break
61
+ }
62
+ }
63
+ }
64
+
65
+ loadEnv()
66
+
67
+ import { createClient } from '@supabase/supabase-js'
68
+ // CIL[DOC-VECTOR type="context" content="purpose='Load environment variables and import dependencies for test fixture teardown'; No verified external callers; imports: none"]
69
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
70
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
71
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
72
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
73
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
74
+ // CIL[END stable_id="~/.framework/tests/fixtures/teardown.ts:module_header:module_header"]
75
+
76
+ // CIL[BEGIN stable_id="~/.framework/tests/fixtures/teardown.ts:SUPABASE_URL:constant" type="constant" identity="SUPABASE_URL" parent="~/.framework/tests/fixtures/teardown.ts"]
77
+ // CIL[DOC-MACRO purpose="URL of the Supabase instance used for test fixture teardown"]
78
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the Supabase project URL from environment"]
79
+ // CIL[DOC-CONTEXT module=".framework/tests/fixtures/teardown" layer="test-infrastructure" related_files=".framework/tests/fixtures/teardown.ts"]
80
+ // CIL[DOC-CONTRACT inputs="none" outputs="string" errors="none" side_effects="none"]
81
+ // CIL[DOC-MICRO logic_summary="Reads process.env.SUPABASE_URL with a non-null assertion" notable_decisions="[]"]
82
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
83
+ // CIL[DOC-STABILITY stable]
84
+ const SUPABASE_URL = process.env.SUPABASE_URL!
85
+ // CIL[DOC-VECTOR type="context" content="purpose='URL of the Supabase instance used for test fixture teardown'; No verified external callers; imports: none"]
86
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
87
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
88
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
89
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
90
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
91
+ // CIL[END stable_id="~/.framework/tests/fixtures/teardown.ts:SUPABASE_URL:constant"]
92
+ // CIL[BEGIN stable_id="~/.framework/tests/fixtures/teardown.ts:SERVICE_KEY:constant" type="constant" identity="SERVICE_KEY" parent="~/.framework/tests/fixtures/teardown.ts"]
93
+ // CIL[DOC-MACRO purpose="Supabase service role key for test fixture teardown"]
94
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the Supabase service role key from environment"]
95
+ // CIL[DOC-CONTEXT module=".framework/tests/fixtures/teardown" layer="test-infrastructure" related_files=".framework/tests/fixtures/teardown.ts"]
96
+ // CIL[DOC-CONTRACT inputs="none" outputs="string" errors="none" side_effects="none"]
97
+ // CIL[DOC-MICRO logic_summary="Reads process.env.SUPABASE_SERVICE_ROLE_KEY with a non-null assertion" notable_decisions="[]"]
98
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
99
+ // CIL[DOC-STABILITY stable]
100
+ const SERVICE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY!
101
+ // CIL[DOC-VECTOR type="context" content="purpose='Supabase service role key for test fixture teardown'; No verified external callers; imports: none"]
102
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
103
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
104
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
105
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
106
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
107
+ // CIL[END stable_id="~/.framework/tests/fixtures/teardown.ts:SERVICE_KEY:constant"]
108
+ // CIL[BEGIN stable_id="~/.framework/tests/fixtures/teardown.ts:ACCOUNT_ID:constant" type="constant" identity="ACCOUNT_ID" parent="~/.framework/tests/fixtures/teardown.ts"]
109
+ // CIL[DOC-MACRO purpose="Spine test account ID for test fixture teardown"]
110
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the target account identifier from environment"]
111
+ // CIL[DOC-CONTEXT module=".framework/tests/fixtures/teardown" layer="test-infrastructure" related_files=".framework/tests/fixtures/teardown.ts"]
112
+ // CIL[DOC-CONTRACT inputs="none" outputs="string" errors="none" side_effects="none"]
113
+ // CIL[DOC-MICRO logic_summary="Reads process.env.SPINE_TEST_ACCOUNT_ID with a non-null assertion" notable_decisions="[]"]
114
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
115
+ // CIL[DOC-STABILITY stable]
116
+ const ACCOUNT_ID = process.env.SPINE_TEST_ACCOUNT_ID!
117
+ // CIL[DOC-VECTOR type="context" content="purpose='Spine test account ID for test fixture teardown'; No verified external callers; imports: none"]
118
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
119
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
120
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
121
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
122
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
123
+ // CIL[END stable_id="~/.framework/tests/fixtures/teardown.ts:ACCOUNT_ID:constant"]
124
+ // CIL[BEGIN stable_id="~/.framework/tests/fixtures/teardown.ts:env_check:variable" type="variable" identity="env_check" parent="~/.framework/tests/fixtures/teardown.ts"]
125
+ // CIL[DOC-MACRO purpose="Validate that required environment variables are present"]
126
+ // CIL[DOC-RESPONSIBILITY responsibility="Exit the process early if any required env var is missing"]
127
+ // CIL[DOC-CONTEXT module=".framework/tests/fixtures/teardown" layer="test-infrastructure" related_files=".framework/tests/fixtures/teardown.ts"]
128
+ // CIL[DOC-CONTRACT inputs="none" outputs="none or process.exit(1)" errors="Missing required environment variable" side_effects="Logs an error and may exit the process"]
129
+ // CIL[DOC-MICRO logic_summary="Checks SUPABASE_URL, SERVICE_KEY, and ACCOUNT_ID for truthy values" notable_decisions="[]"]
130
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
131
+ // CIL[DOC-STABILITY stable]
132
+ if (!SUPABASE_URL || !SERVICE_KEY || !ACCOUNT_ID) {
133
+ console.error('Missing SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, or SPINE_TEST_ACCOUNT_ID')
134
+ process.exit(1)
135
+ }
136
+ // CIL[DOC-VECTOR type="context" content="purpose='Validate that required environment variables are present'; No verified external callers; imports: none"]
137
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
138
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
139
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
140
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
141
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
142
+ // CIL[END stable_id="~/.framework/tests/fixtures/teardown.ts:env_check:variable"]
143
+
144
+ // CIL[BEGIN stable_id="~/.framework/tests/fixtures/teardown.ts:db:constant" type="constant" identity="db" parent="~/.framework/tests/fixtures/teardown.ts"]
145
+ // CIL[DOC-MACRO purpose="Supabase client for the public schema"]
146
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide a database client used to delete test rows"]
147
+ // CIL[DOC-CONTEXT module=".framework/tests/fixtures/teardown" layer="test-infrastructure" related_files=".framework/tests/fixtures/teardown.ts"]
148
+ // CIL[DOC-CONTRACT inputs="none" outputs="SupabaseClient" errors="none" side_effects="none"]
149
+ // CIL[DOC-MICRO logic_summary="Creates a Supabase client configured for the public schema using SUPABASE_URL and SERVICE_KEY" notable_decisions="[]"]
150
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
151
+ // CIL[DOC-STABILITY stable]
152
+ const db = createClient(SUPABASE_URL, SERVICE_KEY, { db: { schema: 'public' } })
153
+ // CIL[DOC-VECTOR type="context" content="purpose='Supabase client for the public schema'; No verified external callers; imports: none"]
154
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
155
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
156
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
157
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
158
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
159
+ // CIL[END stable_id="~/.framework/tests/fixtures/teardown.ts:db:constant"]
160
+
161
+ // CIL[BEGIN stable_id="~/.framework/tests/fixtures/teardown.ts:del:function" type="function" identity="del" parent="~/.framework/tests/fixtures/teardown.ts"]
162
+ // CIL[DOC-MACRO purpose="Delete test rows from a single table"]
163
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute a slug-filtered delete query with an optional extra filter"]
164
+ // CIL[DOC-CONTEXT module=".framework/tests/fixtures/teardown" layer="test-infrastructure" related_files=".framework/tests/fixtures/teardown.ts"]
165
+ // CIL[DOC-CONTRACT inputs="table: string, filter?: (q: any) => any" outputs="none" errors="Logs a warning on Supabase error" side_effects="Deletes rows whose slug starts with test-% and logs the count"]
166
+ // CIL[DOC-MICRO logic_summary="Builds a delete query filtered by slug like test-%, applies an optional filter callback, awaits the result, and logs the affected count or warning" notable_decisions="[]"]
167
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
168
+ // CIL[DOC-STABILITY stable]
169
+ async function del(table: string, filter?: (q: any) => any) {
170
+ let q = db.from(table).delete().like('slug', 'test-%')
171
+ if (filter) q = filter(q)
172
+ const { error, count } = await (q as any)
173
+ if (error) console.warn(` [warn] ${table}:`, error.message)
174
+ else console.log(` ✓ ${table}: removed ${count ?? '?'} rows`)
175
+ }
176
+ // CIL[DOC-VECTOR type="context" content="purpose='Delete test rows from a single table'; No verified external callers; imports: none"]
177
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
178
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
179
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
180
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
181
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
182
+ // CIL[END stable_id="~/.framework/tests/fixtures/teardown.ts:del:function"]
183
+
184
+ // CIL[BEGIN stable_id="~/.framework/tests/fixtures/teardown.ts:teardown:function" type="function" identity="teardown" parent="~/.framework/tests/fixtures/teardown.ts"]
185
+ // CIL[DOC-MACRO purpose="Remove all test fixtures from the public schema in FK-safe order"]
186
+ // CIL[DOC-RESPONSIBILITY responsibility="Orchestrate deletion of seeded test records across multiple tables"]
187
+ // CIL[DOC-CONTEXT module=".framework/tests/fixtures/teardown" layer="test-infrastructure" related_files=".framework/tests/fixtures/teardown.ts"]
188
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="Throws if any delete fails" side_effects="Deletes test rows from items, people, pipelines, types, and roles"]
189
+ // CIL[DOC-MICRO logic_summary="Logs start, deletes records from each table in order, then logs completion" notable_decisions="[]"]
190
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
191
+ // CIL[DOC-STABILITY stable]
192
+ async function teardown() {
193
+ console.log('🧹 Tearing down test fixtures from public schema...')
194
+
195
+ await del('items', q => q.eq('account_id', ACCOUNT_ID))
196
+ await del('people', q => q.eq('account_id', ACCOUNT_ID))
197
+ await del('pipelines', q => q.eq('account_id', ACCOUNT_ID))
198
+ await del('types')
199
+ await del('roles', q => q.eq('account_id', ACCOUNT_ID))
200
+
201
+ console.log('✅ Teardown complete.')
202
+ }
203
+ // CIL[DOC-VECTOR type="context" content="purpose='Remove all test fixtures from the public schema in FK-safe order'; No verified external callers; imports: none"]
204
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
205
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
206
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
207
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
208
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
209
+ // CIL[END stable_id="~/.framework/tests/fixtures/teardown.ts:teardown:function"]
210
+ // CIL[BEGIN stable_id="~/.framework/tests/fixtures/teardown.ts:teardown_invocation:variable" type="variable" identity="teardown_invocation" parent="~/.framework/tests/fixtures/teardown.ts"]
211
+ // CIL[DOC-MACRO purpose="Invoke the teardown routine when the script runs directly"]
212
+ // CIL[DOC-RESPONSIBILITY responsibility="Run teardown and exit with an error code on failure"]
213
+ // CIL[DOC-CONTEXT module=".framework/tests/fixtures/teardown" layer="test-infrastructure" related_files=".framework/tests/fixtures/teardown.ts"]
214
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="Exits with code 1 on unhandled rejection" side_effects="Calls teardown, logs failures, and exits the process on error"]
215
+ // CIL[DOC-MICRO logic_summary="Calls teardown and catches rejections to log an error and exit with code 1" notable_decisions="[]"]
216
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
217
+ // CIL[DOC-STABILITY stable]
218
+ teardown().catch(err => {
219
+ console.error('Teardown failed:', err)
220
+ process.exit(1)
221
+ })
222
+ // CIL[DOC-VECTOR type="context" content="purpose='Invoke the teardown routine when the script runs directly'; No verified external callers; imports: none"]
223
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
224
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
225
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
226
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
227
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
228
+ // CIL[END stable_id="~/.framework/tests/fixtures/teardown.ts:teardown_invocation:variable"]
@@ -0,0 +1,351 @@
1
+ // CIL[BEGIN stable_id="~/.framework/tests/reporter.ts:file_header:constant" type="constant" identity="file_header" parent="~/.framework/tests/reporter.ts"]
2
+ // CIL[DOC-MACRO purpose="Provide module-level documentation and metadata for the Vitest custom reporter."]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe the test reporter's purpose, environment requirements, registration, and related files."]
4
+ // CIL[DOC-CONTEXT module="tests/reporter" layer="test-infrastructure" related_files=".framework/tests/reporter.ts"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="JSDoc metadata" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Contains only docblock and @seeAlso references." notable_decisions="JSDoc is retained as module metadata."]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ // CIL[DOC-STABILITY stable]
9
+ /// <reference types="node" />
10
+ /**
11
+ * @module tests/reporter
12
+ * @audience core-contributor
13
+ * @layer test-infrastructure
14
+ * @stability stable
15
+ *
16
+ * Vitest custom reporter that persists test run results to public.test_runs
17
+ * and public.test_results in Supabase. Also exports writeRunResults() for
18
+ * use by non-Vitest runners (API tests, UI sweep).
19
+ *
20
+ * Registered in vitest.config.ts via:
21
+ * reporters: ['default', './v2-core/tests/reporter.ts']
22
+ *
23
+ * Requires SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY in env.
24
+ *
25
+ * @seeAlso migrations_dayzero/008_test_runs.sql
26
+ * @seeAlso tests/ui/ui-sweep.ts (calls writeRunResults directly)
27
+ * @seeAlso tests/api/api-surface.test.ts (calls writeRunResults directly)
28
+ */
29
+ // CIL[DOC-VECTOR type="context" content="purpose='Provide module-level documentation and metadata for the Vitest custom reporter.'; No verified external callers; imports: none"]
30
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
31
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
32
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
33
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
34
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
35
+ // CIL[END stable_id="~/.framework/tests/reporter.ts:file_header:constant"]
36
+
37
+ // CIL[BEGIN stable_id="~/.framework/tests/reporter.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/tests/reporter.ts"]
38
+ // CIL[DOC-MACRO purpose="Import dependencies required by the test reporter."]
39
+ // CIL[DOC-RESPONSIBILITY responsibility="Load fs, path, url utilities and Vitest reporter types."]
40
+ // CIL[DOC-CONTEXT module="tests/reporter" layer="test-infrastructure" related_files=".framework/tests/reporter.ts"]
41
+ // CIL[DOC-CONTRACT inputs="none" outputs="imported modules and types" errors="none" side_effects="none"]
42
+ // CIL[DOC-MICRO logic_summary="Four import statements for Node and Vitest APIs." notable_decisions="Named imports preferred; Vitest types only imported."]
43
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
44
+ // CIL[DOC-STABILITY stable]
45
+ // CIL[DOC-AUDIENCE audience="core-contributor"]
46
+ import { readFileSync, existsSync } from 'fs'
47
+ import { resolve, dirname } from 'path'
48
+ import { fileURLToPath } from 'url'
49
+ import type { Reporter, File, Task } from 'vitest'
50
+ // CIL[DOC-VECTOR type="context" content="purpose='Import dependencies required by the test reporter.'; No verified external callers; imports: none"]
51
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
52
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
53
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
54
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
55
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
56
+ // CIL[END stable_id="~/.framework/tests/reporter.ts:module_header:module_header"]
57
+
58
+ // CIL[BEGIN stable_id="~/.framework/tests/reporter.ts:__filename:constant" type="constant" identity="__filename" parent="~/.framework/tests/reporter.ts"]
59
+ // CIL[DOC-MACRO purpose="Capture the current module's filename path."]
60
+ // CIL[DOC-RESPONSIBILITY responsibility="Resolve this file's filesystem path for locating environment files."]
61
+ // CIL[DOC-CONTEXT module="tests/reporter" layer="test-infrastructure" related_files=".framework/tests/reporter.ts"]
62
+ // CIL[DOC-CONTRACT inputs="import.meta.url" outputs="__filename string" errors="none" side_effects="none"]
63
+ // CIL[DOC-MICRO logic_summary="Converts import.meta.url to a file path using fileURLToPath." notable_decisions=""]
64
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
65
+ // CIL[DOC-STABILITY stable]
66
+ const __filename = fileURLToPath(import.meta.url)
67
+ // CIL[DOC-VECTOR type="context" content="purpose='Capture the current module's filename path.'; No verified external callers; imports: none"]
68
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
69
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
70
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
71
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
72
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
73
+ // CIL[END stable_id="~/.framework/tests/reporter.ts:__filename:constant"]
74
+ // CIL[BEGIN stable_id="~/.framework/tests/reporter.ts:__dirname:constant" type="constant" identity="__dirname" parent="~/.framework/tests/reporter.ts"]
75
+ // CIL[DOC-MACRO purpose="Capture the current module's directory path."]
76
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide directory context for resolving dotenv files."]
77
+ // CIL[DOC-CONTEXT module="tests/reporter" layer="test-infrastructure" related_files=".framework/tests/reporter.ts"]
78
+ // CIL[DOC-CONTRACT inputs="__filename" outputs="__dirname string" errors="none" side_effects="none"]
79
+ // CIL[DOC-MICRO logic_summary="Derives __dirname from __filename using dirname." notable_decisions=""]
80
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
81
+ // CIL[DOC-STABILITY stable]
82
+ const __dirname = dirname(__filename)
83
+ // CIL[DOC-VECTOR type="context" content="purpose='Capture the current module's directory path.'; No verified external callers; imports: none"]
84
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
85
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
86
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
87
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
88
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
89
+ // CIL[END stable_id="~/.framework/tests/reporter.ts:__dirname:constant"]
90
+
91
+ // CIL[BEGIN stable_id="~/.framework/tests/reporter.ts:loadEnv:function" type="function" identity="loadEnv" parent="~/.framework/tests/reporter.ts"]
92
+ // CIL[DOC-MACRO purpose="Load local test environment variables from .xenv files."]
93
+ // CIL[DOC-RESPONSIBILITY responsibility="Read the closest .xenv or .xenv.test and populate process.env."]
94
+ // CIL[DOC-CONTEXT module="tests/reporter" layer="test-infrastructure" related_files=".framework/tests/reporter.ts"]
95
+ // CIL[DOC-CONTRACT inputs="none (uses __dirname and process.env)" outputs="mutated process.env" errors="silently skips missing files" side_effects="sets process.env key=value pairs"]
96
+ // CIL[DOC-MICRO logic_summary="Searches parent .xenv files, parses KEY=value lines, trims quotes, and assigns only when not already set." notable_decisions="Stops after first found file; does not overwrite existing environment variables."]
97
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
98
+ // CIL[DOC-STABILITY stable]
99
+ function loadEnv() {
100
+ for (const name of ['.xenv.test', '.xenv']) {
101
+ const p = resolve(__dirname, '../', name)
102
+ if (existsSync(p)) {
103
+ const lines = readFileSync(p, 'utf8').split('\n')
104
+ for (const line of lines) {
105
+ const t = line.trim()
106
+ if (!t || t.startsWith('#')) continue
107
+ const eq = t.indexOf('=')
108
+ if (eq === -1) continue
109
+ const k = t.slice(0, eq).trim()
110
+ const v = t.slice(eq + 1).trim().replace(/^["']|["']$/g, '')
111
+ if (!process.env[k]) process.env[k] = v
112
+ }
113
+ break
114
+ }
115
+ }
116
+ }
117
+ // CIL[DOC-VECTOR type="context" content="purpose='Load local test environment variables from .xenv files.'; No verified external callers; imports: none"]
118
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
119
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
120
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
121
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
122
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
123
+ // CIL[END stable_id="~/.framework/tests/reporter.ts:loadEnv:function"]
124
+ // CIL[BEGIN stable_id="~/.framework/tests/reporter.ts:reporter_init:variable" type="variable" identity="reporter_init" parent="~/.framework/tests/reporter.ts"]
125
+ // CIL[DOC-MACRO purpose="Trigger environment loading at module import time."]
126
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute loadEnv when the reporter module is imported."]
127
+ // CIL[DOC-CONTEXT module="tests/reporter" layer="test-infrastructure" related_files=".framework/tests/reporter.ts"]
128
+ // CIL[DOC-CONTRACT inputs="none" outputs="side effect" errors="none" side_effects="process.env populated by loadEnv"]
129
+ // CIL[DOC-MICRO logic_summary="Single call to loadEnv and a section marker comment." notable_decisions="Loads environment immediately on import so reporters can run with correct config."]
130
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
131
+ // CIL[DOC-STABILITY stable]
132
+ loadEnv()
133
+
134
+ // ─── TYPES ─────────────────────────────────────────────────────────────────
135
+ // CIL[DOC-VECTOR type="context" content="purpose='Trigger environment loading at module import time.'; No verified external callers; imports: none"]
136
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
137
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
138
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
139
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
140
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
141
+ // CIL[END stable_id="~/.framework/tests/reporter.ts:reporter_init:variable"]
142
+
143
+ // CIL[BEGIN stable_id="~/.framework/tests/reporter.ts:TestCaseResult:interface" type="interface" identity="TestCaseResult" parent="~/.framework/tests/reporter.ts"]
144
+ // CIL[DOC-MACRO purpose="Define the data shape for an individual test case outcome."]
145
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript contract for test result records."]
146
+ // CIL[DOC-CONTEXT module="tests/reporter" layer="test-infrastructure" related_files=".framework/tests/reporter.ts"]
147
+ // CIL[DOC-CONTRACT inputs="none" outputs="TestCaseResult type" errors="none" side_effects="none"]
148
+ // CIL[DOC-MICRO logic_summary="Fields: suite, optional file/describe, name, status, optional duration and error." notable_decisions="Status is a union of passed, failed, skipped."]
149
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
150
+ // CIL[DOC-STABILITY stable]
151
+ export interface TestCaseResult {
152
+ suite: string
153
+ file?: string
154
+ describe?: string
155
+ name: string
156
+ status: 'passed' | 'failed' | 'skipped'
157
+ duration_ms?: number
158
+ error?: string
159
+ }
160
+ // CIL[DOC-VECTOR type="context" content="purpose='Define the data shape for an individual test case outcome.'; No verified external callers; imports: none"]
161
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
162
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
163
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
164
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
165
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
166
+ // CIL[END stable_id="~/.framework/tests/reporter.ts:TestCaseResult:interface"]
167
+
168
+ // ─── DB WRITER ─────────────────────────────────────────────────────────────
169
+
170
+ // CIL[BEGIN stable_id="~/.framework/tests/reporter.ts:writeRunResults:function" type="function" identity="writeRunResults" parent="~/.framework/tests/reporter.ts"]
171
+ // CIL[DOC-MACRO purpose="Persist a completed test run and its results to Supabase."]
172
+ // CIL[DOC-RESPONSIBILITY responsibility="Insert a public.test_runs row and public.test_results rows from supplied outcome data."]
173
+ // CIL[DOC-CONTEXT module="tests/reporter" layer="test-infrastructure" related_files=".framework/tests/reporter.ts"]
174
+ // CIL[DOC-CONTRACT inputs="suite string, results TestCaseResult[], durationMs number" outputs="run_id string or null" errors="missing env returns null; insert errors warn and return null" side_effects="inserts rows into public.test_runs and public.test_results; logs to console"]
175
+ // CIL[DOC-MICRO logic_summary="Validates env, creates Supabase client, computes pass/fail/skip counts, inserts run, then bulk inserts results." notable_decisions="Returns null on any failure; triggered_by set to 'agent'."]
176
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
177
+ // CIL[DOC-STABILITY stable]
178
+ /**
179
+ * Writes a completed test run + individual results to public schema.
180
+ * Safe to call from any test runner (Vitest, Playwright, fetch-based API tests).
181
+ *
182
+ * @param suite - 'unit' | 'integration' | 'api' | 'ui'
183
+ * @param results - array of individual test case outcomes
184
+ * @param durationMs - total wall-clock duration of the suite
185
+ */
186
+ export async function writeRunResults(
187
+ suite: string,
188
+ results: TestCaseResult[],
189
+ durationMs: number
190
+ ): Promise<string | null> {
191
+ const url = process.env.SUPABASE_URL
192
+ const key = process.env.SUPABASE_SERVICE_ROLE_KEY
193
+ if (!url || !key) {
194
+ console.warn('[reporter] Skipping DB write — SUPABASE_URL or SUPABASE_SERVICE_ROLE_KEY not set')
195
+ return null
196
+ }
197
+
198
+ const { createClient } = await import('@supabase/supabase-js')
199
+ const db = createClient(url, key, { db: { schema: 'public' } })
200
+
201
+ const passed = results.filter(r => r.status === 'passed').length
202
+ const failed = results.filter(r => r.status === 'failed').length
203
+ const skipped = results.filter(r => r.status === 'skipped').length
204
+ const status = failed > 0 ? 'failed' : 'passed'
205
+
206
+ const { data: run, error: runErr } = await db
207
+ .from('test_runs')
208
+ .insert({
209
+ suite,
210
+ status,
211
+ duration_ms: durationMs,
212
+ total: results.length,
213
+ passed,
214
+ failed,
215
+ skipped,
216
+ finished_at: new Date().toISOString(),
217
+ triggered_by: 'agent'
218
+ })
219
+ .select('id')
220
+ .single()
221
+
222
+ if (runErr || !run) {
223
+ console.warn('[reporter] Failed to insert test_run:', runErr?.message)
224
+ return null
225
+ }
226
+
227
+ if (results.length > 0) {
228
+ const rows = results.map(r => ({
229
+ run_id: run.id,
230
+ suite: r.suite,
231
+ file: r.file ?? null,
232
+ describe: r.describe ?? null,
233
+ name: r.name,
234
+ status: r.status,
235
+ duration_ms: r.duration_ms ?? null,
236
+ error: r.error ?? null
237
+ }))
238
+
239
+ const { error: resultErr } = await db.from('test_results').insert(rows)
240
+ if (resultErr) console.warn('[reporter] Failed to insert test_results:', resultErr.message)
241
+ }
242
+
243
+ console.log(`[reporter] Wrote run ${run.id} — ${suite}: ${passed}✓ ${failed}✗ ${skipped}⊘`)
244
+ return run.id
245
+ }
246
+ // CIL[DOC-VECTOR type="context" content="purpose='Persist a completed test run and its results to Supabase.'; No verified external callers; imports: none"]
247
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
248
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
249
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
250
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
251
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
252
+ // CIL[END stable_id="~/.framework/tests/reporter.ts:writeRunResults:function"]
253
+
254
+ // ─── VITEST REPORTER ───────────────────────────────────────────────────────
255
+
256
+ // CIL[BEGIN stable_id="~/.framework/tests/reporter.ts:SpineReporter:class" type="class" identity="SpineReporter" parent="~/.framework/tests/reporter.ts"]
257
+ // CIL[DOC-MACRO purpose="Implement a Vitest Reporter that collects test results and writes them to the database."]
258
+ // CIL[DOC-RESPONSIBILITY responsibility="Track suite start time, traverse Vitest task tree, and call writeRunResults on finish."]
259
+ // CIL[DOC-CONTEXT module="tests/reporter" layer="test-infrastructure" related_files=".framework/tests/reporter.ts"]
260
+ // CIL[DOC-CONTRACT inputs="files?: File[] from onFinished, tasks: Task[], describePath: string" outputs="persisted run id via writeRunResults" errors="none at class level" side_effects="walks task tree and inserts test results to Supabase"]
261
+ // CIL[DOC-MICRO logic_summary="onInit records start time; onFinished computes duration, flattens nested tasks into TestCaseResult rows, and delegates persistence." notable_decisions="suite derived from file path; error message built from first error message and stack."]
262
+ // CIL[DOC-NOTE type="param" content="tasks: Task[] - array of Vitest tasks"]
263
+ // CIL[DOC-NOTE type="param" content="describePath: string - nested describe path string"]
264
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
265
+ // CIL[DOC-STABILITY stable]
266
+ class SpineReporter implements Reporter {
267
+ private startTime = 0
268
+ private suite = 'unit'
269
+
270
+ onInit() {
271
+ this.startTime = Date.now()
272
+ }
273
+
274
+ async onFinished(files?: File[]) {
275
+ if (!files?.length) return
276
+
277
+ const results: TestCaseResult[] = []
278
+
279
+ for (const file of files) {
280
+ const filePath = file.name
281
+ const suiteName = filePath.includes('/integration/') ? 'integration'
282
+ : filePath.includes('/api/') ? 'api'
283
+ : filePath.includes('/ui/') ? 'ui'
284
+ : 'unit'
285
+ this.suite = suiteName
286
+
287
+ /**
288
+ * Recursively collect test tasks into results.
289
+ * @param {Task[]} tasks - array of Vitest tasks
290
+ * @param {string} describePath - nested describe path string
291
+ */
292
+ function collectTasks(tasks: Task[], describePath: string) {
293
+ for (const task of tasks) {
294
+ if (task.type === 'suite') {
295
+ const nested = (task as any).tasks ?? []
296
+ collectTasks(nested, describePath ? `${describePath} > ${task.name}` : task.name)
297
+ } else {
298
+ const result = (task as any).result
299
+ const status: TestCaseResult['status'] =
300
+ result?.state === 'pass' ? 'passed'
301
+ : result?.state === 'skip' ? 'skipped'
302
+ : 'failed'
303
+
304
+ const errorMsg = result?.errors?.[0]
305
+ ? `${result.errors[0].message ?? ''}\n${result.errors[0].stack ?? ''}`.trim()
306
+ : undefined
307
+
308
+ results.push({
309
+ suite: suiteName,
310
+ file: filePath,
311
+ describe: describePath || undefined,
312
+ name: task.name,
313
+ status,
314
+ duration_ms: result?.duration ? Math.round(result.duration) : undefined,
315
+ error: errorMsg
316
+ })
317
+ }
318
+ }
319
+ }
320
+
321
+ collectTasks((file as any).tasks ?? [], '')
322
+ }
323
+
324
+ const durationMs = Date.now() - this.startTime
325
+ await writeRunResults(this.suite, results, durationMs)
326
+ }
327
+ }
328
+ // CIL[DOC-VECTOR type="context" content="purpose='Implement a Vitest Reporter that collects test results and writes them to the database.'; No verified external callers; imports: none"]
329
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
330
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
331
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
332
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
333
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
334
+ // CIL[END stable_id="~/.framework/tests/reporter.ts:SpineReporter:class"]
335
+
336
+ // CIL[BEGIN stable_id="~/.framework/tests/reporter.ts:default:function" type="function" identity="default" parent="~/.framework/tests/reporter.ts"]
337
+ // CIL[DOC-MACRO purpose="Export the SpineReporter class as the default Vitest reporter."]
338
+ // CIL[DOC-RESPONSIBILITY responsibility="Expose SpineReporter to Vitest reporter resolution."]
339
+ // CIL[DOC-CONTEXT module="tests/reporter" layer="test-infrastructure" related_files=".framework/tests/reporter.ts"]
340
+ // CIL[DOC-CONTRACT inputs="none" outputs="default export of SpineReporter" errors="none" side_effects="none"]
341
+ // CIL[DOC-MICRO logic_summary="Single default export statement." notable_decisions=""]
342
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
343
+ // CIL[DOC-STABILITY stable]
344
+ export default SpineReporter
345
+ // CIL[DOC-VECTOR type="context" content="purpose='Export the SpineReporter class as the default Vitest reporter.'; No verified external callers; imports: none"]
346
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
347
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
348
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
349
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
350
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
351
+ // CIL[END stable_id="~/.framework/tests/reporter.ts:default:function"]