spine-framework 0.3.145 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +76 -0
- package/.framework/.spine-manifest.json +19 -0
- package/.framework/cli/commands/agents.ts +61 -33
- package/.framework/cli/commands/auth.ts +60 -28
- package/.framework/cli/commands/create-app.ts +212 -80
- package/.framework/cli/commands/dev.ts +184 -68
- package/.framework/cli/commands/doctor.ts +324 -152
- package/.framework/cli/commands/generate.ts +119 -68
- package/.framework/cli/commands/init.ts +141 -242
- package/.framework/cli/commands/install-app.ts +1336 -314
- package/.framework/cli/commands/items.ts +31 -29
- package/.framework/cli/commands/migrate.ts +299 -156
- package/.framework/cli/commands/migrations.ts +62 -30
- package/.framework/cli/commands/pipelines.ts +31 -29
- package/.framework/cli/commands/status.ts +105 -45
- package/.framework/cli/commands/system.ts +47 -42
- package/.framework/cli/commands/test.ts +161 -102
- package/.framework/cli/commands/upgrade.ts +260 -0
- package/.framework/cli/commands/validate-app.ts +517 -161
- package/.framework/cli/context.ts +117 -85
- package/.framework/cli/env-loader.ts +74 -43
- package/.framework/cli/index.ts +70 -46
- package/.framework/cli/lib/project-files.ts +404 -0
- package/.framework/docs/guides/testing-guide.md +1 -1
- package/.framework/docs/runtime-types.md +72 -72
- package/.framework/functions/_shared/access.ts +84 -0
- package/.framework/functions/_shared/agent-runner.ts +5067 -1026
- package/.framework/functions/_shared/app-manifest.ts +214 -94
- package/.framework/functions/_shared/ast.ts +214 -0
- package/.framework/functions/_shared/audit.ts +91 -55
- package/.framework/functions/_shared/cil.ts +368 -127
- package/.framework/functions/_shared/db.ts +337 -68
- package/.framework/functions/_shared/funnel.ts +228 -0
- package/.framework/functions/_shared/geo.ts +105 -0
- package/.framework/functions/_shared/hash-api-key.ts +94 -17
- package/.framework/functions/_shared/index.ts +22 -224
- package/.framework/functions/_shared/kb.ts +832 -58
- package/.framework/functions/_shared/llm.ts +118 -18
- package/.framework/functions/_shared/logging.ts +317 -19
- package/.framework/functions/_shared/middleware.ts +701 -131
- package/.framework/functions/_shared/notify.ts +70 -0
- package/.framework/functions/_shared/outcomes.ts +34 -19
- package/.framework/functions/_shared/permissions.ts +501 -315
- package/.framework/functions/_shared/pipeline-runner.ts +704 -155
- package/.framework/functions/_shared/principal.ts +436 -263
- package/.framework/functions/_shared/rate-limit.ts +233 -0
- package/.framework/functions/_shared/resolve-credentials.ts +86 -19
- package/.framework/functions/_shared/resolve-ids.ts +203 -139
- package/.framework/functions/_shared/retry-deliveries.ts +51 -16
- package/.framework/functions/_shared/schema-utils.ts +602 -521
- package/.framework/functions/_shared/security.ts +345 -0
- package/.framework/functions/_shared/testing.ts +197 -172
- package/.framework/functions/_shared/tracing.ts +351 -21
- package/.framework/functions/_shared/trigger-engine.ts +425 -136
- package/.framework/functions/_shared/webhook-registration.ts +71 -70
- package/.framework/functions/_shared/webhook-registry.ts +126 -83
- package/.framework/functions/account-nodes.ts +30 -30
- package/.framework/functions/adapters/generic-webhook-inbound.ts +49 -16
- package/.framework/functions/adapters/generic-webhook-outbound.ts +17 -17
- package/.framework/functions/adapters/openai-outbound.ts +15 -16
- package/.framework/functions/admin-data.ts +596 -173
- package/.framework/functions/admin-funnel.ts +64 -60
- package/.framework/functions/admin-install-funnel.ts +84 -66
- package/.framework/functions/admin-signals.ts +69 -51
- package/.framework/functions/ai-agents.ts +431 -106
- package/.framework/functions/ai-interactions.ts +186 -112
- package/.framework/functions/api-keys.ts +107 -107
- package/.framework/functions/apps.ts +154 -136
- package/.framework/functions/auth.ts +83 -65
- package/.framework/functions/cil-agent-ingest.ts +189 -232
- package/.framework/functions/cil-agent.ts +433 -177
- package/.framework/functions/cil-callmap.ts +642 -430
- package/.framework/functions/cil-config.ts +139 -135
- package/.framework/functions/cil-context.ts +214 -127
- package/.framework/functions/cil-doc.ts +587 -458
- package/.framework/functions/cil-embeddings.ts +453 -364
- package/.framework/functions/cil-graph.ts +427 -142
- package/.framework/functions/cil-ingest.ts +1418 -1154
- package/.framework/functions/cil-pipeline.ts +276 -21
- package/.framework/functions/cil-project.ts +659 -132
- package/.framework/functions/cil-validate.ts +198 -164
- package/.framework/functions/debug-auth.ts +57 -55
- package/.framework/functions/deliveries.ts +80 -21
- package/.framework/functions/embeddings.ts +1023 -318
- package/.framework/functions/eval-harness.ts +146 -108
- package/.framework/functions/integration-outbound.ts +205 -75
- package/.framework/functions/integration-routes.ts +128 -23
- package/.framework/functions/integrations.ts +125 -100
- package/.framework/functions/invites.ts +1095 -460
- package/.framework/functions/item-progress.ts +158 -102
- package/.framework/functions/kb.ts +34 -10
- package/.framework/functions/logs.ts +133 -133
- package/.framework/functions/observability.ts +152 -122
- package/.framework/functions/pipeline-executions.ts +147 -132
- package/.framework/functions/pipelines.ts +134 -119
- package/.framework/functions/prompt-configs.ts +96 -80
- package/.framework/functions/roles.ts +112 -82
- package/.framework/functions/security.ts +450 -0
- package/.framework/functions/system-cron.ts +117 -80
- package/.framework/functions/system.ts +158 -98
- package/.framework/functions/tests.ts +29 -29
- package/.framework/functions/timers.ts +94 -95
- package/.framework/functions/trigger-scheduler.ts +10 -0
- package/.framework/functions/triggers.ts +179 -149
- package/.framework/functions/types.ts +137 -125
- package/.framework/mcp/index.ts +133 -0
- package/.framework/mcp/load-env.ts +60 -0
- package/.framework/mcp/shared/app-manifest.ts +275 -0
- package/.framework/mcp/shared/db.ts +477 -0
- package/.framework/mcp/shared/kb.ts +118 -0
- package/.framework/mcp/tools/architect.ts +431 -0
- package/.framework/mcp/tools/cil/context.ts +345 -0
- package/.framework/mcp/tools/cil/graph.ts +242 -0
- package/.framework/mcp/tools/cil/ingest.ts +1217 -0
- package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +693 -0
- package/.framework/mcp/tools/cil/pipeline.ts +767 -0
- package/.framework/mcp/tools/cil/project.ts +791 -0
- package/.framework/mcp/tools/cil/retrieval.ts +336 -0
- package/.framework/mcp/tools/cil/search-core.ts +454 -0
- package/.framework/mcp/tools/cil/search.ts +97 -0
- package/.framework/mcp/tools/cil/suggest.ts +186 -0
- package/.framework/mcp/tools/cil/validate.ts +1369 -0
- package/.framework/mcp/tools/kb/delete.ts +139 -0
- package/.framework/mcp/tools/kb/index.ts +52 -0
- package/.framework/mcp/tools/kb/ingest.ts +84 -0
- package/.framework/mcp/tools/kb/list-types.ts +102 -0
- package/.framework/mcp/tools/kb/publish.ts +100 -0
- package/.framework/mcp/tools/kb/reindex.ts +86 -0
- package/.framework/mcp/tools/kb/revoke.ts +85 -0
- package/.framework/mcp/tools/kb/search.ts +101 -0
- package/.framework/mcp/tools/kb/upsert.ts +125 -0
- package/.framework/mcp/tools/observability.ts +510 -0
- package/.framework/migrations/001_core_schema.sql +15 -0
- package/.framework/migrations/002_core_rls_and_functions.sql +15 -0
- package/.framework/migrations/003_core_system_data.sql +16 -1
- package/.framework/migrations/004_core_rpc_and_broker.sql +17 -1
- package/.framework/migrations/005_core_observability.sql +17 -1
- package/.framework/migrations/006_security_hardening_rls.sql +15 -0
- package/.framework/migrations/007_kb_article_list.sql +17 -1
- package/.framework/migrations/008_items_target.sql +15 -0
- package/.framework/migrations/009_roles_slug_unique.sql +15 -0
- package/.framework/migrations/010_auth_user_trigger.sql +15 -0
- package/.framework/migrations/011_spine_system_account.sql +16 -0
- package/.framework/migrations/012_service_role_grants.sql +16 -0
- package/.framework/migrations/013_get_account_apps_role_filter.sql +15 -0
- package/.framework/migrations/014_apps_required_roles.sql +16 -0
- package/.framework/migrations/015_types_kind_slug_unique.sql +15 -0
- package/.framework/migrations/016_cil_types.sql +281 -0
- package/.framework/migrations/017_cil_stable_ids.sql +37 -0
- package/.framework/migrations/018_runtime_tables.sql +129 -0
- package/.framework/migrations/019_agent_prompt_columns.sql +56 -0
- package/.framework/migrations/020_schema_reconciliation.sql +67 -0
- package/.framework/migrations/021_kb_embedding_lifecycle.sql +31 -0
- package/.framework/migrations/032_cil_status_migration.sql +73 -0
- package/.framework/migrations/033_cil_versioning.sql +73 -0
- package/.framework/migrations/034_match_embeddings_knn.sql +115 -0
- package/.framework/migrations/035_rate_limits.sql +55 -0
- package/.framework/migrations/036_demo_record_flags.sql +72 -0
- package/.framework/migrations/037_kb_types_canonical.sql +244 -0
- package/.framework/migrations/038_drop_demo_record_flags.sql +38 -0
- package/.framework/migrations/042_registration_hierarchy.sql +309 -0
- package/.framework/migrations/043_policy_actor_cleanup.sql +39 -0
- package/.framework/migrations/044_match_embeddings_filtered_knn.sql +151 -0
- package/.framework/migrations/045_security_critical_rls.sql +139 -0
- package/.framework/migrations/046_security_missing_rls.sql +79 -0
- package/.framework/migrations/047_people_updated_by.sql +27 -0
- package/.framework/migrations/048_watcher_last_seen_at.sql +24 -0
- package/.framework/migrations/049_security_blocklist.sql +148 -0
- package/.framework/migrations/050_notifications.sql +49 -0
- package/.framework/migrations/051_message_agent_fields.sql +74 -0
- package/.framework/migrations/052_registration_security.sql +421 -0
- package/.framework/migrations/053_builtin_action_seeds.sql +66 -0
- package/.framework/migrations/054_kb_ingest_lease.sql +157 -0
- package/.framework/migrations/055_type_id_drift_reconciliation.sql +33 -0
- package/.framework/migrations/056_slug_column_reconciliation.sql +38 -0
- package/.framework/migrations/057_pipelines_slug_identity.sql +14 -0
- package/.framework/migrations/058_account_data_field_declarations.sql +53 -0
- package/.framework/migrations/059_registration_placement_fixes.sql +269 -0
- package/.framework/migrations/060_account_person_record_permissions.sql +38 -0
- package/.framework/migrations/061_fk_dedup.sql +32 -0
- package/.framework/public/spine-logo.svg +10 -3
- package/.framework/scripts/app-install-cli.ts +190 -93
- package/.framework/scripts/assemble-frontend.sh +127 -44
- package/.framework/scripts/assemble-functions.sh +128 -30
- package/.framework/scripts/boundary-check.sh +6 -2
- package/.framework/scripts/build-manifest.sh +24 -68
- package/.framework/scripts/check-core-integrity.sh +15 -76
- package/.framework/scripts/checksum-manifest.mts +343 -0
- package/.framework/scripts/cil-migrate-markers.ts +403 -0
- package/.framework/scripts/fix-cil-markers.mjs +176 -0
- package/.framework/scripts/verify-integrity.sh +21 -57
- package/.framework/scripts/verify-manifest.mts +305 -0
- package/.framework/seeds/types/funnel_signal_use.json +74 -21
- package/.framework/seeds/types/spine_instance.json +73 -21
- package/.framework/src/App.tsx +118 -72
- package/.framework/src/apps/admin/index.tsx +855 -58
- package/.framework/src/components/AppWrapper.tsx +43 -45
- package/.framework/src/components/CustomAppLoader.tsx +160 -116
- package/.framework/src/components/admin/AdminListPage.tsx +46 -44
- package/.framework/src/components/admin/AdminSidebar.tsx +57 -47
- package/.framework/src/components/admin/AdminStatsCard.tsx +46 -44
- package/.framework/src/components/admin/PageInstructions.tsx +98 -2
- package/.framework/src/components/admin/SortableTableHeader.tsx +44 -45
- package/.framework/src/components/app-shell/GenericAppShell.tsx +64 -65
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +44 -47
- package/.framework/src/components/app-shell/GenericListPage.tsx +45 -49
- package/.framework/src/components/app-sidebar.tsx +42 -45
- package/.framework/src/components/auth/ProtectedRoute.tsx +48 -41
- package/.framework/src/components/auth/TurnstileWidget.tsx +27 -0
- package/.framework/src/components/kb/KBArticleEditor.tsx +231 -22
- package/.framework/src/components/kb/KBArticleList.tsx +251 -10
- package/.framework/src/components/layout/AppShell.tsx +51 -45
- package/.framework/src/components/layout/Header.tsx +42 -43
- package/.framework/src/components/layout/Layout.tsx +46 -46
- package/.framework/src/components/layout/Sidebar.tsx +196 -96
- package/.framework/src/components/runtime/DataDetailHeader.tsx +55 -30
- package/.framework/src/components/runtime/DataDetailPage.tsx +31 -269
- package/.framework/src/components/runtime/DataFilters.tsx +49 -74
- package/.framework/src/components/runtime/DataHeader.tsx +53 -32
- package/.framework/src/components/runtime/DataListPage.tsx +51 -155
- package/.framework/src/components/runtime/DataStats.tsx +66 -44
- package/.framework/src/components/runtime/DataTable.tsx +49 -149
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +45 -75
- package/.framework/src/components/runtime/index.ts +119 -16
- package/.framework/src/components/search-form.tsx +46 -29
- package/.framework/src/components/shared/AgentView.tsx +65 -48
- package/.framework/src/components/shared/FieldRenderer.tsx +144 -50
- package/.framework/src/components/shared/InviteManager.tsx +207 -97
- package/.framework/src/components/shared/MemberList.tsx +97 -0
- package/.framework/src/components/shared/SchemaFields.tsx +107 -86
- package/.framework/src/components/ui/DataTable.tsx +80 -68
- package/.framework/src/components/ui/Form.tsx +157 -146
- package/.framework/src/components/ui/ItemCard.tsx +74 -67
- package/.framework/src/components/ui/ItemListView.tsx +73 -68
- package/.framework/src/components/ui/LoadingSpinner.tsx +43 -48
- package/.framework/src/components/ui/Modal.tsx +78 -68
- package/.framework/src/components/ui/RichTextEditor.tsx +89 -69
- package/.framework/src/components/ui/accordion.tsx +85 -86
- package/.framework/src/components/ui/alert-dialog.tsx +197 -184
- package/.framework/src/components/ui/alert.tsx +105 -94
- package/.framework/src/components/ui/aspect-ratio.tsx +57 -43
- package/.framework/src/components/ui/avatar.tsx +122 -107
- package/.framework/src/components/ui/badge.tsx +60 -55
- package/.framework/src/components/ui/breadcrumb.tsx +127 -128
- package/.framework/src/components/ui/button-group.tsx +86 -72
- package/.framework/src/components/ui/button.tsx +71 -50
- package/.framework/src/components/ui/calendar.tsx +72 -57
- package/.framework/src/components/ui/card.tsx +136 -129
- package/.framework/src/components/ui/carousel.tsx +226 -107
- package/.framework/src/components/ui/chart.tsx +252 -147
- package/.framework/src/components/ui/checkbox.tsx +43 -44
- package/.framework/src/components/ui/collapsible.tsx +86 -71
- package/.framework/src/components/ui/combobox.tsx +282 -249
- package/.framework/src/components/ui/command.tsx +158 -146
- package/.framework/src/components/ui/context-menu.tsx +239 -240
- package/.framework/src/components/ui/dialog.tsx +174 -157
- package/.framework/src/components/ui/direction.tsx +72 -56
- package/.framework/src/components/ui/drawer.tsx +168 -169
- package/.framework/src/components/ui/dropdown-menu.tsx +254 -223
- package/.framework/src/components/ui/empty.tsx +131 -120
- package/.framework/src/components/ui/field.tsx +205 -173
- package/.framework/src/components/ui/hover-card.tsx +71 -72
- package/.framework/src/components/ui/input-group.tsx +148 -133
- package/.framework/src/components/ui/input-otp.tsx +99 -86
- package/.framework/src/components/ui/input.tsx +43 -41
- package/.framework/src/components/ui/item.tsx +207 -185
- package/.framework/src/components/ui/kbd.tsx +57 -56
- package/.framework/src/components/ui/label.tsx +45 -41
- package/.framework/src/components/ui/menubar.tsx +268 -236
- package/.framework/src/components/ui/native-select.tsx +85 -86
- package/.framework/src/components/ui/navigation-menu.tsx +166 -156
- package/.framework/src/components/ui/pagination.tsx +131 -141
- package/.framework/src/components/ui/popover.tsx +125 -128
- package/.framework/src/components/ui/progress.tsx +47 -44
- package/.framework/src/components/ui/radio-group.tsx +60 -55
- package/.framework/src/components/ui/resizable.tsx +85 -72
- package/.framework/src/components/ui/scroll-area.tsx +57 -58
- package/.framework/src/components/ui/select.tsx +182 -169
- package/.framework/src/components/ui/separator.tsx +42 -43
- package/.framework/src/components/ui/sheet.tsx +170 -159
- package/.framework/src/components/ui/sidebar.tsx +395 -398
- package/.framework/src/components/ui/skeleton.tsx +42 -43
- package/.framework/src/components/ui/slider.tsx +61 -44
- package/.framework/src/components/ui/sonner.tsx +44 -44
- package/.framework/src/components/ui/spinner.tsx +47 -42
- package/.framework/src/components/ui/switch.tsx +56 -42
- package/.framework/src/components/ui/table-primitives.tsx +272 -132
- package/.framework/src/components/ui/table.tsx +140 -142
- package/.framework/src/components/ui/tabs.tsx +110 -93
- package/.framework/src/components/ui/textarea.tsx +43 -44
- package/.framework/src/components/ui/toggle-group.tsx +87 -71
- package/.framework/src/components/ui/toggle.tsx +56 -56
- package/.framework/src/components/ui/tooltip.tsx +99 -85
- package/.framework/src/contexts/AppContext.tsx +166 -114
- package/.framework/src/contexts/AuthContext.tsx +232 -137
- package/.framework/src/hooks/use-mobile.ts +43 -44
- package/.framework/src/hooks/useApi.ts +185 -172
- package/.framework/src/hooks/useAppPath.ts +31 -29
- package/.framework/src/hooks/useApps.ts +77 -42
- package/.framework/src/hooks/useEntityList.ts +66 -29
- package/.framework/src/hooks/useEntityRecord.ts +76 -32
- package/.framework/src/hooks/useForm.ts +62 -30
- package/.framework/src/hooks/useListSchema.ts +60 -43
- package/.framework/src/hooks/useSchemaRecord.ts +115 -95
- package/.framework/src/lib/api.ts +258 -134
- package/.framework/src/lib/registration.ts +181 -0
- package/.framework/src/lib/supabase.ts +118 -81
- package/.framework/src/lib/utils.ts +266 -266
- package/.framework/src/main.tsx +43 -44
- package/.framework/src/pages/DashboardPage.tsx +44 -43
- package/.framework/src/pages/NoAppPage.tsx +50 -0
- package/.framework/src/pages/NotFoundPage.tsx +32 -29
- package/.framework/src/pages/SetupPage.tsx +34 -33
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +69 -58
- package/.framework/src/pages/admin/AIAgentsPage.tsx +43 -40
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +63 -55
- package/.framework/src/pages/admin/APIKeysPage.tsx +44 -42
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +117 -94
- package/.framework/src/pages/admin/AppDetailPage.tsx +48 -42
- package/.framework/src/pages/admin/AppsPage.tsx +45 -42
- package/.framework/src/pages/admin/DeliveriesPage.tsx +49 -17
- package/.framework/src/pages/admin/DesignedPage.tsx +31 -30
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +58 -0
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +49 -0
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +31 -29
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +46 -29
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -29
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +68 -55
- package/.framework/src/pages/admin/IntegrationsPage.tsx +45 -42
- package/.framework/src/pages/admin/InvitesPage.tsx +60 -44
- package/.framework/src/pages/admin/LogsPage.tsx +87 -137
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +31 -29
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +150 -89
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +77 -104
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +44 -43
- package/.framework/src/pages/admin/PipelinesPage.tsx +59 -145
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +53 -42
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +47 -117
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +31 -44
- package/.framework/src/pages/admin/RoleDetailPage.tsx +49 -92
- package/.framework/src/pages/admin/RolesPage.tsx +47 -164
- package/.framework/src/pages/admin/SecurityPage.tsx +310 -0
- package/.framework/src/pages/admin/SelectTestPage.tsx +30 -32
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +37 -44
- package/.framework/src/pages/admin/SimpleDashboard.tsx +32 -44
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +97 -44
- package/.framework/src/pages/admin/TestingDashboard.tsx +126 -71
- package/.framework/src/pages/admin/TimerDetailPage.tsx +67 -55
- package/.framework/src/pages/admin/TimersPage.tsx +44 -42
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +47 -42
- package/.framework/src/pages/admin/TriggersPage.tsx +58 -57
- package/.framework/src/pages/admin/TypeDetailPage.tsx +91 -55
- package/.framework/src/pages/admin/TypesPage.tsx +45 -42
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +258 -128
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +127 -123
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +308 -235
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +159 -110
- package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +432 -0
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +200 -178
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +286 -239
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +211 -90
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +156 -143
- package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +379 -0
- package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +337 -0
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +219 -214
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +135 -65
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +39 -31
- package/.framework/src/pages/auth/LoginPage.tsx +38 -32
- package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -28
- package/.framework/src/pages/auth/RegisterPage.tsx +429 -155
- package/.framework/src/pages/spine-framework/APIPage.tsx +33 -30
- package/.framework/src/pages/spine-framework/CLIPage.tsx +32 -30
- package/.framework/src/types/auth.ts +101 -93
- package/.framework/src/types/types.ts +283 -262
- package/.framework/templates/project.json +87 -0
- package/.framework/templates/spine.config.neutral.json +7 -0
- package/.framework/tests/api/api-surface.test.ts +381 -0
- package/.framework/tests/fixtures/seed.ts +427 -0
- package/.framework/tests/fixtures/teardown.ts +228 -0
- package/.framework/tests/reporter.ts +351 -0
- package/.framework/tests/setup.ts +135 -0
- package/.framework/tests/ui/ui-sweep.ts +278 -0
- package/.framework/tests/unit/admin-data-logger.test.ts +310 -0
- package/.framework/tests/unit/agent-runner.test.ts +2389 -0
- package/.framework/tests/unit/ai-interactions.test.ts +81 -0
- package/.framework/tests/unit/app-manifest.test.ts +359 -0
- package/.framework/tests/unit/assembly-scripts.test.ts +172 -0
- package/.framework/tests/unit/cil-determinism.test.ts +85 -0
- package/.framework/tests/unit/core-isolation.test.ts +153 -0
- package/.framework/tests/unit/funnel-signals.test.ts +135 -0
- package/.framework/tests/unit/install-app.test.ts +1759 -0
- package/.framework/tests/unit/invites-security.test.ts +572 -0
- package/.framework/tests/unit/kb-ingest-lease.test.ts +287 -0
- package/.framework/tests/unit/kb-search.test.ts +119 -0
- package/.framework/tests/unit/migrate.test.ts +509 -0
- package/.framework/tests/unit/notify.test.ts +136 -0
- package/.framework/tests/unit/permissions.test.ts +269 -0
- package/.framework/tests/unit/pipeline-runner.test.ts +755 -0
- package/.framework/tests/unit/principal-cache.test.ts +138 -0
- package/.framework/tests/unit/retrieval-golden.test.ts +520 -0
- package/.framework/tests/unit/runtime-isolation.test.ts +642 -0
- package/.framework/tests/unit/schema-utils.test.ts +225 -0
- package/.framework/tests/unit/trigger-engine.test.ts +513 -0
- package/.framework/tests/unit/validate-app.test.ts +527 -0
- package/README.md +34 -3
- package/bin/spine-framework.cjs +1 -0
- package/config/tailwind.config.cjs +7 -0
- package/config/tsconfig.functions.json +42 -0
- package/config/tsconfig.json +37 -9
- package/config/vite.config.ts +31 -2
- package/netlify.toml +31 -3
- package/package.json +46 -29
- package/scripts/assemble-frontend.sh +127 -44
- package/scripts/assemble-functions.sh +127 -29
- package/scripts/boundary-check.sh +6 -2
- package/scripts/build-manifest.sh +24 -68
- package/scripts/checksum-manifest.mts +345 -0
- package/scripts/dev-clean.sh +86 -0
- package/scripts/dev-netlify.sh +49 -0
- package/scripts/netlify-dev-wrapper.sh +2 -0
- package/scripts/verify-install.ts +358 -0
- package/scripts/verify-integrity.sh +21 -57
- package/scripts/verify-manifest.mts +305 -0
- package/templates/project/gitignore +45 -0
- package/{config → templates/project}/package-lock.json +22335 -9366
- package/vitest.config.ts +46 -0
- package/.framework/public/spine.config.json +0 -91
- package/config/deno.lock +0 -108
- package/config/tsconfig.node.tsbuildinfo +0 -1
- package/config/tsconfig.tsbuildinfo +0 -1
- package/config/vite.config.d.ts +0 -2
- package/custom/.devin/AGENT.md +0 -357
- package/custom/.devin/skills/install-app/SKILL.md +0 -39
- package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +0 -39
- package/custom/.devin/skills/spine-workbench-idea/SKILL.md +0 -36
- package/custom/.devin/skills/spine-workbench-implement/SKILL.md +0 -46
- package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +0 -28
- package/custom/.devin/skills/spine-workbench-plan/SKILL.md +0 -38
- package/custom/.devin/workflows/app-install.yaml +0 -83
- package/custom/README.md +0 -79
- package/docs/README.md +0 -15
- package/scripts/app-install-cli.ts +0 -286
- package/scripts/check-core-integrity.sh +0 -82
- package/scripts/ingest-chunks.cjs +0 -202
- package/scripts/kb-chunk-parser.cjs +0 -312
- package/scripts/kb-chunk-parser.ts +0 -330
- package/scripts/kb-ingest-docs.ts +0 -203
- package/scripts/load-test-app-install.ts +0 -484
- package/scripts/test-login.js +0 -33
- package/spine.config.json +0 -91
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
2
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
3
|
+
// CIL[DOC-MACRO purpose="Provide module-level imports for the validate-app CLI command"]
|
|
4
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Load required modules for CLI execution, filesystem inspection, path resolution and URL helpers"]
|
|
5
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
6
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
7
|
+
// CIL[DOC-MICRO logic_summary="Imports Command from commander, fs utilities, path helpers and url helpers" notable_decisions=""]
|
|
8
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
9
|
+
// CIL[DOC-STABILITY stable]
|
|
10
|
+
|
|
1
11
|
|
|
2
12
|
|
|
3
13
|
|
|
@@ -8,36 +18,88 @@
|
|
|
8
18
|
|
|
9
19
|
|
|
10
20
|
|
|
11
|
-
// CIL[BEGIN chunk_id="validate-app_moduleheader_1784068794" type="module_header" identity="imports" parent="none"]
|
|
12
|
-
// CIL[DOC-MACRO purpose="Import dependencies and define validation types"]
|
|
13
|
-
// CIL[DOC-RESPONSIBILITY responsibility="Load required modules and define interfaces"]
|
|
14
|
-
// CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
|
|
15
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="loaded_modules" errors="none" side_effects="none"]
|
|
16
|
-
// CIL[DOC-MICRO logic_summary="Imports file system, path utilities, Commander, and defines validation types" notable_decisions="[]"]
|
|
17
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
18
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
19
|
-
// CIL[DOC-AUDIENCE audience="developer"]
|
|
20
|
-
// CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, \."]
|
|
21
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
22
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
23
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
24
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
25
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
26
21
|
import { Command } from 'commander'
|
|
27
|
-
import { readFileSync, existsSync, readdirSync, statSync } from 'fs'
|
|
28
|
-
import { join, dirname } from 'path'
|
|
22
|
+
import { readFileSync, existsSync, readdirSync, statSync, realpathSync } from 'fs'
|
|
23
|
+
import { join, dirname, resolve, isAbsolute, sep } from 'path'
|
|
29
24
|
import { fileURLToPath } from 'url'
|
|
25
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Provide module-level imports for the validate-app CLI command'; No verified external callers; imports: none"]
|
|
26
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
27
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
28
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
29
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
30
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
31
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:module_header:module_header"]
|
|
30
32
|
|
|
33
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:__filename:constant" type="constant" identity="__filename" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
34
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
35
|
+
// CIL[DOC-MACRO purpose="Expose the current module filename for path resolution"]
|
|
36
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Derive __filename from import.meta.url"]
|
|
37
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
38
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="string" errors="none" side_effects="none"]
|
|
39
|
+
// CIL[DOC-MICRO logic_summary="Use fileURLToPath to convert import.meta.url to an absolute file path" notable_decisions=""]
|
|
40
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
41
|
+
// CIL[DOC-STABILITY stable]
|
|
31
42
|
const __filename = fileURLToPath(import.meta.url)
|
|
43
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Expose the current module filename for path resolution'; No verified external callers; imports: none"]
|
|
44
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
45
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
46
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
47
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
48
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
49
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:__filename:constant"]
|
|
50
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:__dirname:constant" type="constant" identity="__dirname" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
51
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
52
|
+
// CIL[DOC-MACRO purpose="Expose the current module directory for path resolution"]
|
|
53
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Derive __dirname from __filename"]
|
|
54
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
55
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="string" errors="none" side_effects="none"]
|
|
56
|
+
// CIL[DOC-MICRO logic_summary="Use dirname to get the directory portion of __filename" notable_decisions=""]
|
|
57
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
58
|
+
// CIL[DOC-STABILITY stable]
|
|
32
59
|
const __dirname = dirname(__filename)
|
|
60
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Expose the current module directory for path resolution'; No verified external callers; imports: none"]
|
|
61
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
62
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
63
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
64
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
65
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
66
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:__dirname:constant"]
|
|
33
67
|
|
|
68
|
+
|
|
69
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:SeedEntry:interface" type="interface" identity="SeedEntry" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
70
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
71
|
+
// CIL[DOC-MACRO purpose="Define the shape of a manifest seed entry"]
|
|
72
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declare the TypeScript interface for a single seed configuration used by validate-app"]
|
|
73
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
74
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
75
|
+
// CIL[DOC-MICRO logic_summary="Declares file, table, conflict and optional inject_app_id/permissions_patch fields" notable_decisions=""]
|
|
76
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
77
|
+
// CIL[DOC-STABILITY stable]
|
|
34
78
|
interface SeedEntry {
|
|
35
79
|
file: string
|
|
36
80
|
table: string
|
|
37
81
|
conflict: string
|
|
38
82
|
inject_app_id?: boolean
|
|
83
|
+
permissions_patch?: boolean
|
|
39
84
|
}
|
|
85
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Define the shape of a manifest seed entry'; No verified external callers; imports: none"]
|
|
86
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
87
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
88
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
89
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
90
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
91
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:SeedEntry:interface"]
|
|
92
|
+
|
|
40
93
|
|
|
94
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:Manifest:interface" type="interface" identity="Manifest" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
95
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
96
|
+
// CIL[DOC-MACRO purpose="Define the shape of an app manifest"]
|
|
97
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declare the TypeScript interface for the manifest.json structure used by validate-app"]
|
|
98
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
99
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
100
|
+
// CIL[DOC-MICRO logic_summary="Declares app metadata, type, entry points, seed, owned_types, registration and routing fields" notable_decisions=""]
|
|
101
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
102
|
+
// CIL[DOC-STABILITY stable]
|
|
41
103
|
interface Manifest {
|
|
42
104
|
name: string
|
|
43
105
|
slug: string
|
|
@@ -46,15 +108,44 @@ interface Manifest {
|
|
|
46
108
|
entry_point?: string
|
|
47
109
|
sidebar_component?: string
|
|
48
110
|
seed?: SeedEntry[]
|
|
111
|
+
owned_types?: string[]
|
|
112
|
+
config?: {
|
|
113
|
+
knowledge?: {
|
|
114
|
+
account?: boolean | { scope?: string; item_types?: string[] }
|
|
115
|
+
platform?: boolean | { sources?: string[] }
|
|
116
|
+
cil?: boolean | { project_ids?: string[] }
|
|
117
|
+
}
|
|
118
|
+
[key: string]: any
|
|
119
|
+
}
|
|
49
120
|
registration?: {
|
|
50
121
|
enabled?: boolean
|
|
122
|
+
app_type?: 'full' | 'ui' | 'backend' | 'data'
|
|
51
123
|
default_role?: string
|
|
52
124
|
redirect_path?: string
|
|
53
125
|
account_strategy?: 'existing' | 'new' | 'choice'
|
|
54
126
|
target_account?: string
|
|
127
|
+
parent_account?: string
|
|
128
|
+
default_workspace_name?: boolean
|
|
55
129
|
}
|
|
56
130
|
}
|
|
131
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Define the shape of an app manifest'; No verified external callers; imports: none"]
|
|
132
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
133
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
134
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
135
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
136
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
137
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:Manifest:interface"]
|
|
138
|
+
|
|
57
139
|
|
|
140
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:PackageJson:interface" type="interface" identity="PackageJson" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
141
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
142
|
+
// CIL[DOC-MACRO purpose="Define the shape of a package.json with spine configuration"]
|
|
143
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declare the TypeScript interface for package.json consumed by validate-app"]
|
|
144
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
145
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
146
|
+
// CIL[DOC-MICRO logic_summary="Declares name, version, files and the optional spine block fields" notable_decisions=""]
|
|
147
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
148
|
+
// CIL[DOC-STABILITY stable]
|
|
58
149
|
interface PackageJson {
|
|
59
150
|
name: string
|
|
60
151
|
version: string
|
|
@@ -69,28 +160,47 @@ interface PackageJson {
|
|
|
69
160
|
manifest?: string
|
|
70
161
|
}
|
|
71
162
|
}
|
|
163
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Define the shape of a package.json with spine configuration'; No verified external callers; imports: none"]
|
|
164
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
165
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
166
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
167
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
168
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
169
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:PackageJson:interface"]
|
|
170
|
+
|
|
72
171
|
|
|
172
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:ValidationError:class" type="class" identity="ValidationError" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
173
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
174
|
+
// CIL[DOC-MACRO purpose="Custom error type for app validation failures"]
|
|
175
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Instantiate typed validation errors that identify validation problems"]
|
|
176
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
177
|
+
// CIL[DOC-CONTRACT inputs="message: string" outputs="ValidationError instance" errors="none" side_effects="none"]
|
|
178
|
+
// CIL[DOC-MICRO logic_summary="Extends Error and sets the name property to ValidationError" notable_decisions=""]
|
|
179
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
180
|
+
// CIL[DOC-STABILITY stable]
|
|
73
181
|
class ValidationError extends Error {
|
|
74
182
|
constructor(message: string) {
|
|
75
183
|
super(message)
|
|
76
184
|
this.name = 'ValidationError'
|
|
77
185
|
}
|
|
78
186
|
}
|
|
79
|
-
// CIL[
|
|
80
|
-
// CIL[
|
|
81
|
-
// CIL[DOC-
|
|
82
|
-
// CIL[DOC-
|
|
83
|
-
// CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/db.ts\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
84
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="manifest" errors="validation_errors" side_effects="none"]
|
|
85
|
-
// CIL[DOC-MICRO logic_summary="Validates JSON format, required fields, and app_type values" notable_decisions="[]"]
|
|
86
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
87
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
88
|
-
// CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/db.ts, .framework/functions/_shared/schema-utils.ts, \."]
|
|
89
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
90
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
91
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
187
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Custom error type for app validation failures'; No verified external callers; imports: none"]
|
|
188
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
189
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
190
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
92
191
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
93
192
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
193
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:ValidationError:class"]
|
|
194
|
+
|
|
195
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:validateManifest:function" type="function" identity="validateManifest" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
196
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
197
|
+
// CIL[DOC-MACRO purpose="Validate the presence and content of an app manifest.json"]
|
|
198
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Check that manifest.json exists, is valid JSON, has required fields and a valid app_type"]
|
|
199
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
200
|
+
// CIL[DOC-CONTRACT inputs="appPath: string" outputs="Manifest" errors="ValidationError on missing file, invalid JSON or invalid fields" side_effects="none"]
|
|
201
|
+
// CIL[DOC-MICRO logic_summary="Resolve manifest path, read and parse, reject non-object roots, enforce required fields and allowed app_type values" notable_decisions=""]
|
|
202
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
203
|
+
// CIL[DOC-STABILITY stable]
|
|
94
204
|
function validateManifest(appPath: string): Manifest {
|
|
95
205
|
const manifestPath = join(appPath, 'manifest.json')
|
|
96
206
|
|
|
@@ -104,13 +214,25 @@ function validateManifest(appPath: string): Manifest {
|
|
|
104
214
|
} catch (err) {
|
|
105
215
|
throw new ValidationError('❌ manifest.json is not valid JSON')
|
|
106
216
|
}
|
|
107
|
-
|
|
217
|
+
|
|
218
|
+
if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest)) {
|
|
219
|
+
throw new ValidationError('❌ manifest.json must contain a JSON object')
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (manifest.app_type === undefined && manifest.registration?.app_type !== undefined) {
|
|
223
|
+
manifest.app_type = manifest.registration.app_type
|
|
224
|
+
}
|
|
225
|
+
|
|
108
226
|
const requiredFields = ['name', 'slug', 'version', 'app_type']
|
|
109
227
|
for (const field of requiredFields) {
|
|
110
228
|
if (!manifest[field]) {
|
|
111
229
|
throw new ValidationError(`❌ manifest.json missing required field: ${field}`)
|
|
112
230
|
}
|
|
113
231
|
}
|
|
232
|
+
|
|
233
|
+
if (typeof manifest.name !== 'string' || !manifest.name.trim()) {
|
|
234
|
+
throw new ValidationError(`❌ manifest.json missing required field: name`)
|
|
235
|
+
}
|
|
114
236
|
|
|
115
237
|
const validAppTypes = ['full', 'ui', 'backend', 'data']
|
|
116
238
|
if (!validAppTypes.includes(manifest.app_type)) {
|
|
@@ -119,21 +241,23 @@ function validateManifest(appPath: string): Manifest {
|
|
|
119
241
|
|
|
120
242
|
return manifest
|
|
121
243
|
}
|
|
122
|
-
// CIL[
|
|
123
|
-
// CIL[
|
|
124
|
-
// CIL[DOC-
|
|
125
|
-
// CIL[DOC-
|
|
126
|
-
// CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
127
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="package_json" errors="validation_errors" side_effects="none"]
|
|
128
|
-
// CIL[DOC-MICRO logic_summary="Validates JSON format and version match with manifest" notable_decisions="[]"]
|
|
129
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
130
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
131
|
-
// CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/components/ui/dialog.tsx, .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
132
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
133
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
134
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
244
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Validate the presence and content of an app manifest.json'; No verified external callers; imports: none"]
|
|
245
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
246
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
247
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
135
248
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
136
249
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
250
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:validateManifest:function"]
|
|
251
|
+
|
|
252
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:validatePackageJson:function" type="function" identity="validatePackageJson" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
253
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
254
|
+
// CIL[DOC-MACRO purpose="Validate the presence and version of an app package.json"]
|
|
255
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Check that package.json exists, is valid JSON and its version matches the manifest"]
|
|
256
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
257
|
+
// CIL[DOC-CONTRACT inputs="appPath: string, manifest: Manifest" outputs="PackageJson" errors="ValidationError on missing file, invalid JSON or version mismatch" side_effects="none"]
|
|
258
|
+
// CIL[DOC-MICRO logic_summary="Resolve package path, read and parse, compare package version to manifest version" notable_decisions=""]
|
|
259
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
260
|
+
// CIL[DOC-STABILITY stable]
|
|
137
261
|
function validatePackageJson(appPath: string, manifest: Manifest): PackageJson {
|
|
138
262
|
const packagePath = join(appPath, 'package.json')
|
|
139
263
|
|
|
@@ -154,21 +278,23 @@ function validatePackageJson(appPath: string, manifest: Manifest): PackageJson {
|
|
|
154
278
|
|
|
155
279
|
return packageJson
|
|
156
280
|
}
|
|
157
|
-
// CIL[
|
|
158
|
-
// CIL[
|
|
159
|
-
// CIL[DOC-
|
|
160
|
-
// CIL[DOC-
|
|
161
|
-
// CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\"\\\"]"]
|
|
162
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="none"]
|
|
163
|
-
// CIL[DOC-MICRO logic_summary="Validates presence of index.tsx, pages/, and functions/ based on app_type" notable_decisions="[]"]
|
|
164
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
165
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
166
|
-
// CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/migrations/015_simplify_apps_table.sql, \."]
|
|
167
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
168
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
169
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
281
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Validate the presence and version of an app package.json'; No verified external callers; imports: none"]
|
|
282
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
283
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
284
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
170
285
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
171
286
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
287
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:validatePackageJson:function"]
|
|
288
|
+
|
|
289
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:validateRequiredFiles:function" type="function" identity="validateRequiredFiles" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
290
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
291
|
+
// CIL[DOC-MACRO purpose="Validate the presence of files and directories required by the app type"]
|
|
292
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Check for index.tsx, pages/ and functions/ depending on app_type"]
|
|
293
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
294
|
+
// CIL[DOC-CONTRACT inputs="appPath: string, manifest: Manifest" outputs="void" errors="ValidationError on missing required files or directories" side_effects="none"]
|
|
295
|
+
// CIL[DOC-MICRO logic_summary="Switch on app_type and assert existence of index.tsx, pages/ and/or functions/" notable_decisions=""]
|
|
296
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
297
|
+
// CIL[DOC-STABILITY stable]
|
|
172
298
|
function validateRequiredFiles(appPath: string, manifest: Manifest): void {
|
|
173
299
|
const { app_type } = manifest
|
|
174
300
|
|
|
@@ -190,25 +316,28 @@ function validateRequiredFiles(appPath: string, manifest: Manifest): void {
|
|
|
190
316
|
}
|
|
191
317
|
}
|
|
192
318
|
}
|
|
193
|
-
// CIL[
|
|
194
|
-
// CIL[
|
|
195
|
-
// CIL[DOC-
|
|
196
|
-
// CIL[DOC-
|
|
197
|
-
// CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
|
|
198
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="none"]
|
|
199
|
-
// CIL[DOC-MICRO logic_summary="Ensures only standard directories plus optional .devin/ exist" notable_decisions="[]"]
|
|
200
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
201
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
202
|
-
// CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: .framework/migrations/015_simplify_apps_table.sql, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
|
|
203
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
204
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
205
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
319
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Validate the presence of files and directories required by the app type'; No verified external callers; imports: none"]
|
|
320
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
321
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
322
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
206
323
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
207
324
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
325
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:validateRequiredFiles:function"]
|
|
326
|
+
|
|
327
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:validateAllowedDirectories:function" type="function" identity="validateAllowedDirectories" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
328
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
329
|
+
// CIL[DOC-MACRO purpose="Validate that the app root contains only allowed directories"]
|
|
330
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Scan top-level directories and reject any not in the allow list"]
|
|
331
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
332
|
+
// CIL[DOC-CONTRACT inputs="appPath: string" outputs="void" errors="ValidationError on disallowed directories" side_effects="none"]
|
|
333
|
+
// CIL[DOC-MICRO logic_summary="Read app root directories and compare against an allow list of generic app features including optional .devin" notable_decisions=""]
|
|
334
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
335
|
+
// CIL[DOC-STABILITY stable]
|
|
208
336
|
function validateAllowedDirectories(appPath: string): void {
|
|
209
337
|
const allowedDirs = [
|
|
210
|
-
'pages', 'components', 'hooks', 'utils', 'functions',
|
|
211
|
-
'seed', 'public'
|
|
338
|
+
'pages', 'components', 'hooks', 'utils', 'functions',
|
|
339
|
+
'seed', 'public', 'lib', 'views', 'docs', 'mcp',
|
|
340
|
+
'migrations', 'migrations-archive', 'tests'
|
|
212
341
|
]
|
|
213
342
|
|
|
214
343
|
const entries = readdirSync(appPath, { withFileTypes: true })
|
|
@@ -221,21 +350,23 @@ function validateAllowedDirectories(appPath: string): void {
|
|
|
221
350
|
throw new ValidationError(`❌ Unknown directories found: ${unknownDirs.join(', ')}. Allowed directories: ${allowedDirs.join(', ')} (plus optional .devin/)`)
|
|
222
351
|
}
|
|
223
352
|
}
|
|
224
|
-
// CIL[
|
|
225
|
-
// CIL[
|
|
226
|
-
// CIL[DOC-
|
|
227
|
-
// CIL[DOC-
|
|
228
|
-
// CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[]"]
|
|
229
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="console_output"]
|
|
230
|
-
// CIL[DOC-MICRO logic_summary="Validates AGENTS.md presence and skills directory structure" notable_decisions="[]"]
|
|
231
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
232
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
233
|
-
// CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
234
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
235
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
236
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
353
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Validate that the app root contains only allowed directories'; No verified external callers; imports: none"]
|
|
354
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
355
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
356
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
237
357
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
238
358
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
359
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:validateAllowedDirectories:function"]
|
|
360
|
+
|
|
361
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:validateDevinDirectory:function" type="function" identity="validateDevinDirectory" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
362
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
363
|
+
// CIL[DOC-MACRO purpose="Validate the optional .devin/ directory structure"]
|
|
364
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Check that .devin/ contains AGENTS.md and that every skill has SKILL.md"]
|
|
365
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
366
|
+
// CIL[DOC-CONTRACT inputs="appPath: string" outputs="void" errors="ValidationError on missing AGENTS.md or missing SKILL.md" side_effects="logs to stdout"]
|
|
367
|
+
// CIL[DOC-MICRO logic_summary="If .devin exists, verify AGENTS.md and each skill subdirectory has SKILL.md" notable_decisions=""]
|
|
368
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
369
|
+
// CIL[DOC-STABILITY stable]
|
|
239
370
|
function validateDevinDirectory(appPath: string): void {
|
|
240
371
|
const devinPath = join(appPath, '.devin')
|
|
241
372
|
|
|
@@ -265,21 +396,23 @@ function validateDevinDirectory(appPath: string): void {
|
|
|
265
396
|
console.log(`✅ .devin/ directory not present (optional)`)
|
|
266
397
|
}
|
|
267
398
|
}
|
|
268
|
-
// CIL[
|
|
269
|
-
// CIL[
|
|
270
|
-
// CIL[DOC-
|
|
271
|
-
// CIL[DOC-
|
|
272
|
-
// CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[]"]
|
|
273
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="console_output"]
|
|
274
|
-
// CIL[DOC-MICRO logic_summary="Validates routes and nav_items are root-relative and properly formatted" notable_decisions="[]"]
|
|
275
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="complex_dependencies"]
|
|
276
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
277
|
-
// CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
278
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
279
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
280
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
399
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Validate the optional .devin/ directory structure'; No verified external callers; imports: none"]
|
|
400
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
401
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
402
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
281
403
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
282
404
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
405
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:validateDevinDirectory:function"]
|
|
406
|
+
|
|
407
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:validateRoutes:function" type="function" identity="validateRoutes" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
408
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
409
|
+
// CIL[DOC-MACRO purpose="Validate route and nav_item paths in the manifest"]
|
|
410
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Check that routes are root-relative and do not repeat the route_prefix"]
|
|
411
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
412
|
+
// CIL[DOC-CONTRACT inputs="appPath: string, manifest: Manifest" outputs="void" errors="ValidationError on route prefix duplication or missing leading slash" side_effects="logs warnings to stdout"]
|
|
413
|
+
// CIL[DOC-MICRO logic_summary="If route_prefix is set, ensure routes and nav_items do not include it and start with /" notable_decisions=""]
|
|
414
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
415
|
+
// CIL[DOC-STABILITY stable]
|
|
283
416
|
function validateRoutes(appPath: string, manifest: Manifest): void {
|
|
284
417
|
if (!manifest.route_prefix) {
|
|
285
418
|
console.warn('⚠️ manifest.json is missing route_prefix — install-app will default to /{slug}')
|
|
@@ -317,33 +450,66 @@ function validateRoutes(appPath: string, manifest: Manifest): void {
|
|
|
317
450
|
for (const item of (manifest as any).nav_items) checkNavItem(item)
|
|
318
451
|
}
|
|
319
452
|
}
|
|
320
|
-
// CIL[
|
|
321
|
-
// CIL[
|
|
322
|
-
// CIL[DOC-
|
|
323
|
-
// CIL[DOC-
|
|
324
|
-
// CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[]"]
|
|
325
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="none"]
|
|
326
|
-
// CIL[DOC-MICRO logic_summary="Validates referenced files exist and registration config is consistent" notable_decisions="[]"]
|
|
327
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
328
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
329
|
-
// CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
330
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
331
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
332
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
453
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Validate route and nav_item paths in the manifest'; No verified external callers; imports: none"]
|
|
454
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
455
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
456
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
333
457
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
334
458
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
459
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:validateRoutes:function"]
|
|
460
|
+
|
|
461
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:canonicalfilewithin:function" type="function" identity="canonicalFileWithin" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
462
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
463
|
+
// CIL[DOC-MACRO purpose="Resolve a root-contained file path for manifest-referenced files"]
|
|
464
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Return the canonical path of an existing regular file inside the app root, or null"]
|
|
465
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
466
|
+
// CIL[DOC-CONTRACT inputs="appPath: string, relPath: string" outputs="string canonical path or null" errors="none" side_effects="reads filesystem metadata via realpathSync and statSync"]
|
|
467
|
+
// CIL[DOC-MICRO logic_summary="Rejects absolute paths, lexical escapes, symlink escapes, and non-file targets by canonicalizing app root and target with realpathSync" notable_decisions=""]
|
|
468
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
469
|
+
// CIL[DOC-STABILITY stable]
|
|
470
|
+
function canonicalFileWithin(appPath: string, relPath: string): string | null {
|
|
471
|
+
try {
|
|
472
|
+
if (isAbsolute(relPath)) return null
|
|
473
|
+
const root = realpathSync(appPath)
|
|
474
|
+
const lexical = resolve(root, relPath)
|
|
475
|
+
if (lexical !== root && !lexical.startsWith(root + sep)) return null
|
|
476
|
+
const canonical = realpathSync(lexical)
|
|
477
|
+
if (canonical !== root && !canonical.startsWith(root + sep)) return null
|
|
478
|
+
if (!statSync(canonical).isFile()) return null
|
|
479
|
+
return canonical
|
|
480
|
+
} catch {
|
|
481
|
+
return null
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Resolve a root-contained file path for manifest-referenced files'; No verified external callers; imports: none"]
|
|
485
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
486
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
487
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
488
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
489
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
490
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:canonicalfilewithin:function"]
|
|
491
|
+
|
|
492
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:validateManifestComponents:function" type="function" identity="validateManifestComponents" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
493
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
494
|
+
// CIL[DOC-MACRO purpose="Validate manifest references to component files and registration constraints"]
|
|
495
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Check entry_point, sidebar_component and account strategy fields"]
|
|
496
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
497
|
+
// CIL[DOC-CONTRACT inputs="appPath: string, manifest: Manifest" outputs="void" errors="ValidationError on missing referenced files or inconsistent registration" side_effects="reads filesystem metadata for root-contained files via canonicalFileWithin"]
|
|
498
|
+
// CIL[DOC-MICRO logic_summary="Verify referenced files exist as root-contained regular files via canonicalFileWithin and that existing account strategy has target_account" notable_decisions=""]
|
|
499
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
500
|
+
// CIL[DOC-STABILITY stable]
|
|
335
501
|
function validateManifestComponents(appPath: string, manifest: Manifest): void {
|
|
336
502
|
if (manifest.entry_point) {
|
|
337
503
|
const ep = manifest.entry_point.replace(/^\.\//, '')
|
|
338
|
-
if (!
|
|
339
|
-
throw new ValidationError(`❌ manifest.json entry_point "${manifest.entry_point}" does not exist`)
|
|
504
|
+
if (!canonicalFileWithin(appPath, ep)) {
|
|
505
|
+
throw new ValidationError(`❌ manifest.json entry_point "${manifest.entry_point}" does not exist or escapes the app root`)
|
|
340
506
|
}
|
|
341
507
|
}
|
|
342
508
|
|
|
343
509
|
if (manifest.sidebar_component) {
|
|
344
510
|
const sc = manifest.sidebar_component.replace(/^\.\//, '')
|
|
345
|
-
if (!
|
|
346
|
-
throw new ValidationError(`❌ manifest.json sidebar_component "${manifest.sidebar_component}" does not exist`)
|
|
511
|
+
if (!canonicalFileWithin(appPath, sc)) {
|
|
512
|
+
throw new ValidationError(`❌ manifest.json sidebar_component "${manifest.sidebar_component}" does not exist or escapes the app root`)
|
|
347
513
|
}
|
|
348
514
|
}
|
|
349
515
|
|
|
@@ -351,21 +517,23 @@ function validateManifestComponents(appPath: string, manifest: Manifest): void {
|
|
|
351
517
|
throw new ValidationError(`❌ manifest.json registration.account_strategy is "existing" but target_account is not set`)
|
|
352
518
|
}
|
|
353
519
|
}
|
|
354
|
-
// CIL[
|
|
355
|
-
// CIL[
|
|
356
|
-
// CIL[DOC-
|
|
357
|
-
// CIL[DOC-
|
|
358
|
-
// CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[]"]
|
|
359
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="none"]
|
|
360
|
-
// CIL[DOC-MICRO logic_summary="Validates seed array structure and SQL file existence" notable_decisions="[]"]
|
|
361
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
362
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
363
|
-
// CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
364
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
365
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
366
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
520
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Validate manifest references to component files and registration constraints'; No verified external callers; imports: none"]
|
|
521
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
522
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
523
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
367
524
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
368
525
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
526
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:validateManifestComponents:function"]
|
|
527
|
+
|
|
528
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:validateSeedBlock:function" type="function" identity="validateSeedBlock" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
529
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
530
|
+
// CIL[DOC-MACRO purpose="Validate the seed block in the manifest"]
|
|
531
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Check that seed entries are well-formed and reference root-contained .json files containing an array of object records"]
|
|
532
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
533
|
+
// CIL[DOC-CONTRACT inputs="appPath: string, manifest: Manifest" outputs="void" errors="ValidationError on malformed seed entries, missing seed files, path escapes, or non-object rows" side_effects="none"]
|
|
534
|
+
// CIL[DOC-MICRO logic_summary="Assert seed is an array of objects; each entry needs nonempty-trimmed file/table/conflict strings; entry.file is relative to the app root, must resolve to a root-contained regular .json file via canonicalFileWithin, and must parse to a JSON array of non-null objects" notable_decisions=""]
|
|
535
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
536
|
+
// CIL[DOC-STABILITY stable]
|
|
369
537
|
function validateSeedBlock(appPath: string, manifest: Manifest): void {
|
|
370
538
|
if (!manifest.seed) return
|
|
371
539
|
|
|
@@ -374,36 +542,214 @@ function validateSeedBlock(appPath: string, manifest: Manifest): void {
|
|
|
374
542
|
}
|
|
375
543
|
|
|
376
544
|
for (const entry of manifest.seed) {
|
|
377
|
-
if (!entry
|
|
545
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
|
|
546
|
+
throw new ValidationError('❌ manifest.json seed entries must be objects')
|
|
547
|
+
}
|
|
548
|
+
if (typeof entry.file !== 'string' || !entry.file.trim() || typeof entry.table !== 'string' || !entry.table.trim() || typeof entry.conflict !== 'string' || !entry.conflict.trim()) {
|
|
378
549
|
throw new ValidationError('❌ manifest.json seed entries must have file, table, and conflict fields')
|
|
379
550
|
}
|
|
380
551
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
552
|
+
if (isAbsolute(entry.file) || !existsSync(join(appPath, entry.file))) {
|
|
553
|
+
throw new ValidationError(`❌ Seed file not found: ${entry.file}`)
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const seedFile = canonicalFileWithin(appPath, entry.file)
|
|
557
|
+
if (!seedFile) {
|
|
558
|
+
throw new ValidationError(`❌ Seed file escapes the app root: ${entry.file}`)
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
if (!seedFile.endsWith('.json')) {
|
|
562
|
+
throw new ValidationError(`❌ Seed file must be .json: ${entry.file}`)
|
|
384
563
|
}
|
|
385
564
|
|
|
386
|
-
|
|
387
|
-
|
|
565
|
+
let rows: unknown
|
|
566
|
+
try {
|
|
567
|
+
rows = JSON.parse(readFileSync(seedFile, 'utf8'))
|
|
568
|
+
} catch {
|
|
569
|
+
throw new ValidationError(`❌ Seed file is not valid JSON: ${entry.file}`)
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
if (!Array.isArray(rows)) {
|
|
573
|
+
throw new ValidationError(`❌ Seed file must contain a JSON array of records: ${entry.file}`)
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
for (const row of rows) {
|
|
577
|
+
if (!row || typeof row !== 'object' || Array.isArray(row)) {
|
|
578
|
+
throw new ValidationError(`❌ Seed file must contain only non-null object records: ${entry.file}`)
|
|
579
|
+
}
|
|
388
580
|
}
|
|
389
581
|
}
|
|
390
582
|
}
|
|
391
|
-
// CIL[
|
|
392
|
-
// CIL[
|
|
393
|
-
// CIL[DOC-
|
|
394
|
-
// CIL[DOC-
|
|
395
|
-
// CIL[DOC-
|
|
396
|
-
// CIL[DOC-
|
|
397
|
-
// CIL[
|
|
398
|
-
|
|
583
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Validate the seed block in the manifest'; No verified external callers; imports: none"]
|
|
584
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
585
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
586
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
587
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
588
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
589
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:validateSeedBlock:function"]
|
|
590
|
+
|
|
591
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:validateownedtypes:function" type="function" identity="validateOwnedTypes" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
592
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
593
|
+
// CIL[DOC-MACRO purpose="Validate the optional owned_types manifest declaration"]
|
|
594
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Require owned_types to be an array of non-empty strings where each slug resolves to a record in the app's types seed (seed/types.json)"]
|
|
595
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/install-app.ts"]
|
|
596
|
+
// CIL[DOC-CONTRACT inputs="appPath: string, manifest: Manifest" outputs="void" errors="ValidationError on a malformed owned_types array or a slug absent from the types seed" side_effects="reads types seed files"]
|
|
597
|
+
// CIL[DOC-MICRO logic_summary="Return early when owned_types is absent; shape-check the array, then collect slugs from every declared non-patch types seed entry plus the conventional seed/types.json default and reject undeclared slugs" notable_decisions="absent owned_types is a valid optional field; install-app --reconcile-owned-types trusts the same resolution set"]
|
|
598
|
+
// CIL[DOC-CONFIDENCE pass="first" score="0.9" flags="none"]
|
|
399
599
|
// CIL[DOC-STABILITY stability="stable"]
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
600
|
+
function validateOwnedTypes(appPath: string, manifest: Manifest): void {
|
|
601
|
+
const owned = manifest.owned_types
|
|
602
|
+
if (owned === undefined) return
|
|
603
|
+
|
|
604
|
+
if (!Array.isArray(owned) || owned.some(s => typeof s !== 'string' || !s.trim())) {
|
|
605
|
+
throw new ValidationError('❌ manifest.json owned_types must be an array of non-empty strings')
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// Resolve declared slugs against every types seed this app ships: declared
|
|
609
|
+
// non-patch seed entries for the types table, plus the conventional
|
|
610
|
+
// seed/types.json the installer applies by default.
|
|
611
|
+
const typeSlugs = new Set<string>()
|
|
612
|
+
const collectFrom = (relPath: string) => {
|
|
613
|
+
const file = canonicalFileWithin(appPath, relPath)
|
|
614
|
+
if (!file) return
|
|
615
|
+
try {
|
|
616
|
+
const rows: unknown = JSON.parse(readFileSync(file, 'utf8'))
|
|
617
|
+
if (Array.isArray(rows)) {
|
|
618
|
+
for (const row of rows) {
|
|
619
|
+
if (row && typeof row === 'object' && typeof (row as any).slug === 'string') typeSlugs.add((row as any).slug)
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
} catch { /* malformed declared files already failed in validateSeedBlock */ }
|
|
623
|
+
}
|
|
624
|
+
for (const entry of manifest.seed ?? []) {
|
|
625
|
+
if (entry && typeof entry === 'object' && !Array.isArray(entry)
|
|
626
|
+
&& entry.table === 'types' && entry.permissions_patch !== true && typeof entry.file === 'string') {
|
|
627
|
+
collectFrom(entry.file)
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
collectFrom('seed/types.json')
|
|
631
|
+
|
|
632
|
+
for (const slug of owned) {
|
|
633
|
+
if (!typeSlugs.has(slug)) {
|
|
634
|
+
throw new ValidationError(`❌ manifest.json owned_types declares "${slug}" but no type record with that slug exists in the app's types seed (seed/types.json)`)
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Validate the optional owned_types manifest declaration'; No verified external callers; imports: none"]
|
|
639
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
640
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
641
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
404
642
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
405
643
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
406
|
-
|
|
644
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:validateownedtypes:function"]
|
|
645
|
+
// CIL[DOC-MACRO purpose="Validate the manifest knowledge envelope and seed prompt-config picks"]
|
|
646
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Check config.knowledge shape and verify seeded prompt_configs' retrieval_policy picks stay inside the envelope — an agent may narrow the app envelope but never widen it"]
|
|
647
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/functions/_shared/kb.ts"]
|
|
648
|
+
// CIL[DOC-CONTRACT inputs="appPath: string, manifest: Manifest" outputs="void" errors="ValidationError on malformed envelope or out-of-envelope picks" side_effects="none"]
|
|
649
|
+
// CIL[DOC-MICRO logic_summary="Shape-check account/platform/cil blocks, then intersect each seeded prompt config's item_types and cil project_ids against the envelope; warns when agents would get no access (deny-by-default)" notable_decisions="trailing-* prefix patterns supported in item_types/sources"]
|
|
650
|
+
// CIL[DOC-CONFIDENCE pass="first" score="0.9" flags="none"]
|
|
651
|
+
// CIL[DOC-STABILITY stability="experimental"]
|
|
652
|
+
function validateKnowledgeEnvelope(appPath: string, manifest: Manifest): void {
|
|
653
|
+
const envelope = manifest.config?.knowledge
|
|
654
|
+
if (envelope === undefined) {
|
|
655
|
+
console.warn('⚠️ manifest.json config.knowledge is absent — agents and KB search will be denied (deny-by-default)')
|
|
656
|
+
return
|
|
657
|
+
}
|
|
658
|
+
if (envelope === null || typeof envelope !== 'object' || Array.isArray(envelope)) {
|
|
659
|
+
throw new ValidationError('❌ manifest.json config.knowledge must be an object')
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
const isPatternList = (v: any) => Array.isArray(v) && v.every((s) => typeof s === 'string' && s.length > 0)
|
|
663
|
+
|
|
664
|
+
if (envelope.account !== undefined) {
|
|
665
|
+
const a = envelope.account
|
|
666
|
+
if (a !== true && a !== false && (typeof a !== 'object' || a === null || Array.isArray(a))) {
|
|
667
|
+
throw new ValidationError('❌ config.knowledge.account must be a boolean or an object')
|
|
668
|
+
}
|
|
669
|
+
if (a && typeof a === 'object') {
|
|
670
|
+
if (a.scope !== undefined && !['self', 'self_and_descendants'].includes(a.scope)) {
|
|
671
|
+
throw new ValidationError(`❌ config.knowledge.account.scope must be "self" or "self_and_descendants", got "${a.scope}"`)
|
|
672
|
+
}
|
|
673
|
+
if (a.item_types !== undefined && !isPatternList(a.item_types)) {
|
|
674
|
+
throw new ValidationError('❌ config.knowledge.account.item_types must be an array of item_type slugs or "prefix*" patterns')
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
if (envelope.platform !== undefined) {
|
|
679
|
+
const p = envelope.platform
|
|
680
|
+
if (p !== true && p !== false && (typeof p !== 'object' || p === null || Array.isArray(p))) {
|
|
681
|
+
throw new ValidationError('❌ config.knowledge.platform must be a boolean or an object')
|
|
682
|
+
}
|
|
683
|
+
if (p && typeof p === 'object' && p.sources !== undefined && !isPatternList(p.sources)) {
|
|
684
|
+
throw new ValidationError('❌ config.knowledge.platform.sources must be an array of item_type slugs')
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
if (envelope.cil !== undefined) {
|
|
688
|
+
const c = envelope.cil
|
|
689
|
+
if (c !== true && c !== false && (typeof c !== 'object' || c === null || Array.isArray(c))) {
|
|
690
|
+
throw new ValidationError('❌ config.knowledge.cil must be a boolean or an object')
|
|
691
|
+
}
|
|
692
|
+
if (c && typeof c === 'object' && c.project_ids !== undefined && !isPatternList(c.project_ids)) {
|
|
693
|
+
throw new ValidationError('❌ config.knowledge.cil.project_ids must be an array of project UUIDs')
|
|
694
|
+
}
|
|
695
|
+
if (c === true) {
|
|
696
|
+
console.warn('⚠️ config.knowledge.cil is enabled without project_ids — CIL access requires a non-empty project list to resolve at runtime')
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
// Cross-check seeded prompt-config picks against the envelope.
|
|
701
|
+
const seedPath = join(appPath, 'seed', 'prompt-configs.json')
|
|
702
|
+
if (!existsSync(seedPath)) return
|
|
703
|
+
let configs: any[] = []
|
|
704
|
+
try {
|
|
705
|
+
const parsed = JSON.parse(readFileSync(seedPath, 'utf8'))
|
|
706
|
+
configs = Array.isArray(parsed) ? parsed : (parsed.prompt_configs || parsed.items || [])
|
|
707
|
+
} catch {
|
|
708
|
+
return
|
|
709
|
+
}
|
|
710
|
+
const accountPatterns = envelope.account && envelope.account !== true ? (envelope.account.item_types ?? null) : (envelope.account ? null : [])
|
|
711
|
+
const platformPatterns = envelope.platform && envelope.platform !== true ? (envelope.platform.sources ?? null) : (envelope.platform ? null : [])
|
|
712
|
+
const matchAny = (patterns: string[] | null, t: string) =>
|
|
713
|
+
patterns == null ? true : patterns.some((p) => p === '*' || (p.endsWith('*') ? t.startsWith(p.slice(0, -1)) : p === t))
|
|
714
|
+
const envCilIds = envelope.cil && envelope.cil !== true ? (envelope.cil.project_ids ?? null) : null
|
|
715
|
+
|
|
716
|
+
for (const cfg of configs) {
|
|
717
|
+
const pick = cfg?.metadata?.retrieval_policy?.item_types || []
|
|
718
|
+
const label = cfg.slug || cfg.name || '(unnamed)'
|
|
719
|
+
const outside = pick.filter((t: string) =>
|
|
720
|
+
!(t === 'cil_chunk' && !!envelope.cil) && !matchAny(accountPatterns, t) && !matchAny(platformPatterns, t)
|
|
721
|
+
)
|
|
722
|
+
if (outside.length) {
|
|
723
|
+
throw new ValidationError(
|
|
724
|
+
`❌ seed/prompt-configs.json "${label}" picks item_types outside the knowledge envelope: ${outside.join(', ')}`
|
|
725
|
+
)
|
|
726
|
+
}
|
|
727
|
+
const pickCil = cfg?.metadata?.cil_config?.project_ids || []
|
|
728
|
+
if (pickCil.length) {
|
|
729
|
+
if (!envelope.cil) {
|
|
730
|
+
throw new ValidationError(`❌ prompt config "${label}" sets cil_config.project_ids but config.knowledge.cil is not enabled`)
|
|
731
|
+
}
|
|
732
|
+
if (envCilIds) {
|
|
733
|
+
const bad = pickCil.filter((id: string) => !envCilIds.includes(id))
|
|
734
|
+
if (bad.length) {
|
|
735
|
+
throw new ValidationError(`❌ prompt config "${label}" cil project_ids outside envelope: ${bad.join(', ')}`)
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:validateknowledgeenvelope:function"]
|
|
742
|
+
|
|
743
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:validateAppStructure:function" type="function" identity="validateAppStructure" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
744
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
745
|
+
// CIL[DOC-MACRO purpose="Run the full app structure validation pipeline"]
|
|
746
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Orchestrate manifest, package, required files, directories, devin, routes, components, seed and owned_types checks"]
|
|
747
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
748
|
+
// CIL[DOC-CONTRACT inputs="appPath: string" outputs="void" errors="ValidationError from any sub-validator" side_effects="logs validation result to stdout"]
|
|
749
|
+
// CIL[DOC-MICRO logic_summary="Call each validator in sequence — including validateOwnedTypes after validateSeedBlock so declared seed files are already proven well-formed — and log success" notable_decisions=""]
|
|
750
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
751
|
+
// CIL[DOC-STABILITY stable]
|
|
752
|
+
export function validateAppStructure(appPath: string): void {
|
|
407
753
|
const manifest = validateManifest(appPath)
|
|
408
754
|
validatePackageJson(appPath, manifest)
|
|
409
755
|
validateRequiredFiles(appPath, manifest)
|
|
@@ -412,23 +758,27 @@ function validateAppStructure(appPath: string): void {
|
|
|
412
758
|
validateRoutes(appPath, manifest)
|
|
413
759
|
validateManifestComponents(appPath, manifest)
|
|
414
760
|
validateSeedBlock(appPath, manifest)
|
|
761
|
+
validateOwnedTypes(appPath, manifest)
|
|
762
|
+
validateKnowledgeEnvelope(appPath, manifest)
|
|
415
763
|
console.log(`✅ App structure is valid`)
|
|
416
764
|
}
|
|
417
|
-
// CIL[
|
|
418
|
-
// CIL[
|
|
419
|
-
// CIL[DOC-
|
|
420
|
-
// CIL[DOC-
|
|
421
|
-
// CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[]"]
|
|
422
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="validate_app_command" errors="command_errors" side_effects="process_exit"]
|
|
423
|
-
// CIL[DOC-MICRO logic_summary="Registers validate-app command with path option and error handling" notable_decisions="[]"]
|
|
424
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
425
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
426
|
-
// CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
427
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
428
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
429
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
765
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Run the full app structure validation pipeline'; No verified external callers; imports: none"]
|
|
766
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
767
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
768
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
430
769
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
431
770
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
771
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:validateAppStructure:function"]
|
|
772
|
+
|
|
773
|
+
// CIL[BEGIN stable_id="~/.framework/cli/commands/validate-app.ts:registerValidateAppCommands:function" type="function" identity="registerValidateAppCommands" parent="~/.framework/cli/commands/validate-app.ts"]
|
|
774
|
+
// CIL[DOC-AUDIENCE audience="CLI engineers and framework maintainers"]
|
|
775
|
+
// CIL[DOC-MACRO purpose="Register the validate-app CLI subcommand and run validation"]
|
|
776
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Add a validate-app command to a Commander program that validates a local app directory"]
|
|
777
|
+
// CIL[DOC-CONTEXT module="validate-app" layer="cli" related_files=".framework/cli/commands/validate-app.ts"]
|
|
778
|
+
// CIL[DOC-CONTRACT inputs="program: Command" outputs="none" errors="process.exit(1) on validation or unexpected errors" side_effects="logs to stdout and stderr, may exit process"]
|
|
779
|
+
// CIL[DOC-MICRO logic_summary="Define the validate-app command, resolve the app path, call validateAppStructure and handle errors" notable_decisions=""]
|
|
780
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
781
|
+
// CIL[DOC-STABILITY stable]
|
|
432
782
|
export function registerValidateAppCommands(program: Command) {
|
|
433
783
|
program
|
|
434
784
|
.command('validate-app [path]')
|
|
@@ -451,4 +801,10 @@ export function registerValidateAppCommands(program: Command) {
|
|
|
451
801
|
}
|
|
452
802
|
})
|
|
453
803
|
}
|
|
454
|
-
// CIL[
|
|
804
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Register the validate-app CLI subcommand and run validation'; No verified external callers; imports: none"]
|
|
805
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
806
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
807
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
808
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
809
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
810
|
+
// CIL[END stable_id="~/.framework/cli/commands/validate-app.ts:registerValidateAppCommands:function"]
|