@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
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
// summary instead (so there is nothing to show here).
|
|
8
8
|
import type { FragmentAdherence } from '~/types/execution'
|
|
9
9
|
import MarkdownProse from '~/components/common/MarkdownProse.vue'
|
|
10
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
10
11
|
|
|
11
12
|
const props = defineProps<{ items: FragmentAdherence }>()
|
|
12
13
|
const { t } = useI18n()
|
|
@@ -34,14 +35,12 @@ function label(item: FragmentAdherence[number]): string {
|
|
|
34
35
|
data-testid="step-fragment-adherence"
|
|
35
36
|
class="scroll-mt-4 rounded-xl border border-default bg-default/50 p-4"
|
|
36
37
|
>
|
|
37
|
-
<
|
|
38
|
-
class="mb-2 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted"
|
|
39
|
-
>
|
|
38
|
+
<SectionLabel class="mb-2 flex items-center gap-1.5">
|
|
40
39
|
<UIcon name="i-lucide-clipboard-check" class="h-3.5 w-3.5" />
|
|
41
40
|
<span :title="t('panels.stepDetail.adherence.headingHint')">
|
|
42
41
|
{{ t('panels.stepDetail.adherence.heading') }}
|
|
43
42
|
</span>
|
|
44
|
-
</
|
|
43
|
+
</SectionLabel>
|
|
45
44
|
|
|
46
45
|
<div class="space-y-2.5">
|
|
47
46
|
<article
|
|
@@ -51,7 +50,7 @@ function label(item: FragmentAdherence[number]): string {
|
|
|
51
50
|
class="rounded-lg border border-default bg-default/60 px-3 py-2"
|
|
52
51
|
>
|
|
53
52
|
<div class="flex items-center gap-2">
|
|
54
|
-
<span class="min-w-0 flex-1 truncate text-
|
|
53
|
+
<span class="min-w-0 flex-1 truncate text-sm font-medium text-app-100">{{
|
|
55
54
|
label(item)
|
|
56
55
|
}}</span>
|
|
57
56
|
<div class="h-1.5 w-16 shrink-0 overflow-hidden rounded-full bg-accented/60">
|
|
@@ -62,7 +61,7 @@ function label(item: FragmentAdherence[number]): string {
|
|
|
62
61
|
/>
|
|
63
62
|
</div>
|
|
64
63
|
<span
|
|
65
|
-
class="shrink-0 text-
|
|
64
|
+
class="shrink-0 text-xs font-medium text-default"
|
|
66
65
|
:title="t('panels.stepDetail.adherence.ratingHint')"
|
|
67
66
|
>
|
|
68
67
|
{{ t('panels.stepDetail.adherence.outOfTen', { value: item.rating }) }}
|
|
@@ -71,17 +70,17 @@ function label(item: FragmentAdherence[number]): string {
|
|
|
71
70
|
<MarkdownProse
|
|
72
71
|
v-if="item.assessment"
|
|
73
72
|
:text="item.assessment"
|
|
74
|
-
class="mt-1 text-
|
|
73
|
+
class="mt-1 text-xs leading-relaxed text-toned"
|
|
75
74
|
/>
|
|
76
75
|
<div v-if="item.relatedFindings.length" class="mt-1.5">
|
|
77
|
-
<
|
|
76
|
+
<SectionLabel as="p">
|
|
78
77
|
{{ t('panels.stepDetail.adherence.relatedFindings') }}
|
|
79
|
-
</
|
|
78
|
+
</SectionLabel>
|
|
80
79
|
<ul class="mt-0.5 space-y-0.5">
|
|
81
80
|
<li
|
|
82
81
|
v-for="(finding, fi) in item.relatedFindings"
|
|
83
82
|
:key="fi"
|
|
84
|
-
class="flex items-start gap-1.5 text-
|
|
83
|
+
class="flex items-start gap-1.5 text-2xs text-muted"
|
|
85
84
|
>
|
|
86
85
|
<UIcon name="i-lucide-dot" class="mt-0.5 h-3.5 w-3.5 shrink-0" />
|
|
87
86
|
<span>{{ finding }}</span>
|
|
@@ -13,6 +13,7 @@ import StepContainerStatus from '~/components/panels/StepContainerStatus.vue'
|
|
|
13
13
|
import StepDelegatedStatus from '~/components/panels/StepDelegatedStatus.vue'
|
|
14
14
|
import CopyButton from '~/components/common/CopyButton.vue'
|
|
15
15
|
import MarkdownProse from '~/components/common/MarkdownProse.vue'
|
|
16
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
16
17
|
|
|
17
18
|
// The step's metadata card body: state/timing/model/run id, the container cold-boot
|
|
18
19
|
// phase, the live subtask breakdown, the LLM observability rollup, the applied
|
|
@@ -182,11 +183,11 @@ async function copyRunId() {
|
|
|
182
183
|
|
|
183
184
|
<template>
|
|
184
185
|
<div>
|
|
185
|
-
<dl class="grid grid-cols-2 gap-x-6 gap-y-3 text-
|
|
186
|
+
<dl class="grid grid-cols-2 gap-x-6 gap-y-3 text-sm sm:grid-cols-3">
|
|
186
187
|
<div>
|
|
187
|
-
<
|
|
188
|
+
<SectionLabel as="dt">
|
|
188
189
|
{{ t('panels.stepMeta.stateLabel') }}
|
|
189
|
-
</
|
|
190
|
+
</SectionLabel>
|
|
190
191
|
<dd class="mt-0.5 flex items-center gap-1.5 text-default">
|
|
191
192
|
<UIcon
|
|
192
193
|
v-if="runFailed && step.state === 'working'"
|
|
@@ -199,9 +200,9 @@ async function copyRunId() {
|
|
|
199
200
|
</dd>
|
|
200
201
|
</div>
|
|
201
202
|
<div>
|
|
202
|
-
<
|
|
203
|
+
<SectionLabel as="dt">
|
|
203
204
|
{{ t('panels.stepMeta.duration') }}
|
|
204
|
-
</
|
|
205
|
+
</SectionLabel>
|
|
205
206
|
<dd class="mt-0.5 flex items-center gap-1.5 tabular-nums text-default">
|
|
206
207
|
<UIcon
|
|
207
208
|
v-if="isRunning"
|
|
@@ -210,55 +211,55 @@ async function copyRunId() {
|
|
|
210
211
|
/>
|
|
211
212
|
<span v-if="durationLabel">{{ durationLabel }}</span>
|
|
212
213
|
<span v-else class="text-dimmed">—</span>
|
|
213
|
-
<span v-if="isRunning" class="text-
|
|
214
|
+
<span v-if="isRunning" class="text-2xs text-dimmed">{{
|
|
214
215
|
t('panels.stepMeta.elapsed')
|
|
215
216
|
}}</span>
|
|
216
217
|
</dd>
|
|
217
218
|
</div>
|
|
218
219
|
<div>
|
|
219
|
-
<
|
|
220
|
+
<SectionLabel as="dt">
|
|
220
221
|
{{ t('panels.stepMeta.step') }}
|
|
221
|
-
</
|
|
222
|
+
</SectionLabel>
|
|
222
223
|
<dd class="mt-0.5 text-default">
|
|
223
224
|
{{ t('panels.stepMeta.stepOf', { number: stepNumber, total: totalSteps }) }}
|
|
224
225
|
</dd>
|
|
225
226
|
</div>
|
|
226
227
|
<div>
|
|
227
|
-
<
|
|
228
|
+
<SectionLabel as="dt">
|
|
228
229
|
{{ t('panels.stepMeta.started') }}
|
|
229
|
-
</
|
|
230
|
+
</SectionLabel>
|
|
230
231
|
<dd class="mt-0.5 text-toned">{{ formatClock(step.startedAt) ?? '—' }}</dd>
|
|
231
232
|
</div>
|
|
232
233
|
<div>
|
|
233
|
-
<
|
|
234
|
+
<SectionLabel as="dt">
|
|
234
235
|
{{ t('panels.stepMeta.finished') }}
|
|
235
|
-
</
|
|
236
|
+
</SectionLabel>
|
|
236
237
|
<dd class="mt-0.5 text-toned">{{ formatClock(step.finishedAt) ?? '—' }}</dd>
|
|
237
238
|
</div>
|
|
238
239
|
<div>
|
|
239
|
-
<
|
|
240
|
+
<SectionLabel as="dt">
|
|
240
241
|
{{ t('panels.stepMeta.model') }}
|
|
241
|
-
</
|
|
242
|
+
</SectionLabel>
|
|
242
243
|
<dd class="mt-0.5 truncate text-toned" :title="step.model">
|
|
243
244
|
{{ modelLabel ?? t('panels.stepMeta.notRecorded') }}
|
|
244
245
|
</dd>
|
|
245
246
|
</div>
|
|
246
247
|
<div v-if="promptVariant">
|
|
247
|
-
<
|
|
248
|
+
<SectionLabel as="dt">
|
|
248
249
|
{{ t('panels.stepMeta.promptVariant') }}
|
|
249
|
-
</
|
|
250
|
+
</SectionLabel>
|
|
250
251
|
<dd class="mt-0.5 truncate text-toned">{{ promptVariant.label }}</dd>
|
|
251
|
-
<dd v-if="promptVariant.note" class="mt-0.5 text-
|
|
252
|
+
<dd v-if="promptVariant.note" class="mt-0.5 text-2xs text-app-warning-400/80">
|
|
252
253
|
{{ promptVariant.note }}
|
|
253
254
|
</dd>
|
|
254
255
|
</div>
|
|
255
256
|
<!-- The run id this step belongs to, surfaced for debugging (copyable). -->
|
|
256
257
|
<div class="col-span-2 sm:col-span-3">
|
|
257
|
-
<
|
|
258
|
+
<SectionLabel as="dt">
|
|
258
259
|
{{ t('panels.stepMeta.run') }}
|
|
259
|
-
</
|
|
260
|
+
</SectionLabel>
|
|
260
261
|
<dd
|
|
261
|
-
class="mt-0.5 cursor-pointer truncate font-mono text-
|
|
262
|
+
class="mt-0.5 cursor-pointer truncate font-mono text-xs text-muted hover:text-default"
|
|
262
263
|
:title="t('panels.stepMeta.clickToCopy', { id: step.runId ?? instanceId ?? '' })"
|
|
263
264
|
@click="copyRunId"
|
|
264
265
|
>
|
|
@@ -284,14 +285,14 @@ async function copyRunId() {
|
|
|
284
285
|
|
|
285
286
|
<!-- live subtask breakdown -->
|
|
286
287
|
<div v-if="step.subtasks && step.subtasks.total > 0" class="mt-4">
|
|
287
|
-
<
|
|
288
|
+
<SectionLabel>
|
|
288
289
|
{{
|
|
289
290
|
t('panels.stepMeta.subtasks', {
|
|
290
291
|
completed: step.subtasks.completed,
|
|
291
292
|
total: step.subtasks.total,
|
|
292
293
|
})
|
|
293
294
|
}}
|
|
294
|
-
</
|
|
295
|
+
</SectionLabel>
|
|
295
296
|
<div class="mt-1 h-1 overflow-hidden rounded-full bg-accented/60">
|
|
296
297
|
<div
|
|
297
298
|
class="h-full rounded-full bg-primary transition-all duration-500"
|
|
@@ -304,7 +305,7 @@ async function copyRunId() {
|
|
|
304
305
|
<li
|
|
305
306
|
v-for="(item, idx) in step.subtasks.items"
|
|
306
307
|
:key="idx"
|
|
307
|
-
class="flex items-start gap-1.5 text-
|
|
308
|
+
class="flex items-start gap-1.5 text-xs"
|
|
308
309
|
:class="
|
|
309
310
|
item.status === 'completed'
|
|
310
311
|
? 'text-dimmed line-through'
|
|
@@ -335,12 +336,9 @@ async function copyRunId() {
|
|
|
335
336
|
|
|
336
337
|
<!-- standards (prompt fragments) folded into this step -->
|
|
337
338
|
<div v-if="step.selectedFragmentIds && step.selectedFragmentIds.length" class="mt-4">
|
|
338
|
-
<
|
|
339
|
-
class="text-[11px] uppercase tracking-wide text-dimmed"
|
|
340
|
-
:title="t('panels.stepMeta.standardsAppliedHint')"
|
|
341
|
-
>
|
|
339
|
+
<SectionLabel :title="t('panels.stepMeta.standardsAppliedHint')">
|
|
342
340
|
{{ t('panels.stepMeta.standardsApplied') }}
|
|
343
|
-
</
|
|
341
|
+
</SectionLabel>
|
|
344
342
|
<div class="mt-1 flex flex-wrap gap-1">
|
|
345
343
|
<UBadge
|
|
346
344
|
v-for="id in step.selectedFragmentIds"
|
|
@@ -356,28 +354,28 @@ async function copyRunId() {
|
|
|
356
354
|
|
|
357
355
|
<!-- decision raised on this step -->
|
|
358
356
|
<div v-if="step.decision" class="mt-4">
|
|
359
|
-
<
|
|
357
|
+
<SectionLabel>
|
|
360
358
|
{{ t('panels.stepMeta.decision') }}
|
|
361
|
-
</
|
|
362
|
-
<p class="mt-0.5 text-
|
|
359
|
+
</SectionLabel>
|
|
360
|
+
<p class="mt-0.5 text-sm text-default">{{ step.decision.question }}</p>
|
|
363
361
|
<p
|
|
364
362
|
v-if="step.decision.chosen"
|
|
365
|
-
class="mt-0.5 flex items-center gap-1 text-
|
|
363
|
+
class="mt-0.5 flex items-center gap-1 text-xs text-app-success-400"
|
|
366
364
|
>
|
|
367
365
|
<UIcon name="i-lucide-check" class="h-3 w-3 shrink-0" />
|
|
368
366
|
{{ step.decision.chosen }}
|
|
369
367
|
</p>
|
|
370
|
-
<p v-else class="mt-0.5 text-
|
|
368
|
+
<p v-else class="mt-0.5 text-xs text-app-warning-400">
|
|
371
369
|
{{ t('panels.stepMeta.awaitingChoice') }}
|
|
372
370
|
</p>
|
|
373
371
|
</div>
|
|
374
372
|
|
|
375
373
|
<!-- approval gate state -->
|
|
376
374
|
<div v-if="step.approval" class="mt-4">
|
|
377
|
-
<
|
|
375
|
+
<SectionLabel>
|
|
378
376
|
{{ t('panels.stepMeta.approvalGate') }}
|
|
379
|
-
</
|
|
380
|
-
<p class="mt-0.5 text-
|
|
377
|
+
</SectionLabel>
|
|
378
|
+
<p class="mt-0.5 text-sm text-default">
|
|
381
379
|
{{ approvalStatusLabel }}
|
|
382
380
|
</p>
|
|
383
381
|
</div>
|
|
@@ -385,9 +383,9 @@ async function copyRunId() {
|
|
|
385
383
|
<!-- companion verdict + full correction sequence -->
|
|
386
384
|
<div v-if="companionVerdicts.length" class="mt-4">
|
|
387
385
|
<div class="flex items-center justify-between">
|
|
388
|
-
<
|
|
386
|
+
<SectionLabel as="span">
|
|
389
387
|
{{ t('panels.stepMeta.companionReview') }}
|
|
390
|
-
</
|
|
388
|
+
</SectionLabel>
|
|
391
389
|
<!-- The COLOUR is the verdict (`passed`) and the GLYPH is the arithmetic, which are no
|
|
392
390
|
longer the same fact: a round holding an open `blocker` fails at a rating that cleared
|
|
393
391
|
its bar, and reading the inequality off `passed` printed "95% < 80%" over the findings
|
|
@@ -410,9 +408,9 @@ async function copyRunId() {
|
|
|
410
408
|
class="relative rounded-lg border border-default bg-default/60 px-3 py-2"
|
|
411
409
|
>
|
|
412
410
|
<CopyButton v-if="v.feedback" :text="v.feedback" class="absolute end-1 top-1" />
|
|
413
|
-
<div class="flex items-center gap-2 text-
|
|
411
|
+
<div class="flex items-center gap-2 text-xs">
|
|
414
412
|
<span
|
|
415
|
-
class="inline-flex h-4 shrink-0 items-center rounded px-1 font-mono text-
|
|
413
|
+
class="inline-flex h-4 shrink-0 items-center rounded-sm px-1 font-mono text-2xs tabular-nums"
|
|
416
414
|
:class="
|
|
417
415
|
v.passed
|
|
418
416
|
? 'bg-app-success-500/15 text-app-success-300'
|
|
@@ -429,7 +427,7 @@ async function copyRunId() {
|
|
|
429
427
|
v-if="v.feedback"
|
|
430
428
|
:text="v.feedback"
|
|
431
429
|
data-testid="companion-verdict-summary"
|
|
432
|
-
class="mt-1.5 pe-6 text-
|
|
430
|
+
class="mt-1.5 pe-6 text-xs leading-relaxed text-toned"
|
|
433
431
|
/>
|
|
434
432
|
<ul v-if="findings.length" class="mt-2 space-y-1.5">
|
|
435
433
|
<li
|
|
@@ -448,13 +446,13 @@ async function copyRunId() {
|
|
|
448
446
|
</UBadge>
|
|
449
447
|
<MarkdownProse
|
|
450
448
|
:text="finding.body"
|
|
451
|
-
class="min-w-0 text-
|
|
449
|
+
class="min-w-0 text-xs leading-relaxed text-toned"
|
|
452
450
|
/>
|
|
453
451
|
</li>
|
|
454
452
|
</ul>
|
|
455
453
|
</li>
|
|
456
454
|
</ol>
|
|
457
|
-
<p v-if="companionVerdicts.length > 1" class="mt-1 text-
|
|
455
|
+
<p v-if="companionVerdicts.length > 1" class="mt-1 text-2xs text-dimmed">
|
|
458
456
|
{{
|
|
459
457
|
t(
|
|
460
458
|
'panels.stepMeta.correctionIterations',
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { computed } from 'vue'
|
|
3
3
|
import type { ReproductionPhaseOutcome, ReproductionReport } from '~/types/reproduction'
|
|
4
4
|
import { REPRODUCTION_STATUS_KEYS, REPRODUCTION_TREE_KEYS } from '~/utils/reproduction'
|
|
5
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
5
6
|
|
|
6
7
|
// The BUGFIX REPRODUCTION PROOF for a step: the declared reproducing check as the
|
|
7
8
|
// executor-harness ran it against the pre-fix tree and against the final tree, with both captured
|
|
@@ -54,15 +55,12 @@ function phaseLabel(outcome: ReproductionPhaseOutcome): string {
|
|
|
54
55
|
variant === 'card' ? 'scroll-mt-4 rounded-xl border border-default bg-default/50 p-4' : ''
|
|
55
56
|
"
|
|
56
57
|
>
|
|
57
|
-
<
|
|
58
|
-
v-if="variant === 'card'"
|
|
59
|
-
class="flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted"
|
|
60
|
-
>
|
|
58
|
+
<SectionLabel v-if="variant === 'card'" class="flex items-center gap-1.5">
|
|
61
59
|
<UIcon :name="presentation.icon" class="h-3.5 w-3.5" />
|
|
62
60
|
<span>{{ t('panels.stepDetail.reproduction.heading') }}</span>
|
|
63
|
-
</
|
|
61
|
+
</SectionLabel>
|
|
64
62
|
|
|
65
|
-
<p class="text-
|
|
63
|
+
<p class="text-2xs text-muted" data-testid="reproduction-verdict">
|
|
66
64
|
{{ t(presentation.verdict) }}
|
|
67
65
|
</p>
|
|
68
66
|
|
|
@@ -72,7 +70,7 @@ function phaseLabel(outcome: ReproductionPhaseOutcome): string {
|
|
|
72
70
|
is exactly the inference that gets it wrong. -->
|
|
73
71
|
<p
|
|
74
72
|
v-if="report.note"
|
|
75
|
-
class="text-
|
|
73
|
+
class="text-2xs text-app-warning-300"
|
|
76
74
|
data-testid="reproduction-observation"
|
|
77
75
|
>
|
|
78
76
|
{{ report.note }}
|
|
@@ -82,19 +80,19 @@ function phaseLabel(outcome: ReproductionPhaseOutcome): string {
|
|
|
82
80
|
This is what keeps "could not be reproduced" from looking like "nobody tried". -->
|
|
83
81
|
<template v-if="report.status === 'declared_infeasible'">
|
|
84
82
|
<div v-if="report.reason" class="rounded-md border border-default bg-app-950/40 p-2">
|
|
85
|
-
<
|
|
83
|
+
<SectionLabel as="p">
|
|
86
84
|
{{ t('panels.stepDetail.reproduction.reason') }}
|
|
87
|
-
</
|
|
88
|
-
<p class="mt-1 whitespace-pre-wrap text-
|
|
85
|
+
</SectionLabel>
|
|
86
|
+
<p class="mt-1 whitespace-pre-wrap text-xs text-toned">{{ report.reason }}</p>
|
|
89
87
|
</div>
|
|
90
88
|
<div
|
|
91
89
|
v-if="report.alternativeVerification"
|
|
92
90
|
class="rounded-md border border-default bg-app-950/40 p-2"
|
|
93
91
|
>
|
|
94
|
-
<
|
|
92
|
+
<SectionLabel as="p">
|
|
95
93
|
{{ t('panels.stepDetail.reproduction.alternative') }}
|
|
96
|
-
</
|
|
97
|
-
<p class="mt-1 whitespace-pre-wrap text-
|
|
94
|
+
</SectionLabel>
|
|
95
|
+
<p class="mt-1 whitespace-pre-wrap text-xs text-toned">
|
|
98
96
|
{{ report.alternativeVerification }}
|
|
99
97
|
</p>
|
|
100
98
|
</div>
|
|
@@ -102,17 +100,17 @@ function phaseLabel(outcome: ReproductionPhaseOutcome): string {
|
|
|
102
100
|
|
|
103
101
|
<template v-else>
|
|
104
102
|
<div v-if="report.command" class="flex items-baseline gap-2">
|
|
105
|
-
<span class="shrink-0 text-
|
|
103
|
+
<span class="shrink-0 text-2xs text-dimmed">{{
|
|
106
104
|
t('panels.stepDetail.reproduction.command')
|
|
107
105
|
}}</span>
|
|
108
|
-
<span class="truncate font-mono text-
|
|
106
|
+
<span class="truncate font-mono text-2xs text-toned">{{ report.command }}</span>
|
|
109
107
|
</div>
|
|
110
108
|
|
|
111
109
|
<!-- A dropped path can leave the pre-fix tree without the reproduction, which greens it and
|
|
112
110
|
reads as "the test does not capture the defect". Stated, never implied. -->
|
|
113
111
|
<p
|
|
114
112
|
v-if="report.omittedTestPaths"
|
|
115
|
-
class="text-
|
|
113
|
+
class="text-2xs text-app-warning-300"
|
|
116
114
|
data-testid="reproduction-omitted-paths"
|
|
117
115
|
>
|
|
118
116
|
{{
|
|
@@ -142,10 +140,10 @@ function phaseLabel(outcome: ReproductionPhaseOutcome): string {
|
|
|
142
140
|
: 'text-app-600'
|
|
143
141
|
"
|
|
144
142
|
/>
|
|
145
|
-
<span class="text-
|
|
143
|
+
<span class="text-xs font-medium text-default">
|
|
146
144
|
{{ t(phase.label) }}
|
|
147
145
|
</span>
|
|
148
|
-
<span class="ms-auto shrink-0 text-
|
|
146
|
+
<span class="ms-auto shrink-0 text-2xs tabular-nums text-muted">
|
|
149
147
|
{{
|
|
150
148
|
phase.outcome ? phaseLabel(phase.outcome) : t('panels.stepDetail.reproduction.notRun')
|
|
151
149
|
}}
|
|
@@ -153,12 +151,12 @@ function phaseLabel(outcome: ReproductionPhaseOutcome): string {
|
|
|
153
151
|
</div>
|
|
154
152
|
<pre
|
|
155
153
|
v-if="phase.outcome?.outputTail"
|
|
156
|
-
class="mt-1.5 max-h-48 overflow-auto whitespace-pre-wrap break-words rounded bg-app-950 p-2 font-mono text-
|
|
154
|
+
class="mt-1.5 max-h-48 overflow-auto whitespace-pre-wrap break-words rounded-sm bg-app-950 p-2 font-mono text-2xs text-muted"
|
|
157
155
|
data-testid="reproduction-output"
|
|
158
156
|
>{{ phase.outcome.outputTail }}</pre>
|
|
159
157
|
</div>
|
|
160
158
|
|
|
161
|
-
<p class="text-
|
|
159
|
+
<p class="text-2xs text-dimmed">
|
|
162
160
|
{{
|
|
163
161
|
t('panels.stepDetail.reproduction.attempts', {
|
|
164
162
|
attempts: report.attempts,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ref, computed } from 'vue'
|
|
3
|
+
import IconButton from '~/components/common/IconButton.vue'
|
|
3
4
|
|
|
4
5
|
// Shared "Restart pipeline from this step" control.
|
|
5
6
|
//
|
|
@@ -57,13 +58,13 @@ async function restart() {
|
|
|
57
58
|
|
|
58
59
|
<template>
|
|
59
60
|
<template v-if="canRestart">
|
|
60
|
-
<
|
|
61
|
+
<IconButton
|
|
61
62
|
v-if="!armed"
|
|
62
63
|
icon="i-lucide-rotate-ccw"
|
|
63
64
|
color="neutral"
|
|
64
65
|
variant="ghost"
|
|
65
66
|
size="sm"
|
|
66
|
-
:
|
|
67
|
+
:label="t('panels.stepRestart.restartFromStep')"
|
|
67
68
|
@click="
|
|
68
69
|
() => {
|
|
69
70
|
armed = true
|
|
@@ -3,6 +3,7 @@ import { computed } from 'vue'
|
|
|
3
3
|
import type { PipelineStep } from '~/types/execution'
|
|
4
4
|
import { useStepTimer } from '~/composables/useStepTimer'
|
|
5
5
|
import StepModelActivity from '~/components/observability/StepModelActivity.vue'
|
|
6
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
6
7
|
|
|
7
8
|
// Shared run-metadata + observability block for the step-backed result windows
|
|
8
9
|
// (the CI/conflicts gate, the tester report). It carries the facts every step has in
|
|
@@ -57,26 +58,26 @@ async function copyRunId() {
|
|
|
57
58
|
<template>
|
|
58
59
|
<div class="flex flex-col gap-4">
|
|
59
60
|
<div v-if="stepNumber && totalSteps">
|
|
60
|
-
<h4 class="mb-1
|
|
61
|
+
<SectionLabel as="h4" class="mb-1">
|
|
61
62
|
{{ t('panels.stepMeta.step') }}
|
|
62
|
-
</
|
|
63
|
-
<p class="text-
|
|
63
|
+
</SectionLabel>
|
|
64
|
+
<p class="text-xs text-toned">
|
|
64
65
|
{{ t('panels.stepMeta.stepOf', { number: stepNumber, total: totalSteps }) }}
|
|
65
66
|
</p>
|
|
66
67
|
</div>
|
|
67
68
|
|
|
68
69
|
<div v-if="durationLabel">
|
|
69
|
-
<h4 class="mb-1
|
|
70
|
+
<SectionLabel as="h4" class="mb-1">
|
|
70
71
|
{{ t('panels.stepMeta.duration') }}
|
|
71
|
-
</
|
|
72
|
-
<p class="flex items-center gap-1.5 text-
|
|
72
|
+
</SectionLabel>
|
|
73
|
+
<p class="flex items-center gap-1.5 text-xs tabular-nums text-toned">
|
|
73
74
|
<UIcon
|
|
74
75
|
v-if="isRunning"
|
|
75
76
|
name="i-lucide-loader-circle"
|
|
76
77
|
class="h-3 w-3 animate-spin text-primary"
|
|
77
78
|
/>
|
|
78
79
|
{{ durationLabel }}
|
|
79
|
-
<span v-if="isRunning" class="text-
|
|
80
|
+
<span v-if="isRunning" class="text-2xs text-dimmed">{{
|
|
80
81
|
t('panels.stepMeta.elapsed')
|
|
81
82
|
}}</span>
|
|
82
83
|
</p>
|
|
@@ -86,54 +87,54 @@ async function copyRunId() {
|
|
|
86
87
|
the elapsed clock above — a long, quiet phase keeps this small while elapsed climbs, so a
|
|
87
88
|
genuinely-active-but-quiet run reads apart from a wedged one. Only while actively running. -->
|
|
88
89
|
<div v-if="isRunning && activityAgoLabel" data-testid="step-activity">
|
|
89
|
-
<h4 class="mb-1
|
|
90
|
+
<SectionLabel as="h4" class="mb-1">
|
|
90
91
|
{{ t('panels.stepMeta.activity') }}
|
|
91
|
-
</
|
|
92
|
-
<p class="flex items-center gap-1.5 text-
|
|
92
|
+
</SectionLabel>
|
|
93
|
+
<p class="flex items-center gap-1.5 text-xs tabular-nums text-toned">
|
|
93
94
|
<span class="h-1.5 w-1.5 rounded-full bg-app-success-400" />
|
|
94
95
|
{{ t('panels.stepMeta.activityAgo', { duration: activityAgoLabel }) }}
|
|
95
96
|
</p>
|
|
96
97
|
</div>
|
|
97
98
|
|
|
98
99
|
<div v-if="formatClock(step.startedAt)">
|
|
99
|
-
<h4 class="mb-1
|
|
100
|
+
<SectionLabel as="h4" class="mb-1">
|
|
100
101
|
{{ t('panels.stepMeta.started') }}
|
|
101
|
-
</
|
|
102
|
-
<p class="text-
|
|
102
|
+
</SectionLabel>
|
|
103
|
+
<p class="text-xs text-toned">{{ formatClock(step.startedAt) }}</p>
|
|
103
104
|
</div>
|
|
104
105
|
|
|
105
106
|
<div v-if="formatClock(step.finishedAt)">
|
|
106
|
-
<h4 class="mb-1
|
|
107
|
+
<SectionLabel as="h4" class="mb-1">
|
|
107
108
|
{{ t('panels.stepMeta.finished') }}
|
|
108
|
-
</
|
|
109
|
-
<p class="text-
|
|
109
|
+
</SectionLabel>
|
|
110
|
+
<p class="text-xs text-toned">{{ formatClock(step.finishedAt) }}</p>
|
|
110
111
|
</div>
|
|
111
112
|
|
|
112
113
|
<div v-if="step.model">
|
|
113
|
-
<h4 class="mb-1
|
|
114
|
+
<SectionLabel as="h4" class="mb-1">
|
|
114
115
|
{{ t('panels.stepMeta.model') }}
|
|
115
|
-
</
|
|
116
|
-
<p class="break-all text-
|
|
116
|
+
</SectionLabel>
|
|
117
|
+
<p class="break-all text-xs text-toned" :title="step.model">
|
|
117
118
|
{{ modelLabel ?? step.model }}
|
|
118
119
|
</p>
|
|
119
120
|
</div>
|
|
120
121
|
|
|
121
122
|
<div v-if="promptVariant">
|
|
122
|
-
<h4 class="mb-1
|
|
123
|
+
<SectionLabel as="h4" class="mb-1">
|
|
123
124
|
{{ t('panels.stepMeta.promptVariant') }}
|
|
124
|
-
</
|
|
125
|
-
<p class="break-all text-
|
|
126
|
-
<p v-if="promptVariant.note" class="mt-0.5 text-
|
|
125
|
+
</SectionLabel>
|
|
126
|
+
<p class="break-all text-xs text-toned">{{ promptVariant.label }}</p>
|
|
127
|
+
<p v-if="promptVariant.note" class="mt-0.5 text-2xs text-app-warning-400/80">
|
|
127
128
|
{{ promptVariant.note }}
|
|
128
129
|
</p>
|
|
129
130
|
</div>
|
|
130
131
|
|
|
131
132
|
<div v-if="runId">
|
|
132
|
-
<h4 class="mb-1
|
|
133
|
+
<SectionLabel as="h4" class="mb-1">
|
|
133
134
|
{{ t('panels.stepMeta.run') }}
|
|
134
|
-
</
|
|
135
|
+
</SectionLabel>
|
|
135
136
|
<p
|
|
136
|
-
class="cursor-pointer break-all font-mono text-
|
|
137
|
+
class="cursor-pointer break-all font-mono text-xs text-muted hover:text-default"
|
|
137
138
|
:title="t('panels.stepMeta.clickToCopy', { id: runId })"
|
|
138
139
|
@click="copyRunId"
|
|
139
140
|
>
|
|
@@ -3,6 +3,7 @@ import type { RequirementVerdictStatus, TestReport } from '~/types/domain'
|
|
|
3
3
|
import type { TesterStepState } from '~/types/execution'
|
|
4
4
|
import { resolveVerdictMeta, type VerdictMeta } from './StepTestReport.logic'
|
|
5
5
|
import MarkdownProse from '~/components/common/MarkdownProse.vue'
|
|
6
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
6
7
|
|
|
7
8
|
// A tester step's latest structured report (what was tested, the per-area outcomes,
|
|
8
9
|
// the concerns it raised and the greenlight verdict) plus the fixer-loop phase.
|
|
@@ -43,17 +44,17 @@ function verdictMeta(status: RequirementVerdictStatus): VerdictMeta {
|
|
|
43
44
|
|
|
44
45
|
<template>
|
|
45
46
|
<section class="mt-4 scroll-mt-4">
|
|
46
|
-
<div class="mb-2 flex items-center gap-1.5 text-
|
|
47
|
+
<div class="mb-2 flex items-center gap-1.5 text-2xs">
|
|
47
48
|
<UIcon name="i-lucide-flask-conical" class="h-3.5 w-3.5 text-muted" />
|
|
48
|
-
<
|
|
49
|
+
<SectionLabel as="span">
|
|
49
50
|
{{ t('panels.testReport.title') }}
|
|
50
|
-
</
|
|
51
|
+
</SectionLabel>
|
|
51
52
|
<UBadge :color="report.greenlight ? 'success' : 'warning'" variant="subtle" size="sm">
|
|
52
53
|
{{
|
|
53
54
|
report.greenlight ? t('panels.testReport.greenlit') : t('panels.testReport.needsFixes')
|
|
54
55
|
}}
|
|
55
56
|
</UBadge>
|
|
56
|
-
<span v-if="phase && phase.attempts > 0" class="text-
|
|
57
|
+
<span v-if="phase && phase.attempts > 0" class="text-2xs text-dimmed">
|
|
57
58
|
{{ t('panels.testReport.fixAttempts', { count: phase.attempts, max: phase.maxAttempts })
|
|
58
59
|
}}<span v-if="phase.phase === 'fixing'"> {{ t('panels.testReport.fixing') }}</span>
|
|
59
60
|
</span>
|
|
@@ -61,19 +62,19 @@ function verdictMeta(status: RequirementVerdictStatus): VerdictMeta {
|
|
|
61
62
|
<MarkdownProse
|
|
62
63
|
v-if="report.summary"
|
|
63
64
|
:text="report.summary"
|
|
64
|
-
class="mb-3 text-
|
|
65
|
+
class="mb-3 text-sm leading-relaxed text-toned"
|
|
65
66
|
/>
|
|
66
67
|
|
|
67
68
|
<div v-if="report.tested.length" class="mb-3">
|
|
68
|
-
<div class="mb-1 text-
|
|
69
|
-
<ul class="space-y-0.5 text-
|
|
69
|
+
<div class="mb-1 text-2xs text-dimmed">{{ t('panels.testReport.tested') }}</div>
|
|
70
|
+
<ul class="space-y-0.5 text-xs text-toned">
|
|
70
71
|
<li v-for="(item, i) in report.tested" :key="i">• {{ item }}</li>
|
|
71
72
|
</ul>
|
|
72
73
|
</div>
|
|
73
74
|
|
|
74
75
|
<div v-if="report.outcomes.length" class="mb-3 space-y-1">
|
|
75
|
-
<div class="text-
|
|
76
|
-
<div v-for="(o, i) in report.outcomes" :key="i" class="flex items-start gap-2 text-
|
|
76
|
+
<div class="text-2xs text-dimmed">{{ t('panels.testReport.outcomes') }}</div>
|
|
77
|
+
<div v-for="(o, i) in report.outcomes" :key="i" class="flex items-start gap-2 text-xs">
|
|
77
78
|
<span
|
|
78
79
|
class="mt-1 h-2 w-2 shrink-0 rounded-full"
|
|
79
80
|
:style="{ backgroundColor: OUTCOME_COLOR[o.status] ?? 'var(--ui-text-muted)' }"
|
|
@@ -91,20 +92,20 @@ function verdictMeta(status: RequirementVerdictStatus): VerdictMeta {
|
|
|
91
92
|
class="mb-3 space-y-1"
|
|
92
93
|
data-testid="test-report-requirement-verdicts"
|
|
93
94
|
>
|
|
94
|
-
<div class="text-
|
|
95
|
+
<div class="text-2xs text-dimmed">
|
|
95
96
|
{{ t('panels.testReport.requirementVerdicts.title') }}
|
|
96
97
|
</div>
|
|
97
98
|
<div
|
|
98
99
|
v-for="(verdict, i) in report.requirementVerdicts"
|
|
99
100
|
:key="i"
|
|
100
|
-
class="flex items-start gap-2 text-
|
|
101
|
+
class="flex items-start gap-2 text-xs"
|
|
101
102
|
>
|
|
102
103
|
<span
|
|
103
104
|
class="mt-1 h-2 w-2 shrink-0 rounded-full"
|
|
104
105
|
:style="{ backgroundColor: verdictMeta(verdict.status).color }"
|
|
105
106
|
/>
|
|
106
107
|
<span class="text-toned">
|
|
107
|
-
<span class="font-mono text-
|
|
108
|
+
<span class="font-mono text-2xs text-muted">{{ verdict.requirementId }}</span>
|
|
108
109
|
<span class="text-dimmed"> — {{ verdictMeta(verdict.status).label }}</span>
|
|
109
110
|
<span v-if="verdict.detail" class="text-dimmed"> · {{ verdict.detail }}</span>
|
|
110
111
|
</span>
|
|
@@ -112,15 +113,15 @@ function verdictMeta(status: RequirementVerdictStatus): VerdictMeta {
|
|
|
112
113
|
</div>
|
|
113
114
|
|
|
114
115
|
<div v-if="report.concerns.length" class="space-y-1">
|
|
115
|
-
<div class="text-
|
|
116
|
+
<div class="text-2xs text-dimmed">{{ t('panels.testReport.concerns') }}</div>
|
|
116
117
|
<div
|
|
117
118
|
v-for="(c, i) in report.concerns"
|
|
118
119
|
:key="i"
|
|
119
|
-
class="rounded border border-muted/60 p-2 text-
|
|
120
|
+
class="rounded-sm border border-muted/60 p-2 text-xs"
|
|
120
121
|
>
|
|
121
122
|
<div class="flex items-center gap-1.5">
|
|
122
123
|
<span
|
|
123
|
-
class="rounded px-1 text-
|
|
124
|
+
class="rounded-sm px-1 text-3xs font-semibold uppercase text-highlighted"
|
|
124
125
|
:style="{ backgroundColor: SEVERITY_COLOR[c.severity] ?? 'var(--ui-text-muted)' }"
|
|
125
126
|
>{{ c.severity }}</span
|
|
126
127
|
>
|