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
@@ -20,10 +20,9 @@
20
20
  }
21
21
  },
22
22
  "app_slug": {
23
- "data_type": "select",
23
+ "data_type": "text",
24
24
  "label": "App",
25
- "required": true,
26
- "options": ["framework", "cortex", "portal"]
25
+ "required": true
27
26
  },
28
27
  "version": {
29
28
  "data_type": "text",
@@ -60,13 +59,31 @@
60
59
  "display": "table",
61
60
  "label": "CLI Instances",
62
61
  "fields": {
63
- "title": { "sortable": true, "display_type": "text" },
64
- "app_slug": { "sortable": true, "display_type": "badge" },
65
- "version": { "sortable": true, "display_type": "text" },
66
- "claimed_at": { "sortable": true, "display_type": "timestamp" },
67
- "last_signal_at": { "sortable": true, "display_type": "timestamp" }
62
+ "title": {
63
+ "sortable": true,
64
+ "display_type": "text"
65
+ },
66
+ "app_slug": {
67
+ "sortable": true,
68
+ "display_type": "badge"
69
+ },
70
+ "version": {
71
+ "sortable": true,
72
+ "display_type": "text"
73
+ },
74
+ "claimed_at": {
75
+ "sortable": true,
76
+ "display_type": "timestamp"
77
+ },
78
+ "last_signal_at": {
79
+ "sortable": true,
80
+ "display_type": "timestamp"
81
+ }
68
82
  },
69
- "default_sort": { "field": "created_at", "direction": "desc" }
83
+ "default_sort": {
84
+ "field": "created_at",
85
+ "direction": "desc"
86
+ }
70
87
  },
71
88
  "default_detail": {
72
89
  "type": "detail",
@@ -75,34 +92,69 @@
75
92
  {
76
93
  "title": "Instance",
77
94
  "fields": {
78
- "serial": { "display_type": "input" },
79
- "app_slug": { "display_type": "select" },
80
- "version": { "display_type": "input" }
95
+ "serial": {
96
+ "display_type": "input"
97
+ },
98
+ "app_slug": {
99
+ "display_type": "select"
100
+ },
101
+ "version": {
102
+ "display_type": "input"
103
+ }
81
104
  }
82
105
  },
83
106
  {
84
107
  "title": "Claim",
85
108
  "fields": {
86
- "claimed_by_person_id": { "display_type": "reference_picker" },
87
- "claimed_at": { "display_type": "timestamp" }
109
+ "claimed_by_person_id": {
110
+ "display_type": "reference_picker"
111
+ },
112
+ "claimed_at": {
113
+ "display_type": "timestamp"
114
+ }
88
115
  }
89
116
  },
90
117
  {
91
118
  "title": "Activity",
92
119
  "fields": {
93
- "first_seen_at": { "display_type": "timestamp" },
94
- "last_signal_at": { "display_type": "timestamp" }
120
+ "first_seen_at": {
121
+ "display_type": "timestamp"
122
+ },
123
+ "last_signal_at": {
124
+ "display_type": "timestamp"
125
+ }
95
126
  }
96
127
  }
97
128
  ]
98
129
  }
99
130
  },
100
131
  "record_permissions": {
101
- "system_admin": ["create", "read", "update", "delete"],
102
- "support_admin": ["create", "read", "update"],
103
- "support": ["create", "read", "update"],
104
- "member_admin": ["create", "read", "update"],
105
- "member": ["create", "read", "update"]
132
+ "system_admin": [
133
+ "create",
134
+ "read",
135
+ "update",
136
+ "delete"
137
+ ],
138
+ "support_admin": [
139
+ "create",
140
+ "read",
141
+ "update"
142
+ ],
143
+ "support": [
144
+ "create",
145
+ "read",
146
+ "update"
147
+ ],
148
+ "member_admin": [
149
+ "create",
150
+ "read",
151
+ "update"
152
+ ],
153
+ "member": [
154
+ "create",
155
+ "read",
156
+ "update"
157
+ ]
106
158
  }
107
159
  },
108
160
  "validation_schema": {},
@@ -2,21 +2,15 @@
2
2
 
3
3
 
4
4
 
