@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.
Files changed (265) hide show
  1. package/README.md +32 -2
  2. package/app/assets/css/main.css +22 -0
  3. package/app/assets/css/prose.css +4 -4
  4. package/app/assets/css/type.css +24 -0
  5. package/app/components/assistant/AssistantModal.vue +8 -6
  6. package/app/components/auth/BackendMisconfiguredScreen.vue +4 -3
  7. package/app/components/auth/LoginScreen.vue +40 -26
  8. package/app/components/auth/ResetPasswordScreen.vue +9 -4
  9. package/app/components/auth/UserMenu.vue +5 -4
  10. package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +48 -37
  11. package/app/components/binaryOutput/BinaryOutputReport.vue +10 -14
  12. package/app/components/binaryOutput/StoredAssetView.vue +13 -11
  13. package/app/components/board/AddTaskModal.vue +30 -27
  14. package/app/components/board/AgentFailureCard.vue +21 -18
  15. package/app/components/board/AgentFailureHistory.vue +18 -9
  16. package/app/components/board/CreateInitiativeModal.vue +7 -6
  17. package/app/components/board/FailureDetail.vue +22 -12
  18. package/app/components/board/FailureHistoryList.vue +5 -5
  19. package/app/components/board/RecurringPipelineModal.vue +12 -11
  20. package/app/components/board/ReviewFrictionDialog.vue +8 -6
  21. package/app/components/board/StepExecutionHistory.vue +8 -8
  22. package/app/components/board/nodes/AgentChip.vue +1 -1
  23. package/app/components/board/nodes/BlockNode.vue +25 -24
  24. package/app/components/board/nodes/DecisionBadge.vue +4 -3
  25. package/app/components/board/nodes/EpicNode.vue +4 -4
  26. package/app/components/board/nodes/FrameSwimlanes.vue +8 -10
  27. package/app/components/board/nodes/InitiativeCard.vue +4 -4
  28. package/app/components/board/nodes/LaneGroup.vue +3 -5
  29. package/app/components/board/nodes/TaskCard.vue +20 -15
  30. package/app/components/board/nodes/TaskLane.vue +3 -3
  31. package/app/components/board/nodes/TaskPipelineMini.vue +21 -18
  32. package/app/components/bootstrap/AdoptionReviewModal.vue +36 -26
  33. package/app/components/bootstrap/BootstrapModal.vue +14 -13
  34. package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
  35. package/app/components/brainstorm/BrainstormWindow.vue +13 -10
  36. package/app/components/bugFishing/BugFishingWindow.vue +81 -58
  37. package/app/components/clarity/ClarityReviewWindow.vue +13 -10
  38. package/app/components/common/AsyncViewError.vue +1 -1
  39. package/app/components/common/ClarificationItem.vue +6 -6
  40. package/app/components/common/CopyButton.vue +12 -11
  41. package/app/components/common/DescriptorFields.vue +1 -1
  42. package/app/components/common/EmptyState.vue +1 -1
  43. package/app/components/common/IconButton.vue +34 -9
  44. package/app/components/common/InterviewGateNotice.vue +4 -4
  45. package/app/components/common/MarkdownProse.vue +8 -2
  46. package/app/components/common/SectionLabel.vue +38 -0
  47. package/app/components/consensus/ConsensusSessionWindow.vue +10 -9
  48. package/app/components/context/ContextAttachmentFields.vue +32 -20
  49. package/app/components/docs/DocInterviewWindow.vue +10 -9
  50. package/app/components/documents/ContextDocumentPicker.vue +22 -21
  51. package/app/components/documents/DocumentImportModal.vue +7 -5
  52. package/app/components/documents/DocumentOriginLink.vue +12 -9
  53. package/app/components/documents/DocumentSourceConnectModal.vue +2 -2
  54. package/app/components/documents/DocumentSyncState.vue +4 -4
  55. package/app/components/documents/DocumentTemplatesModal.vue +5 -4
  56. package/app/components/documents/RepoContextDocPicker.vue +7 -9
  57. package/app/components/documents/StartFromDesignModal.vue +4 -4
  58. package/app/components/documents/TaskContextDocs.vue +1 -1
  59. package/app/components/environments/EnvSetupStepper.vue +3 -3
  60. package/app/components/environments/EnvironmentStatusPanel.vue +15 -13
  61. package/app/components/environments/steps/EnvPreflightStep.vue +8 -8
  62. package/app/components/environments/steps/EnvReviewStep.vue +23 -22
  63. package/app/components/environments/steps/EnvSaveStep.vue +5 -5
  64. package/app/components/focus/BlockFocusView.vue +11 -10
  65. package/app/components/followUp/FollowUpWindow.vue +18 -15
  66. package/app/components/forkDecision/ForkDecisionWindow.vue +85 -97
  67. package/app/components/foundational/FoundationalContractSummary.vue +2 -2
  68. package/app/components/foundational/FoundationalServiceCatalogList.vue +6 -5
  69. package/app/components/foundational/FoundationalServiceRegistry.vue +10 -9
  70. package/app/components/foundational/FoundationalServiceSources.vue +7 -6
  71. package/app/components/foundational/FoundationalSuppressions.vue +2 -2
  72. package/app/components/fragments/FragmentLibraryManager.vue +8 -7
  73. package/app/components/fragments/FragmentSelector.vue +22 -20
  74. package/app/components/gates/GateFailingCheckList.vue +7 -6
  75. package/app/components/gates/GateResultView.vue +55 -49
  76. package/app/components/github/AddServiceFromRepoModal.vue +16 -11
  77. package/app/components/github/BranchProtectionPreflight.vue +5 -5
  78. package/app/components/github/GitHubConnect.vue +5 -3
  79. package/app/components/github/GitHubOnboarding.vue +7 -2
  80. package/app/components/github/GitHubPanel.vue +23 -19
  81. package/app/components/github/RepoTreeBrowser.vue +16 -13
  82. package/app/components/humanTest/HumanTestWindow.vue +29 -24
  83. package/app/components/initiative/InitiativePlanNotice.vue +3 -3
  84. package/app/components/initiative/InitiativePlanReview.vue +46 -38
  85. package/app/components/initiative/InitiativePlanningWindow.vue +5 -5
  86. package/app/components/initiative/InitiativeTrackerWindow.vue +213 -165
  87. package/app/components/judge/JudgeResultView.vue +28 -27
  88. package/app/components/kaizen/KaizenPanel.vue +70 -56
  89. package/app/components/kaizen/KaizenStepStatus.vue +7 -6
  90. package/app/components/layout/AccountAuditLog.vue +1 -1
  91. package/app/components/layout/AccountDeploymentSettings.vue +10 -10
  92. package/app/components/layout/AccountFailureKindRules.vue +13 -13
  93. package/app/components/layout/AccountFoundationalSettings.vue +1 -1
  94. package/app/components/layout/AccountFragmentSettings.vue +1 -1
  95. package/app/components/layout/AccountModelPolicySettings.vue +7 -7
  96. package/app/components/layout/AccountPlatformAlertSettings.vue +8 -8
  97. package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
  98. package/app/components/layout/AccountRunCredentialSettings.vue +3 -3
  99. package/app/components/layout/AccountSkillSettings.vue +1 -1
  100. package/app/components/layout/AccountTeamSettings.vue +13 -9
  101. package/app/components/layout/AiProvidersBanner.vue +1 -1
  102. package/app/components/layout/AppearanceSwitcher.vue +5 -4
  103. package/app/components/layout/BoardSwitcher.vue +13 -10
  104. package/app/components/layout/BoardToolbar.vue +10 -5
  105. package/app/components/layout/CommandBar.vue +8 -5
  106. package/app/components/layout/DefaultTestEnvBanner.vue +6 -5
  107. package/app/components/layout/IntegrationsHub.vue +12 -9
  108. package/app/components/layout/LanguageSwitcher.vue +5 -4
  109. package/app/components/layout/ModelProvidersHub.vue +10 -7
  110. package/app/components/layout/NotificationsInbox.vue +47 -36
  111. package/app/components/layout/PersonalSetupModal.vue +9 -6
  112. package/app/components/layout/RolePrompt.vue +5 -4
  113. package/app/components/layout/SideBar.vue +7 -8
  114. package/app/components/layout/SpendWarningBanner.vue +3 -3
  115. package/app/components/layout/TranslationWarningBanner.vue +5 -4
  116. package/app/components/layout/UiModeSwitcher.vue +15 -12
  117. package/app/components/layout/UiRoleSwitcher.vue +10 -8
  118. package/app/components/layout/WorkspaceMembersSettings.vue +2 -2
  119. package/app/components/media/ArtifactLightbox.vue +74 -44
  120. package/app/components/media/ImageCompare.vue +80 -85
  121. package/app/components/merge/MergeEffortChips.vue +4 -6
  122. package/app/components/notifications/NotificationSettingsPanel.vue +6 -5
  123. package/app/components/observability/OutcomeFilterChips.vue +6 -5
  124. package/app/components/observability/RunFailureSummary.vue +22 -23
  125. package/app/components/observability/StepMetricsBar.vue +9 -8
  126. package/app/components/observability/StepModelActivity.vue +8 -5
  127. package/app/components/observability/ToolCallList.vue +19 -20
  128. package/app/components/outcome/OutcomeSummaryWindow.vue +48 -46
  129. package/app/components/palettes/AgentPalette.vue +21 -15
  130. package/app/components/palettes/AgentTierSelect.vue +1 -1
  131. package/app/components/palettes/PipelinePurposeSelect.vue +1 -1
  132. package/app/components/panels/AgentStepDetail.vue +57 -49
  133. package/app/components/panels/AttemptEntryHeader.vue +2 -2
  134. package/app/components/panels/DecisionModal.vue +1 -1
  135. package/app/components/panels/GenericStructuredResultView.vue +6 -5
  136. package/app/components/panels/InspectorPanel.vue +15 -13
  137. package/app/components/panels/MergerResultView.vue +10 -9
  138. package/app/components/panels/ObservabilityPanel.vue +211 -186
  139. package/app/components/panels/OperatorDashboardPanel.vue +124 -115
  140. package/app/components/panels/ReportsPanel.vue +87 -83
  141. package/app/components/panels/ReportsSpendBreakdown.vue +2 -2
  142. package/app/components/panels/ResultWindowShell.vue +152 -137
  143. package/app/components/panels/RunDetailLoadState.vue +1 -1
  144. package/app/components/panels/StepContainerStatus.vue +17 -16
  145. package/app/components/panels/StepDelegatedStatus.vue +24 -21
  146. package/app/components/panels/StepEffortReport.vue +12 -17
  147. package/app/components/panels/StepFragmentAdherence.vue +9 -10
  148. package/app/components/panels/StepMetadataCard.vue +41 -43
  149. package/app/components/panels/StepReproductionReport.vue +18 -20
  150. package/app/components/panels/StepRestartControl.vue +3 -2
  151. package/app/components/panels/StepRunMeta.vue +27 -26
  152. package/app/components/panels/StepTestReport.vue +16 -15
  153. package/app/components/panels/StepToolServers.vue +7 -8
  154. package/app/components/panels/StepValidationReport.vue +5 -5
  155. package/app/components/panels/inspector/ContainerSummary.vue +4 -4
  156. package/app/components/panels/inspector/DocReferenceRepos.vue +5 -4
  157. package/app/components/panels/inspector/EnvProbeReport.vue +16 -13
  158. package/app/components/panels/inspector/EpicChildren.vue +12 -10
  159. package/app/components/panels/inspector/FrontendBindingsResolved.vue +5 -4
  160. package/app/components/panels/inspector/FrontendConfig.vue +29 -36
  161. package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
  162. package/app/components/panels/inspector/InspectorSection.vue +25 -17
  163. package/app/components/panels/inspector/RecurringScheduleSettings.vue +9 -8
  164. package/app/components/panels/inspector/ServiceConnections.vue +5 -4
  165. package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -2
  166. package/app/components/panels/inspector/ServiceSelfTests.vue +9 -13
  167. package/app/components/panels/inspector/ServiceTestConfig.vue +46 -49
  168. package/app/components/panels/inspector/ServiceTestSecrets.vue +3 -3
  169. package/app/components/panels/inspector/ServiceTestingContext.vue +2 -2
  170. package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
  171. package/app/components/panels/inspector/TaskAgentConfig.vue +2 -2
  172. package/app/components/panels/inspector/TaskAprioriBranches.vue +6 -5
  173. package/app/components/panels/inspector/TaskDependencies.vue +1 -1
  174. package/app/components/panels/inspector/TaskEstimateBadge.vue +3 -7
  175. package/app/components/panels/inspector/TaskExecution.vue +18 -16
  176. package/app/components/panels/inspector/TaskRunSettings.vue +45 -44
  177. package/app/components/panels/inspector/TaskStructure.vue +5 -4
  178. package/app/components/pipeline/AgentPromptEditor.vue +15 -14
  179. package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -52
  180. package/app/components/pipeline/EstimateThresholdFields.vue +14 -11
  181. package/app/components/pipeline/GateConfigFields.vue +19 -23
  182. package/app/components/pipeline/IterationCapPrompt.vue +1 -1
  183. package/app/components/pipeline/PipelineBuilder.vue +113 -99
  184. package/app/components/pipeline/PipelineHealthModal.vue +7 -7
  185. package/app/components/pipeline/PipelinePicker.vue +11 -9
  186. package/app/components/pipeline/PipelinePreview.vue +6 -7
  187. package/app/components/pipeline/PipelineProgress.vue +49 -45
  188. package/app/components/prReview/PrReviewWindow.vue +87 -65
  189. package/app/components/providers/AiPresetMismatchDialog.vue +4 -3
  190. package/app/components/providers/AiProviderOnboardingModal.vue +2 -2
  191. package/app/components/providers/ApiKeysSection.vue +11 -9
  192. package/app/components/providers/PersonalSubscriptionSection.vue +4 -3
  193. package/app/components/providers/VendorCredentialsModal.vue +5 -4
  194. package/app/components/provisioning/ProvisioningLogsDrawer.vue +10 -9
  195. package/app/components/ralph/RalphLoopResultView.vue +29 -29
  196. package/app/components/requirements/RequirementsReviewWindow.vue +22 -17
  197. package/app/components/riskPolicy/RiskPolicyPicker.vue +13 -11
  198. package/app/components/riskPolicy/RiskPolicyPreview.vue +16 -15
  199. package/app/components/sandbox/SandboxPanel.vue +93 -73
  200. package/app/components/settings/ApiTokensPanel.vue +1 -1
  201. package/app/components/settings/BudgetSettings.vue +18 -17
  202. package/app/components/settings/CapabilityCredentialsPanel.vue +5 -5
  203. package/app/components/settings/CloudflareHandlerSection.vue +44 -41
  204. package/app/components/settings/ComposeEnvironmentSetupSection.vue +14 -12
  205. package/app/components/settings/ConnectionTestVerdict.vue +1 -1
  206. package/app/components/settings/ConsensusGroupsSection.vue +58 -47
  207. package/app/components/settings/CustomManifestTypeEditor.vue +8 -7
  208. package/app/components/settings/DefaultProvisionTypeSection.vue +5 -5
  209. package/app/components/settings/InfraHandlersConfigurator.vue +26 -24
  210. package/app/components/settings/InfrastructureBackendPicker.vue +18 -18
  211. package/app/components/settings/IssueTrackerPanel.vue +30 -21
  212. package/app/components/settings/KubernetesEngineForm.vue +9 -8
  213. package/app/components/settings/KubernetesEnvironmentForm.vue +4 -3
  214. package/app/components/settings/LocalContainerPoolSettings.vue +2 -2
  215. package/app/components/settings/LocalModelEndpointsPanel.vue +13 -11
  216. package/app/components/settings/MergeClassRulesEditor.vue +6 -5
  217. package/app/components/settings/MergeRolePolicyEditor.vue +13 -12
  218. package/app/components/settings/ModelConfigurationPanel.vue +17 -19
  219. package/app/components/settings/ModelPresetHealthModal.vue +3 -3
  220. package/app/components/settings/ObservabilityConnectionPanel.vue +1 -1
  221. package/app/components/settings/OpenRouterCatalogPanel.vue +10 -8
  222. package/app/components/settings/PackageRegistriesPanel.vue +4 -4
  223. package/app/components/settings/ProviderConnectionTab.vue +5 -4
  224. package/app/components/settings/ProviderManifestEditor.vue +9 -8
  225. package/app/components/settings/ProviderPreferenceEditor.vue +13 -13
  226. package/app/components/settings/RiskPolicyCreateForm.vue +40 -26
  227. package/app/components/settings/RiskPolicyEditorRow.vue +21 -19
  228. package/app/components/settings/RiskPolicyHealthModal.vue +3 -3
  229. package/app/components/settings/RiskPolicyPanel.vue +11 -13
  230. package/app/components/settings/ServiceFragmentDefaultsPanel.vue +15 -12
  231. package/app/components/settings/SharedStacksPanel.vue +5 -5
  232. package/app/components/settings/TaskSourceCard.vue +2 -2
  233. package/app/components/settings/TaskTypeSuppressionsPanel.vue +4 -4
  234. package/app/components/settings/ToolServerChecklist.vue +22 -22
  235. package/app/components/settings/UsageSettings.vue +13 -13
  236. package/app/components/settings/UserSecretsSection.vue +4 -3
  237. package/app/components/settings/WorkspaceMetadataSettings.vue +6 -5
  238. package/app/components/settings/WorkspaceSettingsPanel.vue +72 -58
  239. package/app/components/skills/ReviewSkillQueue.vue +12 -10
  240. package/app/components/skills/SkillLibraryManager.vue +9 -8
  241. package/app/components/slack/SlackPanel.vue +17 -12
  242. package/app/components/spec/ServiceSpecWindow.vue +19 -19
  243. package/app/components/tasks/BugHuntModal.vue +1 -1
  244. package/app/components/tasks/ContextIssuePicker.vue +16 -15
  245. package/app/components/tasks/TaskContextIssues.vue +5 -4
  246. package/app/components/tasks/TaskImportModal.vue +3 -2
  247. package/app/components/tasks/TaskSourceConnectModal.vue +5 -5
  248. package/app/components/testing/TestReportWindow.vue +67 -60
  249. package/app/components/theme/ThemeImportModal.vue +2 -2
  250. package/app/components/tutorial/TutorialNudge.vue +3 -2
  251. package/app/components/tutorial/TutorialOverlay.vue +3 -2
  252. package/app/components/vcs/GitLabConnect.vue +1 -1
  253. package/app/components/visualConfirm/VisualConfirmationWindow.vue +79 -54
  254. package/app/utils/theme/builtins.ts +7 -1
  255. package/i18n/locales/de.json +7 -3
  256. package/i18n/locales/en.json +7 -3
  257. package/i18n/locales/es.json +7 -3
  258. package/i18n/locales/fr.json +7 -3
  259. package/i18n/locales/he.json +7 -3
  260. package/i18n/locales/it.json +7 -3
  261. package/i18n/locales/ja.json +7 -3
  262. package/i18n/locales/pl.json +7 -3
  263. package/i18n/locales/tr.json +7 -3
  264. package/i18n/locales/uk.json +7 -3
  265. package/package.json +1 -1
