@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
@@ -29,6 +29,8 @@ import {
29
29
  } from '~/utils/pipelineRender'
30
30
  import InputGateNotice from '~/components/inputGate/InputGateNotice.vue'
31
31
  import RunDetailLoadState from '~/components/panels/RunDetailLoadState.vue'
32
+ import SectionLabel from '~/components/common/SectionLabel.vue'
33
+ import IconButton from '~/components/common/IconButton.vue'
32
34
 
33
35
  // Detail overlay for a single pipeline step. Opened by clicking an agent in the
34
36
  // inspector list (TaskExecution) or the focus-view pipeline (PipelineProgress) via
@@ -402,13 +404,15 @@ async function copyOutput() {
402
404
  class="hidden w-72 shrink-0 flex-col border-e border-default bg-default/60 md:flex"
403
405
  >
404
406
  <div class="border-b border-default px-4 py-3">
405
- <div class="text-[11px] font-semibold uppercase tracking-wide text-dimmed">
407
+ <SectionLabel>
406
408
  {{ t('panels.stepDetail.contents') }}
407
- </div>
409
+ </SectionLabel>
408
410
  </div>
409
411
  <nav class="flex-1 space-y-0.5 overflow-auto px-2 py-3">
410
- <button
411
- class="block w-full truncate rounded-md px-2 py-1 text-start text-[13px] transition"
412
+ <UButton
413
+ color="neutral"
414
+ variant="ghost"
415
+ class="block w-full truncate rounded-md px-2 py-1 text-start text-sm transition"
412
416
  :class="
413
417
  activeId === 'step-details'
414
418
  ? 'bg-primary/15 font-medium text-primary'
@@ -417,11 +421,13 @@ async function copyOutput() {
417
421
  @click="goTo('step-details')"
418
422
  >
419
423
  {{ t('panels.stepDetail.details') }}
420
- </button>
421
- <button
424
+ </UButton>
425
+ <UButton
426
+ color="neutral"
427
+ variant="ghost"
422
428
  v-for="s in tocSections"
423
429
  :key="s.id"
424
- class="block w-full truncate rounded-md px-2 py-1 text-start text-[13px] transition"
430
+ class="block w-full truncate rounded-md px-2 py-1 text-start text-sm transition"
425
431
  :class="
426
432
  activeId === s.id
427
433
  ? 'bg-primary/15 font-medium text-primary'
@@ -432,7 +438,7 @@ async function copyOutput() {
432
438
  @click="goTo(s.id)"
433
439
  >
434
440
  {{ s.title }}
435
- </button>
441
+ </UButton>
436
442
  </nav>
437
443
  </aside>
438
444
 
@@ -470,24 +476,24 @@ async function copyOutput() {
470
476
  <UIcon name="i-lucide-alert-triangle" class="me-1 h-3 w-3" />
471
477
  {{ t('panels.stepDetail.decisionRequired') }}
472
478
  </UBadge>
473
- <UButton
479
+ <IconButton
474
480
  v-if="outline.sections.length"
475
481
  :icon="allCollapsed ? 'i-lucide-unfold-vertical' : 'i-lucide-fold-vertical'"
476
482
  color="neutral"
477
483
  variant="ghost"
478
484
  size="sm"
479
- :title="
485
+ :label="
480
486
  allCollapsed ? t('panels.stepDetail.expandAll') : t('panels.stepDetail.collapseAll')
481
487
  "
482
488
  @click="setAll(!allCollapsed)"
483
489
  />
484
- <UButton
490
+ <IconButton
485
491
  v-if="hasOutput"
486
492
  icon="i-lucide-copy"
487
493
  color="neutral"
488
494
  variant="ghost"
489
495
  size="sm"
490
- :title="t('panels.stepDetail.copyRawOutput')"
496
+ :label="t('panels.stepDetail.copyRawOutput')"
491
497
  @click="copyOutput"
492
498
  />
493
499
  <!-- Restart the pipeline from this step (shared two-click confirm; resetting
@@ -499,12 +505,12 @@ async function copyOutput() {
499
505
  :step-index="ctx?.stepIndex ?? null"
500
506
  @restarted="close"
501
507
  />
502
- <UButton
508
+ <IconButton
503
509
  icon="i-lucide-x"
504
510
  color="neutral"
505
511
  variant="ghost"
506
512
  size="sm"
507
- :title="t('panels.stepDetail.closeEsc')"
513
+ :label="t('panels.stepDetail.closeEsc')"
508
514
  @click="close"
509
515
  />
510
516
  </div>
@@ -603,7 +609,7 @@ async function copyOutput() {
603
609
  data-testid="dedicated-park-redirect"
604
610
  :data-park="dedicatedPark"
605
611
  >
606
- <p class="text-[13px] leading-relaxed text-app-warning-200/90">
612
+ <p class="text-sm leading-relaxed text-app-warning-200/90">
607
613
  {{ t(parkPresentation.noticeKey) }}
608
614
  </p>
609
615
  <UButton
@@ -640,7 +646,7 @@ async function copyOutput() {
640
646
  <li
641
647
  v-for="(note, i) in runNotes"
642
648
  :key="i"
643
- class="flex items-start gap-1.5 text-[11px] leading-snug text-app-warning-300/80"
649
+ class="flex items-start gap-1.5 text-2xs leading-snug text-app-warning-300/80"
644
650
  >
645
651
  <UIcon name="i-lucide-info" class="mt-0.5 h-3.5 w-3.5 shrink-0" />
646
652
  <span>{{ note }}</span>
@@ -755,7 +761,7 @@ async function copyOutput() {
755
761
  <!-- edit-then-approve: a direct editor over the raw conclusions; the
756
762
  edits become the approved proposal that flows to the next step -->
757
763
  <section v-if="editing" class="scroll-mt-4">
758
- <div class="mb-2 flex items-center gap-1.5 text-[11px] text-app-warning-400">
764
+ <div class="mb-2 flex items-center gap-1.5 text-2xs text-app-warning-400">
759
765
  <UIcon name="i-lucide-pencil" class="h-3.5 w-3.5" />
760
766
  <span class="font-semibold uppercase tracking-wide">{{
761
767
  t('panels.stepDetail.editingConclusions')
@@ -767,7 +773,7 @@ async function copyOutput() {
767
773
  autoresize
768
774
  size="sm"
769
775
  class="w-full"
770
- :ui="{ base: 'font-mono text-[12px] leading-relaxed' }"
776
+ :ui="{ base: 'font-mono text-xs leading-relaxed' }"
771
777
  :placeholder="t('panels.stepDetail.editConclusionsPlaceholder')"
772
778
  />
773
779
  </section>
@@ -781,9 +787,11 @@ async function copyOutput() {
781
787
  :ref="(el) => (sectionEls[s.id] = el as HTMLElement | null)"
782
788
  class="scroll-mt-4"
783
789
  >
784
- <button
790
+ <UButton
791
+ color="neutral"
792
+ variant="ghost"
785
793
  v-if="s.depth > 0"
786
- class="group flex w-full items-center gap-2 rounded-md py-1 text-start transition hover:text-highlighted"
794
+ class="group flex w-full items-center gap-2 rounded-md px-0 py-1 text-start transition hover:bg-transparent hover:text-highlighted"
787
795
  @click="toggle(s.id)"
788
796
  >
789
797
  <UIcon
@@ -796,11 +804,11 @@ async function copyOutput() {
796
804
  :class="s.depth <= 1 ? 'text-lg' : s.depth === 2 ? 'text-base' : 'text-sm'"
797
805
  v-html="s.titleHtml"
798
806
  />
799
- </button>
807
+ </UButton>
800
808
  <!-- eslint-disable-next-line vue/no-v-html -->
801
809
  <div
802
810
  v-show="!collapsed[s.id]"
803
- class="reader-prose mt-1 text-[13px] leading-relaxed text-toned"
811
+ class="reader-prose mt-1 text-sm leading-relaxed text-toned"
804
812
  :class="[
805
813
  s.depth > 0 ? 'ps-6' : '',
806
814
  genericApprovalPending && !editing ? 'review-mode' : '',
@@ -829,25 +837,21 @@ async function copyOutput() {
829
837
  class="absolute inset-x-0 bottom-0 z-10 flex max-h-[70dvh] flex-col rounded-t-2xl border-t border-muted bg-default/95 shadow-2xl backdrop-blur lg:static lg:inset-auto lg:z-auto lg:max-h-none lg:w-96 lg:shrink-0 lg:rounded-none lg:border-s lg:border-t-0 lg:border-default lg:bg-default/60 lg:shadow-none lg:backdrop-blur-none"
830
838
  >
831
839
  <div class="border-b border-default px-4 py-3">
832
- <div class="text-[11px] font-semibold uppercase tracking-wide text-app-warning-400">
840
+ <div class="text-2xs font-semibold uppercase tracking-wide text-app-warning-400">
833
841
  {{
834
842
  editing
835
843
  ? t('panels.stepDetail.approveWithCorrections')
836
844
  : t('panels.stepDetail.reviewAndApprove')
837
845
  }}
838
846
  </div>
839
- <p class="mt-1 text-[12px] text-muted">
847
+ <p class="mt-1 text-xs text-muted">
840
848
  {{ editing ? t('panels.stepDetail.editHint') : t('panels.stepDetail.reviewHint') }}
841
849
  </p>
842
850
  <!-- The gate's configured POLICY, when it has one. Both lines exist because an
843
851
  approve on such a gate legitimately may not advance the run: without the tally, a
844
852
  correctly-recorded approval is indistinguishable from a call that failed, and
845
853
  without the refusal a person would press a button the server answers 403. -->
846
- <p
847
- v-if="gateQuorum"
848
- class="mt-1 text-[12px] text-app-warning-300/90"
849
- data-testid="gate-quorum"
850
- >
854
+ <p v-if="gateQuorum" class="mt-1 text-xs text-app-warning-300/90" data-testid="gate-quorum">
851
855
  {{
852
856
  t('panels.stepDetail.quorumProgress', {
853
857
  recorded: gateQuorum.recorded,
@@ -856,7 +860,7 @@ async function copyOutput() {
856
860
  }}
857
861
  <span v-if="viewerHasApproved">{{ t('panels.stepDetail.quorumYours') }}</span>
858
862
  </p>
859
- <p v-if="gateRefusal" class="mt-1 text-[12px] text-muted" data-testid="gate-not-approver">
863
+ <p v-if="gateRefusal" class="mt-1 text-xs text-muted" data-testid="gate-not-approver">
860
864
  {{ t(GATE_REFUSAL_KEYS[gateRefusal]) }}
861
865
  </p>
862
866
  </div>
@@ -864,7 +868,7 @@ async function copyOutput() {
864
868
  <div class="flex-1 space-y-3 overflow-auto overscroll-contain px-4 py-3">
865
869
  <p
866
870
  v-if="editing"
867
- class="rounded-lg border border-app-warning-500/30 bg-app-warning-500/5 p-3 text-[12px] leading-relaxed text-app-warning-200/90"
871
+ class="rounded-lg border border-app-warning-500/30 bg-app-warning-500/5 p-3 text-xs leading-relaxed text-app-warning-200/90"
868
872
  >
869
873
  {{ t('panels.stepDetail.editingNotice') }}
870
874
  </p>
@@ -875,11 +879,11 @@ async function copyOutput() {
875
879
  data-testid="step-review-composer"
876
880
  class="rounded-lg border border-primary/40 bg-primary/5 p-3"
877
881
  >
878
- <div class="mb-1 text-[10px] uppercase tracking-wide text-primary">
882
+ <div class="mb-1 text-3xs uppercase tracking-wide text-primary">
879
883
  {{ t('panels.stepDetail.commentingOn') }}
880
884
  </div>
881
885
  <pre
882
- class="mb-2 max-h-24 overflow-auto whitespace-pre-wrap rounded bg-app-950/60 p-2 text-[11px] text-toned"
886
+ class="mb-2 max-h-24 overflow-auto whitespace-pre-wrap rounded-sm bg-app-950/60 p-2 text-2xs text-toned"
883
887
  >{{ draftTarget.quotedSource }}</pre>
884
888
  <UTextarea
885
889
  v-model="draftBody"
@@ -914,27 +918,31 @@ async function copyOutput() {
914
918
  class="rounded-lg border border-default bg-default/50 p-3"
915
919
  >
916
920
  <div class="mb-1 flex items-start justify-between gap-2">
917
- <div class="text-[10px] uppercase tracking-wide text-dimmed">
921
+ <SectionLabel>
918
922
  {{ t('panels.stepDetail.commentN', { number: idx + 1 }) }}
919
- </div>
920
- <button
921
- class="text-dimmed transition hover:text-app-error-400"
922
- :title="t('panels.stepDetail.removeComment')"
923
+ </SectionLabel>
924
+ <IconButton
925
+ color="neutral"
926
+ variant="ghost"
927
+ icon="i-lucide-x"
928
+ :label="t('panels.stepDetail.removeComment')"
929
+ :ui="{
930
+ base: 'p-0 text-dimmed transition hover:bg-transparent hover:text-app-error-400',
931
+ leadingIcon: 'h-3.5 w-3.5',
932
+ }"
923
933
  @click="removeComment(idx)"
924
- >
925
- <UIcon name="i-lucide-x" class="h-3.5 w-3.5" />
926
- </button>
934
+ />
927
935
  </div>
928
936
  <pre
929
- class="mb-1 max-h-20 overflow-auto whitespace-pre-wrap rounded bg-app-950/50 p-1.5 text-[10px] text-muted"
937
+ class="mb-1 max-h-20 overflow-auto whitespace-pre-wrap rounded-sm bg-app-950/50 p-1.5 text-3xs text-muted"
930
938
  >{{ c.quotedSource }}</pre>
931
- <p class="text-[12px] text-default">{{ c.body }}</p>
939
+ <p class="text-xs text-default">{{ c.body }}</p>
932
940
  </div>
933
941
 
934
942
  <div>
935
- <label class="mb-1 block text-[11px] font-semibold uppercase tracking-wide text-muted">
943
+ <SectionLabel as="label" class="mb-1 block">
936
944
  {{ t('panels.stepDetail.overallFeedback') }}
937
- </label>
945
+ </SectionLabel>
938
946
  <UTextarea
939
947
  v-model="feedback"
940
948
  data-testid="step-review-feedback"
@@ -1005,14 +1013,14 @@ async function copyOutput() {
1005
1013
  </UButton>
1006
1014
  <p
1007
1015
  v-else-if="!proposalEditable"
1008
- class="text-[10px] text-dimmed"
1016
+ class="text-3xs text-dimmed"
1009
1017
  data-testid="step-rendered-output-note"
1010
1018
  >
1011
1019
  {{ t('panels.stepDetail.renderedOutputNote') }}
1012
1020
  </p>
1013
1021
  <!-- Withheld only until the quorum is one approval away, so it says so rather than
1014
1022
  leaving a reviewer to wonder where the affordance went. -->
1015
- <p v-else class="text-[10px] text-dimmed" data-testid="step-quorum-edit-locked">
1023
+ <p v-else class="text-3xs text-dimmed" data-testid="step-quorum-edit-locked">
1016
1024
  {{ t('panels.stepDetail.quorumEditLocked') }}
1017
1025
  </p>
1018
1026
 
@@ -1021,7 +1029,7 @@ async function copyOutput() {
1021
1029
  v-if="rejectArmed"
1022
1030
  class="rounded-lg border border-app-error-500/40 bg-app-error-500/5 p-2.5"
1023
1031
  >
1024
- <p class="mb-2 text-[11px] text-app-error-200">
1032
+ <p class="mb-2 text-2xs text-app-error-200">
1025
1033
  {{ t('panels.stepDetail.rejectConfirmPrompt') }}
1026
1034
  </p>
1027
1035
  <div class="flex gap-2">
@@ -1073,7 +1081,7 @@ async function copyOutput() {
1073
1081
  {{ t('panels.stepDetail.reject') }}
1074
1082
  </UButton>
1075
1083
  </div>
1076
- <p class="text-[10px] text-dimmed">
1084
+ <p class="text-3xs text-dimmed">
1077
1085
  {{ t('panels.stepDetail.requestChangesHint') }}
1078
1086
  </p>
1079
1087
  </div>
@@ -23,11 +23,11 @@ function formatClock(ms: number | null | undefined, fmt: 'short' | 'long'): stri
23
23
  <template>
24
24
  <div class="flex items-center gap-2">
25
25
  <UIcon v-if="icon" :name="icon" class="h-3.5 w-3.5 shrink-0" :class="iconClass" />
26
- <span class="text-[13px] font-medium text-default">{{ label }}</span>
26
+ <span class="text-sm font-medium text-default">{{ label }}</span>
27
27
  <UBadge :color="outcome === 'failed' ? 'error' : 'neutral'" variant="subtle" size="sm">{{
28
28
  outcomeLabel
29
29
  }}</UBadge>
30
- <span v-if="formatClock(at, dateFormat ?? 'short')" class="ms-auto text-[11px] text-dimmed">{{
30
+ <span v-if="formatClock(at, dateFormat ?? 'short')" class="ms-auto text-2xs text-dimmed">{{
31
31
  formatClock(at, dateFormat ?? 'short')
32
32
  }}</span>
33
33
  </div>
@@ -93,7 +93,7 @@ async function choose(option: string) {
93
93
  {{ opt }}
94
94
  </UButton>
95
95
  </div>
96
- <p class="text-[11px] text-dimmed">
96
+ <p class="text-2xs text-dimmed">
97
97
  {{ t('panels.decision.visualizationHint') }}
98
98
  </p>
99
99
  </div>
@@ -11,6 +11,7 @@ import StepRunMeta from '~/components/panels/StepRunMeta.vue'
11
11
  import ResultWindowShell from '~/components/panels/ResultWindowShell.vue'
12
12
  import MarkdownProse from '~/components/common/MarkdownProse.vue'
13
13
  import CopyButton from '~/components/common/CopyButton.vue'
14
+ import SectionLabel from '~/components/common/SectionLabel.vue'
14
15
 
15
16
  const board = useBoardStore()
16
17
  const execution = useExecutionStore()
@@ -71,18 +72,18 @@ const customJson = computed<string | null>(() => {
71
72
  <MarkdownProse
72
73
  v-if="step?.output"
73
74
  :text="step.output"
74
- class="mb-4 text-[13px] leading-relaxed text-toned"
75
+ class="mb-4 text-sm leading-relaxed text-toned"
75
76
  />
76
77
 
77
78
  <template v-if="customJson">
78
79
  <div class="mb-2 flex items-center gap-2">
79
- <h3 class="text-[11px] font-semibold uppercase tracking-wide text-dimmed">
80
+ <SectionLabel as="h3">
80
81
  {{ t('panels.structuredResult.structuredOutput') }}
81
- </h3>
82
+ </SectionLabel>
82
83
  <CopyButton :text="customJson" class="-my-1" />
83
84
  </div>
84
85
  <pre
85
- class="overflow-x-auto rounded-lg border border-default bg-app-950/60 p-3 text-[12px] leading-relaxed text-default"
86
+ class="overflow-x-auto rounded-lg border border-default bg-app-950/60 p-3 text-xs leading-relaxed text-default"
86
87
  ><code>{{ customJson }}</code></pre>
87
88
  </template>
88
89
 
@@ -92,7 +93,7 @@ const customJson = computed<string | null>(() => {
92
93
  >
93
94
  <UIcon name="i-lucide-braces" class="h-8 w-8 opacity-40" />
94
95
  <p class="text-sm">{{ t('panels.structuredResult.noResult') }}</p>
95
- <p class="max-w-sm text-[11px] text-dimmed">
96
+ <p class="max-w-sm text-2xs text-dimmed">
96
97
  {{ t('panels.structuredResult.noResultHint') }}
97
98
  </p>
98
99
  </div>
@@ -10,6 +10,7 @@ import AgentStopButton from '~/components/board/AgentStopButton.vue'
10
10
  import BootstrapRunSteps from '~/components/bootstrap/BootstrapRunSteps.vue'
11
11
  import { BLUEPRINT_AGENT_KIND } from '@cat-factory/contracts'
12
12
  import { VCS_PROVIDER_ICONS } from '~/utils/vcs'
13
+ import SectionLabel from '~/components/common/SectionLabel.vue'
13
14
 
14
15
  const board = useBoardStore()
15
16
  const pipelines = usePipelinesStore()
@@ -368,7 +369,10 @@ const showOriginalDescription = ref(false)
368
369
  <UBadge :color="statusMeta.chip" variant="subtle" size="sm">
369
370
  {{ statusLabel }}
370
371
  </UBadge>
371
- <span class="text-[10px] uppercase tracking-wide text-dimmed">{{ level }}</span>
372
+ <!-- The block's LEVEL, beside its status chip: a category this block is in, not a
373
+ heading over what follows, so it keeps its own classes rather than adopting the
374
+ eyebrow recipe (`common/SectionLabel.vue`). -->
375
+ <span class="text-3xs uppercase tracking-wide text-dimmed">{{ level }}</span>
372
376
  </div>
373
377
  </div>
374
378
  </div>
@@ -403,16 +407,16 @@ const showOriginalDescription = ref(false)
403
407
  <template v-if="frozenByRework">
404
408
  <div class="rounded-lg border border-app-success-900/60 bg-app-success-950/20 p-3">
405
409
  <div
406
- class="mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-app-success-400"
410
+ class="mb-1.5 flex items-center gap-1.5 text-2xs font-semibold uppercase tracking-wide text-app-success-400"
407
411
  >
408
412
  <UIcon name="i-lucide-file-check-2" class="h-3.5 w-3.5" />
409
413
  {{ t('panels.inspector.reworkedRequirements') }}
410
414
  </div>
411
- <p class="line-clamp-5 whitespace-pre-line text-[13px] leading-relaxed text-toned">
415
+ <p class="line-clamp-5 whitespace-pre-line text-sm leading-relaxed text-toned">
412
416
  {{ reqReworkedText }}
413
417
  </p>
414
418
  <div class="mt-2 flex items-center justify-between gap-2">
415
- <p class="text-[11px] text-dimmed">
419
+ <p class="text-2xs text-dimmed">
416
420
  {{ t('panels.inspector.agentStepsUseDocument') }}
417
421
  </p>
418
422
  <UButton
@@ -464,23 +468,21 @@ const showOriginalDescription = ref(false)
464
468
  @change="saveDescription"
465
469
  @blur="saveDescription"
466
470
  />
467
- <p v-if="isTask && !editable" class="flex items-center gap-1 text-[11px] text-dimmed">
471
+ <p v-if="isTask && !editable" class="flex items-center gap-1 text-2xs text-dimmed">
468
472
  <UIcon name="i-lucide-lock" class="h-3 w-3" />
469
473
  {{ t('panels.inspector.taskStartedLocked') }}
470
474
  </p>
471
475
 
472
476
  <!-- prior incorporated requirements kept as a base after a review-driven reset -->
473
477
  <div v-if="reqHasPriorDoc" class="rounded-lg border border-muted bg-elevated/40 p-3">
474
- <div
475
- class="mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted"
476
- >
478
+ <SectionLabel class="mb-1.5 flex items-center gap-1.5">
477
479
  <UIcon name="i-lucide-history" class="h-3.5 w-3.5" />
478
480
  {{ t('panels.inspector.lastIncorporatedRequirements') }}
479
- </div>
480
- <p class="line-clamp-5 whitespace-pre-line text-[13px] leading-relaxed text-toned">
481
+ </SectionLabel>
482
+ <p class="line-clamp-5 whitespace-pre-line text-sm leading-relaxed text-toned">
481
483
  {{ reqReworkedText }}
482
484
  </p>
483
- <p class="mt-2 text-[11px] text-dimmed">
485
+ <p class="mt-2 text-2xs text-dimmed">
484
486
  {{ t('panels.inspector.priorDocHint') }}
485
487
  </p>
486
488
  </div>
@@ -586,7 +588,7 @@ const showOriginalDescription = ref(false)
586
588
  >
587
589
  {{ t('panels.inspector.mapService') }}
588
590
  </UButton>
589
- <p v-if="isFrame && !serviceRepo" class="text-[11px] text-dimmed">
591
+ <p v-if="isFrame && !serviceRepo" class="text-2xs text-dimmed">
590
592
  {{ t('panels.inspector.mapServiceNoRepo') }}
591
593
  </p>
592
594
 
@@ -613,7 +615,7 @@ const showOriginalDescription = ref(false)
613
615
  on a disabled button doesn't fire hover events. -->
614
616
  <p
615
617
  v-if="isTask && runBlockedReason"
616
- class="flex items-start gap-1.5 text-[11px] text-app-warning-300/90"
618
+ class="flex items-start gap-1.5 text-2xs text-app-warning-300/90"
617
619
  data-testid="run-blocked-reason"
618
620
  >
619
621
  <UIcon name="i-lucide-lock" class="mt-px h-3 w-3 shrink-0" />
@@ -11,6 +11,7 @@ import type { ChangeClass, MergeAxis, MergeDecision, WorkspaceRole } from '@cat-
11
11
  import StepRunMeta from '~/components/panels/StepRunMeta.vue'
12
12
  import ResultWindowShell from '~/components/panels/ResultWindowShell.vue'
13
13
  import MarkdownProse from '~/components/common/MarkdownProse.vue'
14
+ import SectionLabel from '~/components/common/SectionLabel.vue'
14
15
 
15
16
  const board = useBoardStore()
16
17
  const execution = useExecutionStore()
@@ -217,15 +218,15 @@ const reasonText = computed(() => {
217
218
  {{ changeClassLabel }}
218
219
  </UBadge>
219
220
  </div>
220
- <p class="mt-0.5 text-[13px] leading-relaxed text-toned">{{ reasonText }}</p>
221
+ <p class="mt-0.5 text-sm leading-relaxed text-toned">{{ reasonText }}</p>
221
222
  </div>
222
223
  </div>
223
224
 
224
225
  <!-- Scores vs the resolved preset's ceilings. -->
225
226
  <template v-if="axes.length">
226
- <h3 class="mb-2 text-[11px] font-semibold uppercase tracking-wide text-dimmed">
227
+ <SectionLabel as="h3" class="mb-2">
227
228
  {{ t('panels.mergerResult.scores') }}
228
- </h3>
229
+ </SectionLabel>
229
230
  <div class="space-y-2 rounded-lg border border-default bg-app-950/40 p-3">
230
231
  <div v-for="axis in axes" :key="axis.key" class="flex items-center gap-2">
231
232
  <span class="w-20 shrink-0 text-xs text-muted">{{ axis.label }}</span>
@@ -242,7 +243,7 @@ const reasonText = computed(() => {
242
243
  >
243
244
  {{ n(axis.score, { key: 'percent' }) }}
244
245
  </span>
245
- <span class="w-24 shrink-0 text-end text-[10px] tabular-nums text-dimmed">
246
+ <span class="w-24 shrink-0 text-end text-3xs tabular-nums text-dimmed">
246
247
  {{
247
248
  t('panels.mergerResult.ceiling', {
248
249
  value: n(axis.ceiling, { key: 'percent' }),
@@ -255,15 +256,15 @@ const reasonText = computed(() => {
255
256
 
256
257
  <!-- The agent's prose justification. -->
257
258
  <template v-if="decision.assessment?.rationale">
258
- <h3 class="mb-2 mt-4 text-[11px] font-semibold uppercase tracking-wide text-dimmed">
259
+ <SectionLabel as="h3" class="mb-2 mt-4">
259
260
  {{ t('panels.mergerResult.rationale') }}
260
- </h3>
261
+ </SectionLabel>
261
262
  <MarkdownProse
262
263
  :text="decision.assessment.rationale"
263
- class="text-[13px] leading-relaxed text-toned"
264
+ class="text-sm leading-relaxed text-toned"
264
265
  />
265
266
  </template>
266
- <p v-else class="text-[13px] italic leading-relaxed text-dimmed">
267
+ <p v-else class="text-sm italic leading-relaxed text-dimmed">
267
268
  {{ t('panels.mergerResult.noAssessment') }}
268
269
  </p>
269
270
  </template>
@@ -272,7 +273,7 @@ const reasonText = computed(() => {
272
273
  <MarkdownProse
273
274
  v-else-if="step?.output"
274
275
  :text="step.output"
275
- class="text-[13px] leading-relaxed text-toned"
276
+ class="text-sm leading-relaxed text-toned"
276
277
  />
277
278
  <div
278
279
  v-else