5
- // CIL[BEGIN chunk_id="App_module_header_1783931090" type="module_header" identity="imports" parent="none"]
5
+ // CIL[BEGIN stable_id="~/.framework/src/App.tsx:module_header:module_header" type="module_header" identity="module_header" parent="none"]
6
6
  // CIL[DOC-MACRO purpose="Import React and routing dependencies for main app component"]
7
7
  // CIL[DOC-RESPONSIBILITY responsibility="Manage all external module imports and lazy loading"]
8
- // CIL[DOC-CONTEXT module="App" layer="entry-point" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\".framework/src/components/ui/dialog.tsx\",\"\\\"]"]
8
+ // CIL[DOC-CONTEXT module="App" layer="entry-point" related_files=".framework/src/components/AppWrapper.tsx,.framework/src/components/CustomAppLoader.tsx,.framework/src/components/app-shell/GenericAppShell.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/contexts/AppContext.tsx,.framework/src/contexts/AuthContext.tsx,.framework/src/pages/NotFoundPage.tsx,.framework/src/pages/SetupPage.tsx,.framework/src/pages/auth/AuthConfirmPage.tsx,.framework/src/pages/auth/ForgotPasswordPage.tsx,.framework/src/pages/auth/LoginPage.tsx,.framework/src/pages/auth/PendingApprovalPage.tsx,.framework/src/pages/auth/RegisterPage.tsx,.framework/src/pages/spine-framework/APIPage.tsx,.framework/src/pages/spine-framework/CLIPage.tsx"]
9
9
  // CIL[DOC-CONTRACT inputs="none" outputs="Imported modules and lazy components" errors="Import failures" side_effects="Module loading"]
10
10
  // CIL[DOC-MICRO logic_summary="Imports React hooks, routing components, pages, and app shell components" notable_decisions="['lazy_load_admin_app']"]
11
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
11
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
12
12
  // CIL[DOC-STABILITY stability="stable"]
13
13
  // CIL[DOC-AUDIENCE audience="developer"]
14
- // CIL[DOC-VECTOR type="context" content="Layer: entry-point. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/migrations/015_simplify_apps_table.sql, .framework/src/components/ui/dialog.tsx, \."]
15
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
16
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
17
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
18
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
19
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
20
14
  import { Suspense, lazy, useEffect } from 'react'
21
15
  import { Routes, Route, Navigate, useNavigate, useLocation } from 'react-router-dom'
22
16
  import { useAuth } from './contexts/AuthContext'
@@ -26,6 +20,7 @@ import { RegisterPage } from './pages/auth/RegisterPage'
26
20
  import { ForgotPasswordPage } from './pages/auth/ForgotPasswordPage'
27
21
  import { AuthConfirmPage } from './pages/auth/AuthConfirmPage'
28
22
  import { PendingApprovalPage } from './pages/auth/PendingApprovalPage'
23
+ import { NoAppPage } from './pages/NoAppPage'
29
24
  import { NotFoundPage } from './pages/NotFoundPage'
30
25
  import { SetupPage } from './pages/SetupPage'
31
26
  import { AppWrapper } from './components/AppWrapper'
@@ -34,22 +29,40 @@ import { CustomAppLoader } from './components/CustomAppLoader'
34
29
  import { GenericAppShell } from './components/app-shell/GenericAppShell'
35
30
  import { APIPage } from './pages/spine-framework/APIPage'
36
31
  import { CLIPage } from './pages/spine-framework/CLIPage'