@@ -28,6 +28,8 @@ import {
28
28
  mayCarrySkipAxis,
29
29
  } from '~/utils/catalog'
30
30
  import type { ConsensusStrategy } from '~/types/consensus'
31
+ import SectionLabel from '~/components/common/SectionLabel.vue'
32
+ import IconButton from '~/components/common/IconButton.vue'
31
33
 
32
34
  type DraftUnit = { index: number; kind: AgentKind; companionIndex: number | null }
33
35
 
@@ -423,9 +425,9 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
423
425
  data-testid="pipeline-builder-palette"
424
426
  >
425
427
  <div class="mb-2 flex shrink-0 items-center justify-between gap-2">
426
- <h3 class="text-xs font-semibold uppercase tracking-wide text-muted">
428
+ <SectionLabel as="h3">
427
429
  {{ t('pipeline.builder.agentPalette') }}
428
- </h3>
430
+ </SectionLabel>
429
431
  <UButton
430
432
  color="primary"
431
433
  variant="soft"
@@ -447,9 +449,9 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
447
449
  data-testid="pipeline-builder-draft"
448
450
  >
449
451
  <div class="mb-2 flex items-center justify-between gap-2">
450
- <h3 class="text-xs font-semibold uppercase tracking-wide text-muted">
452
+ <SectionLabel as="h3">
451
453
  {{ t('pipeline.builder.pipeline') }}
