@cat-factory/app 0.308.0 → 0.310.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -2
- package/app/assets/css/main.css +22 -0
- package/app/assets/css/prose.css +4 -4
- package/app/assets/css/type.css +24 -0
- package/app/components/assistant/AssistantModal.vue +8 -6
- package/app/components/auth/BackendMisconfiguredScreen.vue +4 -3
- package/app/components/auth/LoginScreen.vue +40 -26
- package/app/components/auth/ResetPasswordScreen.vue +9 -4
- package/app/components/auth/UserMenu.vue +5 -4
- package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +48 -37
- package/app/components/binaryOutput/BinaryOutputReport.vue +10 -14
- package/app/components/binaryOutput/StoredAssetView.vue +13 -11
- package/app/components/board/AddTaskModal.vue +30 -27
- package/app/components/board/AgentFailureCard.vue +21 -18
- package/app/components/board/AgentFailureHistory.vue +18 -9
- package/app/components/board/CreateInitiativeModal.vue +7 -6
- package/app/components/board/FailureDetail.vue +22 -12
- package/app/components/board/FailureHistoryList.vue +5 -5
- package/app/components/board/RecurringPipelineModal.vue +12 -11
- package/app/components/board/ReviewFrictionDialog.vue +8 -6
- package/app/components/board/StepExecutionHistory.vue +8 -8
- package/app/components/board/nodes/AgentChip.vue +1 -1
- package/app/components/board/nodes/BlockNode.vue +25 -24
- package/app/components/board/nodes/DecisionBadge.vue +4 -3
- package/app/components/board/nodes/EpicNode.vue +4 -4
- package/app/components/board/nodes/FrameSwimlanes.vue +8 -10
- package/app/components/board/nodes/InitiativeCard.vue +4 -4
- package/app/components/board/nodes/LaneGroup.vue +3 -5
- package/app/components/board/nodes/TaskCard.vue +20 -15
- package/app/components/board/nodes/TaskLane.vue +3 -3
- package/app/components/board/nodes/TaskPipelineMini.vue +21 -18
- package/app/components/bootstrap/AdoptionReviewModal.vue +36 -26
- package/app/components/bootstrap/BootstrapModal.vue +14 -13
- package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
- package/app/components/brainstorm/BrainstormWindow.vue +13 -10
- package/app/components/bugFishing/BugFishingWindow.vue +81 -58
- package/app/components/clarity/ClarityReviewWindow.vue +13 -10
- package/app/components/common/AsyncViewError.vue +1 -1
- package/app/components/common/ClarificationItem.vue +6 -6
- package/app/components/common/CopyButton.vue +12 -11
- package/app/components/common/DescriptorFields.vue +1 -1
- package/app/components/common/EmptyState.vue +1 -1
- package/app/components/common/IconButton.vue +34 -9
- package/app/components/common/InterviewGateNotice.vue +4 -4
- package/app/components/common/MarkdownProse.vue +8 -2
- package/app/components/common/SectionLabel.vue +38 -0
- package/app/components/consensus/ConsensusSessionWindow.vue +10 -9
- package/app/components/context/ContextAttachmentFields.vue +32 -20
- package/app/components/docs/DocInterviewWindow.vue +10 -9
- package/app/components/documents/ContextDocumentPicker.vue +22 -21
- package/app/components/documents/DocumentImportModal.vue +7 -5
- package/app/components/documents/DocumentOriginLink.vue +12 -9
- package/app/components/documents/DocumentSourceConnectModal.vue +2 -2
- package/app/components/documents/DocumentSyncState.vue +4 -4
- package/app/components/documents/DocumentTemplatesModal.vue +5 -4
- package/app/components/documents/RepoContextDocPicker.vue +7 -9
- package/app/components/documents/StartFromDesignModal.vue +4 -4
- package/app/components/documents/TaskContextDocs.vue +1 -1
- package/app/components/environments/EnvSetupStepper.vue +3 -3
- package/app/components/environments/EnvironmentStatusPanel.vue +15 -13
- package/app/components/environments/steps/EnvPreflightStep.vue +8 -8
- package/app/components/environments/steps/EnvReviewStep.vue +23 -22
- package/app/components/environments/steps/EnvSaveStep.vue +5 -5
- package/app/components/focus/BlockFocusView.vue +11 -10
- package/app/components/followUp/FollowUpWindow.vue +18 -15
- package/app/components/forkDecision/ForkDecisionWindow.vue +85 -97
- package/app/components/foundational/FoundationalContractSummary.vue +2 -2
- package/app/components/foundational/FoundationalServiceCatalogList.vue +6 -5
- package/app/components/foundational/FoundationalServiceRegistry.vue +10 -9
- package/app/components/foundational/FoundationalServiceSources.vue +7 -6
- package/app/components/foundational/FoundationalSuppressions.vue +2 -2
- package/app/components/fragments/FragmentLibraryManager.vue +8 -7
- package/app/components/fragments/FragmentSelector.vue +22 -20
- package/app/components/gates/GateFailingCheckList.vue +7 -6
- package/app/components/gates/GateResultView.vue +55 -49
- package/app/components/github/AddServiceFromRepoModal.vue +16 -11
- package/app/components/github/BranchProtectionPreflight.vue +5 -5
- package/app/components/github/GitHubConnect.vue +5 -3
- package/app/components/github/GitHubOnboarding.vue +7 -2
- package/app/components/github/GitHubPanel.vue +23 -19
- package/app/components/github/RepoTreeBrowser.vue +16 -13
- package/app/components/humanTest/HumanTestWindow.vue +29 -24
- package/app/components/initiative/InitiativePlanNotice.vue +3 -3
- package/app/components/initiative/InitiativePlanReview.vue +46 -38
- package/app/components/initiative/InitiativePlanningWindow.vue +5 -5
- package/app/components/initiative/InitiativeTrackerWindow.vue +213 -165
- package/app/components/judge/JudgeResultView.vue +28 -27
- package/app/components/kaizen/KaizenPanel.vue +70 -56
- package/app/components/kaizen/KaizenStepStatus.vue +7 -6
- package/app/components/layout/AccountAuditLog.vue +1 -1
- package/app/components/layout/AccountDeploymentSettings.vue +10 -10
- package/app/components/layout/AccountFailureKindRules.vue +13 -13
- package/app/components/layout/AccountFoundationalSettings.vue +1 -1
- package/app/components/layout/AccountFragmentSettings.vue +1 -1
- package/app/components/layout/AccountModelPolicySettings.vue +7 -7
- package/app/components/layout/AccountPlatformAlertSettings.vue +8 -8
- package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
- package/app/components/layout/AccountRunCredentialSettings.vue +3 -3
- package/app/components/layout/AccountSkillSettings.vue +1 -1
- package/app/components/layout/AccountTeamSettings.vue +13 -9
- package/app/components/layout/AiProvidersBanner.vue +1 -1
- package/app/components/layout/AppearanceSwitcher.vue +5 -4
- package/app/components/layout/BoardSwitcher.vue +13 -10
- package/app/components/layout/BoardToolbar.vue +10 -5
- package/app/components/layout/CommandBar.vue +8 -5
- package/app/components/layout/DefaultTestEnvBanner.vue +6 -5
- package/app/components/layout/IntegrationsHub.vue +12 -9
- package/app/components/layout/LanguageSwitcher.vue +5 -4
- package/app/components/layout/ModelProvidersHub.vue +10 -7
- package/app/components/layout/NotificationsInbox.vue +47 -36
- package/app/components/layout/PersonalSetupModal.vue +9 -6
- package/app/components/layout/RolePrompt.vue +5 -4
- package/app/components/layout/SideBar.vue +7 -8
- package/app/components/layout/SpendWarningBanner.vue +3 -3
- package/app/components/layout/TranslationWarningBanner.vue +5 -4
- package/app/components/layout/UiModeSwitcher.vue +15 -12
- package/app/components/layout/UiRoleSwitcher.vue +10 -8
- package/app/components/layout/WorkspaceMembersSettings.vue +2 -2
- package/app/components/media/ArtifactLightbox.vue +74 -44
- package/app/components/media/ImageCompare.vue +80 -85
- package/app/components/merge/MergeEffortChips.vue +4 -6
- package/app/components/notifications/NotificationSettingsPanel.vue +6 -5
- package/app/components/observability/OutcomeFilterChips.vue +6 -5
- package/app/components/observability/RunFailureSummary.vue +22 -23
- package/app/components/observability/StepMetricsBar.vue +9 -8
- package/app/components/observability/StepModelActivity.vue +8 -5
- package/app/components/observability/ToolCallList.vue +19 -20
- package/app/components/outcome/OutcomeSummaryWindow.vue +48 -46
- package/app/components/palettes/AgentPalette.vue +21 -15
- package/app/components/palettes/AgentTierSelect.vue +1 -1
- package/app/components/palettes/PipelinePurposeSelect.vue +1 -1
- package/app/components/panels/AgentStepDetail.vue +57 -49
- package/app/components/panels/AttemptEntryHeader.vue +2 -2
- package/app/components/panels/DecisionModal.vue +1 -1
- package/app/components/panels/GenericStructuredResultView.vue +6 -5
- package/app/components/panels/InspectorPanel.vue +15 -13
- package/app/components/panels/MergerResultView.vue +10 -9
- package/app/components/panels/ObservabilityPanel.vue +211 -186
- package/app/components/panels/OperatorDashboardPanel.vue +124 -115
- package/app/components/panels/ReportsPanel.vue +87 -83
- package/app/components/panels/ReportsSpendBreakdown.vue +2 -2
- package/app/components/panels/ResultWindowShell.vue +152 -137
- package/app/components/panels/RunDetailLoadState.vue +1 -1
- package/app/components/panels/StepContainerStatus.vue +17 -16
- package/app/components/panels/StepDelegatedStatus.vue +24 -21
- package/app/components/panels/StepEffortReport.vue +12 -17
- package/app/components/panels/StepFragmentAdherence.vue +9 -10
- package/app/components/panels/StepMetadataCard.vue +41 -43
- package/app/components/panels/StepReproductionReport.vue +18 -20
- package/app/components/panels/StepRestartControl.vue +3 -2
- package/app/components/panels/StepRunMeta.vue +27 -26
- package/app/components/panels/StepTestReport.vue +16 -15
- package/app/components/panels/StepToolServers.vue +7 -8
- package/app/components/panels/StepValidationReport.vue +5 -5
- package/app/components/panels/inspector/ContainerSummary.vue +4 -4
- package/app/components/panels/inspector/DocReferenceRepos.vue +5 -4
- package/app/components/panels/inspector/EnvProbeReport.vue +16 -13
- package/app/components/panels/inspector/EpicChildren.vue +12 -10
- package/app/components/panels/inspector/FrontendBindingsResolved.vue +5 -4
- package/app/components/panels/inspector/FrontendConfig.vue +29 -36
- package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
- package/app/components/panels/inspector/InspectorSection.vue +25 -17
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +9 -8
- package/app/components/panels/inspector/ServiceConnections.vue +5 -4
- package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -2
- package/app/components/panels/inspector/ServiceSelfTests.vue +9 -13
- package/app/components/panels/inspector/ServiceTestConfig.vue +46 -49
- package/app/components/panels/inspector/ServiceTestSecrets.vue +3 -3
- package/app/components/panels/inspector/ServiceTestingContext.vue +2 -2
- package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
- package/app/components/panels/inspector/TaskAgentConfig.vue +2 -2
- package/app/components/panels/inspector/TaskAprioriBranches.vue +6 -5
- package/app/components/panels/inspector/TaskDependencies.vue +1 -1
- package/app/components/panels/inspector/TaskEstimateBadge.vue +3 -7
- package/app/components/panels/inspector/TaskExecution.vue +18 -16
- package/app/components/panels/inspector/TaskRunSettings.vue +45 -44
- package/app/components/panels/inspector/TaskStructure.vue +5 -4
- package/app/components/pipeline/AgentPromptEditor.vue +15 -14
- package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -52
- package/app/components/pipeline/EstimateThresholdFields.vue +14 -11
- package/app/components/pipeline/GateConfigFields.vue +19 -23
- package/app/components/pipeline/IterationCapPrompt.vue +1 -1
- package/app/components/pipeline/PipelineBuilder.vue +113 -99
- package/app/components/pipeline/PipelineHealthModal.vue +7 -7
- package/app/components/pipeline/PipelinePicker.vue +11 -9
- package/app/components/pipeline/PipelinePreview.vue +6 -7
- package/app/components/pipeline/PipelineProgress.vue +49 -45
- package/app/components/prReview/PrReviewWindow.vue +87 -65
- package/app/components/providers/AiPresetMismatchDialog.vue +4 -3
- package/app/components/providers/AiProviderOnboardingModal.vue +2 -2
- package/app/components/providers/ApiKeysSection.vue +11 -9
- package/app/components/providers/PersonalSubscriptionSection.vue +4 -3
- package/app/components/providers/VendorCredentialsModal.vue +5 -4
- package/app/components/provisioning/ProvisioningLogsDrawer.vue +10 -9
- package/app/components/ralph/RalphLoopResultView.vue +29 -29
- package/app/components/requirements/RequirementsReviewWindow.vue +22 -17
- package/app/components/riskPolicy/RiskPolicyPicker.vue +13 -11
- package/app/components/riskPolicy/RiskPolicyPreview.vue +16 -15
- package/app/components/sandbox/SandboxPanel.vue +93 -73
- package/app/components/settings/ApiTokensPanel.vue +1 -1
- package/app/components/settings/BudgetSettings.vue +18 -17
- package/app/components/settings/CapabilityCredentialsPanel.vue +5 -5
- package/app/components/settings/CloudflareHandlerSection.vue +44 -41
- package/app/components/settings/ComposeEnvironmentSetupSection.vue +14 -12
- package/app/components/settings/ConnectionTestVerdict.vue +1 -1
- package/app/components/settings/ConsensusGroupsSection.vue +58 -47
- package/app/components/settings/CustomManifestTypeEditor.vue +8 -7
- package/app/components/settings/DefaultProvisionTypeSection.vue +5 -5
- package/app/components/settings/InfraHandlersConfigurator.vue +26 -24
- package/app/components/settings/InfrastructureBackendPicker.vue +18 -18
- package/app/components/settings/IssueTrackerPanel.vue +30 -21
- package/app/components/settings/KubernetesEngineForm.vue +9 -8
- package/app/components/settings/KubernetesEnvironmentForm.vue +4 -3
- package/app/components/settings/LocalContainerPoolSettings.vue +2 -2
- package/app/components/settings/LocalModelEndpointsPanel.vue +13 -11
- package/app/components/settings/MergeClassRulesEditor.vue +6 -5
- package/app/components/settings/MergeRolePolicyEditor.vue +13 -12
- package/app/components/settings/ModelConfigurationPanel.vue +17 -19
- package/app/components/settings/ModelPresetHealthModal.vue +3 -3
- package/app/components/settings/ObservabilityConnectionPanel.vue +1 -1
- package/app/components/settings/OpenRouterCatalogPanel.vue +10 -8
- package/app/components/settings/PackageRegistriesPanel.vue +4 -4
- package/app/components/settings/ProviderConnectionTab.vue +5 -4
- package/app/components/settings/ProviderManifestEditor.vue +9 -8
- package/app/components/settings/ProviderPreferenceEditor.vue +13 -13
- package/app/components/settings/RiskPolicyCreateForm.vue +40 -26
- package/app/components/settings/RiskPolicyEditorRow.vue +21 -19
- package/app/components/settings/RiskPolicyHealthModal.vue +3 -3
- package/app/components/settings/RiskPolicyPanel.vue +11 -13
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +15 -12
- package/app/components/settings/SharedStacksPanel.vue +5 -5
- package/app/components/settings/TaskSourceCard.vue +2 -2
- package/app/components/settings/TaskTypeSuppressionsPanel.vue +4 -4
- package/app/components/settings/ToolServerChecklist.vue +22 -22
- package/app/components/settings/UsageSettings.vue +13 -13
- package/app/components/settings/UserSecretsSection.vue +4 -3
- package/app/components/settings/WorkspaceMetadataSettings.vue +6 -5
- package/app/components/settings/WorkspaceSettingsPanel.vue +72 -58
- package/app/components/skills/ReviewSkillQueue.vue +12 -10
- package/app/components/skills/SkillLibraryManager.vue +9 -8
- package/app/components/slack/SlackPanel.vue +17 -12
- package/app/components/spec/ServiceSpecWindow.vue +19 -19
- package/app/components/tasks/BugHuntModal.vue +1 -1
- package/app/components/tasks/ContextIssuePicker.vue +16 -15
- package/app/components/tasks/TaskContextIssues.vue +5 -4
- package/app/components/tasks/TaskImportModal.vue +3 -2
- package/app/components/tasks/TaskSourceConnectModal.vue +5 -5
- package/app/components/testing/TestReportWindow.vue +67 -60
- package/app/components/theme/ThemeImportModal.vue +2 -2
- package/app/components/tutorial/TutorialNudge.vue +3 -2
- package/app/components/tutorial/TutorialOverlay.vue +3 -2
- package/app/components/vcs/GitLabConnect.vue +1 -1
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +79 -54
- package/app/utils/theme/builtins.ts +7 -1
- package/i18n/locales/de.json +7 -3
- package/i18n/locales/en.json +7 -3
- package/i18n/locales/es.json +7 -3
- package/i18n/locales/fr.json +7 -3
- package/i18n/locales/he.json +7 -3
- package/i18n/locales/it.json +7 -3
- package/i18n/locales/ja.json +7 -3
- package/i18n/locales/pl.json +7 -3
- package/i18n/locales/tr.json +7 -3
- package/i18n/locales/uk.json +7 -3
- package/package.json +1 -1
|
@@ -137,7 +137,7 @@ const reseedableCount = computed(
|
|
|
137
137
|
{{ t('pipeline.health.newHeading') }}
|
|
138
138
|
</h3>
|
|
139
139
|
</div>
|
|
140
|
-
<p class="text-
|
|
140
|
+
<p class="text-2xs text-dimmed">{{ t('pipeline.health.newDescription') }}</p>
|
|
141
141
|
<ul class="space-y-2">
|
|
142
142
|
<li
|
|
143
143
|
v-for="p in newPipelines"
|
|
@@ -172,7 +172,7 @@ const reseedableCount = computed(
|
|
|
172
172
|
{{ t('pipeline.health.invalidHeading') }}
|
|
173
173
|
</h3>
|
|
174
174
|
</div>
|
|
175
|
-
<p class="text-
|
|
175
|
+
<p class="text-2xs text-dimmed">
|
|
176
176
|
{{ t('pipeline.health.invalidDescription') }}
|
|
177
177
|
</p>
|
|
178
178
|
<ul class="space-y-2">
|
|
@@ -195,7 +195,7 @@ const reseedableCount = computed(
|
|
|
195
195
|
<li
|
|
196
196
|
v-for="(p, i) in h.problems"
|
|
197
197
|
:key="i"
|
|
198
|
-
class="text-
|
|
198
|
+
class="text-2xs"
|
|
199
199
|
:class="
|
|
200
200
|
p.type === 'outdated' ? 'text-app-warning-400/80' : 'text-app-error-400/90'
|
|
201
201
|
"
|
|
@@ -241,7 +241,7 @@ const reseedableCount = computed(
|
|
|
241
241
|
{{ t('pipeline.health.retiredHeading') }}
|
|
242
242
|
</h3>
|
|
243
243
|
</div>
|
|
244
|
-
<p class="text-
|
|
244
|
+
<p class="text-2xs text-dimmed">{{ t('pipeline.health.retiredDescription') }}</p>
|
|
245
245
|
<ul class="space-y-2">
|
|
246
246
|
<li
|
|
247
247
|
v-for="r in retired"
|
|
@@ -250,7 +250,7 @@ const reseedableCount = computed(
|
|
|
250
250
|
>
|
|
251
251
|
<div class="min-w-0">
|
|
252
252
|
<span class="truncate text-sm font-medium text-app-100">{{ r.pipeline.name }}</span>
|
|
253
|
-
<p class="text-
|
|
253
|
+
<p class="text-2xs text-muted/80">
|
|
254
254
|
{{
|
|
255
255
|
r.replacement
|
|
256
256
|
? t('pipeline.health.retiredReplacedBy', { name: r.replacement.name })
|
|
@@ -281,7 +281,7 @@ const reseedableCount = computed(
|
|
|
281
281
|
{{ t('pipeline.health.updatesHeading') }}
|
|
282
282
|
</h3>
|
|
283
283
|
</div>
|
|
284
|
-
<p class="text-
|
|
284
|
+
<p class="text-2xs text-dimmed">
|
|
285
285
|
{{ t('pipeline.health.updatesDescription') }}
|
|
286
286
|
</p>
|
|
287
287
|
<ul class="space-y-2">
|
|
@@ -292,7 +292,7 @@ const reseedableCount = computed(
|
|
|
292
292
|
>
|
|
293
293
|
<div class="min-w-0">
|
|
294
294
|
<span class="truncate text-sm font-medium text-app-100">{{ h.pipeline.name }}</span>
|
|
295
|
-
<p class="text-
|
|
295
|
+
<p class="text-2xs text-app-warning-400/80">{{ h.problems[0]?.message }}</p>
|
|
296
296
|
</div>
|
|
297
297
|
<UButton
|
|
298
298
|
size="xs"
|
|
@@ -94,9 +94,10 @@ function choose(id: string) {
|
|
|
94
94
|
<!-- left: selectable options -->
|
|
95
95
|
<ul class="w-1/2 shrink-0 overflow-y-auto border-e border-default p-1">
|
|
96
96
|
<li v-if="noneLabel !== undefined">
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
<UButton
|
|
98
|
+
color="neutral"
|
|
99
|
+
variant="ghost"
|
|
100
|
+
class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-start text-sm hover:bg-elevated/60"
|
|
100
101
|
:class="modelValue ? 'text-toned' : 'text-app-100'"
|
|
101
102
|
data-testid="pipeline-option-none"
|
|
102
103
|
@mouseenter="hoverId = ''"
|
|
@@ -109,12 +110,13 @@ function choose(id: string) {
|
|
|
109
110
|
name="i-lucide-check"
|
|
110
111
|
class="h-4 w-4 shrink-0 text-primary"
|
|
111
112
|
/>
|
|
112
|
-
</
|
|
113
|
+
</UButton>
|
|
113
114
|
</li>
|
|
114
115
|
<li v-for="p in options" :key="p.id">
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
<UButton
|
|
117
|
+
color="neutral"
|
|
118
|
+
variant="ghost"
|
|
119
|
+
class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-start text-sm hover:bg-elevated/60"
|
|
118
120
|
:class="modelValue === p.id ? 'text-app-100' : 'text-toned'"
|
|
119
121
|
:data-testid="`pipeline-option-${p.id}`"
|
|
120
122
|
@mouseenter="hoverId = p.id"
|
|
@@ -127,14 +129,14 @@ function choose(id: string) {
|
|
|
127
129
|
name="i-lucide-check"
|
|
128
130
|
class="h-4 w-4 shrink-0 text-primary"
|
|
129
131
|
/>
|
|
130
|
-
</
|
|
132
|
+
</UButton>
|
|
131
133
|
</li>
|
|
132
134
|
</ul>
|
|
133
135
|
|
|
134
136
|
<!-- right: preview of the hovered (or selected) pipeline -->
|
|
135
137
|
<div class="w-1/2 overflow-y-auto p-3">
|
|
136
138
|
<PipelinePreview v-if="previewPipeline" :pipeline="previewPipeline" />
|
|
137
|
-
<div v-else class="text-
|
|
139
|
+
<div v-else class="text-xs leading-snug text-dimmed">{{ emptyHint }}</div>
|
|
138
140
|
</div>
|
|
139
141
|
</div>
|
|
140
142
|
</template>
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
pipelineGateCount,
|
|
19
19
|
} from '~/utils/pipeline'
|
|
20
20
|
import AgentKindIcon from '~/components/pipeline/AgentKindIcon.vue'
|
|
21
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
21
22
|
|
|
22
23
|
const props = defineProps<{ pipeline: Pipeline }>()
|
|
23
24
|
const { t } = useI18n()
|
|
@@ -37,15 +38,13 @@ function stepDescription(kind: string): string {
|
|
|
37
38
|
<div class="text-sm font-semibold text-app-100">{{ pipeline.name }}</div>
|
|
38
39
|
<p
|
|
39
40
|
v-if="pipeline.description"
|
|
40
|
-
class="text-
|
|
41
|
+
class="text-xs leading-snug text-muted"
|
|
41
42
|
data-testid="pipeline-preview-description"
|
|
42
43
|
>
|
|
43
44
|
{{ pipeline.description }}
|
|
44
45
|
</p>
|
|
45
46
|
|
|
46
|
-
<
|
|
47
|
-
class="flex flex-wrap items-center gap-x-3 gap-y-1 text-[10px] uppercase tracking-wide text-dimmed"
|
|
48
|
-
>
|
|
47
|
+
<SectionLabel class="flex flex-wrap items-center gap-x-3 gap-y-1">
|
|
49
48
|
<span class="inline-flex items-center gap-1">
|
|
50
49
|
<UIcon name="i-lucide-workflow" class="h-3 w-3" />
|
|
51
50
|
{{ t('pipeline.preview.stepCount', { count: steps.length }, steps.length) }}
|
|
@@ -62,7 +61,7 @@ function stepDescription(kind: string): string {
|
|
|
62
61
|
<UIcon name="i-lucide-git-branch" class="h-3 w-3" />
|
|
63
62
|
{{ t('pipeline.preview.conditionalCount', { count: conditionalCount }, conditionalCount) }}
|
|
64
63
|
</span>
|
|
65
|
-
</
|
|
64
|
+
</SectionLabel>
|
|
66
65
|
|
|
67
66
|
<!-- The ordered steps. The number column doubles as the flow connector (a rule drawn between
|
|
68
67
|
consecutive numbers), so the list reads as a sequence rather than an unordered set. -->
|
|
@@ -76,7 +75,7 @@ function stepDescription(kind: string): string {
|
|
|
76
75
|
>
|
|
77
76
|
<div class="flex flex-col items-center">
|
|
78
77
|
<span
|
|
79
|
-
class="flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-elevated font-mono text-
|
|
78
|
+
class="flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-elevated font-mono text-3xs tabular-nums text-muted"
|
|
80
79
|
>
|
|
81
80
|
{{ i + 1 }}
|
|
82
81
|
</span>
|
|
@@ -101,7 +100,7 @@ function stepDescription(kind: string): string {
|
|
|
101
100
|
</div>
|
|
102
101
|
<!-- Clamped: the catalog prose runs long for some kinds, and <AgentKindIcon> already
|
|
103
102
|
carries the full text in its hover tooltip. -->
|
|
104
|
-
<p class="line-clamp-2 text-
|
|
103
|
+
<p class="line-clamp-2 text-2xs leading-snug text-dimmed">
|
|
105
104
|
{{ stepDescription(s.kind) }}
|
|
106
105
|
</p>
|
|
107
106
|
</div>
|
|
@@ -20,6 +20,8 @@ import StepMetricsBar from '~/components/observability/StepMetricsBar.vue'
|
|
|
20
20
|
import PrReviewPhaseBadge from '~/components/prReview/PrReviewPhaseBadge.vue'
|
|
21
21
|
import { useNowTick, stepDurationLabel } from '~/composables/useStepTimer'
|
|
22
22
|
import type { BadgeColor } from '~/utils/badge'
|
|
23
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
24
|
+
import IconButton from '~/components/common/IconButton.vue'
|
|
23
25
|
|
|
24
26
|
const props = defineProps<{ instance: ExecutionInstance }>()
|
|
25
27
|
const emit = defineEmits<{
|
|
@@ -292,7 +294,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
292
294
|
<span
|
|
293
295
|
v-for="l in legend"
|
|
294
296
|
:key="l.state"
|
|
295
|
-
class="inline-flex items-center gap-1.5 text-
|
|
297
|
+
class="inline-flex items-center gap-1.5 text-2xs text-muted"
|
|
296
298
|
>
|
|
297
299
|
<span
|
|
298
300
|
class="h-2 w-2 rounded-full"
|
|
@@ -365,15 +367,13 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
365
367
|
</span>
|
|
366
368
|
<span
|
|
367
369
|
v-if="isCompanionKind(s.agentKind)"
|
|
368
|
-
class="shrink-0 rounded bg-accented/60 px-1 text-
|
|
370
|
+
class="shrink-0 rounded-sm bg-accented/60 px-1 text-3xs font-medium uppercase tracking-wide text-toned"
|
|
369
371
|
:title="t('pipeline.progress.companionTooltip')"
|
|
370
372
|
>
|
|
371
373
|
{{ t('pipeline.progress.companion') }}
|
|
372
374
|
</span>
|
|
373
375
|
</div>
|
|
374
|
-
<
|
|
375
|
-
class="flex items-center gap-1.5 text-[10px] uppercase tracking-wide text-dimmed"
|
|
376
|
-
>
|
|
376
|
+
<SectionLabel class="flex items-center gap-1.5">
|
|
377
377
|
<span>{{ t('pipeline.progress.stepOf', { current: i + 1, total }) }}</span>
|
|
378
378
|
<!-- live elapsed clock: a running step counts up (so no-subtask steps
|
|
379
379
|
don't read as hung), a finished step shows its total duration -->
|
|
@@ -385,10 +385,10 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
385
385
|
<UIcon name="i-lucide-clock" class="h-2.5 w-2.5 shrink-0" />
|
|
386
386
|
{{ stepElapsed(s) }}
|
|
387
387
|
</span>
|
|
388
|
-
</
|
|
388
|
+
</SectionLabel>
|
|
389
389
|
</div>
|
|
390
390
|
<span
|
|
391
|
-
class="ms-auto shrink-0 text-
|
|
391
|
+
class="ms-auto shrink-0 text-2xs font-medium"
|
|
392
392
|
:style="{ color: stepVisual(s).color }"
|
|
393
393
|
>
|
|
394
394
|
{{ stepVisual(s).label }}
|
|
@@ -398,14 +398,14 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
398
398
|
(resetting later steps is destructive). Stops propagation so it
|
|
399
399
|
doesn't also open the step-detail overlay. -->
|
|
400
400
|
<template v-if="canRestart(s)">
|
|
401
|
-
<
|
|
401
|
+
<IconButton
|
|
402
402
|
v-if="restartArmed !== i"
|
|
403
403
|
icon="i-lucide-rotate-ccw"
|
|
404
404
|
color="neutral"
|
|
405
405
|
variant="ghost"
|
|
406
406
|
size="xs"
|
|
407
|
-
class="shrink-0 opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100 focus-
|
|
408
|
-
:
|
|
407
|
+
class="shrink-0 opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100 focus-within:opacity-100"
|
|
408
|
+
:label="t('pipeline.progress.restartTooltip')"
|
|
409
409
|
@click.stop="
|
|
410
410
|
() => {
|
|
411
411
|
restartArmed = i
|
|
@@ -458,7 +458,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
458
458
|
<!-- container cold-boot phase: shown while the container is spinning up. -->
|
|
459
459
|
<div
|
|
460
460
|
v-if="s.container?.status === 'starting' && !runFailed"
|
|
461
|
-
class="mt-2 flex items-center gap-1.5 text-
|
|
461
|
+
class="mt-2 flex items-center gap-1.5 text-2xs text-app-info-300"
|
|
462
462
|
>
|
|
463
463
|
<UIcon name="i-lucide-loader-circle" class="h-3.5 w-3.5 shrink-0 animate-spin" />
|
|
464
464
|
<span>{{ t('pipeline.progress.spinningUpContainer') }}</span>
|
|
@@ -468,7 +468,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
468
468
|
making calls) so the step isn't a blank "working" before subtasks appear. -->
|
|
469
469
|
<div
|
|
470
470
|
v-else-if="stepPhaseLabel(s) && !runFailed"
|
|
471
|
-
class="mt-2 flex items-center gap-1.5 text-
|
|
471
|
+
class="mt-2 flex items-center gap-1.5 text-2xs text-app-success-300"
|
|
472
472
|
>
|
|
473
473
|
<UIcon name="i-lucide-box" class="h-3.5 w-3.5 shrink-0" />
|
|
474
474
|
<span>{{ stepPhaseLabel(s) }}</span>
|
|
@@ -481,14 +481,14 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
481
481
|
v-if="prPhaseActive(s)"
|
|
482
482
|
:step="s"
|
|
483
483
|
:run-failed="runFailed"
|
|
484
|
-
class="mt-2 text-
|
|
484
|
+
class="mt-2 text-2xs"
|
|
485
485
|
/>
|
|
486
486
|
|
|
487
487
|
<!-- live subtask counts from the agent's todo list -->
|
|
488
488
|
<div v-if="s.subtasks && s.subtasks.total > 0" class="mt-2">
|
|
489
489
|
<div
|
|
490
490
|
v-if="!prPhaseActive(s)"
|
|
491
|
-
class="flex items-center justify-between text-
|
|
491
|
+
class="flex items-center justify-between text-3xs text-muted"
|
|
492
492
|
>
|
|
493
493
|
<span>
|
|
494
494
|
{{
|
|
@@ -515,7 +515,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
515
515
|
<li
|
|
516
516
|
v-for="(item, i) in s.subtasks.items"
|
|
517
517
|
:key="i"
|
|
518
|
-
class="flex items-start gap-1.5 text-
|
|
518
|
+
class="flex items-start gap-1.5 text-2xs"
|
|
519
519
|
:class="
|
|
520
520
|
item.status === 'completed'
|
|
521
521
|
? 'text-dimmed line-through'
|
|
@@ -537,7 +537,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
537
537
|
<!-- model used for this step -->
|
|
538
538
|
<p
|
|
539
539
|
v-if="s.model"
|
|
540
|
-
class="mt-2 flex items-center gap-1 truncate text-
|
|
540
|
+
class="mt-2 flex items-center gap-1 truncate text-3xs text-dimmed"
|
|
541
541
|
:title="s.model"
|
|
542
542
|
>
|
|
543
543
|
<UIcon name="i-lucide-cpu" class="h-3 w-3 shrink-0" />
|
|
@@ -557,7 +557,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
557
557
|
|
|
558
558
|
<!-- A one-line hint that the agent produced prose; the full output (and
|
|
559
559
|
all step metadata) lives in the step-detail overlay opened by click. -->
|
|
560
|
-
<p v-if="stepHasOutput(s)" class="mt-2 flex items-center gap-1 text-
|
|
560
|
+
<p v-if="stepHasOutput(s)" class="mt-2 flex items-center gap-1 text-2xs text-dimmed">
|
|
561
561
|
<UIcon name="i-lucide-book-open-text" class="h-3 w-3 shrink-0" />
|
|
562
562
|
{{ t('pipeline.progress.clickToRead') }}
|
|
563
563
|
</p>
|
|
@@ -567,7 +567,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
567
567
|
which reads as a tester that silently did its job. -->
|
|
568
568
|
<p
|
|
569
569
|
v-if="stepSkipReasonKey(s)"
|
|
570
|
-
class="mt-2 flex items-center gap-1 text-
|
|
570
|
+
class="mt-2 flex items-center gap-1 text-2xs text-dimmed"
|
|
571
571
|
data-testid="step-skip-reason"
|
|
572
572
|
>
|
|
573
573
|
<UIcon name="i-lucide-skip-forward" class="h-3 w-3 shrink-0" />
|
|
@@ -593,12 +593,12 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
593
593
|
]"
|
|
594
594
|
/>
|
|
595
595
|
</span>
|
|
596
|
-
<span class="min-w-0 flex-1 truncate text-
|
|
596
|
+
<span class="min-w-0 flex-1 truncate text-xs text-toned">
|
|
597
597
|
{{ agentKindMeta(companionByStep[i]!.kind).label }}
|
|
598
598
|
<span class="text-dimmed">{{ t('pipeline.progress.companionSuffix') }}</span>
|
|
599
599
|
</span>
|
|
600
600
|
<span
|
|
601
|
-
class="shrink-0 text-
|
|
601
|
+
class="shrink-0 text-2xs font-medium"
|
|
602
602
|
:class="COMPANION_STATE_META[companionByStep[i]!.state].text"
|
|
603
603
|
>
|
|
604
604
|
{{ COMPANION_STATE_META[companionByStep[i]!.state].label }}
|
|
@@ -608,14 +608,15 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
608
608
|
<!-- Follow-up companion (future-looking Coder): a blinking chip that lights up the
|
|
609
609
|
moment the Coder streams an item; click to triage. Blinks while any item is
|
|
610
610
|
undecided (the gate holds the pipeline until they're all decided). -->
|
|
611
|
-
<
|
|
611
|
+
<UButton
|
|
612
|
+
color="neutral"
|
|
613
|
+
variant="ghost"
|
|
612
614
|
v-if="s.followUps?.enabled"
|
|
613
|
-
type="button"
|
|
614
615
|
class="mt-3 flex w-full items-center gap-2 rounded-lg border border-dashed px-2.5 py-1.5 text-start transition hover:border-app-hue-pink/60"
|
|
615
616
|
:class="
|
|
616
617
|
followUpPending(s) > 0
|
|
617
|
-
? 'border-app-hue-pink/50 bg-app-hue-pink/10 followup-blink'
|
|
618
|
-
: 'border-muted/70 bg-default/40'
|
|
618
|
+
? 'border-app-hue-pink/50 bg-app-hue-pink/10 hover:bg-app-hue-pink/10 focus-visible:bg-app-hue-pink/10 disabled:bg-app-hue-pink/10 followup-blink'
|
|
619
|
+
: 'border-muted/70 bg-default/40 hover:bg-default/40 focus-visible:bg-default/40 disabled:bg-default/40'
|
|
619
620
|
"
|
|
620
621
|
@click="ui.openFollowUps(instance.id, i)"
|
|
621
622
|
>
|
|
@@ -624,30 +625,31 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
624
625
|
>
|
|
625
626
|
<UIcon :name="FOLLOW_UP_COMPANION_META.icon" class="h-3 w-3 text-app-hue-pink" />
|
|
626
627
|
</span>
|
|
627
|
-
<span class="min-w-0 flex-1 truncate text-
|
|
628
|
+
<span class="min-w-0 flex-1 truncate text-xs text-toned">
|
|
628
629
|
{{ FOLLOW_UP_COMPANION_META.label }}
|
|
629
630
|
<span class="text-dimmed">{{ t('pipeline.progress.companionSuffix') }}</span>
|
|
630
631
|
</span>
|
|
631
632
|
<span
|
|
632
|
-
class="shrink-0 text-
|
|
633
|
+
class="shrink-0 text-2xs font-medium"
|
|
633
634
|
:class="followUpPending(s) > 0 ? 'text-app-hue-pink' : 'text-muted'"
|
|
634
635
|
>
|
|
635
636
|
{{ followUpLabel(s) }}
|
|
636
637
|
</span>
|
|
637
|
-
</
|
|
638
|
+
</UButton>
|
|
638
639
|
|
|
639
640
|
<!-- Implementation-fork decision phase (Coder step): a spinner while the proposer
|
|
640
641
|
surfaces approaches, then a clickable chip to choose one. -->
|
|
641
|
-
<
|
|
642
|
+
<UButton
|
|
643
|
+
color="neutral"
|
|
644
|
+
variant="ghost"
|
|
642
645
|
v-if="forkPhase(s)"
|
|
643
|
-
type="button"
|
|
644
646
|
data-testid="fork-decision-open"
|
|
645
647
|
:data-fork-phase="forkPhase(s)"
|
|
646
648
|
class="mt-3 flex w-full items-center gap-2 rounded-lg border border-dashed px-2.5 py-1.5 text-start transition hover:border-app-secondary-400/60"
|
|
647
649
|
:class="
|
|
648
650
|
forkPhase(s) === 'awaiting_choice'
|
|
649
|
-
? 'border-app-secondary-500/50 bg-app-secondary-500/10 followup-blink'
|
|
650
|
-
: 'border-muted/70 bg-default/40'
|
|
651
|
+
? 'border-app-secondary-500/50 bg-app-secondary-500/10 hover:bg-app-secondary-500/10 focus-visible:bg-app-secondary-500/10 disabled:bg-app-secondary-500/10 followup-blink'
|
|
652
|
+
: 'border-muted/70 bg-default/40 hover:bg-default/40 focus-visible:bg-default/40 disabled:bg-default/40'
|
|
651
653
|
"
|
|
652
654
|
:disabled="forkPhase(s) === 'proposing'"
|
|
653
655
|
@click="ui.openForkDecision(instance.id, i)"
|
|
@@ -663,23 +665,24 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
663
665
|
:class="forkPhase(s) === 'proposing' ? 'animate-spin' : ''"
|
|
664
666
|
/>
|
|
665
667
|
</span>
|
|
666
|
-
<span class="min-w-0 flex-1 truncate text-
|
|
668
|
+
<span class="min-w-0 flex-1 truncate text-xs text-toned">
|
|
667
669
|
{{
|
|
668
670
|
forkPhase(s) === 'proposing'
|
|
669
671
|
? t('pipeline.progress.forkDecision.proposing')
|
|
670
672
|
: t('pipeline.progress.forkDecision.choose')
|
|
671
673
|
}}
|
|
672
674
|
</span>
|
|
673
|
-
</
|
|
675
|
+
</UButton>
|
|
674
676
|
|
|
675
677
|
<!-- PR deep-review parked for a human to select which findings matter: a
|
|
676
678
|
purpose-built chip opening the findings-selection window, ahead of the
|
|
677
679
|
generic approval gate (mirrors the fork-decision chip above). -->
|
|
678
|
-
<
|
|
680
|
+
<UButton
|
|
681
|
+
color="neutral"
|
|
682
|
+
variant="ghost"
|
|
679
683
|
v-if="prReviewAwaiting(s)"
|
|
680
|
-
type="button"
|
|
681
684
|
data-testid="pr-review-open"
|
|
682
|
-
class="mt-3 flex w-full items-center gap-2 rounded-lg border border-dashed border-primary/50 bg-primary/10 px-2.5 py-1.5 text-start transition followup-blink hover:border-primary/60"
|
|
685
|
+
class="mt-3 flex w-full items-center gap-2 rounded-lg border border-dashed border-primary/50 bg-primary/10 hover:bg-primary/10 focus-visible:bg-primary/10 disabled:bg-primary/10 px-2.5 py-1.5 text-start transition followup-blink hover:border-primary/60"
|
|
683
686
|
@click="ui.openPrReview(instance.id, i)"
|
|
684
687
|
>
|
|
685
688
|
<span
|
|
@@ -687,21 +690,22 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
687
690
|
>
|
|
688
691
|
<UIcon name="i-lucide-clipboard-check" class="h-3 w-3 text-primary" />
|
|
689
692
|
</span>
|
|
690
|
-
<span class="min-w-0 flex-1 truncate text-
|
|
693
|
+
<span class="min-w-0 flex-1 truncate text-xs text-toned">
|
|
691
694
|
{{ t('pipeline.progress.prReview.review') }}
|
|
692
695
|
</span>
|
|
693
|
-
</
|
|
696
|
+
</UButton>
|
|
694
697
|
|
|
695
698
|
<!-- A generating step parked between its candidate pass and its delivering pass: a
|
|
696
699
|
purpose-built chip opening the comparison window, ahead of the generic approval
|
|
697
700
|
gate (mirrors the fork-decision and pr-review chips above). Without it the step
|
|
698
701
|
shows no action at all, because the generic gate below is suppressed for every
|
|
699
702
|
park a dedicated window owns. -->
|
|
700
|
-
<
|
|
703
|
+
<UButton
|
|
704
|
+
color="neutral"
|
|
705
|
+
variant="ghost"
|
|
701
706
|
v-if="candidatesAwaiting(s)"
|
|
702
|
-
type="button"
|
|
703
707
|
data-testid="binary-candidates-open"
|
|
704
|
-
class="mt-3 flex w-full items-center gap-2 rounded-lg border border-dashed border-app-hue-cyan/50 bg-app-hue-cyan/10 px-2.5 py-1.5 text-start transition followup-blink hover:border-app-hue-cyan/60"
|
|
708
|
+
class="mt-3 flex w-full items-center gap-2 rounded-lg border border-dashed border-app-hue-cyan/50 bg-app-hue-cyan/10 hover:bg-app-hue-cyan/10 focus-visible:bg-app-hue-cyan/10 disabled:bg-app-hue-cyan/10 px-2.5 py-1.5 text-start transition followup-blink hover:border-app-hue-cyan/60"
|
|
705
709
|
@click="ui.openBinaryCandidates(instance.id, i)"
|
|
706
710
|
>
|
|
707
711
|
<span
|
|
@@ -712,16 +716,16 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
712
716
|
class="h-3 w-3 text-app-hue-cyan"
|
|
713
717
|
/>
|
|
714
718
|
</span>
|
|
715
|
-
<span class="min-w-0 flex-1 truncate text-
|
|
719
|
+
<span class="min-w-0 flex-1 truncate text-xs text-toned">
|
|
716
720
|
{{ t('pipeline.progress.binaryCandidates.choose') }}
|
|
717
721
|
</span>
|
|
718
|
-
</
|
|
722
|
+
</UButton>
|
|
719
723
|
|
|
720
724
|
<!-- reviewer gate folding/re-reviewing in the background: a working indicator,
|
|
721
725
|
NOT a "Review & approve" gate (the human is summoned only if needed) -->
|
|
722
726
|
<div
|
|
723
727
|
v-if="reviewStageLabel(s.agentKind)"
|
|
724
|
-
class="mt-3 inline-flex items-center gap-1 text-
|
|
728
|
+
class="mt-3 inline-flex items-center gap-1 text-2xs text-primary"
|
|
725
729
|
>
|
|
726
730
|
<UIcon name="i-lucide-loader-circle" class="h-3 w-3 animate-spin" />
|
|
727
731
|
{{ reviewStageLabel(s.agentKind) }}
|
|
@@ -766,7 +770,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
766
770
|
</div>
|
|
767
771
|
<p
|
|
768
772
|
v-else-if="s.decision?.chosen"
|
|
769
|
-
class="mt-2 flex items-center gap-1 truncate text-
|
|
773
|
+
class="mt-2 flex items-center gap-1 truncate text-2xs text-app-success-400"
|
|
770
774
|
:title="s.decision.chosen"
|
|
771
775
|
>
|
|
772
776
|
<UIcon name="i-lucide-check" class="h-3 w-3 shrink-0" />
|