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,647 @@
|
|
|
1
|
+
// CIL[BEGIN chunk_id="cilfilelistpage_module_header_1784193942" type="module_header" identity="module_header" parent="none"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Import React hooks, UI primitives and icons for the CIL file list page"]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide all external dependencies required to render and operate the file list"]
|
|
4
|
+
// CIL[DOC-CONTEXT module="cortex:cil-file-list" layer="presentation" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="ES module imports for React, router, internal API, shadcn UI 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, .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
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, useNavigate } 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 { Input } from '@core/components/ui/input'
|
|
24
|
+
import {
|
|
25
|
+
FileCode2,
|
|
26
|
+
CheckCircle2,
|
|
27
|
+
AlertTriangle,
|
|
28
|
+
Clock,
|
|
29
|
+
ShieldCheck,
|
|
30
|
+
ShieldAlert,
|
|
31
|
+
ArrowLeft,
|
|
32
|
+
RefreshCw,
|
|
33
|
+
Search,
|
|
34
|
+
Code2,
|
|
35
|
+
GitGraph,
|
|
36
|
+
Layers,
|
|
37
|
+
ChevronDown,
|
|
38
|
+
ChevronRight,
|
|
39
|
+
ExternalLink,
|
|
40
|
+
} from 'lucide-react'
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
import { PageInstructions } from '../../../components/admin/PageInstructions'
|
|
45
|
+
// CIL[END chunk_id="cilfilelistpage_module_header_1784193942"]
|
|
46
|
+
// CIL[BEGIN chunk_id="cilfilelistpage_cilfile_1784193942" type="interface" identity="CILFile" parent="none"]
|
|
47
|
+
// CIL[DOC-MACRO purpose="Describe the shape of a CIL file record displayed in the list"]
|
|
48
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Type-check file metadata returned by the CIL ingestion backend"]
|
|
49
|
+
// CIL[DOC-CONTEXT module="cortex:cil-file-list" layer="presentation" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
|
|
50
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="CILFile type shape" errors="none" side_effects="none"]
|
|
51
|
+
// CIL[DOC-MICRO logic_summary="Interface covering id, title, data payload and updated_at timestamp" notable_decisions="[]"]
|
|
52
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
53
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
54
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
|
|
55
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
56
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
57
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
58
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
59
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
60
|
+
interface CILFile {
|
|
61
|
+
id: string
|
|
62
|
+
title: string
|
|
63
|
+
data: {
|
|
64
|
+
file_path: string
|
|
65
|
+
language: string
|
|
66
|
+
project_id: string
|
|
67
|
+
ingestion_pass: number
|
|
68
|
+
chunk_count: number
|
|
69
|
+
line_count: number
|
|
70
|
+
stored_hash: string | null
|
|
71
|
+
is_dead_code: boolean
|
|
72
|
+
has_existing_markers: boolean
|
|
73
|
+
existing_marker_count: number
|
|
74
|
+
git_last_commit: string | null
|
|
75
|
+
}
|
|
76
|
+
updated_at: string
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// CIL[END chunk_id="cilfilelistpage_cilfile_1784193942"]
|
|
80
|
+
// CIL[BEGIN chunk_id="cilfilelistpage_cilchunk_1784193942" type="interface" identity="CILChunk" parent="none"]
|
|
81
|
+
// CIL[DOC-MACRO purpose="Describe the shape of a single indexed CIL chunk"]
|
|
82
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Type-check chunk metadata used when expanding a file's chunk list"]
|
|
83
|
+
// CIL[DOC-CONTEXT module="cortex:cil-file-list" layer="presentation" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
|
|
84
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="CILChunk type shape" errors="none" side_effects="none"]
|
|
85
|
+
// CIL[DOC-MICRO logic_summary="Interface for chunk identity, type, line range, macro and confidence fields" notable_decisions="[]"]
|
|
86
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
87
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
88
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
|
|
89
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
90
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
91
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
92
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
93
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
94
|
+
interface CILChunk {
|
|
95
|
+
id: string
|
|
96
|
+
chunk_name: string
|
|
97
|
+
chunk_type: string
|
|
98
|
+
line_start: number
|
|
99
|
+
line_end: number
|
|
100
|
+
macro: string
|
|
101
|
+
doc_confidence: string
|
|
102
|
+
boundary_confidence: string
|
|
103
|
+
stored_hash: string | null
|
|
104
|
+
is_dead_code: boolean
|
|
105
|
+
stability: string
|
|
106
|
+
file_path: string
|
|
107
|
+
project_id: string
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// CIL[END chunk_id="cilfilelistpage_cilchunk_1784193942"]
|
|
111
|
+
// CIL[BEGIN chunk_id="cilfilelistpage_validationsummary_1784193942" type="interface" identity="ValidationSummary" parent="none"]
|
|
112
|
+
// CIL[DOC-MACRO purpose="Describe the shape of a file validation summary"]
|
|
113
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Type-check counts and trust rating returned by the validate endpoint"]
|
|
114
|
+
// CIL[DOC-CONTEXT module="cortex:cil-file-list" layer="presentation" related_files="[\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/migrations/025_retype_threads_messages.sql\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
|
|
115
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="ValidationSummary type shape" errors="none" side_effects="none"]
|
|
116
|
+
// CIL[DOC-MICRO logic_summary="Interface for total, current, drift_detected, not_found and trust_rating" notable_decisions="[]"]
|
|
117
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
118
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
119
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/principal.ts, .framework/migrations/025_retype_threads_messages.sql, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
|
|
120
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
121
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
122
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
123
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
124
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
125
|
+
interface ValidationSummary {
|
|
126
|
+
total: number
|
|
127
|
+
current: number
|
|
128
|
+
drift_detected: number
|
|
129
|
+
not_found: number
|
|
130
|
+
trust_rating: number
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// CIL[END chunk_id="cilfilelistpage_validationsummary_1784193942"]
|
|
134
|
+
// CIL[BEGIN chunk_id="cilfilelistpage_filevalidation_1784193942" type="interface" identity="FileValidation" parent="none"]
|
|
135
|
+
// CIL[DOC-MACRO purpose="Describe the local validation state for a single file"]
|
|
136
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Track loading, summary and error state while validating a file"]
|
|
137
|
+
// CIL[DOC-CONTEXT module="cortex:cil-file-list" layer="presentation" related_files="[\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\"\\\"]"]
|
|
138
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="FileValidation type shape" errors="none" side_effects="none"]
|
|
139
|
+
// CIL[DOC-MICRO logic_summary="Interface bundling fileId, summary, loading flag and error string" notable_decisions="[]"]
|
|
140
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
141
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
142
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/principal.ts, custom/apps/portal/pages/ContentPage.tsx, \."]
|
|
143
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
144
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
145
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
146
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
147
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
148
|
+
interface FileValidation {
|
|
149
|
+
fileId: string
|
|
150
|
+
summary: ValidationSummary | null
|
|
151
|
+
loading: boolean
|
|
152
|
+
error: string | null
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
// CIL[END chunk_id="cilfilelistpage_filevalidation_1784193942"]
|
|
158
|
+
// CIL[BEGIN chunk_id="cilfilelistpage_passbadge_1784193942" type="function" identity="PassBadge" parent="none"]
|
|
159
|
+
// CIL[DOC-MACRO purpose="Render a badge that shows a CIL file's ingestion pass status"]
|
|
160
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display a compact, color-coded label for the pass number"]
|
|
161
|
+
// CIL[DOC-CONTEXT module="cortex:cil-file-list" layer="presentation" related_files="[]"]
|
|
162
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Badge JSX element" errors="none" side_effects="none"]
|
|
163
|
+
// CIL[DOC-MICRO logic_summary="Returns outline, emerald or secondary Badge variants based on pass value" notable_decisions="[]"]
|
|
164
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
165
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
166
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
167
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
168
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
169
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
170
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
171
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
172
|
+
function PassBadge({ pass }: { pass: number }) {
|
|
173
|
+
if (!pass || pass < 1) {
|
|
174
|
+
return <Badge variant="outline" className="text-xs text-muted-foreground">Not ingested</Badge>
|
|
175
|
+
}
|
|
176
|
+
if (pass >= 2) {
|
|
177
|
+
return <Badge variant="default" className="text-xs bg-emerald-600 hover:bg-emerald-700">Pass {pass} complete</Badge>
|
|
178
|
+
}
|
|
179
|
+
return <Badge variant="secondary" className="text-xs">Pass {pass}</Badge>
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
// CIL[END chunk_id="cilfilelistpage_passbadge_1784193942"]
|
|
185
|
+
// CIL[BEGIN chunk_id="cilfilelistpage_trustbadge_1784193942" type="function" identity="TrustBadge" parent="none"]
|
|
186
|
+
// CIL[DOC-MACRO purpose="Render a badge that shows validation trust and drift warnings"]
|
|
187
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display trust rating or drift count for a validated file"]
|
|
188
|
+
// CIL[DOC-CONTEXT module="cortex:cil-file-list" layer="presentation" related_files="[]"]
|
|
189
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Badge JSX element or null" errors="none" side_effects="none"]
|
|
190
|
+
// CIL[DOC-MICRO logic_summary="Shows ShieldCheck when trusted or ShieldAlert when drift is detected" notable_decisions="[]"]
|
|
191
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
192
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
193
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
194
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
195
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
196
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
197
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
198
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
199
|
+
function TrustBadge({ summary }: { summary: ValidationSummary | null }) {
|
|
200
|
+
if (!summary) return null
|
|
201
|
+
const { trust_rating, drift_detected } = summary
|
|
202
|
+
if (drift_detected > 0) {
|
|
203
|
+
return (
|
|
204
|
+
<Badge variant="destructive" className="text-xs flex items-center gap-1">
|
|
205
|
+
<ShieldAlert className="h-3 w-3" />
|
|
206
|
+
{trust_rating}% ({drift_detected} drift)
|
|
207
|
+
</Badge>
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
return (
|
|
211
|
+
<Badge variant="outline" className="text-xs flex items-center gap-1 border-emerald-500 text-emerald-600">
|
|
212
|
+
<ShieldCheck className="h-3 w-3" />
|
|
213
|
+
{trust_rating}% trusted
|
|
214
|
+
</Badge>
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
// CIL[END chunk_id="cilfilelistpage_trustbadge_1784193942"]
|
|
221
|
+
// CIL[BEGIN chunk_id="cilfilelistpage_cilfilelistpage_1784193942" type="component" identity="CILFileListPage" parent="none"]
|
|
222
|
+
// CIL[DOC-MACRO purpose="Render the CIL file list page for a project"]
|
|
223
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Fetch and display CIL files, run validation, and expand chunk details"]
|
|
224
|
+
// CIL[DOC-CONTEXT module="cortex:cil-file-list" layer="presentation" related_files="[]"]
|
|
225
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX page with file list" errors="silent fetch errors, validation errors" side_effects="GET project/files, GET/POST validate and graph endpoints, navigation"]
|
|
226
|
+
// CIL[DOC-MICRO logic_summary="Loads project and files, filters by search, validates files and toggles chunk expansion" notable_decisions="[]"]
|
|
227
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
228
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
229
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
230
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
231
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
232
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
233
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
234
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
235
|
+
export default function CILFileListPage() {
|
|
236
|
+
const { id: projectId } = useParams<{ id: string }>()
|
|
237
|
+
const navigate = useNavigate()
|
|
238
|
+
const appPath = (path: string) => '/spine-framework/admin' + (path.startsWith('/') ? path : '/' + path)
|
|
239
|
+
|
|
240
|
+
const [project, setProject] = useState<{ id: string; title: string; data: any } | null>(null)
|
|
241
|
+
const [files, setFiles] = useState<CILFile[]>([])
|
|
242
|
+
const [loading, setLoading] = useState(true)
|
|
243
|
+
const [search, setSearch] = useState('')
|
|
244
|
+
const [validations, setValidations] = useState<Record<string, FileValidation>>({})
|
|
245
|
+
const [validatingAll, setValidatingAll] = useState(false)
|
|
246
|
+
const [expandedFiles, setExpandedFiles] = useState<Set<string>>(new Set())
|
|
247
|
+
const [fileChunks, setFileChunks] = useState<Record<string, { chunks: CILChunk[]; loading: boolean; loaded: boolean }>>({})
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
const fetchData = useCallback(() => {
|
|
251
|
+
if (!projectId) return
|
|
252
|
+
setLoading(true)
|
|
253
|
+
|
|
254
|
+
Promise.all([
|
|
255
|
+
apiFetch(`/api/cil-project?action=get&id=${projectId}`).then(r => r.json()),
|
|
256
|
+
apiFetch(`/api/admin-data?action=list&entity=items&type_slug=cil_file&limit=500`)
|
|
257
|
+
.then(r => r.json()),
|
|
258
|
+
])
|
|
259
|
+
.then(([projData, filesData]) => {
|
|
260
|
+
setProject(projData?.project || projData?.data || null)
|
|
261
|
+
const allFiles: CILFile[] = filesData?.data || filesData?.items || []
|
|
262
|
+
setFiles(allFiles.filter(f => f.data?.project_id === projectId))
|
|
263
|
+
})
|
|
264
|
+
.catch(() => {})
|
|
265
|
+
.finally(() => setLoading(false))
|
|
266
|
+
}, [projectId])
|
|
267
|
+
|
|
268
|
+
useEffect(() => { fetchData() }, [fetchData])
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
const validateFile = useCallback(async (fileId: string) => {
|
|
272
|
+
setValidations(prev => ({
|
|
273
|
+
...prev,
|
|
274
|
+
[fileId]: { fileId, summary: null, loading: true, error: null },
|
|
275
|
+
}))
|
|
276
|
+
try {
|
|
277
|
+
const res = await apiFetch(
|
|
278
|
+
`/api/cil-validate?action=validate_file&file_id=${fileId}`
|
|
279
|
+
)
|
|
280
|
+
const data = await res.json()
|
|
281
|
+
setValidations(prev => ({
|
|
282
|
+
...prev,
|
|
283
|
+
[fileId]: {
|
|
284
|
+
fileId,
|
|
285
|
+
summary: data?.summary || null,
|
|
286
|
+
loading: false,
|
|
287
|
+
error: data?.error || null,
|
|
288
|
+
},
|
|
289
|
+
}))
|
|
290
|
+
} catch (err) {
|
|
291
|
+
setValidations(prev => ({
|
|
292
|
+
...prev,
|
|
293
|
+
[fileId]: {
|
|
294
|
+
fileId,
|
|
295
|
+
summary: null,
|
|
296
|
+
loading: false,
|
|
297
|
+
error: err instanceof Error ? err.message : 'Validation failed',
|
|
298
|
+
},
|
|
299
|
+
}))
|
|
300
|
+
}
|
|
301
|
+
}, [])
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
const validateAll = useCallback(async () => {
|
|
305
|
+
const visible = filteredFiles
|
|
306
|
+
setValidatingAll(true)
|
|
307
|
+
for (const f of visible) {
|
|
308
|
+
await validateFile(f.id)
|
|
309
|
+
}
|
|
310
|
+
setValidatingAll(false)
|
|
311
|
+
}, [files, search])
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
const toggleFileChunks = useCallback(async (fileId: string) => {
|
|
315
|
+
const alreadyExpanded = expandedFiles.has(fileId)
|
|
316
|
+
setExpandedFiles(prev => {
|
|
317
|
+
const next = new Set(prev)
|
|
318
|
+
alreadyExpanded ? next.delete(fileId) : next.add(fileId)
|
|
319
|
+
return next
|
|
320
|
+
})
|
|
321
|
+
if (alreadyExpanded) return
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
if (fileChunks[fileId]?.loaded) return
|
|
325
|
+
|
|
326
|
+
setFileChunks(prev => ({ ...prev, [fileId]: { chunks: [], loading: true, loaded: false } }))
|
|
327
|
+
try {
|
|
328
|
+
const res = await apiFetch(`/api/cil-graph?action=get_file_chunks&file_id=${fileId}`)
|
|
329
|
+
const data = await res.json()
|
|
330
|
+
const chunks: CILChunk[] = data?.chunks || data?.data?.chunks || []
|
|
331
|
+
setFileChunks(prev => ({ ...prev, [fileId]: { chunks, loading: false, loaded: true } }))
|
|
332
|
+
} catch {
|
|
333
|
+
setFileChunks(prev => ({ ...prev, [fileId]: { chunks: [], loading: false, loaded: true } }))
|
|
334
|
+
}
|
|
335
|
+
}, [expandedFiles, fileChunks])
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
const filteredFiles = files.filter(f => {
|
|
339
|
+
if (!search) return true
|
|
340
|
+
const q = search.toLowerCase()
|
|
341
|
+
return (
|
|
342
|
+
(f.data?.file_path || '').toLowerCase().includes(q) ||
|
|
343
|
+
(f.data?.language || '').toLowerCase().includes(q)
|
|
344
|
+
)
|
|
345
|
+
})
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
const totalChunks = files.reduce((sum, f) => sum + (f.data?.chunk_count || 0), 0)
|
|
349
|
+
const fullyIngested = files.filter(f => (f.data?.ingestion_pass || 0) >= 2).length
|
|
350
|
+
const deadCodeFiles = files.filter(f => f.data?.is_dead_code).length
|
|
351
|
+
const validatedCount = Object.keys(validations).length
|
|
352
|
+
const driftCount = Object.values(validations).filter(v => (v.summary?.drift_detected || 0) > 0).length
|
|
353
|
+
|
|
354
|
+
if (loading) {
|
|
355
|
+
return (
|
|
356
|
+
<div className="p-6 space-y-4">
|
|
357
|
+
<Skeleton className="h-8 w-64" />
|
|
358
|
+
<Skeleton className="h-6 w-96" />
|
|
359
|
+
<div className="grid gap-3">
|
|
360
|
+
{[...Array(6)].map((_, i) => <Skeleton key={i} className="h-20 w-full" />)}
|
|
361
|
+
</div>
|
|
362
|
+
</div>
|
|
363
|
+
)
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return (
|
|
367
|
+
<div className="p-6 space-y-6">
|
|
368
|
+
|
|
369
|
+
{}
|
|
370
|
+
<div className="flex items-center justify-between">
|
|
371
|
+
<div className="flex items-center gap-3">
|
|
372
|
+
<Button
|
|
373
|
+
variant="ghost"
|
|
374
|
+
size="sm"
|
|
375
|
+
onClick={() => navigate(appPath(`/cil/${projectId}`))}
|
|
376
|
+
className="flex items-center gap-1 text-muted-foreground"
|
|
377
|
+
>
|
|
378
|
+
<ArrowLeft className="h-4 w-4" />
|
|
379
|
+
Back
|
|
380
|
+
</Button>
|
|
381
|
+
<div>
|
|
382
|
+
<h1 className="text-xl font-bold flex items-center gap-2">
|
|
383
|
+
<Layers className="h-5 w-5 text-violet-500" />
|
|
384
|
+
File List
|
|
385
|
+
{project && (
|
|
386
|
+
<span className="text-muted-foreground font-normal text-base">— {project.title}</span>
|
|
387
|
+
)}
|
|
388
|
+
</h1>
|
|
389
|
+
<p className="text-sm text-muted-foreground mt-0.5">
|
|
390
|
+
{files.length} files · {totalChunks} total chunks
|
|
391
|
+
</p>
|
|
392
|
+
</div>
|
|
393
|
+
</div>
|
|
394
|
+
<div className="flex gap-2">
|
|
395
|
+
<Button variant="outline" size="sm" onClick={fetchData}>
|
|
396
|
+
<RefreshCw className="h-4 w-4 mr-1" />
|
|
397
|
+
Refresh
|
|
398
|
+
</Button>
|
|
399
|
+
<Button
|
|
400
|
+
variant="outline"
|
|
401
|
+
size="sm"
|
|
402
|
+
onClick={validateAll}
|
|
403
|
+
disabled={validatingAll || filteredFiles.length === 0}
|
|
404
|
+
>
|
|
405
|
+
<ShieldCheck className="h-4 w-4 mr-1" />
|
|
406
|
+
{validatingAll ? 'Validating…' : `Validate All (${filteredFiles.length})`}
|
|
407
|
+
</Button>
|
|
408
|
+
</div>
|
|
409
|
+
</div>
|
|
410
|
+
|
|
411
|
+
<PageInstructions
|
|
412
|
+
description="Browse indexed files and their chunks for a project."
|
|
413
|
+
sections={[
|
|
414
|
+
{ title: 'What this page is for', content: 'This page lists all files discovered for a CIL project and shows their ingestion, drift, and dead-code status.' },
|
|
415
|
+
{ title: 'How to read this page', content: 'The summary cards show Total Files, Fully Ingested, Dead Code, and Files with Drift. Each file card displays the path, language, chunk count, and status badges.' },
|
|
416
|
+
{ title: 'How to use this page', content: 'Use the search box to filter by path or language. Click a file to view its chunks. Click Validate All to re-check hashes and drift for the filtered files.' },
|
|
417
|
+
{ title: 'Important notes', content: 'Drift means the file changed since the last ingestion and stored hashes no longer match. Dead-code files are not called or imported by any other indexed file.' },
|
|
418
|
+
]}
|
|
419
|
+
/>
|
|
420
|
+
|
|
421
|
+
{}
|
|
422
|
+
<div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
|
|
423
|
+
{[
|
|
424
|
+
{ label: 'Total Files', value: files.length, icon: FileCode2, color: 'text-violet-500' },
|
|
425
|
+
{ label: 'Fully Ingested', value: fullyIngested, icon: CheckCircle2, color: 'text-emerald-500' },
|
|
426
|
+
{ label: 'Dead Code', value: deadCodeFiles, icon: AlertTriangle, color: 'text-amber-500' },
|
|
427
|
+
{ label: 'Files w/ Drift', value: driftCount, icon: ShieldAlert, color: 'text-red-500' },
|
|
428
|
+
].map(stat => (
|
|
429
|
+
<Card key={stat.label} className="p-3">
|
|
430
|
+
<div className="flex items-center gap-2">
|
|
431
|
+
<stat.icon className={`h-4 w-4 ${stat.color}`} />
|
|
432
|
+
<div>
|
|
433
|
+
<div className="text-xs text-muted-foreground">{stat.label}</div>
|
|
434
|
+
<div className="text-lg font-bold">{stat.value}</div>
|
|
435
|
+
</div>
|
|
436
|
+
</div>
|
|
437
|
+
</Card>
|
|
438
|
+
))}
|
|
439
|
+
</div>
|
|
440
|
+
|
|
441
|
+
{}
|
|
442
|
+
<div className="relative max-w-md">
|
|
443
|
+
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
|
444
|
+
<Input
|
|
445
|
+
className="pl-9"
|
|
446
|
+
placeholder="Filter by path or language…"
|
|
447
|
+
value={search}
|
|
448
|
+
onChange={e => setSearch(e.target.value)}
|
|
449
|
+
/>
|
|
450
|
+
</div>
|
|
451
|
+
|
|
452
|
+
{}
|
|
453
|
+
{validatedCount > 0 && (
|
|
454
|
+
<div className="text-sm text-muted-foreground">
|
|
455
|
+
Validated {validatedCount} / {filteredFiles.length} files
|
|
456
|
+
{driftCount > 0 && (
|
|
457
|
+
<span className="ml-2 text-red-500 font-medium">· {driftCount} with drift</span>
|
|
458
|
+
)}
|
|
459
|
+
</div>
|
|
460
|
+
)}
|
|
461
|
+
|
|
462
|
+
{}
|
|
463
|
+
{filteredFiles.length === 0 ? (
|
|
464
|
+
<Card className="p-8 text-center text-muted-foreground">
|
|
465
|
+
{files.length === 0
|
|
466
|
+
? 'No files ingested yet. Run Pass 1 from the Ingestion tab.'
|
|
467
|
+
: 'No files match the current filter.'}
|
|
468
|
+
</Card>
|
|
469
|
+
) : (
|
|
470
|
+
<div className="space-y-2">
|
|
471
|
+
{filteredFiles.map(file => {
|
|
472
|
+
const d = file.data || {}
|
|
473
|
+
const filePath: string = d.file_path || file.title
|
|
474
|
+
const shortName = filePath.split('/').pop() || filePath
|
|
475
|
+
const dirPath = filePath.includes('/')
|
|
476
|
+
? filePath.split('/').slice(0, -1).join('/')
|
|
477
|
+
: ''
|
|
478
|
+
const val = validations[file.id]
|
|
479
|
+
const isValidating = val?.loading === true
|
|
480
|
+
|
|
481
|
+
return (
|
|
482
|
+
<Card key={file.id} className="hover:bg-muted/30 transition-colors">
|
|
483
|
+
<CardContent className="p-4">
|
|
484
|
+
<div className="flex items-start justify-between gap-3">
|
|
485
|
+
|
|
486
|
+
{}
|
|
487
|
+
<div className="flex items-start gap-3 min-w-0 flex-1">
|
|
488
|
+
<FileCode2 className="h-4 w-4 mt-0.5 shrink-0 text-violet-400" />
|
|
489
|
+
<div className="min-w-0">
|
|
490
|
+
<div className="font-mono text-sm font-medium truncate">{shortName}</div>
|
|
491
|
+
{dirPath && (
|
|
492
|
+
<div className="text-xs text-muted-foreground font-mono truncate">{dirPath}/</div>
|
|
493
|
+
)}
|
|
494
|
+
<div className="flex flex-wrap items-center gap-1.5 mt-1.5">
|
|
495
|
+
<Badge variant="outline" className="text-xs font-mono">{d.language || 'unknown'}</Badge>
|
|
496
|
+
<PassBadge pass={d.ingestion_pass || 0} />
|
|
497
|
+
{d.chunk_count > 0 && (
|
|
498
|
+
<Badge variant="secondary" className="text-xs flex items-center gap-1">
|
|
499
|
+
<Code2 className="h-2.5 w-2.5" />
|
|
500
|
+
{d.chunk_count} chunks
|
|
501
|
+
</Badge>
|
|
502
|
+
)}
|
|
503
|
+
{d.line_count > 0 && (
|
|
504
|
+
<span className="text-xs text-muted-foreground">{d.line_count} lines</span>
|
|
505
|
+
)}
|
|
506
|
+
{d.is_dead_code && (
|
|
507
|
+
<Badge variant="outline" className="text-xs text-amber-600 border-amber-400">
|
|
508
|
+
Dead code
|
|
509
|
+
</Badge>
|
|
510
|
+
)}
|
|
511
|
+
{d.has_existing_markers && d.existing_marker_count > 0 && (
|
|
512
|
+
<span className="text-xs text-muted-foreground">
|
|
513
|
+
{d.existing_marker_count} prior markers
|
|
514
|
+
</span>
|
|
515
|
+
)}
|
|
516
|
+
{}
|
|
517
|
+
{val && !val.loading && val.summary && (
|
|
518
|
+
<TrustBadge summary={val.summary} />
|
|
519
|
+
)}
|
|
520
|
+
{val && !val.loading && val.error && (
|
|
521
|
+
<Badge variant="destructive" className="text-xs">Validate error</Badge>
|
|
522
|
+
)}
|
|
523
|
+
</div>
|
|
524
|
+
</div>
|
|
525
|
+
</div>
|
|
526
|
+
|
|
527
|
+
{}
|
|
528
|
+
<div className="flex items-center gap-1.5 shrink-0">
|
|
529
|
+
{}
|
|
530
|
+
{(d.chunk_count || 0) > 0 && (
|
|
531
|
+
<Button
|
|
532
|
+
size="sm"
|
|
533
|
+
variant="ghost"
|
|
534
|
+
className="px-2 h-8 text-xs"
|
|
535
|
+
onClick={() => toggleFileChunks(file.id)}
|
|
536
|
+
title={expandedFiles.has(file.id) ? 'Collapse chunks' : 'Show chunks'}
|
|
537
|
+
>
|
|
538
|
+
{expandedFiles.has(file.id)
|
|
539
|
+
? <ChevronDown className="h-3.5 w-3.5" />
|
|
540
|
+
: <ChevronRight className="h-3.5 w-3.5" />
|
|
541
|
+
}
|
|
542
|
+
</Button>
|
|
543
|
+
)}
|
|
544
|
+
<Button
|
|
545
|
+
size="sm"
|
|
546
|
+
variant="ghost"
|
|
547
|
+
className="px-2 h-8 text-xs"
|
|
548
|
+
disabled={isValidating}
|
|
549
|
+
onClick={() => validateFile(file.id)}
|
|
550
|
+
title="Validate file hashes from disk"
|
|
551
|
+
>
|
|
552
|
+
{isValidating ? (
|
|
553
|
+
<RefreshCw className="h-3.5 w-3.5 animate-spin" />
|
|
554
|
+
) : (
|
|
555
|
+
<ShieldCheck className="h-3.5 w-3.5" />
|
|
556
|
+
)}
|
|
557
|
+
</Button>
|
|
558
|
+
<Button
|
|
559
|
+
size="sm"
|
|
560
|
+
variant="ghost"
|
|
561
|
+
className="px-2 h-8"
|
|
562
|
+
onClick={() => navigate(appPath(`/cil/${projectId}/graph`))}
|
|
563
|
+
title="View call graph"
|
|
564
|
+
>
|
|
565
|
+
<GitGraph className="h-3.5 w-3.5" />
|
|
566
|
+
</Button>
|
|
567
|
+
</div>
|
|
568
|
+
</div>
|
|
569
|
+
|
|
570
|
+
{}
|
|
571
|
+
{val && !val.loading && val.summary && val.summary.drift_detected > 0 && (
|
|
572
|
+
<div className="mt-3 p-2.5 rounded bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-900 text-xs space-y-1">
|
|
573
|
+
<div className="font-medium text-red-700 dark:text-red-400 flex items-center gap-1">
|
|
574
|
+
<ShieldAlert className="h-3 w-3" />
|
|
575
|
+
{val.summary.drift_detected} chunk{val.summary.drift_detected !== 1 ? 's' : ''} have drifted since last ingestion
|
|
576
|
+
</div>
|
|
577
|
+
<div className="text-muted-foreground">
|
|
578
|
+
Run <code className="font-mono bg-muted px-1 rounded">reindex_chunk</code> or re-run Pass 2 with <code className="font-mono bg-muted px-1 rounded">force_reprocess: true</code> to update stored hashes.
|
|
579
|
+
</div>
|
|
580
|
+
</div>
|
|
581
|
+
)}
|
|
582
|
+
|
|
583
|
+
{}
|
|
584
|
+
{expandedFiles.has(file.id) && (() => {
|
|
585
|
+
const fc = fileChunks[file.id]
|
|
586
|
+
if (!fc || fc.loading) return (
|
|
587
|
+
<div className="mt-3 pt-3 border-t space-y-1.5">
|
|
588
|
+
{[...Array(3)].map((_, i) => (
|
|
589
|
+
<div key={i} className="h-6 rounded bg-muted animate-pulse" />
|
|
590
|
+
))}
|
|
591
|
+
</div>
|
|
592
|
+
)
|
|
593
|
+
if (!fc.chunks.length) return (
|
|
594
|
+
<div className="mt-3 pt-3 border-t text-xs text-muted-foreground">No chunks indexed for this file.</div>
|
|
595
|
+
)
|
|
596
|
+
|
|
597
|
+
const CHUNK_TYPE_COLORS: Record<string, string> = {
|
|
598
|
+
function: 'bg-indigo-100 text-indigo-700',
|
|
599
|
+
class: 'bg-violet-100 text-violet-700',
|
|
600
|
+
interface: 'bg-emerald-100 text-emerald-700',
|
|
601
|
+
type: 'bg-cyan-100 text-cyan-700',
|
|
602
|
+
component: 'bg-amber-100 text-amber-700',
|
|
603
|
+
hook: 'bg-pink-100 text-pink-700',
|
|
604
|
+
route: 'bg-red-100 text-red-700',
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
return (
|
|
608
|
+
<div className="mt-3 pt-3 border-t space-y-1">
|
|
609
|
+
{fc.chunks.map(chunk => {
|
|
610
|
+
const typeClass = CHUNK_TYPE_COLORS[chunk.chunk_type] || 'bg-slate-100 text-slate-600'
|
|
611
|
+
return (
|
|
612
|
+
<a
|
|
613
|
+
key={chunk.id}
|
|
614
|
+
href={appPath(`/cil/${projectId}/chunks/${chunk.id}`)}
|
|
615
|
+
className="flex items-center gap-2 group rounded px-1.5 py-1 hover:bg-muted/60 transition-colors text-xs"
|
|
616
|
+
>
|
|
617
|
+
<Code2 className="h-3 w-3 shrink-0 text-muted-foreground" />
|
|
618
|
+
<span className="font-mono font-medium group-hover:text-indigo-600 transition-colors truncate flex-1">
|
|
619
|
+
{chunk.chunk_name}
|
|
620
|
+
</span>
|
|
621
|
+
<span className={`shrink-0 px-1.5 py-0.5 rounded text-xs ${typeClass}`}>
|
|
622
|
+
{chunk.chunk_type}
|
|
623
|
+
</span>
|
|
624
|
+
<span className="shrink-0 text-muted-foreground font-mono">
|
|
625
|
+
L{chunk.line_start}–{chunk.line_end}
|
|
626
|
+
</span>
|
|
627
|
+
{chunk.is_dead_code && (
|
|
628
|
+
<span className="shrink-0 text-amber-500 text-xs">dead</span>
|
|
629
|
+
)}
|
|
630
|
+
<ExternalLink className="h-3 w-3 shrink-0 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" />
|
|
631
|
+
</a>
|
|
632
|
+
)
|
|
633
|
+
})}
|
|
634
|
+
</div>
|
|
635
|
+
)
|
|
636
|
+
})()}
|
|
637
|
+
</CardContent>
|
|
638
|
+
</Card>
|
|
639
|
+
)
|
|
640
|
+
})}
|
|
641
|
+
</div>
|
|
642
|
+
)}
|
|
643
|
+
</div>
|
|
644
|
+
)
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// CIL[END chunk_id="cilfilelistpage_cilfilelistpage_1784193942"]
|