452
- </h3>
454
+ </SectionLabel>
453
455
  <UButton
454
456
  color="neutral"
455
457
  variant="soft"
@@ -490,14 +492,24 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
490
492
  class="gap-1"
491
493
  >
492
494
  {{ l }}
493
- <button type="button" class="hover:text-app-error-400" @click="removeLabel(l)">
494
- <UIcon name="i-lucide-x" class="h-3 w-3" />
495
- </button>
495
+ <IconButton
496
+ color="neutral"
497
+ variant="ghost"
498
+ size="xs"
499
+ icon="i-lucide-x"
500
+ :label="t('pipeline.builder.removeLabel', { label: l })"
501
+ :ui="{
502
+ base: 'p-0 hover:bg-transparent hover:text-app-error-400',
503
+ leadingIcon: 'h-3 w-3',
504
+ }"
505
+ @click="removeLabel(l)"
506
+ />
496
507
  </UBadge>
497
- <input
508
+ <UInput
498
509
  v-model="newLabel"
510
+ size="xs"
511
+ class="w-20 focus-within:w-28"
499
512
  :placeholder="t('pipeline.builder.labelPlaceholder')"
500
- class="w-20 rounded border border-muted bg-default px-1.5 py-0.5 text-[11px] text-default focus:w-28"
501
513
  @keydown.enter.prevent="addLabel"
