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,18 +1,12 @@
|
|
|
1
|
-
// CIL[BEGIN
|
|
2
|
-
// CIL[DOC-MACRO purpose="
|
|
3
|
-
// CIL[DOC-RESPONSIBILITY responsibility="
|
|
4
|
-
// CIL[DOC-CONTEXT module="integration-outbound" layer="
|
|
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
|
-
// CIL[DOC-VECTOR type="context" content="Layer: backend_functions. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/resolve-credentials.ts, .framework/functions/admin-data.ts, .framework/functions/_shared/audit.ts, .framework/functions/_shared/pipeline-runner.ts, .framework/migrations/051_integration_broker.sql."]
|
|
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="Requires integration.slug and a credential field."]
|
|
14
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="Called as a pipeline action or directly via /.netlify/functions/integration-outbound."]
|
|
15
|
-
// CIL[DOC-VECTOR type="user_journey" content="Spine calls an external service through the broker."]
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/functions/integration-outbound.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/integration-outbound.ts"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Module header: imports and adapter registration for outbound integration delivery"]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declares dependencies for the outbound integration handler and built-in adapter map"]
|
|
4
|
+
// CIL[DOC-CONTEXT module="integration-outbound" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts,.framework/functions/adapters/generic-webhook-outbound.ts,.framework/functions/adapters/openai-outbound.ts,.framework/functions/admin-data.ts"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="N/A" outputs="N/A" errors="N/A" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Imports shared middleware, database, audit, credential resolution, admin-data and built-in outbound adapters." notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
8
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="internal engineers"]
|
|
16
10
|
|
|
17
11
|
import { createHandler, CoreContext } from './_shared/middleware'
|
|
18
12
|
import { adminDb } from './_shared/db'
|
|
@@ -21,7 +15,22 @@ import { resolveCredential } from './_shared/resolve-credentials'
|
|
|
21
15
|
import { get as adminDataGet, update as adminDataUpdate } from './admin-data'
|
|
22
16
|
import * as openaiOutbound from './adapters/openai-outbound'
|
|
23
17
|
import * as genericWebhookOutbound from './adapters/generic-webhook-outbound'
|
|
24
|
-
|
|
18
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Module header: imports and adapter registration for outbound integration delivery'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
|
|
19
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
20
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
21
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
22
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
23
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
24
|
+
// CIL[END stable_id="~/.framework/functions/integration-outbound.ts:module_header:module_header"]
|
|
25
|
+
|
|
26
|
+
// CIL[BEGIN stable_id="~/.framework/functions/integration-outbound.ts:OutboundRequest:interface" type="interface" identity="OutboundRequest" parent="~/.framework/functions/integration-outbound.ts"]
|
|
27
|
+
// CIL[DOC-MACRO purpose="Shape of an outbound HTTP request produced by an adapter"]
|
|
28
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Defines the contract between adapters and the outbound executor"]
|
|
29
|
+
// CIL[DOC-CONTEXT module="integration-outbound" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts,.framework/functions/adapters/generic-webhook-outbound.ts,.framework/functions/adapters/openai-outbound.ts,.framework/functions/admin-data.ts,.framework/functions/integration-outbound.ts"]
|
|
30
|
+
// CIL[DOC-CONTRACT inputs="N/A" outputs="an OutboundRequest with url, method, optional headers, body and external_id" errors="N/A" side_effects="none"]
|
|
31
|
+
// CIL[DOC-MICRO logic_summary="Describes the fields required for a single outbound HTTP call." notable_decisions="[]"]
|
|
32
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
33
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
25
34
|
interface OutboundRequest {
|
|
26
35
|
url: string
|
|
27
36
|
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
|
|
@@ -29,7 +38,22 @@ interface OutboundRequest {
|
|
|
29
38
|
body?: any
|
|
30
39
|
external_id?: string
|
|
31
40
|
}
|
|
32
|
-
|
|
41
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Shape of an outbound HTTP request produced by an adapter'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
|
|
42
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
43
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
44
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
45
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
46
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
47
|
+
// CIL[END stable_id="~/.framework/functions/integration-outbound.ts:OutboundRequest:interface"]
|
|
48
|
+
|
|
49
|
+
// CIL[BEGIN stable_id="~/.framework/functions/integration-outbound.ts:OutboundAdapterContext:interface" type="interface" identity="OutboundAdapterContext" parent="~/.framework/functions/integration-outbound.ts"]
|
|
50
|
+
// CIL[DOC-MACRO purpose="Context object passed to outbound adapters when building a request"]
|
|
51
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Encapsulates record, integration, resolved credential and runtime identifiers for adapter use"]
|
|
52
|
+
// CIL[DOC-CONTEXT module="integration-outbound" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts,.framework/functions/adapters/generic-webhook-outbound.ts,.framework/functions/adapters/openai-outbound.ts,.framework/functions/admin-data.ts,.framework/functions/integration-outbound.ts"]
|
|
53
|
+
// CIL[DOC-CONTRACT inputs="N/A" outputs="an OutboundAdapterContext with record, integration, apiKey, accountId, appId and actionConfig" errors="N/A" side_effects="none"]
|
|
54
|
+
// CIL[DOC-MICRO logic_summary="Provides adapters with all runtime data needed to construct a request." notable_decisions="[]"]
|
|
55
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
56
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
33
57
|
interface OutboundAdapterContext {
|
|
34
58
|
record: any
|
|
35
59
|
integration: any
|
|
@@ -38,17 +62,48 @@ interface OutboundAdapterContext {
|
|
|
38
62
|
appId: string | null
|
|
39
63
|
actionConfig: any
|
|
40
64
|
}
|
|
41
|
-
|
|
65
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Context object passed to outbound adapters when building a request'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
|
|
66
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
67
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
68
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
69
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
70
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
71
|
+
// CIL[END stable_id="~/.framework/functions/integration-outbound.ts:OutboundAdapterContext:interface"]
|
|
72
|
+
|
|
73
|
+
// CIL[BEGIN stable_id="~/.framework/functions/integration-outbound.ts:computeNextAttempt:function" type="function" identity="computeNextAttempt" parent="~/.framework/functions/integration-outbound.ts"]
|
|
74
|
+
// CIL[DOC-MACRO purpose="Compute the next retry timestamp for a failed outbound delivery"]
|
|
75
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Calculate exponential backoff with jitter for delivery retries"]
|
|
76
|
+
// CIL[DOC-CONTEXT module="integration-outbound" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts,.framework/functions/adapters/generic-webhook-outbound.ts,.framework/functions/adapters/openai-outbound.ts,.framework/functions/admin-data.ts,.framework/functions/integration-outbound.ts"]
|
|
77
|
+
// CIL[DOC-CONTRACT inputs="attemptCount: number, baseMs: number = 30000, maxDelayMs: number = 3600000" outputs="Date representing the next retry time" errors="none" side_effects="none"]
|
|
78
|
+
// CIL[DOC-MICRO logic_summary="Uses exponential backoff capped by maxDelayMs and adds up to 20% jitter." notable_decisions="[]"]
|
|
79
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
80
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
42
81
|
function computeNextAttempt(attemptCount: number, baseMs = 30000, maxDelayMs = 3600000): Date {
|
|
43
82
|
const delay = Math.min(baseMs * Math.pow(2, attemptCount), maxDelayMs)
|
|
44
83
|
const jitter = Math.floor(Math.random() * delay * 0.2)
|
|
45
84
|
return new Date(Date.now() + delay + jitter)
|
|
46
85
|
}
|
|
47
|
-
|
|
86
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Compute the next retry timestamp for a failed outbound delivery'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
|
|
87
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
88
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
89
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
90
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
91
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
92
|
+
// CIL[END stable_id="~/.framework/functions/integration-outbound.ts:computeNextAttempt:function"]
|
|
93
|
+
|
|
94
|
+
// CIL[BEGIN stable_id="~/.framework/functions/integration-outbound.ts:execute:function" type="function" identity="execute" parent="~/.framework/functions/integration-outbound.ts"]
|
|
95
|
+
// CIL[DOC-MACRO purpose="Execute an outbound integration webhook request with retries and audit logging"]
|
|
96
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Resolve the integration, build an outbound request, call the target, and persist delivery status"]
|
|
97
|
+
// CIL[DOC-CONTEXT module="integration-outbound" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts,.framework/functions/adapters/generic-webhook-outbound.ts,.framework/functions/adapters/openai-outbound.ts,.framework/functions/admin-data.ts,.framework/functions/integration-outbound.ts"]
|
|
98
|
+
// CIL[DOC-CONTRACT inputs="ctx: CoreContext, body: any = {}" outputs="object { success, delivery_id, response_status, response_body, is_retry }" errors="Throws if delivery not found, integration_slug missing or integration not found, adapter missing, request invalid, HTTP non-success, or delivery record update fails" side_effects="Inserts or updates webhook_deliveries, emits audit logs, calls an external HTTP endpoint, and optionally updates the source record"]
|
|
99
|
+
// CIL[DOC-MICRO logic_summary="Resolves tenant or system integration, creates or reuses a delivery record, loads the configured adapter, builds and executes the HTTP request, updates delivery status, and optionally writes the record." notable_decisions="[]"]
|
|
100
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
101
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
48
102
|
export async function execute(ctx: CoreContext, body: any = {}): Promise<any> {
|
|
49
103
|
let deliveryId = body?.delivery_id
|
|
50
104
|
let requestBody = body
|
|
51
105
|
let isRetry = false
|
|
106
|
+
let retryDelivery: any = null
|
|
52
107
|
|
|
53
108
|
if (deliveryId && ctx.principal?.isInternal) {
|
|
54
109
|
const { data: delivery, error: deliveryError } = await adminDb
|
|
@@ -61,6 +116,7 @@ export async function execute(ctx: CoreContext, body: any = {}): Promise<any> {
|
|
|
61
116
|
throw new Error(`Delivery not found: ${deliveryId}`)
|
|
62
117
|
}
|
|
63
118
|
|
|
119
|
+
retryDelivery = delivery
|
|
64
120
|
requestBody = delivery.payload || {}
|
|
65
121
|
isRetry = true
|
|
66
122
|
|
|
@@ -110,7 +166,20 @@ export async function execute(ctx: CoreContext, body: any = {}): Promise<any> {
|
|
|
110
166
|
record = await adminDataGet(getCtx)
|
|
111
167
|
}
|
|
112
168
|
|
|
169
|
+
const logStarted = (id: string) =>
|
|
170
|
+
emitLog(ctx, 'integration.outbound.started', { type: 'integration', id: integration.id }, undefined, {
|
|
171
|
+
delivery_id: id,
|
|
172
|
+
integration_id: integration.id,
|
|
173
|
+
record_id,
|
|
174
|
+
account_id: ctx.accountId,
|
|
175
|
+
is_retry: isRetry
|
|
176
|
+
}).catch(err => console.error('emitLog integration.outbound.started failed:', err))
|
|
177
|
+
|
|
113
178
|
let deliveryPayload: any
|
|
179
|
+
// The delivery INSERT runs concurrently with the outbound request — the
|
|
180
|
+
// wire call dominates latency, so tracking no longer serializes ahead of
|
|
181
|
+
// it. insertPromise is awaited before any delivery update.
|
|
182
|
+
let insertPromise: Promise<string> | null = null
|
|
114
183
|
if (!deliveryId) {
|
|
115
184
|
deliveryPayload = {
|
|
116
185
|
direction: 'outbound',
|
|
@@ -127,32 +196,27 @@ export async function execute(ctx: CoreContext, body: any = {}): Promise<any> {
|
|
|
127
196
|
updated_at: new Date().toISOString()
|
|
128
197
|
}
|
|
129
198
|
|
|
130
|
-
|
|
199
|
+
insertPromise = adminDb
|
|
131
200
|
.from('webhook_deliveries')
|
|
132
201
|
.insert(deliveryPayload)
|
|
133
202
|
.select('id')
|
|
134
203
|
.single()
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
204
|
+
.then(({ data: deliveryRow, error: deliveryInsertError }) => {
|
|
205
|
+
if (deliveryInsertError || !deliveryRow) {
|
|
206
|
+
throw new Error('Failed to create outbound delivery record')
|
|
207
|
+
}
|
|
208
|
+
void logStarted(deliveryRow.id)
|
|
209
|
+
return deliveryRow.id as string
|
|
210
|
+
})
|
|
211
|
+
insertPromise.catch(() => {}) // rejection is surfaced where it is awaited
|
|
141
212
|
} else {
|
|
142
213
|
await adminDb
|
|
143
214
|
.from('webhook_deliveries')
|
|
144
215
|
.update({ status: 'processing', updated_at: new Date().toISOString() })
|
|
145
216
|
.eq('id', deliveryId)
|
|
217
|
+
void logStarted(deliveryId)
|
|
146
218
|
}
|
|
147
219
|
|
|
148
|
-
await emitLog(ctx, 'integration.outbound.started', { type: 'integration', id: integration.id }, undefined, {
|
|
149
|
-
delivery_id: deliveryId,
|
|
150
|
-
integration_id: integration.id,
|
|
151
|
-
record_id,
|
|
152
|
-
account_id: ctx.accountId,
|
|
153
|
-
is_retry: isRetry
|
|
154
|
-
})
|
|
155
|
-
|
|
156
220
|
try {
|
|
157
221
|
const credentialField = action_config.credential_field || 'api_token'
|
|
158
222
|
const resolved = await resolveCredential(ctx, integration, credentialField)
|
|
@@ -201,18 +265,18 @@ export async function execute(ctx: CoreContext, body: any = {}): Promise<any> {
|
|
|
201
265
|
|
|
202
266
|
const success = response.ok
|
|
203
267
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
const attemptCount = (
|
|
268
|
+
// The tracking insert overlapped the wire call — resolve it now for the
|
|
269
|
+
// status update. attempt_count is derived locally (fresh inserts start
|
|
270
|
+
// at 0, retries carry their count from the row loaded above), so no
|
|
271
|
+
// extra SELECT is needed.
|
|
272
|
+
if (!deliveryId && insertPromise) deliveryId = await insertPromise
|
|
273
|
+
const maxAttempts = deliveryPayload?.max_attempts ?? retryDelivery?.max_attempts ?? 3
|
|
274
|
+
const attemptCount = (isRetry ? retryDelivery?.attempt_count : 0) + 1
|
|
211
275
|
|
|
212
276
|
await adminDb
|
|
213
277
|
.from('webhook_deliveries')
|
|
214
278
|
.update({
|
|
215
|
-
status: success ? 'delivered' : (attemptCount >=
|
|
279
|
+
status: success ? 'delivered' : (attemptCount >= maxAttempts ? 'failed' : 'pending'),
|
|
216
280
|
attempt_count: attemptCount,
|
|
217
281
|
next_attempt_at: success ? null : computeNextAttempt(attemptCount).toISOString(),
|
|
218
282
|
response_status: response.status,
|
|
@@ -222,14 +286,14 @@ export async function execute(ctx: CoreContext, body: any = {}): Promise<any> {
|
|
|
222
286
|
})
|
|
223
287
|
.eq('id', deliveryId)
|
|
224
288
|
|
|
225
|
-
|
|
289
|
+
void emitLog(ctx, success ? 'integration.outbound.succeeded' : 'integration.outbound.failed_http', { type: 'integration', id: integration.id }, undefined, {
|
|
226
290
|
delivery_id: deliveryId,
|
|
227
291
|
integration_id: integration.id,
|
|
228
292
|
response_status: response.status,
|
|
229
293
|
duration_ms: durationMs,
|
|
230
294
|
account_id: ctx.accountId,
|
|
231
295
|
is_retry: isRetry
|
|
232
|
-
})
|
|
296
|
+
}).catch(err => console.error('emitLog integration.outbound result failed:', err))
|
|
233
297
|
|
|
234
298
|
if (success && action_config.update_record && record_id) {
|
|
235
299
|
await adminDataUpdate({ ...ctx, query: { entity: 'items', id: record_id } } as any, {
|
|
@@ -255,43 +319,73 @@ export async function execute(ctx: CoreContext, body: any = {}): Promise<any> {
|
|
|
255
319
|
is_retry: isRetry
|
|
256
320
|
}
|
|
257
321
|
} catch (err: any) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
322
|
+
// Resolve the overlapped tracking insert — if it failed there is no
|
|
323
|
+
// delivery row to update, so skip the bookkeeping and rethrow.
|
|
324
|
+
if (!deliveryId && insertPromise) deliveryId = await insertPromise.catch(() => null)
|
|
325
|
+
if (deliveryId) {
|
|
326
|
+
const maxAttempts = deliveryPayload?.max_attempts ?? retryDelivery?.max_attempts ?? 3
|
|
327
|
+
const attemptCount = (isRetry ? retryDelivery?.attempt_count : 0) + 1
|
|
328
|
+
const shouldRetry = attemptCount < maxAttempts
|
|
329
|
+
|
|
330
|
+
await adminDb
|
|
331
|
+
.from('webhook_deliveries')
|
|
332
|
+
.update({
|
|
333
|
+
status: shouldRetry ? 'pending' : 'failed',
|
|
334
|
+
attempt_count: attemptCount,
|
|
335
|
+
next_attempt_at: shouldRetry ? computeNextAttempt(attemptCount).toISOString() : null,
|
|
336
|
+
last_error: err.message || String(err),
|
|
337
|
+
updated_at: new Date().toISOString()
|
|
338
|
+
})
|
|
339
|
+
.eq('id', deliveryId)
|
|
340
|
+
|
|
341
|
+
void emitLog(ctx, 'integration.outbound.error', { type: 'integration', id: integration.id }, undefined, {
|
|
342
|
+
delivery_id: deliveryId,
|
|
343
|
+
integration_id: integration.id,
|
|
344
|
+
error: err.message || String(err),
|
|
345
|
+
account_id: ctx.accountId,
|
|
346
|
+
is_retry: isRetry
|
|
347
|
+
}).catch(logErr => console.error('emitLog integration.outbound.error failed:', logErr))
|
|
348
|
+
}
|
|
285
349
|
|
|
286
350
|
throw err
|
|
287
351
|
}
|
|
288
352
|
}
|
|
289
|
-
|
|
353
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Execute an outbound integration webhook request with retries and audit logging'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
|
|
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/functions/integration-outbound.ts:execute:function"]
|
|
360
|
+
|
|
361
|
+
// CIL[BEGIN stable_id="~/.framework/functions/integration-outbound.ts:builtInOutboundAdapters:constant" type="constant" identity="builtInOutboundAdapters" parent="~/.framework/functions/integration-outbound.ts"]
|
|
362
|
+
// CIL[DOC-MACRO purpose="Registry of built-in outbound adapter modules"]
|
|
363
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Map adapter paths to their module exports"]
|
|
364
|
+
// CIL[DOC-CONTEXT module="integration-outbound" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts,.framework/functions/adapters/generic-webhook-outbound.ts,.framework/functions/adapters/openai-outbound.ts,.framework/functions/admin-data.ts,.framework/functions/integration-outbound.ts"]
|
|
365
|
+
// CIL[DOC-CONTRACT inputs="N/A" outputs="Record<string, any> of built-in adapters" errors="N/A" side_effects="none"]
|
|
366
|
+
// CIL[DOC-MICRO logic_summary="Lists the openai and generic webhook outbound adapter modules." notable_decisions="[]"]
|
|
367
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
368
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
290
369
|
const builtInOutboundAdapters: Record<string, any> = {
|
|
291
370
|
'adapters/openai-outbound': openaiOutbound,
|
|
292
371
|
'adapters/generic-webhook-outbound': genericWebhookOutbound
|
|
293
372
|
}
|
|
294
|
-
|
|
373
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Registry of built-in outbound adapter modules'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
|
|
374
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
375
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
376
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
377
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
378
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
379
|
+
// CIL[END stable_id="~/.framework/functions/integration-outbound.ts:builtInOutboundAdapters:constant"]
|
|
380
|
+
|
|
381
|
+
// CIL[BEGIN stable_id="~/.framework/functions/integration-outbound.ts:loadOutboundAdapter:function" type="function" identity="loadOutboundAdapter" parent="~/.framework/functions/integration-outbound.ts"]
|
|
382
|
+
// CIL[DOC-MACRO purpose="Load an outbound adapter by name from built-ins or dynamic imports"]
|
|
383
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Resolve and return an adapter module that exposes buildRequest"]
|
|
384
|
+
// CIL[DOC-CONTEXT module="integration-outbound" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts,.framework/functions/adapters/generic-webhook-outbound.ts,.framework/functions/adapters/openai-outbound.ts,.framework/functions/admin-data.ts,.framework/functions/integration-outbound.ts"]
|
|
385
|
+
// CIL[DOC-CONTRACT inputs="functionName: string" outputs="adapter module or null" errors="Returns null on import or validation failure" side_effects="Logs a console error on import failure"]
|
|
386
|
+
// CIL[DOC-MICRO logic_summary="Checks built-in registry first, then dynamically imports the requested adapter and verifies buildRequest exists." notable_decisions="[]"]
|
|
387
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
388
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
295
389
|
async function loadOutboundAdapter(functionName: string): Promise<any | null> {
|
|
296
390
|
if (builtInOutboundAdapters[functionName]) {
|
|
297
391
|
return builtInOutboundAdapters[functionName]
|
|
@@ -304,8 +398,44 @@ async function loadOutboundAdapter(functionName: string): Promise<any | null> {
|
|
|
304
398
|
return null
|
|
305
399
|
}
|
|
306
400
|
}
|
|
307
|
-
|
|
401
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Load an outbound adapter by name from built-ins or dynamic imports'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
|
|
402
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
403
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
404
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
405
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
406
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
407
|
+
// CIL[END stable_id="~/.framework/functions/integration-outbound.ts:loadOutboundAdapter:function"]
|
|
408
|
+
|
|
409
|
+
// CIL[BEGIN stable_id="~/.framework/functions/integration-outbound.ts:integrationOutbound:constant" type="constant" identity="integrationOutbound" parent="~/.framework/functions/integration-outbound.ts"]
|
|
410
|
+
// CIL[DOC-MACRO purpose="Handler binding for the outbound integration execute function"]
|
|
411
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Wrap execute in the shared middleware handler"]
|
|
412
|
+
// CIL[DOC-CONTEXT module="integration-outbound" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts,.framework/functions/adapters/generic-webhook-outbound.ts,.framework/functions/adapters/openai-outbound.ts,.framework/functions/admin-data.ts,.framework/functions/integration-outbound.ts"]
|
|
413
|
+
// CIL[DOC-CONTRACT inputs="N/A" outputs="createHandler(execute) result" errors="N/A" side_effects="none"]
|
|
414
|
+
// CIL[DOC-MICRO logic_summary="Creates the middleware-backed handler from the execute function." notable_decisions="[]"]
|
|
415
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
416
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
308
417
|
const integrationOutbound = createHandler(execute)
|
|
418
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Handler binding for the outbound integration execute function'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
|
|
419
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
420
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
421
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
422
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
423
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
424
|
+
// CIL[END stable_id="~/.framework/functions/integration-outbound.ts:integrationOutbound:constant"]
|
|
425
|
+
// CIL[BEGIN stable_id="~/.framework/functions/integration-outbound.ts:default:function" type="function" identity="default" parent="~/.framework/functions/integration-outbound.ts"]
|
|
426
|
+
// CIL[DOC-MACRO purpose="Default export of the integration outbound handler"]
|
|
427
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Export integrationOutbound as the module default"]
|
|
428
|
+
// CIL[DOC-CONTEXT module="integration-outbound" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts,.framework/functions/adapters/generic-webhook-outbound.ts,.framework/functions/adapters/openai-outbound.ts,.framework/functions/admin-data.ts,.framework/functions/integration-outbound.ts"]
|
|
429
|
+
// CIL[DOC-CONTRACT inputs="N/A" outputs="integrationOutbound handler" errors="N/A" side_effects="none"]
|
|
430
|
+
// CIL[DOC-MICRO logic_summary="Exports the prebuilt handler as the module default for serverless entry points." notable_decisions="[]"]
|
|
431
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
432
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
309
433
|
export default integrationOutbound
|
|
434
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Default export of the integration outbound handler'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
|
|
435
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
436
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
437
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
438
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
439
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
440
|
+
// CIL[END stable_id="~/.framework/functions/integration-outbound.ts:default:function"]
|
|
310
441
|
|
|
311
|
-
// CIL[END chunk_id="integration_outbound_module_header_1784200004"]
|