spine-framework 0.3.145 → 0.4.1
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 +5067 -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
package/custom/README.md
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# Spine Framework Custom Workspace
|
|
2
|
-
|
|
3
|
-
This directory is your extension workspace for the Spine Framework. Customize your instance here without modifying the core framework code.
|
|
4
|
-
|
|
5
|
-
## Directory Structure
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
custom/
|
|
9
|
-
├── apps/ # Custom apps extending Spine
|
|
10
|
-
│ ├── cortex/ # AI-powered support & CRM
|
|
11
|
-
│ ├── portal/ # Customer portal & courses
|
|
12
|
-
│ └── your-app/ # Your custom app
|
|
13
|
-
├── components/ # Shared React components
|
|
14
|
-
├── functions/ # Edge functions (Netlify/Vercel)
|
|
15
|
-
├── migrations/ # Database migrations
|
|
16
|
-
├── npm/ # Local npm packages
|
|
17
|
-
├── tests/ # Custom tests
|
|
18
|
-
└── .devin/ # Devin workflows & skills
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Getting Started
|
|
22
|
-
|
|
23
|
-
### 1. Install an App
|
|
24
|
-
|
|
25
|
-
Use the Devin skill to install an app:
|
|
26
|
-
```
|
|
27
|
-
Install the cortex app
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Or manually copy an app package to `custom/apps/`.
|
|
31
|
-
|
|
32
|
-
### 2. Apply Seed Data
|
|
33
|
-
|
|
34
|
-
Seed data defines types, roles, and configuration:
|
|
35
|
-
```bash
|
|
36
|
-
npm run seed -- --app=cortex
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### 3. Start Development
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
npm run dev
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Creating Custom Apps
|
|
46
|
-
|
|
47
|
-
1. Create `custom/apps/my-app/` with:
|
|
48
|
-
- `index.tsx` - App entry point
|
|
49
|
-
- `manifest.json` - App configuration
|
|
50
|
-
- `seed/types.json` - Custom types
|
|
51
|
-
- `seed/roles.json` - Custom roles
|
|
52
|
-
- `pages/` - Page components
|
|
53
|
-
- `components/` - App-specific components
|
|
54
|
-
|
|
55
|
-
2. Add navigation items in `manifest.json`
|
|
56
|
-
|
|
57
|
-
3. Restart the dev server
|
|
58
|
-
|
|
59
|
-
## Database Migrations
|
|
60
|
-
|
|
61
|
-
Place custom migrations in `custom/migrations/`:
|
|
62
|
-
```
|
|
63
|
-
custom/migrations/001_add_custom_table.sql
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
Migrations are applied automatically on startup.
|
|
67
|
-
|
|
68
|
-
## Best Practices
|
|
69
|
-
|
|
70
|
-
- **Never modify `.framework/`** - Use this `custom/` directory instead
|
|
71
|
-
- **Keep apps self-contained** - Each app should have its own seed data
|
|
72
|
-
- **Use the CLI** - `spine-cli` helps manage apps and migrations
|
|
73
|
-
- **Test in isolation** - Apps should work standalone
|
|
74
|
-
|
|
75
|
-
## Support
|
|
76
|
-
|
|
77
|
-
- Framework docs: `.framework/docs/`
|
|
78
|
-
- Devin skills: `custom/.devin/skills/`
|
|
79
|
-
- Community: https://github.com/spine-framework/spine
|
package/docs/README.md
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# Documentation
|
|
2
|
-
|
|
3
|
-
This directory contains the documentation for the Spine framework.
|
|
4
|
-
|
|
5
|
-
## Current documentation
|
|
6
|
-
|
|
7
|
-
The canonical, up-to-date documentation lives in [`spine-framework-documentation/`](./spine-framework-documentation/README.md).
|
|
8
|
-
|
|
9
|
-
- [`spine-framework-documentation/start-here.md`](./spine-framework-documentation/start-here.md) — find the right doc for your task.
|
|
10
|
-
- [`spine-framework-documentation/quickstart.md`](./spine-framework-documentation/quickstart.md) — get a Spine project running locally.
|
|
11
|
-
- [`spine-framework-documentation/concepts/spine-way.md`](./spine-framework-documentation/concepts/spine-way.md) — the ten fundamentals every extension must satisfy.
|
|
12
|
-
|
|
13
|
-
## Archived documentation
|
|
14
|
-
|
|
15
|
-
Older documentation has been moved to [`archive/2026-07-28/`](./archive/2026-07-28/) and is kept for reference only. If a conflict exists between the new tree and an archived document, the new tree wins.
|
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @module scripts/app-install-cli
|
|
5
|
-
* @audience installer
|
|
6
|
-
* @layer cli
|
|
7
|
-
* @stability orphaned
|
|
8
|
-
*
|
|
9
|
-
* Spine App Installation CLI - Validates and executes app installation instruction files.
|
|
10
|
-
* **ORPHANED**: References non-existent schema and template files at `../docs/app-installation/`.
|
|
11
|
-
*
|
|
12
|
-
* **Intended Purpose**: Validate YAML instruction files against JSON schema and execute
|
|
13
|
-
* multi-step app installations (pack installation, app creation, migrations, verification).
|
|
14
|
-
*
|
|
15
|
-
* **Current State**: Cannot function - missing required schema.json and template files.
|
|
16
|
-
*
|
|
17
|
-
* **Dependencies**: commander, js-yaml, ajv for CLI operations and validation.
|
|
18
|
-
*
|
|
19
|
-
* @tags orphaned, cli, app-installation, validation
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import { readFileSync, existsSync, writeFileSync } from 'fs'
|
|
23
|
-
import { resolve, dirname } from 'path'
|
|
24
|
-
import { program } from 'commander'
|
|
25
|
-
import yaml from 'js-yaml'
|
|
26
|
-
import Ajv from 'ajv'
|
|
27
|
-
import { fileURLToPath } from 'url'
|
|
28
|
-
|
|
29
|
-
// Fix __dirname for ES modules
|
|
30
|
-
const __filename = fileURLToPath(import.meta.url)
|
|
31
|
-
const __dirname = dirname(__filename)
|
|
32
|
-
|
|
33
|
-
// Load JSON schema
|
|
34
|
-
const schemaPath = resolve(__dirname, '../docs/app-installation/schema.json')
|
|
35
|
-
const schema = JSON.parse(readFileSync(schemaPath, 'utf8'))
|
|
36
|
-
|
|
37
|
-
const ajv = new Ajv()
|
|
38
|
-
const validate = ajv.compile(schema)
|
|
39
|
-
|
|
40
|
-
interface InstallationContext {
|
|
41
|
-
TARGET_ACCOUNT_ID?: string
|
|
42
|
-
PACK_INSTALLATION_ID?: string
|
|
43
|
-
[key: string]: string | undefined
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// ─── CHUNK_START: APP_INSTALL_CLI_SUBSTITUTE_VARIABLES ──────────────────────────────────────────────
|
|
47
|
-
/**
|
|
48
|
-
* @chunk-id APP_INSTALL_CLI_SUBSTITUTE_VARIABLES_1_0_0
|
|
49
|
-
* @version 1.0.0
|
|
50
|
-
* @hash 122ca9e63f2310e8a01f76dc9c962319d8e267d8737c39895425440489a747bd
|
|
51
|
-
* @macro Variable Substitution Engine
|
|
52
|
-
* @micro Recursively replaces ${VAR} placeholders with context values
|
|
53
|
-
* @inputs obj: any — Object containing ${VAR} placeholders
|
|
54
|
-
* @inputs context: InstallationContext — Variable name to value mapping
|
|
55
|
-
* @outputs any — Object with all placeholders substituted
|
|
56
|
-
* @depends-on [none]
|
|
57
|
-
* @depended-by [validateInstructionFile, executeInstallation]
|
|
58
|
-
* @side-effects [none]
|
|
59
|
-
* @tags orphaned, variable-substitution, template-engine
|
|
60
|
-
*/
|
|
61
|
-
function substituteVariables(obj: any, context: InstallationContext): any {
|
|
62
|
-
if (typeof obj === 'string') {
|
|
63
|
-
return obj.replace(/\$\{([^}]+)\}/g, (match, varName) => {
|
|
64
|
-
return context[varName] || match
|
|
65
|
-
})
|
|
66
|
-
} else if (Array.isArray(obj)) {
|
|
67
|
-
return obj.map(item => substituteVariables(item, context))
|
|
68
|
-
} else if (obj && typeof obj === 'object') {
|
|
69
|
-
const result: any = {}
|
|
70
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
71
|
-
result[key] = substituteVariables(value, context)
|
|
72
|
-
}
|
|
73
|
-
return result
|
|
74
|
-
}
|
|
75
|
-
return obj
|
|
76
|
-
}
|
|
77
|
-
// ─── CHUNK_END: APP_INSTALL_CLI_SUBSTITUTE_VARIABLES ────────────────────────────────────────────────
|
|
78
|
-
|
|
79
|
-
// ─── CHUNK_START: APP_INSTALL_CLI_VALIDATE_INSTRUCTION_FILE ──────────────────────────────────────────────
|
|
80
|
-
/**
|
|
81
|
-
* @chunk-id APP_INSTALL_CLI_VALIDATE_INSTRUCTION_FILE_1_0_0
|
|
82
|
-
* @version 1.0.0
|
|
83
|
-
* @hash c673609fd3442632d832e0c4c3ef2dbda0a51e381bb469e55b7e2cc59005b5e2
|
|
84
|
-
* @macro Installation File Validation
|
|
85
|
-
* @micro Validates YAML instruction files against JSON schema
|
|
86
|
-
* @inputs filePath: string — Path to YAML instruction file
|
|
87
|
-
* @outputs boolean — true if valid, false otherwise
|
|
88
|
-
* @depends-on [schema, validate, substituteVariables]
|
|
89
|
-
* @depended-by [executeInstallation]
|
|
90
|
-
* @side-effects [console output, file system reads]
|
|
91
|
-
* @tags orphaned, validation, yaml, json-schema
|
|
92
|
-
*/
|
|
93
|
-
async function validateInstructionFile(filePath: string): Promise<void> {
|
|
94
|
-
try {
|
|
95
|
-
console.log(`🔍 Validating ${filePath}...`)
|
|
96
|
-
|
|
97
|
-
if (!existsSync(filePath)) {
|
|
98
|
-
console.error(`❌ File not found: ${filePath}`)
|
|
99
|
-
process.exit(1)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const content = readFileSync(filePath, 'utf8')
|
|
103
|
-
const data = yaml.load(content) as any
|
|
104
|
-
|
|
105
|
-
// Validate against schema
|
|
106
|
-
if (!validate(data)) {
|
|
107
|
-
console.error('❌ Validation failed:')
|
|
108
|
-
console.error(JSON.stringify(validate.errors, null, 2))
|
|
109
|
-
process.exit(1)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
console.log('✅ Schema validation passed')
|
|
113
|
-
} catch (error) {
|
|
114
|
-
console.error(`❌ Error validating ${filePath}:`, error)
|
|
115
|
-
process.exit(1)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
// ─── CHUNK_END: APP_INSTALL_CLI_VALIDATE_INSTRUCTION_FILE ────────────────────────────────────────────────
|
|
119
|
-
|
|
120
|
-
// ─── CHUNK_START: APP_INSTALL_CLI_EXECUTE_INSTALLATION ──────────────────────────────────────────────
|
|
121
|
-
/**
|
|
122
|
-
* @chunk-id APP_INSTALL_CLI_EXECUTE_INSTALLATION_1_0_0
|
|
123
|
-
* @version 1.0.0
|
|
124
|
-
* @hash c84aa57769569e4b00ebde4d8b29b7059e6b0d6e8eb3d82cfa51c15e1451e04a
|
|
125
|
-
* @macro Multi-Step App Installation Executor
|
|
126
|
-
* @micro Orchestrates pack installation, app creation, migrations, and verification
|
|
127
|
-
* @inputs filePath: string — Path to YAML instruction file
|
|
128
|
-
* @inputs options: any — CLI options including accountId
|
|
129
|
-
* @outputs void — Console output only
|
|
130
|
-
* @depends-on [validateInstructionFile, substituteVariables, yaml, fs]
|
|
131
|
-
* @depended-by [CLI program command handler]
|
|
132
|
-
* @side-effects [console output, file system reads, process.exit on failure]
|
|
133
|
-
* @tags orphaned, installation, orchestration, multi-step
|
|
134
|
-
*/
|
|
135
|
-
async function executeInstallation(filePath: string, options: any): Promise<void> {
|
|
136
|
-
try {
|
|
137
|
-
console.log(`🚀 Executing installation from ${filePath}...`)
|
|
138
|
-
|
|
139
|
-
// First validate
|
|
140
|
-
await validateInstructionFile(filePath)
|
|
141
|
-
|
|
142
|
-
const content = readFileSync(filePath, 'utf8')
|
|
143
|
-
const instructions = yaml.load(content) as any
|
|
144
|
-
|
|
145
|
-
// Set up context
|
|
146
|
-
const context: InstallationContext = {
|
|
147
|
-
TARGET_ACCOUNT_ID: options.accountId,
|
|
148
|
-
...instructions.variables
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
console.log('📋 Installation plan:')
|
|
152
|
-
console.log(` App: ${instructions.app.name} v${instructions.app.version}`)
|
|
153
|
-
console.log(` Target Account: ${context.TARGET_ACCOUNT_ID}`)
|
|
154
|
-
console.log()
|
|
155
|
-
|
|
156
|
-
// Step 1: Pack installation
|
|
157
|
-
console.log('📦 Step 1: Installing pack...')
|
|
158
|
-
const packInstall = substituteVariables(instructions.installation.pack_installation, context)
|
|
159
|
-
console.log(' Pack installation config:', JSON.stringify(packInstall, null, 2))
|
|
160
|
-
|
|
161
|
-
// Simulate pack installation - in real implementation, this would call the API
|
|
162
|
-
const packInstallationId = 'simulated-pack-id-' + Date.now()
|
|
163
|
-
context.PACK_INSTALLATION_ID = packInstallationId
|
|
164
|
-
console.log(` ✅ Pack installed with ID: ${packInstallationId}`)
|
|
165
|
-
|
|
166
|
-
// Step 2: App creation
|
|
167
|
-
console.log('⚙️ Step 2: Creating app definitions...')
|
|
168
|
-
if (instructions.installation.app_creation) {
|
|
169
|
-
for (const appDef of instructions.installation.app_creation) {
|
|
170
|
-
const appConfig = substituteVariables(appDef, context)
|
|
171
|
-
console.log(` Creating app: ${appConfig.slug}`)
|
|
172
|
-
console.log(' App config:', JSON.stringify(appConfig, null, 2))
|
|
173
|
-
console.log(` ✅ App ${appConfig.slug} created`)
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Step 3: Migrations
|
|
178
|
-
console.log('🔄 Step 3: Running migrations...')
|
|
179
|
-
if (instructions.installation.migrations) {
|
|
180
|
-
for (const migration of instructions.installation.migrations) {
|
|
181
|
-
console.log(` Running migration: ${migration.file}`)
|
|
182
|
-
console.log(` Description: ${migration.description}`)
|
|
183
|
-
if (migration.dependencies) {
|
|
184
|
-
console.log(` Dependencies: ${migration.dependencies.join(', ')}`)
|
|
185
|
-
}
|
|
186
|
-
console.log(` ✅ Migration completed`)
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Step 4: Verification
|
|
191
|
-
console.log('✅ Step 4: Verifying installation...')
|
|
192
|
-
if (instructions.installation.verification) {
|
|
193
|
-
for (const verification of instructions.installation.verification) {
|
|
194
|
-
console.log(` Verifying: ${verification.check}`)
|
|
195
|
-
if (verification.slug) console.log(` Slug: ${verification.slug}`)
|
|
196
|
-
if (verification.integration_id) console.log(` Integration: ${verification.integration_id}`)
|
|
197
|
-
console.log(` ✅ Verification passed`)
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
console.log()
|
|
202
|
-
console.log('🎉 Installation completed successfully!')
|
|
203
|
-
console.log(`📱 App "${instructions.app.name}" is ready to use`)
|
|
204
|
-
|
|
205
|
-
} catch (error) {
|
|
206
|
-
console.error('❌ Installation failed:', error)
|
|
207
|
-
process.exit(1)
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
// ─── CHUNK_END: APP_INSTALL_CLI_EXECUTE_INSTALLATION ────────────────────────────────────────────────
|
|
211
|
-
|
|
212
|
-
// ─── CHUNK_START: APP_INSTALL_CLI_GENERATE_TEMPLATE ──────────────────────────────────────────────
|
|
213
|
-
/**
|
|
214
|
-
* @chunk-id APP_INSTALL_CLI_GENERATE_TEMPLATE_1_0_0
|
|
215
|
-
* @version 1.0.0
|
|
216
|
-
* @hash 4ea17e0556f329f835cec106f09cb570c9e4ea8a92bc82e5fe9ccf4b5dd52aa9
|
|
217
|
-
* @macro Template Generator
|
|
218
|
-
* @micro Outputs YAML templates for app installations or migrations
|
|
219
|
-
* @inputs type: string — Template type ("app" or "migration")
|
|
220
|
-
* @inputs options: any — CLI options including output file path
|
|
221
|
-
* @outputs void — Console output or file write
|
|
222
|
-
* @depends-on [fs, path]
|
|
223
|
-
* @depended-by [CLI program command handler]
|
|
224
|
-
* @side-effects [console output, file system reads/writes, process.exit on failure]
|
|
225
|
-
* @tags orphaned, template-generation, yaml, cli
|
|
226
|
-
*/
|
|
227
|
-
async function generateTemplate(type: string, options: any): Promise<void> {
|
|
228
|
-
try {
|
|
229
|
-
const templateDir = resolve(__dirname, '../docs/app-installation/templates')
|
|
230
|
-
let templateFile: string
|
|
231
|
-
|
|
232
|
-
switch (type) {
|
|
233
|
-
case 'app':
|
|
234
|
-
templateFile = resolve(templateDir, 'app-install.yaml')
|
|
235
|
-
break
|
|
236
|
-
case 'migration':
|
|
237
|
-
templateFile = resolve(templateDir, 'migration.yaml')
|
|
238
|
-
break
|
|
239
|
-
default:
|
|
240
|
-
console.error('❌ Unknown template type. Use "app" or "migration"')
|
|
241
|
-
process.exit(1)
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
const template = readFileSync(templateFile, 'utf8')
|
|
245
|
-
|
|
246
|
-
if (options.output) {
|
|
247
|
-
writeFileSync(options.output, template)
|
|
248
|
-
console.log(`✅ Template generated: ${options.output}`)
|
|
249
|
-
} else {
|
|
250
|
-
console.log(template)
|
|
251
|
-
}
|
|
252
|
-
} catch (error) {
|
|
253
|
-
console.error('❌ Error generating template:', error)
|
|
254
|
-
process.exit(1)
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
// ─── CHUNK_END: APP_INSTALL_CLI_GENERATE_TEMPLATE ────────────────────────────────────────────────
|
|
258
|
-
|
|
259
|
-
// CLI setup
|
|
260
|
-
program
|
|
261
|
-
.name('app-install-cli')
|
|
262
|
-
.description('Spine App Installation CLI - Validate and execute app installation instructions')
|
|
263
|
-
.version('1.0.0')
|
|
264
|
-
|
|
265
|
-
program
|
|
266
|
-
.command('validate')
|
|
267
|
-
.description('Validate an instruction file against the schema')
|
|
268
|
-
.argument('<file>', 'Instruction file path')
|
|
269
|
-
.action(validateInstructionFile)
|
|
270
|
-
|
|
271
|
-
program
|
|
272
|
-
.command('install')
|
|
273
|
-
.description('Execute app installation from instruction file')
|
|
274
|
-
.argument('<file>', 'Instruction file path')
|
|
275
|
-
.option('-a, --account-id <id>', 'Target account ID')
|
|
276
|
-
.option('-d, --dry-run', 'Simulate installation without making changes')
|
|
277
|
-
.action(executeInstallation)
|
|
278
|
-
|
|
279
|
-
program
|
|
280
|
-
.command('template')
|
|
281
|
-
.description('Generate a new instruction template')
|
|
282
|
-
.argument('<type>', 'Template type: app or migration')
|
|
283
|
-
.option('-o, --output <path>', 'Output file path (optional, prints to stdout)')
|
|
284
|
-
.action(generateTemplate)
|
|
285
|
-
|
|
286
|
-
program.parse()
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @module scripts/check-core-integrity
|
|
5
|
-
* @audience installer
|
|
6
|
-
* @layer build
|
|
7
|
-
* @stability stable
|
|
8
|
-
*
|
|
9
|
-
* V2 Core Integrity Checker - Verify v2-core hasn't been modified.
|
|
10
|
-
*
|
|
11
|
-
* **Purpose**: Check v2-core directory integrity against stored manifest.
|
|
12
|
-
* - Compares current source and functions hashes with stored values
|
|
13
|
-
* - Used to detect unauthorized modifications to core framework
|
|
14
|
-
*
|
|
15
|
-
* **Process**:
|
|
16
|
-
* 1. Check for manifest file existence
|
|
17
|
-
* 2. Calculate current hashes for src and functions
|
|
18
|
-
* 3. Compare with stored manifest values
|
|
19
|
-
* 4. Report any mismatches
|
|
20
|
-
*
|
|
21
|
-
* **Dependencies**: find, sha256sum, .spine-manifest.json
|
|
22
|
-
*
|
|
23
|
-
* @tags build, integrity, verification, v2-core, security
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
set -euo pipefail
|
|
27
|
-
|
|
28
|
-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
29
|
-
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
30
|
-
CORE_DIR="$PROJECT_ROOT/.framework"
|
|
31
|
-
MANIFEST_FILE="$CORE_DIR/.spine-manifest.json"
|
|
32
|
-
|
|
33
|
-
echo "Checking .framework integrity..."
|
|
34
|
-
|
|
35
|
-
if [ ! -f "$MANIFEST_FILE" ]; then
|
|
36
|
-
echo " ERROR: Manifest file not found at $MANIFEST_FILE"
|
|
37
|
-
exit 1
|
|
38
|
-
fi
|
|
39
|
-
|
|
40
|
-
// ─── CHUNK_START: CHECK_CORE_INTEGRITY_MAIN ──────────────────────────────────────────────
|
|
41
|
-
/**
|
|
42
|
-
* @chunk-id CHECK_CORE_INTEGRITY_MAIN_1_0_0
|
|
43
|
-
* @version 1.0.0
|
|
44
|
-
* @hash 3799437312b1f95c807f0862818bf01651792c0d5e2bb81d91d734251a76fc75
|
|
45
|
-
* @macro Core Integrity Verification
|
|
46
|
-
* @micro Calculate and compare v2-core file hashes against manifest
|
|
47
|
-
* @inputs $MANIFEST_FILE: string — Path to .spine-manifest.json
|
|
48
|
-
* @outputs exit code — 0 for pass, 1 for failure
|
|
49
|
-
* @depends-on [find, sha256sum, jq/grep, .spine-manifest.json]
|
|
50
|
-
* @depended-by [CI/CD pipelines, pre-deploy hooks]
|
|
51
|
-
* @side-effects [console output, exit with status code]
|
|
52
|
-
* @tags integrity, verification, security, v2-core
|
|
53
|
-
*/
|
|
54
|
-
# Calculate current hashes
|
|
55
|
-
CURRENT_SRC_HASH=$(find "$CORE_DIR/src" -type f -name '*.tsx' -o -name '*.ts' -o -name '*.css' 2>/dev/null | LC_ALL=C sort | xargs cat 2>/dev/null | sha256sum | cut -d' ' -f1)
|
|
56
|
-
CURRENT_FUNCTIONS_HASH=$(find "$CORE_DIR/functions" -type f -name '*.ts' 2>/dev/null | LC_ALL=C sort | xargs cat 2>/dev/null | sha256sum | cut -d' ' -f1)
|
|
57
|
-
|
|
58
|
-
# Extract expected hashes from manifest (using jq if available, fallback to grep)
|
|
59
|
-
if command -v jq >/dev/null 2>&1; then
|
|
60
|
-
EXPECTED_SRC_HASH=$(jq -r '.integrity.src' "$MANIFEST_FILE" | sed 's/sha256-//')
|
|
61
|
-
EXPECTED_FUNCTIONS_HASH=$(jq -r '.integrity.functions' "$MANIFEST_FILE" | sed 's/sha256-//')
|
|
62
|
-
else
|
|
63
|
-
EXPECTED_SRC_HASH=$(grep '"src"' "$MANIFEST_FILE" | cut -d'"' -f4 | sed 's/sha256-//')
|
|
64
|
-
EXPECTED_FUNCTIONS_HASH=$(grep '"functions"' "$MANIFEST_FILE" | cut -d'"' -f4 | sed 's/sha256-//')
|
|
65
|
-
fi
|
|
66
|
-
|
|
67
|
-
# Check integrity
|
|
68
|
-
if [ "$CURRENT_SRC_HASH" = "$EXPECTED_SRC_HASH" ] && [ "$CURRENT_FUNCTIONS_HASH" = "$EXPECTED_FUNCTIONS_HASH" ]; then
|
|
69
|
-
echo " Integrity check PASSED - Core files are unchanged"
|
|
70
|
-
exit 0
|
|
71
|
-
else
|
|
72
|
-
echo " INTEGRITY CHECK FAILED - Core files have been modified!"
|
|
73
|
-
echo " WARRANTY VOIDED - Core tampering detected"
|
|
74
|
-
echo ""
|
|
75
|
-
echo " Expected src hash: $EXPECTED_SRC_HASH"
|
|
76
|
-
echo " Current src hash: $CURRENT_SRC_HASH"
|
|
77
|
-
echo ""
|
|
78
|
-
echo " Expected functions hash: $EXPECTED_FUNCTIONS_HASH"
|
|
79
|
-
echo " Current functions hash: $CURRENT_FUNCTIONS_HASH"
|
|
80
|
-
exit 1
|
|
81
|
-
fi
|
|
82
|
-
// ─── CHUNK_END: CHECK_CORE_INTEGRITY_MAIN ────────────────────────────────────────────────
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const https = require('https');
|
|
5
|
-
const querystring = require('querystring');
|
|
6
|
-
|
|
7
|
-
// Configuration - use local Netlify Functions
|
|
8
|
-
const NETLIFY_URL = 'http://localhost:8888';
|
|
9
|
-
const SUPABASE_SERVICE_ROLE_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV5b2t1aWlienR3YXNkcHJzb3YiLCJyb2xlIjoic2VydmljZV9yb2xlIiwiaWF0IjoxNzM2MTY3Njk5LCJleHAiOjIwNTE3NDM2OTl9.qKqJv8N-IY9q8o_XJtq2o5s3RfD2W4x7J8L9q8o_XJt';
|
|
10
|
-
|
|
11
|
-
// Read chunks from file
|
|
12
|
-
function readChunks(filePath) {
|
|
13
|
-
try {
|
|
14
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
15
|
-
const data = JSON.parse(content);
|
|
16
|
-
return data.chunks || [];
|
|
17
|
-
} catch (error) {
|
|
18
|
-
console.error('Error reading chunks file:', error.message);
|
|
19
|
-
process.exit(1);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Make HTTP request to local Netlify Function
|
|
24
|
-
function makeRequest(functionName, data) {
|
|
25
|
-
return new Promise((resolve, reject) => {
|
|
26
|
-
const postData = JSON.stringify(data);
|
|
27
|
-
const url = `${NETLIFY_URL}/.netlify/functions/${functionName}`;
|
|
28
|
-
|
|
29
|
-
console.log(` 🌐 Calling: ${url}`);
|
|
30
|
-
console.log(` 📦 Data size: ${postData.length} bytes`);
|
|
31
|
-
|
|
32
|
-
const options = {
|
|
33
|
-
hostname: 'localhost',
|
|
34
|
-
port: 8888,
|
|
35
|
-
path: `/.netlify/functions/${functionName}`,
|
|
36
|
-
method: 'POST',
|
|
37
|
-
headers: {
|
|
38
|
-
'Content-Type': 'application/json',
|
|
39
|
-
'Authorization': `Bearer ${SUPABASE_SERVICE_ROLE_KEY}`,
|
|
40
|
-
'Content-Length': Buffer.byteLength(postData)
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const req = require('http').request(options, (res) => {
|
|
45
|
-
let responseData = '';
|
|
46
|
-
|
|
47
|
-
res.on('data', (chunk) => {
|
|
48
|
-
responseData += chunk;
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
res.on('end', () => {
|
|
52
|
-
console.log(` 📡 Response status: ${res.statusCode}`);
|
|
53
|
-
console.log(` 📄 Response body: ${responseData.substring(0, 200)}${responseData.length > 200 ? '...' : ''}`);
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
const parsed = JSON.parse(responseData);
|
|
57
|
-
resolve({ status: res.statusCode, data: parsed });
|
|
58
|
-
} catch (error) {
|
|
59
|
-
resolve({ status: res.statusCode, data: responseData });
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
req.on('error', (error) => {
|
|
65
|
-
console.log(` ❌ Request error: ${error.message}`);
|
|
66
|
-
reject(error);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
req.write(postData);
|
|
70
|
-
req.end();
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Ingest chunks in batches to avoid timeouts
|
|
75
|
-
async function ingestChunks(chunks, batchSize = 10) {
|
|
76
|
-
const results = {
|
|
77
|
-
total: chunks.length,
|
|
78
|
-
processed: 0,
|
|
79
|
-
created: 0,
|
|
80
|
-
updated: 0,
|
|
81
|
-
errors: []
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
console.log(`Starting ingestion of ${chunks.length} chunks in batches of ${batchSize}...`);
|
|
85
|
-
|
|
86
|
-
for (let i = 0; i < chunks.length; i += batchSize) {
|
|
87
|
-
const batch = chunks.slice(i, i + batchSize);
|
|
88
|
-
const batchNum = Math.floor(i / batchSize) + 1;
|
|
89
|
-
const totalBatches = Math.ceil(chunks.length / batchSize);
|
|
90
|
-
|
|
91
|
-
console.log(`Processing batch ${batchNum}/${totalBatches} (${batch.length} chunks)...`);
|
|
92
|
-
|
|
93
|
-
try {
|
|
94
|
-
const response = await makeRequest('custom_kb-ingestion', {
|
|
95
|
-
chunks: batch,
|
|
96
|
-
force_update: false
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
if (response.status === 200) {
|
|
100
|
-
const result = response.data;
|
|
101
|
-
results.processed += batch.length;
|
|
102
|
-
results.created += result.items_created || 0;
|
|
103
|
-
results.updated += result.items_updated || 0;
|
|
104
|
-
|
|
105
|
-
if (result.errors && result.errors.length > 0) {
|
|
106
|
-
results.errors.push(...result.errors);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (result.skipped && result.skipped.length > 0) {
|
|
110
|
-
console.log(` Batch ${batchNum}: ${result.items_created || 0} created, ${result.items_updated || 0} updated, ${result.skipped?.length || 0} skipped`);
|
|
111
|
-
} else {
|
|
112
|
-
console.log(` Batch ${batchNum}: ${result.items_created || 0} created, ${result.items_updated || 0} updated`);
|
|
113
|
-
}
|
|
114
|
-
} else {
|
|
115
|
-
const error = `HTTP ${response.status}: ${JSON.stringify(response.data)}`;
|
|
116
|
-
results.errors.push(`Batch ${batchNum}: ${error}`);
|
|
117
|
-
console.error(` Batch ${batchNum} failed: ${error}`);
|
|
118
|
-
}
|
|
119
|
-
} catch (error) {
|
|
120
|
-
const batchError = `Batch ${batchNum}: ${error.message}`;
|
|
121
|
-
results.errors.push(batchError);
|
|
122
|
-
console.error(` Batch ${batchNum} failed: ${error.message}`);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Small delay between batches to avoid rate limiting
|
|
126
|
-
if (i + batchSize < chunks.length) {
|
|
127
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return results;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Main function
|
|
135
|
-
async function main() {
|
|
136
|
-
const args = process.argv.slice(2);
|
|
137
|
-
|
|
138
|
-
if (args.length < 1) {
|
|
139
|
-
console.log('Usage: node ingest-chunks.js <chunks.json>');
|
|
140
|
-
console.log('Example: node ingest-chunks.js chunks.json');
|
|
141
|
-
process.exit(1);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const chunksFile = args[0];
|
|
145
|
-
|
|
146
|
-
if (!fs.existsSync(chunksFile)) {
|
|
147
|
-
console.error(`Chunks file not found: ${chunksFile}`);
|
|
148
|
-
process.exit(1);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
const chunks = readChunks(chunksFile);
|
|
153
|
-
console.log(`Loaded ${chunks.length} chunks from ${chunksFile}`);
|
|
154
|
-
|
|
155
|
-
// Show sample chunk
|
|
156
|
-
if (chunks.length > 0) {
|
|
157
|
-
console.log('\nSample chunk:');
|
|
158
|
-
console.log(`- ID: ${chunks[0].chunk_id}`);
|
|
159
|
-
console.log(`- Macro: ${chunks[0].macro}`);
|
|
160
|
-
console.log(`- Micro: ${chunks[0].micro}`);
|
|
161
|
-
console.log(`- File: ${chunks[0].metadata.file_path}`);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Ask for confirmation
|
|
165
|
-
console.log('\nReady to ingest chunks into KB system.');
|
|
166
|
-
console.log('This will create KB articles and embeddings for each chunk.');
|
|
167
|
-
console.log('Continue? (y/N)');
|
|
168
|
-
|
|
169
|
-
// For automation, we'll proceed without interactive confirmation
|
|
170
|
-
console.log('Proceeding with ingestion...\n');
|
|
171
|
-
|
|
172
|
-
const results = await ingestChunks(chunks);
|
|
173
|
-
|
|
174
|
-
console.log('\n=== Ingestion Complete ===');
|
|
175
|
-
console.log(`Total chunks: ${results.total}`);
|
|
176
|
-
console.log(`Processed: ${results.processed}`);
|
|
177
|
-
console.log(`Created: ${results.created}`);
|
|
178
|
-
console.log(`Updated: ${results.updated}`);
|
|
179
|
-
console.log(`Errors: ${results.errors.length}`);
|
|
180
|
-
|
|
181
|
-
if (results.errors.length > 0) {
|
|
182
|
-
console.log('\nErrors:');
|
|
183
|
-
results.errors.slice(0, 10).forEach((error, i) => {
|
|
184
|
-
console.log(`${i + 1}. ${error}`);
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
if (results.errors.length > 10) {
|
|
188
|
-
console.log(`... and ${results.errors.length - 10} more errors`);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
console.log('\nYou can now check the KB articles in your Spine instance!');
|
|
193
|
-
|
|
194
|
-
} catch (error) {
|
|
195
|
-
console.error('Fatal error:', error.message);
|
|
196
|
-
process.exit(1);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (require.main === module) {
|
|
201
|
-
main();
|
|
202
|
-
}
|