502
514
  @blur="addLabel"
503
515
  />
@@ -508,7 +520,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
508
520
  <p
509
521
  v-for="warning in draftWarnings"
510
522
  :key="warning.key"
511
- class="mb-2 flex items-center gap-1.5 rounded-md border border-app-warning-800/50 bg-app-warning-950/30 px-2 py-1 text-[11px] text-app-warning-300"
523
+ class="mb-2 flex items-center gap-1.5 rounded-md border border-app-warning-800/50 bg-app-warning-950/30 px-2 py-1 text-2xs text-app-warning-300"
512
524
  :data-testid="warning.testId"
513
525
  >
514
526
  <UIcon name="i-lucide-alert-triangle" class="h-3.5 w-3.5 shrink-0" />
@@ -533,7 +545,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
533
545
  :data-gated="pipelines.draftGates[unit.index] === true"
534
546
  >
535
547
  <div class="flex items-center gap-1.5">
536
- <span class="w-4 shrink-0 text-center text-[10px] text-dimmed">{{ vi + 1 }}</span>
548
+ <span class="w-4 shrink-0 text-center text-3xs text-dimmed">{{ vi + 1 }}</span>
537
549
  <AgentKindIcon :kind="unit.kind" icon-class="h-4 w-4" />
538
550
  <span
539
551
  class="min-w-0 flex-1 truncate text-xs text-app-100"
@@ -544,7 +556,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
544
556
  </span>
545
557
  <div class="flex shrink-0 items-center">
546
558
  <!-- Companion toggle: attach/detach the dependent reviewer for this producer. -->
547
- <UButton
559
+ <IconButton
548
560
  v-if="companionForProducer(unit.kind)"
549
561
  :icon="
550
562
  unit.companionIndex !== null ? 'i-lucide-scan-eye' : 'i-lucide-scan-search'
@@ -552,7 +564,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
552
564
  :color="unit.companionIndex !== null ? 'secondary' : 'neutral'"
553
565
  variant="ghost"
554
566
  size="xs"
555
- :title="
567
+ :label="
556
568
  unit.companionIndex !== null
