spine-framework 0.3.124 → 0.3.126
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/.framework/cli/commands/agents.ts +35 -37
- package/.framework/cli/commands/auth.ts +35 -34
- package/.framework/cli/commands/create-app.ts +104 -40
- package/.framework/cli/commands/dev.ts +104 -69
- package/.framework/cli/commands/doctor.ts +179 -69
- package/.framework/cli/commands/generate.ts +83 -143
- package/.framework/cli/commands/init.ts +72 -34
- package/.framework/cli/commands/install-app.ts +260 -125
- package/.framework/cli/commands/items.ts +33 -44
- package/.framework/cli/commands/migrate.ts +122 -40
- package/.framework/cli/commands/migrations.ts +33 -40
- package/.framework/cli/commands/pipelines.ts +31 -39
- package/.framework/cli/commands/status.ts +47 -23
- package/.framework/cli/commands/system.ts +47 -37
- package/.framework/cli/commands/test.ts +112 -68
- package/.framework/cli/commands/validate-app.ts +215 -121
- package/.framework/cli/context.ts +112 -130
- package/.framework/cli/env-loader.ts +47 -18
- package/.framework/cli/index.ts +81 -42
- package/.framework/docs/runtime-types.md +1024 -0
- package/.framework/functions/_shared/agent-runner.ts +1296 -961
- package/.framework/functions/_shared/app-manifest.ts +82 -68
- package/.framework/functions/_shared/audit.ts +135 -83
- package/.framework/functions/_shared/{cil-state.ts → cil.ts} +158 -56
- package/.framework/functions/_shared/db.ts +80 -126
- package/.framework/functions/_shared/hash-api-key.ts +63 -0
- package/.framework/functions/_shared/index.ts +224 -335
- package/.framework/functions/_shared/kb.ts +319 -0
- package/.framework/functions/_shared/llm.ts +92 -0
- package/.framework/functions/_shared/logging.ts +288 -0
- package/.framework/functions/_shared/middleware.ts +329 -365
- package/.framework/functions/_shared/outcomes.ts +36 -0
- package/.framework/functions/_shared/permissions.ts +359 -643
- package/.framework/functions/_shared/pipeline-runner.ts +243 -316
- package/.framework/functions/_shared/principal.ts +376 -468
- package/.framework/functions/_shared/resolve-credentials.ts +102 -0
- package/.framework/functions/_shared/resolve-ids.ts +188 -16
- package/.framework/functions/_shared/retry-deliveries.ts +104 -0
- package/.framework/functions/_shared/schema-utils.ts +611 -373
- package/.framework/functions/_shared/testing.ts +207 -137
- package/.framework/functions/_shared/tracing.ts +276 -0
- package/.framework/functions/_shared/trigger-engine.ts +159 -211
- package/.framework/functions/_shared/webhook-registration.ts +95 -81
- package/.framework/functions/_shared/webhook-registry.ts +153 -75
- package/.framework/functions/account-nodes.ts +31 -53
- package/.framework/functions/adapters/generic-webhook-inbound.ts +56 -0
- package/.framework/functions/adapters/generic-webhook-outbound.ts +43 -0
- package/.framework/functions/adapters/openai-outbound.ts +40 -0
- package/.framework/functions/admin-data.ts +685 -537
- package/.framework/functions/admin-funnel.ts +31 -20
- package/.framework/functions/admin-install-funnel.ts +47 -28
- package/.framework/functions/admin-signals.ts +47 -29
- package/.framework/functions/ai-agents.ts +122 -147
- package/.framework/functions/ai-interactions.ts +180 -90
- package/.framework/functions/api-keys.ts +250 -192
- package/.framework/functions/apps.ts +203 -197
- package/.framework/functions/auth.ts +98 -91
- package/.framework/functions/cil-agent-ingest.ts +773 -0
- package/.framework/functions/cil-agent.ts +592 -0
- package/.framework/functions/cil-callmap.ts +1227 -0
- package/.framework/functions/cil-config.ts +583 -0
- package/.framework/functions/cil-context.ts +445 -0
- package/.framework/functions/cil-doc.ts +1752 -0
- package/.framework/functions/cil-embeddings.ts +1202 -0
- package/.framework/functions/cil-graph.ts +585 -0
- package/.framework/functions/cil-ingest.ts +2416 -0
- package/.framework/functions/cil-pipeline.ts +318 -0
- package/.framework/functions/cil-project.ts +499 -0
- package/.framework/functions/cil-validate.ts +469 -0
- package/.framework/functions/debug-auth.ts +73 -53
- package/.framework/functions/deliveries.ts +117 -0
- package/.framework/functions/embeddings.ts +528 -516
- package/.framework/functions/eval-harness.ts +158 -106
- package/.framework/functions/integration-outbound.ts +311 -0
- package/.framework/functions/integration-routes.ts +240 -466
- package/.framework/functions/integrations.ts +132 -140
- package/.framework/functions/invites.ts +401 -201
- package/.framework/functions/item-progress.ts +113 -53
- package/.framework/functions/kb.ts +28 -0
- package/.framework/functions/logs.ts +239 -222
- package/.framework/functions/observability.ts +308 -259
- package/.framework/functions/pipeline-executions.ts +179 -235
- package/.framework/functions/pipelines.ts +163 -205
- package/.framework/functions/prompt-configs.ts +109 -156
- package/.framework/functions/roles.ts +97 -147
- package/.framework/functions/system-cron.ts +132 -218
- package/.framework/functions/system.ts +112 -52
- package/.framework/functions/tests.ts +32 -28
- package/.framework/functions/timers.ts +162 -210
- package/.framework/functions/triggers.ts +282 -346
- package/.framework/functions/types.ts +283 -400
- package/.framework/migrations/001_core_schema.sql +630 -0
- package/.framework/migrations/002_core_rls_and_functions.sql +532 -0
- package/.framework/migrations/{003_system_data.sql → 003_core_system_data.sql} +26 -153
- package/.framework/migrations/004_core_rpc_and_broker.sql +421 -0
- package/.framework/migrations/005_core_observability.sql +598 -0
- package/.framework/migrations/006_security_hardening_rls.sql +97 -0
- package/.framework/migrations/007_kb_article_list.sql +237 -0
- package/.framework/migrations/008_items_target.sql +8 -0
- package/.framework/migrations/009_roles_slug_unique.sql +11 -0
- package/.framework/public/spine.config.json +91 -0
- package/.framework/scripts/app-install-cli.ts +112 -98
- package/.framework/src/App.tsx +67 -20
- package/.framework/src/apps/admin/index.tsx +97 -27
- package/.framework/src/components/AppWrapper.tsx +50 -11
- package/.framework/src/components/CustomAppLoader.tsx +131 -22
- package/.framework/src/components/admin/AdminListPage.tsx +75 -8
- package/.framework/src/components/admin/AdminSidebar.tsx +148 -36
- package/.framework/src/components/admin/AdminStatsCard.tsx +48 -29
- package/.framework/src/components/admin/PageInstructions.tsx +49 -0
- package/.framework/src/components/admin/SortableTableHeader.tsx +49 -2
- package/.framework/src/components/app-shell/GenericAppShell.tsx +69 -11
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +55 -10
- package/.framework/src/components/app-shell/GenericListPage.tsx +76 -9
- package/.framework/src/components/app-sidebar.tsx +50 -3
- package/.framework/src/components/auth/ProtectedRoute.tsx +53 -45
- package/.framework/src/components/kb/KBArticleEditor.tsx +409 -0
- package/.framework/src/components/kb/KBArticleList.tsx +557 -0
- package/.framework/src/components/layout/AppShell.tsx +54 -16
- package/.framework/src/components/layout/Header.tsx +50 -38
- package/.framework/src/components/layout/Layout.tsx +48 -32
- package/.framework/src/components/layout/Sidebar.tsx +167 -16
- package/.framework/src/components/runtime/DataDetailHeader.tsx +33 -1
- package/.framework/src/components/runtime/DataDetailPage.tsx +289 -4
- package/.framework/src/components/runtime/DataFilters.tsx +78 -1
- package/.framework/src/components/runtime/DataHeader.tsx +32 -29
- package/.framework/src/components/runtime/DataListPage.tsx +161 -2
- package/.framework/src/components/runtime/DataStats.tsx +48 -1
- package/.framework/src/components/runtime/DataTable.tsx +153 -1
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +77 -46
- package/.framework/src/components/runtime/index.ts +16 -9
- package/.framework/src/components/search-form.tsx +33 -1
- package/.framework/src/components/shared/AgentView.tsx +48 -51
- package/.framework/src/components/shared/FieldRenderer.tsx +84 -67
- package/.framework/src/components/shared/InviteManager.tsx +113 -52
- package/.framework/src/components/shared/MemberList.tsx +182 -0
- package/.framework/src/components/shared/SchemaFields.tsx +96 -78
- package/.framework/src/components/ui/DataTable.tsx +86 -56
- package/.framework/src/components/ui/Form.tsx +188 -109
- package/.framework/src/components/ui/ItemCard.tsx +86 -58
- package/.framework/src/components/ui/ItemListView.tsx +88 -61
- package/.framework/src/components/ui/LoadingSpinner.tsx +52 -27
- package/.framework/src/components/ui/Modal.tsx +81 -4
- package/.framework/src/components/ui/RichTextEditor.tsx +101 -9
- package/.framework/src/components/ui/accordion.tsx +97 -5
- package/.framework/src/components/ui/alert-dialog.tsx +225 -13
- package/.framework/src/components/ui/alert.tsx +113 -6
- package/.framework/src/components/ui/aspect-ratio.tsx +49 -2
- package/.framework/src/components/ui/avatar.tsx +129 -7
- package/.framework/src/components/ui/badge.tsx +65 -3
- package/.framework/src/components/ui/breadcrumb.tsx +145 -8
- package/.framework/src/components/ui/button-group.tsx +81 -4
- package/.framework/src/components/ui/button.tsx +49 -2
- package/.framework/src/components/ui/calendar.tsx +65 -3
- package/.framework/src/components/ui/card.tsx +145 -8
- package/.framework/src/components/ui/carousel.tsx +129 -7
- package/.framework/src/components/ui/chart.tsx +161 -10
- package/.framework/src/components/ui/checkbox.tsx +49 -2
- package/.framework/src/components/ui/collapsible.tsx +81 -5
- package/.framework/src/components/ui/combobox.tsx +305 -20
- package/.framework/src/components/ui/command.tsx +177 -11
- package/.framework/src/components/ui/context-menu.tsx +273 -17
- package/.framework/src/components/ui/dialog.tsx +209 -27
- package/.framework/src/components/ui/direction.tsx +64 -4
- package/.framework/src/components/ui/drawer.tsx +193 -12
- package/.framework/src/components/ui/dropdown-menu.tsx +273 -18
- package/.framework/src/components/ui/empty.tsx +145 -9
- package/.framework/src/components/ui/field.tsx +209 -14
- package/.framework/src/components/ui/hover-card.tsx +81 -4
- package/.framework/src/components/ui/input-group.tsx +162 -10
- package/.framework/src/components/ui/input-otp.tsx +98 -5
- package/.framework/src/components/ui/input.tsx +49 -2
- package/.framework/src/components/ui/item.tsx +225 -13
- package/.framework/src/components/ui/kbd.tsx +65 -3
- package/.framework/src/components/ui/label.tsx +49 -2
- package/.framework/src/components/ui/menubar.tsx +289 -17
- package/.framework/src/components/ui/native-select.tsx +97 -5
- package/.framework/src/components/ui/navigation-menu.tsx +177 -10
- package/.framework/src/components/ui/pagination.tsx +161 -9
- package/.framework/src/components/ui/popover.tsx +145 -8
- package/.framework/src/components/ui/progress.tsx +49 -2
- package/.framework/src/components/ui/radio-group.tsx +65 -3
- package/.framework/src/components/ui/resizable.tsx +82 -4
- package/.framework/src/components/ui/scroll-area.tsx +65 -3
- package/.framework/src/components/ui/select.tsx +193 -11
- package/.framework/src/components/ui/separator.tsx +49 -2
- package/.framework/src/components/ui/sheet.tsx +193 -11
- package/.framework/src/components/ui/sidebar.tsx +481 -38
- package/.framework/src/components/ui/skeleton.tsx +49 -2
- package/.framework/src/components/ui/slider.tsx +49 -2
- package/.framework/src/components/ui/sonner.tsx +49 -2
- package/.framework/src/components/ui/spinner.tsx +49 -2
- package/.framework/src/components/ui/switch.tsx +49 -2
- package/.framework/src/components/ui/table-primitives.tsx +160 -33
- package/.framework/src/components/ui/table.tsx +161 -9
- package/.framework/src/components/ui/tabs.tsx +113 -6
- package/.framework/src/components/ui/textarea.tsx +49 -2
- package/.framework/src/components/ui/toggle-group.tsx +81 -4
- package/.framework/src/components/ui/toggle.tsx +65 -3
- package/.framework/src/components/ui/tooltip.tsx +97 -5
- package/.framework/src/contexts/AppContext.tsx +129 -45
- package/.framework/src/contexts/AuthContext.tsx +187 -144
- package/.framework/src/hooks/use-mobile.ts +48 -2
- package/.framework/src/hooks/useApi.ts +208 -159
- package/.framework/src/hooks/useAppPath.ts +32 -23
- package/.framework/src/hooks/useApps.ts +51 -20
- package/.framework/src/hooks/useEntityList.ts +32 -78
- package/.framework/src/hooks/useEntityRecord.ts +35 -96
- package/.framework/src/hooks/useForm.ts +32 -92
- package/.framework/src/hooks/useListSchema.ts +49 -78
- package/.framework/src/hooks/useSchemaRecord.ts +114 -105
- package/.framework/src/lib/api.ts +195 -116
- package/.framework/src/lib/supabase.ts +98 -64
- package/.framework/src/lib/utils.ts +287 -151
- package/.framework/src/main.tsx +49 -3
- package/.framework/src/pages/DashboardPage.tsx +52 -29
- package/.framework/src/pages/NotFoundPage.tsx +32 -10
- package/.framework/src/pages/SetupPage.tsx +32 -12
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +119 -10
- package/.framework/src/pages/admin/AIAgentsPage.tsx +48 -19
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +187 -17
- package/.framework/src/pages/admin/APIKeysPage.tsx +98 -22
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +113 -26
- package/.framework/src/pages/admin/AppDetailPage.tsx +125 -8
- package/.framework/src/pages/admin/AppsPage.tsx +49 -2
- package/.framework/src/pages/admin/DeliveriesPage.tsx +196 -0
- package/.framework/src/pages/admin/DesignedPage.tsx +32 -18
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +215 -484
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +116 -319
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -16
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +183 -26
- package/.framework/src/pages/admin/IntegrationsPage.tsx +48 -19
- package/.framework/src/pages/admin/InvitesPage.tsx +48 -14
- package/.framework/src/pages/admin/LogsPage.tsx +422 -75
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +113 -24
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +206 -34
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +50 -17
- package/.framework/src/pages/admin/PipelinesPage.tsx +160 -21
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +378 -88
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +125 -16
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +49 -10
- package/.framework/src/pages/admin/RoleDetailPage.tsx +130 -10
- package/.framework/src/pages/admin/RolesPage.tsx +171 -18
- package/.framework/src/pages/admin/SelectTestPage.tsx +34 -9
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +49 -11
- package/.framework/src/pages/admin/SimpleDashboard.tsx +49 -10
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +49 -4
- package/.framework/src/pages/admin/TestingDashboard.tsx +98 -28
- package/.framework/src/pages/admin/TimerDetailPage.tsx +143 -33
- package/.framework/src/pages/admin/TimersPage.tsx +48 -20
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +118 -30
- package/.framework/src/pages/admin/TriggersPage.tsx +64 -19
- package/.framework/src/pages/admin/TypeDetailPage.tsx +138 -15
- package/.framework/src/pages/admin/TypesPage.tsx +48 -20
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +465 -0
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +787 -0
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +699 -0
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +647 -0
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +616 -0
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +1402 -0
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +614 -0
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +571 -0
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +731 -0
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +52 -51
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +31 -22
- package/.framework/src/pages/auth/LoginPage.tsx +50 -23
- package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -15
- package/.framework/src/pages/auth/RegisterPage.tsx +281 -317
- package/.framework/src/pages/spine-framework/APIPage.tsx +33 -0
- package/.framework/src/pages/spine-framework/CLIPage.tsx +33 -0
- package/.framework/src/types/auth.ts +128 -71
- package/.framework/src/types/types.ts +373 -157
- package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +39 -0
- package/custom/.devin/skills/spine-workbench-idea/SKILL.md +36 -0
- package/custom/.devin/skills/spine-workbench-implement/SKILL.md +46 -0
- package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +28 -0
- package/custom/.devin/skills/spine-workbench-plan/SKILL.md +38 -0
- package/docs/README.md +9 -130
- package/netlify.toml +5 -2
- package/package.json +13 -25
- package/scripts/kb-ingest-docs.ts +203 -0
- package/spine.config.json +65 -4
- package/.framework/migrations/001_schema.sql +0 -425
- package/.framework/migrations/002_rls_and_functions.sql +0 -763
- package/.framework/migrations/004_enhancements.sql +0 -43
- package/.framework/migrations/005_auth_user_trigger.sql +0 -105
- package/.framework/migrations/006_fix_current_actor_id.sql +0 -21
- package/.framework/migrations/016_invites.sql +0 -27
- package/.framework/migrations/017_fix_get_account_apps.sql +0 -78
- package/.framework/migrations/018_apps_required_roles.sql +0 -17
- package/.framework/migrations/019_triggers_unique_constraint.sql +0 -13
- package/.framework/migrations/020_get_account_apps_role_filter.sql +0 -117
- package/.framework/migrations/021_app_domains.sql +0 -112
- package/.framework/migrations/022_route_prefix_domain_unique.sql +0 -21
- package/.framework/migrations/023_match_embeddings_rpc.sql +0 -78
- package/.framework/migrations/024_messages_account_id.sql +0 -9
- package/.framework/migrations/025_retype_threads_messages.sql +0 -240
- package/.framework/migrations/026_fix_rls_policies.sql +0 -47
- package/.framework/migrations/027_embedding_lifecycle.sql +0 -176
- package/.framework/migrations/028_fix_message_data_permissions.sql +0 -49
- package/.framework/migrations/029_tighten_support_triage_prompt.sql +0 -41
- package/.framework/migrations/030_messages_updated_by.sql +0 -6
- package/.framework/migrations/031_seed_upsert_constraints.sql +0 -35
- package/docs/APPS.md +0 -232
- package/docs/ARCHITECTURE.md +0 -246
- package/docs/INSTALL.md +0 -155
- package/docs/design-schema-spec.md +0 -1837
- package/docs/dev-guides/01-create-an-app.md +0 -183
- package/docs/dev-guides/02-create-a-function.md +0 -178
- package/docs/dev-guides/03-create-a-component.md +0 -178
- package/docs/dev-guides/04-webhook-handlers.md +0 -129
- package/docs/dev-guides/05-testing.md +0 -168
- package/docs/dev-guides/README.md +0 -40
- package/docs/npm-packages-plan.md +0 -288
- package/docs/spine-core--api-reference.md +0 -822
|
@@ -0,0 +1,699 @@
|
|
|
1
|
+
// CIL[BEGIN chunk_id="cildashboardpage_module_header_1784193942" type="module_header" identity="module_header" parent="none"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Import dependencies and icons for the CIL dashboard page"]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provides module imports and icon references used by the page"]
|
|
4
|
+
// CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="module imports" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Imports React hooks, router, apiFetch, app path hook, UI components, and lucide icons" notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
8
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="developer"]
|
|
10
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/functions/_shared/principal.ts, \."]
|
|
11
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
12
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
13
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
14
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
15
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
16
|
+
import { useEffect, useState, useCallback } from 'react'
|
|
17
|
+
import { useParams } from 'react-router-dom'
|
|
18
|
+
import { apiFetch } from '@core/lib/api'
|
|
19
|
+
import { Card, CardContent, CardHeader, CardTitle } from '@core/components/ui/card'
|
|
20
|
+
import { Button } from '@core/components/ui/button'
|
|
21
|
+
import { Badge } from '@core/components/ui/badge'
|
|
22
|
+
import { Skeleton } from '@core/components/ui/skeleton'
|
|
23
|
+
import { Progress } from '@core/components/ui/progress'
|
|
24
|
+
import {
|
|
25
|
+
CheckCircle2,
|
|
26
|
+
XCircle,
|
|
27
|
+
AlertTriangle,
|
|
28
|
+
Clock,
|
|
29
|
+
ChevronRight,
|
|
30
|
+
RefreshCw,
|
|
31
|
+
FileCode2,
|
|
32
|
+
Layers,
|
|
33
|
+
Zap,
|
|
34
|
+
Sparkles,
|
|
35
|
+
GitGraph,
|
|
36
|
+
Hash,
|
|
37
|
+
DollarSign,
|
|
38
|
+
Bot,
|
|
39
|
+
Search,
|
|
40
|
+
Play,
|
|
41
|
+
Settings2,
|
|
42
|
+
} from 'lucide-react'
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
import { PageInstructions } from '../../../components/admin/PageInstructions'
|
|
47
|
+
// CIL[END chunk_id="cildashboardpage_module_header_1784193942"]
|
|
48
|
+
// CIL[BEGIN chunk_id="cildashboardpage_projectstats_1784193942" type="interface" identity="ProjectStats" parent="none"]
|
|
49
|
+
// CIL[DOC-MACRO purpose="Define the ProjectStats data shape"]
|
|
50
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for project-level ingestion statistics"]
|
|
51
|
+
// CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
52
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="ProjectStats type definition" errors="none" side_effects="none"]
|
|
53
|
+
// CIL[DOC-MICRO logic_summary="Declares file count, chunk count, proposal counts, ingestion cost, and last ingestion timestamp" notable_decisions="[]"]
|
|
54
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
55
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
56
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
|
|
57
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
58
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
59
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
60
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
61
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
62
|
+
interface ProjectStats {
|
|
63
|
+
file_count: number
|
|
64
|
+
chunk_count: number
|
|
65
|
+
proposal_count: number
|
|
66
|
+
approved_count: number
|
|
67
|
+
pending_review_count: number
|
|
68
|
+
total_ingestion_cost_usd: number
|
|
69
|
+
last_ingested_at: string | null
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// CIL[END chunk_id="cildashboardpage_projectstats_1784193942"]
|
|
73
|
+
// CIL[BEGIN chunk_id="cildashboardpage_embedstatus_1784193942" type="interface" identity="EmbedStatus" parent="none"]
|
|
74
|
+
// CIL[DOC-MACRO purpose="Define the EmbedStatus data shape"]
|
|
75
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for chunk embedding coverage"]
|
|
76
|
+
// CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
77
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="EmbedStatus type definition" errors="none" side_effects="none"]
|
|
78
|
+
// CIL[DOC-MICRO logic_summary="Declares total, embedded, unembedded counts and coverage percentage" notable_decisions="[]"]
|
|
79
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
80
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
81
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
|
|
82
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
83
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
84
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
85
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
86
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
87
|
+
interface EmbedStatus {
|
|
88
|
+
total_chunks: number
|
|
89
|
+
embedded_chunks: number
|
|
90
|
+
coverage_pct: number
|
|
91
|
+
unembedded_chunks: number
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// CIL[END chunk_id="cildashboardpage_embedstatus_1784193942"]
|
|
95
|
+
// CIL[BEGIN chunk_id="cildashboardpage_docstatus_1784193942" type="interface" identity="DocStatus" parent="none"]
|
|
96
|
+
// CIL[DOC-MACRO purpose="Define the DocStatus data shape"]
|
|
97
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for documentation coverage"]
|
|
98
|
+
// CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
99
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="DocStatus type definition" errors="none" side_effects="none"]
|
|
100
|
+
// CIL[DOC-MICRO logic_summary="Declares total, documented, undocumented, AI-generated, human-verified counts and coverage percentage" notable_decisions="[]"]
|
|
101
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
102
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
103
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
|
|
104
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
105
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
106
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
107
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
108
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
109
|
+
interface DocStatus {
|
|
110
|
+
total_chunks: number
|
|
111
|
+
documented_count: number
|
|
112
|
+
undocumented_count: number
|
|
113
|
+
ai_generated_count: number
|
|
114
|
+
human_verified_count: number
|
|
115
|
+
coverage_pct: number
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// CIL[END chunk_id="cildashboardpage_docstatus_1784193942"]
|
|
119
|
+
// CIL[BEGIN chunk_id="cildashboardpage_callmapstatus_1784193942" type="interface" identity="CallmapStatus" parent="none"]
|
|
120
|
+
// CIL[DOC-MACRO purpose="Define the CallmapStatus data shape"]
|
|
121
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for call graph link counts"]
|
|
122
|
+
// CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
123
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="CallmapStatus type definition" errors="none" side_effects="none"]
|
|
124
|
+
// CIL[DOC-MICRO logic_summary="Declares import, call, export, and tested-by link counts" notable_decisions="[]"]
|
|
125
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
126
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
127
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
|
|
128
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
129
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
130
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
131
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
132
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
133
|
+
interface CallmapStatus {
|
|
134
|
+
import_links: number
|
|
135
|
+
call_links: number
|
|
136
|
+
export_links: number
|
|
137
|
+
total_links: number
|
|
138
|
+
tested_by_links?: number
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// CIL[END chunk_id="cildashboardpage_callmapstatus_1784193942"]
|
|
142
|
+
// CIL[BEGIN chunk_id="cildashboardpage_configstatus_1784193942" type="interface" identity="ConfigStatus" parent="none"]
|
|
143
|
+
// CIL[DOC-MACRO purpose="Define the ConfigStatus data shape"]
|
|
144
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for config extraction status"]
|
|
145
|
+
// CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
|
|
146
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="ConfigStatus type definition" errors="none" side_effects="none"]
|
|
147
|
+
// CIL[DOC-MICRO logic_summary="Declares config item count and configures link count" notable_decisions="[]"]
|
|
148
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
149
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
150
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
151
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
152
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
153
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
154
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
155
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
156
|
+
interface ConfigStatus {
|
|
157
|
+
config_items: number
|
|
158
|
+
configures_links: number
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// CIL[END chunk_id="cildashboardpage_configstatus_1784193942"]
|
|
162
|
+
// CIL[BEGIN chunk_id="cildashboardpage_dashboarddata_1784193942" type="interface" identity="DashboardData" parent="none"]
|
|
163
|
+
// CIL[DOC-MACRO purpose="Aggregate dashboard data types into a single view model"]
|
|
164
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for the dashboard's combined data state"]
|
|
165
|
+
// CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
|
|
166
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="DashboardData type definition" errors="none" side_effects="none"]
|
|
167
|
+
// CIL[DOC-MICRO logic_summary="Groups project, embed, doc, callmap, and config status objects" notable_decisions="[]"]
|
|
168
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
169
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
170
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
171
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
172
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
173
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
174
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
175
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
176
|
+
interface DashboardData {
|
|
177
|
+
project: { id: string; title: string; data: ProjectStats } | null
|
|
178
|
+
embed: EmbedStatus | null
|
|
179
|
+
doc: DocStatus | null
|
|
180
|
+
callmap: CallmapStatus | null
|
|
181
|
+
config: ConfigStatus | null
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
// CIL[END chunk_id="cildashboardpage_dashboarddata_1784193942"]
|
|
187
|
+
// CIL[BEGIN chunk_id="cildashboardpage_passcard_1784193942" type="function" identity="PassCard" parent="none"]
|
|
188
|
+
// CIL[DOC-MACRO purpose="Render a pipeline pass card with status, label, description, and metric"]
|
|
189
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display a single pipeline step's completion status and metric as a clickable card"]
|
|
190
|
+
// CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
|
|
191
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="none" side_effects="none"]
|
|
192
|
+
// CIL[DOC-MICRO logic_summary="Selects a status color and icon config and renders a compact status card with an optional link" notable_decisions="[]"]
|
|
193
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
194
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
195
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
196
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
197
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
198
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
199
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
200
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
201
|
+
function PassCard({
|
|
202
|
+
number,
|
|
203
|
+
label,
|
|
204
|
+
icon: Icon,
|
|
205
|
+
description,
|
|
206
|
+
status,
|
|
207
|
+
metric,
|
|
208
|
+
href,
|
|
209
|
+
}: {
|
|
210
|
+
number: string
|
|
211
|
+
label: string
|
|
212
|
+
icon: React.ElementType
|
|
213
|
+
description: string
|
|
214
|
+
status: 'complete' | 'partial' | 'empty' | 'unknown'
|
|
215
|
+
metric: string
|
|
216
|
+
href?: string
|
|
217
|
+
}) {
|
|
218
|
+
const statusConfig = {
|
|
219
|
+
complete: { color: 'text-green-600', bg: 'bg-green-50 border-green-200', dot: 'bg-green-500', icon: CheckCircle2 },
|
|
220
|
+
partial: { color: 'text-amber-600', bg: 'bg-amber-50 border-amber-200', dot: 'bg-amber-500', icon: AlertTriangle },
|
|
221
|
+
empty: { color: 'text-slate-400', bg: 'bg-slate-50 border-slate-200', dot: 'bg-slate-300', icon: Clock },
|
|
222
|
+
unknown: { color: 'text-slate-400', bg: 'bg-slate-50 border-slate-200', dot: 'bg-slate-300', icon: Clock },
|
|
223
|
+
}[status]
|
|
224
|
+
|
|
225
|
+
const StatusIcon = statusConfig.icon
|
|
226
|
+
|
|
227
|
+
return (
|
|
228
|
+
<div className={`rounded-lg border p-3 ${statusConfig.bg} flex items-start gap-3`}>
|
|
229
|
+
<div className={`mt-0.5 h-7 w-7 rounded-md flex items-center justify-center shrink-0 ${status === 'complete' ? 'bg-green-100' : status === 'partial' ? 'bg-amber-100' : 'bg-slate-100'}`}>
|
|
230
|
+
<Icon className={`h-4 w-4 ${statusConfig.color}`} />
|
|
231
|
+
</div>
|
|
232
|
+
<div className="flex-1 min-w-0">
|
|
233
|
+
<div className="flex items-center gap-1.5">
|
|
234
|
+
<span className="text-xs font-bold text-muted-foreground">Pass {number}</span>
|
|
235
|
+
<StatusIcon className={`h-3 w-3 ${statusConfig.color}`} />
|
|
236
|
+
</div>
|
|
237
|
+
<div className="text-sm font-medium truncate">{label}</div>
|
|
238
|
+
<div className="text-xs text-muted-foreground">{description}</div>
|
|
239
|
+
<div className={`text-xs font-mono mt-1 font-semibold ${statusConfig.color}`}>{metric}</div>
|
|
240
|
+
</div>
|
|
241
|
+
{href && (
|
|
242
|
+
<a href={href} className="shrink-0 text-xs text-muted-foreground hover:text-foreground">
|
|
243
|
+
<ChevronRight className="h-4 w-4" />
|
|
244
|
+
</a>
|
|
245
|
+
)}
|
|
246
|
+
</div>
|
|
247
|
+
)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
// CIL[END chunk_id="cildashboardpage_passcard_1784193942"]
|
|
253
|
+
// CIL[BEGIN chunk_id="cildashboardpage_stattile_1784193942" type="function" identity="StatTile" parent="none"]
|
|
254
|
+
// CIL[DOC-MACRO purpose="Render a numeric statistic tile with label and optional subtext"]
|
|
255
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display a single dashboard metric inside a styled Card"]
|
|
256
|
+
// CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
|
|
257
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="none" side_effects="none"]
|
|
258
|
+
// CIL[DOC-MICRO logic_summary="Renders a Card with a large value, label, optional sub, and icon" notable_decisions="[]"]
|
|
259
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
260
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
261
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
262
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
263
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
264
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
265
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
266
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
267
|
+
function StatTile({
|
|
268
|
+
label,
|
|
269
|
+
value,
|
|
270
|
+
sub,
|
|
271
|
+
icon: Icon,
|
|
272
|
+
accent = false,
|
|
273
|
+
}: {
|
|
274
|
+
label: string
|
|
275
|
+
value: string | number
|
|
276
|
+
sub?: string
|
|
277
|
+
icon: React.ElementType
|
|
278
|
+
accent?: boolean
|
|
279
|
+
}) {
|
|
280
|
+
return (
|
|
281
|
+
<Card className={accent ? 'border-indigo-200 bg-indigo-50/50' : ''}>
|
|
282
|
+
<CardContent className="pt-4 pb-3">
|
|
283
|
+
<div className="flex items-start justify-between">
|
|
284
|
+
<div>
|
|
285
|
+
<div className={`text-2xl font-bold tabular-nums ${accent ? 'text-indigo-700' : ''}`}>{value}</div>
|
|
286
|
+
<div className="text-xs text-muted-foreground mt-0.5">{label}</div>
|
|
287
|
+
{sub && <div className="text-xs text-muted-foreground mt-0.5">{sub}</div>}
|
|
288
|
+
</div>
|
|
289
|
+
<Icon className={`h-5 w-5 mt-1 ${accent ? 'text-indigo-400' : 'text-muted-foreground/50'}`} />
|
|
290
|
+
</div>
|
|
291
|
+
</CardContent>
|
|
292
|
+
</Card>
|
|
293
|
+
)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
// CIL[END chunk_id="cildashboardpage_stattile_1784193942"]
|
|
299
|
+
// CIL[BEGIN chunk_id="cildashboardpage_coveragebar_1784193942" type="function" identity="CoverageBar" parent="none"]
|
|
300
|
+
// CIL[DOC-MACRO purpose="Render a labeled progress bar for coverage metrics"]
|
|
301
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display a percentage coverage value with a Progress bar"]
|
|
302
|
+
// CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
|
|
303
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="none" side_effects="none"]
|
|
304
|
+
// CIL[DOC-MICRO logic_summary="Renders a label, percentage, and shadcn Progress component" notable_decisions="[]"]
|
|
305
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
306
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
307
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
308
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
309
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
310
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
311
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
312
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
313
|
+
function CoverageBar({ label, pct, color = 'bg-indigo-500' }: { label: string; pct: number; color?: string }) {
|
|
314
|
+
return (
|
|
315
|
+
<div className="space-y-1">
|
|
316
|
+
<div className="flex items-center justify-between text-xs">
|
|
317
|
+
<span className="text-muted-foreground">{label}</span>
|
|
318
|
+
<span className="font-mono font-semibold">{pct}%</span>
|
|
319
|
+
</div>
|
|
320
|
+
<Progress value={pct} className="h-2" />
|
|
321
|
+
</div>
|
|
322
|
+
)
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
// CIL[END chunk_id="cildashboardpage_coveragebar_1784193942"]
|
|
328
|
+
// CIL[BEGIN chunk_id="cildashboardpage_driftalertcard_1784193942" type="function" identity="DriftAlertCard" parent="none"]
|
|
329
|
+
// CIL[DOC-MACRO purpose="Check stored chunk hashes and list drifted chunks for a project"]
|
|
330
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Fetch chunk records, validate stored hashes, and render drift alerts with links"]
|
|
331
|
+
// CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
|
|
332
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="API or validation errors are swallowed" side_effects="Calls /api/admin-data and /api/cil-validate; sets local state"]
|
|
333
|
+
// CIL[DOC-MICRO logic_summary="Lists cil_chunk items for the project, calls the validate endpoint, and displays any drifted chunks or an all-current status" notable_decisions="[]"]
|
|
334
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
335
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
336
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
337
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
338
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
339
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
340
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
341
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
342
|
+
function DriftAlertCard({ projectId, appPath }: { projectId: string; appPath: (p: string) => string }) {
|
|
343
|
+
const [driftChunks, setDriftChunks] = useState<any[] | null>(null)
|
|
344
|
+
const [checking, setChecking] = useState(false)
|
|
345
|
+
|
|
346
|
+
const checkDrift = async () => {
|
|
347
|
+
setChecking(true)
|
|
348
|
+
try {
|
|
349
|
+
|
|
350
|
+
const res = await apiFetch(`/api/admin-data?action=list&entity=items&type_slug=cil_chunk&limit=200`)
|
|
351
|
+
const data = await res.json()
|
|
352
|
+
const chunks = (data?.data || data || []).filter(
|
|
353
|
+
(c: any) => c.data?.project_id === projectId && c.data?.stored_hash
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
if (!chunks.length) { setDriftChunks([]); return }
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
const validateRes = await apiFetch('/api/cil-validate?action=validate', {
|
|
360
|
+
method: 'POST',
|
|
361
|
+
headers: { 'Content-Type': 'application/json' },
|
|
362
|
+
body: JSON.stringify({
|
|
363
|
+
chunks: chunks.slice(0, 50).map((c: any) => ({
|
|
364
|
+
chunk_id: c.id,
|
|
365
|
+
chunk_name: c.data?.chunk_name || '',
|
|
366
|
+
content: c.data?.code_content || '',
|
|
367
|
+
})),
|
|
368
|
+
}),
|
|
369
|
+
})
|
|
370
|
+
const vData = await validateRes.json()
|
|
371
|
+
const results = vData?.results || vData?.data?.results || []
|
|
372
|
+
setDriftChunks(results.filter((r: any) => r.status === 'drift_detected'))
|
|
373
|
+
} finally {
|
|
374
|
+
setChecking(false)
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return (
|
|
379
|
+
<Card>
|
|
380
|
+
<CardHeader className="pb-2">
|
|
381
|
+
<div className="flex items-center justify-between">
|
|
382
|
+
<CardTitle className="text-sm flex items-center gap-1.5">
|
|
383
|
+
<Hash className="h-4 w-4" /> Hash Drift
|
|
384
|
+
</CardTitle>
|
|
385
|
+
<Button size="sm" variant="outline" onClick={checkDrift} disabled={checking} className="h-7 text-xs">
|
|
386
|
+
{checking ? <RefreshCw className="h-3 w-3 animate-spin" /> : <Hash className="h-3 w-3" />}
|
|
387
|
+
{checking ? 'Checking…' : 'Check Now'}
|
|
388
|
+
</Button>
|
|
389
|
+
</div>
|
|
390
|
+
</CardHeader>
|
|
391
|
+
<CardContent>
|
|
392
|
+
{driftChunks === null && (
|
|
393
|
+
<p className="text-xs text-muted-foreground">Click "Check Now" to validate all stored hashes against current code_content.</p>
|
|
394
|
+
)}
|
|
395
|
+
{driftChunks?.length === 0 && (
|
|
396
|
+
<div className="flex items-center gap-1.5 text-sm text-green-600">
|
|
397
|
+
<CheckCircle2 className="h-4 w-4" /> All hashes current
|
|
398
|
+
</div>
|
|
399
|
+
)}
|
|
400
|
+
{driftChunks && driftChunks.length > 0 && (
|
|
401
|
+
<div className="space-y-1.5">
|
|
402
|
+
<div className="flex items-center gap-1.5 text-sm text-red-600 mb-2">
|
|
403
|
+
<XCircle className="h-4 w-4" /> {driftChunks.length} chunk{driftChunks.length !== 1 ? 's' : ''} with drift
|
|
404
|
+
</div>
|
|
405
|
+
{driftChunks.slice(0, 5).map((r: any) => (
|
|
406
|
+
<a
|
|
407
|
+
key={r.chunk_id}
|
|
408
|
+
href={appPath(`/cil/${projectId}/chunks/${r.chunk_id}`)}
|
|
409
|
+
className="flex items-center gap-2 text-xs hover:bg-red-50 rounded p-1 group"
|
|
410
|
+
>
|
|
411
|
+
<XCircle className="h-3 w-3 text-red-500 shrink-0" />
|
|
412
|
+
<span className="font-mono truncate">{r.chunk_name}</span>
|
|
413
|
+
<ChevronRight className="h-3 w-3 text-muted-foreground opacity-0 group-hover:opacity-100 ml-auto" />
|
|
414
|
+
</a>
|
|
415
|
+
))}
|
|
416
|
+
{driftChunks.length > 5 && (
|
|
417
|
+
<p className="text-xs text-muted-foreground">…and {driftChunks.length - 5} more</p>
|
|
418
|
+
)}
|
|
419
|
+
</div>
|
|
420
|
+
)}
|
|
421
|
+
</CardContent>
|
|
422
|
+
</Card>
|
|
423
|
+
)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
// CIL[END chunk_id="cildashboardpage_driftalertcard_1784193942"]
|
|
429
|
+
// CIL[BEGIN chunk_id="cildashboardpage_cildashboardpage_1784193942" type="component" identity="CILDashboardPage" parent="none"]
|
|
430
|
+
// CIL[DOC-MACRO purpose="Render the CIL project dashboard page"]
|
|
431
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Fetch project status and display pipeline passes, coverage, stats, graph links, drift alerts, and quick actions"]
|
|
432
|
+
// CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
|
|
433
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="Failed requests are ignored; empty states shown" side_effects="Calls /api/cil-project, /api/cil-embeddings, /api/cil-doc, /api/cil-callmap, and /api/cil-config; updates local state"]
|
|
434
|
+
// CIL[DOC-MICRO logic_summary="Loads project, embedding, documentation, callmap, and config statuses in parallel, then renders stat tiles, coverage bars, pass cards, graph links, drift alerts, and quick action buttons" notable_decisions="[]"]
|
|
435
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
436
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
437
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
438
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
439
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
440
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
441
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
442
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
443
|
+
export default function CILDashboardPage() {
|
|
444
|
+
const { id: projectId } = useParams<{ id: string }>()
|
|
445
|
+
const appPath = (path: string) => '/spine-framework/admin' + (path.startsWith('/') ? path : '/' + path)
|
|
446
|
+
const [data, setData] = useState<DashboardData>({ project: null, embed: null, doc: null, callmap: null, config: null })
|
|
447
|
+
const [loading, setLoading] = useState(true)
|
|
448
|
+
|
|
449
|
+
const load = useCallback(async () => {
|
|
450
|
+
if (!projectId) return
|
|
451
|
+
setLoading(true)
|
|
452
|
+
try {
|
|
453
|
+
const [projectRes, embedRes, docRes, callmapRes, configRes] = await Promise.allSettled([
|
|
454
|
+
apiFetch(`/api/cil-project?action=get&id=${projectId}`).then(r => r.json()),
|
|
455
|
+
apiFetch(`/api/cil-embeddings?action=status&project_id=${projectId}`).then(r => r.json()),
|
|
456
|
+
apiFetch(`/api/cil-doc?action=gap_report&project_id=${projectId}`).then(r => r.json()),
|
|
457
|
+
apiFetch(`/api/cil-callmap?action=status&project_id=${projectId}`).then(r => r.json()),
|
|
458
|
+
apiFetch(`/api/cil-config?action=status&project_id=${projectId}`).then(r => r.json()),
|
|
459
|
+
])
|
|
460
|
+
|
|
461
|
+
setData({
|
|
462
|
+
project: projectRes.status === 'fulfilled' ? (projectRes.value?.project || projectRes.value?.data?.project) : null,
|
|
463
|
+
embed: embedRes.status === 'fulfilled' ? (embedRes.value?.data || embedRes.value) : null,
|
|
464
|
+
doc: docRes.status === 'fulfilled' ? (docRes.value?.data || docRes.value) : null,
|
|
465
|
+
callmap: callmapRes.status === 'fulfilled' ? (callmapRes.value?.data || callmapRes.value) : null,
|
|
466
|
+
config: configRes.status === 'fulfilled' ? (configRes.value?.data || configRes.value) : null,
|
|
467
|
+
})
|
|
468
|
+
} finally {
|
|
469
|
+
setLoading(false)
|
|
470
|
+
}
|
|
471
|
+
}, [projectId])
|
|
472
|
+
|
|
473
|
+
useEffect(() => { load() }, [load])
|
|
474
|
+
|
|
475
|
+
if (loading) {
|
|
476
|
+
return (
|
|
477
|
+
<div className="p-6 space-y-4">
|
|
478
|
+
<Skeleton className="h-6 w-48" />
|
|
479
|
+
<div className="grid grid-cols-4 gap-4">{Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className="h-24" />)}</div>
|
|
480
|
+
<div className="grid grid-cols-2 gap-4">{Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className="h-32" />)}</div>
|
|
481
|
+
</div>
|
|
482
|
+
)
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const project = data.project
|
|
486
|
+
const stats: ProjectStats = project?.data || { file_count: 0, chunk_count: 0, proposal_count: 0, approved_count: 0, pending_review_count: 0, total_ingestion_cost_usd: 0, last_ingested_at: null }
|
|
487
|
+
const embed = data.embed || { total_chunks: 0, embedded_chunks: 0, coverage_pct: 0, unembedded_chunks: 0 }
|
|
488
|
+
const doc = data.doc || { total_chunks: 0, documented_count: 0, undocumented_count: 0, ai_generated_count: 0, human_verified_count: 0, coverage_pct: 0 }
|
|
489
|
+
const callmap = data.callmap || { import_links: 0, call_links: 0, export_links: 0, total_links: 0, tested_by_links: 0 }
|
|
490
|
+
const config = data.config || { config_items: 0, configures_links: 0 }
|
|
491
|
+
|
|
492
|
+
const lastIngested = stats.last_ingested_at
|
|
493
|
+
? new Date(stats.last_ingested_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })
|
|
494
|
+
: 'Never'
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
const pass1Status = stats.file_count > 0 ? 'complete' : 'empty'
|
|
498
|
+
const pass2Status = stats.chunk_count > 0 ? 'complete' : (stats.file_count > 0 ? 'partial' : 'empty')
|
|
499
|
+
const pass3Status = embed.coverage_pct === 100 ? 'complete' : (embed.embedded_chunks > 0 ? 'partial' : 'empty') as any
|
|
500
|
+
const pass4Status = doc.coverage_pct === 100 ? 'complete' : (doc.documented_count > 0 ? 'partial' : 'empty') as any
|
|
501
|
+
const pass4bStatus = callmap.total_links > 0 ? 'complete' : 'empty' as any
|
|
502
|
+
const pass5Status = config.config_items > 0 ? (config.configures_links > 0 ? 'complete' : 'partial') : 'empty' as any
|
|
503
|
+
|
|
504
|
+
return (
|
|
505
|
+
<div className="p-6 space-y-6 max-w-5xl">
|
|
506
|
+
{}
|
|
507
|
+
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
|
508
|
+
<a href={appPath('/cil')} className="hover:underline">Code Intelligence</a>
|
|
509
|
+
<ChevronRight className="h-3 w-3" />
|
|
510
|
+
<span>{project?.title || 'Project'}</span>
|
|
511
|
+
<ChevronRight className="h-3 w-3" />
|
|
512
|
+
<span>Dashboard</span>
|
|
513
|
+
</div>
|
|
514
|
+
|
|
515
|
+
{}
|
|
516
|
+
<div className="flex items-start justify-between flex-wrap gap-4">
|
|
517
|
+
<div>
|
|
518
|
+
<h1 className="text-2xl font-bold">{project?.title || 'Project Dashboard'}</h1>
|
|
519
|
+
<p className="text-xs text-muted-foreground font-mono mt-0.5">Last ingested: {lastIngested}</p>
|
|
520
|
+
</div>
|
|
521
|
+
<div className="flex items-center gap-2">
|
|
522
|
+
<Button size="sm" variant="outline" onClick={load} className="h-8 text-xs">
|
|
523
|
+
<RefreshCw className="h-3 w-3 mr-1" /> Refresh
|
|
524
|
+
</Button>
|
|
525
|
+
<Button size="sm" asChild className="h-8 text-xs">
|
|
526
|
+
<a href={appPath(`/cil/${projectId}/ingest`)}>
|
|
527
|
+
<Play className="h-3 w-3 mr-1" /> Run Pipeline
|
|
528
|
+
</a>
|
|
529
|
+
</Button>
|
|
530
|
+
</div>
|
|
531
|
+
</div>
|
|
532
|
+
|
|
533
|
+
<PageInstructions
|
|
534
|
+
description="Review CIL project health and ingestion coverage."
|
|
535
|
+
sections={[
|
|
536
|
+
{ title: 'What this page is for', content: 'This page is the project-level overview for a CIL project. It displays stats, coverage, pipeline status, graph links, and drift alerts.' },
|
|
537
|
+
{ title: 'How to read the cards', content: 'The top tiles show Files, Chunks, Pending Review, and cumulative LLM Cost. The Coverage card shows embedding and documentation coverage plus AI-generated, human-verified, and undocumented counts.' },
|
|
538
|
+
{ title: 'How to read the pipeline', content: 'Pass cards summarize Discover Files, AST Chunk, Embed Chunks, AI Document, Call Map, and Config Extract. Each card shows status, counts, and a link to the relevant step.' },
|
|
539
|
+
{ title: 'Important notes', content: 'Use Refresh to reload the dashboard and Run Pipeline to start or continue ingestion. A drift alert appears when stored hashes differ from current code.' },
|
|
540
|
+
]}
|
|
541
|
+
/>
|
|
542
|
+
|
|
543
|
+
{}
|
|
544
|
+
<div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
|
|
545
|
+
<StatTile label="Files" value={stats.file_count.toLocaleString()} icon={FileCode2} />
|
|
546
|
+
<StatTile label="Chunks" value={stats.chunk_count.toLocaleString()} icon={Layers} accent />
|
|
547
|
+
<StatTile
|
|
548
|
+
label="Pending Review"
|
|
549
|
+
value={stats.pending_review_count}
|
|
550
|
+
icon={AlertTriangle}
|
|
551
|
+
/>
|
|
552
|
+
<StatTile
|
|
553
|
+
label="LLM Cost"
|
|
554
|
+
value={`$${(stats.total_ingestion_cost_usd ?? 0).toFixed(4)}`}
|
|
555
|
+
sub="cumulative"
|
|
556
|
+
icon={DollarSign}
|
|
557
|
+
/>
|
|
558
|
+
</div>
|
|
559
|
+
|
|
560
|
+
{}
|
|
561
|
+
<Card>
|
|
562
|
+
<CardHeader className="pb-2">
|
|
563
|
+
<CardTitle className="text-sm">Coverage</CardTitle>
|
|
564
|
+
</CardHeader>
|
|
565
|
+
<CardContent className="space-y-3">
|
|
566
|
+
<CoverageBar label={`Embeddings — ${embed.embedded_chunks} / ${embed.total_chunks} chunks`} pct={embed.coverage_pct} color="bg-indigo-500" />
|
|
567
|
+
<CoverageBar label={`Documentation — ${doc.documented_count} / ${doc.total_chunks} chunks`} pct={doc.coverage_pct} color="bg-emerald-500" />
|
|
568
|
+
<div className="pt-1 grid grid-cols-3 gap-3 text-xs text-center text-muted-foreground">
|
|
569
|
+
<div>
|
|
570
|
+
<div className="font-semibold text-blue-600">{doc.ai_generated_count}</div>
|
|
571
|
+
<div>AI Generated</div>
|
|
572
|
+
</div>
|
|
573
|
+
<div>
|
|
574
|
+
<div className="font-semibold text-green-600">{doc.human_verified_count}</div>
|
|
575
|
+
<div>Human Verified</div>
|
|
576
|
+
</div>
|
|
577
|
+
<div>
|
|
578
|
+
<div className="font-semibold text-slate-500">{doc.undocumented_count}</div>
|
|
579
|
+
<div>Undocumented</div>
|
|
580
|
+
</div>
|
|
581
|
+
</div>
|
|
582
|
+
</CardContent>
|
|
583
|
+
</Card>
|
|
584
|
+
|
|
585
|
+
{}
|
|
586
|
+
<div>
|
|
587
|
+
<h2 className="text-sm font-medium text-muted-foreground uppercase tracking-wide mb-3">Pipeline Status</h2>
|
|
588
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
|
589
|
+
<PassCard
|
|
590
|
+
number="1" label="Discover Files" icon={FileCode2}
|
|
591
|
+
description="Walk repo, register cil_file items, compute hashes"
|
|
592
|
+
status={pass1Status}
|
|
593
|
+
metric={`${stats.file_count.toLocaleString()} files registered`}
|
|
594
|
+
href={appPath(`/cil/${projectId}/ingest`)}
|
|
595
|
+
/>
|
|
596
|
+
<PassCard
|
|
597
|
+
number="2" label="AST Chunk" icon={Layers}
|
|
598
|
+
description="Parse files, propose chunk boundaries, write markers"
|
|
599
|
+
status={pass2Status}
|
|
600
|
+
metric={`${stats.chunk_count.toLocaleString()} chunks · ${stats.pending_review_count} pending`}
|
|
601
|
+
href={appPath(`/cil/${projectId}/ingest`)}
|
|
602
|
+
/>
|
|
603
|
+
<PassCard
|
|
604
|
+
number="3" label="Embed Chunks" icon={Zap}
|
|
605
|
+
description="Semantic + structural + contract vector embeddings"
|
|
606
|
+
status={pass3Status}
|
|
607
|
+
metric={`${embed.coverage_pct}% coverage · ${embed.embedded_chunks} / ${embed.total_chunks}`}
|
|
608
|
+
href={appPath(`/cil/${projectId}/ingest`)}
|
|
609
|
+
/>
|
|
610
|
+
<PassCard
|
|
611
|
+
number="4" label="AI Document" icon={Sparkles}
|
|
612
|
+
description="LLM-generated macro / micro / contract fields"
|
|
613
|
+
status={pass4Status}
|
|
614
|
+
metric={`${doc.coverage_pct}% coverage · $${(stats.total_ingestion_cost_usd ?? 0).toFixed(4)} spent`}
|
|
615
|
+
href={appPath(`/cil/${projectId}/ingest`)}
|
|
616
|
+
/>
|
|
617
|
+
<PassCard
|
|
618
|
+
number="4b" label="Call Map" icon={GitGraph}
|
|
619
|
+
description="Import + call edges between files and chunks"
|
|
620
|
+
status={pass4bStatus}
|
|
621
|
+
metric={`${callmap.call_links.toLocaleString()} calls · ${callmap.import_links.toLocaleString()} imports`}
|
|
622
|
+
href={appPath(`/cil/${projectId}/graph`)}
|
|
623
|
+
/>
|
|
624
|
+
<PassCard
|
|
625
|
+
number="5" label="Config Extract" icon={Settings2}
|
|
626
|
+
description="Config field contracts + cil_configures links"
|
|
627
|
+
status={pass5Status}
|
|
628
|
+
metric={`${config.config_items.toLocaleString()} config items · ${config.configures_links.toLocaleString()} links`}
|
|
629
|
+
href={appPath(`/cil/${projectId}/ingest`)}
|
|
630
|
+
/>
|
|
631
|
+
</div>
|
|
632
|
+
</div>
|
|
633
|
+
|
|
634
|
+
{}
|
|
635
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
636
|
+
{}
|
|
637
|
+
<Card>
|
|
638
|
+
<CardHeader className="pb-2">
|
|
639
|
+
<CardTitle className="text-sm flex items-center gap-1.5">
|
|
640
|
+
<GitGraph className="h-4 w-4" /> Graph Links
|
|
641
|
+
</CardTitle>
|
|
642
|
+
</CardHeader>
|
|
643
|
+
<CardContent className="space-y-2">
|
|
644
|
+
{[
|
|
645
|
+
{ label: 'Import links (file→file)', value: callmap.import_links },
|
|
646
|
+
{ label: 'Call links (chunk→chunk)', value: callmap.call_links },
|
|
647
|
+
{ label: 'Export links', value: callmap.export_links },
|
|
648
|
+
{ label: 'Tested-by links', value: callmap.tested_by_links ?? 0 },
|
|
649
|
+
].map(item => (
|
|
650
|
+
<div key={item.label} className="flex justify-between text-sm">
|
|
651
|
+
<span className="text-muted-foreground">{item.label}</span>
|
|
652
|
+
<span className="font-mono font-medium">{item.value.toLocaleString()}</span>
|
|
653
|
+
</div>
|
|
654
|
+
))}
|
|
655
|
+
<div className="pt-2 flex gap-2">
|
|
656
|
+
<Button size="sm" variant="outline" className="flex-1 h-7 text-xs" asChild>
|
|
657
|
+
<a href={appPath(`/cil/${projectId}/graph`)}>
|
|
658
|
+
<GitGraph className="h-3 w-3 mr-1" /> View Graph
|
|
659
|
+
</a>
|
|
660
|
+
</Button>
|
|
661
|
+
</div>
|
|
662
|
+
</CardContent>
|
|
663
|
+
</Card>
|
|
664
|
+
|
|
665
|
+
{}
|
|
666
|
+
<DriftAlertCard projectId={projectId!} appPath={appPath} />
|
|
667
|
+
</div>
|
|
668
|
+
|
|
669
|
+
{}
|
|
670
|
+
<div>
|
|
671
|
+
<h2 className="text-sm font-medium text-muted-foreground uppercase tracking-wide mb-3">Quick Actions</h2>
|
|
672
|
+
<div className="flex flex-wrap gap-2">
|
|
673
|
+
<Button size="sm" variant="outline" asChild>
|
|
674
|
+
<a href={appPath(`/cil/search`)}>
|
|
675
|
+
<Search className="h-3.5 w-3.5 mr-1.5" /> Search Chunks
|
|
676
|
+
</a>
|
|
677
|
+
</Button>
|
|
678
|
+
<Button size="sm" variant="outline" asChild>
|
|
679
|
+
<a href={appPath(`/cil/${projectId}/agent`)}>
|
|
680
|
+
<Bot className="h-3.5 w-3.5 mr-1.5" /> Ask CIL Agent
|
|
681
|
+
</a>
|
|
682
|
+
</Button>
|
|
683
|
+
<Button size="sm" variant="outline" asChild>
|
|
684
|
+
<a href={appPath(`/cil/${projectId}/files`)}>
|
|
685
|
+
<Layers className="h-3.5 w-3.5 mr-1.5" /> Browse Files
|
|
686
|
+
</a>
|
|
687
|
+
</Button>
|
|
688
|
+
<Button size="sm" variant="outline" asChild>
|
|
689
|
+
<a href={appPath(`/cil/${projectId}/ingest`)}>
|
|
690
|
+
<Play className="h-3.5 w-3.5 mr-1.5" /> Run Ingestion
|
|
691
|
+
</a>
|
|
692
|
+
</Button>
|
|
693
|
+
</div>
|
|
694
|
+
</div>
|
|
695
|
+
</div>
|
|
696
|
+
)
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// CIL[END chunk_id="cildashboardpage_cildashboardpage_1784193942"]
|