@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
@@ -10,6 +10,8 @@
10
10
  // FrontendConfig opening its Build group after a detect run) can bind `v-model:open`;
11
11
  // without a binding the model acts as local state and `defaultOpen` picks the initial
12
12
  // value (controlled callers should drive their own ref instead of passing it).
13
+ import SectionLabel from '~/components/common/SectionLabel.vue'
14
+
13
15
  const props = defineProps<{
14
16
  title: string
15
17
  icon?: string
@@ -26,26 +28,32 @@ if (props.defaultOpen) open.value = true
26
28
  <template>
27
29
  <section class="border-t border-default pt-2" data-testid="inspector-section">
28
30
  <div class="flex items-center gap-1.5">
29
- <button
30
- type="button"
31
- class="flex min-w-0 flex-1 items-center gap-1.5 text-start text-[11px] font-semibold uppercase tracking-wide text-muted hover:text-default"
31
+ <UButton
32
+ color="neutral"
33
+ variant="link"
34
+ class="group min-w-0 flex-1 p-0"
32
35
  :aria-expanded="open"
33
36
  data-testid="inspector-section-toggle"
34
37
  @click="open = !open"
35
38
  >
36
- <UIcon
37
- :name="open ? 'i-lucide-chevron-down' : 'i-lucide-chevron-right'"
38
- class="h-3.5 w-3.5 shrink-0 text-dimmed"
39
- />
40
- <UIcon v-if="icon" :name="icon" class="h-3.5 w-3.5 shrink-0" />
41
- <span class="truncate">{{ title }}</span>
42
- <span v-if="count" class="font-normal normal-case text-dimmed">({{ count }})</span>
43
- <UIcon
44
- v-if="warning"
45
- name="i-lucide-triangle-alert"
46
- class="h-3.5 w-3.5 shrink-0 text-app-warning-400"
47
- />
48
- </button>
39
+ <SectionLabel
40
+ as="span"
41
+ class="flex min-w-0 flex-1 items-center gap-1.5 group-hover:text-default"
42
+ >
43
+ <UIcon
44
+ :name="open ? 'i-lucide-chevron-down' : 'i-lucide-chevron-right'"
45
+ class="h-3.5 w-3.5 shrink-0 text-dimmed"
46
+ />
47
+ <UIcon v-if="icon" :name="icon" class="h-3.5 w-3.5 shrink-0" />
48
+ <span class="truncate">{{ title }}</span>
49
+ <span v-if="count" class="font-normal normal-case text-dimmed">({{ count }})</span>
50
+ <UIcon
51
+ v-if="warning"
52
+ name="i-lucide-triangle-alert"
53
+ class="h-3.5 w-3.5 shrink-0 text-app-warning-400"
54
+ />
55
+ </SectionLabel>
56
+ </UButton>
49
57
  <!-- An action ("+", attach, menu) mutates the body list, so expand (never collapse)
50
58
  on interaction — otherwise the new row lands inside the collapsed body. -->
51
59
  <div v-if="$slots.actions" class="contents" @click="open = true">
@@ -53,7 +61,7 @@ if (props.defaultOpen) open.value = true
53
61
  </div>
54
62
  </div>
55
63
  <div v-if="open" class="mt-2 space-y-3">
56
- <p v-if="hint" class="text-[11px] leading-snug text-dimmed">{{ hint }}</p>
64
+ <p v-if="hint" class="text-2xs leading-snug text-dimmed">{{ hint }}</p>
57
65
  <slot />
58
66
  </div>
59
67
  </section>
@@ -4,6 +4,7 @@
4
4
  // (lazily loaded; retained ~1 week on the backend).
5
5
  import type { Block } from '~/types/domain'
6
6
  import type { Recurrence } from '~/types/recurring'
7
+ import SectionLabel from '~/components/common/SectionLabel.vue'
7
8
 
8
9
  const props = defineProps<{ block: Block }>()
9
10
  const recurring = useRecurringPipelinesStore()
@@ -126,7 +127,7 @@ function fmtTime(ms: number) {
126
127
  <div v-if="schedule" class="space-y-2 rounded-lg border border-primary/50 bg-primary/10 p-3">
127
128
  <div class="flex items-center justify-between">
128
129
  <span
129
- class="flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-primary"
130
+ class="flex items-center gap-1.5 text-2xs font-semibold uppercase tracking-wide text-primary"
130
131
  >
131
132
  <UIcon name="i-lucide-repeat" class="h-3.5 w-3.5" />
132
133
  {{ t('inspector.recurring.title') }}
@@ -146,13 +147,13 @@ function fmtTime(ms: number) {
146
147
  </UBadge>
147
148
  </div>
148
149
 
149
- <p class="text-[11px] text-muted">
150
+ <p class="text-2xs text-muted">
150
151
  <span class="text-toned">{{ pipelineName }}</span>
151
152
  </p>
152
153
 
153
154
  <!-- On-demand: no cadence, no pause/resume — it fires only when a person triggers it. -->
154
155
  <template v-if="schedule.onDemand">
155
- <p class="text-[11px] text-dimmed">{{ t('inspector.recurring.onDemandHint') }}</p>
156
+ <p class="text-2xs text-dimmed">{{ t('inspector.recurring.onDemandHint') }}</p>
156
157
  <div class="flex flex-wrap gap-1.5 pt-1">
157
158
  <UButton size="xs" variant="soft" icon="i-lucide-play" :loading="busy" @click="runNow">
158
159
  {{ t('inspector.recurring.runNow') }}
@@ -161,8 +162,8 @@ function fmtTime(ms: number) {
161
162
  </template>
162
163
 
163
164
  <template v-else-if="!editing">
164
- <p class="text-[11px] text-muted">{{ describeCadence(schedule.recurrence) }}</p>
165
- <p class="text-[11px] text-dimmed">
165
+ <p class="text-2xs text-muted">{{ describeCadence(schedule.recurrence) }}</p>
166
+ <p class="text-2xs text-dimmed">
166
167
  {{ t('inspector.recurring.nextRun', { time: fmtTime(schedule.nextRunAt) }) }}
167
168
  </p>
168
169
  <div class="flex flex-wrap gap-1.5 pt-1">
@@ -213,10 +214,10 @@ function fmtTime(ms: number) {
213
214
 
214
215
  <!-- run history -->
215
216
  <div v-if="runs.length" class="space-y-1 border-t border-default pt-2">
216
- <span class="text-[10px] font-semibold uppercase tracking-wide text-dimmed">
217
+ <SectionLabel as="span">
217
218
  {{ t('inspector.recurring.recentRuns') }}
218
- </span>
219
- <div v-for="run in runs" :key="run.id" class="flex items-center gap-2 text-[11px]">
219
+ </SectionLabel>
220
+ <div v-for="run in runs" :key="run.id" class="flex items-center gap-2 text-2xs">
220
221
  <span :class="RUN_COLOR[run.status] ?? 'text-muted'" class="w-14 shrink-0">
221
222
  {{ runStatusLabel(run.status) }}
222
223
  </span>
@@ -2,6 +2,7 @@
2
2
  import { computed } from 'vue'
3
3
  import type { Block, ServiceConnection } from '~/types/domain'
4
4
  import InspectorSection from '~/components/panels/inspector/InspectorSection.vue'
5
+ import IconButton from '~/components/common/IconButton.vue'
5
6
 
6
7
  // Service-frame (`type: 'service'`) connections: the other services this one USES
7
8
  // (consumer→provider edges, stored on this frame — the consumer end). Each row picks a
@@ -124,23 +125,23 @@ const usedBy = computed(() =>
124
125
  (e: KeyboardEvent) => setDescription(i, (e.target as HTMLInputElement).value)
125
126
  "
126
127
  />
127
- <UButton
128
+ <IconButton
128
129
  size="xs"
129
130
  variant="ghost"
130
131
  color="neutral"
131
132
  icon="i-lucide-x"
132
- :title="t('inspector.serviceConnections.remove')"
133
+ :label="t('inspector.serviceConnections.remove')"
133
134
  data-testid="service-connection-remove"
134
135
  @click="removeConnection(i)"
135
136
  />
136
137
  </div>
137
138
  </div>
138
- <div v-else class="text-[11px] text-dimmed">
139
+ <div v-else class="text-2xs text-dimmed">
139
140
  {{ t('inspector.serviceConnections.empty') }}
140
141
  </div>
141
142
 
142
143
  <div v-if="usedBy.length" class="space-y-1" data-testid="service-connections-used-by">
143
- <span class="text-[11px] text-muted">{{ t('inspector.serviceConnections.usedBy') }}</span>
144
+ <span class="text-2xs text-muted">{{ t('inspector.serviceConnections.usedBy') }}</span>
144
145
  <div class="flex flex-wrap gap-1">
145
146
  <UBadge v-for="f in usedBy" :key="f.id" size="sm" variant="soft" color="neutral">
146
147
  {{ f.title || f.id }}
@@ -114,7 +114,7 @@ async function clear() {
114
114
  <!-- Disabled affordance until an observability integration is connected. -->
115
115
  <div
116
116
  v-if="!connected"
117
- class="flex items-center justify-between gap-2 rounded-md border border-default bg-default/60 px-2 py-1.5 text-[11px] text-muted"
117
+ class="flex items-center justify-between gap-2 rounded-md border border-default bg-default/60 px-2 py-1.5 text-2xs text-muted"
118
118
  >
119
119
  <span>{{ t('inspector.releaseHealth.connectPrompt') }}</span>
120
120
  <UButton
@@ -130,7 +130,7 @@ async function clear() {
130
130
  </div>
131
131
 
132
132
  <div v-else class="space-y-2">
133
- <p class="text-[11px] text-dimmed">
133
+ <p class="text-2xs text-dimmed">
134
134
  {{ t('inspector.releaseHealth.hint') }}
135
135
  </p>
136
136
  <div class="grid grid-cols-2 gap-2">
@@ -188,17 +188,17 @@ async function stop(mode: EnvironmentTestMode) {
188
188
  <div class="mt-3 space-y-3 border-t border-default pt-3" data-testid="env-test-section">
189
189
  <!-- The precondition both self-tests share, stated once at the top: with no provision type
190
190
  there is no environment to stand up and therefore nothing for an agent to drive either. -->
191
- <p v-if="!canTest" class="text-[11px] text-dimmed">
191
+ <p v-if="!canTest" class="text-2xs text-dimmed">
192
192
  {{ t('inspector.testConfig.envTest.infraless') }}
193
193
  </p>
194
194
 
195
195
  <!-- 1. The provisioning self-test: the whole lifecycle against a throwaway branch. -->
196
196
  <div class="flex items-center justify-between gap-2">
197
197
  <div class="min-w-0">
198
- <p class="text-[11px] font-medium text-toned">
198
+ <p class="text-2xs font-medium text-toned">
199
199
  {{ t('inspector.testConfig.envTest.title') }}
200
200
  </p>
201
- <p class="text-[11px] text-muted">{{ t('inspector.testConfig.envTest.hint') }}</p>
201
+ <p class="text-2xs text-muted">{{ t('inspector.testConfig.envTest.hint') }}</p>
202
202
  </div>
203
203
  <UButton
204
204
  v-if="!isRunning('provision')"
@@ -228,7 +228,7 @@ async function stop(mode: EnvironmentTestMode) {
228
228
 
229
229
  <p
230
230
  v-if="provisionRun"
231
- class="text-[11px]"
231
+ class="text-2xs"
232
232
  :class="{
233
233
  'text-app-info-300/80': provisionRun.status === 'running',
234
234
  'text-app-success-300/80': provisionRun.status === 'succeeded',
@@ -253,11 +253,7 @@ async function stop(mode: EnvironmentTestMode) {
253
253
  </template>
254
254
  </p>
255
255
 
256
- <div
257
- v-if="errors.provision"
258
- class="text-[11px] text-app-error-400"
259
- data-testid="env-test-error"
260
- >
256
+ <div v-if="errors.provision" class="text-2xs text-app-error-400" data-testid="env-test-error">
261
257
  <p>{{ errors.provision.text }}</p>
262
258
  <!-- Only the not-provisionable handler case is one-click fixable: jump to Infrastructure →
263
259
  Test environments, where the workspace's per-type environment handler is registered. -->
@@ -279,10 +275,10 @@ async function stop(mode: EnvironmentTestMode) {
279
275
  and could not do with the environment it was handed. -->
280
276
  <div class="flex items-center justify-between gap-2 border-t border-default pt-3">
281
277
  <div class="min-w-0">
282
- <p class="text-[11px] font-medium text-toned">
278
+ <p class="text-2xs font-medium text-toned">
283
279
  {{ t('inspector.testConfig.envProbe.title') }}
284
280
  </p>
285
- <p class="text-[11px] text-muted">
281
+ <p class="text-2xs text-muted">
286
282
  {{ t('inspector.testConfig.envProbe.hint') }}
287
283
  {{
288
284
  probeSurface === 'ui'
@@ -319,7 +315,7 @@ async function stop(mode: EnvironmentTestMode) {
319
315
 
320
316
  <p
321
317
  v-if="probeRun"
322
- class="text-[11px]"
318
+ class="text-2xs"
323
319
  :class="{
324
320
  'text-app-info-300/80': probeRun.status === 'running',
325
321
  'text-app-success-300/80': probeRun.status === 'succeeded',
@@ -355,7 +351,7 @@ async function stop(mode: EnvironmentTestMode) {
355
351
 
356
352
  <div
357
353
  v-if="errors['agent-probe']"
358
- class="text-[11px] text-app-error-400"
354
+ class="text-2xs text-app-error-400"
359
355
  data-testid="env-probe-error"
360
356
  >
361
357
  <p>{{ errors['agent-probe']!.text }}</p>
@@ -19,6 +19,7 @@ import type {
19
19
  import RepoTreeBrowser from '~/components/github/RepoTreeBrowser.vue'
20
20
  import InspectorSection from '~/components/panels/inspector/InspectorSection.vue'
21
21
  import ServiceSelfTests from '~/components/panels/inspector/ServiceSelfTests.vue'
22
+ import IconButton from '~/components/common/IconButton.vue'
22
23
  import { apiErrorEnvelope } from '~/composables/api/errors'
23
24
 
24
25
  // Service-level (frame) configuration: the service-owned PROVISIONING — the provision
@@ -429,7 +430,7 @@ function setSize(value: InstanceSize) {
429
430
  :default-open="props.defaultOpen"
430
431
  >
431
432
  <div class="space-y-1">
432
- <span class="text-[11px] text-muted">{{ t('inspector.testConfig.provisionType') }}</span>
433
+ <span class="text-2xs text-muted">{{ t('inspector.testConfig.provisionType') }}</span>
433
434
  <div class="flex flex-wrap gap-1">
434
435
  <UButton
435
436
  v-for="p in PROVISION_TYPES"
@@ -442,7 +443,7 @@ function setSize(value: InstanceSize) {
442
443
  {{ p.label }}
443
444
  </UButton>
444
445
  </div>
445
- <p class="text-[11px] leading-snug text-dimmed">
446
+ <p class="text-2xs leading-snug text-dimmed">
446
447
  {{ t('inspector.testConfig.provisionTypeHint') }}
447
448
  </p>
448
449
  </div>
@@ -452,14 +453,14 @@ function setSize(value: InstanceSize) {
452
453
  provisions the compose stack, rather than editing the raw path inline. -->
453
454
  <div
454
455
  v-if="provisionType === 'docker-compose'"
455
- class="flex items-center justify-between gap-2 rounded border border-primary/40 bg-primary/10 p-2"
456
+ class="flex items-center justify-between gap-2 rounded-sm border border-primary/40 bg-primary/10 p-2"
456
457
  data-testid="env-setup-nudge"
457
458
  >
458
459
  <div class="min-w-0">
459
- <p class="text-[11px] font-medium text-primary/90">
460
+ <p class="text-2xs font-medium text-primary/90">
460
461
  {{ t('inspector.testConfig.envWizard.title') }}
461
462
  </p>
462
- <p class="text-[11px] leading-snug text-dimmed">
463
+ <p class="text-2xs leading-snug text-dimmed">
463
464
  {{ t('inspector.testConfig.envWizard.hint') }}
464
465
  </p>
465
466
  </div>
@@ -477,9 +478,9 @@ function setSize(value: InstanceSize) {
477
478
 
478
479
  <!-- Auto-detect a recommended provisioning config from the repo (slice 11). Non-binding:
479
480
  it prefills the form below + the kube edit refs; the user confirms/edits everything. -->
480
- <div v-if="repoContext" class="space-y-2 rounded border border-default bg-default/40 p-2">
481
+ <div v-if="repoContext" class="space-y-2 rounded-sm border border-default bg-default/40 p-2">
481
482
  <div class="flex items-center justify-between gap-2">
482
- <span class="text-[11px] text-muted">{{ t('inspector.testConfig.detect.title') }}</span>
483
+ <span class="text-2xs text-muted">{{ t('inspector.testConfig.detect.title') }}</span>
483
484
  <UButton
484
485
  size="xs"
485
486
  variant="soft"
@@ -491,23 +492,23 @@ function setSize(value: InstanceSize) {
491
492
  {{ t('inspector.testConfig.detect.button') }}
492
493
  </UButton>
493
494
  </div>
494
- <p class="text-[11px] leading-snug text-dimmed">
495
+ <p class="text-2xs leading-snug text-dimmed">
495
496
  {{ t('inspector.testConfig.detect.hint') }}
496
497
  </p>
497
498
 
498
- <p v-if="detectError" class="text-[11px] text-app-error-300/80">
499
+ <p v-if="detectError" class="text-2xs text-app-error-300/80">
499
500
  {{ detectError }}
500
501
  </p>
501
502
 
502
503
  <template v-if="detectResult && !detecting">
503
504
  <p
504
505
  v-if="!detectResult.detected && detectResult.provisioning.type !== 'custom'"
505
- class="text-[11px] text-app-warning-300/80"
506
+ class="text-2xs text-app-warning-300/80"
506
507
  >
507
508
  {{ t('inspector.testConfig.detect.none') }}
508
509
  </p>
509
510
  <template v-else>
510
- <p class="text-[11px] text-app-success-300/80">
511
+ <p class="text-2xs text-app-success-300/80">
511
512
  {{
512
513
  t('inspector.testConfig.detect.applied', {
513
514
  type: provisionTypeLabel(detectResult.provisioning.type),
@@ -516,7 +517,7 @@ function setSize(value: InstanceSize) {
516
517
  </p>
517
518
 
518
519
  <div v-if="detectResult.serviceDirCandidates?.length" class="space-y-1">
519
- <span class="text-[11px] text-muted">{{
520
+ <span class="text-2xs text-muted">{{
520
521
  t('inspector.testConfig.detect.serviceDirTitle')
521
522
  }}</span>
522
523
  <div class="flex flex-wrap gap-1">
@@ -534,7 +535,7 @@ function setSize(value: InstanceSize) {
534
535
  </div>
535
536
 
536
537
  <div v-if="detectResult.manifestRootCandidates?.length" class="space-y-1">
537
- <span class="text-[11px] text-muted">{{
538
+ <span class="text-2xs text-muted">{{
538
539
  t('inspector.testConfig.detect.manifestRootTitle')
539
540
  }}</span>
540
541
  <div class="flex flex-wrap gap-1">
@@ -552,7 +553,7 @@ function setSize(value: InstanceSize) {
552
553
  </div>
553
554
 
554
555
  <div v-if="detectResult.overlayCandidates?.length" class="space-y-1">
555
- <span class="text-[11px] text-muted">{{
556
+ <span class="text-2xs text-muted">{{
556
557
  t('inspector.testConfig.detect.overlayTitle')
557
558
  }}</span>
558
559
  <div class="flex flex-wrap gap-1">
@@ -570,7 +571,7 @@ function setSize(value: InstanceSize) {
570
571
  </div>
571
572
 
572
573
  <div v-if="detectResult.composeServiceCandidates?.length" class="space-y-1">
573
- <span class="text-[11px] text-muted">{{
574
+ <span class="text-2xs text-muted">{{
574
575
  t('inspector.testConfig.detect.composeServiceTitle')
575
576
  }}</span>
576
577
  <div class="flex flex-wrap gap-1">
@@ -587,12 +588,12 @@ function setSize(value: InstanceSize) {
587
588
  </div>
588
589
  </div>
589
590
 
590
- <p v-if="detectResult.urlSource" class="text-[11px] text-dimmed">
591
+ <p v-if="detectResult.urlSource" class="text-2xs text-dimmed">
591
592
  {{
592
593
  t('inspector.testConfig.detect.urlSource', { source: detectResult.urlSource.source })
593
594
  }}
594
595
  </p>
595
- <p v-if="detectResult.namespace" class="text-[11px] text-dimmed">
596
+ <p v-if="detectResult.namespace" class="text-2xs text-dimmed">
596
597
  {{ t('inspector.testConfig.detect.namespace', { namespace: detectResult.namespace }) }}
597
598
  </p>
598
599
 
@@ -600,7 +601,7 @@ function setSize(value: InstanceSize) {
600
601
  <li
601
602
  v-for="(n, i) in detectResult.notes"
602
603
  :key="i"
603
- class="flex items-start gap-1.5 text-[11px] leading-snug text-dimmed"
604
+ class="flex items-start gap-1.5 text-2xs leading-snug text-dimmed"
604
605
  >
605
606
  <span
606
607
  :class="
@@ -622,7 +623,7 @@ function setSize(value: InstanceSize) {
622
623
 
623
624
  <div v-if="provisionType === 'docker-compose'" class="space-y-2">
624
625
  <div class="space-y-1">
625
- <label class="text-[11px] text-muted">{{ t('inspector.testConfig.composePath') }}</label>
626
+ <label class="text-2xs text-muted">{{ t('inspector.testConfig.composePath') }}</label>
626
627
  <div class="flex items-center gap-1">
627
628
  <UInput
628
629
  :model-value="composePath"
@@ -634,17 +635,17 @@ function setSize(value: InstanceSize) {
634
635
  (e: KeyboardEvent) => setComposePath((e.target as HTMLInputElement).value)
635
636
  "
636
637
  />
637
- <UButton
638
+ <IconButton
638
639
  v-if="repoContext"
639
640
  size="xs"
640
641
  variant="soft"
641
642
  color="neutral"
642
643
  icon="i-lucide-folder-search"
643
- :title="t('inspector.testConfig.browseRepo')"
644
+ :label="t('inspector.testConfig.browseRepo')"
644
645
  @click="openBrowse('compose')"
645
646
  />
646
647
  </div>
647
- <p class="text-[11px] leading-snug text-dimmed">
648
+ <p class="text-2xs leading-snug text-dimmed">
648
649
  {{ t('inspector.testConfig.composeHint') }}
649
650
  </p>
650
651
  </div>
@@ -660,9 +661,7 @@ function setSize(value: InstanceSize) {
660
661
  connection (the "how") is configured per-type in the Infrastructure window. -->
661
662
  <div v-if="provisionType === 'kubernetes'" class="space-y-2">
662
663
  <div class="space-y-1">
663
- <span class="text-[11px] text-muted">{{
664
- t('inspector.testConfig.manifestSourceLabel')
665
- }}</span>
664
+ <span class="text-2xs text-muted">{{ t('inspector.testConfig.manifestSourceLabel') }}</span>
666
665
  <div class="flex flex-wrap gap-1">
667
666
  <UButton
668
667
  :color="kubeSourceType === 'colocated' ? 'primary' : 'neutral'"
@@ -684,7 +683,7 @@ function setSize(value: InstanceSize) {
684
683
  </div>
685
684
 
686
685
  <div v-if="kubeSourceType === 'separate'" class="space-y-1">
687
- <label class="text-[11px] text-muted">{{ t('inspector.testConfig.manifestRepo') }}</label>
686
+ <label class="text-2xs text-muted">{{ t('inspector.testConfig.manifestRepo') }}</label>
688
687
  <UInput
689
688
  :model-value="kubeRepo"
690
689
  size="xs"
@@ -695,7 +694,7 @@ function setSize(value: InstanceSize) {
695
694
  />
696
695
  </div>
697
696
  <div v-if="kubeSourceType === 'separate'" class="space-y-1">
698
- <label class="text-[11px] text-muted">{{ t('inspector.testConfig.manifestRef') }}</label>
697
+ <label class="text-2xs text-muted">{{ t('inspector.testConfig.manifestRef') }}</label>
699
698
  <UInput
700
699
  :model-value="kubeRef"
701
700
  size="xs"
@@ -707,7 +706,7 @@ function setSize(value: InstanceSize) {
707
706
  </div>
708
707
 
709
708
  <div class="space-y-1">
710
- <label class="text-[11px] text-muted">{{ t('inspector.testConfig.manifestPath') }}</label>
709
+ <label class="text-2xs text-muted">{{ t('inspector.testConfig.manifestPath') }}</label>
711
710
  <div class="flex items-center gap-1">
712
711
  <UInput
713
712
  :model-value="kubePath"
@@ -717,23 +716,23 @@ function setSize(value: InstanceSize) {
717
716
  @blur="(e: FocusEvent) => setKubePath((e.target as HTMLInputElement).value)"
718
717
  @keydown.enter="(e: KeyboardEvent) => setKubePath((e.target as HTMLInputElement).value)"
719
718
  />
720
- <UButton
719
+ <IconButton
721
720
  v-if="repoContext && kubeSourceType === 'colocated'"
722
721
  size="xs"
723
722
  variant="soft"
724
723
  color="neutral"
725
724
  icon="i-lucide-folder-search"
726
- :title="t('inspector.testConfig.browseRepo')"
725
+ :label="t('inspector.testConfig.browseRepo')"
727
726
  @click="openBrowse('k8s')"
728
727
  />
729
728
  </div>
730
- <p class="text-[11px] leading-snug text-dimmed">
729
+ <p class="text-2xs leading-snug text-dimmed">
731
730
  {{ t('inspector.testConfig.manifestPathHint') }}
732
731
  </p>
733
732
  </div>
734
733
 
735
734
  <div class="space-y-1">
736
- <span class="text-[11px] text-muted">{{ t('inspector.testConfig.rendererLabel') }}</span>
735
+ <span class="text-2xs text-muted">{{ t('inspector.testConfig.rendererLabel') }}</span>
737
736
  <div class="flex flex-wrap gap-1">
738
737
  <UButton
739
738
  v-for="r in RENDERERS"
@@ -746,7 +745,7 @@ function setSize(value: InstanceSize) {
746
745
  {{ r.label }}
747
746
  </UButton>
748
747
  </div>
749
- <p class="text-[11px] leading-snug text-dimmed">
748
+ <p class="text-2xs leading-snug text-dimmed">
750
749
  {{ t('inspector.testConfig.rendererHint') }}
751
750
  </p>
752
751
  </div>
@@ -756,7 +755,7 @@ function setSize(value: InstanceSize) {
756
755
  source), the per-PR recipe lives in the target repository's own preview workflow, so
757
756
  declaring the type IS the whole service-side configuration. Say so explicitly rather
758
757
  than rendering an empty panel that reads like something failed to load. -->
759
- <p v-if="provisionType === 'cloudflare'" class="text-[11px] text-dimmed">
758
+ <p v-if="provisionType === 'cloudflare'" class="text-2xs text-dimmed">
760
759
  {{ t('inspector.testConfig.cloudflareHint') }}
761
760
  </p>
762
761
 
@@ -764,9 +763,7 @@ function setSize(value: InstanceSize) {
764
763
  handler the workspace configures). -->
765
764
  <div v-if="provisionType === 'custom'" class="space-y-2">
766
765
  <div class="space-y-1">
767
- <label class="text-[11px] text-muted">{{
768
- t('inspector.testConfig.customManifestId')
769
- }}</label>
766
+ <label class="text-2xs text-muted">{{ t('inspector.testConfig.customManifestId') }}</label>
770
767
  <USelect
771
768
  v-if="customTypeItems.length"
772
769
  :model-value="customManifestId"
@@ -776,15 +773,15 @@ function setSize(value: InstanceSize) {
776
773
  :placeholder="t('inspector.testConfig.customManifestIdPlaceholder')"
777
774
  @update:model-value="(v: string) => setCustomManifestId(v)"
778
775
  />
779
- <p v-else class="text-[11px] leading-snug text-app-warning-300/80">
776
+ <p v-else class="text-2xs leading-snug text-app-warning-300/80">
780
777
  {{ t('inspector.testConfig.customNoTypes') }}
781
778
  </p>
782
- <p class="text-[11px] leading-snug text-dimmed">
779
+ <p class="text-2xs leading-snug text-dimmed">
783
780
  {{ t('inspector.testConfig.customManifestIdHint') }}
784
781
  </p>
785
782
  </div>
786
783
  <div class="space-y-1">
787
- <label class="text-[11px] text-muted">{{
784
+ <label class="text-2xs text-muted">{{
788
785
  t('inspector.testConfig.customManifestPath')
789
786
  }}</label>
790
787
  <UInput
@@ -796,7 +793,7 @@ function setSize(value: InstanceSize) {
796
793
  (e: KeyboardEvent) => setCustomManifestPath((e.target as HTMLInputElement).value)
797
794
  "
798
795
  />
799
- <p class="text-[11px] leading-snug text-dimmed">
796
+ <p class="text-2xs leading-snug text-dimmed">
800
797
  {{ t('inspector.testConfig.customManifestPathHint') }}
801
798
  </p>
802
799
  </div>
@@ -805,10 +802,10 @@ function setSize(value: InstanceSize) {
805
802
  shown when the selected type declares a fixer prompt. -->
806
803
  <div
807
804
  v-if="manifestFixerAvailable && repoContext"
808
- class="space-y-1.5 rounded border border-default bg-default/40 p-2"
805
+ class="space-y-1.5 rounded-sm border border-default bg-default/40 p-2"
809
806
  >
810
807
  <div class="flex items-center justify-between gap-2">
811
- <span class="text-[11px] text-muted">{{
808
+ <span class="text-2xs text-muted">{{
812
809
  t('inspector.testConfig.generateManifest.title')
813
810
  }}</span>
814
811
  <UButton
@@ -823,15 +820,15 @@ function setSize(value: InstanceSize) {
823
820
  {{ t('inspector.testConfig.generateManifest.button') }}
824
821
  </UButton>
825
822
  </div>
826
- <p class="text-[11px] leading-snug text-dimmed">
823
+ <p class="text-2xs leading-snug text-dimmed">
827
824
  {{ t('inspector.testConfig.generateManifest.hint') }}
828
825
  </p>
829
- <p v-if="manifestRepairError" class="text-[11px] text-app-error-300/80">
826
+ <p v-if="manifestRepairError" class="text-2xs text-app-error-300/80">
830
827
  {{ t('inspector.testConfig.generateManifest.error') }}
831
828
  </p>
832
829
  <p
833
830
  v-else-if="manifestRepairJob"
834
- class="text-[11px]"
831
+ class="text-2xs"
835
832
  :class="{
836
833
  'text-app-info-300/80': manifestRepairJob.status === 'running',
837
834
  'text-app-success-300/80': manifestRepairJob.status === 'succeeded',
@@ -840,7 +837,7 @@ function setSize(value: InstanceSize) {
840
837
  >
841
838
  {{ t(`inspector.testConfig.generateManifest.status.${manifestRepairJob.status}`) }}
842
839
  </p>
843
- <p v-else-if="manifestRepairJobId" class="text-[11px] text-app-info-300/80">
840
+ <p v-else-if="manifestRepairJobId" class="text-2xs text-app-info-300/80">
844
841
  {{ t('inspector.testConfig.generateManifest.dispatched') }}
845
842
  </p>
846
843
  </div>
@@ -896,7 +893,7 @@ function setSize(value: InstanceSize) {
896
893
  :hint="t('inspector.testConfig.provisioningHint')"
897
894
  >
898
895
  <div class="space-y-1">
899
- <span class="text-[11px] text-muted">{{ t('inspector.testConfig.cloudProvider') }}</span>
896
+ <span class="text-2xs text-muted">{{ t('inspector.testConfig.cloudProvider') }}</span>
900
897
  <div class="flex flex-wrap gap-1">
901
898
  <UButton
902
899
  v-for="p in PROVIDERS"
@@ -912,7 +909,7 @@ function setSize(value: InstanceSize) {
912
909
  </div>
913
910
 
914
911
  <div class="space-y-1">
915
- <span class="text-[11px] text-muted">{{ t('inspector.testConfig.instanceSize') }}</span>
912
+ <span class="text-2xs text-muted">{{ t('inspector.testConfig.instanceSize') }}</span>
916
913
  <div class="flex flex-wrap gap-1">
917
914
  <UButton
918
915
  v-for="s in SIZES"
@@ -165,13 +165,13 @@ async function clearAll() {
165
165
 
166
166
  <!-- These are REAL secrets: an unmistakable sensitivity + replace-all warning. -->
167
167
  <div
168
- class="flex items-start gap-2 rounded-md border border-app-warning-500/40 bg-app-warning-500/10 px-2.5 py-2 text-[11px] leading-snug text-app-warning-200"
168
+ class="flex items-start gap-2 rounded-md border border-app-warning-500/40 bg-app-warning-500/10 px-2.5 py-2 text-2xs leading-snug text-app-warning-200"
169
169
  >
170
170
  <UIcon name="i-lucide-shield-alert" class="mt-0.5 h-4 w-4 shrink-0 text-app-warning-400" />
171
171
  <span>{{ t('inspector.testSecrets.warning') }}</span>
172
172
  </div>
173
173
 
174
- <p class="text-[11px] leading-snug text-dimmed">
174
+ <p class="text-2xs leading-snug text-dimmed">
175
175
  {{ t('inspector.testSecrets.replaceNote') }}
176
176
  </p>
177
177
 
@@ -234,7 +234,7 @@ async function clearAll() {
234
234
  </UFormField>
235
235
  </div>
236
236
 
237
- <p v-if="duplicateKeys.size" class="text-[11px] text-app-error-400">
237
+ <p v-if="duplicateKeys.size" class="text-2xs text-app-error-400">
238
238
  {{ t('inspector.testSecrets.duplicateKey') }}
239
239
  </p>
240
240
 
@@ -89,7 +89,7 @@ function revert() {
89
89
  >
90
90
  <!-- This text reaches the model in the prompt, so it must never hold a real secret. -->
91
91
  <div
92
- class="flex items-start gap-2 rounded-md border border-muted bg-elevated/40 px-2.5 py-2 text-[11px] leading-snug text-toned"
92
+ class="flex items-start gap-2 rounded-md border border-muted bg-elevated/40 px-2.5 py-2 text-2xs leading-snug text-toned"
93
93
  >
94
94
  <UIcon name="i-lucide-info" class="mt-0.5 h-4 w-4 shrink-0 text-muted" />
95
95
  <span>{{ t('inspector.testingContext.notSecret') }}</span>
@@ -104,7 +104,7 @@ function revert() {
104
104
  />
105
105
 
106
106
  <div class="flex items-center justify-between gap-2">
107
- <p class="text-[11px] text-dimmed" :class="{ 'text-app-error-400': tooLong }">
107
+ <p class="text-2xs text-dimmed" :class="{ 'text-app-error-400': tooLong }">
108
108
  {{
109
109
  t('inspector.testingContext.length', {
110
110
  count: outgoing.length,