557
569
  ? t('pipeline.builder.companionRemove', {
558
570
  companion: companionLabel(unit.kind),
@@ -564,7 +576,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
564
576
  @click="pipelines.toggleCompanion(unit.index)"
565
577
  />
566
578
  <!-- Enable/disable: keep the step in the pipeline but skip it at run. -->
567
- <UButton
579
+ <IconButton
568
580
  :icon="
569
581
  pipelines.draftEnabled[unit.index] === false
570
582
  ? 'i-lucide-eye-off'
@@ -573,7 +585,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
573
585
  :color="pipelines.draftEnabled[unit.index] === false ? 'neutral' : 'primary'"
574
586
  variant="ghost"
575
587
  size="xs"
576
- :title="
588
+ :label="
577
589
  pipelines.draftEnabled[unit.index] === false
578
590
  ? t('pipeline.builder.enableTooltip')
579
591
  : t('pipeline.builder.disableTooltip')
@@ -591,13 +603,13 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
591
603
  so the engine holds it to the same gatability rule as an estimate gate
592
604
  (`assertValidRunConditions`) — without this the builder invited a condition on
593
605
  `merger` and answered the save with a 422. -->
594
- <UButton
606
+ <IconButton
595
607
  v-if="mayCarrySkipAxis(unit.kind)"
596
608
  :icon="CONDITION_ICONS[pipelines.draftStepCondition(unit.index) ?? 'always']"
597
609
  :color="pipelines.draftStepCondition(unit.index) ? 'info' : 'neutral'"
598
610
  variant="ghost"
599
611
  size="xs"
600
- :title="
612
+ :label="
601
613
  t(
602
614
  `pipeline.builder.condition.${pipelines.draftStepCondition(unit.index) ?? 'always'}`,
603
615
  )
@@ -607,14 +619,14 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
607
619
  />
608
620
  <!-- Approval gate: pause after this step so a human reviews (and
609
621
  can edit) its proposal before the next step runs. -->
610
- <UButton
622
+ <IconButton
611
623
  :icon="
612
624
  pipelines.draftGates[unit.index] ? 'i-lucide-shield-check' : 'i-lucide-shield'
613
625
  "
614
626
  :color="pipelines.draftGates[unit.index] ? 'warning' : 'neutral'"
615
627
  variant="ghost"
616
628
  size="xs"
617
- :title="
629
+ :label="
618
630
  pipelines.draftGates[unit.index]
619
631
  ? t('pipeline.builder.approvalRemoveTooltip')
620
632
  : t('pipeline.builder.approvalAddTooltip')
@@ -624,7 +636,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
624
636
  />
625
637
  <!-- Consensus: run this step through the multi-model mechanism (eligible
626
638
  kinds only — architect/analysis/task-estimator). -->
627
- <UButton
639
+ <IconButton
628
640
  v-if="isConsensusEligibleKind(unit.kind)"
629
641
  :icon="
630
642
  pipelines.draftConsensus[unit.index]?.enabled
@@ -634,7 +646,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
634
646
  :color="pipelines.draftConsensus[unit.index]?.enabled ? 'success' : 'neutral'"
635
647
  variant="ghost"
636
648
  size="xs"
637
- :title="
649
+ :label="
638
650
  pipelines.draftConsensus[unit.index]?.enabled
639
651
  ? t('pipeline.builder.consensusRevertTooltip')
640
652
  : t('pipeline.builder.consensusEnableTooltip')
@@ -643,7 +655,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
643
655
  />
644
656
  <!-- Follow-up companion: the future-looking Coder surfaces loose ends /
645
657
  side-tasks / questions mid-run (coder steps only). Enabled by default. -->
646
- <UButton
658
+ <IconButton
647
659
  v-if="unit.kind === 'coder'"
648
660
  :icon="
649
661
  pipelines.draftFollowUps[unit.index] === false
@@ -655,7 +667,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
655
667
  "
656
668
  variant="ghost"
657
669
  size="xs"
658
- :title="
670
+ :label="
659
671
  pipelines.draftFollowUps[unit.index] === false
660
672
  ? t('pipeline.builder.followUpEnableTooltip')
661
673
  : t('pipeline.builder.followUpDisableTooltip')
@@ -665,7 +677,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
665
677
  <!-- Test quality-control companion: audits the Tester's report for coverage
666
678
  before the greenlight/fixer decision and loops the Tester on gaps (Tester
667
679
  steps only). Enabled by default. -->
668
- <UButton
680
+ <IconButton
669
681
  v-if="isTesterKind(unit.kind)"
670
682
  :icon="
671
683
  pipelines.draftTesterQuality[unit.index]?.enabled === false
@@ -679,7 +691,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
679
691
  "
680
692
  variant="ghost"
681
693
  size="xs"
682
- :title="
694
+ :label="
683
695
  pipelines.draftTesterQuality[unit.index]?.enabled === false
684
696
  ? t('pipeline.builder.testerQualityEnableTooltip')
685
697
  : t('pipeline.builder.testerQualityDisableTooltip')
@@ -689,7 +701,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
689
701
  <!-- Auto-recommendation: the requirements reviewer pre-answers findings it
690
702
  judges answerable from universal practice / provided context, offering them
691
703
  as editable default answers (requirements-review steps only). On by default. -->
692
- <UButton
704
+ <IconButton
693
705
  v-if="unit.kind === 'requirements-review'"
694
706
  :icon="
695
707
  pipelines.draftAutoRecommendEnabled(unit.index)
@@ -701,7 +713,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
701
713
  "
702
714
  variant="ghost"
703
715
  size="xs"
704
- :title="
716
+ :label="
705
717
  pipelines.draftAutoRecommendEnabled(unit.index)
706
718
  ? t('pipeline.builder.autoRecommendDisableTooltip')
707
719
  : t('pipeline.builder.autoRecommendEnableTooltip')
@@ -712,7 +724,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
712
724
  preview a reviewer pokes at after the PR is open. Off by default, and the
713
725
  save boundary refuses a Deployer that neither reclaims nor declares this,
714
726
  so the tick is how an unreclaimed environment says it is deliberate. -->
715
- <UButton
727
+ <IconButton
716
728
  v-if="showRetainEnvironmentToggle(unit.kind, unit.index)"
717
729
  :icon="
718
730
  pipelines.draftRetainEnvironment(unit.index)
@@ -722,7 +734,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
722
734
  :color="pipelines.draftRetainEnvironment(unit.index) ? 'warning' : 'neutral'"
723
735
  variant="ghost"
724
736
  size="xs"
725
- :title="
737
+ :label="
726
738
  pipelines.draftRetainEnvironment(unit.index)
727
739
  ? t('pipeline.builder.retainEnvironmentClearTooltip')
728
740
  : t('pipeline.builder.retainEnvironmentSetTooltip')
@@ -731,43 +743,43 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
731
743
  />
732
744
  <!-- System prompt: replace what this agent kind ships with, for every run in
733
745
  this workspace, with the full revision history to switch back through. -->
734
- <UButton
746
+ <IconButton
735
747
  v-if="showPromptEditor(unit.kind)"
736
748
  icon="i-lucide-file-pen-line"
737
749
  :color="agentPrompts.isCustomized(unit.kind) ? 'warning' : 'neutral'"
738
750
  variant="ghost"
739
751
  size="xs"
740
- :title="
752
+ :label="
741
753
  agentPrompts.isCustomized(unit.kind)
742
754
  ? t('pipeline.builder.promptEditedTooltip')
743
755
  : t('pipeline.builder.promptEditTooltip')
744
756
  "
745
757
  @click="promptEditorKind = unit.kind"
746
758
  />
747
- <UButton
759
+ <IconButton
748
760
  icon="i-lucide-chevron-up"
749
761
  color="neutral"
750
762
  variant="ghost"
751
763
  size="xs"
752
- :title="t('pipeline.builder.moveUp')"
764
+ :label="t('pipeline.builder.moveUp')"
753
765
  :disabled="vi === 0"
754
766
  @click="pipelines.moveUnit(vi, vi - 1)"
755
767
  />
756
- <UButton
768
+ <IconButton
757
769
  icon="i-lucide-chevron-down"
758
770
  color="neutral"
759
771
  variant="ghost"
760
772
  size="xs"
761
- :title="t('pipeline.builder.moveDown')"
773
+ :label="t('pipeline.builder.moveDown')"
762
774
  :disabled="vi === pipelines.units.length - 1"
763
775
  @click="pipelines.moveUnit(vi, vi + 1)"
764
776
  />
765
- <UButton
777
+ <IconButton
766
778
  icon="i-lucide-x"
767
779
  color="error"
768
780
  variant="ghost"
769
781
  size="xs"
770
- :title="t('pipeline.builder.removeStep')"
782
+ :label="t('pipeline.builder.removeStep')"
771
783
  @click="removeUnit(unit)"
772
784
  />
773
785
  </div>
@@ -785,10 +797,10 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
785
797
  :disabled="!skillSelectItems.length"
786
798
  @update:model-value="pipelines.setDraftSkillId(unit.index, $event)"
787
799
  />
788
- <p v-if="!skillSelectItems.length" class="text-[10px] text-dimmed">
800
+ <p v-if="!skillSelectItems.length" class="text-3xs text-dimmed">
789
801
  {{ t('pipeline.builder.skillNoneAvailable') }}
790
802
  </p>
791
- <p v-else-if="skillMissing(unit.index)" class="text-[10px] text-app-warning-400">
803
+ <p v-else-if="skillMissing(unit.index)" class="text-3xs text-app-warning-400">
792
804
  {{ t('pipeline.builder.skillMissing') }}
793
805
  </p>
794
806
  </div>
@@ -801,7 +813,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
801
813
  v-if="showVariantPicker(unit.index, unit.kind)"
802
814
  class="ms-6 flex items-center gap-2"
803
815
  >
804
- <span class="text-[10px] text-dimmed">
816
+ <span class="text-3xs text-dimmed">
805
817
  {{ t('pipeline.builder.variantLabel') }}
806
818
  </span>
807
819
  <USelect
@@ -842,7 +854,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
842
854
  setting (itself an override of the deployment routing default), so it is
843
855
  advanced-only until a value is pinned; empty inherits. -->
844
856
  <div v-if="showOutputBudget(unit.index)" class="ms-6 flex items-center gap-2">
845
- <span class="text-[10px] text-dimmed">
857
+ <span class="text-3xs text-dimmed">
846
858
  {{ t('pipeline.outputBudget.stepLabel') }}
847
859
  </span>
848
860
  <OutputBudgetInput
@@ -872,7 +884,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
872
884
  </span>
873
885
  <!-- A companion is an agent kind with a prompt of its own, and this row is its
874
886
  only route to it — so the affordance belongs here too, not only on producers. -->
875
- <UButton
887
+ <IconButton
876
888
  v-if="showPromptEditor(pipelines.draft[unit.companionIndex]!)"
877
889
  icon="i-lucide-file-pen-line"
878
890
  :color="
@@ -882,7 +894,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
882
894
  "
883
895
  variant="ghost"
884
896
  size="xs"
885
- :title="
897
+ :label="
886
898
  agentPrompts.isCustomized(pipelines.draft[unit.companionIndex]!)
887
899
  ? t('pipeline.builder.promptEditedTooltip')
888
900
  : t('pipeline.builder.promptEditTooltip')
@@ -934,57 +946,55 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
934
946
  <UIcon name="i-lucide-layers" class="h-3.5 w-3.5 text-app-success-400" />
935
947
  <span class="text-toned">{{ t('pipeline.builder.consensusGroups') }}</span>
936
948
  </div>
937
- <p class="text-[11px] text-dimmed">
949
+ <p class="text-2xs text-dimmed">
938
950
  {{ t('pipeline.builder.consensusGroupsHint') }}
939
951
  </p>
940
952
  <div class="flex flex-wrap gap-1">
941
- <button
953
+ <UButton
954
+ color="neutral"
955
+ variant="ghost"
942
956
  v-for="group in consensusGroups.groups"
943
957
  :key="group.id"
944
- type="button"
945
- class="rounded border px-1.5 py-0.5 text-[11px]"
958
+ class="rounded-sm border px-1.5 py-0.5 text-2xs"
946
959
  :class="
947
960
  isGroupSelected(unit.index, group.id)
948
- ? 'border-app-success-600 bg-app-success-900/40 text-app-success-200'
949
- : 'border-muted bg-default text-muted hover:text-default'
961
+ ? 'border-app-success-600 bg-app-success-900/40 hover:bg-app-success-900/40 focus-visible:bg-app-success-900/40 disabled:bg-app-success-900/40 text-app-success-200'
962
+ : 'border-muted bg-default hover:bg-default focus-visible:bg-default disabled:bg-default text-muted hover:text-default'
950
963
  "
951
964
  :title="group.description"
952
965
  @click="pipelines.toggleDraftConsensusGroup(unit.index, group.id)"
953
966
  >
954
967
  {{ group.name }}
955
968
  <span class="ms-1 text-dimmed">{{ groupBarLabel(group.id) }}</span>
956
- </button>
969
+ </UButton>
957
970
  </div>
958
971
  </div>
959
972
 
960
- <div v-if="usesGroups(unit.index)" class="text-[11px] text-dimmed">
973
+ <div v-if="usesGroups(unit.index)" class="text-2xs text-dimmed">
961
974
  {{ t('pipeline.builder.consensusGroupsActive') }}
962
975
  </div>
963
976
 
964
977
  <template v-else>
965
978
  <div class="flex items-center gap-2">
966
979
  <label class="text-muted">{{ t('pipeline.builder.strategy') }}</label>
967
- <select
980
+ <USelect
968
981
  v-model="pipelines.draftConsensus[unit.index]!.strategy"
969
- class="rounded border border-muted bg-default px-1.5 py-0.5 text-app-100"
970
- >
971
- <option v-for="s in CONSENSUS_STRATEGIES" :key="s.value" :value="s.value">
972
- {{ s.label }}
973
- </option>
974
- </select>
982
+ :items="CONSENSUS_STRATEGIES"
983
+ size="xs"
984
+ />
975
985
  <label
976
986
  v-if="pipelines.draftConsensus[unit.index]!.strategy === 'debate'"
977
987
  class="ms-2 text-muted"
978
988
  >{{ t('pipeline.builder.rounds') }}</label
979
989
  >
980
- <input
990
+ <UInputNumber
981
991
  v-if="pipelines.draftConsensus[unit.index]!.strategy === 'debate'"
982
- v-model.number="pipelines.draftConsensus[unit.index]!.rounds"
983
- type="number"
984
- min="1"
985
- max="5"
992
+ v-model.optional="pipelines.draftConsensus[unit.index]!.rounds"
993
+ :min="1"
994
+ :max="5"
986
995
  placeholder="2"
987
- class="w-12 rounded border border-muted bg-default px-1.5 py-0.5 text-app-100"
996
+ size="xs"
997
+ class="w-24"
988
998
  />
989
999
  </div>
990
1000
 
@@ -995,23 +1005,25 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
995
1005
  :key="p.id"
996
1006
  class="flex items-center gap-1.5"
997
1007
  >
998
- <input
1008
+ <UInput
999
1009
  v-model="p.role"
1010
+ size="xs"
1011
+ class="w-28"
1000
1012
  :placeholder="t('pipeline.builder.rolePlaceholder')"
1001
- class="w-28 rounded border border-muted bg-default px-1.5 py-0.5 text-app-100"
1002
1013
  />
1003
- <input
1014
+ <UInput
1004
1015
  v-model="p.modelId"
1016
+ size="xs"
1017
+ class="flex-1"
1005
1018
  :placeholder="t('pipeline.builder.modelIdPlaceholder')"
1006
- class="flex-1 rounded border border-muted bg-default px-1.5 py-0.5 text-toned"
1007
1019
  />
1008
- <UButton
1020
+ <IconButton
1009
1021
  icon="i-lucide-x"
1010
1022
  color="error"
1011
1023
  variant="ghost"
1012
1024
  size="xs"
1013
1025
  :disabled="pipelines.draftConsensus[unit.index]!.participants.length <= 2"
1014
- :title="t('pipeline.builder.removeParticipant')"
1026
+ :label="t('pipeline.builder.removeParticipant')"
1015
1027
  @click="removeParticipant(unit.index, pIdx)"
1016
1028
  />
1017
1029
  </div>
@@ -1103,9 +1115,9 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1103
1115
  moved to the task card / inspector when the palettes were removed). -->
1104
1116
  <div v-if="pipelines.pipelines.length" class="flex flex-col lg:min-h-0 lg:overflow-hidden">
1105
1117
  <div class="mb-2 flex shrink-0 items-center justify-between gap-2">
1106
- <h3 class="text-xs font-semibold uppercase tracking-wide text-muted">
1118
+ <SectionLabel as="h3">
1107
1119
  {{ t('pipeline.builder.savedPipelines') }}
1108
- </h3>
1120
+ </SectionLabel>
1109
1121
  <UButton
1110
1122
  v-if="library.archivedInScope"
1111
1123
  :icon="showArchived ? 'i-lucide-archive-restore' : 'i-lucide-archive'"
@@ -1157,7 +1169,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1157
1169
  narrows and whose every change is saved. -->
1158
1170
  <div
1159
1171
  v-if="browseEveryPurpose || library.hiddenByPurpose"
1160
- class="mb-2 flex shrink-0 flex-wrap items-center gap-x-2 px-1 text-[10px] text-dimmed"
1172
+ class="mb-2 flex shrink-0 flex-wrap items-center gap-x-2 px-1 text-3xs text-dimmed"
1161
1173
  >
1162
1174
  <span>
1163
1175
  {{
@@ -1170,9 +1182,10 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1170
1182
  )
1171
1183
  }}