32
+ // CIL[DOC-VECTOR type="context" content="purpose='Import React and routing dependencies for main app component'; No verified external callers; imports: .framework/src/contexts/AuthContext.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/pages/auth/LoginPage.tsx"]
33
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
34
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
35
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
36
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
37
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
38
+ // CIL[END stable_id="~/.framework/src/App.tsx:module_header:module_header"]
39
+
40
+ // CIL[BEGIN stable_id="~/.framework/src/App.tsx:adminapp:constant" type="constant" identity="AdminApp" parent="none"]
41
+ // CIL[DOC-MACRO purpose="Lazy-load the admin app component"]
42
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide a lazy-loaded admin app component"]
43
+ // CIL[DOC-CONTEXT module="App" layer="entry-point" related_files=".framework/src/App.tsx,.framework/src/components/AppWrapper.tsx,.framework/src/components/CustomAppLoader.tsx,.framework/src/components/app-shell/GenericAppShell.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/contexts/AppContext.tsx,.framework/src/contexts/AuthContext.tsx,.framework/src/pages/NotFoundPage.tsx,.framework/src/pages/SetupPage.tsx,.framework/src/pages/auth/AuthConfirmPage.tsx,.framework/src/pages/auth/ForgotPasswordPage.tsx,.framework/src/pages/auth/LoginPage.tsx,.framework/src/pages/auth/PendingApprovalPage.tsx,.framework/src/pages/auth/RegisterPage.tsx,.framework/src/pages/spine-framework/APIPage.tsx,.framework/src/pages/spine-framework/CLIPage.tsx"]
44
+ // CIL[DOC-CONTRACT inputs="none" outputs="Lazy-loaded AdminApp component" errors="none" side_effects="none"]
45
+ // CIL[DOC-MICRO logic_summary="Lazily imports and exposes the admin application bundle" notable_decisions="[]"]
46
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
47
+ // CIL[DOC-STABILITY stability="stable"]
37
48
  const AdminApp = lazy(() => import('./apps/admin/index'))
38
- // CIL[END chunk_id="App_module_header_1783931090"]
39
- // CIL[BEGIN chunk_id="App_app_1783931090" type="function" identity="App" parent="none"]
49
+ // CIL[DOC-VECTOR type="context" content="purpose='Lazy-load the admin app component'; No verified external callers; imports: .framework/src/contexts/AuthContext.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/pages/auth/LoginPage.tsx"]
50
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
51
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
52
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
53
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
54
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
55
+ // CIL[END stable_id="~/.framework/src/App.tsx:adminapp:constant"]
56
+
57
+ // CIL[BEGIN stable_id="~/.framework/src/App.tsx:app:function" type="function" identity="App" parent="none"]
40
58
  // CIL[DOC-MACRO purpose="Root app component handling authentication state and routing"]
41
59
  // CIL[DOC-RESPONSIBILITY responsibility="Manage global app state, auth flows, and route selection"]
42
- // CIL[DOC-CONTEXT module="App" layer="entry-point" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\".framework/src/components/ui/dialog.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
60
+ // CIL[DOC-CONTEXT module="App" layer="entry-point" related_files=".framework/src/App.tsx,.framework/src/components/AppWrapper.tsx,.framework/src/components/CustomAppLoader.tsx,.framework/src/components/app-shell/GenericAppShell.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/contexts/AppContext.tsx,.framework/src/contexts/AuthContext.tsx,.framework/src/pages/NotFoundPage.tsx,.framework/src/pages/SetupPage.tsx,.framework/src/pages/auth/AuthConfirmPage.tsx,.framework/src/pages/auth/ForgotPasswordPage.tsx,.framework/src/pages/auth/LoginPage.tsx,.framework/src/pages/auth/PendingApprovalPage.tsx,.framework/src/pages/auth/RegisterPage.tsx,.framework/src/pages/spine-framework/APIPage.tsx,.framework/src/pages/spine-framework/CLIPage.tsx"]
43
61
  // CIL[DOC-CONTRACT inputs="none" outputs="JSX routes based on auth state" errors="Auth context failures" side_effects="Navigation, route rendering"]
44
- // CIL[DOC-MICRO logic_summary="Shows loading, handles auth states, routes to appropriate components" notable_decisions="['ternary_auth_routing', 'setup_mode_check']"]
45
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
62
+ // CIL[DOC-MICRO logic_summary="Shows loading, handles auth states, routes to appropriate components" notable_decisions="['ternary_auth_routing', 'setup_mode_check', 'unplaced_person_resume_routing']"]
63
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
46
64
  // CIL[DOC-STABILITY stability="stable"]
