@cat-factory/app 0.310.2 → 0.310.3

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 (35) hide show
  1. package/README.md +16 -10
  2. package/app/components/documents/DocumentSourceConnectModal.vue +1 -1
  3. package/app/components/foundational/FoundationalServiceCatalogList.vue +2 -0
  4. package/app/components/foundational/FoundationalServiceRegistry.vue +9 -2
  5. package/app/components/foundational/FoundationalServiceSources.vue +2 -0
  6. package/app/components/foundational/FoundationalSuppressions.vue +1 -0
  7. package/app/components/fragments/FragmentLibraryManager.vue +4 -0
  8. package/app/components/github/RepoTreeBrowser.vue +3 -0
  9. package/app/components/guidedReview/GuidedReviewDraftCard.vue +16 -4
  10. package/app/components/guidedReview/GuidedReviewModal.vue +1 -0
  11. package/app/components/guidedReview/GuidedReviewOverview.vue +1 -0
  12. package/app/components/humanTest/HumanTestWindow.vue +3 -2
  13. package/app/components/initiative/InitiativePlanningWindow.vue +1 -1
  14. package/app/components/judge/JudgeResultView.vue +1 -0
  15. package/app/components/layout/AccountDeploymentSettings.vue +8 -8
  16. package/app/components/layout/AccountTeamSettings.vue +1 -1
  17. package/app/components/panels/AgentStepDetail.vue +2 -0
  18. package/app/components/panels/InspectorPanel.vue +1 -1
  19. package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +1 -1
  20. package/app/components/panels/inspector/ServiceTestSecrets.vue +1 -1
  21. package/app/components/panels/inspector/ServiceValidationConfig.vue +1 -1
  22. package/app/components/panels/inspector/TaskExecution.vue +1 -1
  23. package/app/components/pipeline/PipelineBuilder.vue +1 -1
  24. package/app/components/pipeline/PipelineHealthModal.vue +2 -2
  25. package/app/components/provisioning/ProvisioningLogsDrawer.vue +1 -0
  26. package/app/components/sandbox/SandboxPanel.vue +1 -0
  27. package/app/components/settings/InfraHandlersConfigurator.vue +1 -1
  28. package/app/components/settings/ProviderConnectionTab.vue +1 -0
  29. package/app/components/settings/ToolServerChecklist.vue +1 -1
  30. package/app/components/skills/SkillLibraryManager.vue +2 -0
  31. package/app/components/slack/SlackPanel.vue +1 -1
  32. package/app/components/tasks/TaskSourceConnectModal.vue +1 -1
  33. package/app/components/testing/TestReportWindow.vue +2 -0
  34. package/app/components/visualConfirm/VisualConfirmationWindow.vue +1 -0
  35. package/package.json +1 -1
package/README.md CHANGED
@@ -334,16 +334,22 @@ Every CONTROL in the SPA is the Nuxt UI component for it, never the raw HTML ele
334
334
 
335
335
  What a primary, a secondary or a destructive action looks like is decided once, here, and not per call site. The weights are Nuxt UI's own [variant table](https://github.com/nuxt/ui/blob/v4/skills/nuxt-ui/references/design-system.md) (`solid` highest, then `outline`, `soft`, `subtle`, `ghost`, and `link` for a text link inside content), mapped onto the app's kinds of action:
336
336
 