1172
1184
  </span>
1173
- <button
1174
- type="button"
1175
- class="underline underline-offset-2 hover:text-toned"
1185
+ <UButton
1186
+ color="neutral"
1187
+ variant="link"
1188
+ class="p-0 text-3xs underline underline-offset-2 hover:text-toned"
1176
1189
  data-testid="pipeline-library-purpose-toggle"
1177
1190
  @click="browseEveryPurpose = !browseEveryPurpose"
1178
1191
  >
@@ -1181,7 +1194,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1181
1194
  ? t('pipeline.builder.narrowToDraftPurpose')
1182
1195
  : t('pipeline.builder.listEveryPurpose')
1183
1196
  }}
1184
- </button>
1197
+ </UButton>
1185
1198
  </div>
1186
1199
 
1187
1200
  <ul class="flex-1 space-y-1.5 pe-1 lg:min-h-0 lg:overflow-y-auto">
@@ -1192,9 +1205,10 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1192
1205
  :class="{ 'opacity-60': p.archived }"
1193
1206
  >
1194
1207
  <div class="flex items-center gap-2 px-2 py-1.5">
1195
- <button
1196
- type="button"
1197
- class="flex min-w-0 flex-1 items-center gap-2 text-start"
1208
+ <UButton
1209
+ color="neutral"
1210
+ variant="ghost"
1211
+ class="flex min-w-0 flex-1 items-center gap-2 p-0 text-start hover:bg-transparent"
1198
1212
  @click="toggleSaved(p.id)"