47
- // CIL[DOC-VECTOR type="context" content="Layer: entry-point. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/migrations/015_simplify_apps_table.sql, .framework/src/components/ui/dialog.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
48
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
49
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
50
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
51
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
52
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
65
+ // CIL[DOC-NOTE type="change" content="Batch4b: authenticated-but-unplaced users (falsy account_id, not pending) are routed to /register?resume=1 for all paths so RegisterPage can finish placement — they no longer fall through to NotFound"]
53
66
  function App() {
54
67
  const { user, isLoading } = useAuth()
55
68
 
@@ -86,43 +99,61 @@ function App() {
86
99
  <Routes>
87
100
  <Route path="*" element={<PendingApprovalPage />} />
88
101
  </Routes>
102
+ ) : !user.account_id ? (
103
+ // Authenticated but unplaced (no account bound yet) — e.g. email
104
+ // confirmation interrupted registration. Route everything to
105
+ // /register?resume=1 so RegisterPage can finish placement; never
106
+ // let them hit NotFound.
107
+ <Routes>
108
+ <Route path="/register" element={<RegisterPage />} />
109
+ <Route path="/auth/confirm" element={<AuthConfirmPage />} />
110
+ <Route path="/auth/pending-approval" element={<PendingApprovalPage />} />
111
+ <Route path="*" element={<Navigate to="/register?resume=1" replace />} />
112
+ </Routes>
89
113
  ) : (
90
114
  <AuthenticatedRouter />
91
115
  )}
92
116
  </AppsRegistryProvider>
93
117
  )
94
118
  }
95
- // CIL[END chunk_id="App_app_1783931090"]
96
- // CIL[BEGIN chunk_id="App_authenticatedrouter_1783931090" type="function" identity="AuthenticatedRouter" parent="none"]
119
+ // CIL[DOC-VECTOR type="context" content="purpose='Root app component handling authentication state and routing'; No verified external callers; imports: .framework/src/contexts/AuthContext.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/pages/auth/LoginPage.tsx"]
120
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
121
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
122
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
123
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
124
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
125
+ // CIL[END stable_id="~/.framework/src/App.tsx:app:function"]
126
+
127
+ // CIL[BEGIN stable_id="~/.framework/src/App.tsx:authenticatedrouter:function" type="function" identity="AuthenticatedRouter" parent="none"]
97
128
  // CIL[DOC-LEARNING topic="App:renderer_switch" content="The public.apps.renderer field switches routing: 'custom' uses CustomAppLoader and loads custom/apps/<slug>/index.tsx; 'generic' uses GenericAppShell and builds a schema-driven UI from nav_items."]
98
129
  // CIL[DOC-MACRO purpose="Handle authenticated user routing and dynamic app loading"]
99
130
  // CIL[DOC-RESPONSIBILITY responsibility="Manage app registry, route sorting, and dynamic component rendering"]
100
- // CIL[DOC-CONTEXT module="App" layer="routing" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\"\\\"]"]
131
+ // CIL[DOC-CONTEXT module="App" layer="routing" related_files=".framework/src/App.tsx,.framework/src/components/AppWrapper.tsx,.framework/src/components/CustomAppLoader.tsx,.framework/src/components/app-shell/GenericAppShell.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/contexts/AppContext.tsx,.framework/src/contexts/AuthContext.tsx,.framework/src/pages/NotFoundPage.tsx,.framework/src/pages/SetupPage.tsx,.framework/src/pages/auth/AuthConfirmPage.tsx,.framework/src/pages/auth/ForgotPasswordPage.tsx,.framework/src/pages/auth/LoginPage.tsx,.framework/src/pages/auth/PendingApprovalPage.tsx,.framework/src/pages/auth/RegisterPage.tsx,.framework/src/pages/spine-framework/APIPage.tsx,.framework/src/pages/spine-framework/CLIPage.tsx"]
101
132
  // CIL[DOC-CONTRACT inputs="none" outputs="Dynamic routes for authenticated apps" errors="App loading failures" side_effects="Navigation, lazy loading"]
102
- // CIL[DOC-MICRO logic_summary="Loads apps, sorts routes, handles redirects, renders dynamic app components" notable_decisions="['route_prefix_sorting', 'renderer_type_switching']"]
103
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
133
+ // CIL[DOC-MICRO logic_summary="Loads apps, sorts routes, handles redirects, renders dynamic app components" notable_decisions="['route_prefix_sorting', 'renderer_type_switching', 'no_app_page_landing', 'unplaced_register_guard']"]
134
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
104
135
  // CIL[DOC-STABILITY stability="stable"]
