spine-framework 0.3.124 → 0.3.126

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 (319) hide show
  1. package/.framework/cli/commands/agents.ts +35 -37
  2. package/.framework/cli/commands/auth.ts +35 -34
  3. package/.framework/cli/commands/create-app.ts +104 -40
  4. package/.framework/cli/commands/dev.ts +104 -69
  5. package/.framework/cli/commands/doctor.ts +179 -69
  6. package/.framework/cli/commands/generate.ts +83 -143
  7. package/.framework/cli/commands/init.ts +72 -34
  8. package/.framework/cli/commands/install-app.ts +260 -125
  9. package/.framework/cli/commands/items.ts +33 -44
  10. package/.framework/cli/commands/migrate.ts +122 -40
  11. package/.framework/cli/commands/migrations.ts +33 -40
  12. package/.framework/cli/commands/pipelines.ts +31 -39
  13. package/.framework/cli/commands/status.ts +47 -23
  14. package/.framework/cli/commands/system.ts +47 -37
  15. package/.framework/cli/commands/test.ts +112 -68
  16. package/.framework/cli/commands/validate-app.ts +215 -121
  17. package/.framework/cli/context.ts +112 -130
  18. package/.framework/cli/env-loader.ts +47 -18
  19. package/.framework/cli/index.ts +81 -42
  20. package/.framework/docs/runtime-types.md +1024 -0
  21. package/.framework/functions/_shared/agent-runner.ts +1296 -961
  22. package/.framework/functions/_shared/app-manifest.ts +82 -68
  23. package/.framework/functions/_shared/audit.ts +135 -83
  24. package/.framework/functions/_shared/{cil-state.ts → cil.ts} +158 -56
  25. package/.framework/functions/_shared/db.ts +80 -126
  26. package/.framework/functions/_shared/hash-api-key.ts +63 -0
  27. package/.framework/functions/_shared/index.ts +224 -335
  28. package/.framework/functions/_shared/kb.ts +319 -0
  29. package/.framework/functions/_shared/llm.ts +92 -0
  30. package/.framework/functions/_shared/logging.ts +288 -0
  31. package/.framework/functions/_shared/middleware.ts +329 -365
  32. package/.framework/functions/_shared/outcomes.ts +36 -0
  33. package/.framework/functions/_shared/permissions.ts +359 -643
  34. package/.framework/functions/_shared/pipeline-runner.ts +243 -316
  35. package/.framework/functions/_shared/principal.ts +376 -468
  36. package/.framework/functions/_shared/resolve-credentials.ts +102 -0
  37. package/.framework/functions/_shared/resolve-ids.ts +188 -16
  38. package/.framework/functions/_shared/retry-deliveries.ts +104 -0
  39. package/.framework/functions/_shared/schema-utils.ts +611 -373
  40. package/.framework/functions/_shared/testing.ts +207 -137
  41. package/.framework/functions/_shared/tracing.ts +276 -0
  42. package/.framework/functions/_shared/trigger-engine.ts +159 -211
  43. package/.framework/functions/_shared/webhook-registration.ts +95 -81
  44. package/.framework/functions/_shared/webhook-registry.ts +153 -75
  45. package/.framework/functions/account-nodes.ts +31 -53
  46. package/.framework/functions/adapters/generic-webhook-inbound.ts +56 -0
  47. package/.framework/functions/adapters/generic-webhook-outbound.ts +43 -0
  48. package/.framework/functions/adapters/openai-outbound.ts +40 -0
  49. package/.framework/functions/admin-data.ts +685 -537
  50. package/.framework/functions/admin-funnel.ts +31 -20
  51. package/.framework/functions/admin-install-funnel.ts +47 -28
  52. package/.framework/functions/admin-signals.ts +47 -29
  53. package/.framework/functions/ai-agents.ts +122 -147
  54. package/.framework/functions/ai-interactions.ts +180 -90
  55. package/.framework/functions/api-keys.ts +250 -192
  56. package/.framework/functions/apps.ts +203 -197
  57. package/.framework/functions/auth.ts +98 -91
  58. package/.framework/functions/cil-agent-ingest.ts +773 -0
  59. package/.framework/functions/cil-agent.ts +592 -0
  60. package/.framework/functions/cil-callmap.ts +1227 -0
  61. package/.framework/functions/cil-config.ts +583 -0
  62. package/.framework/functions/cil-context.ts +445 -0
  63. package/.framework/functions/cil-doc.ts +1752 -0
  64. package/.framework/functions/cil-embeddings.ts +1202 -0
  65. package/.framework/functions/cil-graph.ts +585 -0
  66. package/.framework/functions/cil-ingest.ts +2416 -0
  67. package/.framework/functions/cil-pipeline.ts +318 -0
  68. package/.framework/functions/cil-project.ts +499 -0
  69. package/.framework/functions/cil-validate.ts +469 -0
  70. package/.framework/functions/debug-auth.ts +73 -53
  71. package/.framework/functions/deliveries.ts +117 -0
  72. package/.framework/functions/embeddings.ts +528 -516
  73. package/.framework/functions/eval-harness.ts +158 -106
  74. package/.framework/functions/integration-outbound.ts +311 -0
  75. package/.framework/functions/integration-routes.ts +240 -466
  76. package/.framework/functions/integrations.ts +132 -140
  77. package/.framework/functions/invites.ts +401 -201
  78. package/.framework/functions/item-progress.ts +113 -53
  79. package/.framework/functions/kb.ts +28 -0
  80. package/.framework/functions/logs.ts +239 -222
  81. package/.framework/functions/observability.ts +308 -259
  82. package/.framework/functions/pipeline-executions.ts +179 -235
  83. package/.framework/functions/pipelines.ts +163 -205
  84. package/.framework/functions/prompt-configs.ts +109 -156
  85. package/.framework/functions/roles.ts +97 -147
  86. package/.framework/functions/system-cron.ts +132 -218
  87. package/.framework/functions/system.ts +112 -52
  88. package/.framework/functions/tests.ts +32 -28
  89. package/.framework/functions/timers.ts +162 -210
  90. package/.framework/functions/triggers.ts +282 -346
  91. package/.framework/functions/types.ts +283 -400
  92. package/.framework/migrations/001_core_schema.sql +630 -0
  93. package/.framework/migrations/002_core_rls_and_functions.sql +532 -0
  94. package/.framework/migrations/{003_system_data.sql → 003_core_system_data.sql} +26 -153
  95. package/.framework/migrations/004_core_rpc_and_broker.sql +421 -0
  96. package/.framework/migrations/005_core_observability.sql +598 -0
  97. package/.framework/migrations/006_security_hardening_rls.sql +97 -0
  98. package/.framework/migrations/007_kb_article_list.sql +237 -0
  99. package/.framework/migrations/008_items_target.sql +8 -0
  100. package/.framework/migrations/009_roles_slug_unique.sql +11 -0
  101. package/.framework/public/spine.config.json +91 -0
  102. package/.framework/scripts/app-install-cli.ts +112 -98
  103. package/.framework/src/App.tsx +67 -20
  104. package/.framework/src/apps/admin/index.tsx +97 -27
  105. package/.framework/src/components/AppWrapper.tsx +50 -11
  106. package/.framework/src/components/CustomAppLoader.tsx +131 -22
  107. package/.framework/src/components/admin/AdminListPage.tsx +75 -8
  108. package/.framework/src/components/admin/AdminSidebar.tsx +148 -36
  109. package/.framework/src/components/admin/AdminStatsCard.tsx +48 -29
  110. package/.framework/src/components/admin/PageInstructions.tsx +49 -0
  111. package/.framework/src/components/admin/SortableTableHeader.tsx +49 -2
  112. package/.framework/src/components/app-shell/GenericAppShell.tsx +69 -11
  113. package/.framework/src/components/app-shell/GenericDetailPage.tsx +55 -10
  114. package/.framework/src/components/app-shell/GenericListPage.tsx +76 -9
  115. package/.framework/src/components/app-sidebar.tsx +50 -3
  116. package/.framework/src/components/auth/ProtectedRoute.tsx +53 -45
  117. package/.framework/src/components/kb/KBArticleEditor.tsx +409 -0
  118. package/.framework/src/components/kb/KBArticleList.tsx +557 -0
  119. package/.framework/src/components/layout/AppShell.tsx +54 -16
  120. package/.framework/src/components/layout/Header.tsx +50 -38
  121. package/.framework/src/components/layout/Layout.tsx +48 -32
  122. package/.framework/src/components/layout/Sidebar.tsx +167 -16
  123. package/.framework/src/components/runtime/DataDetailHeader.tsx +33 -1
  124. package/.framework/src/components/runtime/DataDetailPage.tsx +289 -4
  125. package/.framework/src/components/runtime/DataFilters.tsx +78 -1
  126. package/.framework/src/components/runtime/DataHeader.tsx +32 -29
  127. package/.framework/src/components/runtime/DataListPage.tsx +161 -2
  128. package/.framework/src/components/runtime/DataStats.tsx +48 -1
  129. package/.framework/src/components/runtime/DataTable.tsx +153 -1
  130. package/.framework/src/components/runtime/SchemaDetailForm.tsx +77 -46
  131. package/.framework/src/components/runtime/index.ts +16 -9
  132. package/.framework/src/components/search-form.tsx +33 -1
  133. package/.framework/src/components/shared/AgentView.tsx +48 -51
  134. package/.framework/src/components/shared/FieldRenderer.tsx +84 -67
  135. package/.framework/src/components/shared/InviteManager.tsx +113 -52
  136. package/.framework/src/components/shared/MemberList.tsx +182 -0
  137. package/.framework/src/components/shared/SchemaFields.tsx +96 -78
  138. package/.framework/src/components/ui/DataTable.tsx +86 -56
  139. package/.framework/src/components/ui/Form.tsx +188 -109
  140. package/.framework/src/components/ui/ItemCard.tsx +86 -58
  141. package/.framework/src/components/ui/ItemListView.tsx +88 -61
  142. package/.framework/src/components/ui/LoadingSpinner.tsx +52 -27
  143. package/.framework/src/components/ui/Modal.tsx +81 -4
  144. package/.framework/src/components/ui/RichTextEditor.tsx +101 -9
  145. package/.framework/src/components/ui/accordion.tsx +97 -5
  146. package/.framework/src/components/ui/alert-dialog.tsx +225 -13
  147. package/.framework/src/components/ui/alert.tsx +113 -6
  148. package/.framework/src/components/ui/aspect-ratio.tsx +49 -2
  149. package/.framework/src/components/ui/avatar.tsx +129 -7
  150. package/.framework/src/components/ui/badge.tsx +65 -3
  151. package/.framework/src/components/ui/breadcrumb.tsx +145 -8
  152. package/.framework/src/components/ui/button-group.tsx +81 -4
  153. package/.framework/src/components/ui/button.tsx +49 -2
  154. package/.framework/src/components/ui/calendar.tsx +65 -3
  155. package/.framework/src/components/ui/card.tsx +145 -8
  156. package/.framework/src/components/ui/carousel.tsx +129 -7
  157. package/.framework/src/components/ui/chart.tsx +161 -10
  158. package/.framework/src/components/ui/checkbox.tsx +49 -2
  159. package/.framework/src/components/ui/collapsible.tsx +81 -5
  160. package/.framework/src/components/ui/combobox.tsx +305 -20
  161. package/.framework/src/components/ui/command.tsx +177 -11
  162. package/.framework/src/components/ui/context-menu.tsx +273 -17
  163. package/.framework/src/components/ui/dialog.tsx +209 -27
  164. package/.framework/src/components/ui/direction.tsx +64 -4
  165. package/.framework/src/components/ui/drawer.tsx +193 -12
  166. package/.framework/src/components/ui/dropdown-menu.tsx +273 -18
  167. package/.framework/src/components/ui/empty.tsx +145 -9
  168. package/.framework/src/components/ui/field.tsx +209 -14
  169. package/.framework/src/components/ui/hover-card.tsx +81 -4
  170. package/.framework/src/components/ui/input-group.tsx +162 -10
  171. package/.framework/src/components/ui/input-otp.tsx +98 -5
  172. package/.framework/src/components/ui/input.tsx +49 -2
  173. package/.framework/src/components/ui/item.tsx +225 -13
  174. package/.framework/src/components/ui/kbd.tsx +65 -3
  175. package/.framework/src/components/ui/label.tsx +49 -2
  176. package/.framework/src/components/ui/menubar.tsx +289 -17
  177. package/.framework/src/components/ui/native-select.tsx +97 -5
  178. package/.framework/src/components/ui/navigation-menu.tsx +177 -10
  179. package/.framework/src/components/ui/pagination.tsx +161 -9
  180. package/.framework/src/components/ui/popover.tsx +145 -8
  181. package/.framework/src/components/ui/progress.tsx +49 -2
  182. package/.framework/src/components/ui/radio-group.tsx +65 -3
  183. package/.framework/src/components/ui/resizable.tsx +82 -4
  184. package/.framework/src/components/ui/scroll-area.tsx +65 -3
  185. package/.framework/src/components/ui/select.tsx +193 -11
  186. package/.framework/src/components/ui/separator.tsx +49 -2
  187. package/.framework/src/components/ui/sheet.tsx +193 -11
  188. package/.framework/src/components/ui/sidebar.tsx +481 -38
  189. package/.framework/src/components/ui/skeleton.tsx +49 -2
  190. package/.framework/src/components/ui/slider.tsx +49 -2
  191. package/.framework/src/components/ui/sonner.tsx +49 -2
  192. package/.framework/src/components/ui/spinner.tsx +49 -2
  193. package/.framework/src/components/ui/switch.tsx +49 -2
  194. package/.framework/src/components/ui/table-primitives.tsx +160 -33
  195. package/.framework/src/components/ui/table.tsx +161 -9
  196. package/.framework/src/components/ui/tabs.tsx +113 -6
  197. package/.framework/src/components/ui/textarea.tsx +49 -2
  198. package/.framework/src/components/ui/toggle-group.tsx +81 -4
  199. package/.framework/src/components/ui/toggle.tsx +65 -3
  200. package/.framework/src/components/ui/tooltip.tsx +97 -5
  201. package/.framework/src/contexts/AppContext.tsx +129 -45
  202. package/.framework/src/contexts/AuthContext.tsx +187 -144
  203. package/.framework/src/hooks/use-mobile.ts +48 -2
  204. package/.framework/src/hooks/useApi.ts +208 -159
  205. package/.framework/src/hooks/useAppPath.ts +32 -23
  206. package/.framework/src/hooks/useApps.ts +51 -20
  207. package/.framework/src/hooks/useEntityList.ts +32 -78
  208. package/.framework/src/hooks/useEntityRecord.ts +35 -96
  209. package/.framework/src/hooks/useForm.ts +32 -92
  210. package/.framework/src/hooks/useListSchema.ts +49 -78
  211. package/.framework/src/hooks/useSchemaRecord.ts +114 -105
  212. package/.framework/src/lib/api.ts +195 -116
  213. package/.framework/src/lib/supabase.ts +98 -64
  214. package/.framework/src/lib/utils.ts +287 -151
  215. package/.framework/src/main.tsx +49 -3
  216. package/.framework/src/pages/DashboardPage.tsx +52 -29
  217. package/.framework/src/pages/NotFoundPage.tsx +32 -10
  218. package/.framework/src/pages/SetupPage.tsx +32 -12
  219. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +119 -10
  220. package/.framework/src/pages/admin/AIAgentsPage.tsx +48 -19
  221. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +187 -17
  222. package/.framework/src/pages/admin/APIKeysPage.tsx +98 -22
  223. package/.framework/src/pages/admin/AlertsConfigPage.tsx +113 -26
  224. package/.framework/src/pages/admin/AppDetailPage.tsx +125 -8
  225. package/.framework/src/pages/admin/AppsPage.tsx +49 -2
  226. package/.framework/src/pages/admin/DeliveriesPage.tsx +196 -0
  227. package/.framework/src/pages/admin/DesignedPage.tsx +32 -18
  228. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +215 -484
  229. package/.framework/src/pages/admin/EmbeddingsPage.tsx +116 -319
  230. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +34 -9
  231. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +34 -9
  232. package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -16
  233. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +183 -26
  234. package/.framework/src/pages/admin/IntegrationsPage.tsx +48 -19
  235. package/.framework/src/pages/admin/InvitesPage.tsx +48 -14
  236. package/.framework/src/pages/admin/LogsPage.tsx +422 -75
  237. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +34 -9
  238. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +113 -24
  239. package/.framework/src/pages/admin/PipelineDetailPage.tsx +206 -34
  240. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +50 -17
  241. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -21
  242. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +378 -88
  243. package/.framework/src/pages/admin/PromptConfigsPage.tsx +125 -16
  244. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +49 -10
  245. package/.framework/src/pages/admin/RoleDetailPage.tsx +130 -10
  246. package/.framework/src/pages/admin/RolesPage.tsx +171 -18
  247. package/.framework/src/pages/admin/SelectTestPage.tsx +34 -9
  248. package/.framework/src/pages/admin/ShadcnTestPage.tsx +49 -11
  249. package/.framework/src/pages/admin/SimpleDashboard.tsx +49 -10
  250. package/.framework/src/pages/admin/TestRunDetailPage.tsx +49 -4
  251. package/.framework/src/pages/admin/TestingDashboard.tsx +98 -28
  252. package/.framework/src/pages/admin/TimerDetailPage.tsx +143 -33
  253. package/.framework/src/pages/admin/TimersPage.tsx +48 -20
  254. package/.framework/src/pages/admin/TriggerDetailPage.tsx +118 -30
  255. package/.framework/src/pages/admin/TriggersPage.tsx +64 -19
  256. package/.framework/src/pages/admin/TypeDetailPage.tsx +138 -15
  257. package/.framework/src/pages/admin/TypesPage.tsx +48 -20
  258. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +465 -0
  259. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +787 -0
  260. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +699 -0
  261. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +647 -0
  262. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +616 -0
  263. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +1402 -0
  264. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +614 -0
  265. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +571 -0
  266. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +731 -0
  267. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
  268. package/.framework/src/pages/auth/AuthConfirmPage.tsx +52 -51
  269. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +31 -22
  270. package/.framework/src/pages/auth/LoginPage.tsx +50 -23
  271. package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -15
  272. package/.framework/src/pages/auth/RegisterPage.tsx +281 -317
  273. package/.framework/src/pages/spine-framework/APIPage.tsx +33 -0
  274. package/.framework/src/pages/spine-framework/CLIPage.tsx +33 -0
  275. package/.framework/src/types/auth.ts +128 -71
  276. package/.framework/src/types/types.ts +373 -157
  277. package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +39 -0
  278. package/custom/.devin/skills/spine-workbench-idea/SKILL.md +36 -0
  279. package/custom/.devin/skills/spine-workbench-implement/SKILL.md +46 -0
  280. package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +28 -0
  281. package/custom/.devin/skills/spine-workbench-plan/SKILL.md +38 -0
  282. package/docs/README.md +9 -130
  283. package/netlify.toml +5 -2
  284. package/package.json +13 -25
  285. package/scripts/kb-ingest-docs.ts +203 -0
  286. package/spine.config.json +65 -4
  287. package/.framework/migrations/001_schema.sql +0 -425
  288. package/.framework/migrations/002_rls_and_functions.sql +0 -763
  289. package/.framework/migrations/004_enhancements.sql +0 -43
  290. package/.framework/migrations/005_auth_user_trigger.sql +0 -105
  291. package/.framework/migrations/006_fix_current_actor_id.sql +0 -21
  292. package/.framework/migrations/016_invites.sql +0 -27
  293. package/.framework/migrations/017_fix_get_account_apps.sql +0 -78
  294. package/.framework/migrations/018_apps_required_roles.sql +0 -17
  295. package/.framework/migrations/019_triggers_unique_constraint.sql +0 -13
  296. package/.framework/migrations/020_get_account_apps_role_filter.sql +0 -117
  297. package/.framework/migrations/021_app_domains.sql +0 -112
  298. package/.framework/migrations/022_route_prefix_domain_unique.sql +0 -21
  299. package/.framework/migrations/023_match_embeddings_rpc.sql +0 -78
  300. package/.framework/migrations/024_messages_account_id.sql +0 -9
  301. package/.framework/migrations/025_retype_threads_messages.sql +0 -240
  302. package/.framework/migrations/026_fix_rls_policies.sql +0 -47
  303. package/.framework/migrations/027_embedding_lifecycle.sql +0 -176
  304. package/.framework/migrations/028_fix_message_data_permissions.sql +0 -49
  305. package/.framework/migrations/029_tighten_support_triage_prompt.sql +0 -41
  306. package/.framework/migrations/030_messages_updated_by.sql +0 -6
  307. package/.framework/migrations/031_seed_upsert_constraints.sql +0 -35
  308. package/docs/APPS.md +0 -232
  309. package/docs/ARCHITECTURE.md +0 -246
  310. package/docs/INSTALL.md +0 -155
  311. package/docs/design-schema-spec.md +0 -1837
  312. package/docs/dev-guides/01-create-an-app.md +0 -183
  313. package/docs/dev-guides/02-create-a-function.md +0 -178
  314. package/docs/dev-guides/03-create-a-component.md +0 -178
  315. package/docs/dev-guides/04-webhook-handlers.md +0 -129
  316. package/docs/dev-guides/05-testing.md +0 -168
  317. package/docs/dev-guides/README.md +0 -40
  318. package/docs/npm-packages-plan.md +0 -288
  319. package/docs/spine-core--api-reference.md +0 -822