1199
1213
  >
1200
1214
  <UIcon
@@ -1249,7 +1263,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1249
1263
  >
1250
1264
  {{ t('pipeline.builder.scopeDefault.unattended') }}
1251
1265
  </UBadge>
1252
- <span class="shrink-0 text-[10px] text-dimmed">
1266
+ <span class="shrink-0 text-3xs text-dimmed">
1253
1267
  {{
1254
1268
  t(
1255
1269
  'pipeline.builder.stepCount',
@@ -1258,7 +1272,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1258
1272
  )
1259
1273
  }}
1260
1274
  </span>
1261
- </button>
1275
+ </UButton>
1262
1276
  <div
1263
1277
  class="flex shrink-0 items-center opacity-0 transition group-hover:opacity-100"
1264
1278
  >
@@ -1269,24 +1283,24 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1269
1283
  ARCHIVING a row that still holds one: a hidden row never holds a default,
1270
1284
  so there is never one here to release. -->
1271
1285
  <template v-if="uiMode.isAdvanced && !p.archived && !p.internal">
1272
- <UButton
1286
+ <IconButton
1273
1287
  :icon="p.isDefault ? 'i-lucide-star' : 'i-lucide-star-off'"
1274
1288
  :color="p.isDefault ? 'primary' : 'neutral'"
