@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
|
@@ -17,6 +17,7 @@ import { BINARY_OUTPUT_STATE_KEYS, binaryOutputView } from '~/utils/binaryOutput
|
|
|
17
17
|
import { binaryCandidateView } from '~/utils/binaryCandidates'
|
|
18
18
|
import CopyButton from '~/components/common/CopyButton.vue'
|
|
19
19
|
import StoredAssetView from '~/components/binaryOutput/StoredAssetView.vue'
|
|
20
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
20
21
|
|
|
21
22
|
// Two callers, one renderer — the same split `StepEffortReport` makes: the generic step-detail
|
|
22
23
|
// panel drops it in as a `card` (its own heading + border, among the other detail sections),
|
|
@@ -59,20 +60,17 @@ const state = computed(() => {
|
|
|
59
60
|
"
|
|
60
61
|
data-testid="binary-output-report"
|
|
61
62
|
>
|
|
62
|
-
<
|
|
63
|
-
v-if="variant === 'card'"
|
|
64
|
-
class="flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted"
|
|
65
|
-
>
|
|
63
|
+
<SectionLabel v-if="variant === 'card'" class="flex items-center gap-1.5">
|
|
66
64
|
<UIcon name="i-lucide-image" class="h-3.5 w-3.5" />
|
|
67
65
|
<span>{{ t('binaryOutput.heading') }}</span>
|
|
68
|
-
</
|
|
66
|
+
</SectionLabel>
|
|
69
67
|
|
|
70
68
|
<!-- The CANDIDATE decision, when this step compared before delivering. It sits ABOVE the
|
|
71
69
|
delivery outcome because it happened first, and because "which of four was this" is the
|
|
72
70
|
question the artifacts below cannot answer. An AUTOMATIC keep says so: nobody looked. -->
|
|
73
71
|
<p
|
|
74
72
|
v-if="candidates && candidates.state.candidates.length > 0"
|
|
75
|
-
class="text-
|
|
73
|
+
class="text-xs leading-relaxed text-toned"
|
|
76
74
|
data-testid="binary-output-candidate-decision"
|
|
77
75
|
>
|
|
78
76
|
{{
|
|
@@ -92,7 +90,7 @@ const state = computed(() => {
|
|
|
92
90
|
<!-- What happened, in one sentence, before any list. Four of the five states have no list
|
|
93
91
|
at all, and the fifth still needs its qualifications read alongside it. -->
|
|
94
92
|
<p
|
|
95
|
-
class="flex items-start gap-2 text-
|
|
93
|
+
class="flex items-start gap-2 text-xs leading-relaxed"
|
|
96
94
|
:class="state.tone"
|
|
97
95
|
data-testid="binary-output-state"
|
|
98
96
|
:data-state="view.state"
|
|
@@ -106,7 +104,7 @@ const state = computed(() => {
|
|
|
106
104
|
so — it is a real state (a trait-carrying kind dispatched under an overriding kind
|
|
107
105
|
records a declaration against a step that never held one), and rendering a blank
|
|
108
106
|
would read as a missing value rather than an absent comparison. -->
|
|
109
|
-
<dl class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-
|
|
107
|
+
<dl class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-2xs">
|
|
110
108
|
<dt class="text-dimmed">{{ t('binaryOutput.target') }}</dt>
|
|
111
109
|
<dd
|
|
112
110
|
v-if="view.target"
|
|
@@ -158,10 +156,8 @@ const state = computed(() => {
|
|
|
158
156
|
:label="row.entity ?? row.description"
|
|
159
157
|
class="mb-2 pe-8"
|
|
160
158
|
/>
|
|
161
|
-
<code class="block break-all pe-8 font-mono text-
|
|
162
|
-
|
|
163
|
-
}}</code>
|
|
164
|
-
<div class="mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-[10px] text-dimmed">
|
|
159
|
+
<code class="block break-all pe-8 font-mono text-2xs text-default">{{ row.location }}</code>
|
|
160
|
+
<div class="mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-3xs text-dimmed">
|
|
165
161
|
<span class="font-mono">{{ row.service }}</span>
|
|
166
162
|
<!-- The join the report cannot make on its own, and the question a human opens this
|
|
167
163
|
for: did it go where the step pointed it? -->
|
|
@@ -225,7 +221,7 @@ const state = computed(() => {
|
|
|
225
221
|
{{ t('binaryOutput.missizedBadge') }}
|
|
226
222
|
</UBadge>
|
|
227
223
|
</div>
|
|
228
|
-
<p v-if="row.description" class="mt-1 text-
|
|
224
|
+
<p v-if="row.description" class="mt-1 text-2xs leading-relaxed text-muted">
|
|
229
225
|
{{ row.description }}
|
|
230
226
|
</p>
|
|
231
227
|
</li>
|
|
@@ -234,7 +230,7 @@ const state = computed(() => {
|
|
|
234
230
|
<!-- Every qualification the report counted, each naming its own number. Never folded into
|
|
235
231
|
one "some entries were dropped": the fix for an unknown service id is not the fix for
|
|
236
232
|
a malformed entry, and neither is the fix for a list that stops short of the tail. -->
|
|
237
|
-
<ul class="space-y-1 text-
|
|
233
|
+
<ul class="space-y-1 text-2xs text-app-warning-400">
|
|
238
234
|
<!-- The step's OWN target went missing from the catalog, and an id the AGENT invented,
|
|
239
235
|
are two different failures with two different fixes (re-register it, versus correct
|
|
240
236
|
the declaration). `binaryOutputView` returns them as DISJOINT fields precisely so
|
|
@@ -80,7 +80,7 @@ const filename = computed(() => {
|
|
|
80
80
|
v-if="isImage && url"
|
|
81
81
|
:src="url"
|
|
82
82
|
:alt="label ?? assetId"
|
|
83
|
-
class="w-full rounded object-contain"
|
|
83
|
+
class="w-full rounded-sm object-contain"
|
|
84
84
|
:class="previewClass"
|
|
85
85
|
data-testid="stored-asset-preview"
|
|
86
86
|
/>
|
|
@@ -89,7 +89,7 @@ const filename = computed(() => {
|
|
|
89
89
|
frame. -->
|
|
90
90
|
<p
|
|
91
91
|
v-else-if="!isImage && url"
|
|
92
|
-
class="flex items-center gap-1.5 rounded bg-elevated/60 px-2 py-1.5 text-
|
|
92
|
+
class="flex items-center gap-1.5 rounded-sm bg-elevated/60 px-2 py-1.5 text-2xs text-toned"
|
|
93
93
|
data-testid="stored-asset-file"
|
|
94
94
|
>
|
|
95
95
|
<UIcon name="i-lucide-file" class="h-3.5 w-3.5 shrink-0" />
|
|
@@ -97,7 +97,7 @@ const filename = computed(() => {
|
|
|
97
97
|
</p>
|
|
98
98
|
<p
|
|
99
99
|
v-else-if="status === 'error'"
|
|
100
|
-
class="flex items-center gap-1.5 text-
|
|
100
|
+
class="flex items-center gap-1.5 text-2xs text-app-warning-300"
|
|
101
101
|
data-testid="stored-asset-error"
|
|
102
102
|
>
|
|
103
103
|
<span>{{ t('binaryOutput.asset.loadFailed') }}</span>
|
|
@@ -105,29 +105,31 @@ const filename = computed(() => {
|
|
|
105
105
|
{{ t('binaryOutput.asset.retry') }}
|
|
106
106
|
</UButton>
|
|
107
107
|
</p>
|
|
108
|
-
<p v-else class="text-
|
|
108
|
+
<p v-else class="text-2xs text-dimmed" data-testid="stored-asset-loading">
|
|
109
109
|
{{ t('binaryOutput.asset.loading') }}
|
|
110
110
|
</p>
|
|
111
111
|
|
|
112
112
|
<!-- The two things a person does with a delivered asset. Both hang off the object URL, so
|
|
113
113
|
they appear only once the bytes are in hand. -->
|
|
114
|
-
<div v-if="url" class="flex items-center gap-3 text-
|
|
115
|
-
<
|
|
116
|
-
|
|
114
|
+
<div v-if="url" class="flex items-center gap-3 text-2xs">
|
|
115
|
+
<ULink
|
|
116
|
+
raw
|
|
117
|
+
:to="url"
|
|
117
118
|
target="_blank"
|
|
118
119
|
rel="noopener"
|
|
119
120
|
class="text-app-info-300 hover:underline"
|
|
120
121
|
data-testid="stored-asset-open"
|
|
121
122
|
@click.stop
|
|
122
|
-
>{{ t('binaryOutput.asset.open') }}</
|
|
123
|
+
>{{ t('binaryOutput.asset.open') }}</ULink
|
|
123
124
|
>
|
|
124
|
-
<
|
|
125
|
-
|
|
125
|
+
<ULink
|
|
126
|
+
raw
|
|
127
|
+
:to="url"
|
|
126
128
|
:download="filename"
|
|
127
129
|
class="text-app-info-300 hover:underline"
|
|
128
130
|
data-testid="stored-asset-download"
|
|
129
131
|
@click.stop
|
|
130
|
-
>{{ t('binaryOutput.asset.download') }}</
|
|
132
|
+
>{{ t('binaryOutput.asset.download') }}</ULink
|
|
131
133
|
>
|
|
132
134
|
</div>
|
|
133
135
|
</div>
|
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
import { descriptorFieldDefaults } from '@cat-factory/contracts'
|
|
47
47
|
import { pipelineAllowedForManualStart } from '~/utils/pipeline'
|
|
48
48
|
import { buildTaskTypePickerRows } from '~/utils/taskTypePicker'
|
|
49
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
49
50
|
|
|
50
51
|
const ui = useUiStore()
|
|
51
52
|
// Interface tier. In BASIC mode this form asks for the task itself (type, title,
|
|
@@ -141,6 +142,11 @@ const timeboxHours = ref<number | undefined>(undefined)
|
|
|
141
142
|
// default — an expedition exists to cover ground nobody thought to look at, so narrowing it is
|
|
142
143
|
// the deliberate act) plus an optional focus folded into every angle's prompt.
|
|
143
144
|
const fishingPhaseIds = ref<string[]>([])
|
|
145
|
+
function toggleFishingPhase(id: string, checked: boolean) {
|
|
146
|
+
fishingPhaseIds.value = checked
|
|
147
|
+
? [...fishingPhaseIds.value, id]
|
|
148
|
+
: fishingPhaseIds.value.filter((x) => x !== id)
|
|
149
|
+
}
|
|
144
150
|
const fishingFocus = ref('')
|
|
145
151
|
/** Held as a string because the input is a text field; parsed at submit, blank ⇒ the default. */
|
|
146
152
|
const fishingMaxPasses = ref('')
|
|
@@ -938,13 +944,14 @@ function openReviewFrictionDialog(conflict: NonNullable<ReturnType<typeof parseC
|
|
|
938
944
|
data-testid="task-type-row"
|
|
939
945
|
:data-task-type-row="row.id"
|
|
940
946
|
>
|
|
941
|
-
<
|
|
947
|
+
<SectionLabel
|
|
942
948
|
v-if="row.caption"
|
|
943
|
-
|
|
949
|
+
as="p"
|
|
950
|
+
class="mb-1 px-1"
|
|
944
951
|
data-testid="task-type-category"
|
|
945
952
|
>
|
|
946
953
|
{{ row.caption }}
|
|
947
|
-
</
|
|
954
|
+
</SectionLabel>
|
|
948
955
|
<div class="flex flex-wrap gap-1">
|
|
949
956
|
<UButton
|
|
950
957
|
v-for="ty in row.choices"
|
|
@@ -981,7 +988,7 @@ function openReviewFrictionDialog(conflict: NonNullable<ReturnType<typeof parseC
|
|
|
981
988
|
</UFormField>
|
|
982
989
|
|
|
983
990
|
<!-- Recurring tasks are configured as a schedule on the service frame. -->
|
|
984
|
-
<div v-if="isRecurring" class="rounded-lg border border-default p-3 text-
|
|
991
|
+
<div v-if="isRecurring" class="rounded-lg border border-default p-3 text-2xs text-muted">
|
|
985
992
|
<template v-if="recurringFrameId">
|
|
986
993
|
{{ t('board.addTask.recurringWithFrame') }}
|
|
987
994
|
</template>
|
|
@@ -1023,7 +1030,7 @@ function openReviewFrictionDialog(conflict: NonNullable<ReturnType<typeof parseC
|
|
|
1023
1030
|
:ui="{ base: 'cursor-default text-toned' }"
|
|
1024
1031
|
/>
|
|
1025
1032
|
</UFormField>
|
|
1026
|
-
<p v-if="resolvingIssueBodies" class="text-
|
|
1033
|
+
<p v-if="resolvingIssueBodies" class="text-2xs text-dimmed">
|
|
1027
1034
|
{{ t('board.addTask.loadingIssue') }}
|
|
1028
1035
|
</p>
|
|
1029
1036
|
|
|
@@ -1054,7 +1061,7 @@ function openReviewFrictionDialog(conflict: NonNullable<ReturnType<typeof parseC
|
|
|
1054
1061
|
<span class="text-sm text-default">{{ t('board.addTask.technical') }}</span>
|
|
1055
1062
|
</template>
|
|
1056
1063
|
<template #description>
|
|
1057
|
-
<span class="text-
|
|
1064
|
+
<span class="text-2xs text-dimmed">
|
|
1058
1065
|
{{ t('board.addTask.technicalHint') }}
|
|
1059
1066
|
</span>
|
|
1060
1067
|
</template>
|
|
@@ -1103,25 +1110,21 @@ function openReviewFrictionDialog(conflict: NonNullable<ReturnType<typeof parseC
|
|
|
1103
1110
|
:description="t('board.addTask.bugFishingFields.angles.hint')"
|
|
1104
1111
|
>
|
|
1105
1112
|
<div class="grid gap-1.5 sm:grid-cols-2">
|
|
1106
|
-
|
|
1113
|
+
<!-- Each angle keeps its own test hook, so the boolean is derived from the id
|
|
1114
|
+
list rather than bound through a checkbox group. -->
|
|
1115
|
+
<UCheckbox
|
|
1107
1116
|
v-for="phase in BUG_FISHING_PHASES"
|
|
1108
1117
|
:key="phase.id"
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
/>
|
|
1118
|
-
<span class="min-w-0">
|
|
1119
|
-
<span class="block text-default">{{ phase.title }}</span>
|
|
1120
|
-
<span class="block text-[11px] text-dimmed">{{ phase.goal }}</span>
|
|
1121
|
-
</span>
|
|
1122
|
-
</label>
|
|
1118
|
+
size="xs"
|
|
1119
|
+
:model-value="fishingPhaseIds.includes(phase.id)"
|
|
1120
|
+
:label="phase.title"
|
|
1121
|
+
:description="phase.goal"
|
|
1122
|
+
class="rounded-md px-1.5 py-1 hover:bg-elevated/40"
|
|
1123
|
+
:data-testid="`add-task-fishing-angle-${phase.id}`"
|
|
1124
|
+
@update:model-value="toggleFishingPhase(phase.id, $event === true)"
|
|
1125
|
+
/>
|
|
1123
1126
|
</div>
|
|
1124
|
-
<p v-if="fishingPhaseIds.length === 0" class="mt-1.5 text-
|
|
1127
|
+
<p v-if="fishingPhaseIds.length === 0" class="mt-1.5 text-2xs text-dimmed">
|
|
1125
1128
|
{{ t('board.addTask.bugFishingFields.angles.allSelected') }}
|
|
1126
1129
|
</p>
|
|
1127
1130
|
</UFormField>
|
|
@@ -1385,11 +1388,11 @@ function openReviewFrictionDialog(conflict: NonNullable<ReturnType<typeof parseC
|
|
|
1385
1388
|
</div>
|
|
1386
1389
|
|
|
1387
1390
|
<div v-if="configDescriptors.length" class="space-y-3">
|
|
1388
|
-
<
|
|
1391
|
+
<SectionLabel as="span">
|
|
1389
1392
|
{{ t('board.addTask.agentConfiguration') }}
|
|
1390
|
-
</
|
|
1393
|
+
</SectionLabel>
|
|
1391
1394
|
<div v-for="d in configDescriptors" :key="d.id" class="space-y-1">
|
|
1392
|
-
<div class="text-
|
|
1395
|
+
<div class="text-2xs text-muted">{{ d.label }}</div>
|
|
1393
1396
|
<div v-if="d.type === 'select'" class="flex flex-wrap gap-1">
|
|
1394
1397
|
<UButton
|
|
1395
1398
|
v-for="opt in d.options"
|
|
@@ -1411,7 +1414,7 @@ function openReviewFrictionDialog(conflict: NonNullable<ReturnType<typeof parseC
|
|
|
1411
1414
|
:data-testid="`agent-config-${d.id}`"
|
|
1412
1415
|
@update:model-value="(v: string | number) => setConfig(d.id, String(v))"
|
|
1413
1416
|
/>
|
|
1414
|
-
<p class="text-
|
|
1417
|
+
<p class="text-2xs leading-snug text-dimmed">{{ d.description }}</p>
|
|
1415
1418
|
</div>
|
|
1416
1419
|
</div>
|
|
1417
1420
|
|
|
@@ -1440,7 +1443,7 @@ function openReviewFrictionDialog(conflict: NonNullable<ReturnType<typeof parseC
|
|
|
1440
1443
|
:issues-hint="t('board.addTask.noIssuesHint')"
|
|
1441
1444
|
/>
|
|
1442
1445
|
|
|
1443
|
-
<p class="text-
|
|
1446
|
+
<p class="text-2xs text-dimmed">
|
|
1444
1447
|
{{ t('board.addTask.plannedHint') }}
|
|
1445
1448
|
</p>
|
|
1446
1449
|
</template>
|
|
@@ -138,7 +138,7 @@ async function retry() {
|
|
|
138
138
|
data-testid="agent-failure-banner"
|
|
139
139
|
:data-run-kind="run.kind"
|
|
140
140
|
>
|
|
141
|
-
<div class="flex items-center gap-1.5" :class="compact ? 'text-
|
|
141
|
+
<div class="flex items-center gap-1.5" :class="compact ? 'text-2xs' : 'text-xs'">
|
|
142
142
|
<UIcon
|
|
143
143
|
name="i-lucide-alert-triangle"
|
|
144
144
|
class="shrink-0 text-app-error-400"
|
|
@@ -150,7 +150,7 @@ async function retry() {
|
|
|
150
150
|
<p
|
|
151
151
|
v-if="failure?.message"
|
|
152
152
|
class="mt-1 leading-snug text-app-error-300/90"
|
|
153
|
-
:class="compact ? 'line-clamp-2 text-
|
|
153
|
+
:class="compact ? 'line-clamp-2 text-3xs' : 'text-2xs'"
|
|
154
154
|
:title="failure.message"
|
|
155
155
|
>
|
|
156
156
|
{{ failure.message }}
|
|
@@ -159,7 +159,7 @@ async function retry() {
|
|
|
159
159
|
<p
|
|
160
160
|
v-if="failure?.hint"
|
|
161
161
|
class="mt-1 leading-snug text-app-error-400/70"
|
|
162
|
-
:class="compact ? 'text-
|
|
162
|
+
:class="compact ? 'text-3xs' : 'text-2xs'"
|
|
163
163
|
>
|
|
164
164
|
{{ failure.hint }}
|
|
165
165
|
</p>
|
|
@@ -168,7 +168,7 @@ async function retry() {
|
|
|
168
168
|
name the concrete .env fix rather than only pointing at the (unhelpful-here) tab. -->
|
|
169
169
|
<p
|
|
170
170
|
v-if="showEnvironmentLocalHint && !compact"
|
|
171
|
-
class="mt-1 text-
|
|
171
|
+
class="mt-1 text-2xs leading-snug text-app-error-400/70"
|
|
172
172
|
data-testid="agent-failure-environment-local-hint"
|
|
173
173
|
>
|
|
174
174
|
{{
|
|
@@ -192,15 +192,16 @@ async function retry() {
|
|
|
192
192
|
v-if="!compact && failure"
|
|
193
193
|
:detail="failure.detail"
|
|
194
194
|
:message="failure.message"
|
|
195
|
-
summary-class="text-
|
|
196
|
-
pre-class="bg-app-error-950/60 text-
|
|
195
|
+
summary-class="text-3xs text-app-error-400/60 hover:text-app-error-300"
|
|
196
|
+
pre-class="bg-app-error-950/60 text-3xs text-app-error-200/80"
|
|
197
197
|
/>
|
|
198
198
|
|
|
199
199
|
<div class="mt-2 flex flex-wrap items-center gap-2">
|
|
200
|
-
<
|
|
201
|
-
|
|
200
|
+
<UButton
|
|
201
|
+
color="neutral"
|
|
202
|
+
variant="ghost"
|
|
202
203
|
class="nodrag flex items-center gap-1 rounded-md bg-app-error-900/40 text-app-error-200 hover:bg-app-error-900/70 disabled:opacity-60"
|
|
203
|
-
:class="compact ? 'px-2 py-0.5 text-
|
|
204
|
+
:class="compact ? 'px-2 py-0.5 text-3xs' : 'px-2 py-1 text-2xs'"
|
|
204
205
|
:disabled="retrying || !access.canExecuteRuns.value"
|
|
205
206
|
:title="access.canExecuteRuns.value ? undefined : t('access.noRunExecute')"
|
|
206
207
|
data-testid="agent-failure-retry"
|
|
@@ -211,36 +212,38 @@ async function retry() {
|
|
|
211
212
|
:class="[compact ? 'h-3 w-3' : 'h-3.5 w-3.5', { 'animate-spin': retrying }]"
|
|
212
213
|
/>
|
|
213
214
|
{{ retrying ? t('board.failure.retrying') : compact ? t('common.retry') : retryLabel }}
|
|
214
|
-
</
|
|
215
|
+
</UButton>
|
|
215
216
|
|
|
216
|
-
<
|
|
217
|
+
<UButton
|
|
218
|
+
color="neutral"
|
|
219
|
+
variant="ghost"
|
|
217
220
|
v-if="run.kind === 'bootstrap'"
|
|
218
|
-
type="button"
|
|
219
221
|
class="nodrag flex items-center gap-1 rounded-md bg-app-error-900/20 text-app-error-300 hover:bg-app-error-900/50"
|
|
220
|
-
:class="compact ? 'px-2 py-0.5 text-
|
|
222
|
+
:class="compact ? 'px-2 py-0.5 text-3xs' : 'px-2 py-1 text-2xs'"
|
|
221
223
|
data-testid="agent-failure-inspect"
|
|
222
224
|
@click.stop="inspectRun"
|
|
223
225
|
>
|
|
224
226
|
<UIcon name="i-lucide-activity" :class="compact ? 'h-3 w-3' : 'h-3.5 w-3.5'" />
|
|
225
227
|
{{ t('observability.modelActivity') }}
|
|
226
|
-
</
|
|
228
|
+
</UButton>
|
|
227
229
|
|
|
228
230
|
<!-- Environment provisioning failures are almost always a deploy-backend / provider-config
|
|
229
231
|
issue, so link straight to where it's set up rather than leaving the user to hunt. The
|
|
230
232
|
destination + label follow the cause: a `deploy_runner_unwired` failure needs the runner
|
|
231
233
|
pool (Agent containers tab), every other cause needs the environment provider (Test
|
|
232
234
|
environments tab) — see `routesToRunnerPool`. -->
|
|
233
|
-
<
|
|
235
|
+
<UButton
|
|
236
|
+
color="neutral"
|
|
237
|
+
variant="ghost"
|
|
234
238
|
v-if="isEnvironmentFailure"
|
|
235
|
-
type="button"
|
|
236
239
|
class="nodrag flex items-center gap-1 rounded-md bg-app-error-900/20 text-app-error-300 hover:bg-app-error-900/50"
|
|
237
|
-
:class="compact ? 'px-2 py-0.5 text-
|
|
240
|
+
:class="compact ? 'px-2 py-0.5 text-3xs' : 'px-2 py-1 text-2xs'"
|
|
238
241
|
data-testid="agent-failure-configure-environment"
|
|
239
242
|
@click.stop="openFailureSetup"
|
|
240
243
|
>
|
|
241
244
|
<UIcon name="i-lucide-settings" :class="compact ? 'h-3 w-3' : 'h-3.5 w-3.5'" />
|
|
242
245
|
{{ failureSetupLabel }}
|
|
243
|
-
</
|
|
246
|
+
</UButton>
|
|
244
247
|
</div>
|
|
245
248
|
</div>
|
|
246
249
|
</template>
|
|
@@ -13,18 +13,27 @@ const { t } = useI18n()
|
|
|
13
13
|
</script>
|
|
14
14
|
|
|
15
15
|
<template>
|
|
16
|
-
<
|
|
16
|
+
<UCollapsible
|
|
17
17
|
v-if="failures.length"
|
|
18
18
|
class="nodrag rounded-lg border border-muted/60 bg-default/40 px-3 py-2"
|
|
19
19
|
data-testid="agent-failure-history"
|
|
20
20
|
>
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
<template #default="{ open }">
|
|
22
|
+
<UButton
|
|
23
|
+
variant="link"
|
|
24
|
+
color="neutral"
|
|
25
|
+
size="xs"
|
|
26
|
+
icon="i-lucide-history"
|
|
27
|
+
:trailing-icon="open ? 'i-lucide-chevron-down' : 'i-lucide-chevron-right'"
|
|
28
|
+
:label="
|
|
29
|
+
t('board.failure.history.previousErrors', { count: failures.length }, failures.length)
|
|
30
|
+
"
|
|
31
|
+
:ui="{ base: 'w-full justify-start gap-1.5 p-0 text-2xs text-muted hover:text-default' }"
|
|
32
|
+
/>
|
|
33
|
+
</template>
|
|
27
34
|
|
|
28
|
-
<
|
|
29
|
-
|
|
35
|
+
<template #content>
|
|
36
|
+
<FailureHistoryList :failures="props.failures" class="mt-2" />
|
|
37
|
+
</template>
|
|
38
|
+
</UCollapsible>
|
|
30
39
|
</template>
|
|
@@ -193,16 +193,17 @@ async function create() {
|
|
|
193
193
|
<div v-if="presets.length > 1" class="space-y-1.5">
|
|
194
194
|
<span class="text-xs font-medium text-toned">{{ t('initiative.create.preset') }}</span>
|
|
195
195
|
<div class="grid gap-2" data-testid="initiative-preset-picker">
|
|
196
|
-
<
|
|
196
|
+
<UButton
|
|
197
|
+
color="neutral"
|
|
198
|
+
variant="ghost"
|
|
197
199
|
v-for="p in presets"
|
|
198
200
|
:key="p.id"
|
|
199
|
-
type="button"
|
|
200
201
|
:data-testid="`initiative-preset-option-${p.id}`"
|
|
201
202
|
:aria-pressed="p.id === selectedPresetId"
|
|
202
203
|
class="flex items-start gap-3 rounded-md border px-3 py-2 text-left transition"
|
|
203
204
|
:class="
|
|
204
205
|
p.id === selectedPresetId
|
|
205
|
-
? 'border-primary bg-primary/10'
|
|
206
|
+
? 'border-primary bg-primary/10 hover:bg-primary/10 focus-visible:bg-primary/10 disabled:bg-primary/10'
|
|
206
207
|
: 'border-muted hover:border-app-600'
|
|
207
208
|
"
|
|
208
209
|
@click="selectPreset(p.id)"
|
|
@@ -216,11 +217,11 @@ async function create() {
|
|
|
216
217
|
<span class="block text-sm font-medium text-default">
|
|
217
218
|
{{ p.presentation.label }}
|
|
218
219
|
</span>
|
|
219
|
-
<span class="block text-
|
|
220
|
+
<span class="block text-2xs text-muted">
|
|
220
221
|
{{ p.presentation.description }}
|
|
221
222
|
</span>
|
|
222
223
|
</span>
|
|
223
|
-
</
|
|
224
|
+
</UButton>
|
|
224
225
|
</div>
|
|
225
226
|
</div>
|
|
226
227
|
|
|
@@ -264,7 +265,7 @@ async function create() {
|
|
|
264
265
|
:issues-hint="t('initiative.create.contextIssuesHint')"
|
|
265
266
|
/>
|
|
266
267
|
|
|
267
|
-
<p class="text-
|
|
268
|
+
<p class="text-2xs text-dimmed">
|
|
268
269
|
{{ t('initiative.create.hint') }}
|
|
269
270
|
</p>
|
|
270
271
|
</div>
|
|
@@ -18,18 +18,28 @@ const { t } = useI18n()
|
|
|
18
18
|
</script>
|
|
19
19
|
|
|
20
20
|
<template>
|
|
21
|
-
<
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
<UCollapsible v-if="detail && detail !== message" class="mt-1">
|
|
22
|
+
<template #default="{ open }">
|
|
23
|
+
<UButton
|
|
24
|
+
variant="link"
|
|
25
|
+
color="neutral"
|
|
26
|
+
size="xs"
|
|
27
|
+
:icon="open ? 'i-lucide-chevron-down' : 'i-lucide-chevron-right'"
|
|
28
|
+
:label="t('board.failure.showDetail')"
|
|
29
|
+
:class="summaryClass"
|
|
30
|
+
:ui="{ base: 'w-full justify-start gap-1 p-0' }"
|
|
31
|
+
/>
|
|
32
|
+
</template>
|
|
25
33
|
<!-- The stack trace / extended detail: the first thing a user does with it is copy it, so
|
|
26
34
|
offer a copy affordance floated over the scroll box (UX-39). -->
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
<template #content>
|
|
36
|
+
<div class="relative mt-1">
|
|
37
|
+
<CopyButton :text="detail" class="absolute end-1 top-1 z-10" />
|
|
38
|
+
<pre
|
|
39
|
+
class="max-h-32 overflow-auto whitespace-pre-wrap rounded-sm p-1.5 pe-9"
|
|
40
|
+
:class="preClass"
|
|
41
|
+
>{{ detail }}</pre>
|
|
42
|
+
</div>
|
|
43
|
+
</template>
|
|
44
|
+
</UCollapsible>
|
|
35
45
|
</template>
|
|
@@ -23,24 +23,24 @@ const ordered = computed(() => [...props.failures].reverse())
|
|
|
23
23
|
class="rounded-md border border-default/80 bg-app-950/50 px-2.5 py-2"
|
|
24
24
|
data-testid="agent-failure-history-entry"
|
|
25
25
|
>
|
|
26
|
-
<div class="flex items-center gap-1.5 text-
|
|
26
|
+
<div class="flex items-center gap-1.5 text-3xs text-dimmed">
|
|
27
27
|
<UIcon name="i-lucide-alert-triangle" class="h-3 w-3 shrink-0 text-app-error-400/70" />
|
|
28
28
|
<time>{{ d(new Date(failure.occurredAt), 'long') }}</time>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
|
-
<p class="mt-1 text-
|
|
31
|
+
<p class="mt-1 text-2xs leading-snug text-toned" :title="failure.message">
|
|
32
32
|
{{ failure.message }}
|
|
33
33
|
</p>
|
|
34
34
|
|
|
35
|
-
<p v-if="failure.hint" class="mt-1 text-
|
|
35
|
+
<p v-if="failure.hint" class="mt-1 text-3xs leading-snug text-dimmed">
|
|
36
36
|
{{ failure.hint }}
|
|
37
37
|
</p>
|
|
38
38
|
|
|
39
39
|
<FailureDetail
|
|
40
40
|
:detail="failure.detail"
|
|
41
41
|
:message="failure.message"
|
|
42
|
-
summary-class="text-
|
|
43
|
-
pre-class="bg-app-950/80 text-
|
|
42
|
+
summary-class="text-3xs text-dimmed hover:text-toned"
|
|
43
|
+
pre-class="bg-app-950/80 text-3xs text-muted"
|
|
44
44
|
/>
|
|
45
45
|
</li>
|
|
46
46
|
</ol>
|
|
@@ -12,6 +12,7 @@ import { BUILTIN_TASK_SOURCE_KINDS } from '@cat-factory/contracts'
|
|
|
12
12
|
import { apiErrorReason } from '~/composables/api/errors'
|
|
13
13
|
import { pipelineAllowedForSchedule } from '~/utils/pipeline'
|
|
14
14
|
import { appliesIntakePredicate } from '~/utils/intakePredicates'
|
|
15
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
15
16
|
|
|
16
17
|
const ui = useUiStore()
|
|
17
18
|
const board = useBoardStore()
|
|
@@ -453,7 +454,7 @@ async function add() {
|
|
|
453
454
|
<USwitch v-model="onDemand" :disabled="onDemandLocked" size="sm" class="mt-0.5" />
|
|
454
455
|
<div class="space-y-0.5">
|
|
455
456
|
<p class="text-xs font-medium text-default">{{ t('board.recurring.onDemand') }}</p>
|
|
456
|
-
<p class="text-
|
|
457
|
+
<p class="text-2xs text-dimmed">
|
|
457
458
|
{{
|
|
458
459
|
onDemandLocked
|
|
459
460
|
? t('board.recurring.onDemandLockedHint')
|
|
@@ -466,10 +467,10 @@ async function add() {
|
|
|
466
467
|
<RecurringRecurrenceEditor v-if="!onDemand" v-model="recurrence" />
|
|
467
468
|
|
|
468
469
|
<div v-if="filesTicket" class="space-y-3 rounded-lg border border-default p-3">
|
|
469
|
-
<
|
|
470
|
+
<SectionLabel as="p">
|
|
470
471
|
{{ t('board.recurring.issueTracker') }}
|
|
471
|
-
</
|
|
472
|
-
<p class="text-
|
|
472
|
+
</SectionLabel>
|
|
473
|
+
<p class="text-2xs text-dimmed">
|
|
473
474
|
{{ t('board.recurring.issueTrackerHint') }}
|
|
474
475
|
</p>
|
|
475
476
|
<div class="flex gap-1">
|
|
@@ -541,22 +542,22 @@ async function add() {
|
|
|
541
542
|
<p class="text-xs font-medium text-default">
|
|
542
543
|
{{ t('board.recurring.trackerTrigger') }}
|
|
543
544
|
</p>
|
|
544
|
-
<p class="text-
|
|
545
|
+
<p class="text-2xs text-dimmed">
|
|
545
546
|
{{ t('board.recurring.trackerTriggerHint') }}
|
|
546
547
|
</p>
|
|
547
548
|
</div>
|
|
548
549
|
</div>
|
|
549
550
|
|
|
550
551
|
<div v-if="showIntake" class="space-y-3 rounded-lg border border-default p-3">
|
|
551
|
-
<
|
|
552
|
+
<SectionLabel as="p">
|
|
552
553
|
{{ t('board.recurring.intake') }}
|
|
553
|
-
</
|
|
554
|
-
<p class="text-
|
|
554
|
+
</SectionLabel>
|
|
555
|
+
<p class="text-2xs text-dimmed">
|
|
555
556
|
{{ t('board.recurring.intakeHint') }}
|
|
556
557
|
</p>
|
|
557
558
|
<!-- Two different remedies: connect something, versus connect something ELSE. A source
|
|
558
559
|
that is connected but cannot run a scheduled search is not an absent connection. -->
|
|
559
|
-
<p v-if="intakeSources.length === 0" class="text-
|
|
560
|
+
<p v-if="intakeSources.length === 0" class="text-2xs text-app-warning-500">
|
|
560
561
|
{{
|
|
561
562
|
tasks.anyOffered
|
|
562
563
|
? t('board.recurring.intakeNoIntakeSources')
|
|
@@ -626,7 +627,7 @@ async function add() {
|
|
|
626
627
|
</UFormField>
|
|
627
628
|
|
|
628
629
|
<template v-if="intakeSource">
|
|
629
|
-
<p class="text-
|
|
630
|
+
<p class="text-2xs text-dimmed">
|
|
630
631
|
{{
|
|
631
632
|
intakeDispatch === 'per-ticket'
|
|
632
633
|
? t('board.recurring.intakeDispatchPerTicketHint')
|
|
@@ -677,7 +678,7 @@ async function add() {
|
|
|
677
678
|
</template>
|
|
678
679
|
</div>
|
|
679
680
|
|
|
680
|
-
<p class="text-
|
|
681
|
+
<p class="text-2xs text-dimmed">
|
|
681
682
|
{{ t('board.recurring.footerHint') }}
|
|
682
683
|
</p>
|
|
683
684
|
</div>
|