105
- // CIL[DOC-VECTOR type="context" content="Layer: routing. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/migrations/015_simplify_apps_table.sql, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, \."]
106
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
107
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
108
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
109
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
110
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
136
+ // CIL[DOC-NOTE type="change" content="Batch4b: '/' now resolves to admin / root app / first app prefix / NoAppPage; redirect effect no longer bounces unplaced users off /register"]
111
137
  function AuthenticatedRouter() {
112
138
  const { user } = useAuth()
113
139
  const { routableApps: apps, loading } = useAppsRegistry()
114
140
  const navigate = useNavigate()
115
141
  const location = useLocation()
116
142
 
143
+ // Authenticated but unplaced (no account bound) — RegisterPage resume mode
144
+ // must be allowed to run; never bounce them off /register.
145
+ const isUnplaced = !!user && !user.account_id
146
+
117
147
  const defaultRedirect = user?.roles?.includes('system_admin')
118
148
  ? '/spine-framework/admin'
119
149
  : (apps[0]?.route_prefix || '/')
120
150
 
121
151
  useEffect(() => {
122
152
  if (!loading && ['/login', '/register'].includes(location.pathname)) {
153
+ if (isUnplaced && location.pathname === '/register') return
123
154
  navigate(defaultRedirect, { replace: true })
124
155
  }
125
- }, [loading, location.pathname, defaultRedirect, navigate])
156
+ }, [loading, location.pathname, defaultRedirect, navigate, isUnplaced])
126
157
 