1275
1289
  variant="ghost"
1276
1290
  size="xs"
1277
- :title="
1291
+ :label="
1278
1292
  p.isDefault
1279
1293
  ? t('pipeline.builder.scopeDefault.releaseInteractive')
1280
1294
  : t('pipeline.builder.scopeDefault.claimInteractive')
1281
1295
  "
1282
1296
  @click="toggleDefault(p, 'interactive')"
1283
1297
  />
1284
- <UButton
1298
+ <IconButton
1285
1299
  :icon="p.isUnattendedDefault ? 'i-lucide-bot' : 'i-lucide-bot-off'"
1286
1300
  :color="p.isUnattendedDefault ? 'info' : 'neutral'"
1287
1301
  variant="ghost"
1288
1302
  size="xs"
1289
- :title="
1303
+ :label="
1290
1304
  p.isUnattendedDefault
1291
1305
  ? t('pipeline.builder.scopeDefault.releaseUnattended')
1292
1306
  : t('pipeline.builder.scopeDefault.claimUnattended')
@@ -1296,47 +1310,47 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1296
1310
  </template>
1297
1311
  <!-- Archive/unarchive: organize the library without deleting. Works on
1298
1312
  built-ins too (view metadata, not structure). -->
1299
- <UButton
1313
+ <IconButton
1300
1314
  :icon="p.archived ? 'i-lucide-archive-restore' : 'i-lucide-archive'"
1301
1315
  color="neutral"
1302
1316
  variant="ghost"
1303
1317
  size="xs"
1304
- :title="
1318
+ :label="
1305
1319
  p.archived ? t('pipeline.builder.unarchive') : t('pipeline.builder.archive')
1306
1320
  "
1307
1321
  @click="toggleArchive(p)"
1308
1322
  />
1309
1323
  <!-- Clone is available on every pipeline — it's how a read-only
1310
1324
  built-in template becomes an editable copy. -->
1311
- <UButton
1325
+ <IconButton
1312
1326
  icon="i-lucide-copy"
1313
1327
  color="neutral"
1314
1328
  variant="ghost"
1315
1329
  size="xs"
1316
- :title="
1330
+ :label="
1317
1331
  p.builtin ? t('pipeline.builder.cloneDefault') : t('pipeline.builder.clone')
1318
1332
  "
1319
1333
  @click="clone(p)"
1320
1334
  />
1321
1335
  <!-- Built-in templates are read-only; only custom pipelines edit in place. -->
1322
- <UButton
1336
+ <IconButton
1323
1337
  v-if="!p.builtin"
1324
1338
  icon="i-lucide-pencil"
1325
1339
  color="neutral"
1326
1340
  variant="ghost"
1327
1341
  size="xs"
1328
- :title="t('pipeline.builder.edit')"
1342
+ :label="t('pipeline.builder.edit')"
1329
1343
  @click="edit(p)"
1330
1344
  />
1331
1345
  <!-- Built-in templates are read-only — they can be cloned but not
1332
1346
  deleted (the backend rejects it too); only custom ones delete. -->
1333
- <UButton
1347
+ <IconButton
1334
1348
  v-if="!p.builtin"
1335
1349
  icon="i-lucide-trash-2"
1336
1350
  color="neutral"
1337
1351
  variant="ghost"
1338
1352
  size="xs"
1339
- :title="t('pipeline.builder.delete')"
1353
+ :label="t('pipeline.builder.delete')"
1340
1354
  @click="removePipeline(p)"
1341
1355
  />
1342
1356
  </div>
@@ -1356,7 +1370,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1356
1370
  p.enabled?.[i] === false ? t('pipeline.builder.disabledStepTooltip') : undefined
1357
1371
  "
1358
1372
  >
1359
- <span class="w-4 shrink-0 text-center text-[10px] text-dimmed">{{ i + 1 }}</span>
1373
+ <span class="w-4 shrink-0 text-center text-3xs text-dimmed">{{ i + 1 }}</span>
1360
1374
  <AgentKindIcon :kind="k" show-label />
1361
1375
  <!-- A step that does not run on every task says so HERE, in the library, because
1362
1376
  this list is what a reader compares two pipelines by: a preset whose testers
@@ -1400,9 +1414,9 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1400
1414
  <template #body>
1401
1415
  <div class="space-y-3">
1402
1416
  <div>
1403
- <label class="mb-1 block text-[11px] font-semibold uppercase tracking-wide text-muted">
1417
+ <SectionLabel as="label" class="mb-1 block">
1404
1418
  {{ t('pipeline.builder.addAgentModal.name') }}
1405
- </label>
1419
+ </SectionLabel>
1406
1420
  <UInput
1407
1421
  v-model="newAgentName"
1408
1422
  :placeholder="t('pipeline.builder.addAgentModal.namePlaceholder')"
@@ -1411,9 +1425,9 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1411
1425
  />
1412
1426
  </div>
1413
1427
  <div>
1414
- <label class="mb-1 block text-[11px] font-semibold uppercase tracking-wide text-muted">
1428
+ <SectionLabel as="label" class="mb-1 block">
1415
1429
  {{ t('pipeline.builder.addAgentModal.description') }}
1416
- </label>
1430
+ </SectionLabel>
1417
1431
  <UTextarea
1418
1432
  v-model="newAgentDesc"
1419
1433
  :rows="2"