spine-framework 0.3.125 → 0.3.127
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 -161
- 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,731 @@
|
|
|
1
|
+
|
|
2
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_module_header_1784191730" type="module_header" identity="module_header" parent="none"]
|
|
3
|
+
// CIL[DOC-MACRO purpose="Import dependencies for FlexiblePipelinePage.tsx"]
|
|
4
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Set up module imports and external references"]
|
|
5
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\"\\\"]"]
|
|
6
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="module imports" errors="none" side_effects="none"]
|
|
7
|
+
// CIL[DOC-MICRO logic_summary="Imports React hooks, router, apiFetch, UI components, and icons" notable_decisions="[]"]
|
|
8
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
9
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
10
|
+
// CIL[DOC-AUDIENCE audience="developer"]
|
|
11
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/functions/_shared/schema-utils.ts, custom/apps/portal/pages/ContentPage.tsx, \."]
|
|
12
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
13
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
14
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
15
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
16
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
17
|
+
import { useEffect, useState, useCallback } from 'react'
|
|
18
|
+
import { useParams } from 'react-router-dom'
|
|
19
|
+
import { apiFetch } from '@core/lib/api'
|
|
20
|
+
import { Card, CardContent, CardHeader, CardTitle } from '@core/components/ui/card'
|
|
21
|
+
import { Button } from '@core/components/ui/button'
|
|
22
|
+
import { Badge } from '@core/components/ui/badge'
|
|
23
|
+
import { Skeleton } from '@core/components/ui/skeleton'
|
|
24
|
+
import { Progress } from '@core/components/ui/progress'
|
|
25
|
+
import { Alert, AlertDescription } from '@core/components/ui/alert'
|
|
26
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@core/components/ui/tabs'
|
|
27
|
+
import {
|
|
28
|
+
CheckCircle2,
|
|
29
|
+
RefreshCw,
|
|
30
|
+
Play,
|
|
31
|
+
AlertTriangle,
|
|
32
|
+
TrendingUp,
|
|
33
|
+
GitBranch,
|
|
34
|
+
Clock,
|
|
35
|
+
FileText,
|
|
36
|
+
Zap,
|
|
37
|
+
Sparkles,
|
|
38
|
+
Info,
|
|
39
|
+
ChevronRight,
|
|
40
|
+
ChevronDown,
|
|
41
|
+
Folder,
|
|
42
|
+
FileCode2,
|
|
43
|
+
} from 'lucide-react'
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
import { PageInstructions } from '../../../components/admin/PageInstructions'
|
|
47
|
+
// CIL[END chunk_id="flexiblepipelinepage_module_header_1784191730"]
|
|
48
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_filepipelinestate_1784191730" type="interface" identity="FilePipelineState" parent="none"]
|
|
49
|
+
// CIL[DOC-MACRO purpose="Define the FilePipelineState data shape"]
|
|
50
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for file pipeline state"]
|
|
51
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
52
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="FilePipelineState type definition" errors="none" side_effects="none"]
|
|
53
|
+
// CIL[DOC-MICRO logic_summary="Declares file path, status, completed/ready/blocked steps, and progress percentage" notable_decisions="[]"]
|
|
54
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
55
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
56
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
|
|
57
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
58
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
59
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
60
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
61
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
62
|
+
interface FilePipelineState {
|
|
63
|
+
file_path: string
|
|
64
|
+
current_status: string
|
|
65
|
+
completed_steps: number[]
|
|
66
|
+
ready_for: number[]
|
|
67
|
+
blocked_by: number[]
|
|
68
|
+
progress_percentage: number
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// CIL[END chunk_id="flexiblepipelinepage_filepipelinestate_1784191730"]
|
|
72
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_pipelinestatus_1784191730" type="interface" identity="PipelineStatus" parent="none"]
|
|
73
|
+
// CIL[DOC-MACRO purpose="Define the PipelineStatus data shape"]
|
|
74
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for overall pipeline status"]
|
|
75
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
76
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="PipelineStatus type definition" errors="none" side_effects="none"]
|
|
77
|
+
// CIL[DOC-MICRO logic_summary="Declares project id, files array, step summary, and overall progress" notable_decisions="[]"]
|
|
78
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
79
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
80
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
|
|
81
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
82
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
83
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
84
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
85
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
86
|
+
interface PipelineStatus {
|
|
87
|
+
project_id: string
|
|
88
|
+
files: FilePipelineState[]
|
|
89
|
+
step_summary: Record<number, { completed: number; pending: number; in_progress: number }>
|
|
90
|
+
overall_progress: number
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// CIL[END chunk_id="flexiblepipelinepage_pipelinestatus_1784191730"]
|
|
94
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_filesreadyforstep_1784191730" type="interface" identity="FilesReadyForStep" parent="none"]
|
|
95
|
+
// CIL[DOC-MACRO purpose="Define the FilesReadyForStep data shape"]
|
|
96
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for step-ready files"]
|
|
97
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
98
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="FilesReadyForStep type definition" errors="none" side_effects="none"]
|
|
99
|
+
// CIL[DOC-MICRO logic_summary="Declares step metadata and an array of file readiness records" notable_decisions="[]"]
|
|
100
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
101
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
102
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
|
|
103
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
104
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
105
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
106
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
107
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
108
|
+
interface FilesReadyForStep {
|
|
109
|
+
ok: boolean
|
|
110
|
+
project_id: string
|
|
111
|
+
step: number
|
|
112
|
+
step_name: string
|
|
113
|
+
prerequisites: number[]
|
|
114
|
+
target_status: string
|
|
115
|
+
file_count: number
|
|
116
|
+
files: Array<{
|
|
117
|
+
file_path: string
|
|
118
|
+
status: string
|
|
119
|
+
chunk_count: number
|
|
120
|
+
completed_steps: number[]
|
|
121
|
+
ready_for: number[]
|
|
122
|
+
blocked_by: number[]
|
|
123
|
+
can_proceed: boolean
|
|
124
|
+
blocking_reasons: string[]
|
|
125
|
+
}>
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// CIL[END chunk_id="flexiblepipelinepage_filesreadyforstep_1784191730"]
|
|
129
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_bottleneckanalysis_1784191730" type="interface" identity="BottleneckAnalysis" parent="none"]
|
|
130
|
+
// CIL[DOC-MACRO purpose="Define the BottleneckAnalysis data shape"]
|
|
131
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for bottleneck analysis"]
|
|
132
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
133
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="BottleneckAnalysis type definition" errors="none" side_effects="none"]
|
|
134
|
+
// CIL[DOC-MICRO logic_summary="Declares bottlenecks, recommendations, optimal processing order, and summary" notable_decisions="[]"]
|
|
135
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
136
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
137
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
|
|
138
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
139
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
140
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
141
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
142
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
143
|
+
interface BottleneckAnalysis {
|
|
144
|
+
project_id: string
|
|
145
|
+
bottlenecks: Array<{
|
|
146
|
+
step: number
|
|
147
|
+
step_name: string
|
|
148
|
+
ready: number
|
|
149
|
+
blocked: number
|
|
150
|
+
blocking_reasons: string[]
|
|
151
|
+
}>
|
|
152
|
+
recommendations: Array<{
|
|
153
|
+
step: number
|
|
154
|
+
action: string
|
|
155
|
+
priority: 'high' | 'medium' | 'low'
|
|
156
|
+
}>
|
|
157
|
+
optimal_processing_order: Array<{
|
|
158
|
+
file_path: string
|
|
159
|
+
suggested_next_step: number | null
|
|
160
|
+
}>
|
|
161
|
+
summary: {
|
|
162
|
+
total_files: number
|
|
163
|
+
bottleneck_count: number
|
|
164
|
+
ready_for_processing: number
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
// CIL[END chunk_id="flexiblepipelinepage_bottleneckanalysis_1784191730"]
|
|
170
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_step_labels_1784191730" type="constant" identity="STEP_LABELS" parent="none"]
|
|
171
|
+
// CIL[DOC-MACRO purpose="Map pipeline step numbers to labels"]
|
|
172
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide human-readable labels for pipeline steps"]
|
|
173
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[]"]
|
|
174
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Record<number,string> step labels" errors="none" side_effects="none"]
|
|
175
|
+
// CIL[DOC-MICRO logic_summary="Defines a constant mapping step numbers to display labels" notable_decisions="[]"]
|
|
176
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
177
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
178
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
179
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
180
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
181
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
182
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
183
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
184
|
+
const STEP_LABELS: Record<number, string> = {
|
|
185
|
+
4: 'Chunk',
|
|
186
|
+
5: 'First-Pass Docs',
|
|
187
|
+
6: 'Embed (1st Pass)',
|
|
188
|
+
8: 'Second-Pass Docs',
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// CIL[END chunk_id="flexiblepipelinepage_step_labels_1784191730"]
|
|
192
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_step_colors_1784191730" type="constant" identity="STEP_COLORS" parent="none"]
|
|
193
|
+
// CIL[DOC-MACRO purpose="Map pipeline step numbers to color classes"]
|
|
194
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide Tailwind color classes for pipeline steps"]
|
|
195
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[]"]
|
|
196
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Record<number,string> Tailwind classes" errors="none" side_effects="none"]
|
|
197
|
+
// CIL[DOC-MICRO logic_summary="Defines a constant mapping step numbers to Tailwind color classes" notable_decisions="[]"]
|
|
198
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
199
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
200
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
201
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
202
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
203
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
204
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
205
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
206
|
+
const STEP_COLORS: Record<number, string> = {
|
|
207
|
+
4: 'bg-blue-100 text-blue-700',
|
|
208
|
+
5: 'bg-purple-100 text-purple-700',
|
|
209
|
+
6: 'bg-green-100 text-green-700',
|
|
210
|
+
8: 'bg-violet-100 text-violet-700',
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// CIL[END chunk_id="flexiblepipelinepage_step_colors_1784191730"]
|
|
214
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_priority_colors_1784191730" type="constant" identity="PRIORITY_COLORS" parent="none"]
|
|
215
|
+
// CIL[DOC-MACRO purpose="Map priority levels to color classes"]
|
|
216
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide Tailwind color classes for priority levels"]
|
|
217
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[]"]
|
|
218
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Record<string,string> Tailwind classes" errors="none" side_effects="none"]
|
|
219
|
+
// CIL[DOC-MICRO logic_summary="Defines a constant mapping priority levels to Tailwind color classes" notable_decisions="[]"]
|
|
220
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
221
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
222
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
223
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
224
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
225
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
226
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
227
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
228
|
+
const PRIORITY_COLORS: Record<string, string> = {
|
|
229
|
+
high: 'bg-red-100 text-red-700',
|
|
230
|
+
medium: 'bg-yellow-100 text-yellow-700',
|
|
231
|
+
low: 'bg-gray-100 text-gray-700',
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
// CIL[END chunk_id="flexiblepipelinepage_priority_colors_1784191730"]
|
|
236
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_fileprogresscard_1784191730" type="function" identity="FileProgressCard" parent="none"]
|
|
237
|
+
// CIL[DOC-MACRO purpose="Render a file progress card"]
|
|
238
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display file status, progress, and the next actionable step"]
|
|
239
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[]"]
|
|
240
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX element" errors="none" side_effects="calls onProcess callback when user clicks process"]
|
|
241
|
+
// CIL[DOC-MICRO logic_summary="Renders file badges, a progress bar, and a process button for the next step" notable_decisions="[]"]
|
|
242
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
243
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
244
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
245
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
246
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
247
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
248
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
249
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
250
|
+
function FileProgressCard({ file, onProcess }: {
|
|
251
|
+
file: FilePipelineState
|
|
252
|
+
onProcess: (filePath: string, step: number) => void
|
|
253
|
+
}) {
|
|
254
|
+
const nextStep = file.ready_for[0]
|
|
255
|
+
const canProceed = nextStep !== undefined
|
|
256
|
+
|
|
257
|
+
return (
|
|
258
|
+
<Card className="mb-2">
|
|
259
|
+
<CardContent className="p-4">
|
|
260
|
+
<div className="flex items-center justify-between mb-2">
|
|
261
|
+
<div className="flex items-center gap-2">
|
|
262
|
+
<FileText className="h-4 w-4 text-muted-foreground" />
|
|
263
|
+
<span className="text-sm font-medium font-mono">{file.file_path}</span>
|
|
264
|
+
</div>
|
|
265
|
+
<div className="flex items-center gap-2">
|
|
266
|
+
<Badge variant="outline" className="text-xs">
|
|
267
|
+
{file.current_status}
|
|
268
|
+
</Badge>
|
|
269
|
+
<Badge className="text-xs bg-blue-100 text-blue-700">
|
|
270
|
+
{Math.round(file.progress_percentage)}%
|
|
271
|
+
</Badge>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
|
|
275
|
+
<Progress value={file.progress_percentage} className="mb-3 h-2" />
|
|
276
|
+
|
|
277
|
+
<div className="flex items-center justify-between">
|
|
278
|
+
<div className="flex items-center gap-2 text-xs text-muted-foreground">
|
|
279
|
+
<span>Completed: {file.completed_steps.join(', ') || 'None'}</span>
|
|
280
|
+
{file.ready_for.length > 0 && (
|
|
281
|
+
<span>• Ready for: {file.ready_for.join(', ')}</span>
|
|
282
|
+
)}
|
|
283
|
+
{file.blocked_by.length > 0 && (
|
|
284
|
+
<span>• Blocked by: {file.blocked_by.join(', ')}</span>
|
|
285
|
+
)}
|
|
286
|
+
</div>
|
|
287
|
+
|
|
288
|
+
{canProceed && (
|
|
289
|
+
<Button
|
|
290
|
+
size="sm"
|
|
291
|
+
onClick={() => onProcess(file.file_path, nextStep)}
|
|
292
|
+
className="h-6 text-xs"
|
|
293
|
+
>
|
|
294
|
+
<Play className="h-3 w-3 mr-1" />
|
|
295
|
+
{STEP_LABELS[nextStep]}
|
|
296
|
+
</Button>
|
|
297
|
+
)}
|
|
298
|
+
</div>
|
|
299
|
+
</CardContent>
|
|
300
|
+
</Card>
|
|
301
|
+
)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// CIL[END chunk_id="flexiblepipelinepage_fileprogresscard_1784191730"]
|
|
305
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_stepsummarycard_1784191730" type="function" identity="StepSummaryCard" parent="none"]
|
|
306
|
+
// CIL[DOC-MACRO purpose="Render a step summary card"]
|
|
307
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display step completion metrics and a batch process button"]
|
|
308
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[]"]
|
|
309
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX element" errors="none" side_effects="calls onProcess callback when user clicks process"]
|
|
310
|
+
// CIL[DOC-MICRO logic_summary="Renders step icon, label, progress bar, and a button to process pending files" notable_decisions="[]"]
|
|
311
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
312
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
313
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
314
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
315
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
316
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
317
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
318
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
319
|
+
function StepSummaryCard({ step, summary, onProcess }: {
|
|
320
|
+
step: number
|
|
321
|
+
summary: { completed: number; pending: number; in_progress: number }
|
|
322
|
+
onProcess: (step: number) => void
|
|
323
|
+
}) {
|
|
324
|
+
const total = summary.completed + summary.pending + summary.in_progress
|
|
325
|
+
const progress = total > 0 ? (summary.completed / total) * 100 : 0
|
|
326
|
+
|
|
327
|
+
return (
|
|
328
|
+
<Card className="mb-3">
|
|
329
|
+
<CardContent className="p-4">
|
|
330
|
+
<div className="flex items-center justify-between mb-3">
|
|
331
|
+
<div className="flex items-center gap-2">
|
|
332
|
+
<div className={`h-8 w-8 rounded-full flex items-center justify-center text-xs font-bold ${STEP_COLORS[step]}`}>
|
|
333
|
+
{step}
|
|
334
|
+
</div>
|
|
335
|
+
<div>
|
|
336
|
+
<h4 className="text-sm font-medium">{STEP_LABELS[step]}</h4>
|
|
337
|
+
<p className="text-xs text-muted-foreground">
|
|
338
|
+
{summary.completed} completed, {summary.pending} ready, {summary.in_progress} in progress
|
|
339
|
+
</p>
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
<Badge className={STEP_COLORS[step]}>
|
|
343
|
+
{Math.round(progress)}%
|
|
344
|
+
</Badge>
|
|
345
|
+
</div>
|
|
346
|
+
|
|
347
|
+
<Progress value={progress} className="mb-3 h-2" />
|
|
348
|
+
|
|
349
|
+
{summary.pending > 0 && (
|
|
350
|
+
<Button
|
|
351
|
+
size="sm"
|
|
352
|
+
onClick={() => onProcess(step)}
|
|
353
|
+
className="w-full"
|
|
354
|
+
variant="outline"
|
|
355
|
+
>
|
|
356
|
+
<Play className="h-3 w-3 mr-1" />
|
|
357
|
+
Process {summary.pending} ready files
|
|
358
|
+
</Button>
|
|
359
|
+
)}
|
|
360
|
+
</CardContent>
|
|
361
|
+
</Card>
|
|
362
|
+
)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// CIL[END chunk_id="flexiblepipelinepage_stepsummarycard_1784191730"]
|
|
366
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_bottleneckalert_1784191730" type="function" identity="BottleneckAlert" parent="none"]
|
|
367
|
+
// CIL[DOC-MACRO purpose="Render a bottleneck alert"]
|
|
368
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display a bottleneck with blocking reasons and priority"]
|
|
369
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[]"]
|
|
370
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX element" errors="none" side_effects="none"]
|
|
371
|
+
// CIL[DOC-MICRO logic_summary="Renders an alert with step name, ready/blocked counts, blocking reasons, and a high-priority badge" notable_decisions="[]"]
|
|
372
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
373
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
374
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
375
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
376
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
377
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
378
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
379
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
380
|
+
function BottleneckAlert({ bottleneck }: { bottleneck: BottleneckAnalysis['bottlenecks'][0] }) {
|
|
381
|
+
return (
|
|
382
|
+
<Alert className="mb-3">
|
|
383
|
+
<AlertTriangle className="h-4 w-4" />
|
|
384
|
+
<AlertDescription>
|
|
385
|
+
<div className="flex items-center justify-between">
|
|
386
|
+
<div>
|
|
387
|
+
<span className="font-medium">{bottleneck.step_name}</span>
|
|
388
|
+
<span className="text-sm text-muted-foreground ml-2">
|
|
389
|
+
{bottleneck.ready} ready, {bottleneck.blocked} blocked
|
|
390
|
+
</span>
|
|
391
|
+
</div>
|
|
392
|
+
<Badge className={PRIORITY_COLORS.high}>
|
|
393
|
+
High Priority
|
|
394
|
+
</Badge>
|
|
395
|
+
</div>
|
|
396
|
+
{bottleneck.blocking_reasons.length > 0 && (
|
|
397
|
+
<div className="mt-2 text-xs text-muted-foreground">
|
|
398
|
+
<strong>Blocking issues:</strong>
|
|
399
|
+
<ul className="list-disc list-inside mt-1">
|
|
400
|
+
{bottleneck.blocking_reasons.map((reason, i) => (
|
|
401
|
+
<li key={i}>{reason}</li>
|
|
402
|
+
))}
|
|
403
|
+
</ul>
|
|
404
|
+
</div>
|
|
405
|
+
)}
|
|
406
|
+
</AlertDescription>
|
|
407
|
+
</Alert>
|
|
408
|
+
)
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// CIL[END chunk_id="flexiblepipelinepage_bottleneckalert_1784191730"]
|
|
412
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_recommendationcard_1784191730" type="function" identity="RecommendationCard" parent="none"]
|
|
413
|
+
// CIL[DOC-MACRO purpose="Render a recommendation card"]
|
|
414
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Display a pipeline recommendation with its priority"]
|
|
415
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[]"]
|
|
416
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX element" errors="none" side_effects="none"]
|
|
417
|
+
// CIL[DOC-MICRO logic_summary="Renders a recommendation with step, action text, and a priority badge" notable_decisions="[]"]
|
|
418
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
419
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
420
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
421
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
422
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
423
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
424
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
425
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
426
|
+
function RecommendationCard({ recommendation }: { recommendation: BottleneckAnalysis['recommendations'][0] }) {
|
|
427
|
+
return (
|
|
428
|
+
<Card className="mb-2">
|
|
429
|
+
<CardContent className="p-3">
|
|
430
|
+
<div className="flex items-center justify-between">
|
|
431
|
+
<div className="flex items-center gap-2">
|
|
432
|
+
<TrendingUp className="h-4 w-4 text-muted-foreground" />
|
|
433
|
+
<span className="text-sm">Step {recommendation.step}</span>
|
|
434
|
+
<span className="text-sm text-muted-foreground">{recommendation.action}</span>
|
|
435
|
+
</div>
|
|
436
|
+
<Badge className={PRIORITY_COLORS[recommendation.priority]}>
|
|
437
|
+
{recommendation.priority}
|
|
438
|
+
</Badge>
|
|
439
|
+
</div>
|
|
440
|
+
</CardContent>
|
|
441
|
+
</Card>
|
|
442
|
+
)
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
// CIL[END chunk_id="flexiblepipelinepage_recommendationcard_1784191730"]
|
|
447
|
+
// CIL[BEGIN chunk_id="flexiblepipelinepage_flexiblepipelinepage_1784191730" type="function" identity="FlexiblePipelinePage" parent="none"]
|
|
448
|
+
// CIL[DOC-MACRO purpose="Render the flexible pipeline dashboard"]
|
|
449
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Load pipeline status, ready files, and bottlenecks; render tabbed UI"]
|
|
450
|
+
// CIL[DOC-CONTEXT module="cortex.pages.cil" layer="presentation" related_files="[]"]
|
|
451
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX element" errors="none" side_effects="fetches data via apiFetch, registers React effects, logs API errors"]
|
|
452
|
+
// CIL[DOC-MICRO logic_summary="Loads pipeline status, per-step ready files, and bottlenecks; renders overview, files, steps, and bottlenecks tabs" notable_decisions="[]"]
|
|
453
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
454
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
455
|
+
// CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
456
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
457
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
458
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
459
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
460
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
461
|
+
export default function FlexiblePipelinePage() {
|
|
462
|
+
const { id: projectId } = useParams<{ id: string }>()
|
|
463
|
+
|
|
464
|
+
const [pipelineStatus, setPipelineStatus] = useState<PipelineStatus | null>(null)
|
|
465
|
+
const [readyFiles, setReadyFiles] = useState<Record<number, FilesReadyForStep>>({})
|
|
466
|
+
const [bottlenecks, setBottlenecks] = useState<BottleneckAnalysis | null>(null)
|
|
467
|
+
const [loading, setLoading] = useState(true)
|
|
468
|
+
const [activeTab, setActiveTab] = useState('overview')
|
|
469
|
+
|
|
470
|
+
const loadPipelineStatus = useCallback(async () => {
|
|
471
|
+
if (!projectId) return
|
|
472
|
+
|
|
473
|
+
try {
|
|
474
|
+
const response = await apiFetch(`/api/cil-pipeline?action=get_pipeline_status`, {
|
|
475
|
+
method: 'POST',
|
|
476
|
+
body: JSON.stringify({ project_id: projectId })
|
|
477
|
+
})
|
|
478
|
+
const data = await response.json()
|
|
479
|
+
setPipelineStatus(data)
|
|
480
|
+
} catch (error) {
|
|
481
|
+
console.error('Failed to load pipeline status:', error)
|
|
482
|
+
}
|
|
483
|
+
}, [projectId])
|
|
484
|
+
|
|
485
|
+
const loadReadyFiles = useCallback(async () => {
|
|
486
|
+
if (!projectId) return
|
|
487
|
+
|
|
488
|
+
const steps = [4, 5, 6, 8]
|
|
489
|
+
const results: Record<number, FilesReadyForStep> = {}
|
|
490
|
+
|
|
491
|
+
for (const step of steps) {
|
|
492
|
+
try {
|
|
493
|
+
const response = await apiFetch(`/api/cil-pipeline?action=get_files_ready_for_step`, {
|
|
494
|
+
method: 'POST',
|
|
495
|
+
body: JSON.stringify({ project_id: projectId, step, include_blocking_info: true })
|
|
496
|
+
})
|
|
497
|
+
const data = await response.json()
|
|
498
|
+
results[step] = data
|
|
499
|
+
} catch (error) {
|
|
500
|
+
console.error(`Failed to load ready files for step ${step}:`, error)
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
setReadyFiles(results)
|
|
505
|
+
}, [projectId])
|
|
506
|
+
|
|
507
|
+
const loadBottlenecks = useCallback(async () => {
|
|
508
|
+
if (!projectId) return
|
|
509
|
+
|
|
510
|
+
try {
|
|
511
|
+
const response = await apiFetch(`/api/cil-pipeline?action=get_pipeline_bottlenecks`, {
|
|
512
|
+
method: 'POST',
|
|
513
|
+
body: JSON.stringify({ project_id: projectId })
|
|
514
|
+
})
|
|
515
|
+
const data = await response.json()
|
|
516
|
+
setBottlenecks(data)
|
|
517
|
+
} catch (error) {
|
|
518
|
+
console.error('Failed to load bottlenecks:', error)
|
|
519
|
+
}
|
|
520
|
+
}, [projectId])
|
|
521
|
+
|
|
522
|
+
useEffect(() => {
|
|
523
|
+
const loadData = async () => {
|
|
524
|
+
setLoading(true)
|
|
525
|
+
await Promise.all([
|
|
526
|
+
loadPipelineStatus(),
|
|
527
|
+
loadReadyFiles(),
|
|
528
|
+
loadBottlenecks()
|
|
529
|
+
])
|
|
530
|
+
setLoading(false)
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
loadData()
|
|
534
|
+
}, [loadPipelineStatus, loadReadyFiles, loadBottlenecks])
|
|
535
|
+
|
|
536
|
+
const handleProcessFile = useCallback(async (filePath: string, step: number) => {
|
|
537
|
+
console.log(`Processing ${filePath} for step ${step}`)
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
}, [])
|
|
541
|
+
|
|
542
|
+
const handleProcessStep = useCallback(async (step: number) => {
|
|
543
|
+
const files = readyFiles[step]?.files || []
|
|
544
|
+
console.log(`Processing ${files.length} files for step ${step}`)
|
|
545
|
+
|
|
546
|
+
}, [readyFiles])
|
|
547
|
+
|
|
548
|
+
if (loading) {
|
|
549
|
+
return (
|
|
550
|
+
<div className="space-y-4">
|
|
551
|
+
<Skeleton className="h-8 w-64" />
|
|
552
|
+
<Skeleton className="h-32 w-full" />
|
|
553
|
+
<Skeleton className="h-32 w-full" />
|
|
554
|
+
<Skeleton className="h-32 w-full" />
|
|
555
|
+
</div>
|
|
556
|
+
)
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
if (!pipelineStatus) {
|
|
560
|
+
return (
|
|
561
|
+
<Alert>
|
|
562
|
+
<AlertTriangle className="h-4 w-4" />
|
|
563
|
+
<AlertDescription>
|
|
564
|
+
Failed to load pipeline status. Please try refreshing the page.
|
|
565
|
+
</AlertDescription>
|
|
566
|
+
</Alert>
|
|
567
|
+
)
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
return (
|
|
571
|
+
<div className="space-y-6">
|
|
572
|
+
<div className="flex items-center justify-between">
|
|
573
|
+
<div>
|
|
574
|
+
<h1 className="text-2xl font-bold">Flexible Pipeline</h1>
|
|
575
|
+
<p className="text-muted-foreground">
|
|
576
|
+
True iterative processing with dependency-aware file selection
|
|
577
|
+
</p>
|
|
578
|
+
</div>
|
|
579
|
+
<Button onClick={() => window.location.reload()} variant="outline">
|
|
580
|
+
<RefreshCw className="h-4 w-4 mr-2" />
|
|
581
|
+
Refresh
|
|
582
|
+
</Button>
|
|
583
|
+
</div>
|
|
584
|
+
|
|
585
|
+
<PageInstructions
|
|
586
|
+
description="View the flexible pipeline status and identify bottlenecks."
|
|
587
|
+
sections={[
|
|
588
|
+
{ title: 'What this page is for', content: 'This page shows the dependency-aware file processing pipeline for the selected CIL project, including overall progress and per-step status.' },
|
|
589
|
+
{ title: 'How to read this page', content: 'The Overall Progress card shows the completion percentage and counts for total, complete, and in-progress files. Tabs provide Overview, Files, Steps, and Bottlenecks views.' },
|
|
590
|
+
{ title: 'How to use this page', content: 'Switch tabs to inspect step summaries, individual file progress, and which files are ready for the next step. Use the Process buttons to advance selected files.' },
|
|
591
|
+
{ title: 'Important notes', content: 'Bottlenecks are files that cannot proceed until another step completes. Refresh the page to see live progress during ingestion.' },
|
|
592
|
+
]}
|
|
593
|
+
/>
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
<Card>
|
|
597
|
+
<CardHeader>
|
|
598
|
+
<CardTitle className="flex items-center gap-2">
|
|
599
|
+
<TrendingUp className="h-5 w-5" />
|
|
600
|
+
Overall Progress
|
|
601
|
+
</CardTitle>
|
|
602
|
+
</CardHeader>
|
|
603
|
+
<CardContent>
|
|
604
|
+
<div className="space-y-3">
|
|
605
|
+
<div className="flex items-center justify-between">
|
|
606
|
+
<span className="text-sm font-medium">Pipeline Completion</span>
|
|
607
|
+
<Badge className="bg-green-100 text-green-700">
|
|
608
|
+
{Math.round(pipelineStatus.overall_progress)}%
|
|
609
|
+
</Badge>
|
|
610
|
+
</div>
|
|
611
|
+
<Progress value={pipelineStatus.overall_progress} className="h-3" />
|
|
612
|
+
<div className="flex items-center gap-4 text-sm text-muted-foreground">
|
|
613
|
+
<span>{pipelineStatus.files.length} files total</span>
|
|
614
|
+
<span>•</span>
|
|
615
|
+
<span>{pipelineStatus.files.filter(f => f.progress_percentage === 100).length} complete</span>
|
|
616
|
+
<span>•</span>
|
|
617
|
+
<span>{pipelineStatus.files.filter(f => f.progress_percentage < 100).length} in progress</span>
|
|
618
|
+
</div>
|
|
619
|
+
</div>
|
|
620
|
+
</CardContent>
|
|
621
|
+
</Card>
|
|
622
|
+
|
|
623
|
+
<Tabs value={activeTab} onValueChange={setActiveTab}>
|
|
624
|
+
<TabsList className="grid w-full grid-cols-4">
|
|
625
|
+
<TabsTrigger value="overview">Overview</TabsTrigger>
|
|
626
|
+
<TabsTrigger value="files">Files</TabsTrigger>
|
|
627
|
+
<TabsTrigger value="steps">Steps</TabsTrigger>
|
|
628
|
+
<TabsTrigger value="bottlenecks">Bottlenecks</TabsTrigger>
|
|
629
|
+
</TabsList>
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
<TabsContent value="overview" className="space-y-4">
|
|
633
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
634
|
+
{Object.entries(pipelineStatus.step_summary).map(([step, summary]) => (
|
|
635
|
+
<StepSummaryCard
|
|
636
|
+
key={step}
|
|
637
|
+
step={parseInt(step)}
|
|
638
|
+
summary={summary}
|
|
639
|
+
onProcess={handleProcessStep}
|
|
640
|
+
/>
|
|
641
|
+
))}
|
|
642
|
+
</div>
|
|
643
|
+
</TabsContent>
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
<TabsContent value="files" className="space-y-4">
|
|
647
|
+
<div className="space-y-2">
|
|
648
|
+
{pipelineStatus.files.map((file) => (
|
|
649
|
+
<FileProgressCard
|
|
650
|
+
key={file.file_path}
|
|
651
|
+
file={file}
|
|
652
|
+
onProcess={handleProcessFile}
|
|
653
|
+
/>
|
|
654
|
+
))}
|
|
655
|
+
</div>
|
|
656
|
+
</TabsContent>
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
<TabsContent value="steps" className="space-y-4">
|
|
660
|
+
{Object.entries(readyFiles).map(([step, data]) => (
|
|
661
|
+
<Card key={step}>
|
|
662
|
+
<CardHeader>
|
|
663
|
+
<CardTitle className="flex items-center gap-2">
|
|
664
|
+
<div className={`h-6 w-6 rounded-full flex items-center justify-center text-xs font-bold ${STEP_COLORS[parseInt(step)]}`}>
|
|
665
|
+
{step}
|
|
666
|
+
</div>
|
|
667
|
+
{STEP_LABELS[parseInt(step)]}
|
|
668
|
+
<Badge variant="outline">
|
|
669
|
+
{data.file_count} files ready
|
|
670
|
+
</Badge>
|
|
671
|
+
</CardTitle>
|
|
672
|
+
</CardHeader>
|
|
673
|
+
<CardContent>
|
|
674
|
+
<div className="space-y-2">
|
|
675
|
+
{data.files.map((file) => (
|
|
676
|
+
<div key={file.file_path} className="flex items-center justify-between p-2 border rounded">
|
|
677
|
+
<div className="flex items-center gap-2">
|
|
678
|
+
<FileText className="h-4 w-4 text-muted-foreground" />
|
|
679
|
+
<span className="text-sm font-mono">{file.file_path}</span>
|
|
680
|
+
{file.can_proceed ? (
|
|
681
|
+
<Badge className="bg-green-100 text-green-700">Ready</Badge>
|
|
682
|
+
) : (
|
|
683
|
+
<Badge variant="outline">Blocked</Badge>
|
|
684
|
+
)}
|
|
685
|
+
</div>
|
|
686
|
+
<Button
|
|
687
|
+
size="sm"
|
|
688
|
+
onClick={() => handleProcessFile(file.file_path, parseInt(step))}
|
|
689
|
+
disabled={!file.can_proceed}
|
|
690
|
+
className="h-6 text-xs"
|
|
691
|
+
>
|
|
692
|
+
<Play className="h-3 w-3 mr-1" />
|
|
693
|
+
Process
|
|
694
|
+
</Button>
|
|
695
|
+
</div>
|
|
696
|
+
))}
|
|
697
|
+
</div>
|
|
698
|
+
</CardContent>
|
|
699
|
+
</Card>
|
|
700
|
+
))}
|
|
701
|
+
</TabsContent>
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
<TabsContent value="bottlenecks" className="space-y-4">
|
|
705
|
+
{bottlenecks?.bottlenecks.map((bottleneck) => (
|
|
706
|
+
<BottleneckAlert key={bottleneck.step} bottleneck={bottleneck} />
|
|
707
|
+
))}
|
|
708
|
+
|
|
709
|
+
{bottlenecks?.recommendations && (
|
|
710
|
+
<Card>
|
|
711
|
+
<CardHeader>
|
|
712
|
+
<CardTitle className="flex items-center gap-2">
|
|
713
|
+
<GitBranch className="h-5 w-5" />
|
|
714
|
+
Recommendations
|
|
715
|
+
</CardTitle>
|
|
716
|
+
</CardHeader>
|
|
717
|
+
<CardContent>
|
|
718
|
+
<div className="space-y-2">
|
|
719
|
+
{bottlenecks.recommendations.map((rec, i) => (
|
|
720
|
+
<RecommendationCard key={i} recommendation={rec} />
|
|
721
|
+
))}
|
|
722
|
+
</div>
|
|
723
|
+
</CardContent>
|
|
724
|
+
</Card>
|
|
725
|
+
)}
|
|
726
|
+
</TabsContent>
|
|
727
|
+
</Tabs>
|
|
728
|
+
</div>
|
|
729
|
+
)
|
|
730
|
+
}
|
|
731
|
+
// CIL[END chunk_id="flexiblepipelinepage_flexiblepipelinepage_1784191730"]
|