spine-framework 0.3.125 → 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 +169 -97
- package/.framework/cli/commands/generate.ts +82 -160
- 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} +147 -54
- package/.framework/functions/_shared/db.ts +80 -126
- package/.framework/functions/_shared/hash-api-key.ts +63 -0
- package/.framework/functions/_shared/index.ts +222 -347
- 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 +162 -14
- 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 +687 -533
- 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 +173 -145
- 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 +192 -115
- 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 +3 -3
- 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,787 @@
|
|
|
1
|
+
// CIL[BEGIN chunk_id="cilchunkdetailpage_module_header_1784193942" type="module_header" identity="module_header" parent="none"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Import dependencies and icons for the CIL chunk detail page"]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provides React hooks, router, apiFetch, app path hook, UI components, and lucide icons used by the page"]
|
|
4
|
+
// CIL[DOC-CONTEXT module="cortex:cil-chunk-detail" 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="none" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Imports useEffect, useState, useCallback, useParams, apiFetch, useAppPath, card/button/badge/skeleton/textarea/label/select/tabs 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 { Textarea } from '@core/components/ui/textarea'
|
|
24
|
+
import { Label } from '@core/components/ui/label'
|
|
25
|
+
import {
|
|
26
|
+
Select,
|
|
27
|
+
SelectContent,
|
|
28
|
+
SelectItem,
|
|
29
|
+
SelectTrigger,
|
|
30
|
+
SelectValue,
|
|
31
|
+
} from '@core/components/ui/select'
|
|
32
|
+
import {
|
|
33
|
+
Tabs,
|
|
34
|
+
TabsContent,
|
|
35
|
+
TabsList,
|
|
36
|
+
TabsTrigger,
|
|
37
|
+
} from '@core/components/ui/tabs'
|
|
38
|
+
import {
|
|
39
|
+
CheckCircle2,
|
|
40
|
+
XCircle,
|
|
41
|
+
AlertTriangle,
|
|
42
|
+
ChevronRight,
|
|
43
|
+
ArrowRight,
|
|
44
|
+
RefreshCw,
|
|
45
|
+
Save,
|
|
46
|
+
Zap,
|
|
47
|
+
FileCode2,
|
|
48
|
+
Hash,
|
|
49
|
+
TestTube2,
|
|
50
|
+
} from 'lucide-react'
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
import { PageInstructions } from '../../../components/admin/PageInstructions'
|
|
55
|
+
// CIL[END chunk_id="cilchunkdetailpage_module_header_1784193942"]
|
|
56
|
+
// CIL[BEGIN chunk_id="cilchunkdetailpage_chunkcontract_1784193942" type="interface" identity="ChunkContract" parent="none"]
|
|
57
|
+
// CIL[DOC-MACRO purpose="Define the shape of a chunk contract"]
|
|
58
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Declare the TypeScript interface representing an ingested code chunk and its metadata"]
|
|
59
|
+
// CIL[DOC-CONTEXT module="cortex:cil-chunk-detail" layer="presentation" related_files="[\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/schema-utils.ts\",\".framework/migrations/015_simplify_apps_table.sql\",\"\\\"]"]
|
|
60
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="ChunkContract type definition" errors="none" side_effects="none"]
|
|
61
|
+
// CIL[DOC-MICRO logic_summary="Describes id, name, file path, line range, type, macro/micro docs, input/output specs, side effects, stability, test paths, confidence fields, hash, dead-code flag, and caller/callee lists" notable_decisions="[]"]
|
|
62
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
63
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
64
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/schema-utils.ts, .framework/migrations/015_simplify_apps_table.sql, \."]
|
|
65
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
66
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
67
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
68
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
69
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
70
|
+
interface ChunkContract {
|
|
71
|
+
id: string
|
|
72
|
+
chunk_name: string
|
|
73
|
+
file_path: string
|
|
74
|
+
line_start: number
|
|
75
|
+
line_end: number
|
|
76
|
+
chunk_type: string
|
|
77
|
+
macro: string
|
|
78
|
+
micro: string
|
|
79
|
+
input_spec: string
|
|
80
|
+
output_spec: string
|
|
81
|
+
side_effects: string
|
|
82
|
+
stability: string
|
|
83
|
+
test_unit_path: string | null
|
|
84
|
+
test_e2e_path: string | null
|
|
85
|
+
doc_confidence: string
|
|
86
|
+
boundary_confidence: string
|
|
87
|
+
stored_hash: string | null
|
|
88
|
+
hash_status: string
|
|
89
|
+
is_dead_code: boolean
|
|
90
|
+
callers: { chunk_id: string; chunk_name: string; file_path: string }[]
|
|
91
|
+
callees: { chunk_id: string; chunk_name: string; file_path: string }[]
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// CIL[END chunk_id="cilchunkdetailpage_chunkcontract_1784193942"]
|
|
95
|
+
// CIL[BEGIN chunk_id="cilchunkdetailpage_embeddingstatus_1784193942" type="interface" identity="EmbeddingStatus" parent="none"]
|
|
96
|
+
// CIL[DOC-MACRO purpose="Define the shape of embedding coverage status"]
|
|
97
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for chunk embedding coverage"]
|
|
98
|
+
// CIL[DOC-CONTEXT module="cortex:cil-chunk-detail" layer="presentation" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
|
|
99
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="EmbeddingStatus type definition" errors="none" side_effects="none"]
|
|
100
|
+
// CIL[DOC-MICRO logic_summary="Declares coverage percentage and counts of embedded vs total chunks" 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: custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/pages/admin/RolesPage.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/IntegrationsPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
|
|
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 EmbeddingStatus {
|
|
110
|
+
coverage_pct: number
|
|
111
|
+
embedded_chunks: number
|
|
112
|
+
total_chunks: number
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
// CIL[END chunk_id="cilchunkdetailpage_embeddingstatus_1784193942"]
|
|
118
|
+
// CIL[BEGIN chunk_id="cilchunkdetailpage_doc_confidence_config_1784193942" type="constant" identity="DOC_CONFIDENCE_CONFIG" parent="none"]
|
|
119
|
+
// CIL[DOC-MACRO purpose="Map doc-confidence levels to badge labels, colors, and icons"]
|
|
120
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide display metadata for human_verified, ai_generated, and unverified_legacy confidence states"]
|
|
121
|
+
// CIL[DOC-CONTEXT module="cortex:cil-chunk-detail" layer="presentation" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/components/ui/table-primitives.tsx\",\"\\\"]"]
|
|
122
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Record<string, { label, color, icon }>" errors="none" side_effects="none"]
|
|
123
|
+
// CIL[DOC-MICRO logic_summary="Associates each confidence key with a UI label, Tailwind color class, and lucide icon component" notable_decisions="[]"]
|
|
124
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
125
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
126
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/RolesPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/components/ui/table-primitives.tsx, \."]
|
|
127
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
128
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
129
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
130
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
131
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
132
|
+
const DOC_CONFIDENCE_CONFIG: Record<string, { label: string; color: string; icon: React.ElementType }> = {
|
|
133
|
+
human_verified: { label: 'Human Verified', color: 'text-green-600', icon: CheckCircle2 },
|
|
134
|
+
ai_generated: { label: 'AI Generated', color: 'text-blue-600', icon: Zap },
|
|
135
|
+
unverified_legacy: { label: 'Unverified', color: 'text-amber-600', icon: AlertTriangle },
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// CIL[END chunk_id="cilchunkdetailpage_doc_confidence_config_1784193942"]
|
|
139
|
+
// CIL[BEGIN chunk_id="cilchunkdetailpage_stability_badge_1784193942" type="constant" identity="STABILITY_BADGE" parent="none"]
|
|
140
|
+
// CIL[DOC-MACRO purpose="Map stability levels to badge variants"]
|
|
141
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide Badge variant values for stable, internal, and experimental stability states"]
|
|
142
|
+
// CIL[DOC-CONTEXT module="cortex:cil-chunk-detail" layer="presentation" related_files="[\".framework/src/pages/admin/RolesPage.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/migrations/025_retype_threads_messages.sql\",\"\\\"]"]
|
|
143
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Record<string, Badge variant union>" errors="none" side_effects="none"]
|
|
144
|
+
// CIL[DOC-MICRO logic_summary="Maps stable to default, internal to secondary, and experimental to outline variant names" notable_decisions="[]"]
|
|
145
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
146
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
147
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/RolesPage.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/migrations/025_retype_threads_messages.sql, \."]
|
|
148
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
149
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
150
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
151
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
152
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
153
|
+
const STABILITY_BADGE: Record<string, 'default' | 'secondary' | 'outline'> = {
|
|
154
|
+
stable: 'default',
|
|
155
|
+
internal: 'secondary',
|
|
156
|
+
experimental: 'outline',
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// CIL[END chunk_id="cilchunkdetailpage_stability_badge_1784193942"]
|
|
160
|
+
// CIL[BEGIN chunk_id="cilchunkdetailpage_hashstatusbadge_1784193942" type="function" identity="HashStatusBadge" parent="none"]
|
|
161
|
+
// CIL[DOC-MACRO purpose="Render a badge indicating the current hash validation status"]
|
|
162
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display current, drift_detected, or unknown hash status as a Badge with icon"]
|
|
163
|
+
// CIL[DOC-CONTEXT module="cortex:cil-chunk-detail" layer="presentation" related_files="[]"]
|
|
164
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="none" side_effects="none"]
|
|
165
|
+
// CIL[DOC-MICRO logic_summary="Returns a green Current badge, a destructive Drift Detected badge, or a muted Unknown badge based on status value" notable_decisions="[]"]
|
|
166
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
167
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
168
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
169
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
170
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
171
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
172
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
173
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
174
|
+
function HashStatusBadge({ status }: { status: string }) {
|
|
175
|
+
if (status === 'current') return (
|
|
176
|
+
<Badge variant="default" className="bg-green-600 text-white gap-1">
|
|
177
|
+
<CheckCircle2 className="h-3 w-3" /> Current
|
|
178
|
+
</Badge>
|
|
179
|
+
)
|
|
180
|
+
if (status === 'drift_detected') return (
|
|
181
|
+
<Badge variant="destructive" className="gap-1">
|
|
182
|
+
<XCircle className="h-3 w-3" /> Drift Detected
|
|
183
|
+
</Badge>
|
|
184
|
+
)
|
|
185
|
+
return (
|
|
186
|
+
<Badge variant="outline" className="gap-1 text-muted-foreground">
|
|
187
|
+
<Hash className="h-3 w-3" /> Unknown
|
|
188
|
+
</Badge>
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
// CIL[END chunk_id="cilchunkdetailpage_hashstatusbadge_1784193942"]
|
|
195
|
+
// CIL[BEGIN chunk_id="cilchunkdetailpage_chunklinkcard_1784193942" type="function" identity="ChunkLinkCard" parent="none"]
|
|
196
|
+
// CIL[DOC-MACRO purpose="Render a navigable card linking to another chunk"]
|
|
197
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display chunk name and file path and link to the chunk detail route"]
|
|
198
|
+
// CIL[DOC-CONTEXT module="cortex:cil-chunk-detail" layer="presentation" related_files="[]"]
|
|
199
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="none" side_effects="none"]
|
|
200
|
+
// CIL[DOC-MICRO logic_summary="Builds a route via useAppPath and renders an anchor with icon, name, path, and hover arrow" notable_decisions="[]"]
|
|
201
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
202
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
203
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
204
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
205
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
206
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
207
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
208
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
209
|
+
function ChunkLinkCard({
|
|
210
|
+
chunk,
|
|
211
|
+
label,
|
|
212
|
+
projectId,
|
|
213
|
+
}: {
|
|
214
|
+
chunk: { chunk_id: string; chunk_name: string; file_path: string }
|
|
215
|
+
label: string
|
|
216
|
+
projectId: string
|
|
217
|
+
}) {
|
|
218
|
+
const appPath = (path: string) => '/spine-framework/admin' + (path.startsWith('/') ? path : '/' + path)
|
|
219
|
+
return (
|
|
220
|
+
<a
|
|
221
|
+
href={appPath(`/cil/${projectId}/chunks/${chunk.chunk_id}`)}
|
|
222
|
+
className="flex items-center gap-2 p-2 rounded-md border hover:bg-muted/50 transition-colors group text-sm"
|
|
223
|
+
>
|
|
224
|
+
<FileCode2 className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
|
|
225
|
+
<div className="flex-1 min-w-0">
|
|
226
|
+
<div className="font-mono font-medium truncate">{chunk.chunk_name}</div>
|
|
227
|
+
<div className="text-xs text-muted-foreground truncate">{chunk.file_path}</div>
|
|
228
|
+
</div>
|
|
229
|
+
<ArrowRight className="h-3 w-3 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity shrink-0" />
|
|
230
|
+
</a>
|
|
231
|
+
)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
// CIL[END chunk_id="cilchunkdetailpage_chunklinkcard_1784193942"]
|
|
237
|
+
// CIL[BEGIN chunk_id="cilchunkdetailpage_contracteditor_1784193942" type="function" identity="ContractEditor" parent="none"]
|
|
238
|
+
// CIL[DOC-MACRO purpose="Render and edit a chunk contract form"]
|
|
239
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a UI to edit macro, micro, specs, stability, test paths, and doc confidence, then persist via API"]
|
|
240
|
+
// CIL[DOC-CONTEXT module="cortex:cil-chunk-detail" layer="presentation" related_files="[]"]
|
|
241
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="none" side_effects="PATCH /api/admin-data; calls onSave callback to update parent contract"]
|
|
242
|
+
// CIL[DOC-MICRO logic_summary="Initializes form from contract, renders textarea fields and stability/confidence selects, saves changes, and shows saving/saved feedback" notable_decisions="[]"]
|
|
243
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
244
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
245
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
246
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
247
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
248
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
249
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
250
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
251
|
+
function ContractEditor({
|
|
252
|
+
contract,
|
|
253
|
+
projectId,
|
|
254
|
+
onSave,
|
|
255
|
+
}: {
|
|
256
|
+
contract: ChunkContract
|
|
257
|
+
projectId: string
|
|
258
|
+
onSave: (updated: Partial<ChunkContract>) => void
|
|
259
|
+
}) {
|
|
260
|
+
const [form, setForm] = useState({
|
|
261
|
+
macro: contract.macro || '',
|
|
262
|
+
micro: contract.micro || '',
|
|
263
|
+
input_spec: contract.input_spec || '',
|
|
264
|
+
output_spec: contract.output_spec || '',
|
|
265
|
+
side_effects: contract.side_effects || '',
|
|
266
|
+
stability: contract.stability || 'internal',
|
|
267
|
+
test_unit_path: contract.test_unit_path || '',
|
|
268
|
+
test_e2e_path: contract.test_e2e_path || '',
|
|
269
|
+
doc_confidence: contract.doc_confidence || 'unverified_legacy',
|
|
270
|
+
})
|
|
271
|
+
const [saving, setSaving] = useState(false)
|
|
272
|
+
const [saved, setSaved] = useState(false)
|
|
273
|
+
|
|
274
|
+
const handleSave = async () => {
|
|
275
|
+
setSaving(true)
|
|
276
|
+
try {
|
|
277
|
+
const res = await apiFetch(`/api/admin-data?id=${contract.id}`, {
|
|
278
|
+
method: 'PATCH',
|
|
279
|
+
headers: { 'Content-Type': 'application/json' },
|
|
280
|
+
body: JSON.stringify({
|
|
281
|
+
entity: 'items',
|
|
282
|
+
data: {
|
|
283
|
+
...form,
|
|
284
|
+
test_unit_path: form.test_unit_path || null,
|
|
285
|
+
test_e2e_path: form.test_e2e_path || null,
|
|
286
|
+
},
|
|
287
|
+
}),
|
|
288
|
+
})
|
|
289
|
+
if (res.ok) {
|
|
290
|
+
setSaved(true)
|
|
291
|
+
onSave(form)
|
|
292
|
+
setTimeout(() => setSaved(false), 2000)
|
|
293
|
+
}
|
|
294
|
+
} finally {
|
|
295
|
+
setSaving(false)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const field = (
|
|
300
|
+
key: keyof typeof form,
|
|
301
|
+
label: string,
|
|
302
|
+
placeholder: string,
|
|
303
|
+
rows = 2
|
|
304
|
+
) => (
|
|
305
|
+
<div className="space-y-1">
|
|
306
|
+
<Label className="text-xs font-medium">{label}</Label>
|
|
307
|
+
<Textarea
|
|
308
|
+
value={form[key] as string}
|
|
309
|
+
onChange={e => setForm(f => ({ ...f, [key]: e.target.value }))}
|
|
310
|
+
placeholder={placeholder}
|
|
311
|
+
rows={rows}
|
|
312
|
+
className="text-sm font-mono resize-none"
|
|
313
|
+
/>
|
|
314
|
+
</div>
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
return (
|
|
318
|
+
<div className="space-y-4">
|
|
319
|
+
{field('macro', 'Macro (Purpose — one sentence)', 'What this chunk IS and its primary responsibility', 2)}
|
|
320
|
+
{field('micro', 'Micro (Implementation detail)', 'How it does it — key algorithm, pattern, or approach', 2)}
|
|
321
|
+
{field('input_spec', 'Inputs', 'Parameter names, types, constraints (one per line)', 3)}
|
|
322
|
+
{field('output_spec', 'Returns', 'Return type and shape description', 2)}
|
|
323
|
+
{field('side_effects', 'Side Effects', 'DB writes, API calls, file I/O, mutations, thrown errors', 2)}
|
|
324
|
+
{field('test_unit_path', 'Unit Test Path', 'Relative path to unit test file (e.g. src/__tests__/foo.test.ts)', 1)}
|
|
325
|
+
{field('test_e2e_path', 'E2E Test Path', 'Relative path to e2e test file', 1)}
|
|
326
|
+
|
|
327
|
+
<div className="grid grid-cols-2 gap-3">
|
|
328
|
+
<div className="space-y-1">
|
|
329
|
+
<Label className="text-xs font-medium">Stability</Label>
|
|
330
|
+
<Select value={form.stability} onValueChange={v => setForm(f => ({ ...f, stability: v }))}>
|
|
331
|
+
<SelectTrigger className="h-8 text-sm">
|
|
332
|
+
<SelectValue />
|
|
333
|
+
</SelectTrigger>
|
|
334
|
+
<SelectContent>
|
|
335
|
+
<SelectItem value="stable">Stable</SelectItem>
|
|
336
|
+
<SelectItem value="internal">Internal</SelectItem>
|
|
337
|
+
<SelectItem value="experimental">Experimental</SelectItem>
|
|
338
|
+
</SelectContent>
|
|
339
|
+
</Select>
|
|
340
|
+
</div>
|
|
341
|
+
<div className="space-y-1">
|
|
342
|
+
<Label className="text-xs font-medium">Doc Confidence</Label>
|
|
343
|
+
<Select value={form.doc_confidence} onValueChange={v => setForm(f => ({ ...f, doc_confidence: v }))}>
|
|
344
|
+
<SelectTrigger className="h-8 text-sm">
|
|
345
|
+
<SelectValue />
|
|
346
|
+
</SelectTrigger>
|
|
347
|
+
<SelectContent>
|
|
348
|
+
<SelectItem value="human_verified">Human Verified</SelectItem>
|
|
349
|
+
<SelectItem value="ai_generated">AI Generated</SelectItem>
|
|
350
|
+
<SelectItem value="unverified_legacy">Unverified Legacy</SelectItem>
|
|
351
|
+
</SelectContent>
|
|
352
|
+
</Select>
|
|
353
|
+
</div>
|
|
354
|
+
</div>
|
|
355
|
+
|
|
356
|
+
<Button onClick={handleSave} disabled={saving} className="w-full">
|
|
357
|
+
{saving ? (
|
|
358
|
+
<><RefreshCw className="h-3 w-3 mr-2 animate-spin" /> Saving…</>
|
|
359
|
+
) : saved ? (
|
|
360
|
+
<><CheckCircle2 className="h-3 w-3 mr-2 text-green-400" /> Saved</>
|
|
361
|
+
) : (
|
|
362
|
+
<><Save className="h-3 w-3 mr-2" /> Save Contract</>
|
|
363
|
+
)}
|
|
364
|
+
</Button>
|
|
365
|
+
</div>
|
|
366
|
+
)
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
// CIL[END chunk_id="cilchunkdetailpage_contracteditor_1784193942"]
|
|
372
|
+
// CIL[BEGIN chunk_id="cilchunkdetailpage_cilchunkdetailpage_1784193942" type="component" identity="CILChunkDetailPage" parent="none"]
|
|
373
|
+
// CIL[DOC-MACRO purpose="Render the CIL chunk detail page"]
|
|
374
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Fetch and display a single chunk contract, code content, graph, and blast radius; support hash validation, embedding, and contract editing"]
|
|
375
|
+
// CIL[DOC-CONTEXT module="cortex:cil-chunk-detail" layer="presentation" related_files="[]"]
|
|
376
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="Renders loading skeleton or not found message; API errors swallowed" side_effects="GET /api/cil-graph, GET /api/admin-data, POST /api/cil-validate, POST /api/cil-embeddings; updates local contract, codeContent, hashStatus, embedResult, blastRadius"]
|
|
377
|
+
// CIL[DOC-MICRO logic_summary="Loads chunk contract and stored code, renders header with stability/hash/doc badges, action buttons, and Tabs for contract, graph, code, and blast radius; uses HashStatusBadge, ChunkLinkCard, and ContractEditor subcomponents" notable_decisions="[]"]
|
|
378
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
379
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
380
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
381
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
382
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
383
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
384
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
385
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
386
|
+
export default function CILChunkDetailPage() {
|
|
387
|
+
const { id: projectId, chunkId } = useParams<{ id: string; chunkId: string }>()
|
|
388
|
+
const appPath = (path: string) => '/spine-framework/admin' + (path.startsWith('/') ? path : '/' + path)
|
|
389
|
+
const [contract, setContract] = useState<ChunkContract | null>(null)
|
|
390
|
+
const [codeContent, setCodeContent] = useState<string>('')
|
|
391
|
+
const [loading, setLoading] = useState(true)
|
|
392
|
+
const [validating, setValidating] = useState(false)
|
|
393
|
+
const [hashStatus, setHashStatus] = useState<string>('unknown')
|
|
394
|
+
const [embedding, setEmbedding] = useState(false)
|
|
395
|
+
const [embedResult, setEmbedResult] = useState<string | null>(null)
|
|
396
|
+
const [blastRadius, setBlastRadius] = useState<any[] | null>(null)
|
|
397
|
+
const [loadingBlast, setLoadingBlast] = useState(false)
|
|
398
|
+
|
|
399
|
+
const loadChunk = useCallback(async () => {
|
|
400
|
+
if (!chunkId) return
|
|
401
|
+
setLoading(true)
|
|
402
|
+
try {
|
|
403
|
+
const res = await apiFetch(`/api/cil-graph?action=get_chunk_contract&chunk_id=${chunkId}`)
|
|
404
|
+
const data = await res.json()
|
|
405
|
+
const c = data?.contract || data?.data?.contract
|
|
406
|
+
if (c) {
|
|
407
|
+
setContract(c)
|
|
408
|
+
setHashStatus(c.hash_status || 'unknown')
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
const itemRes = await apiFetch(`/api/admin-data?action=get&entity=items&id=${c.id}`)
|
|
413
|
+
const itemData = await itemRes.json()
|
|
414
|
+
const item = itemData?.data || itemData
|
|
415
|
+
setCodeContent(item?.data?.code_content || '')
|
|
416
|
+
} catch {
|
|
417
|
+
} finally {
|
|
418
|
+
setLoading(false)
|
|
419
|
+
}
|
|
420
|
+
}, [chunkId])
|
|
421
|
+
|
|
422
|
+
useEffect(() => { loadChunk() }, [loadChunk])
|
|
423
|
+
|
|
424
|
+
const handleValidate = async () => {
|
|
425
|
+
if (!chunkId || !contract || !codeContent) return
|
|
426
|
+
setValidating(true)
|
|
427
|
+
try {
|
|
428
|
+
const res = await apiFetch('/api/cil-validate?action=validate', {
|
|
429
|
+
method: 'POST',
|
|
430
|
+
headers: { 'Content-Type': 'application/json' },
|
|
431
|
+
body: JSON.stringify({
|
|
432
|
+
chunks: [{ chunk_id: contract.id, chunk_name: contract.chunk_name, content: codeContent }],
|
|
433
|
+
}),
|
|
434
|
+
})
|
|
435
|
+
const data = await res.json()
|
|
436
|
+
const result = (data?.results || data?.data?.results)?.[0]
|
|
437
|
+
if (result) setHashStatus(result.status)
|
|
438
|
+
} finally {
|
|
439
|
+
setValidating(false)
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const handleEmbed = async () => {
|
|
444
|
+
if (!chunkId) return
|
|
445
|
+
setEmbedding(true)
|
|
446
|
+
setEmbedResult(null)
|
|
447
|
+
try {
|
|
448
|
+
const res = await apiFetch('/api/cil-embeddings?action=embed_chunk', {
|
|
449
|
+
method: 'POST',
|
|
450
|
+
headers: { 'Content-Type': 'application/json' },
|
|
451
|
+
body: JSON.stringify({ chunk_id: contract?.id || chunkId, force_regenerate: false }),
|
|
452
|
+
})
|
|
453
|
+
const data = await res.json()
|
|
454
|
+
const r = data?.data || data
|
|
455
|
+
if (r?.created?.length) {
|
|
456
|
+
setEmbedResult(`Generated ${r.created.length} vector(s): ${r.created.join(', ')}`)
|
|
457
|
+
} else if (r?.skipped?.length) {
|
|
458
|
+
setEmbedResult(`Already current — ${r.skipped.length} vector(s) unchanged`)
|
|
459
|
+
} else {
|
|
460
|
+
setEmbedResult('Embedding complete')
|
|
461
|
+
}
|
|
462
|
+
} catch (err) {
|
|
463
|
+
setEmbedResult(`Error: ${err}`)
|
|
464
|
+
} finally {
|
|
465
|
+
setEmbedding(false)
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
const handleBlastRadius = async () => {
|
|
470
|
+
if (!chunkId) return
|
|
471
|
+
setLoadingBlast(true)
|
|
472
|
+
try {
|
|
473
|
+
const res = await apiFetch(`/api/cil-graph?action=get_blast_radius&chunk_id=${contract?.id || chunkId}&max_depth=3`)
|
|
474
|
+
const data = await res.json()
|
|
475
|
+
setBlastRadius((data?.affected || data?.data?.affected) ?? [])
|
|
476
|
+
} finally {
|
|
477
|
+
setLoadingBlast(false)
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (loading) {
|
|
482
|
+
return (
|
|
483
|
+
<div className="p-6 space-y-4">
|
|
484
|
+
<Skeleton className="h-6 w-48" />
|
|
485
|
+
<Skeleton className="h-8 w-96" />
|
|
486
|
+
<div className="grid grid-cols-3 gap-4">
|
|
487
|
+
<Skeleton className="h-32" />
|
|
488
|
+
<Skeleton className="h-32" />
|
|
489
|
+
<Skeleton className="h-32" />
|
|
490
|
+
</div>
|
|
491
|
+
</div>
|
|
492
|
+
)
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
if (!contract) {
|
|
496
|
+
return <div className="p-6 text-muted-foreground text-center">Chunk not found.</div>
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
const docCfg = DOC_CONFIDENCE_CONFIG[contract.doc_confidence] || DOC_CONFIDENCE_CONFIG.unverified_legacy
|
|
500
|
+
const DocIcon = docCfg.icon
|
|
501
|
+
|
|
502
|
+
return (
|
|
503
|
+
<div className="p-6 space-y-5 max-w-5xl">
|
|
504
|
+
{}
|
|
505
|
+
<div className="flex items-center gap-2 text-sm text-muted-foreground flex-wrap">
|
|
506
|
+
<a href={appPath('/cil')} className="hover:underline">Code Intelligence</a>
|
|
507
|
+
<ChevronRight className="h-3 w-3" />
|
|
508
|
+
<a href={appPath(`/cil/${projectId}/ingest`)} className="hover:underline">Project</a>
|
|
509
|
+
<ChevronRight className="h-3 w-3" />
|
|
510
|
+
<span className="font-mono">{contract.chunk_name}</span>
|
|
511
|
+
</div>
|
|
512
|
+
|
|
513
|
+
{}
|
|
514
|
+
<div className="flex items-start justify-between gap-4 flex-wrap">
|
|
515
|
+
<div>
|
|
516
|
+
<h1 className="text-xl font-bold font-mono">{contract.chunk_name}</h1>
|
|
517
|
+
<p className="text-xs text-muted-foreground mt-0.5 font-mono">
|
|
518
|
+
{contract.file_path} · L{contract.line_start}–{contract.line_end}
|
|
519
|
+
</p>
|
|
520
|
+
</div>
|
|
521
|
+
<div className="flex items-center gap-2 flex-wrap">
|
|
522
|
+
<Badge variant={STABILITY_BADGE[contract.stability] || 'outline'}>
|
|
523
|
+
{contract.stability}
|
|
524
|
+
</Badge>
|
|
525
|
+
<Badge variant="secondary">{contract.chunk_type}</Badge>
|
|
526
|
+
<Badge variant={contract.is_dead_code ? 'destructive' : 'outline'}>
|
|
527
|
+
{contract.is_dead_code ? 'Dead Code' : 'Active'}
|
|
528
|
+
</Badge>
|
|
529
|
+
<span className={`flex items-center gap-1 text-xs ${docCfg.color}`}>
|
|
530
|
+
<DocIcon className="h-3.5 w-3.5" />
|
|
531
|
+
{docCfg.label}
|
|
532
|
+
</span>
|
|
533
|
+
</div>
|
|
534
|
+
</div>
|
|
535
|
+
|
|
536
|
+
<PageInstructions
|
|
537
|
+
description="Inspect a single CIL chunk, its contract, and its relationships."
|
|
538
|
+
sections={[
|
|
539
|
+
{ title: 'What this page is for', content: 'This page displays one indexed code chunk, including its contract, code, call graph, and hash/embed status.' },
|
|
540
|
+
{ title: 'How to read this page', content: 'The Contract tab shows macro and micro summaries plus documentation status. The Graph tab lists callers and callees. The Code tab shows the source. Blast Radius appears after calculation.' },
|
|
541
|
+
{ title: 'How to use this page', content: 'Click Validate Hash to confirm the stored hash matches the current file contents. Click Embed Chunk to regenerate its vector embeddings. Click Blast Radius to see impacted chunks.' },
|
|
542
|
+
{ title: 'Important notes', content: 'Dead-code chunks are marked with a destructive badge. Documentation coverage is shown as AI-generated, human-verified, or undocumented.' },
|
|
543
|
+
]}
|
|
544
|
+
/>
|
|
545
|
+
|
|
546
|
+
{}
|
|
547
|
+
<div className="flex items-center gap-3 flex-wrap">
|
|
548
|
+
<HashStatusBadge status={hashStatus} />
|
|
549
|
+
<Button
|
|
550
|
+
size="sm"
|
|
551
|
+
variant="outline"
|
|
552
|
+
onClick={handleValidate}
|
|
553
|
+
disabled={validating || !codeContent}
|
|
554
|
+
className="h-7 text-xs"
|
|
555
|
+
>
|
|
556
|
+
{validating ? <RefreshCw className="h-3 w-3 mr-1 animate-spin" /> : <Hash className="h-3 w-3 mr-1" />}
|
|
557
|
+
Validate Hash
|
|
558
|
+
</Button>
|
|
559
|
+
<Button
|
|
560
|
+
size="sm"
|
|
561
|
+
variant="outline"
|
|
562
|
+
onClick={handleEmbed}
|
|
563
|
+
disabled={embedding}
|
|
564
|
+
className="h-7 text-xs"
|
|
565
|
+
>
|
|
566
|
+
{embedding ? <RefreshCw className="h-3 w-3 mr-1 animate-spin" /> : <Zap className="h-3 w-3 mr-1" />}
|
|
567
|
+
Embed Chunk
|
|
568
|
+
</Button>
|
|
569
|
+
<Button
|
|
570
|
+
size="sm"
|
|
571
|
+
variant="outline"
|
|
572
|
+
onClick={handleBlastRadius}
|
|
573
|
+
disabled={loadingBlast}
|
|
574
|
+
className="h-7 text-xs"
|
|
575
|
+
>
|
|
576
|
+
{loadingBlast ? <RefreshCw className="h-3 w-3 mr-1 animate-spin" /> : <AlertTriangle className="h-3 w-3 mr-1" />}
|
|
577
|
+
Blast Radius
|
|
578
|
+
</Button>
|
|
579
|
+
{embedResult && (
|
|
580
|
+
<span className="text-xs text-muted-foreground">{embedResult}</span>
|
|
581
|
+
)}
|
|
582
|
+
</div>
|
|
583
|
+
|
|
584
|
+
<Tabs defaultValue="contract">
|
|
585
|
+
<TabsList>
|
|
586
|
+
<TabsTrigger value="contract">Contract</TabsTrigger>
|
|
587
|
+
<TabsTrigger value="graph">
|
|
588
|
+
Graph
|
|
589
|
+
{(contract.callers.length + contract.callees.length) > 0 && (
|
|
590
|
+
<span className="ml-1.5 bg-primary/15 text-primary text-xs rounded-full px-1.5 py-0.5 leading-none">
|
|
591
|
+
{contract.callers.length + contract.callees.length}
|
|
592
|
+
</span>
|
|
593
|
+
)}
|
|
594
|
+
</TabsTrigger>
|
|
595
|
+
<TabsTrigger value="code">Code</TabsTrigger>
|
|
596
|
+
{blastRadius !== null && (
|
|
597
|
+
<TabsTrigger value="blast">
|
|
598
|
+
Blast Radius
|
|
599
|
+
{blastRadius.length > 0 && (
|
|
600
|
+
<span className="ml-1.5 bg-red-100 text-red-700 text-xs rounded-full px-1.5 py-0.5 leading-none">
|
|
601
|
+
{blastRadius.length}
|
|
602
|
+
</span>
|
|
603
|
+
)}
|
|
604
|
+
</TabsTrigger>
|
|
605
|
+
)}
|
|
606
|
+
</TabsList>
|
|
607
|
+
|
|
608
|
+
{}
|
|
609
|
+
<TabsContent value="contract" className="mt-4 space-y-4">
|
|
610
|
+
{}
|
|
611
|
+
{(contract.macro || contract.micro) && (
|
|
612
|
+
<Card>
|
|
613
|
+
<CardContent className="pt-4 space-y-2">
|
|
614
|
+
{contract.macro && (
|
|
615
|
+
<p className="text-sm"><span className="font-medium text-muted-foreground">Purpose: </span>{contract.macro}</p>
|
|
616
|
+
)}
|
|
617
|
+
{contract.micro && (
|
|
618
|
+
<p className="text-sm"><span className="font-medium text-muted-foreground">Detail: </span>{contract.micro}</p>
|
|
619
|
+
)}
|
|
620
|
+
</CardContent>
|
|
621
|
+
</Card>
|
|
622
|
+
)}
|
|
623
|
+
|
|
624
|
+
{}
|
|
625
|
+
{(contract.input_spec || contract.output_spec || contract.side_effects) && (
|
|
626
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
|
|
627
|
+
{contract.input_spec && (
|
|
628
|
+
<Card>
|
|
629
|
+
<CardHeader className="pb-1 pt-3">
|
|
630
|
+
<CardTitle className="text-xs text-muted-foreground uppercase tracking-wide">Inputs</CardTitle>
|
|
631
|
+
</CardHeader>
|
|
632
|
+
<CardContent className="pb-3">
|
|
633
|
+
<pre className="text-xs font-mono whitespace-pre-wrap">{contract.input_spec}</pre>
|
|
634
|
+
</CardContent>
|
|
635
|
+
</Card>
|
|
636
|
+
)}
|
|
637
|
+
{contract.output_spec && (
|
|
638
|
+
<Card>
|
|
639
|
+
<CardHeader className="pb-1 pt-3">
|
|
640
|
+
<CardTitle className="text-xs text-muted-foreground uppercase tracking-wide">Returns</CardTitle>
|
|
641
|
+
</CardHeader>
|
|
642
|
+
<CardContent className="pb-3">
|
|
643
|
+
<pre className="text-xs font-mono whitespace-pre-wrap">{contract.output_spec}</pre>
|
|
644
|
+
</CardContent>
|
|
645
|
+
</Card>
|
|
646
|
+
)}
|
|
647
|
+
{contract.side_effects && (
|
|
648
|
+
<Card>
|
|
649
|
+
<CardHeader className="pb-1 pt-3">
|
|
650
|
+
<CardTitle className="text-xs text-muted-foreground uppercase tracking-wide">Side Effects</CardTitle>
|
|
651
|
+
</CardHeader>
|
|
652
|
+
<CardContent className="pb-3">
|
|
653
|
+
<pre className="text-xs font-mono whitespace-pre-wrap">{contract.side_effects}</pre>
|
|
654
|
+
</CardContent>
|
|
655
|
+
</Card>
|
|
656
|
+
)}
|
|
657
|
+
</div>
|
|
658
|
+
)}
|
|
659
|
+
|
|
660
|
+
{}
|
|
661
|
+
{(contract.test_unit_path || contract.test_e2e_path) && (
|
|
662
|
+
<Card>
|
|
663
|
+
<CardHeader className="pb-1 pt-3">
|
|
664
|
+
<CardTitle className="text-xs text-muted-foreground uppercase tracking-wide flex items-center gap-1">
|
|
665
|
+
<TestTube2 className="h-3 w-3" /> Tests
|
|
666
|
+
</CardTitle>
|
|
667
|
+
</CardHeader>
|
|
668
|
+
<CardContent className="pb-3 space-y-1">
|
|
669
|
+
{contract.test_unit_path && (
|
|
670
|
+
<p className="text-xs font-mono">Unit: {contract.test_unit_path}</p>
|
|
671
|
+
)}
|
|
672
|
+
{contract.test_e2e_path && (
|
|
673
|
+
<p className="text-xs font-mono">E2E: {contract.test_e2e_path}</p>
|
|
674
|
+
)}
|
|
675
|
+
</CardContent>
|
|
676
|
+
</Card>
|
|
677
|
+
)}
|
|
678
|
+
|
|
679
|
+
{}
|
|
680
|
+
<Card>
|
|
681
|
+
<CardHeader className="pb-2">
|
|
682
|
+
<CardTitle className="text-sm">Edit Contract</CardTitle>
|
|
683
|
+
</CardHeader>
|
|
684
|
+
<CardContent>
|
|
685
|
+
<ContractEditor
|
|
686
|
+
contract={contract}
|
|
687
|
+
projectId={projectId!}
|
|
688
|
+
onSave={updated => setContract(c => c ? { ...c, ...updated } : c)}
|
|
689
|
+
/>
|
|
690
|
+
</CardContent>
|
|
691
|
+
</Card>
|
|
692
|
+
</TabsContent>
|
|
693
|
+
|
|
694
|
+
{}
|
|
695
|
+
<TabsContent value="graph" className="mt-4">
|
|
696
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
697
|
+
<Card>
|
|
698
|
+
<CardHeader className="pb-2">
|
|
699
|
+
<CardTitle className="text-sm">Called By ({contract.callers.length})</CardTitle>
|
|
700
|
+
</CardHeader>
|
|
701
|
+
<CardContent className="space-y-1.5">
|
|
702
|
+
{contract.callers.length === 0 ? (
|
|
703
|
+
<p className="text-xs text-muted-foreground">No callers recorded — may be an entrypoint or dead code</p>
|
|
704
|
+
) : (
|
|
705
|
+
contract.callers.map(c => (
|
|
706
|
+
<ChunkLinkCard key={c.chunk_id} chunk={c} label="caller" projectId={projectId!} />
|
|
707
|
+
))
|
|
708
|
+
)}
|
|
709
|
+
</CardContent>
|
|
710
|
+
</Card>
|
|
711
|
+
|
|
712
|
+
<Card>
|
|
713
|
+
<CardHeader className="pb-2">
|
|
714
|
+
<CardTitle className="text-sm">Calls ({contract.callees.length})</CardTitle>
|
|
715
|
+
</CardHeader>
|
|
716
|
+
<CardContent className="space-y-1.5">
|
|
717
|
+
{contract.callees.length === 0 ? (
|
|
718
|
+
<p className="text-xs text-muted-foreground">No outgoing calls recorded</p>
|
|
719
|
+
) : (
|
|
720
|
+
contract.callees.map(c => (
|
|
721
|
+
<ChunkLinkCard key={c.chunk_id} chunk={c} label="callee" projectId={projectId!} />
|
|
722
|
+
))
|
|
723
|
+
)}
|
|
724
|
+
</CardContent>
|
|
725
|
+
</Card>
|
|
726
|
+
</div>
|
|
727
|
+
</TabsContent>
|
|
728
|
+
|
|
729
|
+
{}
|
|
730
|
+
<TabsContent value="code" className="mt-4">
|
|
731
|
+
<Card>
|
|
732
|
+
<CardHeader className="pb-2">
|
|
733
|
+
<div className="flex items-center justify-between">
|
|
734
|
+
<CardTitle className="text-sm font-mono">{contract.chunk_name}</CardTitle>
|
|
735
|
+
<span className="text-xs text-muted-foreground">
|
|
736
|
+
L{contract.line_start}–{contract.line_end} · {contract.chunk_type}
|
|
737
|
+
</span>
|
|
738
|
+
</div>
|
|
739
|
+
</CardHeader>
|
|
740
|
+
<CardContent>
|
|
741
|
+
{codeContent ? (
|
|
742
|
+
<pre className="text-xs font-mono bg-muted rounded-md p-3 overflow-auto max-h-[60vh] whitespace-pre">
|
|
743
|
+
{codeContent}
|
|
744
|
+
</pre>
|
|
745
|
+
) : (
|
|
746
|
+
<p className="text-xs text-muted-foreground">
|
|
747
|
+
Code content not stored — run Pass 2 ingestion to capture chunk source.
|
|
748
|
+
</p>
|
|
749
|
+
)}
|
|
750
|
+
</CardContent>
|
|
751
|
+
</Card>
|
|
752
|
+
</TabsContent>
|
|
753
|
+
|
|
754
|
+
{}
|
|
755
|
+
{blastRadius !== null && (
|
|
756
|
+
<TabsContent value="blast" className="mt-4">
|
|
757
|
+
<Card>
|
|
758
|
+
<CardHeader className="pb-2">
|
|
759
|
+
<CardTitle className="text-sm">
|
|
760
|
+
Blast Radius — {blastRadius.length} chunk{blastRadius.length !== 1 ? 's' : ''} affected
|
|
761
|
+
</CardTitle>
|
|
762
|
+
</CardHeader>
|
|
763
|
+
<CardContent>
|
|
764
|
+
{blastRadius.length === 0 ? (
|
|
765
|
+
<p className="text-xs text-muted-foreground">No callers — change to this chunk has no upstream blast radius</p>
|
|
766
|
+
) : (
|
|
767
|
+
<div className="space-y-1.5">
|
|
768
|
+
{blastRadius.map((item: any) => (
|
|
769
|
+
<div key={item.chunk_id} className="flex items-center gap-2 text-sm">
|
|
770
|
+
<span className="text-xs bg-red-100 text-red-700 rounded px-1.5 py-0.5 font-mono shrink-0">
|
|
771
|
+
depth {item.depth}
|
|
772
|
+
</span>
|
|
773
|
+
<ChunkLinkCard chunk={item} label="affected" projectId={projectId!} />
|
|
774
|
+
</div>
|
|
775
|
+
))}
|
|
776
|
+
</div>
|
|
777
|
+
)}
|
|
778
|
+
</CardContent>
|
|
779
|
+
</Card>
|
|
780
|
+
</TabsContent>
|
|
781
|
+
)}
|
|
782
|
+
</Tabs>
|
|
783
|
+
</div>
|
|
784
|
+
)
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// CIL[END chunk_id="cilchunkdetailpage_cilchunkdetailpage_1784193942"]
|