spine-framework 0.3.145 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +76 -0
- package/.framework/.spine-manifest.json +19 -0
- package/.framework/cli/commands/agents.ts +61 -33
- package/.framework/cli/commands/auth.ts +60 -28
- package/.framework/cli/commands/create-app.ts +212 -80
- package/.framework/cli/commands/dev.ts +184 -68
- package/.framework/cli/commands/doctor.ts +324 -152
- package/.framework/cli/commands/generate.ts +119 -68
- package/.framework/cli/commands/init.ts +141 -242
- package/.framework/cli/commands/install-app.ts +1336 -314
- package/.framework/cli/commands/items.ts +31 -29
- package/.framework/cli/commands/migrate.ts +299 -156
- package/.framework/cli/commands/migrations.ts +62 -30
- package/.framework/cli/commands/pipelines.ts +31 -29
- package/.framework/cli/commands/status.ts +105 -45
- package/.framework/cli/commands/system.ts +47 -42
- package/.framework/cli/commands/test.ts +161 -102
- package/.framework/cli/commands/upgrade.ts +260 -0
- package/.framework/cli/commands/validate-app.ts +517 -161
- package/.framework/cli/context.ts +117 -85
- package/.framework/cli/env-loader.ts +74 -43
- package/.framework/cli/index.ts +70 -46
- package/.framework/cli/lib/project-files.ts +404 -0
- package/.framework/docs/guides/testing-guide.md +1 -1
- package/.framework/docs/runtime-types.md +72 -72
- package/.framework/functions/_shared/access.ts +84 -0
- package/.framework/functions/_shared/agent-runner.ts +5051 -1026
- package/.framework/functions/_shared/app-manifest.ts +214 -94
- package/.framework/functions/_shared/ast.ts +214 -0
- package/.framework/functions/_shared/audit.ts +91 -55
- package/.framework/functions/_shared/cil.ts +368 -127
- package/.framework/functions/_shared/db.ts +337 -68
- package/.framework/functions/_shared/funnel.ts +228 -0
- package/.framework/functions/_shared/geo.ts +105 -0
- package/.framework/functions/_shared/hash-api-key.ts +94 -17
- package/.framework/functions/_shared/index.ts +22 -224
- package/.framework/functions/_shared/kb.ts +832 -58
- package/.framework/functions/_shared/llm.ts +118 -18
- package/.framework/functions/_shared/logging.ts +317 -19
- package/.framework/functions/_shared/middleware.ts +701 -131
- package/.framework/functions/_shared/notify.ts +70 -0
- package/.framework/functions/_shared/outcomes.ts +34 -19
- package/.framework/functions/_shared/permissions.ts +501 -315
- package/.framework/functions/_shared/pipeline-runner.ts +704 -155
- package/.framework/functions/_shared/principal.ts +436 -263
- package/.framework/functions/_shared/rate-limit.ts +233 -0
- package/.framework/functions/_shared/resolve-credentials.ts +86 -19
- package/.framework/functions/_shared/resolve-ids.ts +203 -139
- package/.framework/functions/_shared/retry-deliveries.ts +51 -16
- package/.framework/functions/_shared/schema-utils.ts +602 -521
- package/.framework/functions/_shared/security.ts +345 -0
- package/.framework/functions/_shared/testing.ts +197 -172
- package/.framework/functions/_shared/tracing.ts +351 -21
- package/.framework/functions/_shared/trigger-engine.ts +425 -136
- package/.framework/functions/_shared/webhook-registration.ts +71 -70
- package/.framework/functions/_shared/webhook-registry.ts +126 -83
- package/.framework/functions/account-nodes.ts +30 -30
- package/.framework/functions/adapters/generic-webhook-inbound.ts +49 -16
- package/.framework/functions/adapters/generic-webhook-outbound.ts +17 -17
- package/.framework/functions/adapters/openai-outbound.ts +15 -16
- package/.framework/functions/admin-data.ts +596 -173
- package/.framework/functions/admin-funnel.ts +64 -60
- package/.framework/functions/admin-install-funnel.ts +84 -66
- package/.framework/functions/admin-signals.ts +69 -51
- package/.framework/functions/ai-agents.ts +431 -106
- package/.framework/functions/ai-interactions.ts +186 -112
- package/.framework/functions/api-keys.ts +107 -107
- package/.framework/functions/apps.ts +154 -136
- package/.framework/functions/auth.ts +83 -65
- package/.framework/functions/cil-agent-ingest.ts +189 -232
- package/.framework/functions/cil-agent.ts +433 -177
- package/.framework/functions/cil-callmap.ts +642 -430
- package/.framework/functions/cil-config.ts +139 -135
- package/.framework/functions/cil-context.ts +214 -127
- package/.framework/functions/cil-doc.ts +587 -458
- package/.framework/functions/cil-embeddings.ts +453 -364
- package/.framework/functions/cil-graph.ts +427 -142
- package/.framework/functions/cil-ingest.ts +1418 -1154
- package/.framework/functions/cil-pipeline.ts +276 -21
- package/.framework/functions/cil-project.ts +659 -132
- package/.framework/functions/cil-validate.ts +198 -164
- package/.framework/functions/debug-auth.ts +57 -55
- package/.framework/functions/deliveries.ts +80 -21
- package/.framework/functions/embeddings.ts +1023 -318
- package/.framework/functions/eval-harness.ts +146 -108
- package/.framework/functions/integration-outbound.ts +205 -75
- package/.framework/functions/integration-routes.ts +128 -23
- package/.framework/functions/integrations.ts +125 -100
- package/.framework/functions/invites.ts +1095 -460
- package/.framework/functions/item-progress.ts +158 -102
- package/.framework/functions/kb.ts +34 -10
- package/.framework/functions/logs.ts +133 -133
- package/.framework/functions/observability.ts +152 -122
- package/.framework/functions/pipeline-executions.ts +147 -132
- package/.framework/functions/pipelines.ts +134 -119
- package/.framework/functions/prompt-configs.ts +96 -80
- package/.framework/functions/roles.ts +112 -82
- package/.framework/functions/security.ts +450 -0
- package/.framework/functions/system-cron.ts +117 -80
- package/.framework/functions/system.ts +158 -98
- package/.framework/functions/tests.ts +29 -29
- package/.framework/functions/timers.ts +94 -95
- package/.framework/functions/trigger-scheduler.ts +10 -0
- package/.framework/functions/triggers.ts +179 -149
- package/.framework/functions/types.ts +137 -125
- package/.framework/mcp/index.ts +133 -0
- package/.framework/mcp/load-env.ts +60 -0
- package/.framework/mcp/shared/app-manifest.ts +275 -0
- package/.framework/mcp/shared/db.ts +477 -0
- package/.framework/mcp/shared/kb.ts +118 -0
- package/.framework/mcp/tools/architect.ts +431 -0
- package/.framework/mcp/tools/cil/context.ts +345 -0
- package/.framework/mcp/tools/cil/graph.ts +242 -0
- package/.framework/mcp/tools/cil/ingest.ts +1217 -0
- package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +693 -0
- package/.framework/mcp/tools/cil/pipeline.ts +767 -0
- package/.framework/mcp/tools/cil/project.ts +791 -0
- package/.framework/mcp/tools/cil/retrieval.ts +336 -0
- package/.framework/mcp/tools/cil/search-core.ts +454 -0
- package/.framework/mcp/tools/cil/search.ts +97 -0
- package/.framework/mcp/tools/cil/suggest.ts +186 -0
- package/.framework/mcp/tools/cil/validate.ts +1369 -0
- package/.framework/mcp/tools/kb/delete.ts +139 -0
- package/.framework/mcp/tools/kb/index.ts +52 -0
- package/.framework/mcp/tools/kb/ingest.ts +84 -0
- package/.framework/mcp/tools/kb/list-types.ts +102 -0
- package/.framework/mcp/tools/kb/publish.ts +100 -0
- package/.framework/mcp/tools/kb/reindex.ts +86 -0
- package/.framework/mcp/tools/kb/revoke.ts +85 -0
- package/.framework/mcp/tools/kb/search.ts +101 -0
- package/.framework/mcp/tools/kb/upsert.ts +125 -0
- package/.framework/mcp/tools/observability.ts +510 -0
- package/.framework/migrations/001_core_schema.sql +15 -0
- package/.framework/migrations/002_core_rls_and_functions.sql +15 -0
- package/.framework/migrations/003_core_system_data.sql +16 -1
- package/.framework/migrations/004_core_rpc_and_broker.sql +17 -1
- package/.framework/migrations/005_core_observability.sql +17 -1
- package/.framework/migrations/006_security_hardening_rls.sql +15 -0
- package/.framework/migrations/007_kb_article_list.sql +17 -1
- package/.framework/migrations/008_items_target.sql +15 -0
- package/.framework/migrations/009_roles_slug_unique.sql +15 -0
- package/.framework/migrations/010_auth_user_trigger.sql +15 -0
- package/.framework/migrations/011_spine_system_account.sql +16 -0
- package/.framework/migrations/012_service_role_grants.sql +16 -0
- package/.framework/migrations/013_get_account_apps_role_filter.sql +15 -0
- package/.framework/migrations/014_apps_required_roles.sql +16 -0
- package/.framework/migrations/015_types_kind_slug_unique.sql +15 -0
- package/.framework/migrations/016_cil_types.sql +281 -0
- package/.framework/migrations/017_cil_stable_ids.sql +37 -0
- package/.framework/migrations/018_runtime_tables.sql +129 -0
- package/.framework/migrations/019_agent_prompt_columns.sql +56 -0
- package/.framework/migrations/020_schema_reconciliation.sql +67 -0
- package/.framework/migrations/021_kb_embedding_lifecycle.sql +31 -0
- package/.framework/migrations/032_cil_status_migration.sql +73 -0
- package/.framework/migrations/033_cil_versioning.sql +73 -0
- package/.framework/migrations/034_match_embeddings_knn.sql +115 -0
- package/.framework/migrations/035_rate_limits.sql +55 -0
- package/.framework/migrations/036_demo_record_flags.sql +72 -0
- package/.framework/migrations/037_kb_types_canonical.sql +244 -0
- package/.framework/migrations/038_drop_demo_record_flags.sql +38 -0
- package/.framework/migrations/042_registration_hierarchy.sql +309 -0
- package/.framework/migrations/043_policy_actor_cleanup.sql +39 -0
- package/.framework/migrations/044_match_embeddings_filtered_knn.sql +151 -0
- package/.framework/migrations/045_security_critical_rls.sql +139 -0
- package/.framework/migrations/046_security_missing_rls.sql +79 -0
- package/.framework/migrations/047_people_updated_by.sql +27 -0
- package/.framework/migrations/048_watcher_last_seen_at.sql +24 -0
- package/.framework/migrations/049_security_blocklist.sql +148 -0
- package/.framework/migrations/050_notifications.sql +49 -0
- package/.framework/migrations/051_message_agent_fields.sql +74 -0
- package/.framework/migrations/052_registration_security.sql +421 -0
- package/.framework/migrations/053_builtin_action_seeds.sql +66 -0
- package/.framework/migrations/054_kb_ingest_lease.sql +157 -0
- package/.framework/migrations/055_type_id_drift_reconciliation.sql +33 -0
- package/.framework/migrations/056_slug_column_reconciliation.sql +38 -0
- package/.framework/migrations/057_pipelines_slug_identity.sql +14 -0
- package/.framework/migrations/058_account_data_field_declarations.sql +53 -0
- package/.framework/migrations/059_registration_placement_fixes.sql +269 -0
- package/.framework/migrations/060_account_person_record_permissions.sql +38 -0
- package/.framework/migrations/061_fk_dedup.sql +32 -0
- package/.framework/public/spine-logo.svg +10 -3
- package/.framework/scripts/app-install-cli.ts +190 -93
- package/.framework/scripts/assemble-frontend.sh +127 -44
- package/.framework/scripts/assemble-functions.sh +128 -30
- package/.framework/scripts/boundary-check.sh +6 -2
- package/.framework/scripts/build-manifest.sh +24 -68
- package/.framework/scripts/check-core-integrity.sh +15 -76
- package/.framework/scripts/checksum-manifest.mts +343 -0
- package/.framework/scripts/cil-migrate-markers.ts +403 -0
- package/.framework/scripts/fix-cil-markers.mjs +176 -0
- package/.framework/scripts/verify-integrity.sh +21 -57
- package/.framework/scripts/verify-manifest.mts +305 -0
- package/.framework/seeds/types/funnel_signal_use.json +74 -21
- package/.framework/seeds/types/spine_instance.json +73 -21
- package/.framework/src/App.tsx +118 -72
- package/.framework/src/apps/admin/index.tsx +855 -58
- package/.framework/src/components/AppWrapper.tsx +43 -45
- package/.framework/src/components/CustomAppLoader.tsx +160 -116
- package/.framework/src/components/admin/AdminListPage.tsx +46 -44
- package/.framework/src/components/admin/AdminSidebar.tsx +57 -47
- package/.framework/src/components/admin/AdminStatsCard.tsx +46 -44
- package/.framework/src/components/admin/PageInstructions.tsx +98 -2
- package/.framework/src/components/admin/SortableTableHeader.tsx +44 -45
- package/.framework/src/components/app-shell/GenericAppShell.tsx +64 -65
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +44 -47
- package/.framework/src/components/app-shell/GenericListPage.tsx +45 -49
- package/.framework/src/components/app-sidebar.tsx +42 -45
- package/.framework/src/components/auth/ProtectedRoute.tsx +48 -41
- package/.framework/src/components/auth/TurnstileWidget.tsx +27 -0
- package/.framework/src/components/kb/KBArticleEditor.tsx +231 -22
- package/.framework/src/components/kb/KBArticleList.tsx +251 -10
- package/.framework/src/components/layout/AppShell.tsx +51 -45
- package/.framework/src/components/layout/Header.tsx +42 -43
- package/.framework/src/components/layout/Layout.tsx +46 -46
- package/.framework/src/components/layout/Sidebar.tsx +196 -96
- package/.framework/src/components/runtime/DataDetailHeader.tsx +55 -30
- package/.framework/src/components/runtime/DataDetailPage.tsx +31 -269
- package/.framework/src/components/runtime/DataFilters.tsx +49 -74
- package/.framework/src/components/runtime/DataHeader.tsx +53 -32
- package/.framework/src/components/runtime/DataListPage.tsx +51 -155
- package/.framework/src/components/runtime/DataStats.tsx +66 -44
- package/.framework/src/components/runtime/DataTable.tsx +49 -149
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +45 -75
- package/.framework/src/components/runtime/index.ts +119 -16
- package/.framework/src/components/search-form.tsx +46 -29
- package/.framework/src/components/shared/AgentView.tsx +65 -48
- package/.framework/src/components/shared/FieldRenderer.tsx +144 -50
- package/.framework/src/components/shared/InviteManager.tsx +207 -97
- package/.framework/src/components/shared/MemberList.tsx +97 -0
- package/.framework/src/components/shared/SchemaFields.tsx +107 -86
- package/.framework/src/components/ui/DataTable.tsx +80 -68
- package/.framework/src/components/ui/Form.tsx +157 -146
- package/.framework/src/components/ui/ItemCard.tsx +74 -67
- package/.framework/src/components/ui/ItemListView.tsx +73 -68
- package/.framework/src/components/ui/LoadingSpinner.tsx +43 -48
- package/.framework/src/components/ui/Modal.tsx +78 -68
- package/.framework/src/components/ui/RichTextEditor.tsx +89 -69
- package/.framework/src/components/ui/accordion.tsx +85 -86
- package/.framework/src/components/ui/alert-dialog.tsx +197 -184
- package/.framework/src/components/ui/alert.tsx +105 -94
- package/.framework/src/components/ui/aspect-ratio.tsx +57 -43
- package/.framework/src/components/ui/avatar.tsx +122 -107
- package/.framework/src/components/ui/badge.tsx +60 -55
- package/.framework/src/components/ui/breadcrumb.tsx +127 -128
- package/.framework/src/components/ui/button-group.tsx +86 -72
- package/.framework/src/components/ui/button.tsx +71 -50
- package/.framework/src/components/ui/calendar.tsx +72 -57
- package/.framework/src/components/ui/card.tsx +136 -129
- package/.framework/src/components/ui/carousel.tsx +226 -107
- package/.framework/src/components/ui/chart.tsx +252 -147
- package/.framework/src/components/ui/checkbox.tsx +43 -44
- package/.framework/src/components/ui/collapsible.tsx +86 -71
- package/.framework/src/components/ui/combobox.tsx +282 -249
- package/.framework/src/components/ui/command.tsx +158 -146
- package/.framework/src/components/ui/context-menu.tsx +239 -240
- package/.framework/src/components/ui/dialog.tsx +174 -157
- package/.framework/src/components/ui/direction.tsx +72 -56
- package/.framework/src/components/ui/drawer.tsx +168 -169
- package/.framework/src/components/ui/dropdown-menu.tsx +254 -223
- package/.framework/src/components/ui/empty.tsx +131 -120
- package/.framework/src/components/ui/field.tsx +205 -173
- package/.framework/src/components/ui/hover-card.tsx +71 -72
- package/.framework/src/components/ui/input-group.tsx +148 -133
- package/.framework/src/components/ui/input-otp.tsx +99 -86
- package/.framework/src/components/ui/input.tsx +43 -41
- package/.framework/src/components/ui/item.tsx +207 -185
- package/.framework/src/components/ui/kbd.tsx +57 -56
- package/.framework/src/components/ui/label.tsx +45 -41
- package/.framework/src/components/ui/menubar.tsx +268 -236
- package/.framework/src/components/ui/native-select.tsx +85 -86
- package/.framework/src/components/ui/navigation-menu.tsx +166 -156
- package/.framework/src/components/ui/pagination.tsx +131 -141
- package/.framework/src/components/ui/popover.tsx +125 -128
- package/.framework/src/components/ui/progress.tsx +47 -44
- package/.framework/src/components/ui/radio-group.tsx +60 -55
- package/.framework/src/components/ui/resizable.tsx +85 -72
- package/.framework/src/components/ui/scroll-area.tsx +57 -58
- package/.framework/src/components/ui/select.tsx +182 -169
- package/.framework/src/components/ui/separator.tsx +42 -43
- package/.framework/src/components/ui/sheet.tsx +170 -159
- package/.framework/src/components/ui/sidebar.tsx +395 -398
- package/.framework/src/components/ui/skeleton.tsx +42 -43
- package/.framework/src/components/ui/slider.tsx +61 -44
- package/.framework/src/components/ui/sonner.tsx +44 -44
- package/.framework/src/components/ui/spinner.tsx +47 -42
- package/.framework/src/components/ui/switch.tsx +56 -42
- package/.framework/src/components/ui/table-primitives.tsx +272 -132
- package/.framework/src/components/ui/table.tsx +140 -142
- package/.framework/src/components/ui/tabs.tsx +110 -93
- package/.framework/src/components/ui/textarea.tsx +43 -44
- package/.framework/src/components/ui/toggle-group.tsx +87 -71
- package/.framework/src/components/ui/toggle.tsx +56 -56
- package/.framework/src/components/ui/tooltip.tsx +99 -85
- package/.framework/src/contexts/AppContext.tsx +166 -114
- package/.framework/src/contexts/AuthContext.tsx +232 -137
- package/.framework/src/hooks/use-mobile.ts +43 -44
- package/.framework/src/hooks/useApi.ts +185 -172
- package/.framework/src/hooks/useAppPath.ts +31 -29
- package/.framework/src/hooks/useApps.ts +77 -42
- package/.framework/src/hooks/useEntityList.ts +66 -29
- package/.framework/src/hooks/useEntityRecord.ts +76 -32
- package/.framework/src/hooks/useForm.ts +62 -30
- package/.framework/src/hooks/useListSchema.ts +60 -43
- package/.framework/src/hooks/useSchemaRecord.ts +115 -95
- package/.framework/src/lib/api.ts +258 -134
- package/.framework/src/lib/registration.ts +181 -0
- package/.framework/src/lib/supabase.ts +118 -81
- package/.framework/src/lib/utils.ts +266 -266
- package/.framework/src/main.tsx +43 -44
- package/.framework/src/pages/DashboardPage.tsx +44 -43
- package/.framework/src/pages/NoAppPage.tsx +50 -0
- package/.framework/src/pages/NotFoundPage.tsx +32 -29
- package/.framework/src/pages/SetupPage.tsx +34 -33
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +69 -58
- package/.framework/src/pages/admin/AIAgentsPage.tsx +43 -40
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +63 -55
- package/.framework/src/pages/admin/APIKeysPage.tsx +44 -42
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +117 -94
- package/.framework/src/pages/admin/AppDetailPage.tsx +48 -42
- package/.framework/src/pages/admin/AppsPage.tsx +45 -42
- package/.framework/src/pages/admin/DeliveriesPage.tsx +49 -17
- package/.framework/src/pages/admin/DesignedPage.tsx +31 -30
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +58 -0
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +49 -0
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +31 -29
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +46 -29
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -29
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +68 -55
- package/.framework/src/pages/admin/IntegrationsPage.tsx +45 -42
- package/.framework/src/pages/admin/InvitesPage.tsx +60 -44
- package/.framework/src/pages/admin/LogsPage.tsx +87 -137
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +31 -29
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +150 -89
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +77 -104
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +44 -43
- package/.framework/src/pages/admin/PipelinesPage.tsx +59 -145
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +53 -42
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +47 -117
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +31 -44
- package/.framework/src/pages/admin/RoleDetailPage.tsx +49 -92
- package/.framework/src/pages/admin/RolesPage.tsx +47 -164
- package/.framework/src/pages/admin/SecurityPage.tsx +310 -0
- package/.framework/src/pages/admin/SelectTestPage.tsx +30 -32
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +37 -44
- package/.framework/src/pages/admin/SimpleDashboard.tsx +32 -44
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +97 -44
- package/.framework/src/pages/admin/TestingDashboard.tsx +126 -71
- package/.framework/src/pages/admin/TimerDetailPage.tsx +67 -55
- package/.framework/src/pages/admin/TimersPage.tsx +44 -42
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +47 -42
- package/.framework/src/pages/admin/TriggersPage.tsx +58 -57
- package/.framework/src/pages/admin/TypeDetailPage.tsx +91 -55
- package/.framework/src/pages/admin/TypesPage.tsx +45 -42
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +258 -128
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +127 -123
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +308 -235
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +159 -110
- package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +432 -0
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +200 -178
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +286 -239
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +211 -90
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +156 -143
- package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +379 -0
- package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +337 -0
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +219 -214
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +135 -65
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +39 -31
- package/.framework/src/pages/auth/LoginPage.tsx +38 -32
- package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -28
- package/.framework/src/pages/auth/RegisterPage.tsx +429 -155
- package/.framework/src/pages/spine-framework/APIPage.tsx +33 -30
- package/.framework/src/pages/spine-framework/CLIPage.tsx +32 -30
- package/.framework/src/types/auth.ts +101 -93
- package/.framework/src/types/types.ts +283 -262
- package/.framework/templates/project.json +87 -0
- package/.framework/templates/spine.config.neutral.json +7 -0
- package/.framework/tests/api/api-surface.test.ts +381 -0
- package/.framework/tests/fixtures/seed.ts +427 -0
- package/.framework/tests/fixtures/teardown.ts +228 -0
- package/.framework/tests/reporter.ts +351 -0
- package/.framework/tests/setup.ts +135 -0
- package/.framework/tests/ui/ui-sweep.ts +278 -0
- package/.framework/tests/unit/admin-data-logger.test.ts +310 -0
- package/.framework/tests/unit/agent-runner.test.ts +2389 -0
- package/.framework/tests/unit/ai-interactions.test.ts +81 -0
- package/.framework/tests/unit/app-manifest.test.ts +359 -0
- package/.framework/tests/unit/assembly-scripts.test.ts +172 -0
- package/.framework/tests/unit/cil-determinism.test.ts +85 -0
- package/.framework/tests/unit/core-isolation.test.ts +153 -0
- package/.framework/tests/unit/funnel-signals.test.ts +135 -0
- package/.framework/tests/unit/install-app.test.ts +1759 -0
- package/.framework/tests/unit/invites-security.test.ts +572 -0
- package/.framework/tests/unit/kb-ingest-lease.test.ts +287 -0
- package/.framework/tests/unit/kb-search.test.ts +119 -0
- package/.framework/tests/unit/migrate.test.ts +509 -0
- package/.framework/tests/unit/notify.test.ts +136 -0
- package/.framework/tests/unit/permissions.test.ts +269 -0
- package/.framework/tests/unit/pipeline-runner.test.ts +755 -0
- package/.framework/tests/unit/principal-cache.test.ts +138 -0
- package/.framework/tests/unit/retrieval-golden.test.ts +520 -0
- package/.framework/tests/unit/runtime-isolation.test.ts +642 -0
- package/.framework/tests/unit/schema-utils.test.ts +225 -0
- package/.framework/tests/unit/trigger-engine.test.ts +513 -0
- package/.framework/tests/unit/validate-app.test.ts +527 -0
- package/README.md +34 -3
- package/bin/spine-framework.cjs +1 -0
- package/config/tailwind.config.cjs +7 -0
- package/config/tsconfig.functions.json +42 -0
- package/config/tsconfig.json +37 -9
- package/config/vite.config.ts +31 -2
- package/netlify.toml +31 -3
- package/package.json +46 -29
- package/scripts/assemble-frontend.sh +127 -44
- package/scripts/assemble-functions.sh +127 -29
- package/scripts/boundary-check.sh +6 -2
- package/scripts/build-manifest.sh +24 -68
- package/scripts/checksum-manifest.mts +345 -0
- package/scripts/dev-clean.sh +86 -0
- package/scripts/dev-netlify.sh +49 -0
- package/scripts/netlify-dev-wrapper.sh +2 -0
- package/scripts/verify-install.ts +358 -0
- package/scripts/verify-integrity.sh +21 -57
- package/scripts/verify-manifest.mts +305 -0
- package/templates/project/gitignore +45 -0
- package/{config → templates/project}/package-lock.json +22335 -9366
- package/vitest.config.ts +46 -0
- package/.framework/public/spine.config.json +0 -91
- package/config/deno.lock +0 -108
- package/config/tsconfig.node.tsbuildinfo +0 -1
- package/config/tsconfig.tsbuildinfo +0 -1
- package/config/vite.config.d.ts +0 -2
- package/custom/.devin/AGENT.md +0 -357
- package/custom/.devin/skills/install-app/SKILL.md +0 -39
- package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +0 -39
- package/custom/.devin/skills/spine-workbench-idea/SKILL.md +0 -36
- package/custom/.devin/skills/spine-workbench-implement/SKILL.md +0 -46
- package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +0 -28
- package/custom/.devin/skills/spine-workbench-plan/SKILL.md +0 -38
- package/custom/.devin/workflows/app-install.yaml +0 -83
- package/custom/README.md +0 -79
- package/docs/README.md +0 -15
- package/scripts/app-install-cli.ts +0 -286
- package/scripts/check-core-integrity.sh +0 -82
- package/scripts/ingest-chunks.cjs +0 -202
- package/scripts/kb-chunk-parser.cjs +0 -312
- package/scripts/kb-chunk-parser.ts +0 -330
- package/scripts/kb-ingest-docs.ts +0 -203
- package/scripts/load-test-app-install.ts +0 -484
- package/scripts/test-login.js +0 -33
- package/spine.config.json +0 -91
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:module_header:module_header"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Defines imports and dependencies for the KB article list UI."]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide React, utility, and UI component imports for KBArticleList."]
|
|
4
|
+
// CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Import block for hooks, API, utilities, and UI primitives." notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
8
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="developers"]
|
|
10
|
+
|
|
1
11
|
import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
2
12
|
import { apiFetch } from '../../lib/api'
|
|
3
13
|
import { formatDateTime } from '../../lib/utils'
|
|
@@ -8,6 +18,24 @@ import { Badge } from '../ui/badge'
|
|
|
8
18
|
import { Skeleton } from '../ui/skeleton'
|
|
9
19
|
import { Plus, Search, Edit, BookOpen, GripVertical, X } from 'lucide-react'
|
|
10
20
|
|
|
21
|
+
|
|
22
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Defines imports and dependencies for the KB article list UI.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
|
|
23
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
24
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
25
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
26
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
27
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
28
|
+
// CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:module_header:module_header"]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
// CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:KBArticleListProps:interface"]
|
|
32
|
+
// CIL[DOC-MACRO purpose="Defines the props accepted by the KBArticleList component."]
|
|
33
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Contract between parent and KBArticleList."]
|
|
34
|
+
// CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
|
|
35
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="KBArticleListProps interface" errors="none" side_effects="none"]
|
|
36
|
+
// CIL[DOC-MICRO logic_summary="Lists optional and required props for the component." notable_decisions="[]"]
|
|
37
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
38
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
11
39
|
export interface KBArticleListProps {
|
|
12
40
|
typeSlugs: string[]
|
|
13
41
|
typeName?: string
|
|
@@ -15,7 +43,23 @@ export interface KBArticleListProps {
|
|
|
15
43
|
onNew?: () => void
|
|
16
44
|
onEdit?: (record: KBRecord) => void
|
|
17
45
|
}
|
|
18
|
-
|
|
46
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Defines the props accepted by the KBArticleList component.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
|
|
47
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
48
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
49
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
50
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
51
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
52
|
+
// CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:KBArticleListProps:interface"]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
// CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:KBRecord:interface"]
|
|
56
|
+
// CIL[DOC-MACRO purpose="Defines the shape of a knowledge base record."]
|
|
57
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Data model for KB articles."]
|
|
58
|
+
// CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
|
|
59
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="KBRecord interface" errors="none" side_effects="none"]
|
|
60
|
+
// CIL[DOC-MICRO logic_summary="Defines KBRecord fields including id, title, status, and data." notable_decisions="[]"]
|
|
61
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
62
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
19
63
|
interface KBRecord {
|
|
20
64
|
id: string
|
|
21
65
|
title: string
|
|
@@ -27,27 +71,127 @@ interface KBRecord {
|
|
|
27
71
|
data: Record<string, any>
|
|
28
72
|
[key: string]: any
|
|
29
73
|
}
|
|
30
|
-
|
|
74
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Defines the shape of a knowledge base record.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
|
|
75
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
76
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
77
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
78
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
79
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
80
|
+
// CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:KBRecord:interface"]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
// CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:TreeNode:interface"]
|
|
84
|
+
// CIL[DOC-MACRO purpose="Defines a tree node that extends KBRecord with children."]
|
|
85
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Recursive tree structure contract."]
|
|
86
|
+
// CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
|
|
87
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="TreeNode interface" errors="none" side_effects="none"]
|
|
88
|
+
// CIL[DOC-MICRO logic_summary="Extends KBRecord with a children array." notable_decisions="[]"]
|
|
89
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
90
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
31
91
|
interface TreeNode extends KBRecord {
|
|
32
92
|
children: TreeNode[]
|
|
33
93
|
}
|
|
34
|
-
|
|
94
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Defines a tree node that extends KBRecord with children.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
|
|
95
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
96
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
97
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
98
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
99
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
100
|
+
// CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:TreeNode:interface"]
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
// CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:isNullId:function"]
|
|
104
|
+
// CIL[DOC-MACRO purpose="Tests whether a value is a null, undefined, or empty id."]
|
|
105
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Predicate for missing id values."]
|
|
106
|
+
// CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
|
|
107
|
+
// CIL[DOC-CONTRACT inputs="a: string | null | undefined" outputs="boolean (type predicate a is null | undefined)" errors="none" side_effects="none"]
|
|
108
|
+
// CIL[DOC-MICRO logic_summary="Returns true for null, undefined, or empty string." notable_decisions="[]"]
|
|
109
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
110
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
35
111
|
function isNullId(a: string | null | undefined): a is null | undefined {
|
|
36
112
|
return a === null || a === undefined || a === ''
|
|
37
113
|
}
|
|
38
|
-
|
|
114
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Tests whether a value is a null, undefined, or empty id.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
|
|
115
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
116
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
117
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
118
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
119
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
120
|
+
// CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:isNullId:function"]
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
// CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:sameId:function"]
|
|
124
|
+
// CIL[DOC-MACRO purpose="Compares two id values for equality, treating nullish as equal."]
|
|
125
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Determine id equality for parent and record comparisons."]
|
|
126
|
+
// CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
|
|
127
|
+
// CIL[DOC-CONTRACT inputs="a, b: string | null | undefined" outputs="boolean" errors="none" side_effects="none"]
|
|
128
|
+
// CIL[DOC-MICRO logic_summary="Returns true if values are equal or both nullish." notable_decisions="[]"]
|
|
129
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
130
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
39
131
|
function sameId(a: string | null | undefined, b: string | null | undefined): boolean {
|
|
40
132
|
return a === b || (isNullId(a) && isNullId(b))
|
|
41
133
|
}
|
|
42
|
-
|
|
134
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Compares two id values for equality, treating nullish as equal.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
|
|
135
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
136
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
137
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
138
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
139
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
140
|
+
// CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:sameId:function"]
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
// CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:sameParent:function"]
|
|
144
|
+
// CIL[DOC-MACRO purpose="Checks whether a record's parent_id matches the given parent."]
|
|
145
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Parent equality predicate for tree grouping."]
|
|
146
|
+
// CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
|
|
147
|
+
// CIL[DOC-CONTRACT inputs="record: KBRecord, parentId: string | undefined" outputs="boolean" errors="none" side_effects="none"]
|
|
148
|
+
// CIL[DOC-MICRO logic_summary="Compares record.data.parent_id to parentId using sameId." notable_decisions="[]"]
|
|
149
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
150
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
43
151
|
function sameParent(record: KBRecord, parentId: string | undefined): boolean {
|
|
44
152
|
return sameId(record.data?.parent_id as string | undefined, parentId)
|
|
45
153
|
}
|
|
46
|
-
|
|
154
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Checks whether a record's parent_id matches the given parent.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
|
|
155
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
156
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
157
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
158
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
159
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
160
|
+
// CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:sameParent:function"]
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
// CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:sortByOrder:function"]
|
|
164
|
+
// CIL[DOC-MACRO purpose="Sorts two KB records by their data.order value."]
|
|
165
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Order comparison for tree siblings."]
|
|
166
|
+
// CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
|
|
167
|
+
// CIL[DOC-CONTRACT inputs="a: KBRecord, b: KBRecord" outputs="number" errors="none" side_effects="none"]
|
|
168
|
+
// CIL[DOC-MICRO logic_summary="Subtracts b order from a order, defaulting to MAX_SAFE_INTEGER." notable_decisions="[]"]
|
|
169
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
170
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
47
171
|
function sortByOrder(a: KBRecord, b: KBRecord): number {
|
|
48
172
|
return (a.data?.order ?? Number.MAX_SAFE_INTEGER) - (b.data?.order ?? Number.MAX_SAFE_INTEGER)
|
|
49
173
|
}
|
|
50
|
-
|
|
174
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Sorts two KB records by their data.order value.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
|
|
175
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
176
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
177
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
178
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
179
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
180
|
+
// CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:sortByOrder:function"]
|
|
181
|
+
|
|
182
|
+
// CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:KBArticleList:component"]
|
|
183
|
+
// CIL[DOC-MACRO purpose="Renders a searchable, filterable, drag-and-drop knowledge base article list."]
|
|
184
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display KB articles as a tree or flat list, support search, status/type filters, and reordering via drag-and-drop."]
|
|
185
|
+
// CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
|
|
186
|
+
// CIL[DOC-CONTRACT inputs="typeSlugs: string[], typeName?: string, onSelect?: (record: KBRecord) => void, onNew?: () => void, onEdit?: (record: KBRecord) => void" outputs="JSX" errors="Network or permission errors" side_effects="Fetches data from API, updates state, PATCHes records on drop."]
|
|
187
|
+
// CIL[DOC-MICRO logic_summary="Loads record types, fetches article trees, handles search, builds filtered tree, renders list, and applies drag-and-drop reordering." notable_decisions="[]"]
|
|
188
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
189
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
190
|
+
// CIL[DOC-NOTE type="param" content="typeSlugs: string[] - allowed knowledge base type slugs"]
|
|
191
|
+
// CIL[DOC-NOTE type="param" content="typeName?: string - display name for the knowledge base"]
|
|
192
|
+
// CIL[DOC-NOTE type="param" content="onSelect?: (record: KBRecord) => void - callback when an article is selected"]
|
|
193
|
+
// CIL[DOC-NOTE type="param" content="onNew?: () => void - callback to create a new article"]
|
|
194
|
+
// CIL[DOC-NOTE type="param" content="onEdit?: (record: KBRecord) => void - callback to edit an article"
|
|
51
195
|
export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }: KBArticleListProps) {
|
|
52
196
|
const [typeRecords, setTypeRecords] = useState<any[]>([])
|
|
53
197
|
const [articles, setArticles] = useState<KBRecord[]>([])
|
|
@@ -60,14 +204,25 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
60
204
|
const [typeFilter, setTypeFilter] = useState<string>('all')
|
|
61
205
|
const [dragging, setDragging] = useState<string | null>(null)
|
|
62
206
|
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
63
210
|
const typeById = useMemo(() => {
|
|
64
211
|
const map: Record<string, any> = {}
|
|
65
212
|
typeRecords.forEach((t) => { map[t.id] = t })
|
|
66
213
|
return map
|
|
67
214
|
}, [typeRecords])
|
|
68
215
|
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
69
220
|
const typeSlugsSet = useMemo(() => new Set(typeSlugs), [typeSlugs])
|
|
70
221
|
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
|
|
71
226
|
const statusOptions = useMemo(() => {
|
|
72
227
|
const opts = new Set<string>()
|
|
73
228
|
typeRecords.forEach((t) => {
|
|
@@ -77,22 +232,36 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
77
232
|
return ['all', ...Array.from(opts)]
|
|
78
233
|
}, [typeRecords])
|
|
79
234
|
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
80
238
|
const statusLabel = (s: string) => s === 'all' ? 'All' : (s?.charAt(0).toUpperCase() + s?.slice(1))
|
|
81
239
|
|
|
82
240
|
useEffect(() => {
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
|
|
83
244
|
let cancelled = false
|
|
245
|
+
|
|
84
246
|
setLoading(true)
|
|
85
247
|
apiFetch('/api/types?action=list')
|
|
86
248
|
.then((r) => r.json())
|
|
87
249
|
.then((j) => {
|
|
88
250
|
if (cancelled) return
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
89
254
|
const found = (j.data || []).filter((t: any) => typeSlugsSet.has(t.slug))
|
|
255
|
+
|
|
90
256
|
setTypeRecords(found)
|
|
91
257
|
})
|
|
92
258
|
.catch(() => setTypeRecords([]))
|
|
93
259
|
return () => { cancelled = true }
|
|
94
260
|
}, [typeSlugsSet])
|
|
95
261
|
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
|
|
96
265
|
const loadTree = useCallback(async () => {
|
|
97
266
|
if (typeRecords.length === 0) return
|
|
98
267
|
setLoading(true)
|
|
@@ -107,6 +276,17 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
107
276
|
const record = records[0]
|
|
108
277
|
return record?.data?.trees || {}
|
|
109
278
|
}
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
110
290
|
const [globalTrees, accountTrees] = await Promise.all([
|
|
111
291
|
loadCache('KB Article List - Global'),
|
|
112
292
|
loadCache('KB Article List - Account'),
|
|
@@ -125,11 +305,17 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
125
305
|
}
|
|
126
306
|
}, [typeRecords, typeSlugs, typeById])
|
|
127
307
|
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
|
|
128
312
|
const handleSearch = useCallback(async (query: string) => {
|
|
129
313
|
if (typeRecords.length === 0 || query.trim().length < 2) {
|
|
130
314
|
setSearchResultIds(null)
|
|
131
315
|
return
|
|
132
316
|
}
|
|
317
|
+
|
|
318
|
+
|
|
133
319
|
setSearching(true)
|
|
134
320
|
setError(null)
|
|
135
321
|
try {
|
|
@@ -158,12 +344,17 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
158
344
|
}
|
|
159
345
|
}, [typeRecords, typeSlugs])
|
|
160
346
|
|
|
347
|
+
|
|
161
348
|
useEffect(() => {
|
|
162
349
|
loadTree()
|
|
163
350
|
}, [loadTree])
|
|
164
351
|
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
|
|
165
355
|
const hasActiveSearch = searchResultIds !== null
|
|
166
356
|
|
|
357
|
+
|
|
167
358
|
const { visibleArticles, roots, byId } = useMemo(() => {
|
|
168
359
|
let out = articles
|
|
169
360
|
if (statusFilter !== 'all') out = out.filter((a) => a.status === statusFilter)
|
|
@@ -182,6 +373,10 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
182
373
|
ancestorSet.add(parentId)
|
|
183
374
|
current = fullById.get(parentId)
|
|
184
375
|
}
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
|
|
185
380
|
}
|
|
186
381
|
out = out.filter((a) => ancestorSet.has(a.id))
|
|
187
382
|
}
|
|
@@ -209,11 +404,17 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
209
404
|
return { visibleArticles: out, roots: roots.sort(sortByOrder), byId }
|
|
210
405
|
}, [articles, statusFilter, typeFilter, searchResultIds])
|
|
211
406
|
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
|
|
212
410
|
const isTreeMode = useMemo(
|
|
213
411
|
() => statusFilter === 'all' && typeFilter === 'all',
|
|
214
412
|
[statusFilter, typeFilter]
|
|
215
413
|
)
|
|
216
414
|
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
|
|
217
418
|
const handleDrop = async (itemId: string, targetParentId: string | undefined, insertIndex: number) => {
|
|
218
419
|
const item = articles.find((a) => a.id === itemId)
|
|
219
420
|
if (!item) return
|
|
@@ -231,6 +432,8 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
231
432
|
if (originalIndex !== -1 && insertIndex > originalIndex) {
|
|
232
433
|
effectiveIndex = insertIndex - 1
|
|
233
434
|
}
|
|
435
|
+
|
|
436
|
+
|
|
234
437
|
}
|
|
235
438
|
|
|
236
439
|
const targetChildren = articles
|
|
@@ -239,7 +442,7 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
239
442
|
const newGroup = [...targetChildren]
|
|
240
443
|
newGroup.splice(effectiveIndex, 0, item)
|
|
241
444
|
|
|
242
|
-
const updates: { id: string; type_slug
|
|
445
|
+
const updates: { id: string; type_slug?: string; data: any }[] = []
|
|
243
446
|
|
|
244
447
|
newGroup.forEach((a, order) => {
|
|
245
448
|
const nextData = { ...a.data, order }
|
|
@@ -250,7 +453,7 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
250
453
|
if (a.data?.order !== order || parentChanged) {
|
|
251
454
|
updates.push({
|
|
252
455
|
id: a.id,
|
|
253
|
-
type_slug: a.type_slug || typeById[a.type_id]?.slug ||
|
|
456
|
+
type_slug: a.type_slug || typeById[a.type_id]?.slug || undefined,
|
|
254
457
|
data: nextData,
|
|
255
458
|
})
|
|
256
459
|
}
|
|
@@ -264,7 +467,7 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
264
467
|
if (a.data?.order !== order) {
|
|
265
468
|
updates.push({
|
|
266
469
|
id: a.id,
|
|
267
|
-
type_slug: a.type_slug || typeById[a.type_id]?.slug ||
|
|
470
|
+
type_slug: a.type_slug || typeById[a.type_id]?.slug || undefined,
|
|
268
471
|
data: { ...a.data, order },
|
|
269
472
|
})
|
|
270
473
|
}
|
|
@@ -289,10 +492,15 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
289
492
|
}
|
|
290
493
|
}
|
|
291
494
|
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
|
|
292
498
|
const DropIndicator = () => (
|
|
293
499
|
<div className="h-0.5 bg-primary rounded-full my-1" />
|
|
294
500
|
)
|
|
295
501
|
|
|
502
|
+
|
|
503
|
+
|
|
296
504
|
function getDropIndex(e: React.DragEvent, container: HTMLElement | null): number {
|
|
297
505
|
if (!container) return 0
|
|
298
506
|
const itemEls = Array.from(container.children).filter((c) => c.getAttribute('data-item') === 'true')
|
|
@@ -304,9 +512,13 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
304
512
|
const centerY = rect.top + rect.height / 2 - containerRect.top
|
|
305
513
|
if (mouseY < centerY) return i
|
|
306
514
|
}
|
|
515
|
+
|
|
307
516
|
return itemEls.length
|
|
308
517
|
}
|
|
309
518
|
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
|
|
310
522
|
function SortableDropZone({
|
|
311
523
|
parentId,
|
|
312
524
|
nodes,
|
|
@@ -340,6 +552,7 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
340
552
|
if (!e.relatedTarget || !listRef.current?.contains(e.relatedTarget as Node)) {
|
|
341
553
|
setOver(true)
|
|
342
554
|
}
|
|
555
|
+
|
|
343
556
|
}}
|
|
344
557
|
onDragLeave={(e) => {
|
|
345
558
|
e.preventDefault()
|
|
@@ -359,8 +572,16 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
359
572
|
e.preventDefault()
|
|
360
573
|
e.stopPropagation()
|
|
361
574
|
setOver(false)
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
|
|
362
578
|
const id = e.dataTransfer.getData('text/plain')
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
|
|
363
583
|
const index = computeIndex(e)
|
|
584
|
+
|
|
364
585
|
setInsertIndex(null)
|
|
365
586
|
if (id) handleDrop(id, parentId, index)
|
|
366
587
|
}}
|
|
@@ -389,7 +610,11 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
389
610
|
onDrop={(e) => {
|
|
390
611
|
e.preventDefault()
|
|
391
612
|
e.stopPropagation()
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
|
|
392
616
|
const id = e.dataTransfer.getData('text/plain')
|
|
617
|
+
|
|
393
618
|
if (id) handleDrop(id, node.id, node.children.length)
|
|
394
619
|
}}
|
|
395
620
|
className={cn(
|
|
@@ -427,6 +652,14 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
427
652
|
)
|
|
428
653
|
}
|
|
429
654
|
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
|
|
430
663
|
const renderFlatRow = (record: KBRecord) => (
|
|
431
664
|
<div
|
|
432
665
|
key={record.id}
|
|
@@ -555,3 +788,11 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
|
|
|
555
788
|
</div>
|
|
556
789
|
)
|
|
557
790
|
}
|
|
791
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Renders a searchable, filterable, drag-and-drop knowledge base article list.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
|
|
792
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
793
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
794
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
795
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
796
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
797
|
+
// CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:KBArticleList:component"]
|
|
798
|
+
|
|
@@ -1,23 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
// CIL[
|
|
5
|
-
// CIL[DOC-
|
|
6
|
-
// CIL[DOC-
|
|
7
|
-
// CIL[DOC-
|
|
8
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="React, Link, Sidebar components, Separator, Breadcrumb components" errors="none" side_effects="none"]
|
|
9
|
-
// CIL[DOC-MICRO logic_summary="Imports React, router Link, shadcn sidebar, separator and breadcrumb components" notable_decisions="[]"]
|
|
10
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/src/components/layout/AppShell.tsx:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/src/components/layout/AppShell.tsx"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="AppShell layout component module entry point"]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide shared application shell imports and component"]
|
|
4
|
+
// CIL[DOC-CONTEXT module="AppShell" layer="component" related_files=".framework/src/components/ui/breadcrumb.tsx,.framework/src/components/ui/separator.tsx,.framework/src/components/ui/sidebar.tsx"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Module header with React and UI imports for the AppShell layout component" notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
11
8
|
// CIL[DOC-STABILITY stability="stable"]
|
|
12
|
-
// CIL[DOC-AUDIENCE audience="
|
|
13
|
-
|
|
14
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
15
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
16
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
17
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
18
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="system-ui"]
|
|
10
|
+
|
|
19
11
|
import * as React from "react"
|
|
20
12
|
import { Link } from 'react-router-dom'
|
|
13
|
+
import { cn } from "../../lib/utils"
|
|
21
14
|
import { SidebarProvider, SidebarInset, SidebarTrigger } from "../ui/sidebar"
|
|
22
15
|
import { Separator } from "../ui/separator"
|
|
23
16
|
import {
|
|
@@ -28,49 +21,56 @@ import {
|
|
|
28
21
|
BreadcrumbPage,
|
|
29
22
|
BreadcrumbSeparator,
|
|
30
23
|
} from "../ui/breadcrumb"
|
|
31
|
-
|
|
32
|
-
// CIL[
|
|
33
|
-
// CIL[DOC-
|
|
34
|
-
// CIL[DOC-
|
|
35
|
-
// CIL[DOC-
|
|
36
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="AppShellProps interface" errors="none" side_effects="none"]
|
|
37
|
-
// CIL[DOC-MICRO logic_summary="Interface with sidebar, children, breadcrumbs, and optional header actions" notable_decisions="[]"]
|
|
38
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
39
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
40
|
-
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/functions/_shared/schema-utils.ts, .framework/src/components/ui/dialog.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
|
|
41
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
42
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
43
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
24
|
+
|
|
25
|
+
// CIL[DOC-VECTOR type="context" content="purpose='AppShell layout component module entry point'; No verified external callers; imports: .framework/src/components/ui/sidebar.tsx,.framework/src/components/ui/separator.tsx,.framework/src/components/ui/breadcrumb.tsx"]
|
|
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"]
|
|
44
29
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
45
30
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
31
|
+
// CIL[END stable_id="~/.framework/src/components/layout/AppShell.tsx:module_header:module_header"]
|
|
32
|
+
|
|
33
|
+
// CIL[BEGIN stable_id="~/.framework/src/components/layout/AppShell.tsx:appshellprops:interface" type="interface" identity="AppShellProps" parent="~/.framework/src/components/layout/AppShell.tsx:module_header:module_header"]
|
|
34
|
+
// CIL[DOC-MACRO purpose="Props interface for the AppShell layout component"]
|
|
35
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declare the inputs accepted by AppShell"]
|
|
36
|
+
// CIL[DOC-CONTEXT module="AppShell" layer="component" related_files=".framework/src/components/layout/AppShell.tsx,.framework/src/components/ui/breadcrumb.tsx,.framework/src/components/ui/separator.tsx,.framework/src/components/ui/sidebar.tsx"]
|
|
37
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="AppShellProps interface type" errors="none" side_effects="none"]
|
|
38
|
+
// CIL[DOC-MICRO logic_summary="Defines AppShell props including sidebar, children, breadcrumbs, headerActions, banner and mainClassName" notable_decisions="mainClassName overrides the default main padding (p-4 md:p-6 lg:p-8) — apps whose pages self-pad pass a zero/tighter value to close the gap above the page header"]
|
|
39
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
40
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
41
|
+
|
|
46
42
|
interface AppShellProps {
|
|
47
43
|
sidebar: React.ReactNode
|
|
48
44
|
children: React.ReactNode
|
|
49
45
|
breadcrumbs?: { title: string; url?: string }[]
|
|
50
46
|
headerActions?: React.ReactNode
|
|
51
47
|
banner?: React.ReactNode
|
|
48
|
+
mainClassName?: string
|
|
52
49
|
}
|
|
53
|
-
// CIL[
|
|
54
|
-
// CIL[
|
|
55
|
-
// CIL[DOC-
|
|
56
|
-
// CIL[DOC-
|
|
57
|
-
// CIL[DOC-CONTEXT module="src/components/layout/AppShell" layer="frontend-component" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
58
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="JSX app shell layout" errors="none" side_effects="Manages sidebar state and provides navigation structure"]
|
|
59
|
-
// CIL[DOC-MICRO logic_summary="SidebarProvider with collapsible sidebar, header with breadcrumbs, and main content area" notable_decisions="[]"]
|
|
60
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
61
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
62
|
-
// CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
63
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
64
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
65
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
50
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Props interface for the AppShell layout component'; No verified external callers; imports: .framework/src/components/ui/sidebar.tsx,.framework/src/components/ui/separator.tsx,.framework/src/components/ui/breadcrumb.tsx"]
|
|
51
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
52
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
53
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
66
54
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
67
55
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
56
|
+
// CIL[END stable_id="~/.framework/src/components/layout/AppShell.tsx:appshellprops:interface"]
|
|
57
|
+
|
|
58
|
+
// CIL[BEGIN stable_id="~/.framework/src/components/layout/AppShell.tsx:appshell:function" type="function" identity="AppShell" parent="~/.framework/src/components/layout/AppShell.tsx:module_header:module_header"]
|
|
59
|
+
// CIL[DOC-MACRO purpose="Render the main application shell with sidebar, header and content area"]
|
|
60
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Compose sidebar, breadcrumbs, header actions, banner and children into the app layout"]
|
|
61
|
+
// CIL[DOC-CONTEXT module="AppShell" layer="component" related_files=".framework/src/components/layout/AppShell.tsx,.framework/src/components/ui/breadcrumb.tsx,.framework/src/components/ui/separator.tsx,.framework/src/components/ui/sidebar.tsx"]
|
|
62
|
+
// CIL[DOC-CONTRACT inputs="sidebar: React.ReactNode, children: React.ReactNode, breadcrumbs: { title: string; url?: string }[] | undefined, headerActions: React.ReactNode | undefined, banner: React.ReactNode | undefined, mainClassName: string | undefined" outputs="React tree" errors="none" side_effects="none"]
|
|
63
|
+
// CIL[DOC-MICRO logic_summary="Wraps children in a sidebar-aware layout with optional breadcrumbs and header actions" notable_decisions="mainClassName replaces the default main padding (p-4 md:p-6 lg:p-8) entirely via cn() — pass an empty/tight value when pages self-pad to close the gap above the page header"]
|
|
64
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
65
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
66
|
+
|
|
68
67
|
export function AppShell({
|
|
69
68
|
sidebar,
|
|
70
69
|
children,
|
|
71
70
|
breadcrumbs,
|
|
72
71
|
headerActions,
|
|
73
72
|
banner,
|
|
73
|
+
mainClassName,
|
|
74
74
|
}: AppShellProps) {
|
|
75
75
|
return (
|
|
76
76
|
<SidebarProvider>
|
|
@@ -119,11 +119,17 @@ export function AppShell({
|
|
|
119
119
|
)}
|
|
120
120
|
</header>
|
|
121
121
|
|
|
122
|
-
<main className="flex-1 flex flex-col min-h-0 overflow-auto p-4 md:p-6 lg:p-8">
|
|
122
|
+
<main className={cn("flex-1 flex flex-col min-h-0 overflow-auto", mainClassName ?? "p-4 md:p-6 lg:p-8")}>
|
|
123
123
|
{children}
|
|
124
124
|
</main>
|
|
125
125
|
</SidebarInset>
|
|
126
126
|
</SidebarProvider>
|
|
127
127
|
)
|
|
128
128
|
}
|
|
129
|
-
// CIL[
|
|
129
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Render the main application shell with sidebar, header and content area'; No verified external callers; imports: .framework/src/components/ui/sidebar.tsx,.framework/src/components/ui/separator.tsx,.framework/src/components/ui/breadcrumb.tsx"]
|
|
130
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
131
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
132
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
133
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
134
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
135
|
+
// CIL[END stable_id="~/.framework/src/components/layout/AppShell.tsx:appshell:function"]
|