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
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module functions/_shared
|
|
3
|
+
* @audience internal
|
|
4
|
+
* @layer rate-limit
|
|
5
|
+
* @stability stable
|
|
6
|
+
*
|
|
7
|
+
* Configurable DB-backed rate limiting for sensitive actions
|
|
8
|
+
*
|
|
9
|
+
* @seeAlso .framework/functions/_shared/db.ts (provides database access for rate limits).
|
|
10
|
+
* @seeAlso .framework/functions/_shared/audit.ts (emits security.rate_limit_exceeded audit events).
|
|
11
|
+
* @seeAlso .framework/functions/_shared/middleware.ts (contains context types used in this module).
|
|
12
|
+
*
|
|
13
|
+
* @cil-generated
|
|
14
|
+
*/
|
|
15
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/rate-limit.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/_shared/rate-limit.ts"]
|
|
16
|
+
// CIL[DOC-MACRO purpose="Configurable DB-backed rate limiting for sensitive actions"]
|
|
17
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Resolve rate-limit policy from accounts.data (override or named profile) falling back to apps.config.rate_limits, and enforce it via the atomic rate_limit_hit RPC"]
|
|
18
|
+
// CIL[DOC-CONTEXT module="functions/_shared" layer="rate-limit" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts,.framework/migrations/035_rate_limits.sql"]
|
|
19
|
+
// CIL[DOC-CONTRACT inputs="ctx, action name, optional identifier override" outputs="void or throws RateLimitError (429)" errors="RateLimitError when over policy; fail-closed policies throw on limiter outage" side_effects="Increments rate_limits counters"]
|
|
20
|
+
// CIL[DOC-MICRO logic_summary="accounts.data.rate_limits[action] wins; accounts.data.rate_limit_profile selects config.rate_limits.profiles[profile][action] before the app's base policy; each policy is a fixed window counter keyed action:identifier; over-limit throws 429 with retry_after" notable_decisions="Policy is data/config, not code — accounts and apps declare limits and Core enforces; window_seconds 0 means lifetime cap; fail_closed reserved for cost-bearing actions like agent_step"]
|
|
21
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
22
|
+
// CIL[DOC-AUDIENCE audience="internal"]
|
|
23
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Configurable DB-backed rate limiting for sensitive actions'; No verified external callers; imports: .framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts"]
|
|
24
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
25
|
+
// CIL[DOC-VECTOR type="configuration" content="Policies read from accounts.data.rate_limits / accounts.data.rate_limit_profile, falling back to apps.config.rate_limits (incl. named profiles) keyed by action name"]
|
|
26
|
+
// CIL[DOC-VECTOR type="constraint" content="Requires migration 035 (rate_limits table + rate_limit_hit RPC); fail-closed only for cost-bearing actions"]
|
|
27
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
28
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
29
|
+
|
|
30
|
+
import { adminDb } from './db'
|
|
31
|
+
import type { CoreContext, RequestContext } from './middleware'
|
|
32
|
+
import { emitAudit } from './audit'
|
|
33
|
+
// CIL[END stable_id="~/.framework/functions/_shared/rate-limit.ts:module_header:module_header"]
|
|
34
|
+
|
|
35
|
+
// CIL[DOC-MACRO purpose="RateLimitPolicy defines the parameters for controlling the rate of actions within a specified time window."]
|
|
36
|
+
// CIL[DOC-RESPONSIBILITY responsibility="RateLimitPolicy defines the parameters for controlling the rate of actions within a specified time window. It is used to enforce limits on the number of allowed actions to prevent abuse and manage resource usage."]
|
|
37
|
+
// CIL[DOC-CONTEXT module="rate-limit" layer="app-specific" related_files=".framework/functions/_shared/db,.framework/functions/_shared/middleware,.framework/functions/_shared/audit"]
|
|
38
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
39
|
+
// CIL[DOC-MICRO logic_summary="RateLimitPolicy defines the parameters for controlling the rate of actions within a specified time window. It is used to enforce limits on the number of allowed actions to prevent abuse and manage resource usage." notable_decisions="none"]
|
|
40
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
41
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
42
|
+
/**
|
|
43
|
+
* RateLimitPolicy defines the parameters for controlling the rate of actions within a specified time window. It is used to enforce limits on the number of allowed actions to prevent abuse and manage resource usage.
|
|
44
|
+
*
|
|
45
|
+
* @sideEffects none
|
|
46
|
+
* @stability stable
|
|
47
|
+
* @cil-generated
|
|
48
|
+
*/
|
|
49
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/rate-limit.ts:ratelimitpolicy:type" type="type" identity="RateLimitPolicy" parent="~/.framework/functions/_shared/rate-limit.ts"]
|
|
50
|
+
// CIL[DOC-MACRO purpose="RateLimitPolicy type"]
|
|
51
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Implements the RateLimitPolicy type."]
|
|
52
|
+
// CIL[DOC-CONTEXT module=".framework/functions/_shared/rate-limit.ts" layer="app-specific" related_files=""]
|
|
53
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
54
|
+
// CIL[DOC-MICRO logic_summary="Implements the RateLimitPolicy type." notable_decisions="[]"]
|
|
55
|
+
// CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
|
|
56
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
57
|
+
export type RateLimitPolicy = {
|
|
58
|
+
/** Max hits allowed inside the window. */
|
|
59
|
+
limit: number
|
|
60
|
+
/** Window size in seconds. 0 = lifetime cap (no reset). */
|
|
61
|
+
window_seconds: number
|
|
62
|
+
/** When true, an inability to check the limit denies the action. Use for cost-bearing actions (e.g. agent_step). Default false = fail-open. */
|
|
63
|
+
fail_closed?: boolean
|
|
64
|
+
}
|
|
65
|
+
// CIL[END stable_id="~/.framework/functions/_shared/rate-limit.ts:ratelimitpolicy:type"]
|
|
66
|
+
// CIL[DOC-VECTOR type="context" content="purpose='RateLimitPolicy defines the parameters for controlling the rate of actions within a specified time window.'; No verified external callers" status="ready"]
|
|
67
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
|
|
68
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
|
|
69
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
|
|
70
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
71
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
72
|
+
|
|
73
|
+
// CIL[DOC-MACRO purpose="Custom error class for handling rate limit violations."]
|
|
74
|
+
// CIL[DOC-RESPONSIBILITY responsibility="RateLimitError is an error class that represents a situation where a rate limit has been exceeded for a specific action. It provides additional context such as the action, limit, and retry duration."]
|
|
75
|
+
// CIL[DOC-CONTEXT module="rate-limit" layer="app-specific" related_files=".framework/functions/_shared/db,.framework/functions/_shared/middleware,.framework/functions/_shared/audit"]
|
|
76
|
+
// CIL[DOC-CONTRACT inputs="action: string (required) — the action that triggered the rate limit.\\nlimit: number (required) — the maximum number of allowed requests.\\nretryAfter: number | null (optional|nullable) — the duration in seconds to wait before retrying." outputs="RateLimitError — an instance of RateLimitError with specific properties set." errors="none" side_effects="none"]
|
|
77
|
+
// CIL[DOC-MICRO logic_summary="Constructs an error message that includes the action for which the rate limit was exceeded." notable_decisions="none"]
|
|
78
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
79
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
80
|
+
/**
|
|
81
|
+
* RateLimitError is an error class that represents a situation where a rate limit has been exceeded for a specific action. It provides additional context such as the action, limit, and retry duration.
|
|
82
|
+
*
|
|
83
|
+
* @macro Custom error class for handling rate limit violations.
|
|
84
|
+
* @micro Constructs an error message that includes the action for which the rate limit was exceeded.
|
|
85
|
+
* @inputSpec
|
|
86
|
+
* action: string (required) — the action that triggered the rate limit.
|
|
87
|
+
* limit: number (required) — the maximum number of allowed requests.
|
|
88
|
+
* retryAfter: number | null (optional|nullable) — the duration in seconds to wait before retrying.
|
|
89
|
+
* @outputSpec RateLimitError — an instance of RateLimitError with specific properties set.
|
|
90
|
+
* @sideEffects none
|
|
91
|
+
* @stability stable
|
|
92
|
+
* @cil-generated
|
|
93
|
+
*/
|
|
94
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/rate-limit.ts:ratelimiterror:class" type="class" identity="RateLimitError" parent="~/.framework/functions/_shared/rate-limit.ts"]
|
|
95
|
+
// CIL[DOC-MACRO purpose="RateLimitError class"]
|
|
96
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Implements the RateLimitError class."]
|
|
97
|
+
// CIL[DOC-CONTEXT module=".framework/functions/_shared/rate-limit.ts" layer="app-specific" related_files=""]
|
|
98
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
99
|
+
// CIL[DOC-MICRO logic_summary="Implements the RateLimitError class." notable_decisions="[]"]
|
|
100
|
+
// CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
|
|
101
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
102
|
+
export class RateLimitError extends Error {
|
|
103
|
+
statusCode = 429
|
|
104
|
+
action: string
|
|
105
|
+
limit: number
|
|
106
|
+
retryAfter: number | null
|
|
107
|
+
|
|
108
|
+
constructor(action: string, limit: number, retryAfter: number | null) {
|
|
109
|
+
super(`Rate limit exceeded for ${action}`)
|
|
110
|
+
this.name = 'RateLimitError'
|
|
111
|
+
this.action = action
|
|
112
|
+
this.limit = limit
|
|
113
|
+
this.retryAfter = retryAfter
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// CIL[END stable_id="~/.framework/functions/_shared/rate-limit.ts:ratelimiterror:class"]
|
|
117
|
+
// CIL[DOC-VECTOR type="context" content="purpose='RateLimitError is an error class that represents a situation where a rate limit has been exceeded for a specific action.'; No verified external callers" status="ready"]
|
|
118
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
|
|
119
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
|
|
120
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
|
|
121
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
122
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
123
|
+
|
|
124
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/rate-limit.ts:resolveratelimitpolicies:function" type="function" identity="resolveRateLimitPolicies" parent="~/.framework/functions/_shared/rate-limit.ts"]
|
|
125
|
+
// CIL[DOC-MACRO purpose="Resolve the effective rate-limit policies for an action"]
|
|
126
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Read accounts.data.rate_limits / rate_limit_profile for the request account, falling back to apps.config.rate_limits for the calling app"]
|
|
127
|
+
// CIL[DOC-CONTRACT inputs="ctx, action" outputs="RateLimitPolicy[] (empty = unlimited)" errors="returns [] on lookup failure" side_effects="accounts + apps table reads"]
|
|
128
|
+
// CIL[DOC-MICRO logic_summary="accounts.data.rate_limits[action] wins; accounts.data.rate_limit_profile selects config.rate_limits.profiles[profile][action] before the app's base config.rate_limits[action]" notable_decisions="Policy follows the account, not a named app — enforcement is identical no matter which URL the client hit; ctx.appId selects only the calling app's config"]
|
|
129
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
130
|
+
export async function resolveRateLimitPolicies(
|
|
131
|
+
ctx: CoreContext & { appId?: string | null },
|
|
132
|
+
action: string
|
|
133
|
+
): Promise<RateLimitPolicy[]> {
|
|
134
|
+
const toPolicies = (raw: any): RateLimitPolicy[] =>
|
|
135
|
+
(Array.isArray(raw) ? raw : raw ? [raw] : []).filter(
|
|
136
|
+
(p: any) => typeof p?.limit === 'number' && typeof p?.window_seconds === 'number'
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
// 1. Account-declared override wins.
|
|
141
|
+
let acctData: any = null
|
|
142
|
+
if (ctx.accountId) {
|
|
143
|
+
const { data: acct } = await adminDb
|
|
144
|
+
.from('accounts').select('data').eq('id', ctx.accountId).maybeSingle()
|
|
145
|
+
acctData = acct?.data || null
|
|
146
|
+
}
|
|
147
|
+
const acctPolicies = toPolicies(acctData?.rate_limits?.[action])
|
|
148
|
+
if (acctPolicies.length) return acctPolicies
|
|
149
|
+
|
|
150
|
+
// 2/3. Calling app's config only — no cross-app lookups.
|
|
151
|
+
let appCfg: any = null
|
|
152
|
+
if (ctx.appId) {
|
|
153
|
+
const { data: appRow } = await adminDb
|
|
154
|
+
.from('apps').select('config').eq('slug', ctx.appId).maybeSingle()
|
|
155
|
+
appCfg = appRow?.config || null
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const profile = typeof acctData?.rate_limit_profile === 'string'
|
|
159
|
+
? acctData.rate_limit_profile
|
|
160
|
+
: null
|
|
161
|
+
if (profile) {
|
|
162
|
+
const raw =
|
|
163
|
+
appCfg?.rate_limits?.profiles?.[profile]?.[action] ??
|
|
164
|
+
appCfg?.rate_limits?.[action]
|
|
165
|
+
return toPolicies(raw)
|
|
166
|
+
}
|
|
167
|
+
return toPolicies(appCfg?.rate_limits?.[action])
|
|
168
|
+
} catch {
|
|
169
|
+
return []
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// CIL[END stable_id="~/.framework/functions/_shared/rate-limit.ts:resolveratelimitpolicies:function"]
|
|
173
|
+
|
|
174
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/rate-limit.ts:checkratelimit:function" type="function" identity="checkRateLimit" parent="~/.framework/functions/_shared/rate-limit.ts"]
|
|
175
|
+
// CIL[DOC-MACRO purpose="Enforce rate-limit policies for an action"]
|
|
176
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Atomically increment each policy's window counter and throw RateLimitError when any policy is exceeded"]
|
|
177
|
+
// CIL[DOC-CONTRACT inputs="ctx, action, opts.identifier (defaults to account or anonymous-ip)" outputs="void" errors="RateLimitError (429) over limit; Error (503) when a fail_closed policy cannot be checked" side_effects="rate_limits upsert via RPC"]
|
|
178
|
+
// CIL[DOC-MICRO logic_summary="For each resolved policy compute window_start (floored epoch or epoch-zero for lifetime), call rate_limit_hit, compare count to limit" notable_decisions="Counters always increment before the check so the first hit counts; retry_after is seconds until the window rolls"]
|
|
179
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
180
|
+
export async function checkRateLimit(
|
|
181
|
+
ctx: CoreContext,
|
|
182
|
+
action: string,
|
|
183
|
+
opts: { identifier?: string; policies?: RateLimitPolicy[] } = {}
|
|
184
|
+
): Promise<void> {
|
|
185
|
+
const policies = opts.policies ?? await resolveRateLimitPolicies(ctx, action)
|
|
186
|
+
if (!policies.length) return
|
|
187
|
+
|
|
188
|
+
const identifier = opts.identifier || (ctx.accountId ? `acct:${ctx.accountId}` : 'anon')
|
|
189
|
+
const now = Date.now()
|
|
190
|
+
|
|
191
|
+
for (const policy of policies) {
|
|
192
|
+
const windowStart = policy.window_seconds > 0
|
|
193
|
+
? new Date(Math.floor(now / (policy.window_seconds * 1000)) * policy.window_seconds * 1000)
|
|
194
|
+
: new Date(0)
|
|
195
|
+
const key = `${action}:${identifier}`
|
|
196
|
+
|
|
197
|
+
let count: number | null = null
|
|
198
|
+
try {
|
|
199
|
+
const { data, error } = await adminDb.rpc('rate_limit_hit', {
|
|
200
|
+
p_key: key,
|
|
201
|
+
p_window_start: windowStart.toISOString(),
|
|
202
|
+
})
|
|
203
|
+
if (error) throw error
|
|
204
|
+
count = typeof data === 'number' ? data : null
|
|
205
|
+
} catch (err: any) {
|
|
206
|
+
console.warn(`checkRateLimit(${action}) RPC failed:`, err?.message)
|
|
207
|
+
if (policy.fail_closed) {
|
|
208
|
+
const e: any = new Error(`Rate limit unavailable for ${action}`)
|
|
209
|
+
e.statusCode = 503
|
|
210
|
+
throw e
|
|
211
|
+
}
|
|
212
|
+
continue
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (count !== null && count > policy.limit) {
|
|
216
|
+
const retryAfter = policy.window_seconds > 0
|
|
217
|
+
? Math.ceil((windowStart.getTime() + policy.window_seconds * 1000 - now) / 1000)
|
|
218
|
+
: null
|
|
219
|
+
// Security signal: the flagged-accounts report aggregates these.
|
|
220
|
+
void emitAudit({ ...ctx, db: adminDb } as any, 'security.rate_limit_exceeded', {
|
|
221
|
+
type: 'rate_limit', id: key, account_id: ctx.accountId
|
|
222
|
+
}, {
|
|
223
|
+
result: 'denied',
|
|
224
|
+
action_name: action,
|
|
225
|
+
identifier,
|
|
226
|
+
limit: policy.limit,
|
|
227
|
+
retry_after: retryAfter,
|
|
228
|
+
}).catch(() => {})
|
|
229
|
+
throw new RateLimitError(action, policy.limit, retryAfter)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// CIL[END stable_id="~/.framework/functions/_shared/rate-limit.ts:checkratelimit:function"]
|
|
@@ -1,32 +1,75 @@
|
|
|
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="
|
|
8
|
-
// CIL[DOC-STABILITY stability="
|
|
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="Credential field must be defined in integrations.credentials."]
|
|
14
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="Helper used by broker and core LLM callers."]
|
|
15
|
-
// CIL[DOC-VECTOR type="user_journey" content="Runtime credential resolution for outbound calls."]
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/resolve-credentials.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/_shared/resolve-credentials.ts"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Module header for resolve-credentials; imports shared dependencies."]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declares module-level imports and identifies file scope."]
|
|
4
|
+
// CIL[DOC-CONTEXT module="resolve-credentials" layer="shared" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/middleware.ts"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Imports CoreContext from middleware and emitLog from audit." notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
8
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="developers"]
|
|
10
|
+
|
|
16
11
|
|
|
17
12
|
import { CoreContext } from './middleware'
|
|
18
13
|
import { emitLog } from './audit'
|
|
14
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Module header for resolve-credentials; imports shared dependencies.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts"]
|
|
15
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
16
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
17
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
18
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
19
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
20
|
+
// CIL[END stable_id="~/.framework/functions/_shared/resolve-credentials.ts:module_header:module_header"]
|
|
21
|
+
|
|
19
22
|
|
|
23
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/resolve-credentials.ts:CredentialEntry:interface" type="interface" identity="CredentialEntry" parent="~/.framework/functions/_shared/resolve-credentials.ts"]
|
|
24
|
+
// CIL[DOC-MACRO purpose="Describes a single credential entry with source and raw value."]
|
|
25
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Defines the shape of a credential configuration entry."]
|
|
26
|
+
// CIL[DOC-CONTEXT module="resolve-credentials" layer="shared" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts"]
|
|
27
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="CredentialEntry type" errors="none" side_effects="none"]
|
|
28
|
+
// CIL[DOC-MICRO logic_summary="Interface with source and value fields; source is either 'value' or 'env_var'." notable_decisions="[]"]
|
|
29
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
30
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
20
31
|
interface CredentialEntry {
|
|
21
32
|
source: 'value' | 'env_var'
|
|
22
33
|
value: string
|
|
23
34
|
}
|
|
35
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Describes a single credential entry with source and raw value.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts"]
|
|
36
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
37
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
38
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
39
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
40
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
41
|
+
// CIL[END stable_id="~/.framework/functions/_shared/resolve-credentials.ts:CredentialEntry:interface"]
|
|
42
|
+
|
|
24
43
|
|
|
44
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/resolve-credentials.ts:ResolvedCredential:interface" type="interface" identity="ResolvedCredential" parent="~/.framework/functions/_shared/resolve-credentials.ts"]
|
|
45
|
+
// CIL[DOC-MACRO purpose="Describes a resolved credential with final value and source."]
|
|
46
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Defines the return type for resolved credentials."]
|
|
47
|
+
// CIL[DOC-CONTEXT module="resolve-credentials" layer="shared" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts"]
|
|
48
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="ResolvedCredential type" errors="none" side_effects="none"]
|
|
49
|
+
// CIL[DOC-MICRO logic_summary="Exported interface with value and source fields representing a resolved credential." notable_decisions="[]"]
|
|
50
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
51
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
25
52
|
export interface ResolvedCredential {
|
|
26
53
|
value: string
|
|
27
54
|
source: 'value' | 'env_var'
|
|
28
55
|
}
|
|
56
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Describes a resolved credential with final value and source.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts"]
|
|
57
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
58
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
59
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
60
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
61
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
62
|
+
// CIL[END stable_id="~/.framework/functions/_shared/resolve-credentials.ts:ResolvedCredential:interface"]
|
|
29
63
|
|
|
64
|
+
|
|
65
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/resolve-credentials.ts:resolveCredential:function" type="function" identity="resolveCredential" parent="~/.framework/functions/_shared/resolve-credentials.ts"]
|
|
66
|
+
// CIL[DOC-MACRO purpose="Resolves a single credential from a literal value or an environment variable, validating and auditing the result."]
|
|
67
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Read the credential entry for the given field, validate its configuration, resolve env_var values from process.env, audit each outcome, and return the resolved credential."]
|
|
68
|
+
// CIL[DOC-CONTEXT module="resolve-credentials" layer="shared" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts"]
|
|
69
|
+
// CIL[DOC-CONTRACT inputs="ctx: CoreContext, integration: any, fieldName: string" outputs="ResolvedCredential" errors="Missing credential configuration, missing environment variable, empty credential value" side_effects="Emits audit log events via emitLog"]
|
|
70
|
+
// CIL[DOC-MICRO logic_summary="Extracts the credential entry from integration.credentials; validates that source and value are present; for env_var reads process.env and throws if unset; for literal value throws if empty; audits resolution and returns the resolved credential." notable_decisions="[\"Environment variables are read from process.env\",\"Credential source is either 'value' or 'env_var'\"]"]
|
|
71
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
72
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
30
73
|
export async function resolveCredential(
|
|
31
74
|
ctx: CoreContext,
|
|
32
75
|
integration: any,
|
|
@@ -56,7 +99,10 @@ export async function resolveCredential(
|
|
|
56
99
|
throw new Error(`Environment variable ${entry.value} for ${fieldName} is not set`)
|
|
57
100
|
}
|
|
58
101
|
|
|
59
|
-
|
|
102
|
+
// Success audit is fire-and-forget — the resolved credential is already
|
|
103
|
+
// in hand and the outbound call shouldn't wait on a logs insert. Failure
|
|
104
|
+
// paths above stay awaited so the audit row is durable before the throw.
|
|
105
|
+
void emitLog(ctx, 'integration.credential_resolved', { type: 'integration', id: integration?.id }, undefined, {
|
|
60
106
|
field: fieldName,
|
|
61
107
|
source: 'env_var',
|
|
62
108
|
env_var: entry.value,
|
|
@@ -77,7 +123,7 @@ export async function resolveCredential(
|
|
|
77
123
|
throw new Error(`Credential ${fieldName} on integration ${integration?.id} is empty`)
|
|
78
124
|
}
|
|
79
125
|
|
|
80
|
-
|
|
126
|
+
void emitLog(ctx, 'integration.credential_resolved', { type: 'integration', id: integration?.id }, undefined, {
|
|
81
127
|
field: fieldName,
|
|
82
128
|
source: 'value',
|
|
83
129
|
integration_id: integration?.id,
|
|
@@ -86,7 +132,23 @@ export async function resolveCredential(
|
|
|
86
132
|
|
|
87
133
|
return { value: entry.value, source: 'value' }
|
|
88
134
|
}
|
|
135
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Resolves a single credential from a literal value or an environment variable, validating and auditing the result.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts"]
|
|
136
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
137
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
138
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
139
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
140
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
141
|
+
// CIL[END stable_id="~/.framework/functions/_shared/resolve-credentials.ts:resolveCredential:function"]
|
|
142
|
+
|
|
89
143
|
|
|
144
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/resolve-credentials.ts:resolveCredentials:function" type="function" identity="resolveCredentials" parent="~/.framework/functions/_shared/resolve-credentials.ts"]
|
|
145
|
+
// CIL[DOC-MACRO purpose="Resolves multiple credentials for a list of field names."]
|
|
146
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Iterates the requested field names and resolves each one via resolveCredential, accumulating the results."]
|
|
147
|
+
// CIL[DOC-CONTEXT module="resolve-credentials" layer="shared" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts"]
|
|
148
|
+
// CIL[DOC-CONTRACT inputs="ctx: CoreContext, integration: any, fieldNames: string[]" outputs="Record<string, ResolvedCredential>" errors="Propagates any error thrown by resolveCredential" side_effects="none"]
|
|
149
|
+
// CIL[DOC-MICRO logic_summary="Loops over fieldNames, awaits resolveCredential for each, and stores results in a record keyed by field name." notable_decisions="[]"]
|
|
150
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
151
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
90
152
|
export async function resolveCredentials(
|
|
91
153
|
ctx: CoreContext,
|
|
92
154
|
integration: any,
|
|
@@ -98,5 +160,10 @@ export async function resolveCredentials(
|
|
|
98
160
|
}
|
|
99
161
|
return result
|
|
100
162
|
}
|
|
101
|
-
|
|
102
|
-
// CIL[
|
|
163
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Resolves multiple credentials for a list of field names.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts"]
|
|
164
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
165
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
166
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
167
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
168
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
169
|
+
// CIL[END stable_id="~/.framework/functions/_shared/resolve-credentials.ts:resolveCredentials:function"]
|