@@ -0,0 +1,64 @@
1
+ import { useParams, useNavigate } from 'react-router-dom'
2
+ import { KBArticleList } from '../../../components/kb/KBArticleList'
3
+ import { KBArticleEditor } from '../../../components/kb/KBArticleEditor'
4
+ import { PageInstructions } from '../../../components/admin/PageInstructions'
5
+
6
+ const KB_TYPE_SLUGS = ['kb-spine-admin', 'kb-spine-internal', 'kb-spine-public', 'kb-account']
7
+
8
+ interface KBAdminPageProps {
9
+ mode?: 'view' | 'edit' | 'new'
10
+ }
11
+
12
+ export function KBAdminPage({ mode = 'view' }: KBAdminPageProps) {
13
+ const { typeSlug, id } = useParams<{ typeSlug: string; id: string }>()
14
+ const navigate = useNavigate()
15
+
16
+ const isList = mode === 'view' && !id
17
+
18
+ if (isList) {
19
+ return (
20
+ <>
21
+ <PageInstructions
22
+ description="Manage knowledge base articles, categories, and their lifecycle."
23
+ sections={[
24
+ { title: 'What this page is for', content: 'This page lists the articles and categories for the selected knowledge base type and provides the editor for creating or updating content.' },
25
+ { title: 'How to read this page', content: 'In list mode you see existing records and can filter or select one. In edit or new mode the article editor shows the content fields and save controls for the selected type slug.' },
26
+ { title: 'How to create / edit / delete', content: 'Click New to create an article, select an existing record to view it, click Edit to change it, and use the editor\'s delete action to remove it.' },
27
+ { title: 'Important notes', content: 'Knowledge base records are typed by slug (kb-spine-admin, kb-spine-internal, kb-spine-public, kb-account). Make sure you are editing under the correct category.' },
28
+ ]}
29
+ />
30
+ <KBArticleList
31
+ typeSlugs={KB_TYPE_SLUGS}
32
+ typeName="Knowledge Base"
33
+ onSelect={(record) => navigate(`/spine-framework/admin/kb/${record.type_slug}/${record.id}`)}
34
+ onNew={() => navigate(`/spine-framework/admin/kb/${typeSlug}/new`)}
35
+ onEdit={(record) => navigate(`/spine-framework/admin/kb/${record.type_slug}/${record.id}/edit`)}
36
+ />
37
+ </>
38
+ )
39
+ }
40
+
41
+ return (
42
+ <>
43
+ <PageInstructions
44
+ description="Manage knowledge base articles, categories, and their lifecycle."
45
+ sections={[
46
+ { title: 'What this page is for', content: 'This page lists the articles and categories for the selected knowledge base type and provides the editor for creating or updating content.' },
47
+ { title: 'How to read this page', content: 'In list mode you see existing records and can filter or select one. In edit or new mode the article editor shows the content fields and save controls for the selected type slug.' },
48
+ { title: 'How to create / edit / delete', content: 'Click New to create an article, select an existing record to view it, click Edit to change it, and use the editor\'s delete action to remove it.' },
49
+ { title: 'Important notes', content: 'Knowledge base records are typed by slug (kb-spine-admin, kb-spine-internal, kb-spine-public, kb-account). Make sure you are editing under the correct category.' },
50
+ ]}
51
+ />
52
+ <KBArticleEditor
53
+ typeSlug={typeSlug}
54
+ mode={mode}
55
+ articleId={mode === 'new' ? null : id}
56
+ onBack={() => navigate(`/spine-framework/admin/kb/${typeSlug}`)}
57
+ onSave={(record) => navigate(`/spine-framework/admin/kb/${typeSlug}/${record?.id || id || ''}`)}
58
+ onEdit={(articleId) => navigate(`/spine-framework/admin/kb/${typeSlug}/${articleId}/edit`)}
59
+ onCancel={() => navigate(`/spine-framework/admin/kb/${typeSlug}`)}
60
+ onDelete={() => navigate(`/spine-framework/admin/kb/${typeSlug}`)}
61
+ />
62
+ </>
63
+ )
64
+ }
@@ -1,50 +1,58 @@
1
- /**
2
- * @module src/pages/auth/AuthConfirmPage
3
- * @audience installer
4
- * @layer frontend-page
5
- * @stability stable
6
- *
7
- * Universal auth callback page. Handles two token types delivered by Supabase
8
- * via email link, both arriving as query params on `/auth/confirm`:
9
- *
10
- * type=signup — email confirmation after registration
11
- * type=recovery — password-reset link from ForgotPasswordPage
12
- *
13
- * Flow:
14
- * 1. On mount, read `token_hash` and `type` from the URL search params.
15
- * 2. Call `supabase.auth.verifyOtp({ token_hash, type })` to exchange the
16
- * token for a live session. Supabase fires `SIGNED_IN` via
17
- * `onAuthStateChange`, which triggers `fetchUserContext` in AuthContext.
18
- * 3a. signup → navigate to "/" (AuthenticatedRouter takes over).
19
- * 3b. recovery → show a "set new password" form.
20
- * On submit call `supabase.auth.updateUser({ password })`, then navigate.
21
- *
22
- * Error cases:
23
- * - Token missing/malformed — show error + link back to login.
24
- * - Token expired (>1 h) — show error + link to /forgot-password to retry.
25
- * - Password too short — inline validation, never sent to Supabase.
26
- *
27
- * @seeAlso src/pages/auth/ForgotPasswordPage.tsx (generates recovery links)
28
- * @seeAlso src/pages/auth/RegisterPage.tsx (generates signup links)
29
- * @seeAlso src/contexts/AuthContext.tsx (onAuthStateChange handler)
30
- */
31
-
1
+ // CIL[BEGIN chunk_id="AuthConfirmPage_module_header_1783662155" type="module_header" identity="module_header" parent="none"]
2
+ // CIL[DOC-MACRO purpose="Import React hooks, routing, Supabase, and UI components for auth confirmation"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide necessary imports for token verification and password reset functionality"]
4
+ // CIL[DOC-CONTEXT module="src/pages/auth/AuthConfirmPage" layer="frontend-page" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="React hooks, routing, Supabase client, LoadingSpinner" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Standard imports for auth callback page with token handling" notable_decisions="[]"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
8
+ // CIL[DOC-STABILITY stability="stable"]
9
+ // CIL[DOC-AUDIENCE audience="developer"]
10
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/components/ui/dialog.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
11
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
12
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
13
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
14
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
15
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
32
16
  import React, { useState, useEffect } from 'react'