337
- | Kind | Props |
338
- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------- |
339
- | Primary action, ONE per view | none (the default, `primary solid`) |
340
- | Secondary action in a dialog footer or a window header | `color="neutral" variant="outline"` |
341
- | Inline, navigation and chrome actions | `color="neutral" variant="ghost"`, usually with `size="xs"` |
342
- | Icon-only action | `IconButton` with `color="neutral" variant="ghost"` |
343
- | Destructive action | `color="error" variant="soft"`; `color="error"` alone (solid) only as the confirm of a dialog |
344
- | Status chip | `UBadge` with `variant="subtle" size="sm"`, and a `BadgeColor` map for the colour |
345
-
346
- - **The defaults are Nuxt UI's own**: `primary solid md` for both `UButton` and `UBadge`, stated in `app.config.ts` (`ui.button.defaultVariants`, `ui.badge.defaultVariants`) so the value has one visible home and the guard can read it. A call site states only what DIFFERS. Sibling buttons never mix variants.
337
+ | Kind | Props |
338
+ | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
339
+ | Primary action, ONE per view | none (the default, `primary solid`) |
340
+ | Dismissal in a dialog or form (Cancel, Close) | `color="neutral" variant="ghost"` |
341
+ | Real secondary action (Save draft, Back) | `color="neutral" variant="outline"` |
342
+ | Bulk action in a dialog footer, beside Close (Reseed all, Update all) | `variant="ghost"` (primary colour): the dialog's main action, kept light because each row above it has its own button |
343
+ | Send-back on a gate (bounce, request a fix) | `color="warning" variant="soft"`, so the approve beside it stays the one primary |
344
+ | Inline, navigation and chrome actions | `color="neutral" variant="ghost"`, usually with `size="xs"` |
345
+ | Icon-only action | `IconButton` with `color="neutral" variant="ghost"` |
346
+ | Destructive action, labelled | `color="error" variant="soft"`; `color="error"` alone (solid) only as the confirm step of a destructive action (a dialog's confirm, or an armed inline confirm such as a step's reject) |
347
+ | Destructive action, icon-only (a row's trash icon) | `IconButton` with `color="error" variant="ghost"` |
348
+ | A banner's call to action | solid, in the banner's colour (`color="warning"`, `color="error"`) |
349
+ | Status chip | `UBadge` with `variant="subtle" size="sm"`, and a `BadgeColor` map for the colour |
350
+
351
+ - **The defaults are Nuxt UI's own**: `primary solid md` for both `UButton` and `UBadge`, stated in `app.config.ts` (`ui.button.defaultVariants`, `ui.badge.defaultVariants`) so the value has one visible home and the guard can read it. A call site states only what DIFFERS.
352
+ - **One solid button per view.** Two solid buttons side by side compete for the same attention, so the second action takes a lighter variant from the table. The guard refuses two solid buttons under one parent element; it counts a `v-if` chain as one button and a `v-for` list as one, looks through a plain `<template>` wrapper, and treats a slot `<template #name>` as its own region. A file holding several forms that each end in a Save is several views and passes. A site that genuinely needs two says why with a `solid-ok:` comment on its own line, directly above the second button.
347
353
  - **The unstyled group is the one a theme restyles, so it is the primary tier.** A theme document's `style.defaults` (a size, a button variant, a button colour) REPLACES the default for every control that does not state that prop; it does not scale or shift the others. So whichever group is unstyled is the group a theme moves. With the primary actions unstyled, a theme with `size: 'lg'` or `variants: { buttons: 'outline' }` restyles the actions and leaves the chrome alone. With the quiet chrome unstyled, the same theme would grow or fill every toolbar and icon button past the actions and invert the hierarchy. This is why the dense, quiet chrome carries its props and the primary action carries none, and why Nuxt UI's own internal buttons (a modal's close button, a toast's actions) agree with the app's.
348
354
  - **A restated default is a bug, not noise.** It pins the value against a theme that changes the default, and it hides which props are the reason a control looks the way it does. `scripts/check-frontend-variants.mjs` (CI) refuses a value equal to the default on `UButton` and `UBadge` (either casing, either quote style, or a key of a `v-bind="{ … }"` object) and on every component that spreads its attributes into one (`IconButton`; the list is derived, so a new wrapper is covered), reading the defaults from `app.config.ts` itself. Inside a `UFieldGroup` or `UButtonGroup` it does not check `size`: the group sets the size there, so an explicit `size` overrides the group rather than restating the default. It reads template tags only, so a `ButtonProps` object (a toast's `actions`, a modal's `:close`) is not checked. A site that must keep a literal says why with a `variant-default-ok:` comment on its own line, directly above the tag; it waives that tag only.
349
355
 
@@ -157,7 +157,7 @@ async function disconnect() {
157
157
  <UButton
158
158
  v-if="connected"
159
159
  color="error"
160
- variant="ghost"
160
+ variant="soft"
161
161
  icon="i-lucide-unplug"
162
162
  @click="disconnect"
163
163
  >
@@ -105,6 +105,7 @@ async function suppress(serviceId: string) {
105
105
 
106
106
  <div class="mt-2 flex items-center gap-2">
107
107
  <UButton
108
+ color="neutral"
108
109
  v-if="s.contracts.length"
109
110
  size="xs"
110
111
  variant="ghost"
@@ -141,6 +142,7 @@ async function suppress(serviceId: string) {
141
142
  deployment registered in code; the board's own row is managed in the registry tab,
142
143
  where deleting it is the honest action. -->
143
144
  <IconButton
145
+ color="neutral"
144
146
  v-if="s.tier !== 'workspace'"
145
147
  icon="i-lucide-eye-off"
146
148
  size="xs"
@@ -205,6 +205,7 @@ async function remove(service: FoundationalService) {
205
205
  </div>
206
206
  <div class="flex shrink-0 gap-1">
207
207
  <IconButton
208
+ color="neutral"
208
209
  v-if="!s.sourceId"
209
210
  icon="i-lucide-pencil"
210
211
  size="xs"
@@ -310,7 +311,13 @@ async function remove(service: FoundationalService) {
310
311
  :placeholder="t('foundational.registry.contractBodyPlaceholder')"
311
312
  />
312
313
  </div>
313
- <UButton icon="i-lucide-plus" size="xs" variant="ghost" @click="addContract">
314
+ <UButton
315
+ color="neutral"
316
+ icon="i-lucide-plus"
317
+ size="xs"
318
+ variant="ghost"
319
+ @click="addContract"
320
+ >
314
321
  {{ t('foundational.registry.addContract') }}
315
322
  </UButton>
316
323
  </div>
@@ -325,7 +332,7 @@ async function remove(service: FoundationalService) {
325
332
  >
326
333
  {{ t('foundational.registry.save') }}
327
334
  </UButton>
328
- <UButton size="sm" variant="ghost" @click="editing = null">
335
+ <UButton color="neutral" size="sm" variant="ghost" @click="editing = null">
329
336
  {{ t('foundational.registry.cancel') }}
330
337
  </UButton>
331
338
  </div>
@@ -297,6 +297,7 @@ async function unlink(id: string) {
297
297
  </UBadge>
298
298
  <div class="ms-auto flex gap-1">
299
299
  <IconButton
300
+ color="neutral"
300
301
  icon="i-lucide-search-check"
301
302
  size="xs"
302
303
  variant="ghost"
@@ -305,6 +306,7 @@ async function unlink(id: string) {
305
306
  @click="check(s.id)"
306
307
  />
307
308
  <IconButton
309
+ color="neutral"
308
310
  icon="i-lucide-refresh-cw"
309
311
  size="xs"
310
312
  variant="ghost"
@@ -81,6 +81,7 @@ async function restore(serviceId: string) {
81
81
  </p>
82
82
  </div>
83
83
  <UButton
84
+ color="neutral"
84
85
  icon="i-lucide-eye"
85
86
  size="xs"
86
87
  variant="ghost"
@@ -752,6 +752,7 @@ async function unlinkSource(id: string) {
752
752
  <!-- Editing a repo-SOURCED fragment locally would be overwritten on the next sync,
753
753
  so only hand-authored fragments are editable here. -->
754
754
  <IconButton
755
+ color="neutral"
755
756
  v-if="!f.source"
756
757
  icon="i-lucide-pencil"
757
758
  size="xs"
@@ -868,6 +869,7 @@ async function unlinkSource(id: string) {
868
869
  </div>
869
870
  <div class="ms-auto flex gap-1">
870
871
  <IconButton
872
+ color="neutral"
871
873
  icon="i-lucide-refresh-cw"
872
874
  size="xs"
873
875
  variant="ghost"
@@ -1026,6 +1028,7 @@ async function unlinkSource(id: string) {
1026
1028
  </UBadge>
1027
1029
  <div class="ms-auto flex gap-1">
1028
1030
  <UButton
1031
+ color="neutral"
1029
1032
  icon="i-lucide-search-check"
1030
1033
  size="xs"
1031
1034
  variant="ghost"
@@ -1033,6 +1036,7 @@ async function unlinkSource(id: string) {
1033
1036
  @click="checkSource(s.id)"
1034
1037
  />
1035
1038
  <UButton
1039
+ color="neutral"
1036
1040
  icon="i-lucide-refresh-cw"
1037
1041
  size="xs"
1038
1042
  variant="ghost"
@@ -207,6 +207,7 @@ watch(
207
207
  class="flex items-center justify-between gap-2 px-3 py-1.5"
208
208
  >
209
209
  <UButton
210
+ color="neutral"
210
211
  variant="ghost"
211
212
  class="flex items-center gap-2 truncate p-0 text-sm text-default hover:bg-transparent hover:text-primary"
212
213
  @click="browseTo(entry.path)"
@@ -257,6 +258,7 @@ watch(
257
258
  @update:model-value="toggleAllFiles"
258
259
  />
259
260
  <UButton
261
+ color="neutral"
260
262
  variant="ghost"
261
263
  class="p-0 text-xs text-muted hover:bg-transparent hover:text-primary"
262
264
  @click="toggleAllFiles"
@@ -283,6 +285,7 @@ watch(
283
285
  @update:model-value="pick(entry.path)"
284
286
  />
285
287
  <UButton
288
+ color="neutral"
286
289
  variant="ghost"
287
290
  class="flex items-center gap-2 truncate p-0 text-sm hover:bg-transparent hover:text-primary"
288
291
  :class="isPicked(entry.path) ? 'text-primary' : 'text-toned'"
@@ -114,7 +114,13 @@ async function discard(): Promise<void> {
114
114
  <UButton size="sm" :loading="saving" @click="save">
115
115
  {{ t('guidedReview.drafts.save') }}
116
116
  </UButton>
117
- <UButton size="sm" variant="ghost" :disabled="saving" @click="editing = false">
117
+ <UButton
118
+ color="neutral"
119
+ size="sm"
120
+ variant="ghost"
121
+ :disabled="saving"
122
+ @click="editing = false"
123
+ >
118
124
  {{ t('guidedReview.drafts.cancel') }}
119
125
  </UButton>
120
126
  </div>
@@ -126,13 +132,19 @@ async function discard(): Promise<void> {
126
132
  {{ t('guidedReview.drafts.postFailed') }}: {{ draft.postError }}
127
133
  </p>
128
134
  <div v-if="editable" class="mt-2 flex gap-2">
129
- <UButton size="xs" variant="ghost" icon="i-lucide-pencil" @click="startEdit">
135
+ <UButton
136
+ color="neutral"
137
+ size="xs"
138
+ variant="ghost"
139
+ icon="i-lucide-pencil"
140
+ @click="startEdit"
141
+ >
130
142
  {{ t('guidedReview.drafts.edit') }}
131
143
  </UButton>
132
144
  <UButton
145
+ color="error"
146
+ variant="soft"
133
147
  size="xs"
134
- variant="ghost"
135
- color="neutral"
136
148
  icon="i-lucide-trash-2"
137
149
  :loading="saving"
138
150
  @click="discard"
@@ -218,6 +218,7 @@ const title = computed(() =>
218
218
  <span class="max-w-48 truncate">{{ threadTitle(tab) }}</span>
219
219
  </UButton>
220
220
  <UButton
221
+ color="neutral"
221
222
  v-if="!draftOpen"
222
223
  size="sm"
223
224
  variant="ghost"
@@ -36,6 +36,7 @@ const SEVERITY_COLOR = { high: 'error', medium: 'warning', low: 'neutral' } as c
36
36
  </UBadge>
37
37
  <span class="flex-1" />
38
38
  <UButton
39
+ color="neutral"
39
40
  size="xs"
40
41
  variant="ghost"
41
42
  icon="i-lucide-refresh-cw"
@@ -223,9 +223,9 @@ const canDestroy = computed(
223
223
  {{ t('humanTest.actions.recreate') }}
224
224
  </UButton>
225
225
  <UButton
226
- size="xs"
226
+ color="error"
227
227
  variant="soft"
228
- color="neutral"
228
+ size="xs"
229
229
  icon="i-lucide-trash-2"
230
230
  :disabled="busy || !canDestroy || !access.canExecuteRuns.value"
231
231
  :title="access.canExecuteRuns.value ? undefined : t('access.noRunExecute')"
@@ -281,6 +281,7 @@ const canDestroy = computed(
281
281
  class="w-full"
282
282
  />
283
283
  <UButton
284
+ variant="soft"
284
285
  size="sm"
285
286
  color="warning"
286
287
  icon="i-lucide-wrench"
@@ -343,7 +343,7 @@ async function onDiscard() {
343
343
  <UButton
344
344
  v-if="canDiscard"
345
345
  color="error"
346
- variant="ghost"
346
+ variant="soft"
347
347
  size="sm"
348
348
  icon="i-lucide-trash-2"
349
349
  :loading="resetting"
@@ -280,6 +280,7 @@ async function act(choice: 'proceed' | 'bounce' | 'stop') {
280
280
  {{ t('judge.stop') }}
281
281
  </UButton>
282
282
  <UButton
283
+ variant="soft"
283
284
  size="sm"
284
285
  color="warning"
285
286
  icon="i-lucide-undo-2"
@@ -483,9 +483,9 @@ async function clearWeb() {
483
483
  {{ t('common.save') }}
484
484
  </UButton>
485
485
  <UButton
486
+ color="error"
487
+ variant="soft"
486
488
  v-if="summary?.slackOAuthConfigured"
487
- color="neutral"
488
- variant="ghost"
489
489
  size="xs"
490
490
  :loading="savingSlack"
491
491
  @click="clearSlack"
@@ -538,9 +538,9 @@ async function clearWeb() {
538
538
  {{ t('common.save') }}
539
539
  </UButton>
540
540
  <UButton
541
+ color="error"
542
+ variant="soft"
541
543
  v-if="summary?.linearOAuthConfigured"
542
- color="neutral"
543
- variant="ghost"
544
544
  size="xs"
545
545
  :loading="savingLinear"
546
546
  @click="clearLinear"
@@ -593,9 +593,9 @@ async function clearWeb() {
593
593
  {{ t('common.save') }}
594
594
  </UButton>
595
595
  <UButton
596
+ color="error"
597
+ variant="soft"
596
598
  v-if="summary?.figmaOAuthConfigured"
597
- color="neutral"
598
- variant="ghost"
599
599
  size="xs"
600
600
  :loading="savingFigma"
601
601
  @click="clearFigma"
@@ -644,9 +644,9 @@ async function clearWeb() {
644
644
  {{ t('common.save') }}
645
645
  </UButton>
646
646
  <UButton
647
+ color="error"
648
+ variant="soft"
647
649
  v-if="summary?.webSearch"
648
- color="neutral"
649
- variant="ghost"
650
650
  size="xs"
651
651
  :loading="savingWeb"
652
652
  @click="clearWeb"
@@ -328,7 +328,7 @@ async function disconnectEmail() {
328
328
  </template>
329
329
  <template #from>{{ accounts.emailConnection.fromAddress }}</template>
330
330
  </i18n-t>
331
- <UButton size="xs" color="error" variant="ghost" :loading="busy" @click="disconnectEmail">
331
+ <UButton size="xs" color="error" variant="soft" :loading="busy" @click="disconnectEmail">
332
332
  {{ t('layout.accountTeam.email.disconnect') }}
333
333
  </UButton>
334
334
  </div>
@@ -657,6 +657,7 @@ async function copyOutput() {
657
657
  provider error, behind a toggle (most useful on a failed-to-start run) -->
658
658
  <div v-if="executionId">
659
659
  <UButton
660
+ color="neutral"
660
661
  :icon="showProvisioning ? 'i-lucide-chevron-up' : 'i-lucide-scroll-text'"
661
662
  variant="ghost"
662
663
  size="xs"
@@ -685,6 +686,7 @@ async function copyOutput() {
685
686
  superseded and the FAILED attempts, scoped to the step being looked at -->
686
687
  <div v-if="hasStepHistory">
687
688
  <UButton
689
+ color="neutral"
688
690
  :icon="showHistory ? 'i-lucide-chevron-up' : 'i-lucide-history'"
689
691
  variant="ghost"
690
692
  size="xs"
@@ -678,7 +678,7 @@ const showOriginalDescription = ref(false)
678
678
  </UButton>
679
679
  <UButton
680
680
  color="error"
681
- variant="ghost"
681
+ variant="soft"
682
682
  size="sm"
683
683
  icon="i-lucide-trash-2"
684
684
  :class="isServiceFrame ? '' : 'ms-auto'"
@@ -101,7 +101,7 @@ async function clear() {
101
101
  <UButton
102
102
  v-if="saved"
103
103
  color="error"
104
- variant="ghost"
104
+ variant="soft"
105
105
  size="xs"
106
106
  icon="i-lucide-trash-2"
107
107
  :loading="busy"
@@ -152,7 +152,7 @@ async function clearAll() {
152
152
  <UButton
153
153
  v-if="configured.length"
154
154
  color="error"
155
- variant="ghost"
155
+ variant="soft"
156
156
  size="xs"
157
157
  icon="i-lucide-trash-2"
158
158
  :loading="busy"
@@ -209,7 +209,7 @@ async function clear() {
209
209
  <UButton
210
210
  v-if="configured"
211
211
  color="error"
212
- variant="ghost"
212
+ variant="soft"
213
213
  size="xs"
214
214
  icon="i-lucide-trash-2"
215
215
  :loading="busy"
@@ -347,7 +347,7 @@ async function mergePr() {
347
347
  <UButton
348
348
  icon="i-lucide-trash-2"
349
349
  color="error"
350
- variant="ghost"
350
+ variant="soft"
351
351
  size="xs"
352
352
  :loading="resetting"
353
353
  :disabled="stopping || !access.canExecuteRuns.value"
@@ -1340,7 +1340,7 @@ const { toggleArchive, toggleDefault, edit, removePipeline, clone } = usePipelin
1340
1340
  <IconButton
1341
1341
  v-if="!p.builtin"
1342
1342
  icon="i-lucide-trash-2"
1343
- color="neutral"
1343
+ color="error"
1344
1344
  variant="ghost"
1345
1345
  size="xs"
1346
1346
  :label="t('pipeline.builder.delete')"
@@ -218,7 +218,7 @@ const reseedableCount = computed(
218
218
  v-else
219
219
  size="xs"
220
220
  color="error"
221
- variant="subtle"
221
+ variant="soft"
222
222
  icon="i-lucide-trash-2"
223
223
  :loading="isBusy(h.pipeline.id)"
224
224
  :disabled="locked"
@@ -259,7 +259,7 @@ const reseedableCount = computed(
259
259
  <UButton
260
260
  size="xs"
261
261
  color="error"
262
- variant="subtle"
262
+ variant="soft"
263
263
  icon="i-lucide-trash-2"
264
264
  :loading="isBusy(r.pipeline.id)"
265
265
  :disabled="locked"
@@ -120,6 +120,7 @@ function when(epochMs: number): string {
120
120
  {{ t('provisioning.title') }}
121
121
  </SectionLabel>
122
122
  <UButton
123
+ color="neutral"
123
124
  icon="i-lucide-rotate-ccw"
124
125
  variant="ghost"
125
126
  size="xs"
@@ -629,6 +629,7 @@ async function archive(prompt: SandboxPromptVersion) {
629
629
  Offered on a graded candidate and on an older workspace revision (rolling
630
630
  back), but not on the one already live, where it would be a no-op. -->
631
631
  <IconButton
632
+ color="neutral"
632
633
  v-if="canPromote(p)"
633
634
  icon="i-lucide-rocket"
634
635
  variant="ghost"
@@ -540,7 +540,7 @@ function toastRemoved() {
540
540
  <UButton
541
541
  icon="i-lucide-trash-2"
542
542
  color="error"
543
- variant="ghost"
543
+ variant="soft"
544
544
  size="xs"
545
545
  :disabled="busy"
546
546
  @click="removeKubeOverride"
@@ -356,6 +356,7 @@ function fieldHelp(key: string): string | undefined {
356
356
  <div class="flex items-start justify-between gap-3">
357
357
  <p class="text-xs text-muted">{{ blurb }}</p>
358
358
  <UButton
359
+ color="neutral"
359
360
  :icon="showLogs ? 'i-lucide-chevron-up' : 'i-lucide-scroll-text'"
360
361
  variant="ghost"
361
362
  size="xs"
@@ -242,7 +242,7 @@ async function runProbe(id: string) {
242
242
  <UButton
243
243
  v-if="server.oauth.connected"
244
244
  size="xs"
245
- variant="ghost"
245
+ variant="soft"
246
246
  color="error"
247
247
  :loading="store.connecting === server.id"
248
248
  :disabled="store.connecting !== null"
@@ -236,6 +236,7 @@ async function unlinkSource(id: string) {
236
236
  </UBadge>
237
237
  <div class="ms-auto flex gap-1">
238
238
  <IconButton
239
+ color="neutral"
239
240
  icon="i-lucide-search-check"
240
241
  size="xs"
241
242
  variant="ghost"
@@ -244,6 +245,7 @@ async function unlinkSource(id: string) {
244
245
  @click="checkSource(s.id)"
245
246
  />
246
247
  <IconButton
248
+ color="neutral"
247
249
  icon="i-lucide-refresh-cw"
248
250
  size="xs"
249
251
  variant="ghost"
@@ -257,7 +257,7 @@ async function saveMapping() {
257
257
  </span>
258
258
  <UButton
259
259
  color="error"
260
- variant="ghost"
260
+ variant="soft"
261
261
  size="xs"
262
262
  icon="i-lucide-unplug"
263
263
  @click="disconnect"
@@ -193,7 +193,7 @@ async function toggleEnabled(enabled: boolean) {
193
193
  <UButton
194
194
  v-if="connected"
195
195
  color="error"
196
- variant="ghost"
196
+ variant="soft"
197
197
  icon="i-lucide-unplug"
198
198
  @click="disconnect"
199
199
  >
@@ -438,6 +438,7 @@ const GROUP_STATUS_META: Record<ScenarioGroup['status'], { icon: string; text: s
438
438
  </p>
439
439
  <template v-if="infraSetup.logs">
440
440
  <UButton
441
+ color="neutral"
441
442
  :icon="showInfraSetupLogs ? 'i-lucide-chevron-up' : 'i-lucide-scroll-text'"
442
443
  variant="ghost"
443
444
  size="xs"
@@ -476,6 +477,7 @@ const GROUP_STATUS_META: Record<ScenarioGroup['status'], { icon: string; text: s
476
477
 
477
478
  <div v-if="executionId">
478
479
  <UButton
480
+ color="neutral"
479
481
  :icon="showProvisioning ? 'i-lucide-chevron-up' : 'i-lucide-scroll-text'"
480
482
  variant="ghost"
481
483
  size="xs"
@@ -406,6 +406,7 @@ watch(pendingUpload, async (file) => {
406
406
  {{ t('visualConfirm.requestFix.foldedHint') }}
407
407
  </span>
408
408
  <UButton
409
+ variant="soft"
409
410
  size="sm"
410
411
  color="warning"
411
412
  icon="i-lucide-wrench"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/app",
3
- "version": "0.310.2",
3
+ "version": "0.310.3",
4
4
  "description": "Reusable Nuxt layer for the Agent Architecture Board SPA (components, stores, composables, pages). Consume it from a thin deployment app via `extends: ['@cat-factory/app']` and point it at your backend with NUXT_PUBLIC_API_BASE. See deploy/frontend for an example.",
5
5
  "repository": {
6
6
  "type": "git",