@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
@@ -7,6 +7,7 @@
7
7
  // serviceFragmentDefaults store (the backend replaces the whole list on each change).
8
8
  import { onMounted, ref } from 'vue'
9
9
  import { buildFragmentPickerGroups } from '~/utils/fragmentPicker'
10
+ import SectionLabel from '~/components/common/SectionLabel.vue'
10
11
 
11
12
  const { t } = useI18n()
12
13
  const fragments = useFragmentsStore()
@@ -59,9 +60,9 @@ function remove(id: string) {
59
60
  </p>
60
61
 
61
62
  <div class="flex items-center justify-between">
62
- <span class="text-[11px] font-semibold uppercase tracking-wide text-muted">
63
+ <SectionLabel as="span">
63
64
  {{ t('settings.serviceFragmentDefaults.defaultFragments') }}
64
- </span>
65
+ </SectionLabel>
65
66
  <UDropdownMenu v-if="menu.length" :items="menu" :ui="{ content: 'max-h-72 overflow-y-auto' }">
66
67
  <UButton
67
68
  size="xs"
@@ -90,28 +91,30 @@ function remove(id: string) {
90
91
  {{ f.title }}<UIcon name="i-lucide-x" class="ms-0.5 h-3 w-3" />
91
92
  </UBadge>
92
93
  </div>
93
- <p v-else class="text-[11px] text-dimmed">
94
+ <p v-else class="text-2xs text-dimmed">
94
95
  {{ t('settings.serviceFragmentDefaults.empty') }}
95
96
  </p>
96
97
 
97
- <div class="flex flex-wrap gap-x-4 gap-y-1 border-t border-default pt-3 text-[11px]">
98
+ <div class="flex flex-wrap gap-x-4 gap-y-1 border-t border-default pt-3 text-2xs">
98
99
  <span class="text-dimmed">
99
100
  {{ t('settings.serviceFragmentDefaults.footer.question') }}
100
101
  </span>
101
- <button
102
- type="button"
103
- class="font-medium text-primary hover:underline"
102
+ <UButton
103
+ color="primary"
104
+ variant="link"
105
+ class="p-0 text-2xs font-medium text-primary hover:underline"
104
106
  @click="ui.openFragmentLibrary()"
105
107
  >
106
108
  {{ t('settings.serviceFragmentDefaults.footer.manageBoard') }}
107
- </button>
108
- <button
109
- type="button"
110
- class="font-medium text-primary hover:underline"
109
+ </UButton>
110
+ <UButton
111
+ color="primary"
112
+ variant="link"
113
+ class="p-0 text-2xs font-medium text-primary hover:underline"
111
114
  @click="ui.openAccountSettings('fragments')"
112
115
  >
113
116
  {{ t('settings.serviceFragmentDefaults.footer.manageAccount') }}
114
- </button>
117
+ </UButton>
115
118
  </div>
116
119
  </div>
117
120
  </template>
@@ -288,7 +288,7 @@ async function remove(stack: SharedStack) {
288
288
  {{ statusLabel(stack.status) }}
289
289
  </UBadge>
290
290
  </div>
291
- <p class="truncate text-[11px] text-dimmed">{{ stack.cloneUrl }}</p>
291
+ <p class="truncate text-2xs text-dimmed">{{ stack.cloneUrl }}</p>
292
292
  <div v-if="stack.managedNetworks.length" class="flex flex-wrap gap-1">
293
293
  <UBadge
294
294
  v-for="net in stack.managedNetworks"
@@ -347,7 +347,7 @@ async function remove(stack: SharedStack) {
347
347
  />
348
348
  </div>
349
349
  </div>
350
- <p v-if="stack.lastError" class="text-[11px] text-app-error-400">{{ stack.lastError }}</p>
350
+ <p v-if="stack.lastError" class="text-2xs text-app-error-400">{{ stack.lastError }}</p>
351
351
  </div>
352
352
  </section>
353
353
 
@@ -407,12 +407,12 @@ async function remove(stack: SharedStack) {
407
407
  >
408
408
  {{ t('settings.sharedStacks.detect.button') }}
409
409
  </UButton>
410
- <span class="text-[11px] text-dimmed">{{ t('settings.sharedStacks.detect.hint') }}</span>
410
+ <span class="text-2xs text-dimmed">{{ t('settings.sharedStacks.detect.hint') }}</span>
411
411
  </div>
412
412
 
413
413
  <p
414
414
  v-if="detectedEnvFiles.length"
415
- class="text-[11px] text-dimmed"
415
+ class="text-2xs text-dimmed"
416
416
  data-testid="shared-stack-env-files"
417
417
  >
418
418
  {{ t('settings.sharedStacks.detect.envFiles') }}
@@ -428,7 +428,7 @@ async function remove(stack: SharedStack) {
428
428
  <li
429
429
  v-for="(label, index) in layerLabels"
430
430
  :key="index"
431
- class="font-mono text-[11px] text-dimmed"
431
+ class="font-mono text-2xs text-dimmed"
432
432
  >
433
433
  {{ label }}
434
434
  </li>
@@ -95,7 +95,7 @@ const STATUS_UI: Record<
95
95
  <UIcon :name="state.icon" class="h-5 w-5 shrink-0 text-toned" />
96
96
  <div class="min-w-0">
97
97
  <div class="text-sm font-medium text-default">{{ state.label }}</div>
98
- <div class="text-[11px] text-dimmed">{{ subtitle }}</div>
98
+ <div class="text-2xs text-dimmed">{{ subtitle }}</div>
99
99
  </div>
100
100
  </div>
101
101
  <div class="flex shrink-0 items-center gap-2">
@@ -139,7 +139,7 @@ const STATUS_UI: Record<
139
139
  variant="subtle"
140
140
  :icon="STATUS_UI[diagnostic.status].icon"
141
141
  :description="diagnostic.message + (diagnostic.detail ? ` ${diagnostic.detail}` : '')"
142
- :ui="{ description: 'text-[11px]' }"
142
+ :ui="{ description: 'text-2xs' }"
143
143
  />
144
144
  </div>
145
145
  </template>
@@ -65,17 +65,17 @@ async function toggle(row: TaskTypeSuppression, offered: boolean) {
65
65
  {{ t('settings.taskTypeSuppressions.intro') }}
66
66
  </p>
67
67
 
68
- <p v-if="loading" class="text-[11px] text-dimmed">
68
+ <p v-if="loading" class="text-2xs text-dimmed">
69
69
  {{ t('settings.taskTypeSuppressions.loading') }}
70
70
  </p>
71
- <p v-else-if="!rows.length" class="text-[11px] text-dimmed">
71
+ <p v-else-if="!rows.length" class="text-2xs text-dimmed">
72
72
  {{ t('settings.taskTypeSuppressions.empty') }}
73
73
  </p>
74
74
  <ul v-else class="space-y-2" data-testid="task-type-suppressions">
75
75
  <li
76
76
  v-for="row in rows"
77
77
  :key="row.taskType.taskType"
78
- class="flex items-start justify-between gap-3 rounded border border-default px-3 py-2"
78
+ class="flex items-start justify-between gap-3 rounded-sm border border-default px-3 py-2"
79
79
  data-testid="task-type-suppression"
80
80
  :data-task-type="row.taskType.taskType"
81
81
  >
@@ -94,7 +94,7 @@ async function toggle(row: TaskTypeSuppression, offered: boolean) {
94
94
  {{ row.taskType.presentation.category }}
95
95
  </UBadge>
96
96
  </div>
97
- <p class="mt-0.5 text-[11px] text-dimmed">
97
+ <p class="mt-0.5 text-2xs text-dimmed">
98
98
  {{ row.taskType.presentation.description }}
99
99
  </p>
100
100
  </div>
@@ -128,10 +128,10 @@ async function runProbe(id: string) {
128
128
  <UBadge color="neutral" variant="soft" size="sm">
129
129
  {{ TRANSPORT_LABELS[server.transport] }}
130
130
  </UBadge>
131
- <code class="font-mono text-[11px] text-dimmed">{{ server.id }}</code>
131
+ <code class="font-mono text-2xs text-dimmed">{{ server.id }}</code>
132
132
  </div>
133
133
 
134
- <p class="truncate font-mono text-[11px] text-dimmed" :title="server.target">
134
+ <p class="truncate font-mono text-2xs text-dimmed" :title="server.target">
135
135
  {{ server.target }}
136
136
  </p>
137
137
  <p v-if="server.guidance" class="text-xs text-muted">{{ server.guidance }}</p>
@@ -139,12 +139,12 @@ async function runProbe(id: string) {
139
139
  <!-- Which agents get it. An EMPTY list is a registration attached to nothing: it never reaches
140
140
  a dispatch, so the credentials it asks for are keys an operator fills in for no run. Said
141
141
  out loud, because no other surface in the platform can see that state. -->
142
- <p v-if="server.declaredBy.length" class="text-[11px] text-muted">
142
+ <p v-if="server.declaredBy.length" class="text-2xs text-muted">
143
143
  {{ t('settings.toolServers.declaredBy', { kinds: server.declaredBy.join(', ') }) }}
144
144
  </p>
145
145
  <p
146
146
  v-else
147
- class="text-[11px] text-app-warning-400"
147
+ class="text-2xs text-app-warning-400"
148
148
  :data-testid="`tool-server-orphan-${server.id}`"
149
149
  >
150
150
  {{ t('settings.toolServers.declaredByNone') }}
@@ -153,21 +153,21 @@ async function runProbe(id: string) {
153
153
  <!-- Which harnesses could serve it. EMPTY means the declaration can never run anywhere (an
154
154
  `http` server narrowed to Codex, whose MCP client is stdio-only): it is never dropped FOR
155
155
  A REASON on any run, so no prompt and no log line ever mentions it. -->
156
- <p v-if="server.servableHarnesses.length" class="text-[11px] text-muted">
156
+ <p v-if="server.servableHarnesses.length" class="text-2xs text-muted">
157
157
  {{
158
158
  t('settings.toolServers.servableHarnesses', {
159
159
  harnesses: server.servableHarnesses.join(', '),
160
160
  })
161
161
  }}
162
162
  </p>
163
- <p v-else class="text-[11px] text-app-warning-400">
163
+ <p v-else class="text-2xs text-app-warning-400">
164
164
  {{ t('settings.toolServers.servableHarnessesNone') }}
165
165
  </p>
166
166
 
167
- <p v-if="server.allowedTools?.length" class="text-[11px] text-muted">
167
+ <p v-if="server.allowedTools?.length" class="text-2xs text-muted">
168
168
  {{ t('settings.toolServers.allowedTools', { tools: server.allowedTools.join(', ') }) }}
169
169
  </p>
170
- <p v-if="server.credentials.length" class="text-[11px] text-muted">
170
+ <p v-if="server.credentials.length" class="text-2xs text-muted">
171
171
  {{
172
172
  t('settings.toolServers.credentials', {
173
173
  keys: server.credentials.map((c) => c.key).join(', '),
@@ -199,25 +199,25 @@ async function runProbe(id: string) {
199
199
  : t('settings.toolServers.oauth.machineGrant')
200
200
  }}
201
201
  </UBadge>
202
- <span v-if="server.oauth.connectedBy" class="text-[11px] text-muted">
202
+ <span v-if="server.oauth.connectedBy" class="text-2xs text-muted">
203
203
  {{ t('settings.toolServers.oauth.connectedBy', { user: server.oauth.connectedBy }) }}
204
204
  </span>
205
205
  </div>
206
206
 
207
- <p v-if="server.oauth.scopes?.length" class="text-[11px] text-muted">
207
+ <p v-if="server.oauth.scopes?.length" class="text-2xs text-muted">
208
208
  {{ t('settings.toolServers.oauth.scopes', { scopes: server.oauth.scopes.join(', ') }) }}
209
209
  </p>
210
210
  <!-- A grant with no refresh token works until its access token expires and then needs
211
211
  granting again by hand. Said BEFORE it happens, which is the only time it is useful. -->
212
212
  <p
213
213
  v-if="server.oauth.connected && server.oauth.refreshable === false"
214
- class="text-[11px] text-app-warning-400"
214
+ class="text-2xs text-app-warning-400"
215
215
  >
216
216
  {{ t('settings.toolServers.oauth.notRefreshable') }}
217
217
  </p>
218
218
  <p
219
219
  v-if="server.oauth.lastError"
220
- class="text-[11px] text-app-error-400"
220
+ class="text-2xs text-app-error-400"
221
221
  :data-testid="`tool-server-oauth-error-${server.id}`"
222
222
  >
223
223
  {{ t('settings.toolServers.oauth.lastError', { detail: server.oauth.lastError }) }}
@@ -272,7 +272,7 @@ async function runProbe(id: string) {
272
272
  verify it from a run, or change the declaration. -->
273
273
  <p
274
274
  v-else-if="server.notProbeableReason"
275
- class="text-[11px] text-dimmed"
275
+ class="text-2xs text-dimmed"
276
276
  :data-testid="`tool-server-unprobeable-${server.id}`"
277
277
  >
278
278
  {{ NOT_PROBEABLE_LABELS[server.notProbeableReason] }}
@@ -293,12 +293,12 @@ async function runProbe(id: string) {
293
293
  >
294
294
  {{ STATUS_LABELS[resultFor(server.id)!.status] }}
295
295
  </UBadge>
296
- <span v-if="resultFor(server.id)!.httpStatus" class="text-[11px] text-muted">
296
+ <span v-if="resultFor(server.id)!.httpStatus" class="text-2xs text-muted">
297
297
  {{ t('settings.toolServers.httpStatus', { status: resultFor(server.id)!.httpStatus }) }}
298
298
  </span>
299
299
  </div>
300
300
 
301
- <p v-if="resultFor(server.id)!.status === 'ok'" class="text-[11px] text-toned">
301
+ <p v-if="resultFor(server.id)!.status === 'ok'" class="text-2xs text-toned">
302
302
  {{
303
303
  t('settings.toolServers.okDetail', {
304
304
  name: resultFor(server.id)!.serverName || server.id,
@@ -310,7 +310,7 @@ async function runProbe(id: string) {
310
310
  </p>
311
311
  <!-- A count off a truncated read is a FLOOR, not a total, and the difference decides whether
312
312
  the allowedTools verdict below means anything. -->
313
- <p v-if="resultFor(server.id)!.toolsComplete === false" class="text-[11px] text-dimmed">
313
+ <p v-if="resultFor(server.id)!.toolsComplete === false" class="text-2xs text-dimmed">
314
314
  {{ t('settings.toolServers.toolsIncomplete') }}
315
315
  </p>
316
316
 
@@ -319,7 +319,7 @@ async function runProbe(id: string) {
319
319
  advertising the tool. Withheld entirely when the tool list was a prefix. -->
320
320
  <p
321
321
  v-if="resultFor(server.id)!.allowedTools?.unmatched?.length"
322
- class="text-[11px] text-app-warning-400"
322
+ class="text-2xs text-app-warning-400"
323
323
  :data-testid="`tool-server-unmatched-${server.id}`"
324
324
  >
325
325
  {{
@@ -330,14 +330,14 @@ async function runProbe(id: string) {
330
330
  </p>
331
331
  <p
332
332
  v-else-if="resultFor(server.id)!.allowedTools?.checked === false"
333
- class="text-[11px] text-dimmed"
333
+ class="text-2xs text-dimmed"
334
334
  >
335
335
  {{ t('settings.toolServers.allowedToolsUnchecked') }}
336
336
  </p>
337
337
 
338
338
  <p
339
339
  v-if="resultFor(server.id)!.unresolvedCredentials?.length"
340
- class="text-[11px] text-app-warning-400"
340
+ class="text-2xs text-app-warning-400"
341
341
  >
342
342
  {{
343
343
  t('settings.toolServers.unresolvedCredentials', {
@@ -347,7 +347,7 @@ async function runProbe(id: string) {
347
347
  </p>
348
348
  <p
349
349
  v-if="resultFor(server.id)!.refusedCredentials?.length"
350
- class="text-[11px] text-app-error-400"
350
+ class="text-2xs text-app-error-400"
351
351
  >
352
352
  {{
353
353
  t('settings.toolServers.refusedCredentials', {
@@ -357,7 +357,7 @@ async function runProbe(id: string) {
357
357
  </p>
358
358
  <p
359
359
  v-if="resultFor(server.id)!.unusableCredentials?.length"
360
- class="text-[11px] text-app-error-400"
360
+ class="text-2xs text-app-error-400"
361
361
  >
362
362
  {{
363
363
  t('settings.toolServers.unusableCredentials', {
@@ -384,7 +384,7 @@ async function runProbe(id: string) {
384
384
  </UButton>
385
385
  <pre
386
386
  v-if="expanded[server.id]"
387
- class="overflow-x-auto rounded bg-app-950 p-2 font-mono text-[10px] text-muted"
387
+ class="overflow-x-auto rounded-sm bg-app-950 p-2 font-mono text-3xs text-muted"
388
388
  >{{ resultFor(server.id)!.error }}</pre>
389
389
  </template>
390
390
  </div>
@@ -38,17 +38,17 @@ const hasAny = computed(() => usage.rows.length > 0)
38
38
 
39
39
  <template>
40
40
  <div class="space-y-6">
41
- <p class="text-[11px] text-muted">
41
+ <p class="text-2xs text-muted">
42
42
  {{ t('settings.usage.body') }}
43
43
  </p>
44
44
 
45
- <p v-if="usage.report" class="text-[11px] text-dimmed">
45
+ <p v-if="usage.report" class="text-2xs text-dimmed">
46
46
  {{ t('settings.usage.period', { date: d(new Date(usage.report.periodStart), 'short') }) }}
47
47
  </p>
48
48
 
49
- <p v-if="usage.loading" class="text-[11px] text-dimmed">{{ t('common.loading') }}</p>
50
- <p v-else-if="usage.error" class="text-[11px] text-app-error-400">{{ usage.error }}</p>
51
- <p v-else-if="!hasAny" class="text-[11px] text-dimmed">{{ t('settings.usage.empty') }}</p>
49
+ <p v-if="usage.loading" class="text-2xs text-dimmed">{{ t('common.loading') }}</p>
50
+ <p v-else-if="usage.error" class="text-2xs text-app-error-400">{{ usage.error }}</p>
51
+ <p v-else-if="!hasAny" class="text-2xs text-dimmed">{{ t('settings.usage.empty') }}</p>
52
52
 
53
53
  <template v-else>
54
54
  <!-- Subscriptions (flat-rate quota harnesses) -->
@@ -57,7 +57,7 @@ const hasAny = computed(() => usage.rows.length > 0)
57
57
  <h3 class="text-sm font-semibold text-default">
58
58
  {{ t('settings.usage.subscription') }}
59
59
  </h3>
60
- <span class="text-[11px] text-muted">
60
+ <span class="text-2xs text-muted">
61
61
  {{
62
62
  t('settings.usage.tokens', {
63
63
  input: formatTokens(usage.subscriptionTotal.inputTokens),
@@ -66,21 +66,21 @@ const hasAny = computed(() => usage.rows.length > 0)
66
66
  }}
67
67
  </span>
68
68
  </div>
69
- <p class="text-[10px] text-dimmed">{{ t('settings.usage.illustrative') }}</p>
69
+ <p class="text-3xs text-dimmed">{{ t('settings.usage.illustrative') }}</p>
70
70
  <div
71
71
  v-for="row in usage.subscription"
72
72
  :key="`sub-${row.vendor}-${row.provider}-${row.model}`"
73
73
  class="space-y-1"
74
74
  :data-testid="'usage-row-subscription'"
75
75
  >
76
- <div class="flex items-center justify-between gap-2 text-[11px]">
76
+ <div class="flex items-center justify-between gap-2 text-2xs">
77
77
  <span class="min-w-0 truncate font-medium text-toned">{{ row.model }}</span>
78
- <span class="shrink-0 rounded bg-accented/60 px-1.5 py-0.5 text-[10px] text-toned">
78
+ <span class="shrink-0 rounded-sm bg-accented/60 px-1.5 py-0.5 text-3xs text-toned">
79
79
  {{ row.vendor ?? row.provider }}
80
80
  </span>
81
81
  </div>
82
82
  <UProgress :model-value="pctOf(row, usage.subscription)" size="xs" color="primary" />
83
- <div class="flex justify-between text-[10px] text-dimmed">
83
+ <div class="flex justify-between text-3xs text-dimmed">
84
84
  <span>
85
85
  {{
86
86
  t('settings.usage.tokens', {
@@ -101,7 +101,7 @@ const hasAny = computed(() => usage.rows.length > 0)
101
101
  <h3 class="text-sm font-semibold text-default">
102
102
  {{ t('settings.usage.metered') }}
103
103
  </h3>
104
- <span class="text-[11px] text-muted">
104
+ <span class="text-2xs text-muted">
105
105
  {{
106
106
  t('settings.usage.tokens', {
107
107
  input: formatTokens(usage.meteredTotal.inputTokens),
@@ -117,13 +117,13 @@ const hasAny = computed(() => usage.rows.length > 0)
117
117
  class="space-y-1"
118
118
  :data-testid="'usage-row-metered'"
119
119
  >
120
- <div class="flex items-center justify-between gap-2 text-[11px]">
120
+ <div class="flex items-center justify-between gap-2 text-2xs">
121
121
  <span class="min-w-0 truncate font-medium text-toned">
122
122
  {{ row.provider }}:{{ row.model }}
123
123
  </span>
124
124
  </div>
125
125
  <UProgress :model-value="pctOf(row, usage.metered)" size="xs" color="neutral" />
126
- <div class="flex justify-between text-[10px] text-dimmed">
126
+ <div class="flex justify-between text-3xs text-dimmed">
127
127
  <span>
128
128
  {{
129
129
  t('settings.usage.tokens', {
@@ -10,6 +10,7 @@ import type { ProviderConfigField, UserSecretKind } from '~/types/userSecrets'
10
10
  import IntegrationBackTitle from '~/components/layout/IntegrationBackTitle.vue'
11
11
  import SecretInput from '~/components/common/SecretInput.vue'
12
12
  import ConnectionWarnings from '~/components/settings/ConnectionWarnings.vue'
13
+ import SectionLabel from '~/components/common/SectionLabel.vue'
13
14
 
14
15
  const { t } = useI18n()
15
16
  const ui = useUiStore()
@@ -170,7 +171,7 @@ async function remove() {
170
171
  >
171
172
  <div>
172
173
  <span class="font-medium text-default">{{ status.label }}</span>
173
- <div class="text-[11px] text-app-success-400">
174
+ <div class="text-2xs text-app-success-400">
174
175
  {{ t('settings.userSecrets.connectedStored') }}
175
176
  </div>
176
177
  </div>
@@ -185,11 +186,11 @@ async function remove() {
185
186
  </div>
186
187
 
187
188
  <div v-if="descriptor" class="rounded-lg border border-dashed border-muted p-3 space-y-3">
188
- <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
189
+ <SectionLabel as="p">
189
190
  {{
190
191
  status ? t('settings.userSecrets.replaceToken') : t('settings.userSecrets.addToken')
191
192
  }}
192
- </p>
193
+ </SectionLabel>
193
194
 
194
195
  <UFormField :label="t('settings.userSecrets.labelField')">
195
196
  <UInput v-model="labelDraft" :placeholder="descriptor.label" />
@@ -17,6 +17,7 @@ import {
17
17
  } from '~/modular/workspace-metadata'
18
18
  import type { WorkspaceMetadataFieldDefinition } from '~/modular/workspace-metadata'
19
19
  import type { AppSlots } from '~/modular/slots'
20
+ import SectionLabel from '~/components/common/SectionLabel.vue'
20
21
 
21
22
  const { t } = useI18n()
22
23
  const slots = useReactiveSlots<AppSlots>()
@@ -93,12 +94,12 @@ function selectItems(field: WorkspaceMetadataFieldDefinition) {
93
94
  <h3 class="text-sm font-semibold text-default">
94
95
  {{ t('settings.workspaceSettings.metadata.heading') }}
95
96
  </h3>
96
- <p class="text-[11px] text-muted">
97
+ <p class="text-2xs text-muted">
97
98
  {{ t('settings.workspaceSettings.metadata.body') }}
98
99
  </p>
99
100
  </section>
100
101
 
101
- <p v-if="fields.length === 0" class="text-[11px] text-dimmed">
102
+ <p v-if="fields.length === 0" class="text-2xs text-dimmed">
102
103
  {{ t('settings.workspaceSettings.metadata.empty') }}
103
104
  </p>
104
105
 
@@ -106,9 +107,9 @@ function selectItems(field: WorkspaceMetadataFieldDefinition) {
106
107
  <div class="space-y-4">
107
108
  <label v-for="field in fields" :key="field.key" class="block">
108
109
  <!-- Field labels are deployment DATA, rendered verbatim (see the module docs). -->
109
- <span class="mb-1 block text-[10px] uppercase tracking-wide text-dimmed">
110
+ <SectionLabel as="span" class="mb-1 block">
110
111
  {{ field.label }}
111
- </span>
112
+ </SectionLabel>
112
113
  <USelect
113
114
  v-if="field.type === 'select'"
114
115
  v-model="draft[field.key]"
@@ -124,7 +125,7 @@ function selectItems(field: WorkspaceMetadataFieldDefinition) {
124
125
  size="sm"
125
126
  :data-testid="`workspace-metadata-${field.key}`"
126
127
  />
127
- <span v-if="field.description" class="mt-1 block text-[11px] text-dimmed">
128
+ <span v-if="field.description" class="mt-1 block text-2xs text-dimmed">
128
129
  {{ field.description }}
129
130
  </span>
130
131
  </label>