33
17
  import { Link, useNavigate, useSearchParams } from 'react-router-dom'
34
18
  import { supabase } from '../../lib/supabase'
35
19
  import { LoadingSpinner } from '../../components/ui/LoadingSpinner'
36
-
37
- // ─── TYPES ────────────────────────────────────────────────────────────────────
38
-
20
+ // CIL[END chunk_id="AuthConfirmPage_module_header_1783662155"]
21
+ // CIL[BEGIN chunk_id="AuthConfirmPage_stage_1783662155" type="type" identity="stage" parent="none"]
22
+ // CIL[DOC-MACRO purpose="Define authentication confirmation page states for token verification flow"]
23
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide type definition for all possible page states during auth confirmation"]
24
+ // CIL[DOC-CONTEXT module="src/pages/auth/AuthConfirmPage" layer="frontend-page" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
25
+ // CIL[DOC-CONTRACT inputs="none" outputs="Stage union type" errors="none" side_effects="none"]
26
+ // CIL[DOC-MICRO logic_summary="Type definition for auth confirmation flow states" notable_decisions="[]"]
27
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
28
+ // CIL[DOC-STABILITY stability="stable"]
29
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/src/pages/admin/RolesPage.tsx, \."]
30
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
31
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
32
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
33
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
34
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
39
35
  type Stage =