127
158
  if (loading) {
128
159
  return (
@@ -145,6 +176,38 @@ function AuthenticatedRouter() {
145
176
 
146
177
  const toRoutePath = (prefix: string) => prefix === '/' ? '/*' : `${prefix}/*`
147
178
 
179
+ const renderAppElement = (app: (typeof apps)[number]) => {
180
+ if (app.renderer === 'custom') {
181
+ return (
182
+ <AppWrapper app={app}>
183
+ <CustomAppLoader slug={app.slug} />
184
+ </AppWrapper>
185
+ )
186
+ }
187
+ if (app.renderer === 'generic') {
188
+ return (
189
+ <AppWrapper app={app}>
190
+ <GenericAppShell app={app} />
191
+ </AppWrapper>
192
+ )
193
+ }
194
+ return null
195
+ }
196
+
197
+ // '/' landing: system_admin → admin; a root-mounted app renders directly;
198
+ // otherwise first sorted app prefix; nothing routable → neutral NoAppPage
199
+ // instead of Navigate-to-'/' falling through to NotFoundPage.
200
+ const rootApp = sorted.find(a => a.route_prefix === '/')
201
+ const firstAppPrefix = sorted.find(a => a.route_prefix && a.route_prefix !== '/')?.route_prefix
202
+ const rootElement =
203
+ user?.is_system_admin || user?.roles?.includes('system_admin')
204
+ ? <Navigate to="/spine-framework/admin" replace />
205
+ : rootApp
206
+ ? renderAppElement(rootApp)
207
+ : firstAppPrefix
208
+ ? <Navigate to={firstAppPrefix} replace />
209
+ : <NoAppPage />
210
+
148
211
  return (
149
212
  <Suspense fallback={<div className="min-h-screen flex items-center justify-center"><LoadingSpinner /></div>}>
150
213
  <Routes>
@@ -156,39 +219,15 @@ function AuthenticatedRouter() {
156
219
  <Route path="/register" element={<RegisterPage />} />
157
220
  <Route path="/forgot-password" element={<ForgotPasswordPage />} />
158
221
  <Route path="/auth/confirm" element={<AuthConfirmPage />} />
222
+ <Route path="/auth/pending-approval" element={<PendingApprovalPage />} />
223
+
224
+ <Route path="/" element={rootElement} />
159
225
 
160
226
  {sorted.map(app => {
161
227
  const prefix = app.route_prefix!
162
-
163
- if (app.renderer === 'custom') {
164
- return (
165
- <Route
166
- key={app.slug}
167
- path={toRoutePath(prefix)}
168
- element={
169
- <AppWrapper app={app}>
170
- <CustomAppLoader slug={app.slug} />
171
- </AppWrapper>
172
- }
173
- />
174
- )
175
- }
176
-
177
- if (app.renderer === 'generic') {
178
- return (
179
- <Route
180
- key={app.slug}
181
- path={toRoutePath(prefix)}
182
- element={
183
- <AppWrapper app={app}>
184
- <GenericAppShell app={app} />
185
- </AppWrapper>
186
- }
187
- />
188
- )
189
- }
190
-
191
- return null
228
+ const element = renderAppElement(app)
229
+ if (!element) return null
230
+ return <Route key={app.slug} path={toRoutePath(prefix)} element={element} />
192
231
  })}
193
232
 
194
233
  <Route path="*" element={<NotFoundPage />} />
@@ -196,20 +235,27 @@ function AuthenticatedRouter() {
196
235
  </Suspense>
197
236
  )
198
237
  }
199
- // CIL[END chunk_id="App_authenticatedrouter_1783931090"]
200
- // CIL[BEGIN chunk_id="App_export_1783931090" type="export" identity="export_default" parent="none"]
238
+ // CIL[DOC-VECTOR type="context" content="purpose='Handle authenticated user routing and dynamic app loading'; No verified external callers; imports: .framework/src/contexts/AuthContext.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/pages/auth/LoginPage.tsx"]
239
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
240
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
241
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
242
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
243
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
244
+ // CIL[END stable_id="~/.framework/src/App.tsx:authenticatedrouter:function"]
245
+
246
+ // CIL[BEGIN stable_id="~/.framework/src/App.tsx:export_default:export" type="export" identity="export_default" parent="none"]
201
247
  // CIL[DOC-MACRO purpose="Export the main App component as default"]
202
248
  // CIL[DOC-RESPONSIBILITY responsibility="Provide the entry point for the React application"]
203
- // CIL[DOC-CONTEXT module="App" layer="entry-point" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/components/ui/table-primitives.tsx\",\"\\\"]"]
249
+ // CIL[DOC-CONTEXT module="App" layer="entry-point" related_files=".framework/src/App.tsx,.framework/src/components/AppWrapper.tsx,.framework/src/components/CustomAppLoader.tsx,.framework/src/components/app-shell/GenericAppShell.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/contexts/AppContext.tsx,.framework/src/contexts/AuthContext.tsx,.framework/src/pages/NotFoundPage.tsx,.framework/src/pages/SetupPage.tsx,.framework/src/pages/auth/AuthConfirmPage.tsx,.framework/src/pages/auth/ForgotPasswordPage.tsx,.framework/src/pages/auth/LoginPage.tsx,.framework/src/pages/auth/PendingApprovalPage.tsx,.framework/src/pages/auth/RegisterPage.tsx,.framework/src/pages/spine-framework/APIPage.tsx,.framework/src/pages/spine-framework/CLIPage.tsx"]
204
250
  // CIL[DOC-CONTRACT inputs="none" outputs="App component" errors="none" side_effects="Application bootstrap"]
205
251
  // CIL[DOC-MICRO logic_summary="Default export of the root App component" notable_decisions="[]"]
206
- // CIL[DOC-CONFIDENCE pass="second" score="1.00" flags="none"]
252
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
207
253
  // CIL[DOC-STABILITY stability="stable"]
208
- // CIL[DOC-VECTOR type="context" content="Layer: entry-point. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/migrations/015_simplify_apps_table.sql, custom/apps/portal/pages/ContentPage.tsx, .framework/src/components/ui/table-primitives.tsx, \."]
209
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
210
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
211
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
254
+ export default App
255
+ // CIL[DOC-VECTOR type="context" content="purpose='Export the main App component as default'; No verified external callers; imports: .framework/src/contexts/AuthContext.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/pages/auth/LoginPage.tsx"]
256
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
257
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
258
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
212
259
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
213
260
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
214
- export default App
215
- // CIL[END chunk_id="App_export_1783931090"]
261
+ // CIL[END stable_id="~/.framework/src/App.tsx:export_default:export"]