spine-framework 0.3.145 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +76 -0
- package/.framework/.spine-manifest.json +19 -0
- package/.framework/cli/commands/agents.ts +61 -33
- package/.framework/cli/commands/auth.ts +60 -28
- package/.framework/cli/commands/create-app.ts +212 -80
- package/.framework/cli/commands/dev.ts +184 -68
- package/.framework/cli/commands/doctor.ts +324 -152
- package/.framework/cli/commands/generate.ts +119 -68
- package/.framework/cli/commands/init.ts +141 -242
- package/.framework/cli/commands/install-app.ts +1336 -314
- package/.framework/cli/commands/items.ts +31 -29
- package/.framework/cli/commands/migrate.ts +299 -156
- package/.framework/cli/commands/migrations.ts +62 -30
- package/.framework/cli/commands/pipelines.ts +31 -29
- package/.framework/cli/commands/status.ts +105 -45
- package/.framework/cli/commands/system.ts +47 -42
- package/.framework/cli/commands/test.ts +161 -102
- package/.framework/cli/commands/upgrade.ts +260 -0
- package/.framework/cli/commands/validate-app.ts +517 -161
- package/.framework/cli/context.ts +117 -85
- package/.framework/cli/env-loader.ts +74 -43
- package/.framework/cli/index.ts +70 -46
- package/.framework/cli/lib/project-files.ts +404 -0
- package/.framework/docs/guides/testing-guide.md +1 -1
- package/.framework/docs/runtime-types.md +72 -72
- package/.framework/functions/_shared/access.ts +84 -0
- package/.framework/functions/_shared/agent-runner.ts +5051 -1026
- package/.framework/functions/_shared/app-manifest.ts +214 -94
- package/.framework/functions/_shared/ast.ts +214 -0
- package/.framework/functions/_shared/audit.ts +91 -55
- package/.framework/functions/_shared/cil.ts +368 -127
- package/.framework/functions/_shared/db.ts +337 -68
- package/.framework/functions/_shared/funnel.ts +228 -0
- package/.framework/functions/_shared/geo.ts +105 -0
- package/.framework/functions/_shared/hash-api-key.ts +94 -17
- package/.framework/functions/_shared/index.ts +22 -224
- package/.framework/functions/_shared/kb.ts +832 -58
- package/.framework/functions/_shared/llm.ts +118 -18
- package/.framework/functions/_shared/logging.ts +317 -19
- package/.framework/functions/_shared/middleware.ts +701 -131
- package/.framework/functions/_shared/notify.ts +70 -0
- package/.framework/functions/_shared/outcomes.ts +34 -19
- package/.framework/functions/_shared/permissions.ts +501 -315
- package/.framework/functions/_shared/pipeline-runner.ts +704 -155
- package/.framework/functions/_shared/principal.ts +436 -263
- package/.framework/functions/_shared/rate-limit.ts +233 -0
- package/.framework/functions/_shared/resolve-credentials.ts +86 -19
- package/.framework/functions/_shared/resolve-ids.ts +203 -139
- package/.framework/functions/_shared/retry-deliveries.ts +51 -16
- package/.framework/functions/_shared/schema-utils.ts +602 -521
- package/.framework/functions/_shared/security.ts +345 -0
- package/.framework/functions/_shared/testing.ts +197 -172
- package/.framework/functions/_shared/tracing.ts +351 -21
- package/.framework/functions/_shared/trigger-engine.ts +425 -136
- package/.framework/functions/_shared/webhook-registration.ts +71 -70
- package/.framework/functions/_shared/webhook-registry.ts +126 -83
- package/.framework/functions/account-nodes.ts +30 -30
- package/.framework/functions/adapters/generic-webhook-inbound.ts +49 -16
- package/.framework/functions/adapters/generic-webhook-outbound.ts +17 -17
- package/.framework/functions/adapters/openai-outbound.ts +15 -16
- package/.framework/functions/admin-data.ts +596 -173
- package/.framework/functions/admin-funnel.ts +64 -60
- package/.framework/functions/admin-install-funnel.ts +84 -66
- package/.framework/functions/admin-signals.ts +69 -51
- package/.framework/functions/ai-agents.ts +431 -106
- package/.framework/functions/ai-interactions.ts +186 -112
- package/.framework/functions/api-keys.ts +107 -107
- package/.framework/functions/apps.ts +154 -136
- package/.framework/functions/auth.ts +83 -65
- package/.framework/functions/cil-agent-ingest.ts +189 -232
- package/.framework/functions/cil-agent.ts +433 -177
- package/.framework/functions/cil-callmap.ts +642 -430
- package/.framework/functions/cil-config.ts +139 -135
- package/.framework/functions/cil-context.ts +214 -127
- package/.framework/functions/cil-doc.ts +587 -458
- package/.framework/functions/cil-embeddings.ts +453 -364
- package/.framework/functions/cil-graph.ts +427 -142
- package/.framework/functions/cil-ingest.ts +1418 -1154
- package/.framework/functions/cil-pipeline.ts +276 -21
- package/.framework/functions/cil-project.ts +659 -132
- package/.framework/functions/cil-validate.ts +198 -164
- package/.framework/functions/debug-auth.ts +57 -55
- package/.framework/functions/deliveries.ts +80 -21
- package/.framework/functions/embeddings.ts +1023 -318
- package/.framework/functions/eval-harness.ts +146 -108
- package/.framework/functions/integration-outbound.ts +205 -75
- package/.framework/functions/integration-routes.ts +128 -23
- package/.framework/functions/integrations.ts +125 -100
- package/.framework/functions/invites.ts +1095 -460
- package/.framework/functions/item-progress.ts +158 -102
- package/.framework/functions/kb.ts +34 -10
- package/.framework/functions/logs.ts +133 -133
- package/.framework/functions/observability.ts +152 -122
- package/.framework/functions/pipeline-executions.ts +147 -132
- package/.framework/functions/pipelines.ts +134 -119
- package/.framework/functions/prompt-configs.ts +96 -80
- package/.framework/functions/roles.ts +112 -82
- package/.framework/functions/security.ts +450 -0
- package/.framework/functions/system-cron.ts +117 -80
- package/.framework/functions/system.ts +158 -98
- package/.framework/functions/tests.ts +29 -29
- package/.framework/functions/timers.ts +94 -95
- package/.framework/functions/trigger-scheduler.ts +10 -0
- package/.framework/functions/triggers.ts +179 -149
- package/.framework/functions/types.ts +137 -125
- package/.framework/mcp/index.ts +133 -0
- package/.framework/mcp/load-env.ts +60 -0
- package/.framework/mcp/shared/app-manifest.ts +275 -0
- package/.framework/mcp/shared/db.ts +477 -0
- package/.framework/mcp/shared/kb.ts +118 -0
- package/.framework/mcp/tools/architect.ts +431 -0
- package/.framework/mcp/tools/cil/context.ts +345 -0
- package/.framework/mcp/tools/cil/graph.ts +242 -0
- package/.framework/mcp/tools/cil/ingest.ts +1217 -0
- package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +693 -0
- package/.framework/mcp/tools/cil/pipeline.ts +767 -0
- package/.framework/mcp/tools/cil/project.ts +791 -0
- package/.framework/mcp/tools/cil/retrieval.ts +336 -0
- package/.framework/mcp/tools/cil/search-core.ts +454 -0
- package/.framework/mcp/tools/cil/search.ts +97 -0
- package/.framework/mcp/tools/cil/suggest.ts +186 -0
- package/.framework/mcp/tools/cil/validate.ts +1369 -0
- package/.framework/mcp/tools/kb/delete.ts +139 -0
- package/.framework/mcp/tools/kb/index.ts +52 -0
- package/.framework/mcp/tools/kb/ingest.ts +84 -0
- package/.framework/mcp/tools/kb/list-types.ts +102 -0
- package/.framework/mcp/tools/kb/publish.ts +100 -0
- package/.framework/mcp/tools/kb/reindex.ts +86 -0
- package/.framework/mcp/tools/kb/revoke.ts +85 -0
- package/.framework/mcp/tools/kb/search.ts +101 -0
- package/.framework/mcp/tools/kb/upsert.ts +125 -0
- package/.framework/mcp/tools/observability.ts +510 -0
- package/.framework/migrations/001_core_schema.sql +15 -0
- package/.framework/migrations/002_core_rls_and_functions.sql +15 -0
- package/.framework/migrations/003_core_system_data.sql +16 -1
- package/.framework/migrations/004_core_rpc_and_broker.sql +17 -1
- package/.framework/migrations/005_core_observability.sql +17 -1
- package/.framework/migrations/006_security_hardening_rls.sql +15 -0
- package/.framework/migrations/007_kb_article_list.sql +17 -1
- package/.framework/migrations/008_items_target.sql +15 -0
- package/.framework/migrations/009_roles_slug_unique.sql +15 -0
- package/.framework/migrations/010_auth_user_trigger.sql +15 -0
- package/.framework/migrations/011_spine_system_account.sql +16 -0
- package/.framework/migrations/012_service_role_grants.sql +16 -0
- package/.framework/migrations/013_get_account_apps_role_filter.sql +15 -0
- package/.framework/migrations/014_apps_required_roles.sql +16 -0
- package/.framework/migrations/015_types_kind_slug_unique.sql +15 -0
- package/.framework/migrations/016_cil_types.sql +281 -0
- package/.framework/migrations/017_cil_stable_ids.sql +37 -0
- package/.framework/migrations/018_runtime_tables.sql +129 -0
- package/.framework/migrations/019_agent_prompt_columns.sql +56 -0
- package/.framework/migrations/020_schema_reconciliation.sql +67 -0
- package/.framework/migrations/021_kb_embedding_lifecycle.sql +31 -0
- package/.framework/migrations/032_cil_status_migration.sql +73 -0
- package/.framework/migrations/033_cil_versioning.sql +73 -0
- package/.framework/migrations/034_match_embeddings_knn.sql +115 -0
- package/.framework/migrations/035_rate_limits.sql +55 -0
- package/.framework/migrations/036_demo_record_flags.sql +72 -0
- package/.framework/migrations/037_kb_types_canonical.sql +244 -0
- package/.framework/migrations/038_drop_demo_record_flags.sql +38 -0
- package/.framework/migrations/042_registration_hierarchy.sql +309 -0
- package/.framework/migrations/043_policy_actor_cleanup.sql +39 -0
- package/.framework/migrations/044_match_embeddings_filtered_knn.sql +151 -0
- package/.framework/migrations/045_security_critical_rls.sql +139 -0
- package/.framework/migrations/046_security_missing_rls.sql +79 -0
- package/.framework/migrations/047_people_updated_by.sql +27 -0
- package/.framework/migrations/048_watcher_last_seen_at.sql +24 -0
- package/.framework/migrations/049_security_blocklist.sql +148 -0
- package/.framework/migrations/050_notifications.sql +49 -0
- package/.framework/migrations/051_message_agent_fields.sql +74 -0
- package/.framework/migrations/052_registration_security.sql +421 -0
- package/.framework/migrations/053_builtin_action_seeds.sql +66 -0
- package/.framework/migrations/054_kb_ingest_lease.sql +157 -0
- package/.framework/migrations/055_type_id_drift_reconciliation.sql +33 -0
- package/.framework/migrations/056_slug_column_reconciliation.sql +38 -0
- package/.framework/migrations/057_pipelines_slug_identity.sql +14 -0
- package/.framework/migrations/058_account_data_field_declarations.sql +53 -0
- package/.framework/migrations/059_registration_placement_fixes.sql +269 -0
- package/.framework/migrations/060_account_person_record_permissions.sql +38 -0
- package/.framework/migrations/061_fk_dedup.sql +32 -0
- package/.framework/public/spine-logo.svg +10 -3
- package/.framework/scripts/app-install-cli.ts +190 -93
- package/.framework/scripts/assemble-frontend.sh +127 -44
- package/.framework/scripts/assemble-functions.sh +128 -30
- package/.framework/scripts/boundary-check.sh +6 -2
- package/.framework/scripts/build-manifest.sh +24 -68
- package/.framework/scripts/check-core-integrity.sh +15 -76
- package/.framework/scripts/checksum-manifest.mts +343 -0
- package/.framework/scripts/cil-migrate-markers.ts +403 -0
- package/.framework/scripts/fix-cil-markers.mjs +176 -0
- package/.framework/scripts/verify-integrity.sh +21 -57
- package/.framework/scripts/verify-manifest.mts +305 -0
- package/.framework/seeds/types/funnel_signal_use.json +74 -21
- package/.framework/seeds/types/spine_instance.json +73 -21
- package/.framework/src/App.tsx +118 -72
- package/.framework/src/apps/admin/index.tsx +855 -58
- package/.framework/src/components/AppWrapper.tsx +43 -45
- package/.framework/src/components/CustomAppLoader.tsx +160 -116
- package/.framework/src/components/admin/AdminListPage.tsx +46 -44
- package/.framework/src/components/admin/AdminSidebar.tsx +57 -47
- package/.framework/src/components/admin/AdminStatsCard.tsx +46 -44
- package/.framework/src/components/admin/PageInstructions.tsx +98 -2
- package/.framework/src/components/admin/SortableTableHeader.tsx +44 -45
- package/.framework/src/components/app-shell/GenericAppShell.tsx +64 -65
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +44 -47
- package/.framework/src/components/app-shell/GenericListPage.tsx +45 -49
- package/.framework/src/components/app-sidebar.tsx +42 -45
- package/.framework/src/components/auth/ProtectedRoute.tsx +48 -41
- package/.framework/src/components/auth/TurnstileWidget.tsx +27 -0
- package/.framework/src/components/kb/KBArticleEditor.tsx +231 -22
- package/.framework/src/components/kb/KBArticleList.tsx +251 -10
- package/.framework/src/components/layout/AppShell.tsx +51 -45
- package/.framework/src/components/layout/Header.tsx +42 -43
- package/.framework/src/components/layout/Layout.tsx +46 -46
- package/.framework/src/components/layout/Sidebar.tsx +196 -96
- package/.framework/src/components/runtime/DataDetailHeader.tsx +55 -30
- package/.framework/src/components/runtime/DataDetailPage.tsx +31 -269
- package/.framework/src/components/runtime/DataFilters.tsx +49 -74
- package/.framework/src/components/runtime/DataHeader.tsx +53 -32
- package/.framework/src/components/runtime/DataListPage.tsx +51 -155
- package/.framework/src/components/runtime/DataStats.tsx +66 -44
- package/.framework/src/components/runtime/DataTable.tsx +49 -149
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +45 -75
- package/.framework/src/components/runtime/index.ts +119 -16
- package/.framework/src/components/search-form.tsx +46 -29
- package/.framework/src/components/shared/AgentView.tsx +65 -48
- package/.framework/src/components/shared/FieldRenderer.tsx +144 -50
- package/.framework/src/components/shared/InviteManager.tsx +207 -97
- package/.framework/src/components/shared/MemberList.tsx +97 -0
- package/.framework/src/components/shared/SchemaFields.tsx +107 -86
- package/.framework/src/components/ui/DataTable.tsx +80 -68
- package/.framework/src/components/ui/Form.tsx +157 -146
- package/.framework/src/components/ui/ItemCard.tsx +74 -67
- package/.framework/src/components/ui/ItemListView.tsx +73 -68
- package/.framework/src/components/ui/LoadingSpinner.tsx +43 -48
- package/.framework/src/components/ui/Modal.tsx +78 -68
- package/.framework/src/components/ui/RichTextEditor.tsx +89 -69
- package/.framework/src/components/ui/accordion.tsx +85 -86
- package/.framework/src/components/ui/alert-dialog.tsx +197 -184
- package/.framework/src/components/ui/alert.tsx +105 -94
- package/.framework/src/components/ui/aspect-ratio.tsx +57 -43
- package/.framework/src/components/ui/avatar.tsx +122 -107
- package/.framework/src/components/ui/badge.tsx +60 -55
- package/.framework/src/components/ui/breadcrumb.tsx +127 -128
- package/.framework/src/components/ui/button-group.tsx +86 -72
- package/.framework/src/components/ui/button.tsx +71 -50
- package/.framework/src/components/ui/calendar.tsx +72 -57
- package/.framework/src/components/ui/card.tsx +136 -129
- package/.framework/src/components/ui/carousel.tsx +226 -107
- package/.framework/src/components/ui/chart.tsx +252 -147
- package/.framework/src/components/ui/checkbox.tsx +43 -44
- package/.framework/src/components/ui/collapsible.tsx +86 -71
- package/.framework/src/components/ui/combobox.tsx +282 -249
- package/.framework/src/components/ui/command.tsx +158 -146
- package/.framework/src/components/ui/context-menu.tsx +239 -240
- package/.framework/src/components/ui/dialog.tsx +174 -157
- package/.framework/src/components/ui/direction.tsx +72 -56
- package/.framework/src/components/ui/drawer.tsx +168 -169
- package/.framework/src/components/ui/dropdown-menu.tsx +254 -223
- package/.framework/src/components/ui/empty.tsx +131 -120
- package/.framework/src/components/ui/field.tsx +205 -173
- package/.framework/src/components/ui/hover-card.tsx +71 -72
- package/.framework/src/components/ui/input-group.tsx +148 -133
- package/.framework/src/components/ui/input-otp.tsx +99 -86
- package/.framework/src/components/ui/input.tsx +43 -41
- package/.framework/src/components/ui/item.tsx +207 -185
- package/.framework/src/components/ui/kbd.tsx +57 -56
- package/.framework/src/components/ui/label.tsx +45 -41
- package/.framework/src/components/ui/menubar.tsx +268 -236
- package/.framework/src/components/ui/native-select.tsx +85 -86
- package/.framework/src/components/ui/navigation-menu.tsx +166 -156
- package/.framework/src/components/ui/pagination.tsx +131 -141
- package/.framework/src/components/ui/popover.tsx +125 -128
- package/.framework/src/components/ui/progress.tsx +47 -44
- package/.framework/src/components/ui/radio-group.tsx +60 -55
- package/.framework/src/components/ui/resizable.tsx +85 -72
- package/.framework/src/components/ui/scroll-area.tsx +57 -58
- package/.framework/src/components/ui/select.tsx +182 -169
- package/.framework/src/components/ui/separator.tsx +42 -43
- package/.framework/src/components/ui/sheet.tsx +170 -159
- package/.framework/src/components/ui/sidebar.tsx +395 -398
- package/.framework/src/components/ui/skeleton.tsx +42 -43
- package/.framework/src/components/ui/slider.tsx +61 -44
- package/.framework/src/components/ui/sonner.tsx +44 -44
- package/.framework/src/components/ui/spinner.tsx +47 -42
- package/.framework/src/components/ui/switch.tsx +56 -42
- package/.framework/src/components/ui/table-primitives.tsx +272 -132
- package/.framework/src/components/ui/table.tsx +140 -142
- package/.framework/src/components/ui/tabs.tsx +110 -93
- package/.framework/src/components/ui/textarea.tsx +43 -44
- package/.framework/src/components/ui/toggle-group.tsx +87 -71
- package/.framework/src/components/ui/toggle.tsx +56 -56
- package/.framework/src/components/ui/tooltip.tsx +99 -85
- package/.framework/src/contexts/AppContext.tsx +166 -114
- package/.framework/src/contexts/AuthContext.tsx +232 -137
- package/.framework/src/hooks/use-mobile.ts +43 -44
- package/.framework/src/hooks/useApi.ts +185 -172
- package/.framework/src/hooks/useAppPath.ts +31 -29
- package/.framework/src/hooks/useApps.ts +77 -42
- package/.framework/src/hooks/useEntityList.ts +66 -29
- package/.framework/src/hooks/useEntityRecord.ts +76 -32
- package/.framework/src/hooks/useForm.ts +62 -30
- package/.framework/src/hooks/useListSchema.ts +60 -43
- package/.framework/src/hooks/useSchemaRecord.ts +115 -95
- package/.framework/src/lib/api.ts +258 -134
- package/.framework/src/lib/registration.ts +181 -0
- package/.framework/src/lib/supabase.ts +118 -81
- package/.framework/src/lib/utils.ts +266 -266
- package/.framework/src/main.tsx +43 -44
- package/.framework/src/pages/DashboardPage.tsx +44 -43
- package/.framework/src/pages/NoAppPage.tsx +50 -0
- package/.framework/src/pages/NotFoundPage.tsx +32 -29
- package/.framework/src/pages/SetupPage.tsx +34 -33
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +69 -58
- package/.framework/src/pages/admin/AIAgentsPage.tsx +43 -40
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +63 -55
- package/.framework/src/pages/admin/APIKeysPage.tsx +44 -42
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +117 -94
- package/.framework/src/pages/admin/AppDetailPage.tsx +48 -42
- package/.framework/src/pages/admin/AppsPage.tsx +45 -42
- package/.framework/src/pages/admin/DeliveriesPage.tsx +49 -17
- package/.framework/src/pages/admin/DesignedPage.tsx +31 -30
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +58 -0
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +49 -0
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +31 -29
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +46 -29
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -29
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +68 -55
- package/.framework/src/pages/admin/IntegrationsPage.tsx +45 -42
- package/.framework/src/pages/admin/InvitesPage.tsx +60 -44
- package/.framework/src/pages/admin/LogsPage.tsx +87 -137
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +31 -29
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +150 -89
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +77 -104
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +44 -43
- package/.framework/src/pages/admin/PipelinesPage.tsx +59 -145
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +53 -42
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +47 -117
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +31 -44
- package/.framework/src/pages/admin/RoleDetailPage.tsx +49 -92
- package/.framework/src/pages/admin/RolesPage.tsx +47 -164
- package/.framework/src/pages/admin/SecurityPage.tsx +310 -0
- package/.framework/src/pages/admin/SelectTestPage.tsx +30 -32
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +37 -44
- package/.framework/src/pages/admin/SimpleDashboard.tsx +32 -44
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +97 -44
- package/.framework/src/pages/admin/TestingDashboard.tsx +126 -71
- package/.framework/src/pages/admin/TimerDetailPage.tsx +67 -55
- package/.framework/src/pages/admin/TimersPage.tsx +44 -42
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +47 -42
- package/.framework/src/pages/admin/TriggersPage.tsx +58 -57
- package/.framework/src/pages/admin/TypeDetailPage.tsx +91 -55
- package/.framework/src/pages/admin/TypesPage.tsx +45 -42
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +258 -128
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +127 -123
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +308 -235
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +159 -110
- package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +432 -0
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +200 -178
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +286 -239
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +211 -90
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +156 -143
- package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +379 -0
- package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +337 -0
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +219 -214
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +135 -65
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +39 -31
- package/.framework/src/pages/auth/LoginPage.tsx +38 -32
- package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -28
- package/.framework/src/pages/auth/RegisterPage.tsx +429 -155
- package/.framework/src/pages/spine-framework/APIPage.tsx +33 -30
- package/.framework/src/pages/spine-framework/CLIPage.tsx +32 -30
- package/.framework/src/types/auth.ts +101 -93
- package/.framework/src/types/types.ts +283 -262
- package/.framework/templates/project.json +87 -0
- package/.framework/templates/spine.config.neutral.json +7 -0
- package/.framework/tests/api/api-surface.test.ts +381 -0
- package/.framework/tests/fixtures/seed.ts +427 -0
- package/.framework/tests/fixtures/teardown.ts +228 -0
- package/.framework/tests/reporter.ts +351 -0
- package/.framework/tests/setup.ts +135 -0
- package/.framework/tests/ui/ui-sweep.ts +278 -0
- package/.framework/tests/unit/admin-data-logger.test.ts +310 -0
- package/.framework/tests/unit/agent-runner.test.ts +2389 -0
- package/.framework/tests/unit/ai-interactions.test.ts +81 -0
- package/.framework/tests/unit/app-manifest.test.ts +359 -0
- package/.framework/tests/unit/assembly-scripts.test.ts +172 -0
- package/.framework/tests/unit/cil-determinism.test.ts +85 -0
- package/.framework/tests/unit/core-isolation.test.ts +153 -0
- package/.framework/tests/unit/funnel-signals.test.ts +135 -0
- package/.framework/tests/unit/install-app.test.ts +1759 -0
- package/.framework/tests/unit/invites-security.test.ts +572 -0
- package/.framework/tests/unit/kb-ingest-lease.test.ts +287 -0
- package/.framework/tests/unit/kb-search.test.ts +119 -0
- package/.framework/tests/unit/migrate.test.ts +509 -0
- package/.framework/tests/unit/notify.test.ts +136 -0
- package/.framework/tests/unit/permissions.test.ts +269 -0
- package/.framework/tests/unit/pipeline-runner.test.ts +755 -0
- package/.framework/tests/unit/principal-cache.test.ts +138 -0
- package/.framework/tests/unit/retrieval-golden.test.ts +520 -0
- package/.framework/tests/unit/runtime-isolation.test.ts +642 -0
- package/.framework/tests/unit/schema-utils.test.ts +225 -0
- package/.framework/tests/unit/trigger-engine.test.ts +513 -0
- package/.framework/tests/unit/validate-app.test.ts +527 -0
- package/README.md +34 -3
- package/bin/spine-framework.cjs +1 -0
- package/config/tailwind.config.cjs +7 -0
- package/config/tsconfig.functions.json +42 -0
- package/config/tsconfig.json +37 -9
- package/config/vite.config.ts +31 -2
- package/netlify.toml +31 -3
- package/package.json +46 -29
- package/scripts/assemble-frontend.sh +127 -44
- package/scripts/assemble-functions.sh +127 -29
- package/scripts/boundary-check.sh +6 -2
- package/scripts/build-manifest.sh +24 -68
- package/scripts/checksum-manifest.mts +345 -0
- package/scripts/dev-clean.sh +86 -0
- package/scripts/dev-netlify.sh +49 -0
- package/scripts/netlify-dev-wrapper.sh +2 -0
- package/scripts/verify-install.ts +358 -0
- package/scripts/verify-integrity.sh +21 -57
- package/scripts/verify-manifest.mts +305 -0
- package/templates/project/gitignore +45 -0
- package/{config → templates/project}/package-lock.json +22335 -9366
- package/vitest.config.ts +46 -0
- package/.framework/public/spine.config.json +0 -91
- package/config/deno.lock +0 -108
- package/config/tsconfig.node.tsbuildinfo +0 -1
- package/config/tsconfig.tsbuildinfo +0 -1
- package/config/vite.config.d.ts +0 -2
- package/custom/.devin/AGENT.md +0 -357
- package/custom/.devin/skills/install-app/SKILL.md +0 -39
- package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +0 -39
- package/custom/.devin/skills/spine-workbench-idea/SKILL.md +0 -36
- package/custom/.devin/skills/spine-workbench-implement/SKILL.md +0 -46
- package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +0 -28
- package/custom/.devin/skills/spine-workbench-plan/SKILL.md +0 -38
- package/custom/.devin/workflows/app-install.yaml +0 -83
- package/custom/README.md +0 -79
- package/docs/README.md +0 -15
- package/scripts/app-install-cli.ts +0 -286
- package/scripts/check-core-integrity.sh +0 -82
- package/scripts/ingest-chunks.cjs +0 -202
- package/scripts/kb-chunk-parser.cjs +0 -312
- package/scripts/kb-chunk-parser.ts +0 -330
- package/scripts/kb-ingest-docs.ts +0 -203
- package/scripts/load-test-app-install.ts +0 -484
- package/scripts/test-login.js +0 -33
- package/spine.config.json +0 -91
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Import Node.js and shared CIL utilities used by the marker migration script"]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide the module-level imports required by the rest of the script"]
|
|
4
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Import fs/promises, path, and shared CIL helpers" notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
8
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="system-admin"]
|
|
10
|
+
import * as fs from 'fs/promises'
|
|
11
|
+
import * as path from 'path'
|
|
12
|
+
import { toCanonicalPath, generateStableId } from '../functions/_shared/cil'
|
|
13
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Import Node.js and shared CIL utilities used by the marker migration script'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
14
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
15
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
16
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
17
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
18
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
19
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:module_header:module_header"]
|
|
20
|
+
|
|
21
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:MarkerRewrite:interface" type="interface" identity="MarkerRewrite" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
22
|
+
// CIL[DOC-MACRO purpose="Define the shape of a marker rewrite result for a single file"]
|
|
23
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Type the per-file rewrite report consumed by the main report"]
|
|
24
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts,.framework/scripts/cil-migrate-markers.ts"]
|
|
25
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
26
|
+
// CIL[DOC-MICRO logic_summary="Declare an interface with file, rewrite count and error list fields" notable_decisions="[]"]
|
|
27
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
28
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
29
|
+
interface MarkerRewrite {
|
|
30
|
+
file: string
|
|
31
|
+
rewrites: number
|
|
32
|
+
errors: string[]
|
|
33
|
+
}
|
|
34
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Define the shape of a marker rewrite result for a single file'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
35
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
36
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
37
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
38
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
39
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
40
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:MarkerRewrite:interface"]
|
|
41
|
+
|
|
42
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:LEGACY_PATTERNS:constant" type="constant" identity="LEGACY_PATTERNS" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
43
|
+
// CIL[DOC-MACRO purpose="Define legacy marker patterns recognized for migration"]
|
|
44
|
+
// CIL[DOC-RESPONSIBILITY responsibility="List regular expressions that identify old CHUNK_START/CHUNK_END markers"]
|
|
45
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts,.framework/scripts/cil-migrate-markers.ts"]
|
|
46
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
47
|
+
// CIL[DOC-MICRO logic_summary="Store a single pattern object with begin and end regexes" notable_decisions="[]"]
|
|
48
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
49
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
50
|
+
const LEGACY_PATTERNS = [
|
|
51
|
+
{
|
|
52
|
+
name: 'chunk_start_end',
|
|
53
|
+
begin: /^([ \t]*\/\*\*\s*───\s*CHUNK_START:\s*(.+?)\s*───\s*\*\/)/,
|
|
54
|
+
end: /^([ \t]*\/\*\*\s*───\s*CHUNK_END:\s*(.+?)\s*───\s*\*\/)/,
|
|
55
|
+
},
|
|
56
|
+
]
|
|
57
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Define legacy marker patterns recognized for migration'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
58
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
59
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
60
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
61
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
62
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
63
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:LEGACY_PATTERNS:constant"]
|
|
64
|
+
|
|
65
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:TS_JS:constant" type="constant" identity="TS_JS" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
66
|
+
// CIL[DOC-MACRO purpose="List file extensions treated as TypeScript or JavaScript"]
|
|
67
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Drive comment-prefix selection for TS/JS source files"]
|
|
68
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts,.framework/scripts/cil-migrate-markers.ts"]
|
|
69
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
70
|
+
// CIL[DOC-MICRO logic_summary="Declare an array of TypeScript and JavaScript extensions" notable_decisions="[]"]
|
|
71
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
72
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
73
|
+
const TS_JS = ['.ts', '.tsx', '.js', '.jsx']
|
|
74
|
+
// CIL[DOC-VECTOR type="context" content="purpose='List file extensions treated as TypeScript or JavaScript'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
75
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
76
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
77
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
78
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
79
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
80
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:TS_JS:constant"]
|
|
81
|
+
|
|
82
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:parseIdentityFromChunkId:function" type="function" identity="parseIdentityFromChunkId" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
83
|
+
// CIL[DOC-MACRO purpose="Extract a human-readable identity from a legacy chunk id"]
|
|
84
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Convert legacy chunk id strings to stable identities"]
|
|
85
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts,.framework/scripts/cil-migrate-markers.ts"]
|
|
86
|
+
// CIL[DOC-CONTRACT inputs="chunkId: string | undefined" outputs="string" errors="none" side_effects="none"]
|
|
87
|
+
// CIL[DOC-MICRO logic_summary="Split the chunk id and derive an identity from trailing underscore-separated parts" notable_decisions="[]"]
|
|
88
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
89
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
90
|
+
function parseIdentityFromChunkId(chunkId: string | undefined): string {
|
|
91
|
+
if (!chunkId) return 'unknown'
|
|
92
|
+
const parts = chunkId.split('_')
|
|
93
|
+
if (parts.length < 2) return chunkId
|
|
94
|
+
const epoch = parts.pop()
|
|
95
|
+
const nameParts = parts.slice(1)
|
|
96
|
+
return nameParts.length > 0 ? nameParts.join('_') : epoch || chunkId
|
|
97
|
+
}
|
|
98
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Extract a human-readable identity from a legacy chunk id'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
99
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
100
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
101
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
102
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
103
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
104
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:parseIdentityFromChunkId:function"]
|
|
105
|
+
|
|
106
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:guessType:function" type="function" identity="guessType" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
107
|
+
// CIL[DOC-MACRO purpose="Infer a CIL chunk type from a symbol name"]
|
|
108
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Assign type labels such as method, class, hook or function when no explicit type is given"]
|
|
109
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts,.framework/scripts/cil-migrate-markers.ts"]
|
|
110
|
+
// CIL[DOC-CONTRACT inputs="name: string" outputs="string" errors="none" side_effects="none"]
|
|
111
|
+
// CIL[DOC-MICRO logic_summary="Apply heuristics based on dots, initial capitalization and use prefix" notable_decisions="[]"]
|
|
112
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
113
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
114
|
+
function guessType(name: string): string {
|
|
115
|
+
if (!name) return 'unknown'
|
|
116
|
+
if (name.includes('.')) return 'method'
|
|
117
|
+
if (name[0] === name[0].toUpperCase()) return 'class'
|
|
118
|
+
if (name.startsWith('use') && name.length > 3 && name[3] === name[3].toUpperCase()) return 'hook'
|
|
119
|
+
return 'function'
|
|
120
|
+
}
|
|
121
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Infer a CIL chunk type from a symbol name'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
122
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
123
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
124
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
125
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
126
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
127
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:guessType:function"]
|
|
128
|
+
|
|
129
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:parseStableId:function" type="function" identity="parseStableId" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
130
|
+
// CIL[DOC-MACRO purpose="Parse a stable id string to extract identity and type"]
|
|
131
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Recover chunk identity and type from stable id colons"]
|
|
132
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts,.framework/scripts/cil-migrate-markers.ts"]
|
|
133
|
+
// CIL[DOC-CONTRACT inputs="stableId: string" outputs="{ identity, type }" errors="none" side_effects="none"]
|
|
134
|
+
// CIL[DOC-MICRO logic_summary="Split by colon and return the last two segments as identity and type" notable_decisions="[]"]
|
|
135
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
136
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
137
|
+
function parseStableId(stableId: string): { identity: string; type: string } {
|
|
138
|
+
const parts = stableId.split(':')
|
|
139
|
+
return {
|
|
140
|
+
identity: parts.length >= 2 ? parts[parts.length - 2] : 'unknown',
|
|
141
|
+
type: parts.length >= 1 ? parts[parts.length - 1] : 'unknown',
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Parse a stable id string to extract identity and type'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
145
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
146
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
147
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
148
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
149
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
150
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:parseStableId:function"]
|
|
151
|
+
|
|
152
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:markerPrefix:function" type="function" identity="markerPrefix" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
153
|
+
// CIL[DOC-MACRO purpose="Choose the correct comment syntax for CIL markers in a file"]
|
|
154
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Return the prefix and suffix for CIL comments based on file extension"]
|
|
155
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts,.framework/scripts/cil-migrate-markers.ts"]
|
|
156
|
+
// CIL[DOC-CONTRACT inputs="filePath: string" outputs="{ prefix, suffix }" errors="none" side_effects="none"]
|
|
157
|
+
// CIL[DOC-MICRO logic_summary="Map file extensions to //, --, # or HTML comment markers" notable_decisions="[]"]
|
|
158
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
159
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
160
|
+
function markerPrefix(filePath: string): { prefix: string; suffix: string } {
|
|
161
|
+
const ext = path.extname(filePath)
|
|
162
|
+
if (TS_JS.includes(ext)) return { prefix: '// ', suffix: '' }
|
|
163
|
+
if (['.sql', '.psql'].includes(ext)) return { prefix: '-- ', suffix: '' }
|
|
164
|
+
if (['.sh', '.bash', '.yaml', '.yml', '.py'].includes(ext)) return { prefix: '# ', suffix: '' }
|
|
165
|
+
if (['.md', '.mdx'].includes(ext)) return { prefix: '<!-- ', suffix: ' -->' }
|
|
166
|
+
return { prefix: '// ', suffix: '' }
|
|
167
|
+
}
|
|
168
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Choose the correct comment syntax for CIL markers in a file'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
169
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
170
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
171
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
172
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
173
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
174
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:markerPrefix:function"]
|
|
175
|
+
|
|
176
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:SKIP_DIRS:constant" type="constant" identity="SKIP_DIRS" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
177
|
+
// CIL[DOC-MACRO purpose="Define directories excluded from recursive file walking"]
|
|
178
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Prevent scanning of build output and dependency folders"]
|
|
179
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts,.framework/scripts/cil-migrate-markers.ts"]
|
|
180
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
181
|
+
// CIL[DOC-MICRO logic_summary="Create a Set of directory names to ignore during traversal" notable_decisions="[]"]
|
|
182
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
183
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
184
|
+
const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.devin', 'tmp', 'temp', '.assembled', '.netlify', '.next', '.output', 'coverage'])
|
|
185
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Define directories excluded from recursive file walking'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
186
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
187
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
188
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
189
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
190
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
191
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:SKIP_DIRS:constant"]
|
|
192
|
+
|
|
193
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:walk:function" type="function" identity="walk" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
194
|
+
// CIL[DOC-MACRO purpose="Recursively enumerate files under a directory"]
|
|
195
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Yield absolute file paths while skipping symlinks and ignored directories"]
|
|
196
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts,.framework/scripts/cil-migrate-markers.ts"]
|
|
197
|
+
// CIL[DOC-CONTRACT inputs="dir: string" outputs="AsyncGenerator<string>" errors="rethrows fs errors" side_effects="none"]
|
|
198
|
+
// CIL[DOC-MICRO logic_summary="Read a directory, recurse into subdirectories and yield regular files" notable_decisions="[]"]
|
|
199
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
200
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
201
|
+
async function* walk(dir: string): AsyncGenerator<string> {
|
|
202
|
+
const entries = await fs.readdir(dir)
|
|
203
|
+
for (const entry of entries) {
|
|
204
|
+
const full = path.join(dir, entry)
|
|
205
|
+
const stat = await fs.lstat(full)
|
|
206
|
+
if (stat.isSymbolicLink()) continue
|
|
207
|
+
if (stat.isDirectory()) {
|
|
208
|
+
if (SKIP_DIRS.has(path.basename(full))) continue
|
|
209
|
+
yield* walk(full)
|
|
210
|
+
} else if (stat.isFile()) {
|
|
211
|
+
yield full
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Recursively enumerate files under a directory'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
216
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
217
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
218
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
219
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
220
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
221
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:walk:function"]
|
|
222
|
+
|
|
223
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:rewriteFileMarkers:function" type="function" identity="rewriteFileMarkers" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
224
|
+
// CIL[DOC-MACRO purpose="Rewrite legacy markers in a single file to stable CIL markers"]
|
|
225
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Normalize chunk markers and persist or preview the updated file"]
|
|
226
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts,.framework/scripts/cil-migrate-markers.ts"]
|
|
227
|
+
// CIL[DOC-CONTRACT inputs="absolutePath: string, repoRoot: string, dryRun: boolean" outputs="MarkerRewrite" errors="pushes error messages into result" side_effects="writes file when not in dry-run mode"]
|
|
228
|
+
// CIL[DOC-MICRO logic_summary="Scan each line, convert legacy and chunk-id markers to stable markers, then write if needed" notable_decisions="[]"]
|
|
229
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
230
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
231
|
+
async function rewriteFileMarkers(absolutePath: string, repoRoot: string, dryRun: boolean): Promise<MarkerRewrite> {
|
|
232
|
+
const rel = path.relative(repoRoot, absolutePath)
|
|
233
|
+
const canonical = toCanonicalPath(repoRoot, absolutePath)
|
|
234
|
+
const content = await fs.readFile(absolutePath, 'utf-8')
|
|
235
|
+
const lines = content.split('\n')
|
|
236
|
+
const { prefix, suffix } = markerPrefix(absolutePath)
|
|
237
|
+
const result: string[] = []
|
|
238
|
+
const legacyToStable: Record<string, string> = {}
|
|
239
|
+
let rewrites = 0
|
|
240
|
+
const errors: string[] = []
|
|
241
|
+
|
|
242
|
+
for (let i = 0; i < lines.length; i++) {
|
|
243
|
+
const line = lines[i]
|
|
244
|
+
let matched = false
|
|
245
|
+
|
|
246
|
+
for (const pattern of LEGACY_PATTERNS) {
|
|
247
|
+
const beginMatch = line.match(pattern.begin)
|
|
248
|
+
if (beginMatch) {
|
|
249
|
+
const name = beginMatch[2].trim()
|
|
250
|
+
const type = guessType(name)
|
|
251
|
+
const stableId = generateStableId(canonical, name, type)
|
|
252
|
+
legacyToStable[name] = stableId
|
|
253
|
+
result.push(`${beginMatch[1].match(/^[ \t]*/)?.[0] || ''}${prefix}CIL[BEGIN stable_id="${stableId}"]${suffix}`)
|
|
254
|
+
rewrites++
|
|
255
|
+
matched = true
|
|
256
|
+
break
|
|
257
|
+
}
|
|
258
|
+
const endMatch = line.match(pattern.end)
|
|
259
|
+
if (endMatch) {
|
|
260
|
+
const name = endMatch[2].trim()
|
|
261
|
+
const stableId = legacyToStable[name] || generateStableId(canonical, name, guessType(name))
|
|
262
|
+
result.push(`${endMatch[1].match(/^[ \t]*/)?.[0] || ''}${prefix}CIL[END stable_id="${stableId}"]${suffix}`)
|
|
263
|
+
rewrites++
|
|
264
|
+
matched = true
|
|
265
|
+
break
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (!matched) {
|
|
270
|
+
// template: CIL[BEGIN stable_id="..." type="method" identity="..." parent="none"]
|
|
271
|
+
const cilBegin = line.match(/(\s*)(\/\/|#|--|<!--)\s*CIL\[BEGIN\s+([^\]]+)\]/)
|
|
272
|
+
if (cilBegin) {
|
|
273
|
+
const attr = cilBegin[3]
|
|
274
|
+
const stableId = attr.match(/stable_id="([^"]+)"/)?.[1]
|
|
275
|
+
if (!attr.includes('chunk_id="') && stableId) {
|
|
276
|
+
// Already-migrated stable marker — ensure it has type/identity/parent
|
|
277
|
+
if (attr.includes('identity="') && attr.includes('type="') && attr.includes('parent="')) {
|
|
278
|
+
result.push(line)
|
|
279
|
+
continue
|
|
280
|
+
}
|
|
281
|
+
const { identity, type } = parseStableId(stableId)
|
|
282
|
+
const parent = attr.match(/parent="([^"]+)"/)?.[1] || 'none'
|
|
283
|
+
result.push(`${cilBegin[1]}${prefix}CIL[BEGIN stable_id="${stableId}" type="${type}" identity="${identity}" parent="${parent}"]${suffix}`)
|
|
284
|
+
rewrites++
|
|
285
|
+
continue
|
|
286
|
+
}
|
|
287
|
+
const chunkId = attr.match(/chunk_id="([^"]+)"/)?.[1]
|
|
288
|
+
const identity = attr.match(/identity="([^"]+)"/)?.[1] || parseIdentityFromChunkId(chunkId)
|
|
289
|
+
const type = attr.match(/type="([^"]+)"/)?.[1] || guessType(identity)
|
|
290
|
+
const stableIdFromChunk = generateStableId(canonical, identity, type)
|
|
291
|
+
if (chunkId) legacyToStable[chunkId] = stableIdFromChunk
|
|
292
|
+
result.push(`${cilBegin[1]}${prefix}CIL[BEGIN stable_id="${stableIdFromChunk}" type="${type}" identity="${identity}" parent="none"]${suffix}`)
|
|
293
|
+
rewrites++
|
|
294
|
+
continue
|
|
295
|
+
}
|
|
296
|
+
const cilEnd = line.match(/(\s*)(\/\/|#|--|<!--)\s*CIL\[END\s+([^\]]+)\]/)
|
|
297
|
+
if (cilEnd) {
|
|
298
|
+
const attr = cilEnd[3]
|
|
299
|
+
const stableId = attr.match(/stable_id="([^"]+)"/)?.[1]
|
|
300
|
+
if (!attr.includes('chunk_id="') && stableId) {
|
|
301
|
+
// Already-migrated stable end marker — keep as-is
|
|
302
|
+
result.push(line)
|
|
303
|
+
continue
|
|
304
|
+
}
|
|
305
|
+
const chunkId = attr.match(/chunk_id="([^"]+)"/)?.[1]
|
|
306
|
+
const stableIdFromChunk = chunkId ? legacyToStable[chunkId] : undefined
|
|
307
|
+
if (!stableIdFromChunk) {
|
|
308
|
+
const identity = attr.match(/identity="([^"]+)"/)?.[1] || parseIdentityFromChunkId(chunkId)
|
|
309
|
+
const type = attr.match(/type="([^"]+)"/)?.[1] || guessType(identity)
|
|
310
|
+
result.push(`${cilEnd[1]}${prefix}CIL[END stable_id="${generateStableId(canonical, identity, type)}"${suffix}`)
|
|
311
|
+
} else {
|
|
312
|
+
result.push(`${cilEnd[1]}${prefix}CIL[END stable_id="${stableIdFromChunk}"]${suffix}`)
|
|
313
|
+
}
|
|
314
|
+
rewrites++
|
|
315
|
+
continue
|
|
316
|
+
}
|
|
317
|
+
result.push(line)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const newContent = result.join('\n')
|
|
322
|
+
if (!dryRun && newContent !== content) {
|
|
323
|
+
await fs.writeFile(absolutePath, newContent, 'utf-8')
|
|
324
|
+
}
|
|
325
|
+
return { file: rel, rewrites, errors }
|
|
326
|
+
}
|
|
327
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Rewrite legacy markers in a single file to stable CIL markers'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
328
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
329
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
330
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
331
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
332
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
333
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:rewriteFileMarkers:function"]
|
|
334
|
+
|
|
335
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:main:function" type="function" identity="main" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
336
|
+
// CIL[DOC-MACRO purpose="Walk a project tree and migrate legacy CIL markers to stable markers"]
|
|
337
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Orchestrate file discovery, per-file marker rewriting and a summary report"]
|
|
338
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts,.framework/scripts/cil-migrate-markers.ts"]
|
|
339
|
+
// CIL[DOC-CONTRACT inputs="process.argv flags" outputs="console report" errors="logs per-file errors to stderr" side_effects="updates marker comments in files unless in dry-run mode"]
|
|
340
|
+
// CIL[DOC-MICRO logic_summary="Parse CLI arguments, walk the project tree, call rewriteFileMarkers for each file and print a report" notable_decisions="[]"]
|
|
341
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
342
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
343
|
+
async function main() {
|
|
344
|
+
const args = process.argv.slice(2)
|
|
345
|
+
const repoRootArg = args.find(a => a.startsWith('--repo-root='))?.split('=')[1] || process.cwd()
|
|
346
|
+
const projectPathArg = args.find(a => a.startsWith('--project-path='))?.split('=')[1] || ''
|
|
347
|
+
const dryRun = args.includes('--dry-run')
|
|
348
|
+
const repoRoot = path.resolve(repoRootArg)
|
|
349
|
+
const projectDir = projectPathArg ? path.resolve(repoRoot, projectPathArg) : repoRoot
|
|
350
|
+
|
|
351
|
+
const report: MarkerRewrite[] = []
|
|
352
|
+
for await (const file of walk(projectDir)) {
|
|
353
|
+
if (file.includes('node_modules') || file.includes('.git')) continue
|
|
354
|
+
try {
|
|
355
|
+
const res = await rewriteFileMarkers(file, repoRoot, dryRun)
|
|
356
|
+
if (res.rewrites > 0) {
|
|
357
|
+
if (dryRun) {
|
|
358
|
+
console.log(`[dry-run] would rewrite ${res.rewrites} markers in ${res.file}`)
|
|
359
|
+
} else {
|
|
360
|
+
console.log(`rewrote ${res.rewrites} markers in ${res.file}`)
|
|
361
|
+
}
|
|
362
|
+
report.push(res)
|
|
363
|
+
}
|
|
364
|
+
} catch (err: any) {
|
|
365
|
+
console.error(`error in ${file}:`, err.message)
|
|
366
|
+
report.push({ file: path.relative(repoRoot, file), rewrites: 0, errors: [err.message] })
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const total = report.reduce((s, r) => s + r.rewrites, 0)
|
|
371
|
+
const errorCount = report.filter(r => r.errors.length > 0).length
|
|
372
|
+
console.log('\n--- report ---')
|
|
373
|
+
console.log(`files touched: ${report.filter(r => r.rewrites > 0).length}`)
|
|
374
|
+
console.log(`markers rewritten: ${total}`)
|
|
375
|
+
console.log(`errors: ${errorCount}`)
|
|
376
|
+
}
|
|
377
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Walk a project tree and migrate legacy CIL markers to stable markers'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
378
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
379
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
380
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
381
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
382
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
383
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:main:function"]
|
|
384
|
+
|
|
385
|
+
// CIL[BEGIN stable_id="~/.framework/scripts/cil-migrate-markers.ts:module_footer:module_footer" type="module_footer" identity="module_footer" parent="~/.framework/scripts/cil-migrate-markers.ts"]
|
|
386
|
+
// CIL[DOC-MACRO purpose="Execute the main entry point and handle uncaught errors"]
|
|
387
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Call main and exit with a non-zero code on failure"]
|
|
388
|
+
// CIL[DOC-CONTEXT module="cil-migrate-markers" layer="infrastructure" related_files=".framework/functions/_shared/cil.ts,.framework/scripts/cil-migrate-markers.ts"]
|
|
389
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="prints to stderr and exits 1" side_effects="triggers top-level async main execution"]
|
|
390
|
+
// CIL[DOC-MICRO logic_summary="Invoke main and attach a catch handler that logs and exits" notable_decisions="[]"]
|
|
391
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
392
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
393
|
+
main().catch(err => {
|
|
394
|
+
console.error(err)
|
|
395
|
+
process.exit(1)
|
|
396
|
+
})
|
|
397
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Execute the main entry point and handle uncaught errors'; No verified external callers; imports: .framework/functions/_shared/cil.ts"]
|
|
398
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
399
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
400
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
401
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
402
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
403
|
+
// CIL[END stable_id="~/.framework/scripts/cil-migrate-markers.ts:module_footer:module_footer"]
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import crypto from 'node:crypto'
|
|
4
|
+
import ts from 'typescript'
|
|
5
|
+
|
|
6
|
+
const STABLE_ID_PREFIX = '~'
|
|
7
|
+
|
|
8
|
+
function toCanonicalPath(repoRoot, absolutePath) {
|
|
9
|
+
const rel = absolutePath.startsWith(repoRoot) ? absolutePath.slice(repoRoot.length) : absolutePath
|
|
10
|
+
const normalized = rel.replace(/\\/g, '/').replace(/^\/+/, '')
|
|
11
|
+
return normalized ? `${STABLE_ID_PREFIX}/${normalized}` : `${STABLE_ID_PREFIX}/`
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function collapseBlankLines(lines) {
|
|
15
|
+
const result = []
|
|
16
|
+
let lastBlank = false
|
|
17
|
+
for (const line of lines) {
|
|
18
|
+
const isBlank = line.trim() === ''
|
|
19
|
+
if (isBlank && lastBlank) continue
|
|
20
|
+
result.push(line)
|
|
21
|
+
lastBlank = isBlank
|
|
22
|
+
}
|
|
23
|
+
return result
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function stripCilMarkers(lines) {
|
|
27
|
+
return lines.filter(line => {
|
|
28
|
+
const trimmed = line.trim()
|
|
29
|
+
return !trimmed.match(/^\/\/\s*CIL\[(BEGIN|END)/) &&
|
|
30
|
+
!trimmed.match(/^--\s*CIL\[(BEGIN|END)/) &&
|
|
31
|
+
!trimmed.match(/^#\s*CIL\[(BEGIN|END)/) &&
|
|
32
|
+
!trimmed.match(/^<!--\s*CIL\[(BEGIN|END)/)
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function detectLanguage(filePath) {
|
|
37
|
+
const ext = path.extname(filePath).toLowerCase()
|
|
38
|
+
const map = {
|
|
39
|
+
'.ts': 'typescript',
|
|
40
|
+
'.tsx': 'typescriptreact',
|
|
41
|
+
'.js': 'javascript',
|
|
42
|
+
'.jsx': 'javascriptreact',
|
|
43
|
+
'.sql': 'sql',
|
|
44
|
+
}
|
|
45
|
+
return map[ext] || 'unknown'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function proposeAstChunks(content, canonicalPath, language) {
|
|
49
|
+
const proposals = []
|
|
50
|
+
if (!['typescript', 'typescriptreact', 'javascript', 'javascriptreact'].includes(language)) {
|
|
51
|
+
return proposals
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const scriptKind =
|
|
55
|
+
language === 'typescript' ? ts.ScriptKind.TS :
|
|
56
|
+
language === 'typescriptreact' ? ts.ScriptKind.TSX :
|
|
57
|
+
language === 'javascript' ? ts.ScriptKind.JS :
|
|
58
|
+
ts.ScriptKind.JSX
|
|
59
|
+
|
|
60
|
+
const sourceFile = ts.createSourceFile(canonicalPath, content, ts.ScriptTarget.Latest, true, scriptKind)
|
|
61
|
+
|
|
62
|
+
const imports = sourceFile.statements.filter(s => ts.isImportDeclaration(s))
|
|
63
|
+
let headerEnd = 1
|
|
64
|
+
if (imports.length > 0) {
|
|
65
|
+
headerEnd = sourceFile.getLineAndCharacterOfPosition(imports[imports.length - 1].getEnd()).line + 1
|
|
66
|
+
}
|
|
67
|
+
proposals.push({
|
|
68
|
+
name: 'module_header',
|
|
69
|
+
type: 'module_header',
|
|
70
|
+
stable_id: `${canonicalPath}:module_header:module_header`,
|
|
71
|
+
line_start: 1,
|
|
72
|
+
line_end: headerEnd,
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
function addSymbol(name, type, node) {
|
|
76
|
+
const start = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1
|
|
77
|
+
const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line + 1
|
|
78
|
+
proposals.push({
|
|
79
|
+
name,
|
|
80
|
+
type,
|
|
81
|
+
stable_id: `${canonicalPath}:${name.toLowerCase()}:${type}`,
|
|
82
|
+
line_start: start,
|
|
83
|
+
line_end: end,
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
88
|
+
if (ts.isFunctionDeclaration(node) && node.name) addSymbol(node.name.text, 'function', node)
|
|
89
|
+
else if (ts.isClassDeclaration(node) && node.name) addSymbol(node.name.text, 'class', node)
|
|
90
|
+
else if (ts.isInterfaceDeclaration(node) && node.name) addSymbol(node.name.text, 'interface', node)
|
|
91
|
+
else if (ts.isTypeAliasDeclaration(node) && node.name) addSymbol(node.name.text, 'type', node)
|
|
92
|
+
else if (ts.isVariableStatement(node)) {
|
|
93
|
+
for (const decl of node.declarationList.declarations) {
|
|
94
|
+
if (ts.isIdentifier(decl.name)) {
|
|
95
|
+
addSymbol(decl.name.text, 'constant', node)
|
|
96
|
+
break
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
return proposals
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function processFile(absolutePath, repoRoot) {
|
|
106
|
+
const content = fs.readFileSync(absolutePath, 'utf-8')
|
|
107
|
+
const lines = content.split('\n')
|
|
108
|
+
const stripped = stripCilMarkers(lines)
|
|
109
|
+
const cleaned = collapseBlankLines(stripped)
|
|
110
|
+
|
|
111
|
+
const language = detectLanguage(absolutePath)
|
|
112
|
+
const canonicalPath = toCanonicalPath(repoRoot, absolutePath)
|
|
113
|
+
const relPath = canonicalPath.slice(2)
|
|
114
|
+
|
|
115
|
+
const proposals = proposeAstChunks(cleaned.join('\n'), canonicalPath, language)
|
|
116
|
+
if (proposals.length === 0) {
|
|
117
|
+
return { file_path: relPath, markers: [], hash: null, skipped: true }
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Build new content with markers
|
|
121
|
+
const insertions = []
|
|
122
|
+
for (const p of proposals) {
|
|
123
|
+
const beginLine = `// CIL[BEGIN stable_id="${p.stable_id}" type="${p.type}" identity="${p.name}" parent="none"]`
|
|
124
|
+
const endLine = `// CIL[END stable_id="${p.stable_id}"]`
|
|
125
|
+
insertions.push({ line: p.line_start, text: beginLine })
|
|
126
|
+
insertions.push({ line: p.line_end + 1, text: endLine })
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
insertions.sort((a, b) => b.line - a.line)
|
|
130
|
+
for (const ins of insertions) {
|
|
131
|
+
const idx = ins.line - 1
|
|
132
|
+
cleaned.splice(idx, 0, ins.text)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const withBlanks = []
|
|
136
|
+
for (let i = 0; i < cleaned.length; i++) {
|
|
137
|
+
const line = cleaned[i]
|
|
138
|
+
withBlanks.push(line)
|
|
139
|
+
if (line.startsWith('// CIL[END') || line.startsWith('-- CIL[END') || line.startsWith('# CIL[END')) {
|
|
140
|
+
if (i + 1 < cleaned.length && (cleaned[i + 1].startsWith('// CIL[BEGIN') || cleaned[i + 1].startsWith('-- CIL[BEGIN') || cleaned[i + 1].startsWith('# CIL[BEGIN'))) {
|
|
141
|
+
withBlanks.push('')
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const newContent = withBlanks.join('\n')
|
|
147
|
+
fs.writeFileSync(absolutePath, newContent, 'utf-8')
|
|
148
|
+
|
|
149
|
+
const hash = fs.readFileSync(absolutePath)
|
|
150
|
+
const fileHash = crypto.createHash('sha256').update(hash).digest('hex')
|
|
151
|
+
|
|
152
|
+
const markers = proposals.map(p => ({
|
|
153
|
+
stable_id: p.stable_id,
|
|
154
|
+
chunk_id: p.stable_id,
|
|
155
|
+
type: p.type,
|
|
156
|
+
identity: p.name,
|
|
157
|
+
parent: 'none',
|
|
158
|
+
start_line: p.line_start,
|
|
159
|
+
end_line: p.line_end,
|
|
160
|
+
}))
|
|
161
|
+
|
|
162
|
+
return { file_path: relPath, markers, hash: fileHash, skipped: false }
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const repoRoot = process.argv[2]
|
|
166
|
+
const files = process.argv.slice(3)
|
|
167
|
+
if (!repoRoot || files.length === 0) {
|
|
168
|
+
console.error('Usage: node fix-cil-markers.mjs <repoRoot> <file1> [file2] ...')
|
|
169
|
+
process.exit(1)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
for (const file of files) {
|
|
173
|
+
const absolutePath = path.resolve(repoRoot, file)
|
|
174
|
+
const result = processFile(absolutePath, repoRoot)
|
|
175
|
+
console.log(JSON.stringify(result))
|
|
176
|
+
}
|