spine-framework 0.3.144 → 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 +20 -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,26 +1,37 @@
|
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/app-manifest.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/_shared/app-manifest.ts"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Shared manifest loader for Spine apps"]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Defines AppManifest and NavItem interfaces and provides manifest loading, caching, merging, and discovery helpers"]
|
|
4
|
+
// CIL[DOC-CONTEXT module="functions/_shared" layer="shared" related_files=".framework/functions/_shared/app-manifest.ts"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Module-level entry point; no runtime logic" notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
8
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="developers"]
|
|
1
10
|
|
|
2
11
|
|
|
3
12
|
|
|
4
13
|
|
|
5
14
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// CIL[DOC-
|
|
10
|
-
// CIL[DOC-
|
|
11
|
-
// CIL[DOC-
|
|
12
|
-
// CIL[DOC-
|
|
13
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
14
|
-
// CIL[DOC-AUDIENCE audience="developer"]
|
|
15
|
-
// CIL[DOC-VECTOR type="context" content="Layer: infrastructure. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
16
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
17
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
18
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
15
|
+
|
|
16
|
+
import { readFileSync, realpathSync, readdirSync, statSync } from 'fs'
|
|
17
|
+
import { resolve, join, sep } from 'path'
|
|
18
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Shared manifest loader for Spine apps'; No verified external callers; imports: none"]
|
|
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"]
|
|
19
22
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
20
23
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
21
|
-
|
|
22
|
-
import { resolve } from 'path'
|
|
24
|
+
// CIL[END stable_id="~/.framework/functions/_shared/app-manifest.ts:module_header:module_header"]
|
|
23
25
|
|
|
26
|
+
|
|
27
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/app-manifest.ts:AppManifest:interface" type="interface" identity="AppManifest" parent="~/.framework/functions/_shared/app-manifest.ts"]
|
|
28
|
+
// CIL[DOC-MACRO purpose="Describes the runtime configuration shape of a Spine app manifest"]
|
|
29
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declare the AppManifest type fields used by loaders and renderers"]
|
|
30
|
+
// CIL[DOC-CONTEXT module="functions/_shared" layer="shared" related_files=".framework/functions/_shared/app-manifest.ts"]
|
|
31
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="AppManifest type definition" errors="none" side_effects="none"]
|
|
32
|
+
// CIL[DOC-MICRO logic_summary="Optional and required fields for app metadata, routing, roles, and domains" notable_decisions="[]"]
|
|
33
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
34
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
24
35
|
export interface AppManifest {
|
|
25
36
|
name: string
|
|
26
37
|
slug: string
|
|
@@ -39,7 +50,23 @@ export interface AppManifest {
|
|
|
39
50
|
preview_domain?: string
|
|
40
51
|
prod_domain?: string
|
|
41
52
|
}
|
|
53
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Describes the runtime configuration shape of a Spine app manifest'; No verified external callers; imports: none"]
|
|
54
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
55
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
56
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
57
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
58
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
59
|
+
// CIL[END stable_id="~/.framework/functions/_shared/app-manifest.ts:AppManifest:interface"]
|
|
42
60
|
|
|
61
|
+
|
|
62
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/app-manifest.ts:NavItem:interface" type="interface" identity="NavItem" parent="~/.framework/functions/_shared/app-manifest.ts"]
|
|
63
|
+
// CIL[DOC-MACRO purpose="Describes the shape of a navigation item in an app manifest"]
|
|
64
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declare the NavItem type used for app navigation trees"]
|
|
65
|
+
// CIL[DOC-CONTEXT module="functions/_shared" layer="shared" related_files=".framework/functions/_shared/app-manifest.ts"]
|
|
66
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="NavItem type definition" errors="none" side_effects="none"]
|
|
67
|
+
// CIL[DOC-MICRO logic_summary="Title, path, icon, order, and optional nested children" notable_decisions="[]"]
|
|
68
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
69
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
43
70
|
export interface NavItem {
|
|
44
71
|
title: string
|
|
45
72
|
path: string
|
|
@@ -47,108 +74,169 @@ export interface NavItem {
|
|
|
47
74
|
order?: number
|
|
48
75
|
children?: NavItem[]
|
|
49
76
|
}
|
|
77
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Describes the shape of a navigation item in an app manifest'; No verified external callers; imports: none"]
|
|
78
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
79
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
80
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
81
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
82
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
83
|
+
// CIL[END stable_id="~/.framework/functions/_shared/app-manifest.ts:NavItem:interface"]
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
50
89
|
|
|
51
|
-
const manifestCache = new Map<string, AppManifest>()
|
|
52
90
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// CIL[
|
|
60
|
-
// CIL[DOC-
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/app-manifest.ts:manifestCache:constant" type="constant" identity="manifestCache" parent="~/.framework/functions/_shared/app-manifest.ts"]
|
|
98
|
+
// CIL[DOC-MACRO purpose="Cache loaded manifests by file path to avoid repeated disk reads"]
|
|
99
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Hold in-memory Map of manifest paths to AppManifest objects"]
|
|
100
|
+
// CIL[DOC-CONTEXT module="functions/_shared" layer="shared" related_files=".framework/functions/_shared/app-manifest.ts"]
|
|
101
|
+
// CIL[DOC-CONTRACT inputs="canonical manifest path string key" outputs="AppManifest or undefined" errors="none" side_effects="Cache state is mutable module state"]
|
|
102
|
+
// CIL[DOC-MICRO logic_summary="Instantiated once at module load; keyed by canonical manifest path" notable_decisions="[]"]
|
|
103
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
61
104
|
// CIL[DOC-STABILITY stability="stable"]
|
|
62
|
-
|
|
63
|
-
// CIL[DOC-VECTOR type="
|
|
64
|
-
// CIL[DOC-VECTOR type="
|
|
65
|
-
// CIL[DOC-VECTOR type="
|
|
105
|
+
const manifestCache = new Map<string, AppManifest>()
|
|
106
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Cache loaded manifests by file path to avoid repeated disk reads'; No verified external callers; imports: none"]
|
|
107
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
108
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
109
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
66
110
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
67
111
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
68
|
-
|
|
69
|
-
if (manifestCache.has(manifestPath)) {
|
|
70
|
-
return manifestCache.get(manifestPath)!
|
|
71
|
-
}
|
|
112
|
+
// CIL[END stable_id="~/.framework/functions/_shared/app-manifest.ts:manifestCache:constant"]
|
|
72
113
|
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/app-manifest.ts:loadManifest:function" type="function" identity="loadManifest" parent="~/.framework/functions/_shared/app-manifest.ts"]
|
|
117
|
+
// CIL[DOC-MACRO purpose="Read, parse, and cache a Spine app manifest JSON file"]
|
|
118
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Load manifest from disk, validate required fields, cache, and return it"]
|
|
119
|
+
// CIL[DOC-CONTEXT module="functions/_shared" layer="shared" related_files=".framework/functions/_shared/app-manifest.ts"]
|
|
120
|
+
// CIL[DOC-CONTRACT inputs="manifestPath: relative or absolute path to manifest JSON, projectRoot: optional root (defaults to REPO_PATH or cwd)" outputs="AppManifest or null" errors="Returns null on path escapes, missing or invalid fields, or read/parse errors and logs to console" side_effects="Reads from filesystem and updates manifestCache keyed by canonical path"]
|
|
121
|
+
// CIL[DOC-MICRO logic_summary="Canonicalizes project root and manifest path with realpathSync, rejects lexical or symlink escapes, parses JSON, validates object shape, nonempty name, slug charset, and required_roles array, then caches by canonical path" notable_decisions="[]"]
|
|
122
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
123
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
124
|
+
export function loadManifest(
|
|
125
|
+
manifestPath: string,
|
|
126
|
+
projectRoot: string = resolve(process.env.REPO_PATH || process.cwd())
|
|
127
|
+
): AppManifest | null {
|
|
73
128
|
try {
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
129
|
+
const root = realpathSync(resolve(projectRoot))
|
|
130
|
+
const lexical = resolve(root, manifestPath)
|
|
131
|
+
if (lexical !== root && !lexical.startsWith(root + sep)) {
|
|
132
|
+
console.error(`[app-manifest] Manifest path escapes project root: ${manifestPath}`)
|
|
133
|
+
return null
|
|
134
|
+
}
|
|
135
|
+
const canonical = realpathSync(lexical)
|
|
136
|
+
if (canonical !== root && !canonical.startsWith(root + sep)) {
|
|
137
|
+
console.error(`[app-manifest] Manifest resolves outside project root: ${manifestPath}`)
|
|
138
|
+
return null
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (manifestCache.has(canonical)) {
|
|
142
|
+
return manifestCache.get(canonical)!
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const content = readFileSync(canonical, 'utf-8')
|
|
78
146
|
const manifest: AppManifest = JSON.parse(content)
|
|
79
|
-
|
|
80
|
-
if (!manifest
|
|
81
|
-
console.error(`[app-manifest] Invalid manifest at ${manifestPath}:
|
|
147
|
+
|
|
148
|
+
if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest)) {
|
|
149
|
+
console.error(`[app-manifest] Invalid manifest at ${manifestPath}: root must be an object`)
|
|
150
|
+
return null
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (typeof manifest.name !== 'string' || !manifest.name.trim()) {
|
|
154
|
+
console.error(`[app-manifest] Invalid manifest at ${manifestPath}: missing name`)
|
|
155
|
+
return null
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (typeof manifest.slug !== 'string' || !/^[a-z][a-z0-9-]*$/.test(manifest.slug)) {
|
|
159
|
+
console.error(`[app-manifest] Invalid manifest at ${manifestPath}: missing or invalid slug`)
|
|
82
160
|
return null
|
|
83
161
|
}
|
|
84
|
-
|
|
85
|
-
if (
|
|
162
|
+
|
|
163
|
+
if (manifest.required_roles === undefined || manifest.required_roles === null) {
|
|
86
164
|
manifest.required_roles = []
|
|
165
|
+
} else if (!Array.isArray(manifest.required_roles) || manifest.required_roles.some((r) => typeof r !== 'string' || !r.trim())) {
|
|
166
|
+
console.error(`[app-manifest] Invalid manifest at ${manifestPath}: required_roles must be an array of nonempty strings`)
|
|
167
|
+
return null
|
|
87
168
|
}
|
|
88
|
-
|
|
89
|
-
manifestCache.set(
|
|
90
|
-
|
|
169
|
+
|
|
170
|
+
manifestCache.set(canonical, manifest)
|
|
171
|
+
|
|
91
172
|
return manifest
|
|
92
173
|
} catch (err) {
|
|
93
174
|
console.error(`[app-manifest] Failed to load ${manifestPath}:`, err)
|
|
94
175
|
return null
|
|
95
176
|
}
|
|
96
177
|
}
|
|
97
|
-
// CIL[
|
|
98
|
-
// CIL[
|
|
99
|
-
// CIL[DOC-
|
|
100
|
-
// CIL[DOC-
|
|
101
|
-
// CIL[DOC-CONTEXT module="_shared/app-manifest" layer="infrastructure" related_files="[\"\\\"]"]
|
|
102
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="void" errors="none" side_effects="cache clearing"]
|
|
103
|
-
// CIL[DOC-MICRO logic_summary="Clears all cached manifest entries" notable_decisions="[]"]
|
|
104
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
105
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
106
|
-
// CIL[DOC-VECTOR type="context" content="Layer: infrastructure. Direct callers: 0. Direct calls: 0. Related files: \."]
|
|
107
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
108
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
109
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
178
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Read, parse, and cache a Spine app manifest JSON file'; No verified external callers; imports: none"]
|
|
179
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
180
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
181
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
110
182
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
111
183
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
184
|
+
// CIL[END stable_id="~/.framework/functions/_shared/app-manifest.ts:loadManifest:function"]
|
|
185
|
+
|
|
186
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/app-manifest.ts:clearManifestCache:function" type="function" identity="clearManifestCache" parent="~/.framework/functions/_shared/app-manifest.ts"]
|
|
187
|
+
// CIL[DOC-MACRO purpose="Clear the manifest cache"]
|
|
188
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Reset the manifestCache Map"]
|
|
189
|
+
// CIL[DOC-CONTEXT module="functions/_shared" layer="shared" related_files=".framework/functions/_shared/app-manifest.ts"]
|
|
190
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="void" errors="none" side_effects="Empties manifestCache"]
|
|
191
|
+
// CIL[DOC-MICRO logic_summary="Calls Map.clear on the module-level cache" notable_decisions="[]"]
|
|
192
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
193
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
112
194
|
export function clearManifestCache(): void {
|
|
113
195
|
manifestCache.clear()
|
|
114
196
|
}
|
|
115
|
-
// CIL[
|
|
116
|
-
// CIL[
|
|
117
|
-
// CIL[DOC-
|
|
118
|
-
// CIL[DOC-
|
|
119
|
-
// CIL[DOC-CONTEXT module="_shared/app-manifest" layer="infrastructure" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/schema-utils.ts\",\".framework/src/components/ui/dialog.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"\\\"]"]
|
|
120
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="merged record" errors="manifest load errors" side_effects="file reads"]
|
|
121
|
-
// CIL[DOC-MICRO logic_summary="Merges database record with manifest file data" notable_decisions="[]"]
|
|
122
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
123
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
124
|
-
// CIL[DOC-VECTOR type="context" content="Layer: infrastructure. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/schema-utils.ts, .framework/src/components/ui/dialog.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/IntegrationsPage.tsx, \."]
|
|
125
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
126
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
127
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
197
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Clear the manifest cache'; No verified external callers; imports: none"]
|
|
198
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
199
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
200
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
128
201
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
129
202
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
203
|
+
// CIL[END stable_id="~/.framework/functions/_shared/app-manifest.ts:clearManifestCache:function"]
|
|
204
|
+
|
|
205
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/app-manifest.ts:mergeWithManifest:function" type="function" identity="mergeWithManifest" parent="~/.framework/functions/_shared/app-manifest.ts"]
|
|
206
|
+
// CIL[DOC-MACRO purpose="Merge a database app record with its manifest file values"]
|
|
207
|
+
// CIL[DOC-RESPONSIBILITY responsibility="When config_source is manifest, load and overlay manifest fields onto the database record"]
|
|
208
|
+
// CIL[DOC-CONTEXT module="functions/_shared" layer="shared" related_files=".framework/functions/_shared/app-manifest.ts"]
|
|
209
|
+
// CIL[DOC-CONTRACT inputs="dbRecord: any database app row object" outputs="merged app object or null" errors="Falls back to database record if manifest missing or invalid, logging a warning" side_effects="Calls loadManifest which may read from disk and cache"]
|
|
210
|
+
// CIL[DOC-MICRO logic_summary="Returns DB-derived fallback when no manifest config, preserving an existing required_roles array and deriving from min_role only when absent; otherwise loads manifest and overlays manifest-authoritative fields on the full DB record" notable_decisions="[]"]
|
|
211
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
212
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
130
213
|
export function mergeWithManifest(dbRecord: any): any {
|
|
131
214
|
if (!dbRecord) return null
|
|
132
|
-
|
|
215
|
+
|
|
216
|
+
const fallbackRoles = Array.isArray(dbRecord.required_roles)
|
|
217
|
+
? dbRecord.required_roles
|
|
218
|
+
: dbRecord.min_role ? [dbRecord.min_role] : []
|
|
219
|
+
|
|
133
220
|
if (!dbRecord.manifest_path || dbRecord.config_source !== 'manifest') {
|
|
134
221
|
return {
|
|
135
222
|
...dbRecord,
|
|
136
|
-
required_roles:
|
|
223
|
+
required_roles: fallbackRoles,
|
|
137
224
|
_source: 'database'
|
|
138
225
|
}
|
|
139
226
|
}
|
|
140
|
-
|
|
227
|
+
|
|
141
228
|
const manifest = loadManifest(dbRecord.manifest_path)
|
|
142
229
|
if (!manifest) {
|
|
143
230
|
console.warn(`[app-manifest] Could not load manifest for ${dbRecord.slug}, falling back to DB`)
|
|
144
231
|
return {
|
|
145
232
|
...dbRecord,
|
|
146
|
-
required_roles:
|
|
233
|
+
required_roles: fallbackRoles,
|
|
147
234
|
_source: 'database (manifest missing)'
|
|
148
235
|
}
|
|
149
236
|
}
|
|
150
|
-
|
|
237
|
+
|
|
151
238
|
return {
|
|
239
|
+
...dbRecord,
|
|
152
240
|
id: dbRecord.id,
|
|
153
241
|
slug: manifest.slug,
|
|
154
242
|
name: manifest.name,
|
|
@@ -171,25 +259,57 @@ export function mergeWithManifest(dbRecord: any): any {
|
|
|
171
259
|
_manifest_path: dbRecord.manifest_path
|
|
172
260
|
}
|
|
173
261
|
}
|
|
174
|
-
// CIL[
|
|
175
|
-
// CIL[
|
|
176
|
-
// CIL[DOC-
|
|
177
|
-
// CIL[DOC-
|
|
178
|
-
// CIL[DOC-CONTEXT module="_shared/app-manifest" layer="infrastructure" related_files="[]"]
|
|
179
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="manifest list" errors="none" side_effects="none"]
|
|
180
|
-
// CIL[DOC-MICRO logic_summary="Returns hardcoded list of app manifest locations" notable_decisions="[]"]
|
|
181
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
182
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
183
|
-
// CIL[DOC-VECTOR type="context" content="Layer: infrastructure. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
184
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
185
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
186
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
262
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Merge a database app record with its manifest file values'; No verified external callers; imports: none"]
|
|
263
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
264
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
265
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
187
266
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
188
267
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
268
|
+
// CIL[END stable_id="~/.framework/functions/_shared/app-manifest.ts:mergeWithManifest:function"]
|
|
269
|
+
|
|
270
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/app-manifest.ts:discoverManifests:function" type="function" identity="discoverManifests" parent="~/.framework/functions/_shared/app-manifest.ts"]
|
|
271
|
+
// CIL[DOC-MACRO purpose="Discover app manifests by enumerating custom/apps directories"]
|
|
272
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Enumerate custom/apps children, load and validate each manifest, and return slug/path entries for directories whose name matches the manifest slug"]
|
|
273
|
+
// CIL[DOC-CONTEXT module="functions/_shared" layer="shared" related_files=".framework/functions/_shared/app-manifest.ts"]
|
|
274
|
+
// CIL[DOC-CONTRACT inputs="projectRoot?: string defaults to REPO_PATH or cwd" outputs="Array of {slug, path} objects sorted lexically by directory name" errors="Returns [] when custom/apps is absent or unreadable" side_effects="Reads the filesystem and may populate the manifest cache"]
|
|
275
|
+
// CIL[DOC-MICRO logic_summary="Canonicalizes the project root, lists custom/apps entries sorted lexically, skips non-directories and external symlink escapes via loadManifest containment, and keeps entries whose directory name equals the validated manifest slug" notable_decisions="[]"]
|
|
276
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
277
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
278
|
+
export function discoverManifests(
|
|
279
|
+
projectRoot: string = resolve(process.env.REPO_PATH || process.cwd())
|
|
280
|
+
): Array<{slug: string, path: string}> {
|
|
281
|
+
try {
|
|
282
|
+
const root = realpathSync(resolve(projectRoot))
|
|
283
|
+
const appsDir = join(root, 'custom', 'apps')
|
|
284
|
+
const names = readdirSync(appsDir, { withFileTypes: true })
|
|
285
|
+
.map((d) => d.name)
|
|
286
|
+
.sort()
|
|
287
|
+
|
|
288
|
+
const found: Array<{slug: string, path: string}> = []
|
|
289
|
+
for (const name of names) {
|
|
290
|
+
const dirPath = join(appsDir, name)
|
|
291
|
+
let isDir = false
|
|
292
|
+
try {
|
|
293
|
+
isDir = statSync(dirPath).isDirectory()
|
|
294
|
+
} catch {
|
|
295
|
+
continue
|
|
296
|
+
}
|
|
297
|
+
if (!isDir) continue
|
|
298
|
+
|
|
299
|
+
const rel = `custom/apps/${name}/manifest.json`
|
|
300
|
+
const manifest = loadManifest(rel, root)
|
|
301
|
+
if (!manifest || manifest.slug !== name) continue
|
|
302
|
+
found.push({ slug: manifest.slug, path: rel })
|
|
303
|
+
}
|
|
304
|
+
return found
|
|
305
|
+
} catch {
|
|
306
|
+
return []
|
|
307
|
+
}
|
|
194
308
|
}
|
|
195
|
-
// CIL[
|
|
309
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Discover app manifests by enumerating custom/apps directories'; No verified external callers; imports: none"]
|
|
310
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
311
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
312
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
313
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
314
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
315
|
+
// CIL[END stable_id="~/.framework/functions/_shared/app-manifest.ts:discoverManifests:function"]
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/ast.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/_shared/ast.ts"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Provides the TypeScript compiler API import for AST identity extraction"]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declare the typescript dependency and serve as the module-level CIL header"]
|
|
4
|
+
// CIL[DOC-CONTEXT module=".framework/functions/_shared/ast.ts" layer="shared" related_files=".framework/functions/_shared/ast.ts"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="" outputs="" errors="" side_effects=""]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Imports the entire typescript namespace as ts"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
8
|
+
// CIL[DOC-STABILITY stable]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="cil pipeline"]
|
|
10
|
+
import * as ts from 'typescript'
|
|
11
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Provides the TypeScript compiler API import for AST identity extraction'; No verified external callers; imports: none"]
|
|
12
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
13
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
14
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
15
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
16
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
17
|
+
// CIL[END stable_id="~/.framework/functions/_shared/ast.ts:module_header:module_header"]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/ast.ts:IdentityProposal:interface" type="interface" identity="IdentityProposal" parent="~/.framework/functions/_shared/ast.ts"]
|
|
21
|
+
// CIL[DOC-MACRO purpose="Defines the shape of an extracted code identity proposal"]
|
|
22
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Model an identity proposal with identity, type, parent, line range and text"]
|
|
23
|
+
// CIL[DOC-CONTEXT module=".framework/functions/_shared/ast.ts" layer="shared" related_files=".framework/functions/_shared/ast.ts"]
|
|
24
|
+
// CIL[DOC-CONTRACT inputs="none (structural interface)" outputs="none (structural interface)" errors="none" side_effects="none"]
|
|
25
|
+
// CIL[DOC-MICRO logic_summary="Simple TypeScript interface describing a proposed chunk identity"]
|
|
26
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
27
|
+
// CIL[DOC-STABILITY stable]
|
|
28
|
+
export interface IdentityProposal {
|
|
29
|
+
identity: string
|
|
30
|
+
type: string
|
|
31
|
+
parent: string
|
|
32
|
+
line_start: number
|
|
33
|
+
line_end: number
|
|
34
|
+
text: string
|
|
35
|
+
}
|
|
36
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Defines the shape of an extracted code identity proposal'; No verified external callers; imports: none"]
|
|
37
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
38
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
39
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
40
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
41
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
42
|
+
// CIL[END stable_id="~/.framework/functions/_shared/ast.ts:IdentityProposal:interface"]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/ast.ts:isCapitalized:function" type="function" identity="isCapitalized" parent="~/.framework/functions/_shared/ast.ts"]
|
|
46
|
+
// CIL[DOC-MACRO purpose="Check whether a string begins with an uppercase letter"]
|
|
47
|
+
// CIL[DOC-STABILITY stability="internal"]
|
|
48
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
49
|
+
// CIL[DOC-CONTEXT module="ast" layer="functions" related_files=".framework/functions/_shared/ast.ts"]
|
|
50
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Determine capitalization of an identifier to classify React components"]
|
|
51
|
+
// CIL[DOC-CONTRACT inputs="name: string" outputs="boolean" errors="" side_effects="none"]
|
|
52
|
+
// CIL[DOC-MICRO logic_summary="Returns true when the first character is the same as its uppercase form"]
|
|
53
|
+
function isCapitalized(name: string): boolean {
|
|
54
|
+
return name.length > 0 && name[0] === name[0].toUpperCase()
|
|
55
|
+
}
|
|
56
|
+
// CIL[END stable_id="~/.framework/functions/_shared/ast.ts:isCapitalized:function"]
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Check whether a string begins with an uppercase letter'; No verified external callers; imports: none"]
|
|
60
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
61
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
62
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
63
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
64
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
65
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/ast.ts:isHook:function" type="function" identity="isHook" parent="~/.framework/functions/_shared/ast.ts"]
|
|
66
|
+
// CIL[DOC-MACRO purpose="Validation function for identifying React Hook names"]
|
|
67
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Decide if a string is a valid React hook name by convention"]
|
|
68
|
+
// CIL[DOC-CONTEXT module=".framework/functions/_shared/ast.ts" layer="shared" related_files=".framework/functions/_shared/ast.ts"]
|
|
69
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
70
|
+
// CIL[DOC-CONTRACT inputs="name: string" outputs="boolean" errors="" side_effects="none"]
|
|
71
|
+
// CIL[DOC-MICRO logic_summary="Checks if the name starts with 'use', has length greater than 3, and the fourth character is uppercase"]
|
|
72
|
+
// CIL[DOC-STABILITY stable]
|
|
73
|
+
function isHook(name: string): boolean {
|
|
74
|
+
return name.startsWith('use') && name.length > 3 && name[3] === name[3].toUpperCase()
|
|
75
|
+
}
|
|
76
|
+
// CIL[END stable_id="~/.framework/functions/_shared/ast.ts:isHook:function"]
|
|
77
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Validation function for identifying React Hook names'; No verified external callers; imports: none"]
|
|
78
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
79
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
80
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
81
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
82
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/ast.ts:lineOf:function" type="function" identity="lineOf" parent="~/.framework/functions/_shared/ast.ts"]
|
|
86
|
+
// CIL[DOC-MACRO purpose="Compute the 1-based line number of a TypeScript AST node"]
|
|
87
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Convert a node's start position to a human-readable line number"]
|
|
88
|
+
// CIL[DOC-CONTEXT module=".framework/functions/_shared/ast.ts" layer="shared" related_files=".framework/functions/_shared/ast.ts"]
|
|
89
|
+
// CIL[DOC-CONTRACT inputs="sourceFile: ts.SourceFile, node: ts.Node" outputs="number" errors="" side_effects="none"]
|
|
90
|
+
// CIL[DOC-MICRO logic_summary="Uses sourceFile.getLineAndCharacterOfPosition and adds 1"]
|
|
91
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
92
|
+
// CIL[DOC-STABILITY stable]
|
|
93
|
+
function lineOf(sourceFile: ts.SourceFile, node: ts.Node): number {
|
|
94
|
+
return sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1
|
|
95
|
+
}
|
|
96
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Compute the 1-based line number of a TypeScript AST node'; No verified external callers; imports: none"]
|
|
97
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
98
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
99
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
100
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
101
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
102
|
+
// CIL[END stable_id="~/.framework/functions/_shared/ast.ts:lineOf:function"]
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
// CIL[BEGIN stable_id="~/.framework/functions/_shared/ast.ts:extractIdentities:function" type="function" identity="extractIdentities" parent="~/.framework/functions/_shared/ast.ts"]
|
|
106
|
+
// CIL[DOC-MACRO purpose="Extract candidate code identities from a TypeScript source file"]
|
|
107
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Walk the TypeScript AST and build a list of IdentityProposal objects for CIL chunking"]
|
|
108
|
+
// CIL[DOC-CONTEXT module=".framework/functions/_shared/ast.ts" layer="shared" related_files=".framework/functions/_shared/ast.ts"]
|
|
109
|
+
// CIL[DOC-CONTRACT inputs="sourceFile: ts.SourceFile, fileStableId: string" outputs="IdentityProposal[]" errors="" side_effects="none"]
|
|
110
|
+
// CIL[DOC-MICRO logic_summary="Traverses declarations, class members, interfaces, type aliases, variable statements and export assignments; determines types using isHook, isCapitalized; increments anonymousCounter for default exports"]
|
|
111
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
112
|
+
// CIL[DOC-STABILITY stable]
|
|
113
|
+
export function extractIdentities(sourceFile: ts.SourceFile, fileStableId: string): IdentityProposal[] {
|
|
114
|
+
const proposals: IdentityProposal[] = []
|
|
115
|
+
|
|
116
|
+
proposals.push({
|
|
117
|
+
identity: 'module_header',
|
|
118
|
+
type: 'module_header',
|
|
119
|
+
parent: fileStableId,
|
|
120
|
+
line_start: 1,
|
|
121
|
+
line_end: sourceFile.getLineAndCharacterOfPosition(sourceFile.getFullStart() + sourceFile.getFullWidth()).line + 1,
|
|
122
|
+
text: sourceFile.text,
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
proposals.push({
|
|
126
|
+
identity: 'file',
|
|
127
|
+
type: 'file',
|
|
128
|
+
parent: 'none',
|
|
129
|
+
line_start: 1,
|
|
130
|
+
line_end: sourceFile.getLineAndCharacterOfPosition(sourceFile.getFullStart() + sourceFile.getFullWidth()).line + 1,
|
|
131
|
+
text: sourceFile.text,
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
let anonymousCounter = 0
|
|
135
|
+
|
|
136
|
+
function visit(node: ts.Node, parentId: string) {
|
|
137
|
+
const startLine = lineOf(sourceFile, node)
|
|
138
|
+
const endLine = lineOf(sourceFile, node) + sourceFile.text.slice(node.getStart(), node.getEnd()).split('\n').length - 1
|
|
139
|
+
const text = sourceFile.text.slice(node.getStart(), node.getEnd())
|
|
140
|
+
|
|
141
|
+
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
142
|
+
const name = node.name.text
|
|
143
|
+
const type = isHook(name) ? 'hook' : isCapitalized(name) ? 'component' : 'function'
|
|
144
|
+
proposals.push({ identity: name, type, parent: parentId, line_start: startLine, line_end: endLine, text })
|
|
145
|
+
ts.forEachChild(node, child => visit(child, `${parentId}:${name}:${type}`))
|
|
146
|
+
return
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (ts.isClassDeclaration(node) && node.name) {
|
|
150
|
+
const className = node.name.text
|
|
151
|
+
const classId = `${parentId}:${className}:class`
|
|
152
|
+
proposals.push({ identity: className, type: 'class', parent: parentId, line_start: startLine, line_end: endLine, text })
|
|
153
|
+
node.members.forEach(member => {
|
|
154
|
+
if (ts.isMethodDeclaration(member) && member.name) {
|
|
155
|
+
const methodName = ts.isIdentifier(member.name) ? member.name.text : ts.isStringLiteral(member.name) ? member.name.text : String(member.name.getText(sourceFile))
|
|
156
|
+
proposals.push({
|
|
157
|
+
identity: `${className}.${methodName}`,
|
|
158
|
+
type: 'method',
|
|
159
|
+
parent: classId,
|
|
160
|
+
line_start: lineOf(sourceFile, member),
|
|
161
|
+
line_end: lineOf(sourceFile, member) + text.slice(member.getStart(), member.getEnd()).split('\n').length - 1,
|
|
162
|
+
text: sourceFile.text.slice(member.getStart(), member.getEnd()),
|
|
163
|
+
})
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (ts.isInterfaceDeclaration(node) && node.name) {
|
|
170
|
+
proposals.push({ identity: node.name.text, type: 'interface', parent: parentId, line_start: startLine, line_end: endLine, text })
|
|
171
|
+
return
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (ts.isTypeAliasDeclaration(node) && node.name) {
|
|
175
|
+
proposals.push({ identity: node.name.text, type: 'type', parent: parentId, line_start: startLine, line_end: endLine, text })
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (ts.isVariableStatement(node)) {
|
|
180
|
+
for (const decl of node.declarationList.declarations) {
|
|
181
|
+
if (ts.isIdentifier(decl.name)) {
|
|
182
|
+
const name = decl.name.text
|
|
183
|
+
const isConst = Boolean(node.declarationList.flags & ts.NodeFlags.Const)
|
|
184
|
+
let type = isConst ? 'constant' : 'variable'
|
|
185
|
+
if (decl.initializer) {
|
|
186
|
+
if (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer)) {
|
|
187
|
+
type = isHook(name) ? 'hook' : isCapitalized(name) ? 'component' : 'function'
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
proposals.push({ identity: name, type, parent: parentId, line_start: startLine, line_end: endLine, text })
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (ts.isExportAssignment(node)) {
|
|
197
|
+
anonymousCounter += 1
|
|
198
|
+
proposals.push({ identity: 'default', type: 'function', parent: parentId, line_start: startLine, line_end: endLine, text })
|
|
199
|
+
return
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
ts.forEachChild(node, child => visit(child, parentId))
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
visit(sourceFile, fileStableId)
|
|
206
|
+
return proposals
|
|
207
|
+
}
|
|
208
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Extract candidate code identities from a TypeScript source file'; No verified external callers; imports: none"]
|
|
209
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
210
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
211
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
212
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
213
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
214
|
+
// CIL[END stable_id="~/.framework/functions/_shared/ast.ts:extractIdentities:function"]
|