@cat-factory/app 0.307.1 → 0.309.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 +21 -0
- 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 +3 -2
- package/app/components/auth/UserMenu.vue +1 -1
- package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +15 -15
- package/app/components/binaryOutput/BinaryOutputReport.vue +10 -14
- package/app/components/binaryOutput/StoredAssetView.vue +5 -5
- package/app/components/board/AddTaskModal.vue +16 -14
- package/app/components/board/AgentFailureCard.vue +9 -9
- package/app/components/board/AgentFailureHistory.vue +1 -1
- package/app/components/board/CreateInitiativeModal.vue +2 -2
- package/app/components/board/FailureDetail.vue +1 -1
- package/app/components/board/FailureHistoryList.vue +5 -5
- package/app/components/board/RecurringPipelineModal.vue +12 -11
- package/app/components/board/ReviewFrictionDialog.vue +4 -3
- package/app/components/board/StepExecutionHistory.vue +8 -8
- package/app/components/board/nodes/AgentChip.vue +1 -1
- package/app/components/board/nodes/BlockNode.vue +8 -9
- package/app/components/board/nodes/EpicNode.vue +4 -4
- package/app/components/board/nodes/FrameSwimlanes.vue +4 -7
- 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 +8 -8
- package/app/components/board/nodes/TaskLane.vue +3 -3
- package/app/components/board/nodes/TaskPipelineMini.vue +13 -12
- package/app/components/bootstrap/AdoptionReviewModal.vue +7 -6
- package/app/components/bootstrap/BootstrapModal.vue +11 -10
- package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
- package/app/components/brainstorm/BrainstormWindow.vue +8 -7
- package/app/components/bugFishing/BugFishingWindow.vue +37 -36
- package/app/components/clarity/ClarityReviewWindow.vue +8 -7
- package/app/components/common/AsyncViewError.vue +1 -1
- package/app/components/common/ClarificationItem.vue +6 -6
- package/app/components/common/DescriptorFields.vue +1 -1
- package/app/components/common/EmptyState.vue +1 -1
- 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 +9 -8
- package/app/components/docs/DocInterviewWindow.vue +10 -9
- package/app/components/documents/ContextDocumentPicker.vue +10 -12
- package/app/components/documents/DocumentImportModal.vue +3 -2
- package/app/components/documents/DocumentSourceConnectModal.vue +2 -2
- package/app/components/documents/DocumentSyncState.vue +1 -1
- package/app/components/documents/DocumentTemplatesModal.vue +5 -4
- package/app/components/documents/RepoContextDocPicker.vue +3 -6
- 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 +11 -10
- 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 +10 -10
- package/app/components/forkDecision/ForkDecisionWindow.vue +23 -26
- package/app/components/foundational/FoundationalContractSummary.vue +2 -2
- package/app/components/foundational/FoundationalServiceCatalogList.vue +3 -3
- package/app/components/foundational/FoundationalServiceRegistry.vue +3 -3
- package/app/components/foundational/FoundationalSuppressions.vue +2 -2
- package/app/components/fragments/FragmentLibraryManager.vue +3 -3
- package/app/components/fragments/FragmentSelector.vue +10 -11
- package/app/components/gates/GateFailingCheckList.vue +3 -3
- package/app/components/gates/GateResultView.vue +39 -38
- package/app/components/github/AddServiceFromRepoModal.vue +5 -4
- package/app/components/github/BranchProtectionPreflight.vue +5 -5
- package/app/components/github/GitHubConnect.vue +5 -3
- package/app/components/github/GitHubPanel.vue +14 -13
- package/app/components/github/RepoTreeBrowser.vue +1 -1
- package/app/components/humanTest/HumanTestWindow.vue +18 -17
- package/app/components/initiative/InitiativePlanNotice.vue +3 -3
- package/app/components/initiative/InitiativePlanReview.vue +19 -21
- package/app/components/initiative/InitiativePlanningWindow.vue +5 -5
- package/app/components/initiative/InitiativeTrackerWindow.vue +54 -53
- package/app/components/judge/JudgeResultView.vue +24 -25
- package/app/components/kaizen/KaizenPanel.vue +4 -4
- 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 +4 -0
- package/app/components/layout/AiProvidersBanner.vue +1 -1
- package/app/components/layout/AppearanceSwitcher.vue +1 -1
- package/app/components/layout/BoardSwitcher.vue +3 -2
- package/app/components/layout/BoardToolbar.vue +6 -2
- package/app/components/layout/CommandBar.vue +4 -2
- package/app/components/layout/DefaultTestEnvBanner.vue +2 -2
- package/app/components/layout/IntegrationsHub.vue +4 -3
- package/app/components/layout/LanguageSwitcher.vue +1 -1
- package/app/components/layout/ModelProvidersHub.vue +6 -4
- package/app/components/layout/NotificationsInbox.vue +8 -7
- package/app/components/layout/PersonalSetupModal.vue +5 -3
- package/app/components/layout/RolePrompt.vue +1 -1
- package/app/components/layout/SideBar.vue +3 -5
- package/app/components/layout/SpendWarningBanner.vue +3 -3
- package/app/components/layout/TranslationWarningBanner.vue +1 -1
- package/app/components/layout/UiModeSwitcher.vue +7 -6
- package/app/components/layout/UiRoleSwitcher.vue +2 -2
- package/app/components/media/ArtifactLightbox.vue +6 -6
- package/app/components/media/ImageCompare.vue +16 -16
- package/app/components/merge/MergeEffortChips.vue +4 -6
- package/app/components/notifications/NotificationSettingsPanel.vue +6 -5
- package/app/components/observability/OutcomeFilterChips.vue +1 -1
- package/app/components/observability/RunFailureSummary.vue +14 -17
- package/app/components/observability/StepMetricsBar.vue +9 -8
- package/app/components/observability/StepModelActivity.vue +4 -3
- package/app/components/observability/ToolCallList.vue +15 -18
- package/app/components/outcome/OutcomeSummaryWindow.vue +43 -42
- package/app/components/palettes/AgentPalette.vue +7 -5
- package/app/components/palettes/AgentTierSelect.vue +1 -1
- package/app/components/palettes/PipelinePurposeSelect.vue +2 -1
- package/app/components/panels/AgentStepDetail.vue +27 -30
- 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 +66 -76
- package/app/components/panels/OperatorDashboardPanel.vue +27 -26
- package/app/components/panels/ReportsPanel.vue +26 -25
- package/app/components/panels/ReportsSpendBreakdown.vue +2 -2
- package/app/components/panels/ResultWindowShell.vue +19 -18
- package/app/components/panels/RunDetailLoadState.vue +1 -1
- package/app/components/panels/StepContainerStatus.vue +8 -7
- package/app/components/panels/StepDelegatedStatus.vue +13 -12
- 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/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 +8 -7
- package/app/components/panels/inspector/FrontendBindingsResolved.vue +5 -4
- package/app/components/panels/inspector/FrontendConfig.vue +26 -34
- package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
- package/app/components/panels/inspector/InspectorSection.vue +7 -4
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +9 -8
- package/app/components/panels/inspector/ServiceConnections.vue +2 -2
- 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 +41 -45
- 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 +13 -12
- package/app/components/panels/inspector/TaskRunSettings.vue +35 -38
- 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 +2 -2
- package/app/components/pipeline/GateConfigFields.vue +6 -6
- package/app/components/pipeline/IterationCapPrompt.vue +1 -1
- package/app/components/pipeline/PipelineBuilder.vue +28 -27
- package/app/components/pipeline/PipelineHealthModal.vue +7 -7
- package/app/components/pipeline/PipelinePicker.vue +3 -3
- package/app/components/pipeline/PipelinePreview.vue +6 -7
- package/app/components/pipeline/PipelineProgress.vue +23 -24
- package/app/components/prReview/PrReviewWindow.vue +42 -41
- package/app/components/providers/AiPresetMismatchDialog.vue +4 -3
- package/app/components/providers/AiProviderOnboardingModal.vue +2 -2
- package/app/components/providers/ApiKeysSection.vue +7 -6
- 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 +25 -26
- package/app/components/requirements/RequirementsReviewWindow.vue +13 -12
- package/app/components/riskPolicy/RiskPolicyPicker.vue +5 -5
- package/app/components/riskPolicy/RiskPolicyPreview.vue +16 -15
- package/app/components/sandbox/SandboxPanel.vue +21 -20
- 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 +16 -16
- package/app/components/settings/ComposeEnvironmentSetupSection.vue +14 -12
- package/app/components/settings/ConnectionTestVerdict.vue +1 -1
- package/app/components/settings/ConsensusGroupsSection.vue +21 -20
- package/app/components/settings/CustomManifestTypeEditor.vue +8 -7
- package/app/components/settings/DefaultProvisionTypeSection.vue +5 -5
- package/app/components/settings/InfraHandlersConfigurator.vue +14 -15
- package/app/components/settings/InfrastructureBackendPicker.vue +2 -2
- package/app/components/settings/IssueTrackerPanel.vue +9 -15
- 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 +10 -9
- package/app/components/settings/MergeClassRulesEditor.vue +6 -5
- package/app/components/settings/MergeRolePolicyEditor.vue +13 -12
- package/app/components/settings/ModelConfigurationPanel.vue +8 -11
- package/app/components/settings/ModelPresetHealthModal.vue +3 -3
- package/app/components/settings/ObservabilityConnectionPanel.vue +1 -1
- package/app/components/settings/OpenRouterCatalogPanel.vue +6 -5
- 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 +8 -7
- package/app/components/settings/RiskPolicyCreateForm.vue +40 -26
- package/app/components/settings/RiskPolicyEditorRow.vue +18 -17
- package/app/components/settings/RiskPolicyHealthModal.vue +3 -3
- package/app/components/settings/RiskPolicyPanel.vue +11 -13
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +5 -4
- 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 +8 -7
- package/app/components/skills/SkillLibraryManager.vue +2 -2
- package/app/components/slack/SlackPanel.vue +8 -7
- package/app/components/spec/ServiceSpecWindow.vue +15 -16
- package/app/components/tasks/BugHuntModal.vue +1 -1
- package/app/components/tasks/ContextIssuePicker.vue +4 -6
- package/app/components/tasks/TaskContextIssues.vue +1 -1
- package/app/components/tasks/TaskImportModal.vue +3 -2
- package/app/components/tasks/TaskSourceConnectModal.vue +5 -5
- package/app/components/testing/TestReportWindow.vue +54 -53
- 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 +23 -25
- package/app/composables/usePipelineErrorToast.ts +2 -0
- package/app/utils/catalog.ts +8 -0
- package/app/utils/theme/builtins.ts +7 -1
- package/i18n/locales/de.json +6 -3
- package/i18n/locales/en.json +6 -3
- package/i18n/locales/es.json +6 -3
- package/i18n/locales/fr.json +6 -3
- package/i18n/locales/he.json +6 -3
- package/i18n/locales/it.json +6 -3
- package/i18n/locales/ja.json +6 -3
- package/i18n/locales/pl.json +6 -3
- package/i18n/locales/tr.json +6 -3
- package/i18n/locales/uk.json +6 -3
- package/package.json +2 -2
|
@@ -25,6 +25,7 @@ import type {
|
|
|
25
25
|
NotificationType,
|
|
26
26
|
} from '~/types/notifications'
|
|
27
27
|
import IntegrationBackTitle from '~/components/layout/IntegrationBackTitle.vue'
|
|
28
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
28
29
|
|
|
29
30
|
const ui = useUiStore()
|
|
30
31
|
const notifications = useNotificationsStore()
|
|
@@ -174,11 +175,11 @@ function resetToDefaults() {
|
|
|
174
175
|
</div>
|
|
175
176
|
|
|
176
177
|
<template v-else>
|
|
177
|
-
<
|
|
178
|
+
<SectionLabel class="flex items-center gap-3 px-2">
|
|
178
179
|
<span class="flex-1">{{ t('notificationSettings.column.event') }}</span>
|
|
179
180
|
<span class="w-16 text-center">{{ t('notificationSettings.column.inApp') }}</span>
|
|
180
181
|
<span class="w-16 text-center">{{ t('notificationSettings.column.email') }}</span>
|
|
181
|
-
</
|
|
182
|
+
</SectionLabel>
|
|
182
183
|
|
|
183
184
|
<div class="max-h-[50vh] space-y-1 overflow-y-auto pr-1">
|
|
184
185
|
<div
|
|
@@ -198,13 +199,13 @@ function resetToDefaults() {
|
|
|
198
199
|
</div>
|
|
199
200
|
</div>
|
|
200
201
|
|
|
201
|
-
<p class="text-
|
|
202
|
+
<p class="text-2xs text-dimmed">
|
|
202
203
|
{{ t('notificationSettings.panel.inAppNote') }}
|
|
203
204
|
</p>
|
|
204
|
-
<p class="text-
|
|
205
|
+
<p class="text-2xs text-dimmed">
|
|
205
206
|
{{ t('notificationSettings.panel.emailNote') }}
|
|
206
207
|
</p>
|
|
207
|
-
<p class="text-
|
|
208
|
+
<p class="text-2xs text-dimmed">
|
|
208
209
|
{{ t('notificationSettings.panel.otherChannelsNote') }}
|
|
209
210
|
<UButton
|
|
210
211
|
v-if="slack.available"
|
|
@@ -24,7 +24,7 @@ function toneClass(option: (typeof props.options)[number], active: boolean): str
|
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
26
|
<template>
|
|
27
|
-
<div class="flex rounded-lg border border-default p-0.5 text-
|
|
27
|
+
<div class="flex rounded-lg border border-default p-0.5 text-xs">
|
|
28
28
|
<button
|
|
29
29
|
v-for="option in options"
|
|
30
30
|
:key="option.value"
|
|
@@ -86,15 +86,15 @@ const earlierFailedToolCalls = computed(() =>
|
|
|
86
86
|
<div class="flex items-start gap-3">
|
|
87
87
|
<UIcon name="i-lucide-siren" class="mt-0.5 h-5 w-5 shrink-0 text-app-error-400" />
|
|
88
88
|
<div class="min-w-0 flex-1">
|
|
89
|
-
<h2 class="text-
|
|
89
|
+
<h2 class="text-sm font-semibold text-app-error-200">
|
|
90
90
|
{{ t('observability.failure.title') }}
|
|
91
91
|
</h2>
|
|
92
92
|
|
|
93
93
|
<!-- The run's own structured record. Absent on a run that is still going, or that
|
|
94
94
|
failed without one; the evidence below stands on its own either way. -->
|
|
95
95
|
<template v-if="evidence.failure">
|
|
96
|
-
<p class="mt-1 text-
|
|
97
|
-
<div class="mt-1 flex flex-wrap gap-x-3 gap-y-0.5 text-
|
|
96
|
+
<p class="mt-1 text-sm text-default">{{ evidence.failure.message }}</p>
|
|
97
|
+
<div class="mt-1 flex flex-wrap gap-x-3 gap-y-0.5 text-2xs text-dimmed">
|
|
98
98
|
<span>{{ t('observability.failure.kind', { kind: failureKindLabel }) }}</span>
|
|
99
99
|
<span v-if="evidence.failure.stepIndex != null">
|
|
100
100
|
{{ t('observability.failure.atStep', { index: evidence.failure.stepIndex + 1 }) }}
|
|
@@ -108,10 +108,10 @@ const earlierFailedToolCalls = computed(() =>
|
|
|
108
108
|
<FailureDetail
|
|
109
109
|
:detail="evidence.failure.detail"
|
|
110
110
|
:message="evidence.failure.message"
|
|
111
|
-
summary-class="text-
|
|
112
|
-
pre-class="bg-app-950/60 text-
|
|
111
|
+
summary-class="text-2xs text-dimmed hover:text-toned"
|
|
112
|
+
pre-class="bg-app-950/60 text-2xs text-muted"
|
|
113
113
|
/>
|
|
114
|
-
<p v-if="evidence.failure.hint" class="mt-1.5 text-
|
|
114
|
+
<p v-if="evidence.failure.hint" class="mt-1.5 text-xs text-toned">
|
|
115
115
|
{{ evidence.failure.hint }}
|
|
116
116
|
</p>
|
|
117
117
|
</template>
|
|
@@ -133,7 +133,7 @@ const earlierFailedToolCalls = computed(() =>
|
|
|
133
133
|
:style="{ color: agentMeta(evidence.lastErroredCall.agentKind).color }"
|
|
134
134
|
/>
|
|
135
135
|
<div class="min-w-0 flex-1">
|
|
136
|
-
<div class="flex flex-wrap items-baseline gap-x-2 text-
|
|
136
|
+
<div class="flex flex-wrap items-baseline gap-x-2 text-xs">
|
|
137
137
|
<span class="font-medium text-default">
|
|
138
138
|
{{ t('observability.failure.lastErroredCall') }}
|
|
139
139
|
</span>
|
|
@@ -145,13 +145,10 @@ const earlierFailedToolCalls = computed(() =>
|
|
|
145
145
|
{{ evidence.lastErroredCall.httpStatus ?? t('observability.call.error') }}
|
|
146
146
|
</UBadge>
|
|
147
147
|
</div>
|
|
148
|
-
<p
|
|
149
|
-
v-if="evidence.lastErroredCall.errorMessage"
|
|
150
|
-
class="mt-0.5 text-[12px] text-app-error-300"
|
|
151
|
-
>
|
|
148
|
+
<p v-if="evidence.lastErroredCall.errorMessage" class="mt-0.5 text-xs text-app-error-300">
|
|
152
149
|
{{ evidence.lastErroredCall.errorMessage }}
|
|
153
150
|
</p>
|
|
154
|
-
<p v-if="evidence.erroredCallCount > 1" class="mt-0.5 text-
|
|
151
|
+
<p v-if="evidence.erroredCallCount > 1" class="mt-0.5 text-2xs text-dimmed">
|
|
155
152
|
{{
|
|
156
153
|
t(
|
|
157
154
|
'observability.failure.moreErroredCalls',
|
|
@@ -173,7 +170,7 @@ const earlierFailedToolCalls = computed(() =>
|
|
|
173
170
|
>
|
|
174
171
|
<UIcon name="i-lucide-wrench" class="mt-0.5 h-4 w-4 shrink-0 text-app-error-400" />
|
|
175
172
|
<div class="min-w-0 flex-1">
|
|
176
|
-
<div class="flex flex-wrap items-baseline gap-x-2 text-
|
|
173
|
+
<div class="flex flex-wrap items-baseline gap-x-2 text-xs">
|
|
177
174
|
<span class="font-medium text-default">
|
|
178
175
|
<!-- "One of the failing calls" when even the failures were bounded: the row is
|
|
179
176
|
real either way, but calling it the LAST would be a claim about rows this
|
|
@@ -191,16 +188,16 @@ const earlierFailedToolCalls = computed(() =>
|
|
|
191
188
|
</div>
|
|
192
189
|
<pre
|
|
193
190
|
v-if="failedToolResult"
|
|
194
|
-
class="mt-1 max-h-32 overflow-auto whitespace-pre-wrap text-
|
|
191
|
+
class="mt-1 max-h-32 overflow-auto whitespace-pre-wrap text-2xs leading-relaxed text-app-error-300"
|
|
195
192
|
>{{ failedToolResult }}</pre>
|
|
196
|
-
<p v-else class="mt-0.5 text-
|
|
193
|
+
<p v-else class="mt-0.5 text-2xs italic text-dimmed">
|
|
197
194
|
{{
|
|
198
195
|
evidence.lastFailedToolCall.bodies === 'stored'
|
|
199
196
|
? t('observability.failure.toolReturnedNothing')
|
|
200
197
|
: t('observability.failure.toolBodiesWithheld')
|
|
201
198
|
}}
|
|
202
199
|
</p>
|
|
203
|
-
<p v-if="earlierFailedToolCalls" class="mt-0.5 text-
|
|
200
|
+
<p v-if="earlierFailedToolCalls" class="mt-0.5 text-2xs text-dimmed">
|
|
204
201
|
{{
|
|
205
202
|
t(
|
|
206
203
|
'observability.failure.moreFailedToolCalls',
|
|
@@ -220,7 +217,7 @@ const earlierFailedToolCalls = computed(() =>
|
|
|
220
217
|
come back from being reported as one that came back clean. -->
|
|
221
218
|
<div
|
|
222
219
|
v-else-if="emptyReason"
|
|
223
|
-
class="flex flex-wrap items-center justify-between gap-2 rounded-lg border border-dashed px-3 py-2 text-
|
|
220
|
+
class="flex flex-wrap items-center justify-between gap-2 rounded-lg border border-dashed px-3 py-2 text-xs"
|
|
224
221
|
:class="
|
|
225
222
|
emptyReason === 'sink-unreachable'
|
|
226
223
|
? 'border-app-warning-900/60 text-app-warning-300'
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
totalInputTokens,
|
|
12
12
|
transportRatio,
|
|
13
13
|
} from '~/utils/observability'
|
|
14
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
14
15
|
|
|
15
16
|
// Compact, at-a-glance LLM rollup for one pipeline step: token usage, an
|
|
16
17
|
// output-limit headroom bar (how close the step ran to truncation), a
|
|
@@ -57,7 +58,7 @@ const headroomTone = computed(() => headroomColor(headroom.value, m.value.trunca
|
|
|
57
58
|
<template>
|
|
58
59
|
<div
|
|
59
60
|
v-if="m.calls > 0"
|
|
60
|
-
class="rounded-lg border border-default bg-default/40 p-2.5 text-
|
|
61
|
+
class="rounded-lg border border-default bg-default/40 p-2.5 text-xs"
|
|
61
62
|
:class="clickable ? 'cursor-pointer transition hover:border-muted hover:bg-default/70' : ''"
|
|
62
63
|
:role="clickable ? 'button' : undefined"
|
|
63
64
|
@click="clickable ? $emit('inspect') : undefined"
|
|
@@ -88,13 +89,13 @@ const headroomTone = computed(() => headroomColor(headroom.value, m.value.trunca
|
|
|
88
89
|
>
|
|
89
90
|
{{ onSubscription ? `~${cost}` : cost }}
|
|
90
91
|
</span>
|
|
91
|
-
<
|
|
92
|
+
<SectionLabel
|
|
92
93
|
v-if="onSubscription"
|
|
93
|
-
|
|
94
|
+
as="span"
|
|
94
95
|
:title="t('observability.metricsBar.subscriptionCostHint')"
|
|
95
96
|
>
|
|
96
97
|
{{ t('observability.metricsBar.subscription') }}
|
|
97
|
-
</
|
|
98
|
+
</SectionLabel>
|
|
98
99
|
</template>
|
|
99
100
|
<div class="ms-auto flex items-center gap-1">
|
|
100
101
|
<UBadge v-if="m.errors > 0" color="error" variant="subtle" size="sm">
|
|
@@ -112,7 +113,7 @@ const headroomTone = computed(() => headroomColor(headroom.value, m.value.trunca
|
|
|
112
113
|
</div>
|
|
113
114
|
|
|
114
115
|
<!-- input breakdown: the headline's three classes, priced an order of magnitude apart -->
|
|
115
|
-
<div v-if="hasCache" class="mt-1.5 flex items-center gap-1.5 text-
|
|
116
|
+
<div v-if="hasCache" class="mt-1.5 flex items-center gap-1.5 text-2xs tabular-nums">
|
|
116
117
|
<span class="text-muted" :title="t('observability.metricsBar.freshHint')">
|
|
117
118
|
{{ t('observability.metricsBar.fresh', { tokens: formatTokens(m.promptTokens) }) }}
|
|
118
119
|
</span>
|
|
@@ -136,7 +137,7 @@ const headroomTone = computed(() => headroomColor(headroom.value, m.value.trunca
|
|
|
136
137
|
|
|
137
138
|
<!-- output-limit headroom -->
|
|
138
139
|
<div v-if="headroom !== null" class="mt-2">
|
|
139
|
-
<div class="flex items-center justify-between text-
|
|
140
|
+
<div class="flex items-center justify-between text-2xs">
|
|
140
141
|
<span class="text-dimmed">{{ t('observability.metricsBar.outputLimit') }}</span>
|
|
141
142
|
<span class="tabular-nums" :class="headroomTone">
|
|
142
143
|
{{ formatTokens(m.peakCompletionTokens) }} /
|
|
@@ -156,7 +157,7 @@ const headroomTone = computed(() => headroomColor(headroom.value, m.value.trunca
|
|
|
156
157
|
:style="{ width: `${Math.max(2, pct(headroom))}%` }"
|
|
157
158
|
/>
|
|
158
159
|
</div>
|
|
159
|
-
<p v-if="m.truncatedCalls > 0" class="mt-1 text-
|
|
160
|
+
<p v-if="m.truncatedCalls > 0" class="mt-1 text-2xs text-app-error-400">
|
|
160
161
|
{{
|
|
161
162
|
t(
|
|
162
163
|
'observability.metricsBar.truncatedCalls',
|
|
@@ -169,7 +170,7 @@ const headroomTone = computed(() => headroomColor(headroom.value, m.value.trunca
|
|
|
169
170
|
|
|
170
171
|
<!-- transport overhead vs model execution -->
|
|
171
172
|
<div v-if="transport !== null" class="mt-2">
|
|
172
|
-
<div class="flex items-center justify-between text-
|
|
173
|
+
<div class="flex items-center justify-between text-2xs">
|
|
173
174
|
<span class="text-dimmed">{{ t('observability.metricsBar.transportVsExecution') }}</span>
|
|
174
175
|
<span class="tabular-nums text-muted">
|
|
175
176
|
{{ formatMs(m.overheadMs) }} / {{ formatMs(m.upstreamMs) }}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { computed } from 'vue'
|
|
3
3
|
import type { StepMetrics } from '~/types/execution'
|
|
4
4
|
import StepMetricsBar from '~/components/observability/StepMetricsBar.vue'
|
|
5
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
5
6
|
|
|
6
7
|
// The shared "Model activity" block: the LLM observability rollup (StepMetricsBar) under
|
|
7
8
|
// a labelled header with a "View all calls →" link into the full per-call panel. Used by
|
|
@@ -31,12 +32,12 @@ function openObservability() {
|
|
|
31
32
|
<template>
|
|
32
33
|
<div v-if="instanceId || hasCalls">
|
|
33
34
|
<div class="mb-1 flex items-center justify-between">
|
|
34
|
-
<
|
|
35
|
+
<SectionLabel as="span">
|
|
35
36
|
{{ t('observability.modelActivity') }}
|
|
36
|
-
</
|
|
37
|
+
</SectionLabel>
|
|
37
38
|
<button
|
|
38
39
|
v-if="instanceId"
|
|
39
|
-
class="text-
|
|
40
|
+
class="text-2xs text-app-info-400 hover:text-app-info-300"
|
|
40
41
|
@click="openObservability"
|
|
41
42
|
>
|
|
42
43
|
{{ t('observability.viewAllCalls') }}
|
|
@@ -5,6 +5,7 @@ import type { ToolOutcomeFilter } from '~/utils/observability'
|
|
|
5
5
|
import { filterToolCallsByOutcome, formatMs } from '~/utils/observability'
|
|
6
6
|
import { agentKindMeta } from '~/utils/catalog'
|
|
7
7
|
import OutcomeFilterChips from '~/components/observability/OutcomeFilterChips.vue'
|
|
8
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
8
9
|
|
|
9
10
|
// The tool-call TRAJECTORY drill-down: what the run's agents DID, oldest first, in the order
|
|
10
11
|
// they did it. The sibling of the model-call list, and the one that holds the failures no LLM
|
|
@@ -142,10 +143,10 @@ function prettyArgs(raw: string): string {
|
|
|
142
143
|
<div class="space-y-4">
|
|
143
144
|
<div class="flex flex-wrap items-center justify-between gap-2">
|
|
144
145
|
<div>
|
|
145
|
-
<
|
|
146
|
+
<SectionLabel as="h2">
|
|
146
147
|
{{ t('observability.toolCalls.title') }}
|
|
147
|
-
</
|
|
148
|
-
<p class="text-
|
|
148
|
+
</SectionLabel>
|
|
149
|
+
<p class="text-2xs text-app-600">{{ t('observability.toolCalls.subtitle') }}</p>
|
|
149
150
|
</div>
|
|
150
151
|
<OutcomeFilterChips v-model="filter" :options="filterOptions" />
|
|
151
152
|
</div>
|
|
@@ -198,7 +199,7 @@ function prettyArgs(raw: string): string {
|
|
|
198
199
|
implies has to explain itself here. -->
|
|
199
200
|
<p
|
|
200
201
|
v-if="boundedNotice"
|
|
201
|
-
class="rounded-lg border border-dashed border-app-warning-900/50 px-3 py-2 text-
|
|
202
|
+
class="rounded-lg border border-dashed border-app-warning-900/50 px-3 py-2 text-2xs text-app-warning-300/90"
|
|
202
203
|
>
|
|
203
204
|
{{ boundedNotice }}
|
|
204
205
|
</p>
|
|
@@ -225,8 +226,8 @@ function prettyArgs(raw: string): string {
|
|
|
225
226
|
:style="{ color: agentMeta(call.agentKind).color }"
|
|
226
227
|
:title="agentMeta(call.agentKind).label"
|
|
227
228
|
/>
|
|
228
|
-
<span class="font-mono text-
|
|
229
|
-
<div class="ms-auto flex items-center gap-2.5 text-
|
|
229
|
+
<span class="font-mono text-sm text-default">{{ call.tool }}</span>
|
|
230
|
+
<div class="ms-auto flex items-center gap-2.5 text-2xs tabular-nums text-muted">
|
|
230
231
|
<span :title="t('observability.toolCalls.durationHint')">
|
|
231
232
|
{{ formatMs(Math.max(0, call.endedAt - call.startedAt)) }}
|
|
232
233
|
</span>
|
|
@@ -238,20 +239,18 @@ function prettyArgs(raw: string): string {
|
|
|
238
239
|
</button>
|
|
239
240
|
|
|
240
241
|
<div v-if="expanded[call.id]" class="border-t border-default px-4 py-3 space-y-3">
|
|
241
|
-
<div class="flex flex-wrap gap-x-5 gap-y-1 text-
|
|
242
|
+
<div class="flex flex-wrap gap-x-5 gap-y-1 text-2xs text-dimmed">
|
|
242
243
|
<span>{{ t('observability.toolCalls.dispatch', { jobId: call.jobId }) }}</span>
|
|
243
244
|
<span>{{ t('observability.toolCalls.seq', { seq: call.seq }) }}</span>
|
|
244
245
|
</div>
|
|
245
246
|
<!-- `withheld` is not an empty body: nothing was captured, so an empty `args` here
|
|
246
247
|
must not read as a tool that took none. -->
|
|
247
|
-
<p v-if="call.bodies !== 'stored'" class="text-
|
|
248
|
+
<p v-if="call.bodies !== 'stored'" class="text-xs italic text-dimmed">
|
|
248
249
|
{{ t('observability.toolCalls.bodiesWithheld') }}
|
|
249
250
|
</p>
|
|
250
251
|
<template v-else>
|
|
251
252
|
<div>
|
|
252
|
-
<
|
|
253
|
-
class="mb-1 flex items-center gap-2 text-[11px] uppercase tracking-wide text-dimmed"
|
|
254
|
-
>
|
|
253
|
+
<SectionLabel class="mb-1 flex items-center gap-2">
|
|
255
254
|
<span>{{ t('observability.toolCalls.arguments') }}</span>
|
|
256
255
|
<span
|
|
257
256
|
v-if="call.argsDropped > 0"
|
|
@@ -259,15 +258,13 @@ function prettyArgs(raw: string): string {
|
|
|
259
258
|
>
|
|
260
259
|
{{ t('observability.toolCalls.dropped', { chars: call.argsDropped }) }}
|
|
261
260
|
</span>
|
|
262
|
-
</
|
|
261
|
+
</SectionLabel>
|
|
263
262
|
<pre
|
|
264
|
-
class="max-h-60 overflow-auto rounded-lg bg-app-950/70 p-3 text-
|
|
263
|
+
class="max-h-60 overflow-auto rounded-lg bg-app-950/70 p-3 text-2xs leading-relaxed text-toned"
|
|
265
264
|
>{{ call.args ? prettyArgs(call.args) : '—' }}</pre>
|
|
266
265
|
</div>
|
|
267
266
|
<div>
|
|
268
|
-
<
|
|
269
|
-
class="mb-1 flex items-center gap-2 text-[11px] uppercase tracking-wide text-dimmed"
|
|
270
|
-
>
|
|
267
|
+
<SectionLabel class="mb-1 flex items-center gap-2">
|
|
271
268
|
<span>{{ t('observability.toolCalls.result') }}</span>
|
|
272
269
|
<span
|
|
273
270
|
v-if="call.resultDropped > 0"
|
|
@@ -275,9 +272,9 @@ function prettyArgs(raw: string): string {
|
|
|
275
272
|
>
|
|
276
273
|
{{ t('observability.toolCalls.dropped', { chars: call.resultDropped }) }}
|
|
277
274
|
</span>
|
|
278
|
-
</
|
|
275
|
+
</SectionLabel>
|
|
279
276
|
<pre
|
|
280
|
-
class="max-h-60 overflow-auto rounded-lg bg-app-950/70 p-3 text-
|
|
277
|
+
class="max-h-60 overflow-auto rounded-lg bg-app-950/70 p-3 text-2xs leading-relaxed"
|
|
281
278
|
:class="call.ok ? 'text-toned' : 'text-app-error-300'"
|
|
282
279
|
>{{ call.result || '—' }}</pre>
|
|
283
280
|
</div>
|
|
@@ -45,6 +45,7 @@ import ResultWindowShell from '~/components/panels/ResultWindowShell.vue'
|
|
|
45
45
|
import MarkdownProse from '~/components/common/MarkdownProse.vue'
|
|
46
46
|
import EmptyState from '~/components/common/EmptyState.vue'
|
|
47
47
|
import type { BadgeColor } from '~/utils/badge'
|
|
48
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
48
49
|
|
|
49
50
|
const board = useBoardStore()
|
|
50
51
|
const documents = useDocumentsStore()
|
|
@@ -458,16 +459,16 @@ function openTestReport() {
|
|
|
458
459
|
|
|
459
460
|
<!-- What was asked, in the requester's own words. -->
|
|
460
461
|
<section class="mb-5">
|
|
461
|
-
<h3 class="mb-1.5
|
|
462
|
+
<SectionLabel as="h3" class="mb-1.5">
|
|
462
463
|
{{ t('outcome.ask.title') }}
|
|
463
|
-
</
|
|
464
|
+
</SectionLabel>
|
|
464
465
|
<MarkdownProse
|
|
465
466
|
v-if="outcome.ask"
|
|
466
467
|
:text="outcome.ask"
|
|
467
|
-
class="text-
|
|
468
|
+
class="text-sm leading-relaxed text-toned"
|
|
468
469
|
data-testid="outcome-ask"
|
|
469
470
|
/>
|
|
470
|
-
<p v-else class="text-
|
|
471
|
+
<p v-else class="text-sm italic leading-relaxed text-dimmed">
|
|
471
472
|
{{ t('outcome.ask.none') }}
|
|
472
473
|
</p>
|
|
473
474
|
</section>
|
|
@@ -477,9 +478,9 @@ function openTestReport() {
|
|
|
477
478
|
agents actually read, and every section below is a statement about work done against
|
|
478
479
|
it. A design that moved mid-run is the reading that changes all of them. -->
|
|
479
480
|
<section class="mb-5" data-testid="outcome-sources">
|
|
480
|
-
<h3 class="mb-1.5
|
|
481
|
+
<SectionLabel as="h3" class="mb-1.5">
|
|
481
482
|
{{ t('outcome.sources.title') }}
|
|
482
|
-
</
|
|
483
|
+
</SectionLabel>
|
|
483
484
|
<div v-if="outcome.sources.status === 'reported'" class="space-y-1">
|
|
484
485
|
<div
|
|
485
486
|
v-for="source in sourceRows"
|
|
@@ -495,7 +496,7 @@ function openTestReport() {
|
|
|
495
496
|
<UIcon :name="source.icon" class="h-3.5 w-3.5 shrink-0 text-primary" />
|
|
496
497
|
<span class="truncate">{{ source.title }}</span>
|
|
497
498
|
</DocumentOriginLink>
|
|
498
|
-
<p class="mt-0.5 text-
|
|
499
|
+
<p class="mt-0.5 text-2xs text-dimmed" data-testid="outcome-source-revision">
|
|
499
500
|
{{ source.revision }}
|
|
500
501
|
</p>
|
|
501
502
|
<!-- Stated separately from the revision above: the last revision alone says the run
|
|
@@ -503,23 +504,23 @@ function openTestReport() {
|
|
|
503
504
|
changed under it. -->
|
|
504
505
|
<p
|
|
505
506
|
v-if="source.movedDuringRun"
|
|
506
|
-
class="mt-0.5 text-
|
|
507
|
+
class="mt-0.5 text-2xs text-app-warning-300"
|
|
507
508
|
data-testid="outcome-source-moved"
|
|
508
509
|
>
|
|
509
510
|
{{ t('outcome.sources.moved') }}
|
|
510
511
|
</p>
|
|
511
512
|
</div>
|
|
512
513
|
</div>
|
|
513
|
-
<p v-else class="text-
|
|
514
|
+
<p v-else class="text-sm italic leading-relaxed text-dimmed">
|
|
514
515
|
{{ t(SOURCES_GAP_KEYS[outcome.sources.gap]) }}
|
|
515
516
|
</p>
|
|
516
517
|
</section>
|
|
517
518
|
|
|
518
519
|
<!-- Requirement coverage: which required behaviours were checked, and what was seen. -->
|
|
519
520
|
<section class="mb-5" data-testid="outcome-requirements">
|
|
520
|
-
<h3 class="mb-1.5
|
|
521
|
+
<SectionLabel as="h3" class="mb-1.5">
|
|
521
522
|
{{ t('outcome.requirements.title') }}
|
|
522
|
-
</
|
|
523
|
+
</SectionLabel>
|
|
523
524
|
<template v-if="outcome.requirements.status === 'reported'">
|
|
524
525
|
<div class="mb-2 flex flex-wrap items-center gap-1.5">
|
|
525
526
|
<UBadge color="success" variant="subtle" size="sm">
|
|
@@ -550,7 +551,7 @@ function openTestReport() {
|
|
|
550
551
|
and do not cover rather than letting them read as the whole picture. -->
|
|
551
552
|
<p
|
|
552
553
|
v-if="specNote"
|
|
553
|
-
class="mb-2 text-
|
|
554
|
+
class="mb-2 text-2xs leading-relaxed text-app-warning-300/90"
|
|
554
555
|
data-testid="outcome-spec-note"
|
|
555
556
|
>
|
|
556
557
|
{{ specNote }}
|
|
@@ -560,7 +561,7 @@ function openTestReport() {
|
|
|
560
561
|
deciding which of the two numbers to distrust. -->
|
|
561
562
|
<p
|
|
562
563
|
v-if="unmatchedVerdicts > 0"
|
|
563
|
-
class="mb-2 text-
|
|
564
|
+
class="mb-2 text-2xs leading-relaxed text-app-warning-300/90"
|
|
564
565
|
data-testid="outcome-unmatched-verdicts"
|
|
565
566
|
>
|
|
566
567
|
{{ t('outcome.requirements.unmatchedVerdicts', { count: unmatchedVerdicts }) }}
|
|
@@ -578,7 +579,7 @@ function openTestReport() {
|
|
|
578
579
|
/>
|
|
579
580
|
<div class="min-w-0">
|
|
580
581
|
<div class="flex flex-wrap items-center gap-1.5">
|
|
581
|
-
<span class="text-
|
|
582
|
+
<span class="text-sm text-default">{{ req.title ?? req.id }}</span>
|
|
582
583
|
<UBadge
|
|
583
584
|
v-if="req.regression"
|
|
584
585
|
color="error"
|
|
@@ -588,18 +589,18 @@ function openTestReport() {
|
|
|
588
589
|
>
|
|
589
590
|
{{ t('outcome.requirements.regressionTag') }}
|
|
590
591
|
</UBadge>
|
|
591
|
-
<
|
|
592
|
+
<SectionLabel as="span">
|
|
592
593
|
{{ t(VERDICT_META[req.verdict].key) }}
|
|
593
|
-
</
|
|
594
|
+
</SectionLabel>
|
|
594
595
|
</div>
|
|
595
|
-
<p v-if="req.detail" class="mt-0.5 text-
|
|
596
|
+
<p v-if="req.detail" class="mt-0.5 text-xs leading-relaxed text-muted">
|
|
596
597
|
{{ req.detail }}
|
|
597
598
|
</p>
|
|
598
599
|
</div>
|
|
599
600
|
</li>
|
|
600
601
|
</ul>
|
|
601
602
|
</template>
|
|
602
|
-
<p v-else class="text-
|
|
603
|
+
<p v-else class="text-sm italic leading-relaxed text-dimmed">
|
|
603
604
|
{{ t(REQUIREMENTS_GAP_KEYS[outcome.requirements.gap]) }}
|
|
604
605
|
</p>
|
|
605
606
|
</section>
|
|
@@ -607,9 +608,9 @@ function openTestReport() {
|
|
|
607
608
|
<!-- How it was tested: the tester's own verdict and prose, attributed as its account. -->
|
|
608
609
|
<section class="mb-5" data-testid="outcome-tests">
|
|
609
610
|
<div class="mb-1.5 flex flex-wrap items-center gap-2">
|
|
610
|
-
<
|
|
611
|
+
<SectionLabel as="h3">
|
|
611
612
|
{{ t('outcome.tests.title') }}
|
|
612
|
-
</
|
|
613
|
+
</SectionLabel>
|
|
613
614
|
<UBadge
|
|
614
615
|
v-if="outcome.tests.status === 'reported'"
|
|
615
616
|
:color="TESTS_VERDICT_COLOR[outcome.tests.verdict]"
|
|
@@ -642,15 +643,15 @@ function openTestReport() {
|
|
|
642
643
|
<template v-if="outcome.tests.status === 'reported'">
|
|
643
644
|
<p
|
|
644
645
|
v-if="outcome.tests.abortReason"
|
|
645
|
-
class="mb-2 rounded-md border border-app-error-900/70 bg-app-error-500/10 p-2 text-
|
|
646
|
+
class="mb-2 rounded-md border border-app-error-900/70 bg-app-error-500/10 p-2 text-sm leading-relaxed text-app-error-200"
|
|
646
647
|
data-testid="outcome-tests-abort"
|
|
647
648
|
>
|
|
648
649
|
{{ t('outcome.tests.abort', { reason: outcome.tests.abortReason }) }}
|
|
649
650
|
</p>
|
|
650
|
-
<p v-if="outcome.tests.summary" class="text-
|
|
651
|
+
<p v-if="outcome.tests.summary" class="text-sm leading-relaxed text-toned">
|
|
651
652
|
{{ t('outcome.tests.summary', { summary: outcome.tests.summary }) }}
|
|
652
653
|
</p>
|
|
653
|
-
<p class="mt-1.5 text-
|
|
654
|
+
<p class="mt-1.5 text-xs text-muted">
|
|
654
655
|
{{
|
|
655
656
|
t('outcome.tests.counts', {
|
|
656
657
|
passed: outcome.tests.passed,
|
|
@@ -663,7 +664,7 @@ function openTestReport() {
|
|
|
663
664
|
<li
|
|
664
665
|
v-for="(concern, i) in outcome.tests.concerns"
|
|
665
666
|
:key="i"
|
|
666
|
-
class="flex items-start gap-2 text-
|
|
667
|
+
class="flex items-start gap-2 text-xs text-toned"
|
|
667
668
|
data-testid="outcome-concern"
|
|
668
669
|
>
|
|
669
670
|
<UBadge :color="SEVERITY_COLOR[concern.severity]" variant="subtle" size="sm">
|
|
@@ -673,18 +674,18 @@ function openTestReport() {
|
|
|
673
674
|
</li>
|
|
674
675
|
</ul>
|
|
675
676
|
</template>
|
|
676
|
-
<p v-else class="text-
|
|
677
|
+
<p v-else class="text-sm italic leading-relaxed text-dimmed">
|
|
677
678
|
{{ t(TESTS_GAP_KEYS[outcome.tests.gap]) }}
|
|
678
679
|
</p>
|
|
679
680
|
</section>
|
|
680
681
|
|
|
681
682
|
<!-- What it looks like: the captured views, and whether a human was asked about them. -->
|
|
682
683
|
<section class="mb-5" data-testid="outcome-visuals">
|
|
683
|
-
<h3 class="mb-1.5
|
|
684
|
+
<SectionLabel as="h3" class="mb-1.5">
|
|
684
685
|
{{ t('outcome.visuals.title') }}
|
|
685
|
-
</
|
|
686
|
+
</SectionLabel>
|
|
686
687
|
<template v-if="outcome.visuals.status === 'reported'">
|
|
687
|
-
<p class="mb-2 text-
|
|
688
|
+
<p class="mb-2 text-xs leading-relaxed text-muted">
|
|
688
689
|
{{
|
|
689
690
|
outcome.visuals.source === 'visual_confirm'
|
|
690
691
|
? t('outcome.visuals.source.visual_confirm')
|
|
@@ -718,7 +719,7 @@ function openTestReport() {
|
|
|
718
719
|
/>
|
|
719
720
|
</div>
|
|
720
721
|
<span
|
|
721
|
-
class="flex items-center gap-1 truncate px-1.5 py-1 text-
|
|
722
|
+
class="flex items-center gap-1 truncate px-1.5 py-1 text-2xs text-toned"
|
|
722
723
|
:title="view.view"
|
|
723
724
|
>
|
|
724
725
|
<UIcon
|
|
@@ -733,12 +734,12 @@ function openTestReport() {
|
|
|
733
734
|
</div>
|
|
734
735
|
</template>
|
|
735
736
|
<template v-else>
|
|
736
|
-
<p class="text-
|
|
737
|
+
<p class="text-sm italic leading-relaxed text-dimmed">
|
|
737
738
|
{{ t(VISUALS_GAP_KEYS[outcome.visuals.gap]) }}
|
|
738
739
|
</p>
|
|
739
740
|
<p
|
|
740
741
|
v-if="outcome.visuals.detail"
|
|
741
|
-
class="mt-1 text-
|
|
742
|
+
class="mt-1 text-xs leading-relaxed text-dimmed"
|
|
742
743
|
data-testid="outcome-visuals-detail"
|
|
743
744
|
>
|
|
744
745
|
{{ outcome.visuals.detail }}
|
|
@@ -750,9 +751,9 @@ function openTestReport() {
|
|
|
750
751
|
not read diffs starts from. Beside the captured views on purpose: the shots are what
|
|
751
752
|
this run saw, this is the thing itself. -->
|
|
752
753
|
<section class="mb-5" data-testid="outcome-environments">
|
|
753
|
-
<h3 class="mb-1.5
|
|
754
|
+
<SectionLabel as="h3" class="mb-1.5">
|
|
754
755
|
{{ t('outcome.environments.title') }}
|
|
755
|
-
</
|
|
756
|
+
</SectionLabel>
|
|
756
757
|
<template v-if="outcome.environments.status === 'reported'">
|
|
757
758
|
<div
|
|
758
759
|
v-for="row in environmentRows"
|
|
@@ -765,10 +766,10 @@ function openTestReport() {
|
|
|
765
766
|
<UBadge :color="ENVIRONMENT_STATE_COLOR[row.state]" variant="subtle" size="sm">
|
|
766
767
|
{{ t(ENVIRONMENT_STATE_KEYS[row.state]) }}
|
|
767
768
|
</UBadge>
|
|
768
|
-
<span v-if="row.service" class="truncate text-
|
|
769
|
+
<span v-if="row.service" class="truncate text-xs text-toned">
|
|
769
770
|
{{ row.service }}
|
|
770
771
|
</span>
|
|
771
|
-
<span class="text-
|
|
772
|
+
<span class="text-2xs text-dimmed">
|
|
772
773
|
{{ t(ENVIRONMENT_ORIGIN_KEYS[row.origin]) }}
|
|
773
774
|
</span>
|
|
774
775
|
</div>
|
|
@@ -789,15 +790,15 @@ function openTestReport() {
|
|
|
789
790
|
</UButton>
|
|
790
791
|
<p
|
|
791
792
|
v-else-if="row.url"
|
|
792
|
-
class="mt-1.5 break-all text-
|
|
793
|
+
class="mt-1.5 break-all text-xs text-dimmed"
|
|
793
794
|
data-testid="outcome-environment-url"
|
|
794
795
|
>
|
|
795
796
|
{{ row.url }}
|
|
796
797
|
</p>
|
|
797
|
-
<p v-if="row.retained" class="mt-1 text-
|
|
798
|
+
<p v-if="row.retained" class="mt-1 text-2xs text-muted">
|
|
798
799
|
{{ t('outcome.environments.retained') }}
|
|
799
800
|
</p>
|
|
800
|
-
<p v-if="row.expiresAt" class="mt-1 text-
|
|
801
|
+
<p v-if="row.expiresAt" class="mt-1 text-2xs text-dimmed">
|
|
801
802
|
{{
|
|
802
803
|
row.lapsed
|
|
803
804
|
? t('outcome.environments.expired', { date: d(new Date(row.expiresAt), 'long') })
|
|
@@ -810,7 +811,7 @@ function openTestReport() {
|
|
|
810
811
|
otherwise holds "quota exceeded" reports a fault the environment does not have. -->
|
|
811
812
|
<p
|
|
812
813
|
v-if="row.detail"
|
|
813
|
-
class="mt-1 break-words text-
|
|
814
|
+
class="mt-1 break-words text-xs leading-relaxed text-dimmed"
|
|
814
815
|
data-testid="outcome-environment-detail"
|
|
815
816
|
:data-detail-kind="row.detailKind"
|
|
816
817
|
>
|
|
@@ -822,16 +823,16 @@ function openTestReport() {
|
|
|
822
823
|
</p>
|
|
823
824
|
</div>
|
|
824
825
|
</template>
|
|
825
|
-
<p v-else class="text-
|
|
826
|
+
<p v-else class="text-sm italic leading-relaxed text-dimmed">
|
|
826
827
|
{{ t(ENVIRONMENTS_GAP_KEYS[outcome.environments.gap]) }}
|
|
827
828
|
</p>
|
|
828
829
|
</section>
|
|
829
830
|
|
|
830
831
|
<!-- The machine checks, listed only where one actually recorded a verdict. -->
|
|
831
832
|
<section v-if="checkRows.length" data-testid="outcome-checks">
|
|
832
|
-
<h3 class="mb-1.5
|
|
833
|
+
<SectionLabel as="h3" class="mb-1.5">
|
|
833
834
|
{{ t('outcome.checks.title') }}
|
|
834
|
-
</
|
|
835
|
+
</SectionLabel>
|
|
835
836
|
<div class="flex flex-wrap items-center gap-1.5">
|
|
836
837
|
<UBadge
|
|
837
838
|
v-for="check in checkRows"
|