40
- | 'verifying' // exchanging token with Supabase
41
- | 'signup_success' // signup confirmed — brief success then redirect
42
- | 'set_password' // recovery: show new-password form
43
- | 'password_saved' // recovery: update succeeded — brief success then redirect
44
- | 'error' // unrecoverable error
45
-
46
- // ─── COMPONENT ────────────────────────────────────────────────────────────────
47
-
36
+ | 'verifying'
37
+ | 'signup_success'
38
+ | 'set_password'
39
+ | 'password_saved'
40
+ | 'error'
41
+ // CIL[END chunk_id="AuthConfirmPage_stage_1783662155"]
42
+ // CIL[BEGIN chunk_id="AuthConfirmPage_authconfirmpage_1783662155" type="function" identity="AuthConfirmPage" parent="none"]
43
+ // CIL[DOC-MACRO purpose="Handle email confirmation and password reset flows with token verification"]
44
+ // CIL[DOC-RESPONSIBILITY responsibility="Verify auth tokens, handle signup confirmation, and manage password reset flow"]
45
+ // CIL[DOC-CONTEXT module="src/pages/auth/AuthConfirmPage" layer="frontend-page" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
46
+ // CIL[DOC-CONTRACT inputs="none" outputs="authenticated session or password reset form" errors="token errors, validation errors" side_effects="updates auth state, creates user session"]
47
+ // CIL[DOC-MICRO logic_summary="Token verification with multiple flow handling and error states" notable_decisions="[]"]
48
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
49
+ // CIL[DOC-STABILITY stability="stable"]
50
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/RolesPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/components/ui/dialog.tsx, .framework/functions/_shared/principal.ts, \."]
51
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
52
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
53
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
54
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
55
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
48
56
  export function AuthConfirmPage() {
49
57
  const [searchParams] = useSearchParams()
50
58
  const navigate = useNavigate()
@@ -55,13 +63,11 @@ export function AuthConfirmPage() {
55
63
  const [stage, setStage] = useState<Stage>('verifying')
56
64
  const [errorMessage, setErrorMessage] = useState('')
57
65
 
58
- // New-password form state
59
66
  const [newPassword, setNewPassword] = useState('')
60
67
  const [confirmPassword, setConfirmPassword] = useState('')
61
68
  const [passwordError, setPasswordError] = useState('')
62
69
  const [isSaving, setIsSaving] = useState(false)
63
70
 
64
- // ── Token exchange on mount ──────────────────────────────────────────────
65
71
  useEffect(() => {
66
72
  if (!tokenHash || !type) {
67
73
  setErrorMessage('Invalid or missing confirmation link. Please request a new one.')
@@ -76,7 +82,6 @@ export function AuthConfirmPage() {
76
82
  })
77
83
 
78
84
  if (error) {
79
- // Common GoTrue error messages — surface human-friendly versions
80
85
  if (error.message.includes('expired') || error.message.includes('otp_expired')) {
81
86
  setErrorMessage('This link has expired. Links are valid for 1 hour.')
82
87
  } else if (error.message.includes('invalid')) {
@@ -91,14 +96,12 @@ export function AuthConfirmPage() {
91
96
  if (type === 'recovery') {
92
97
  setStage('set_password')
93
98
  } else {
94
- // signup, invite, magic_link — session is live, go to app
95
99
  setStage('signup_success')
96
100
  setTimeout(() => navigate('/', { replace: true }), 1500)
97
101
  }
98
102
  })()
99
- }, []) // eslint-disable-line react-hooks/exhaustive-deps
103
+ }, [])
100
104
 
101
- // ── Save new password ────────────────────────────────────────────────────
102
105
  const handleSetPassword = async (e: React.FormEvent) => {
103
106
  e.preventDefault()
104
107
  setPasswordError('')
@@ -126,8 +129,6 @@ export function AuthConfirmPage() {
126
129
  }
127
130
  }
128
131
 
129
- // ── Render ───────────────────────────────────────────────────────────────
130
-
131
132
  if (stage === 'verifying') {
132
133
  return (
133
134
  <div className="min-h-screen flex items-center justify-center bg-slate-50">
@@ -205,7 +206,6 @@ export function AuthConfirmPage() {
205
206
  )
206
207
  }
207
208
 
208
- // stage === 'set_password'
209
209
  return (
210
210
  <div className="min-h-screen flex items-center justify-center bg-slate-50 py-12 px-4 sm:px-6 lg:px-8">
211
211
  <div className="max-w-md w-full space-y-8">
@@ -286,3 +286,4 @@ export function AuthConfirmPage() {
286
286
  </div>
287
287
  )
288
288
  }
289
+ // CIL[END chunk_id="AuthConfirmPage_authconfirmpage_1783662155"]
@@ -1,29 +1,37 @@
1
- /**
2
- * @module src/pages/auth/ForgotPasswordPage
3
- * @audience installer
4
- * @layer frontend-page
5
- * @stability stable
6
- *
7
- * Password-reset request page. Collects the user's email address and calls
8
- * `supabase.auth.resetPasswordForEmail`, passing `emailRedirectTo` so the
9
- * link in the email returns the user to the correct origin (local dev,
10
- * Netlify preview, Cortex, Portal — whatever they're currently on).
11
- *
12
- * Supabase sends a recovery email whose link resolves to:
13
- * <origin>/auth/confirm?token_hash=...&type=recovery
14
- *
15
- * That page (AuthConfirmPage) then handles the token exchange and prompts
16
- * the user to set a new password.
17
- *
18
- * @seeAlso src/pages/auth/AuthConfirmPage.tsx (token exchange + new-password form)
19
- * @seeAlso src/pages/auth/LoginPage.tsx (links here via /forgot-password)
20
- */
21
-
1
+ // CIL[BEGIN chunk_id="ForgotPasswordPage_module_header_1783662155" type="module_header" identity="module_header" parent="none"]
2
+ // CIL[DOC-MACRO purpose="Import React hooks, routing, Supabase, and UI components for password reset"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide necessary imports for password reset functionality"]
4
+ // CIL[DOC-CONTEXT module="src/pages/auth/ForgotPasswordPage" layer="frontend-page" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="React hooks, routing, Supabase client, LoadingSpinner" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Standard imports for password reset page with email handling" notable_decisions="[]"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
8
+ // CIL[DOC-STABILITY stability="stable"]
9
+ // CIL[DOC-AUDIENCE audience="developer"]
10
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/components/ui/dialog.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, \."]
11
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
12
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
13
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
14
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
15
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
22
16
  import React, { useState } from 'react'
23
17
  import { Link } from 'react-router-dom'
24
18
  import { supabase } from '../../lib/supabase'
25
19
  import { LoadingSpinner } from '../../components/ui/LoadingSpinner'
26
-
20
+ // CIL[END chunk_id="ForgotPasswordPage_module_header_1783662155"]
21
+ // CIL[BEGIN chunk_id="ForgotPasswordPage_forgotpasswordpage_1783662155" type="function" identity="ForgotPasswordPage" parent="none"]
22
+ // CIL[DOC-MACRO purpose="Handle password reset request form with email submission and success states"]
23
+ // CIL[DOC-RESPONSIBILITY responsibility="Manage password reset flow, form submission, and user feedback states"]
24
+ // CIL[DOC-CONTEXT module="src/pages/auth/ForgotPasswordPage" layer="frontend-page" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\"\\\"]"]
25
+ // CIL[DOC-CONTRACT inputs="none" outputs="password reset email or error message" errors="validation errors, API errors" side_effects="sends password reset email via Supabase"]
26
+ // CIL[DOC-MICRO logic_summary="Form with email validation, async submission, and success confirmation" notable_decisions="[]"]
27
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
28
+ // CIL[DOC-STABILITY stability="stable"]
29
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/RolesPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/src/components/ui/dialog.tsx, \."]
30
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
31
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
32
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
33
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
34
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
27
35
  export function ForgotPasswordPage() {
28
36
  const [email, setEmail] = useState('')
29
37
  const [isLoading, setIsLoading] = useState(false)
@@ -144,3 +152,4 @@ export function ForgotPasswordPage() {
144
152
  </div>
145
153
  )
146
154
  }
155
+ // CIL[END chunk_id="ForgotPasswordPage_forgotpasswordpage_1783662155"]
@@ -1,23 +1,37 @@
1
- /**
2
- * @module src/pages/auth/LoginPage
3
- * @audience installer
4
- * @layer frontend-page
5
- * @stability stable
6
- *
7
- * Unauthenticated login page. Renders a centred card with email/password
8
- * inputs. On submit, calls `AuthContext.login(email, password)` and
9
- * navigates to `/dashboard` on success. Displays inline error text on
10
- * failure. Shows a `LoadingSpinner` inside the submit button while the
11
- * auth request is in-flight.
12
- *
13
- * @seeAlso src/contexts/AuthContext.tsx (login implementation)
14
- */
15
-
1
+ // CIL[BEGIN chunk_id="LoginPage_module_header_1783662155" type="module_header" identity="module_header" parent="none"]
2
+ // CIL[DOC-MACRO purpose="Import React hooks and components for login page functionality"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide necessary imports for React component, routing, auth context, and UI elements"]
4
+ // CIL[DOC-CONTEXT module="src/pages/auth/LoginPage" layer="frontend-page" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/CoursesPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="React, useState, Link, useAuth, LoadingSpinner" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Standard React component imports for authentication page" notable_decisions="[]"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
8
+ // CIL[DOC-STABILITY stability="stable"]
9
+ // CIL[DOC-AUDIENCE audience="developer"]
10
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/CoursesPage.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/src/pages/admin/RolesPage.tsx, \."]
11
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
12
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
13
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
14
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
15
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
16
16
  import React, { useState } from 'react'
17
- import { Link } from 'react-router-dom'
17
+ import { Link, useNavigate } from 'react-router-dom'
18
18
  import { useAuth } from '../../contexts/AuthContext'
19
19
  import { LoadingSpinner } from '../../components/ui/LoadingSpinner'
20
-
20
+ // CIL[END chunk_id="LoginPage_module_header_1783662155"]
21
+ // CIL[BEGIN chunk_id="LoginPage_loginpage_1783662155" type="function" identity="LoginPage" parent="none"]
22
+ // CIL[DOC-MACRO purpose="Render login form with email/password inputs and authentication handling"]
23
+ // CIL[DOC-RESPONSIBILITY responsibility="Manage login state, form submission, error display, and user authentication flow"]
24
+ // CIL[DOC-CONTEXT module="src/pages/auth/LoginPage" layer="frontend-page" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
25
+ // CIL[DOC-CONTRACT inputs="none" outputs="authenticated user session or error message" errors="login failure, network errors" side_effects="updates auth context state"]
26
+ // CIL[DOC-MICRO logic_summary="Form with controlled state, async login call, loading states, and error handling" notable_decisions="[]"]
27
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
28
+ // CIL[DOC-STABILITY stability="stable"]
29
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/src/pages/admin/RolesPage.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
30
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
31
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
32
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
33
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
34
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
21
35
  export function LoginPage() {
22
36
  const [email, setEmail] = useState('')
23
37
  const [password, setPassword] = useState('')
@@ -25,10 +39,7 @@ export function LoginPage() {
25
39
  const [isLoading, setIsLoading] = useState(false)
26
40
 
27
41
  const { login } = useAuth()
28
-
29
- // After login, App.tsx switches to AuthenticatedRouter which handles
30
- // all routing decisions based on the user's role and installed apps.
31
- // LoginPage has no redirect logic of its own.
42
+ const navigate = useNavigate()
32
43
 
33
44
  const handleSubmit = async (e: React.FormEvent) => {
34
45
  e.preventDefault()
@@ -36,8 +47,23 @@ export function LoginPage() {
36
47
  setIsLoading(true)
37
48
 
38
49
  try {
39
- await login(email, password)
40
- // App.tsx switches to AuthenticatedRouter on success — no redirect needed here
50
+ const user = await login(email, password)
51
+ const role = user?.roles?.[0]
52
+ if (!role) {
53
+ navigate('/')
54
+ return
55
+ }
56
+
57
+ const res = await fetch('/spine.config.json')
58
+ if (!res.ok) {
59
+ navigate('/')
60
+ return
61
+ }
62
+
63
+ const reg = (await res.json()).registration ?? {}
64
+ const app = reg.default_app_by_role?.[role] ?? reg.default_app
65
+ const path = reg.apps?.[app]?.path ?? '/'
66
+ navigate(path, { replace: true })
41
67
  } catch (err: any) {
42
68
  setError(err.message || 'Login failed')
43
69
  } finally {
@@ -147,3 +173,4 @@ export function LoginPage() {
147
173
  </div>
148
174
  )
149
175
  }
176
+ // CIL[END chunk_id="LoginPage_loginpage_1783662155"]
@@ -1,20 +1,35 @@
1
- /**
2
- * @module src/pages/auth/PendingApprovalPage
3
- * @audience installer
4
- * @layer frontend-page
5
- * @stability stable
6
- *
7
- * Shown to authenticated users whose people.status === 'pending'.
8
- * They have successfully signed up but their access request has not yet
9
- * been approved by an account administrator.
10
- *
11
- * @seeAlso src/App.tsx (pending gate)
12
- * @seeAlso functions/invites.ts (approve action)
13
- */
14
-
1
+ // CIL[BEGIN chunk_id="PendingApprovalPage_module_header_1783662155" type="module_header" identity="module_header" parent="none"]
2
+ // CIL[DOC-MACRO purpose="Import React and auth context for pending approval page functionality"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide necessary imports for pending approval display and logout functionality"]
4
+ // CIL[DOC-CONTEXT module="src/pages/auth/PendingApprovalPage" layer="frontend-page" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="React, useAuth" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Minimal imports for pending approval page with logout" notable_decisions="[]"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
8
+ // CIL[DOC-STABILITY stability="stable"]
9
+ // CIL[DOC-AUDIENCE audience="developer"]
10
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/RolesPage.tsx, \."]
11
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
12
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
13
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
14
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
15
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
15
16
  import React from 'react'
16
17
  import { useAuth } from '../../contexts/AuthContext'
17
-
18
+ // CIL[END chunk_id="PendingApprovalPage_module_header_1783662155"]
19
+ // CIL[BEGIN chunk_id="PendingApprovalPage_pendingapprovalpage_1783662155" type="function" identity="PendingApprovalPage" parent="none"]
20
+ // CIL[DOC-MACRO purpose="Display pending approval page for users awaiting account administrator approval"]
21
+ // CIL[DOC-RESPONSIBILITY responsibility="Show waiting state message and provide logout option for pending users"]
22
+ // CIL[DOC-CONTEXT module="src/pages/auth/PendingApprovalPage" layer="frontend-page" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"\\\"]"]
23
+ // CIL[DOC-CONTRACT inputs="none" outputs="pending approval UI with logout option" errors="none" side_effects="logs out user on logout button click"]
24
+ // CIL[DOC-MICRO logic_summary="Simple waiting page with static content and logout functionality" notable_decisions="[]"]
25
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
26
+ // CIL[DOC-STABILITY stability="stable"]
27
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, \."]
28
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
29
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
30
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
31
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
32
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
18
33
  export function PendingApprovalPage() {
19
34
  const { logout } = useAuth()
20
35
 
@@ -52,3 +67,4 @@ export function PendingApprovalPage() {
52
67
  </div>
53
68
  )
54
69
  }
70
+ // CIL[END chunk_id="PendingApprovalPage_pendingapprovalpage_1783662155"]