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.
- package/.env.example +76 -0
- package/.framework/.spine-manifest.json +19 -0
- package/.framework/cli/commands/agents.ts +61 -33
- package/.framework/cli/commands/auth.ts +60 -28
- package/.framework/cli/commands/create-app.ts +212 -80
- package/.framework/cli/commands/dev.ts +184 -68
- package/.framework/cli/commands/doctor.ts +324 -152
- package/.framework/cli/commands/generate.ts +119 -68
- package/.framework/cli/commands/init.ts +141 -242
- package/.framework/cli/commands/install-app.ts +1336 -314
- package/.framework/cli/commands/items.ts +31 -29
- package/.framework/cli/commands/migrate.ts +299 -156
- package/.framework/cli/commands/migrations.ts +62 -30
- package/.framework/cli/commands/pipelines.ts +31 -29
- package/.framework/cli/commands/status.ts +105 -45
- package/.framework/cli/commands/system.ts +47 -42
- package/.framework/cli/commands/test.ts +161 -102
- package/.framework/cli/commands/upgrade.ts +260 -0
- package/.framework/cli/commands/validate-app.ts +517 -161
- package/.framework/cli/context.ts +117 -85
- package/.framework/cli/env-loader.ts +74 -43
- package/.framework/cli/index.ts +70 -46
- package/.framework/cli/lib/project-files.ts +404 -0
- package/.framework/docs/guides/testing-guide.md +1 -1
- package/.framework/docs/runtime-types.md +72 -72
- package/.framework/functions/_shared/access.ts +84 -0
- package/.framework/functions/_shared/agent-runner.ts +5051 -1026
- package/.framework/functions/_shared/app-manifest.ts +214 -94
- package/.framework/functions/_shared/ast.ts +214 -0
- package/.framework/functions/_shared/audit.ts +91 -55
- package/.framework/functions/_shared/cil.ts +368 -127
- package/.framework/functions/_shared/db.ts +337 -68
- package/.framework/functions/_shared/funnel.ts +228 -0
- package/.framework/functions/_shared/geo.ts +105 -0
- package/.framework/functions/_shared/hash-api-key.ts +94 -17
- package/.framework/functions/_shared/index.ts +22 -224
- package/.framework/functions/_shared/kb.ts +832 -58
- package/.framework/functions/_shared/llm.ts +118 -18
- package/.framework/functions/_shared/logging.ts +317 -19
- package/.framework/functions/_shared/middleware.ts +701 -131
- package/.framework/functions/_shared/notify.ts +70 -0
- package/.framework/functions/_shared/outcomes.ts +34 -19
- package/.framework/functions/_shared/permissions.ts +501 -315
- package/.framework/functions/_shared/pipeline-runner.ts +704 -155
- package/.framework/functions/_shared/principal.ts +436 -263
- package/.framework/functions/_shared/rate-limit.ts +233 -0
- package/.framework/functions/_shared/resolve-credentials.ts +86 -19
- package/.framework/functions/_shared/resolve-ids.ts +203 -139
- package/.framework/functions/_shared/retry-deliveries.ts +51 -16
- package/.framework/functions/_shared/schema-utils.ts +602 -521
- package/.framework/functions/_shared/security.ts +345 -0
- package/.framework/functions/_shared/testing.ts +197 -172
- package/.framework/functions/_shared/tracing.ts +351 -21
- package/.framework/functions/_shared/trigger-engine.ts +425 -136
- package/.framework/functions/_shared/webhook-registration.ts +71 -70
- package/.framework/functions/_shared/webhook-registry.ts +126 -83
- package/.framework/functions/account-nodes.ts +30 -30
- package/.framework/functions/adapters/generic-webhook-inbound.ts +49 -16
- package/.framework/functions/adapters/generic-webhook-outbound.ts +17 -17
- package/.framework/functions/adapters/openai-outbound.ts +15 -16
- package/.framework/functions/admin-data.ts +596 -173
- package/.framework/functions/admin-funnel.ts +64 -60
- package/.framework/functions/admin-install-funnel.ts +84 -66
- package/.framework/functions/admin-signals.ts +69 -51
- package/.framework/functions/ai-agents.ts +431 -106
- package/.framework/functions/ai-interactions.ts +186 -112
- package/.framework/functions/api-keys.ts +107 -107
- package/.framework/functions/apps.ts +154 -136
- package/.framework/functions/auth.ts +83 -65
- package/.framework/functions/cil-agent-ingest.ts +189 -232
- package/.framework/functions/cil-agent.ts +433 -177
- package/.framework/functions/cil-callmap.ts +642 -430
- package/.framework/functions/cil-config.ts +139 -135
- package/.framework/functions/cil-context.ts +214 -127
- package/.framework/functions/cil-doc.ts +587 -458
- package/.framework/functions/cil-embeddings.ts +453 -364
- package/.framework/functions/cil-graph.ts +427 -142
- package/.framework/functions/cil-ingest.ts +1418 -1154
- package/.framework/functions/cil-pipeline.ts +276 -21
- package/.framework/functions/cil-project.ts +659 -132
- package/.framework/functions/cil-validate.ts +198 -164
- package/.framework/functions/debug-auth.ts +57 -55
- package/.framework/functions/deliveries.ts +80 -21
- package/.framework/functions/embeddings.ts +1023 -318
- package/.framework/functions/eval-harness.ts +146 -108
- package/.framework/functions/integration-outbound.ts +205 -75
- package/.framework/functions/integration-routes.ts +128 -23
- package/.framework/functions/integrations.ts +125 -100
- package/.framework/functions/invites.ts +1095 -460
- package/.framework/functions/item-progress.ts +158 -102
- package/.framework/functions/kb.ts +34 -10
- package/.framework/functions/logs.ts +133 -133
- package/.framework/functions/observability.ts +152 -122
- package/.framework/functions/pipeline-executions.ts +147 -132
- package/.framework/functions/pipelines.ts +134 -119
- package/.framework/functions/prompt-configs.ts +96 -80
- package/.framework/functions/roles.ts +112 -82
- package/.framework/functions/security.ts +450 -0
- package/.framework/functions/system-cron.ts +117 -80
- package/.framework/functions/system.ts +158 -98
- package/.framework/functions/tests.ts +29 -29
- package/.framework/functions/timers.ts +94 -95
- package/.framework/functions/trigger-scheduler.ts +10 -0
- package/.framework/functions/triggers.ts +179 -149
- package/.framework/functions/types.ts +137 -125
- package/.framework/mcp/index.ts +133 -0
- package/.framework/mcp/load-env.ts +60 -0
- package/.framework/mcp/shared/app-manifest.ts +275 -0
- package/.framework/mcp/shared/db.ts +477 -0
- package/.framework/mcp/shared/kb.ts +118 -0
- package/.framework/mcp/tools/architect.ts +431 -0
- package/.framework/mcp/tools/cil/context.ts +345 -0
- package/.framework/mcp/tools/cil/graph.ts +242 -0
- package/.framework/mcp/tools/cil/ingest.ts +1217 -0
- package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +693 -0
- package/.framework/mcp/tools/cil/pipeline.ts +767 -0
- package/.framework/mcp/tools/cil/project.ts +791 -0
- package/.framework/mcp/tools/cil/retrieval.ts +336 -0
- package/.framework/mcp/tools/cil/search-core.ts +454 -0
- package/.framework/mcp/tools/cil/search.ts +97 -0
- package/.framework/mcp/tools/cil/suggest.ts +186 -0
- package/.framework/mcp/tools/cil/validate.ts +1369 -0
- package/.framework/mcp/tools/kb/delete.ts +139 -0
- package/.framework/mcp/tools/kb/index.ts +52 -0
- package/.framework/mcp/tools/kb/ingest.ts +84 -0
- package/.framework/mcp/tools/kb/list-types.ts +102 -0
- package/.framework/mcp/tools/kb/publish.ts +100 -0
- package/.framework/mcp/tools/kb/reindex.ts +86 -0
- package/.framework/mcp/tools/kb/revoke.ts +85 -0
- package/.framework/mcp/tools/kb/search.ts +101 -0
- package/.framework/mcp/tools/kb/upsert.ts +125 -0
- package/.framework/mcp/tools/observability.ts +510 -0
- package/.framework/migrations/001_core_schema.sql +15 -0
- package/.framework/migrations/002_core_rls_and_functions.sql +15 -0
- package/.framework/migrations/003_core_system_data.sql +16 -1
- package/.framework/migrations/004_core_rpc_and_broker.sql +17 -1
- package/.framework/migrations/005_core_observability.sql +17 -1
- package/.framework/migrations/006_security_hardening_rls.sql +15 -0
- package/.framework/migrations/007_kb_article_list.sql +17 -1
- package/.framework/migrations/008_items_target.sql +15 -0
- package/.framework/migrations/009_roles_slug_unique.sql +15 -0
- package/.framework/migrations/010_auth_user_trigger.sql +15 -0
- package/.framework/migrations/011_spine_system_account.sql +16 -0
- package/.framework/migrations/012_service_role_grants.sql +16 -0
- package/.framework/migrations/013_get_account_apps_role_filter.sql +15 -0
- package/.framework/migrations/014_apps_required_roles.sql +16 -0
- package/.framework/migrations/015_types_kind_slug_unique.sql +15 -0
- package/.framework/migrations/016_cil_types.sql +281 -0
- package/.framework/migrations/017_cil_stable_ids.sql +37 -0
- package/.framework/migrations/018_runtime_tables.sql +129 -0
- package/.framework/migrations/019_agent_prompt_columns.sql +56 -0
- package/.framework/migrations/020_schema_reconciliation.sql +67 -0
- package/.framework/migrations/021_kb_embedding_lifecycle.sql +31 -0
- package/.framework/migrations/032_cil_status_migration.sql +73 -0
- package/.framework/migrations/033_cil_versioning.sql +73 -0
- package/.framework/migrations/034_match_embeddings_knn.sql +115 -0
- package/.framework/migrations/035_rate_limits.sql +55 -0
- package/.framework/migrations/036_demo_record_flags.sql +72 -0
- package/.framework/migrations/037_kb_types_canonical.sql +244 -0
- package/.framework/migrations/038_drop_demo_record_flags.sql +38 -0
- package/.framework/migrations/042_registration_hierarchy.sql +309 -0
- package/.framework/migrations/043_policy_actor_cleanup.sql +39 -0
- package/.framework/migrations/044_match_embeddings_filtered_knn.sql +151 -0
- package/.framework/migrations/045_security_critical_rls.sql +139 -0
- package/.framework/migrations/046_security_missing_rls.sql +79 -0
- package/.framework/migrations/047_people_updated_by.sql +27 -0
- package/.framework/migrations/048_watcher_last_seen_at.sql +24 -0
- package/.framework/migrations/049_security_blocklist.sql +148 -0
- package/.framework/migrations/050_notifications.sql +49 -0
- package/.framework/migrations/051_message_agent_fields.sql +74 -0
- package/.framework/migrations/052_registration_security.sql +421 -0
- package/.framework/migrations/053_builtin_action_seeds.sql +66 -0
- package/.framework/migrations/054_kb_ingest_lease.sql +157 -0
- package/.framework/migrations/055_type_id_drift_reconciliation.sql +33 -0
- package/.framework/migrations/056_slug_column_reconciliation.sql +38 -0
- package/.framework/migrations/057_pipelines_slug_identity.sql +14 -0
- package/.framework/migrations/058_account_data_field_declarations.sql +53 -0
- package/.framework/migrations/059_registration_placement_fixes.sql +269 -0
- package/.framework/migrations/060_account_person_record_permissions.sql +38 -0
- package/.framework/migrations/061_fk_dedup.sql +32 -0
- package/.framework/public/spine-logo.svg +10 -3
- package/.framework/scripts/app-install-cli.ts +190 -93
- package/.framework/scripts/assemble-frontend.sh +127 -44
- package/.framework/scripts/assemble-functions.sh +128 -30
- package/.framework/scripts/boundary-check.sh +6 -2
- package/.framework/scripts/build-manifest.sh +24 -68
- package/.framework/scripts/check-core-integrity.sh +15 -76
- package/.framework/scripts/checksum-manifest.mts +343 -0
- package/.framework/scripts/cil-migrate-markers.ts +403 -0
- package/.framework/scripts/fix-cil-markers.mjs +176 -0
- package/.framework/scripts/verify-integrity.sh +21 -57
- package/.framework/scripts/verify-manifest.mts +305 -0
- package/.framework/seeds/types/funnel_signal_use.json +74 -21
- package/.framework/seeds/types/spine_instance.json +73 -21
- package/.framework/src/App.tsx +118 -72
- package/.framework/src/apps/admin/index.tsx +855 -58
- package/.framework/src/components/AppWrapper.tsx +43 -45
- package/.framework/src/components/CustomAppLoader.tsx +160 -116
- package/.framework/src/components/admin/AdminListPage.tsx +46 -44
- package/.framework/src/components/admin/AdminSidebar.tsx +57 -47
- package/.framework/src/components/admin/AdminStatsCard.tsx +46 -44
- package/.framework/src/components/admin/PageInstructions.tsx +98 -2
- package/.framework/src/components/admin/SortableTableHeader.tsx +44 -45
- package/.framework/src/components/app-shell/GenericAppShell.tsx +64 -65
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +44 -47
- package/.framework/src/components/app-shell/GenericListPage.tsx +45 -49
- package/.framework/src/components/app-sidebar.tsx +42 -45
- package/.framework/src/components/auth/ProtectedRoute.tsx +48 -41
- package/.framework/src/components/auth/TurnstileWidget.tsx +27 -0
- package/.framework/src/components/kb/KBArticleEditor.tsx +231 -22
- package/.framework/src/components/kb/KBArticleList.tsx +251 -10
- package/.framework/src/components/layout/AppShell.tsx +51 -45
- package/.framework/src/components/layout/Header.tsx +42 -43
- package/.framework/src/components/layout/Layout.tsx +46 -46
- package/.framework/src/components/layout/Sidebar.tsx +196 -96
- package/.framework/src/components/runtime/DataDetailHeader.tsx +55 -30
- package/.framework/src/components/runtime/DataDetailPage.tsx +31 -269
- package/.framework/src/components/runtime/DataFilters.tsx +49 -74
- package/.framework/src/components/runtime/DataHeader.tsx +53 -32
- package/.framework/src/components/runtime/DataListPage.tsx +51 -155
- package/.framework/src/components/runtime/DataStats.tsx +66 -44
- package/.framework/src/components/runtime/DataTable.tsx +49 -149
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +45 -75
- package/.framework/src/components/runtime/index.ts +119 -16
- package/.framework/src/components/search-form.tsx +46 -29
- package/.framework/src/components/shared/AgentView.tsx +65 -48
- package/.framework/src/components/shared/FieldRenderer.tsx +144 -50
- package/.framework/src/components/shared/InviteManager.tsx +207 -97
- package/.framework/src/components/shared/MemberList.tsx +97 -0
- package/.framework/src/components/shared/SchemaFields.tsx +107 -86
- package/.framework/src/components/ui/DataTable.tsx +80 -68
- package/.framework/src/components/ui/Form.tsx +157 -146
- package/.framework/src/components/ui/ItemCard.tsx +74 -67
- package/.framework/src/components/ui/ItemListView.tsx +73 -68
- package/.framework/src/components/ui/LoadingSpinner.tsx +43 -48
- package/.framework/src/components/ui/Modal.tsx +78 -68
- package/.framework/src/components/ui/RichTextEditor.tsx +89 -69
- package/.framework/src/components/ui/accordion.tsx +85 -86
- package/.framework/src/components/ui/alert-dialog.tsx +197 -184
- package/.framework/src/components/ui/alert.tsx +105 -94
- package/.framework/src/components/ui/aspect-ratio.tsx +57 -43
- package/.framework/src/components/ui/avatar.tsx +122 -107
- package/.framework/src/components/ui/badge.tsx +60 -55
- package/.framework/src/components/ui/breadcrumb.tsx +127 -128
- package/.framework/src/components/ui/button-group.tsx +86 -72
- package/.framework/src/components/ui/button.tsx +71 -50
- package/.framework/src/components/ui/calendar.tsx +72 -57
- package/.framework/src/components/ui/card.tsx +136 -129
- package/.framework/src/components/ui/carousel.tsx +226 -107
- package/.framework/src/components/ui/chart.tsx +252 -147
- package/.framework/src/components/ui/checkbox.tsx +43 -44
- package/.framework/src/components/ui/collapsible.tsx +86 -71
- package/.framework/src/components/ui/combobox.tsx +282 -249
- package/.framework/src/components/ui/command.tsx +158 -146
- package/.framework/src/components/ui/context-menu.tsx +239 -240
- package/.framework/src/components/ui/dialog.tsx +174 -157
- package/.framework/src/components/ui/direction.tsx +72 -56
- package/.framework/src/components/ui/drawer.tsx +168 -169
- package/.framework/src/components/ui/dropdown-menu.tsx +254 -223
- package/.framework/src/components/ui/empty.tsx +131 -120
- package/.framework/src/components/ui/field.tsx +205 -173
- package/.framework/src/components/ui/hover-card.tsx +71 -72
- package/.framework/src/components/ui/input-group.tsx +148 -133
- package/.framework/src/components/ui/input-otp.tsx +99 -86
- package/.framework/src/components/ui/input.tsx +43 -41
- package/.framework/src/components/ui/item.tsx +207 -185
- package/.framework/src/components/ui/kbd.tsx +57 -56
- package/.framework/src/components/ui/label.tsx +45 -41
- package/.framework/src/components/ui/menubar.tsx +268 -236
- package/.framework/src/components/ui/native-select.tsx +85 -86
- package/.framework/src/components/ui/navigation-menu.tsx +166 -156
- package/.framework/src/components/ui/pagination.tsx +131 -141
- package/.framework/src/components/ui/popover.tsx +125 -128
- package/.framework/src/components/ui/progress.tsx +47 -44
- package/.framework/src/components/ui/radio-group.tsx +60 -55
- package/.framework/src/components/ui/resizable.tsx +85 -72
- package/.framework/src/components/ui/scroll-area.tsx +57 -58
- package/.framework/src/components/ui/select.tsx +182 -169
- package/.framework/src/components/ui/separator.tsx +42 -43
- package/.framework/src/components/ui/sheet.tsx +170 -159
- package/.framework/src/components/ui/sidebar.tsx +395 -398
- package/.framework/src/components/ui/skeleton.tsx +42 -43
- package/.framework/src/components/ui/slider.tsx +61 -44
- package/.framework/src/components/ui/sonner.tsx +44 -44
- package/.framework/src/components/ui/spinner.tsx +47 -42
- package/.framework/src/components/ui/switch.tsx +56 -42
- package/.framework/src/components/ui/table-primitives.tsx +272 -132
- package/.framework/src/components/ui/table.tsx +140 -142
- package/.framework/src/components/ui/tabs.tsx +110 -93
- package/.framework/src/components/ui/textarea.tsx +43 -44
- package/.framework/src/components/ui/toggle-group.tsx +87 -71
- package/.framework/src/components/ui/toggle.tsx +56 -56
- package/.framework/src/components/ui/tooltip.tsx +99 -85
- package/.framework/src/contexts/AppContext.tsx +166 -114
- package/.framework/src/contexts/AuthContext.tsx +232 -137
- package/.framework/src/hooks/use-mobile.ts +43 -44
- package/.framework/src/hooks/useApi.ts +185 -172
- package/.framework/src/hooks/useAppPath.ts +31 -29
- package/.framework/src/hooks/useApps.ts +77 -42
- package/.framework/src/hooks/useEntityList.ts +66 -29
- package/.framework/src/hooks/useEntityRecord.ts +76 -32
- package/.framework/src/hooks/useForm.ts +62 -30
- package/.framework/src/hooks/useListSchema.ts +60 -43
- package/.framework/src/hooks/useSchemaRecord.ts +115 -95
- package/.framework/src/lib/api.ts +258 -134
- package/.framework/src/lib/registration.ts +181 -0
- package/.framework/src/lib/supabase.ts +118 -81
- package/.framework/src/lib/utils.ts +266 -266
- package/.framework/src/main.tsx +43 -44
- package/.framework/src/pages/DashboardPage.tsx +44 -43
- package/.framework/src/pages/NoAppPage.tsx +50 -0
- package/.framework/src/pages/NotFoundPage.tsx +32 -29
- package/.framework/src/pages/SetupPage.tsx +34 -33
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +69 -58
- package/.framework/src/pages/admin/AIAgentsPage.tsx +43 -40
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +63 -55
- package/.framework/src/pages/admin/APIKeysPage.tsx +44 -42
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +117 -94
- package/.framework/src/pages/admin/AppDetailPage.tsx +48 -42
- package/.framework/src/pages/admin/AppsPage.tsx +45 -42
- package/.framework/src/pages/admin/DeliveriesPage.tsx +49 -17
- package/.framework/src/pages/admin/DesignedPage.tsx +31 -30
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +58 -0
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +49 -0
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +31 -29
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +46 -29
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -29
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +68 -55
- package/.framework/src/pages/admin/IntegrationsPage.tsx +45 -42
- package/.framework/src/pages/admin/InvitesPage.tsx +60 -44
- package/.framework/src/pages/admin/LogsPage.tsx +87 -137
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +31 -29
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +150 -89
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +77 -104
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +44 -43
- package/.framework/src/pages/admin/PipelinesPage.tsx +59 -145
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +53 -42
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +47 -117
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +31 -44
- package/.framework/src/pages/admin/RoleDetailPage.tsx +49 -92
- package/.framework/src/pages/admin/RolesPage.tsx +47 -164
- package/.framework/src/pages/admin/SecurityPage.tsx +310 -0
- package/.framework/src/pages/admin/SelectTestPage.tsx +30 -32
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +37 -44
- package/.framework/src/pages/admin/SimpleDashboard.tsx +32 -44
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +97 -44
- package/.framework/src/pages/admin/TestingDashboard.tsx +126 -71
- package/.framework/src/pages/admin/TimerDetailPage.tsx +67 -55
- package/.framework/src/pages/admin/TimersPage.tsx +44 -42
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +47 -42
- package/.framework/src/pages/admin/TriggersPage.tsx +58 -57
- package/.framework/src/pages/admin/TypeDetailPage.tsx +91 -55
- package/.framework/src/pages/admin/TypesPage.tsx +45 -42
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +258 -128
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +127 -123
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +308 -235
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +159 -110
- package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +432 -0
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +200 -178
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +286 -239
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +211 -90
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +156 -143
- package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +379 -0
- package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +337 -0
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +219 -214
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +135 -65
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +39 -31
- package/.framework/src/pages/auth/LoginPage.tsx +38 -32
- package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -28
- package/.framework/src/pages/auth/RegisterPage.tsx +429 -155
- package/.framework/src/pages/spine-framework/APIPage.tsx +33 -30
- package/.framework/src/pages/spine-framework/CLIPage.tsx +32 -30
- package/.framework/src/types/auth.ts +101 -93
- package/.framework/src/types/types.ts +283 -262
- package/.framework/templates/project.json +87 -0
- package/.framework/templates/spine.config.neutral.json +7 -0
- package/.framework/tests/api/api-surface.test.ts +381 -0
- package/.framework/tests/fixtures/seed.ts +427 -0
- package/.framework/tests/fixtures/teardown.ts +228 -0
- package/.framework/tests/reporter.ts +351 -0
- package/.framework/tests/setup.ts +135 -0
- package/.framework/tests/ui/ui-sweep.ts +278 -0
- package/.framework/tests/unit/admin-data-logger.test.ts +310 -0
- package/.framework/tests/unit/agent-runner.test.ts +2389 -0
- package/.framework/tests/unit/ai-interactions.test.ts +81 -0
- package/.framework/tests/unit/app-manifest.test.ts +359 -0
- package/.framework/tests/unit/assembly-scripts.test.ts +172 -0
- package/.framework/tests/unit/cil-determinism.test.ts +85 -0
- package/.framework/tests/unit/core-isolation.test.ts +153 -0
- package/.framework/tests/unit/funnel-signals.test.ts +135 -0
- package/.framework/tests/unit/install-app.test.ts +1759 -0
- package/.framework/tests/unit/invites-security.test.ts +572 -0
- package/.framework/tests/unit/kb-ingest-lease.test.ts +287 -0
- package/.framework/tests/unit/kb-search.test.ts +119 -0
- package/.framework/tests/unit/migrate.test.ts +509 -0
- package/.framework/tests/unit/notify.test.ts +136 -0
- package/.framework/tests/unit/permissions.test.ts +269 -0
- package/.framework/tests/unit/pipeline-runner.test.ts +755 -0
- package/.framework/tests/unit/principal-cache.test.ts +138 -0
- package/.framework/tests/unit/retrieval-golden.test.ts +520 -0
- package/.framework/tests/unit/runtime-isolation.test.ts +642 -0
- package/.framework/tests/unit/schema-utils.test.ts +225 -0
- package/.framework/tests/unit/trigger-engine.test.ts +513 -0
- package/.framework/tests/unit/validate-app.test.ts +527 -0
- package/README.md +34 -3
- package/bin/spine-framework.cjs +1 -0
- package/config/tailwind.config.cjs +7 -0
- package/config/tsconfig.functions.json +42 -0
- package/config/tsconfig.json +37 -9
- package/config/vite.config.ts +31 -2
- package/netlify.toml +31 -3
- package/package.json +46 -29
- package/scripts/assemble-frontend.sh +127 -44
- package/scripts/assemble-functions.sh +127 -29
- package/scripts/boundary-check.sh +6 -2
- package/scripts/build-manifest.sh +24 -68
- package/scripts/checksum-manifest.mts +345 -0
- package/scripts/dev-clean.sh +86 -0
- package/scripts/dev-netlify.sh +49 -0
- package/scripts/netlify-dev-wrapper.sh +2 -0
- package/scripts/verify-install.ts +358 -0
- package/scripts/verify-integrity.sh +21 -57
- package/scripts/verify-manifest.mts +305 -0
- package/templates/project/gitignore +45 -0
- package/{config → templates/project}/package-lock.json +22335 -9366
- package/vitest.config.ts +46 -0
- package/.framework/public/spine.config.json +0 -91
- package/config/deno.lock +0 -108
- package/config/tsconfig.node.tsbuildinfo +0 -1
- package/config/tsconfig.tsbuildinfo +0 -1
- package/config/vite.config.d.ts +0 -2
- package/custom/.devin/AGENT.md +0 -357
- package/custom/.devin/skills/install-app/SKILL.md +0 -39
- package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +0 -39
- package/custom/.devin/skills/spine-workbench-idea/SKILL.md +0 -36
- package/custom/.devin/skills/spine-workbench-implement/SKILL.md +0 -46
- package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +0 -28
- package/custom/.devin/skills/spine-workbench-plan/SKILL.md +0 -38
- package/custom/.devin/workflows/app-install.yaml +0 -83
- package/custom/README.md +0 -79
- package/docs/README.md +0 -15
- package/scripts/app-install-cli.ts +0 -286
- package/scripts/check-core-integrity.sh +0 -82
- package/scripts/ingest-chunks.cjs +0 -202
- package/scripts/kb-chunk-parser.cjs +0 -312
- package/scripts/kb-chunk-parser.ts +0 -330
- package/scripts/kb-ingest-docs.ts +0 -203
- package/scripts/load-test-app-install.ts +0 -484
- package/scripts/test-login.js +0 -33
- package/spine.config.json +0 -91
|
@@ -1,14 +1,71 @@
|
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/kb/KBAdminPage.tsx:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/src/pages/admin/kb/KBAdminPage.tsx"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Renders the admin knowledge base page with article list and editor."]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide the top-level React component for managing KB articles and categories."]
|
|
4
|
+
// CIL[DOC-CONTEXT module="admin/kb" layer="page" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/kb/KBArticleEditor.tsx,.framework/src/components/kb/KBArticleList.tsx"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="URL parameters (typeSlug, id) and mode prop" outputs="JSX for list or editor view" errors="None" side_effects="Programmatic navigation via react-router"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Imports subcomponents and conditionally renders the list or editor based on mode and id." notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
8
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="admin-ui"]
|
|
10
|
+
|
|
1
11
|
import { useParams, useNavigate } from 'react-router-dom'
|
|
2
12
|
import { KBArticleList } from '../../../components/kb/KBArticleList'
|
|
3
13
|
import { KBArticleEditor } from '../../../components/kb/KBArticleEditor'
|
|
4
14
|
import { PageInstructions } from '../../../components/admin/PageInstructions'
|
|
15
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Renders the admin knowledge base page with article list and editor.'; No verified external callers; imports: .framework/src/components/kb/KBArticleList.tsx,.framework/src/components/kb/KBArticleEditor.tsx,.framework/src/components/admin/PageInstructions.tsx"]
|
|
16
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
17
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
18
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
19
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
20
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
21
|
+
// CIL[END stable_id="~/.framework/src/pages/admin/kb/KBAdminPage.tsx:module_header:module_header"]
|
|
22
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/kb/KBAdminPage.tsx:kb_type_slugs:constant" type="constant" identity="KB_TYPE_SLUGS" parent="~/.framework/src/pages/admin/kb/KBAdminPage.tsx"]
|
|
23
|
+
// CIL[DOC-MACRO purpose="Defines the allowed knowledge base type slugs."]
|
|
24
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Enumerate valid KB categories used by the admin page and article list."]
|
|
25
|
+
// CIL[DOC-CONTEXT module="admin/kb" layer="data" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/kb/KBArticleEditor.tsx,.framework/src/components/kb/KBArticleList.tsx,.framework/src/pages/admin/kb/KBAdminPage.tsx"]
|
|
26
|
+
// CIL[DOC-CONTRACT inputs="None" outputs="Array of type slug strings" errors="None" side_effects="None"]
|
|
27
|
+
// CIL[DOC-MICRO logic_summary="Static string array enumerating valid knowledge base categories." notable_decisions="[]"]
|
|
28
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
29
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
5
30
|
|
|
6
31
|
const KB_TYPE_SLUGS = ['kb-spine-admin', 'kb-spine-internal', 'kb-spine-public', 'kb-account']
|
|
32
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Defines the allowed knowledge base type slugs.'; No verified external callers; imports: .framework/src/components/kb/KBArticleList.tsx,.framework/src/components/kb/KBArticleEditor.tsx,.framework/src/components/admin/PageInstructions.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/pages/admin/kb/KBAdminPage.tsx:kb_type_slugs:constant"]
|
|
39
|
+
|
|
7
40
|
|
|
41
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/kb/KBAdminPage.tsx:KBAdminPageProps:interface" type="interface" identity="KBAdminPageProps" parent="~/.framework/src/pages/admin/kb/KBAdminPage.tsx"]
|
|
42
|
+
// CIL[DOC-MACRO purpose="Defines the props accepted by the KBAdminPage component."]
|
|
43
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declare the optional mode prop for view/edit/new state."]
|
|
44
|
+
// CIL[DOC-CONTEXT module="admin/kb" layer="interface" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/kb/KBArticleEditor.tsx,.framework/src/components/kb/KBArticleList.tsx,.framework/src/pages/admin/kb/KBAdminPage.tsx"]
|
|
45
|
+
// CIL[DOC-CONTRACT inputs="None" outputs="Type definition for KBAdminPageProps" errors="None" side_effects="None"]
|
|
46
|
+
// CIL[DOC-MICRO logic_summary="Optional mode union type supporting view, edit, and new modes." notable_decisions="[]"]
|
|
47
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
48
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
8
49
|
interface KBAdminPageProps {
|
|
9
50
|
mode?: 'view' | 'edit' | 'new'
|
|
10
51
|
}
|
|
52
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Defines the props accepted by the KBAdminPage component.'; No verified external callers; imports: .framework/src/components/kb/KBArticleList.tsx,.framework/src/components/kb/KBArticleEditor.tsx,.framework/src/components/admin/PageInstructions.tsx"]
|
|
53
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
54
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
55
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
56
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
57
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
58
|
+
// CIL[END stable_id="~/.framework/src/pages/admin/kb/KBAdminPage.tsx:KBAdminPageProps:interface"]
|
|
59
|
+
|
|
11
60
|
|
|
61
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/kb/KBAdminPage.tsx:kbadminpage:function" type="function" identity="KBAdminPage" parent="~/.framework/src/pages/admin/kb/KBAdminPage.tsx"]
|
|
62
|
+
// CIL[DOC-MACRO purpose="Displays the knowledge base article list or editor based on route mode and id."]
|
|
63
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Render the admin KB page and route user actions to the appropriate editor/list views."]
|
|
64
|
+
// CIL[DOC-CONTEXT module="admin/kb" layer="page" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/kb/KBArticleEditor.tsx,.framework/src/components/kb/KBArticleList.tsx,.framework/src/pages/admin/kb/KBAdminPage.tsx"]
|
|
65
|
+
// CIL[DOC-CONTRACT inputs="mode prop and URL params typeSlug/id" outputs="JSX with KBArticleList or KBArticleEditor" errors="None" side_effects="Navigates using useNavigate"]
|
|
66
|
+
// CIL[DOC-MICRO logic_summary="Determines list mode from the mode prop and absence of id, then renders list or editor with navigation callbacks." notable_decisions="[]"]
|
|
67
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
68
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
12
69
|
export function KBAdminPage({ mode = 'view' }: KBAdminPageProps) {
|
|
13
70
|
const { typeSlug, id } = useParams<{ typeSlug: string; id: string }>()
|
|
14
71
|
const navigate = useNavigate()
|
|
@@ -62,3 +119,10 @@ export function KBAdminPage({ mode = 'view' }: KBAdminPageProps) {
|
|
|
62
119
|
</>
|
|
63
120
|
)
|
|
64
121
|
}
|
|
122
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Displays the knowledge base article list or editor based on route mode and id.'; No verified external callers; imports: .framework/src/components/kb/KBArticleList.tsx,.framework/src/components/kb/KBArticleEditor.tsx,.framework/src/components/admin/PageInstructions.tsx"]
|
|
123
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
124
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
125
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
126
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
127
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
128
|
+
// CIL[END stable_id="~/.framework/src/pages/admin/kb/KBAdminPage.tsx:kbadminpage:function"]
|
|
@@ -1,61 +1,64 @@
|
|
|
1
|
-
// CIL[BEGIN
|
|
2
|
-
// CIL[DOC-MACRO purpose="
|
|
3
|
-
// CIL[DOC-RESPONSIBILITY responsibility="
|
|
4
|
-
// CIL[DOC-CONTEXT module="
|
|
5
|
-
// CIL[DOC-CONTRACT inputs="
|
|
6
|
-
// CIL[DOC-MICRO logic_summary="
|
|
7
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/auth/AuthConfirmPage.tsx:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/src/pages/auth/AuthConfirmPage.tsx"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Defines the AuthConfirmPage React component for confirming email signup and password reset tokens."]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Import dependencies, the Supabase client, and shared UI components."]
|
|
4
|
+
// CIL[DOC-CONTEXT module="AuthConfirmPage" layer="pages/auth" related_files=".framework/src/components/ui/LoadingSpinner.tsx,.framework/src/lib/supabase.ts"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="N/A" outputs="N/A" errors="N/A" side_effects="N/A"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Top-level module imports for the auth confirmation page." notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
8
8
|
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
-
// CIL[DOC-AUDIENCE audience="
|
|
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"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="developers maintaining auth flows"]
|
|
16
10
|
import React, { useState, useEffect } from 'react'
|
|
17
11
|
import { Link, useNavigate, useSearchParams } from 'react-router-dom'
|
|
18
12
|
import { supabase } from '../../lib/supabase'
|
|
13
|
+
import { useAuth } from '../../contexts/AuthContext'
|
|
19
14
|
import { LoadingSpinner } from '../../components/ui/LoadingSpinner'
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// CIL[DOC-
|
|
26
|
-
// CIL[DOC-
|
|
27
|
-
// CIL[DOC-
|
|
28
|
-
// CIL[DOC-
|
|
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."]
|
|
15
|
+
import {
|
|
16
|
+
clearPendingRegistration,
|
|
17
|
+
finalizeRegistration,
|
|
18
|
+
readPendingRegistration,
|
|
19
|
+
} from '../../lib/registration'
|
|
20
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Defines the AuthConfirmPage React component for confirming email signup and password reset tokens.'; No verified external callers; imports: .framework/src/lib/supabase.ts,.framework/src/components/ui/LoadingSpinner.tsx"]
|
|
21
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
22
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
23
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
33
24
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
34
25
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
26
|
+
// CIL[END stable_id="~/.framework/src/pages/auth/AuthConfirmPage.tsx:module_header:module_header"]
|
|
27
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/auth/AuthConfirmPage.tsx:stage:type" type="type" identity="Stage" parent="~/.framework/src/pages/auth/AuthConfirmPage.tsx"]
|
|
28
|
+
// CIL[DOC-MACRO purpose="Union type describing the possible stages of the email and password confirmation flow."]
|
|
29
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Define the string literal stage values used by the AuthConfirmPage state machine."]
|
|
30
|
+
// CIL[DOC-CONTEXT module="AuthConfirmPage" layer="pages/auth" related_files=".framework/src/components/ui/LoadingSpinner.tsx,.framework/src/lib/supabase.ts,.framework/src/pages/auth/AuthConfirmPage.tsx"]
|
|
31
|
+
// CIL[DOC-CONTRACT inputs="N/A" outputs="Stage union string literal" errors="N/A" side_effects="N/A"]
|
|
32
|
+
// CIL[DOC-MICRO logic_summary="Literal union type for the component's UI and verification state." notable_decisions="[]"]
|
|
33
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
34
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
35
35
|
type Stage =
|
|
36
36
|
| 'verifying'
|
|
37
37
|
| 'signup_success'
|
|
38
38
|
| 'set_password'
|
|
39
39
|
| 'password_saved'
|
|
40
40
|
| 'error'
|
|
41
|
-
|
|
42
|
-
// CIL[
|
|
43
|
-
// CIL[DOC-
|
|
44
|
-
// CIL[DOC-
|
|
45
|
-
// CIL[DOC-
|
|
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."]
|
|
41
|
+
|
|
42
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Union type describing the possible stages of the email and password confirmation flow.'; No verified external callers; imports: .framework/src/lib/supabase.ts,.framework/src/components/ui/LoadingSpinner.tsx"]
|
|
43
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
44
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
45
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
54
46
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
55
47
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
48
|
+
// CIL[END stable_id="~/.framework/src/pages/auth/AuthConfirmPage.tsx:stage:type"]
|
|
49
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/auth/AuthConfirmPage.tsx:authconfirmpage:function" type="function" identity="AuthConfirmPage" parent="~/.framework/src/pages/auth/AuthConfirmPage.tsx"]
|
|
50
|
+
// CIL[DOC-MACRO purpose="Render the authentication confirmation page and allow users to set a new password after a recovery flow."]
|
|
51
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Verify the OTP token hash, display success or error UI, and handle the new password form submission."]
|
|
52
|
+
// CIL[DOC-CONTEXT module="AuthConfirmPage" layer="pages/auth" related_files=".framework/src/components/ui/LoadingSpinner.tsx,.framework/src/lib/supabase.ts,.framework/src/pages/auth/AuthConfirmPage.tsx"]
|
|
53
|
+
// CIL[DOC-CONTRACT inputs="token_hash and type URL query parameters" outputs="JSX for the verifying, error, signup success, set password, or password saved states" errors="Invalid or missing confirmation link, expired or invalid OTP, failed password update, mismatched or short passwords" side_effects="Calls supabase.auth.verifyOtp and supabase.auth.updateUser; navigates to / on success after a timeout"]
|
|
54
|
+
// CIL[DOC-MICRO logic_summary="Reads token_hash and type from the query string, verifies the OTP with Supabase, then renders a stage-based UI and processes password form submission with client-side validation." notable_decisions="['hash/implicit session fallback via getSession + PASSWORD_RECOVERY listener','resumes spine.pending_registration intent after signup confirm via finalizeRegistration + refreshUser']"]
|
|
55
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
56
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
57
|
+
// CIL[DOC-NOTE type="change" content="Batch4b: links with no token_hash fall back to supabase.auth.getSession (implicit/hash flow); successful signup confirms resume pending registration intent — non-invite runs authenticated complete-registration, invite just rebinds context"]
|
|
56
58
|
export function AuthConfirmPage() {
|
|
57
59
|
const [searchParams] = useSearchParams()
|
|
58
60
|
const navigate = useNavigate()
|
|
61
|
+
const { refreshUser } = useAuth()
|
|
59
62
|
|
|
60
63
|
const tokenHash = searchParams.get('token_hash')
|
|
61
64
|
const type = searchParams.get('type') as 'signup' | 'recovery' | string | null
|
|
@@ -69,37 +72,98 @@ export function AuthConfirmPage() {
|
|
|
69
72
|
const [isSaving, setIsSaving] = useState(false)
|
|
70
73
|
|
|
71
74
|
useEffect(() => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
let cancelled = false
|
|
76
|
+
|
|
77
|
+
// After a confirmed signup, resume the pending registration intent saved
|
|
78
|
+
// in sessionStorage before the email round-trip (spine.pending_registration).
|
|
79
|
+
// Invite intents need no server call — the stub was claimed by the
|
|
80
|
+
// auth.users trigger when signUp ran.
|
|
81
|
+
const finishSignup = async () => {
|
|
82
|
+
const intent = readPendingRegistration()
|
|
83
|
+
try {
|
|
84
|
+
if (intent && !intent.invite && intent.path) {
|
|
85
|
+
const result = await finalizeRegistration(intent)
|
|
86
|
+
clearPendingRegistration()
|
|
87
|
+
await refreshUser()
|
|
88
|
+
if (cancelled) return
|
|
89
|
+
setStage('signup_success')
|
|
90
|
+
setTimeout(() => navigate(
|
|
91
|
+
result.status === 'pending' ? '/auth/pending-approval' : '/',
|
|
92
|
+
{ replace: true }
|
|
93
|
+
), 1500)
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
if (intent) clearPendingRegistration()
|
|
97
|
+
await refreshUser()
|
|
98
|
+
if (cancelled) return
|
|
99
|
+
setStage('signup_success')
|
|
100
|
+
setTimeout(() => navigate('/', { replace: true }), 1500)
|
|
101
|
+
} catch {
|
|
102
|
+
// Keep the intent — /register?resume=1 retries it and surfaces the
|
|
103
|
+
// error. The signup itself is still confirmed.
|
|
104
|
+
if (cancelled) return
|
|
105
|
+
setStage('signup_success')
|
|
106
|
+
setTimeout(() => navigate('/register?resume=1', { replace: true }), 1500)
|
|
107
|
+
}
|
|
76
108
|
}
|
|
77
109
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
110
|
+
if (tokenHash && type) {
|
|
111
|
+
;(async () => {
|
|
112
|
+
const { error } = await supabase.auth.verifyOtp({
|
|
113
|
+
token_hash: tokenHash,
|
|
114
|
+
type: type as any,
|
|
115
|
+
})
|
|
83
116
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
117
|
+
if (error) {
|
|
118
|
+
if (error.message.includes('expired') || error.message.includes('otp_expired')) {
|
|
119
|
+
setErrorMessage('This link has expired. Links are valid for 1 hour.')
|
|
120
|
+
} else if (error.message.includes('invalid')) {
|
|
121
|
+
setErrorMessage('This link is invalid or has already been used.')
|
|
122
|
+
} else {
|
|
123
|
+
setErrorMessage(error.message)
|
|
124
|
+
}
|
|
125
|
+
setStage('error')
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (type === 'recovery') {
|
|
130
|
+
setStage('set_password')
|
|
89
131
|
} else {
|
|
90
|
-
|
|
132
|
+
void finishSignup()
|
|
91
133
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
134
|
+
})()
|
|
135
|
+
return () => { cancelled = true }
|
|
136
|
+
}
|
|
95
137
|
|
|
96
|
-
|
|
138
|
+
// Hash/implicit callback: detectSessionInUrl consumes #access_token before
|
|
139
|
+
// this page reads params, so a live session means the link verified.
|
|
140
|
+
const hashType = new URLSearchParams(window.location.hash.replace(/^#/, '')).get('type')
|
|
141
|
+
if (hashType === 'recovery') {
|
|
142
|
+
setStage('set_password')
|
|
143
|
+
return () => { cancelled = true }
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const { data: { subscription } } = supabase.auth.onAuthStateChange((event) => {
|
|
147
|
+
if (event === 'PASSWORD_RECOVERY' && !cancelled) {
|
|
97
148
|
setStage('set_password')
|
|
98
|
-
} else {
|
|
99
|
-
setStage('signup_success')
|
|
100
|
-
setTimeout(() => navigate('/', { replace: true }), 1500)
|
|
101
149
|
}
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
;(async () => {
|
|
153
|
+
const { data: { session } } = await supabase.auth.getSession()
|
|
154
|
+
if (cancelled) return
|
|
155
|
+
if (session) {
|
|
156
|
+
await finishSignup()
|
|
157
|
+
return
|
|
158
|
+
}
|
|
159
|
+
setErrorMessage('Invalid or missing confirmation link. Please request a new one.')
|
|
160
|
+
setStage('error')
|
|
102
161
|
})()
|
|
162
|
+
|
|
163
|
+
return () => {
|
|
164
|
+
cancelled = true
|
|
165
|
+
subscription.unsubscribe()
|
|
166
|
+
}
|
|
103
167
|
}, [])
|
|
104
168
|
|
|
105
169
|
const handleSetPassword = async (e: React.FormEvent) => {
|
|
@@ -210,8 +274,8 @@ export function AuthConfirmPage() {
|
|
|
210
274
|
<div className="min-h-screen flex items-center justify-center bg-slate-50 py-12 px-4 sm:px-6 lg:px-8">
|
|
211
275
|
<div className="max-w-md w-full space-y-8">
|
|
212
276
|
<div>
|
|
213
|
-
<div className="mx-auto
|
|
214
|
-
<
|
|
277
|
+
<div className="mx-auto flex items-center justify-center">
|
|
278
|
+
<img src="/spine-logo.svg" alt="Spine Framework" className="h-14 w-auto" />
|
|
215
279
|
</div>
|
|
216
280
|
<h2 className="mt-6 text-center text-3xl font-extrabold text-slate-900">
|
|
217
281
|
Set a new password
|
|
@@ -286,4 +350,10 @@ export function AuthConfirmPage() {
|
|
|
286
350
|
</div>
|
|
287
351
|
)
|
|
288
352
|
}
|
|
289
|
-
// CIL[
|
|
353
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Render the authentication confirmation page and allow users to set a new password after a recovery flow.'; No verified external callers; imports: .framework/src/lib/supabase.ts,.framework/src/components/ui/LoadingSpinner.tsx"]
|
|
354
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
355
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
356
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
357
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
358
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
359
|
+
// CIL[END stable_id="~/.framework/src/pages/auth/AuthConfirmPage.tsx:authconfirmpage:function"]
|
|
@@ -1,39 +1,38 @@
|
|
|
1
|
-
// CIL[BEGIN
|
|
2
|
-
// CIL[DOC-MACRO purpose="
|
|
3
|
-
// CIL[DOC-RESPONSIBILITY responsibility="
|
|
4
|
-
// CIL[DOC-CONTEXT module="
|
|
5
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="
|
|
6
|
-
// CIL[DOC-MICRO logic_summary="
|
|
7
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/auth/ForgotPasswordPage.tsx:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/src/pages/auth/ForgotPasswordPage.tsx"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Provides imports and entry-point metadata for the ForgotPasswordPage component."]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declare module dependencies and export the ForgotPasswordPage component."]
|
|
4
|
+
// CIL[DOC-CONTEXT module="auth" layer="presentation" related_files=".framework/src/components/ui/LoadingSpinner.tsx,.framework/src/lib/supabase.ts"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Imports React, routing, Supabase client, and a loading spinner; contains no runtime logic." notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
8
8
|
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
-
// CIL[DOC-AUDIENCE audience="
|
|
10
|
-
|
|
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"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="developers,ui-maintainers"]
|
|
10
|
+
|
|
16
11
|
import React, { useState } from 'react'
|
|
17
12
|
import { Link } from 'react-router-dom'
|
|
18
13
|
import { supabase } from '../../lib/supabase'
|
|
19
14
|
import { LoadingSpinner } from '../../components/ui/LoadingSpinner'
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// CIL[DOC-
|
|
23
|
-
// CIL[DOC-
|
|
24
|
-
// CIL[DOC-
|
|
25
|
-
// CIL[DOC-
|
|
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."]
|
|
15
|
+
import { TurnstileWidget, turnstileEnabled } from '../../components/auth/TurnstileWidget'
|
|
16
|
+
|
|
17
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Provides imports and entry-point metadata for the ForgotPasswordPage component.'; No verified external callers; imports: .framework/src/lib/supabase.ts,.framework/src/components/ui/LoadingSpinner.tsx"]
|
|
18
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
19
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
20
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
33
21
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
34
22
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
23
|
+
// CIL[END stable_id="~/.framework/src/pages/auth/ForgotPasswordPage.tsx:module_header:module_header"]
|
|
24
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/auth/ForgotPasswordPage.tsx:ForgotPasswordPage:component" type="component" identity="ForgotPasswordPage" parent="~/.framework/src/pages/auth/ForgotPasswordPage.tsx"]
|
|
25
|
+
// CIL[DOC-MACRO purpose="Render a password-reset request page and submit the email to Supabase."]
|
|
26
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a UI for users to enter their email and trigger a password reset email."]
|
|
27
|
+
// CIL[DOC-CONTEXT module="auth" layer="presentation" related_files=".framework/src/components/ui/LoadingSpinner.tsx,.framework/src/lib/supabase.ts,.framework/src/pages/auth/ForgotPasswordPage.tsx"]
|
|
28
|
+
// CIL[DOC-CONTRACT inputs="email (string from user input)" outputs="Rendered JSX form or success confirmation; local state updates for loading/submitted/error." errors="Supabase resetPasswordForEmail errors surfaced to the UI." side_effects="Calls supabase.auth.resetPasswordForEmail with a redirectTo URL; updates component state."]
|
|
29
|
+
// CIL[DOC-MICRO logic_summary="Manages email, loading, submitted and error state. On submit it prevents default, clears errors, sets loading, calls Supabase reset, and on success shows a confirmation with a back-to-login link." notable_decisions="[]"]
|
|
30
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
31
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
32
|
+
|
|
35
33
|
export function ForgotPasswordPage() {
|
|
36
34
|
const [email, setEmail] = useState('')
|
|
35
|
+
const [captchaToken, setCaptchaToken] = useState<string | null>(null)
|
|
37
36
|
const [isLoading, setIsLoading] = useState(false)
|
|
38
37
|
const [submitted, setSubmitted] = useState(false)
|
|
39
38
|
const [error, setError] = useState('')
|
|
@@ -46,6 +45,7 @@ export function ForgotPasswordPage() {
|
|
|
46
45
|
try {
|
|
47
46
|
const { error: resetError } = await supabase.auth.resetPasswordForEmail(email, {
|
|
48
47
|
redirectTo: `${window.location.origin}/auth/confirm`,
|
|
48
|
+
captchaToken: captchaToken ?? undefined,
|
|
49
49
|
})
|
|
50
50
|
|
|
51
51
|
if (resetError) {
|
|
@@ -90,8 +90,8 @@ export function ForgotPasswordPage() {
|
|
|
90
90
|
<div className="min-h-screen flex items-center justify-center bg-slate-50 py-12 px-4 sm:px-6 lg:px-8">
|
|
91
91
|
<div className="max-w-md w-full space-y-8">
|
|
92
92
|
<div>
|
|
93
|
-
<div className="mx-auto
|
|
94
|
-
<
|
|
93
|
+
<div className="mx-auto flex items-center justify-center">
|
|
94
|
+
<img src="/spine-logo.svg" alt="Spine Framework" className="h-14 w-auto" />
|
|
95
95
|
</div>
|
|
96
96
|
<h2 className="mt-6 text-center text-3xl font-extrabold text-slate-900">
|
|
97
97
|
Reset your password
|
|
@@ -125,10 +125,12 @@ export function ForgotPasswordPage() {
|
|
|
125
125
|
/>
|
|
126
126
|
</div>
|
|
127
127
|
|
|
128
|
+
<TurnstileWidget onToken={setCaptchaToken} />
|
|
129
|
+
|
|
128
130
|
<div>
|
|
129
131
|
<button
|
|
130
132
|
type="submit"
|
|
131
|
-
disabled={isLoading}
|
|
133
|
+
disabled={isLoading || (turnstileEnabled && !captchaToken)}
|
|
132
134
|
className="group relative w-full flex justify-center py-2 px-4 border border-transparent rounded-[5px] shadow-sm text-sm font-medium text-white bg-slate-900 hover:bg-slate-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-accent-blue disabled:opacity-50 disabled:cursor-not-allowed"
|
|
133
135
|
>
|
|
134
136
|
{isLoading ? (
|
|
@@ -152,4 +154,10 @@ export function ForgotPasswordPage() {
|
|
|
152
154
|
</div>
|
|
153
155
|
)
|
|
154
156
|
}
|
|
155
|
-
// CIL[
|
|
157
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Render a password-reset request page and submit the email to Supabase.'; No verified external callers; imports: .framework/src/lib/supabase.ts,.framework/src/components/ui/LoadingSpinner.tsx"]
|
|
158
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
159
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
160
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
161
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
162
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
163
|
+
// CIL[END stable_id="~/.framework/src/pages/auth/ForgotPasswordPage.tsx:ForgotPasswordPage:component"]
|
|
@@ -1,40 +1,38 @@
|
|
|
1
|
-
// CIL[BEGIN
|
|
2
|
-
// CIL[DOC-MACRO purpose="
|
|
3
|
-
// CIL[DOC-RESPONSIBILITY responsibility="
|
|
4
|
-
// CIL[DOC-CONTEXT module="
|
|
5
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="
|
|
6
|
-
// CIL[DOC-MICRO logic_summary="
|
|
7
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/auth/LoginPage.tsx:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/src/pages/auth/LoginPage.tsx"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Module header for the LoginPage component: imports, dependencies, and module-level context."]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declare module-level imports and setup for the authentication login page."]
|
|
4
|
+
// CIL[DOC-CONTEXT module="auth" layer="presentation" related_files=".framework/src/components/ui/LoadingSpinner.tsx,.framework/src/contexts/AuthContext.tsx"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Imports React, routing, auth context, and the LoadingSpinner UI component." notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.85" flags="none"]
|
|
8
8
|
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
-
// CIL[DOC-AUDIENCE audience="
|
|
10
|
-
|
|
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"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="developers"]
|
|
10
|
+
|
|
16
11
|
import React, { useState } from 'react'
|
|
17
12
|
import { Link, useNavigate } from 'react-router-dom'
|
|
18
13
|
import { useAuth } from '../../contexts/AuthContext'
|
|
19
14
|
import { LoadingSpinner } from '../../components/ui/LoadingSpinner'
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// CIL[DOC-
|
|
23
|
-
// CIL[DOC-
|
|
24
|
-
// CIL[DOC-
|
|
25
|
-
// CIL[DOC-
|
|
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."]
|
|
15
|
+
import { TurnstileWidget, turnstileEnabled } from '../../components/auth/TurnstileWidget'
|
|
16
|
+
|
|
17
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Module header for the LoginPage component: imports, dependencies, and module-level context.'; No verified external callers; imports: .framework/src/contexts/AuthContext.tsx,.framework/src/components/ui/LoadingSpinner.tsx"]
|
|
18
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
19
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
20
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
33
21
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
34
22
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
23
|
+
// CIL[END stable_id="~/.framework/src/pages/auth/LoginPage.tsx:module_header:module_header"]
|
|
24
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/auth/LoginPage.tsx:LoginPage:component" type="component" identity="LoginPage" parent="~/.framework/src/pages/auth/LoginPage.tsx"]
|
|
25
|
+
// CIL[DOC-MACRO purpose="Render the login form and handle user authentication."]
|
|
26
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Collect email and password, call auth login, and navigate to the appropriate post-login route."]
|
|
27
|
+
// CIL[DOC-CONTEXT module="auth" layer="presentation" related_files=".framework/src/components/ui/LoadingSpinner.tsx,.framework/src/contexts/AuthContext.tsx,.framework/src/pages/auth/LoginPage.tsx"]
|
|
28
|
+
// CIL[DOC-CONTRACT inputs="none (reads from local form state and AuthContext)" outputs="JSX login page" errors="displays authentication error message" side_effects="calls login API and navigates with react-router"]
|
|
29
|
+
// CIL[DOC-MICRO logic_summary="Manages email/password/isLoading state; on submit prevents default, calls login, fetches spine.config.json, resolves default app by role, and navigates." notable_decisions="[]"]
|
|
30
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.85" flags="none"]
|
|
31
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
35
32
|
export function LoginPage() {
|
|
36
33
|
const [email, setEmail] = useState('')
|
|
37
34
|
const [password, setPassword] = useState('')
|
|
35
|
+
const [captchaToken, setCaptchaToken] = useState<string | null>(null)
|
|
38
36
|
const [error, setError] = useState('')
|
|
39
37
|
const [isLoading, setIsLoading] = useState(false)
|
|
40
38
|
|
|
@@ -47,7 +45,7 @@ export function LoginPage() {
|
|
|
47
45
|
setIsLoading(true)
|
|
48
46
|
|
|
49
47
|
try {
|
|
50
|
-
const user = await login(email, password)
|
|
48
|
+
const user = await login(email, password, captchaToken ?? undefined)
|
|
51
49
|
const role = user?.roles?.[0]
|
|
52
50
|
if (!role) {
|
|
53
51
|
navigate('/')
|
|
@@ -75,8 +73,8 @@ export function LoginPage() {
|
|
|
75
73
|
<div className="min-h-screen flex items-center justify-center bg-slate-50 py-12 px-4 sm:px-6 lg:px-8">
|
|
76
74
|
<div className="max-w-md w-full space-y-8">
|
|
77
75
|
<div>
|
|
78
|
-
<div className="mx-auto
|
|
79
|
-
<
|
|
76
|
+
<div className="mx-auto flex items-center justify-center">
|
|
77
|
+
<img src="/spine-logo.svg" alt="Spine Framework" className="h-14 w-auto" />
|
|
80
78
|
</div>
|
|
81
79
|
<h2 className="mt-6 text-center text-3xl font-extrabold text-slate-900">
|
|
82
80
|
Sign in to Spine
|
|
@@ -152,10 +150,12 @@ export function LoginPage() {
|
|
|
152
150
|
</div>
|
|
153
151
|
</div>
|
|
154
152
|
|
|
153
|
+
<TurnstileWidget onToken={setCaptchaToken} />
|
|
154
|
+
|
|
155
155
|
<div>
|
|
156
156
|
<button
|
|
157
157
|
type="submit"
|
|
158
|
-
disabled={isLoading}
|
|
158
|
+
disabled={isLoading || (turnstileEnabled && !captchaToken)}
|
|
159
159
|
className="group relative w-full flex justify-center py-2 px-4 border border-transparent rounded-[5px] shadow-sm text-sm font-medium text-white bg-slate-900 hover:bg-slate-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-accent-blue disabled:opacity-50 disabled:cursor-not-allowed"
|
|
160
160
|
>
|
|
161
161
|
{isLoading ? (
|
|
@@ -173,4 +173,10 @@ export function LoginPage() {
|
|
|
173
173
|
</div>
|
|
174
174
|
)
|
|
175
175
|
}
|
|
176
|
-
// CIL[
|
|
176
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Render the login form and handle user authentication.'; No verified external callers; imports: .framework/src/contexts/AuthContext.tsx,.framework/src/components/ui/LoadingSpinner.tsx"]
|
|
177
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
178
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
179
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
180
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
181
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
182
|
+
// CIL[END stable_id="~/.framework/src/pages/auth/LoginPage.tsx:LoginPage:component"]
|