@cat-factory/app 0.311.2 → 0.311.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.
- package/README.md +65 -4
- package/app/app.config.ts +7 -0
- package/app/components/assistant/AssistantModal.vue +2 -5
- package/app/components/auth/AuthGate.vue +2 -1
- package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +14 -15
- package/app/components/binaryOutput/StoredAssetView.vue +1 -3
- package/app/components/board/AddTaskModal.vue +3 -10
- package/app/components/board/AgentFailureCard.vue +4 -5
- package/app/components/board/AgentStopButton.vue +5 -7
- package/app/components/board/BoardCanvas.vue +31 -30
- package/app/components/board/CreateInitiativeModal.vue +2 -4
- package/app/components/board/RecurringPipelineModal.vue +2 -7
- package/app/components/board/nodes/AgentChip.vue +3 -2
- package/app/components/board/nodes/BlockNode.vue +14 -11
- package/app/components/board/nodes/InitiativeCard.vue +6 -3
- package/app/components/bootstrap/AdoptionReviewModal.vue +2 -5
- package/app/components/bootstrap/BootstrapModal.vue +6 -15
- package/app/components/bootstrap/BootstrapRunSteps.vue +3 -1
- package/app/components/brainstorm/BrainstormWindow.vue +32 -26
- package/app/components/bugFishing/BugFishingWindow.vue +15 -13
- package/app/components/clarity/ClarityReviewWindow.vue +31 -26
- package/app/components/common/ClarificationItem.vue +3 -1
- package/app/components/common/EmptyState.vue +41 -19
- package/app/components/common/InterviewGateNotice.vue +3 -1
- package/app/components/common/Spinner.vue +28 -0
- package/app/components/consensus/ConsensusSessionWindow.vue +5 -5
- package/app/components/docs/DocInterviewWindow.vue +6 -6
- package/app/components/documents/ContextDocumentPicker.vue +2 -2
- package/app/components/documents/DocumentImportModal.vue +9 -8
- package/app/components/documents/DocumentSourceConnectModal.vue +10 -10
- package/app/components/documents/DocumentTemplatesModal.vue +13 -7
- package/app/components/documents/RepoContextDocPicker.vue +2 -2
- package/app/components/documents/SpawnPreviewModal.vue +4 -6
- package/app/components/documents/StartFromDesignModal.vue +2 -1
- package/app/components/documents/TaskContextDocs.vue +4 -5
- package/app/components/environments/EnvironmentStatusPanel.vue +11 -8
- package/app/components/environments/steps/EnvPickStep.vue +7 -3
- package/app/components/environments/steps/EnvPreflightStep.vue +6 -5
- package/app/components/focus/BlockFocusView.vue +6 -5
- package/app/components/followUp/FollowUpWindow.vue +7 -9
- package/app/components/forkDecision/ForkDecisionWindow.vue +9 -8
- package/app/components/foundational/FoundationalServiceCatalogList.vue +9 -5
- package/app/components/foundational/FoundationalServiceRegistry.vue +11 -7
- package/app/components/foundational/FoundationalServiceSources.vue +20 -22
- package/app/components/foundational/FoundationalSuppressions.vue +2 -2
- package/app/components/foundational/ServiceCatalogConnection.vue +15 -15
- package/app/components/fragments/FragmentLibraryManager.vue +36 -34
- package/app/components/fragments/FragmentSelector.vue +7 -3
- package/app/components/gates/GateResultView.vue +6 -9
- package/app/components/github/AddServiceFromRepoModal.vue +6 -10
- package/app/components/github/GitHubConnect.vue +10 -17
- package/app/components/github/GitHubPanel.vue +44 -47
- package/app/components/github/RepoTreeBrowser.vue +9 -5
- package/app/components/guidedReview/GuidedReviewModal.vue +16 -6
- package/app/components/guidedReview/GuidedReviewOverview.vue +2 -1
- package/app/components/guidedReview/GuidedReviewPicker.vue +10 -7
- package/app/components/guidedReview/GuidedReviewThread.vue +9 -4
- package/app/components/humanTest/HumanTestWindow.vue +2 -1
- package/app/components/initiative/InitiativePlanningWindow.vue +6 -6
- package/app/components/initiative/InitiativeTrackerWindow.vue +11 -11
- package/app/components/judge/JudgeResultView.vue +2 -7
- package/app/components/kaizen/KaizenPanel.vue +20 -5
- package/app/components/kaizen/KaizenStepStatus.vue +2 -1
- package/app/components/layout/AccountAuditLog.vue +11 -3
- package/app/components/layout/AccountDeploymentSettings.vue +17 -62
- package/app/components/layout/AccountFailureKindRules.vue +6 -5
- package/app/components/layout/AccountModelPolicySettings.vue +2 -6
- package/app/components/layout/AccountPlatformAlertSettings.vue +5 -13
- package/app/components/layout/AccountRiskPolicySettings.vue +13 -14
- package/app/components/layout/AccountRunCredentialSettings.vue +2 -2
- package/app/components/layout/AccountTeamSettings.vue +12 -9
- package/app/components/layout/BoardSwitcher.vue +2 -2
- package/app/components/layout/BoardToolbar.vue +3 -11
- package/app/components/layout/CommandBar.vue +7 -3
- package/app/components/layout/ConnectionStatusBanner.vue +2 -1
- package/app/components/layout/IntegrationsHub.vue +7 -3
- package/app/components/layout/ModelProvidersHub.vue +7 -3
- package/app/components/layout/NotificationsInbox.vue +3 -11
- package/app/components/layout/WorkspaceMembersSettings.vue +12 -5
- package/app/components/media/ArtifactLightbox.vue +4 -3
- package/app/components/notifications/NotificationSettingsPanel.vue +4 -11
- package/app/components/observability/ToolCallList.vue +12 -17
- package/app/components/panels/AgentStepDetail.vue +5 -5
- package/app/components/panels/GenericStructuredResultView.vue +6 -9
- package/app/components/panels/InspectorPanel.vue +2 -1
- package/app/components/panels/MergerResultView.vue +5 -6
- package/app/components/panels/ObservabilityPanel.vue +26 -41
- package/app/components/panels/OperatorDashboardPanel.vue +29 -17
- package/app/components/panels/ReportsPanel.vue +17 -11
- package/app/components/panels/ReportsSpendBreakdown.vue +7 -3
- package/app/components/panels/RunDetailLoadState.vue +4 -3
- package/app/components/panels/StepContainerStatus.vue +4 -3
- package/app/components/panels/StepDelegatedStatus.vue +3 -2
- package/app/components/panels/StepMetadataCard.vue +6 -8
- package/app/components/panels/StepRunMeta.vue +2 -5
- package/app/components/panels/inspector/ContainerSummary.vue +7 -1
- package/app/components/panels/inspector/EpicChildren.vue +7 -3
- package/app/components/panels/inspector/FrontendConfig.vue +7 -3
- package/app/components/panels/inspector/InitiativeInspector.vue +5 -2
- package/app/components/panels/inspector/ServiceConnections.vue +7 -3
- package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -6
- package/app/components/panels/inspector/ServiceTestSecrets.vue +2 -6
- package/app/components/panels/inspector/ServiceTestingContext.vue +2 -6
- package/app/components/panels/inspector/ServiceValidationConfig.vue +38 -39
- package/app/components/panels/inspector/TaskExecution.vue +5 -6
- package/app/components/panels/inspector/TaskRunSettings.vue +7 -3
- package/app/components/panels/inspector/TaskStructure.vue +0 -1
- package/app/components/pipeline/AgentPromptEditor.vue +25 -18
- package/app/components/pipeline/PipelineBuilder.vue +14 -24
- package/app/components/pipeline/PipelineProgress.vue +16 -17
- package/app/components/prReview/PrReviewPhaseBadge.vue +3 -2
- package/app/components/prReview/PrReviewWindow.vue +16 -20
- package/app/components/providers/ApiKeysSection.vue +2 -6
- package/app/components/providers/PersonalCredentialModal.vue +2 -6
- package/app/components/providers/PersonalSubscriptionSection.vue +3 -7
- package/app/components/providers/VendorCredentialsModal.vue +2 -6
- package/app/components/provisioning/ProvisioningLogsDrawer.vue +10 -6
- package/app/components/ralph/RalphLoopResultView.vue +2 -7
- package/app/components/requirements/RequirementsReviewWindow.vue +44 -39
- package/app/components/sandbox/SandboxPanel.vue +37 -25
- package/app/components/settings/AccountSettingsPanel.vue +6 -3
- package/app/components/settings/ApiTokensPanel.vue +2 -6
- package/app/components/settings/BudgetSettings.vue +2 -2
- package/app/components/settings/CapabilityCredentialsPanel.vue +2 -6
- package/app/components/settings/CloudflareHandlerSection.vue +3 -7
- package/app/components/settings/ConsensusGroupsSection.vue +7 -3
- package/app/components/settings/CustomManifestTypeEditor.vue +7 -3
- package/app/components/settings/DefaultProvisionTypeSection.vue +2 -2
- package/app/components/settings/InfraHandlersConfigurator.vue +8 -11
- package/app/components/settings/IssueTrackerPanel.vue +9 -9
- package/app/components/settings/LocalContainerPoolSettings.vue +2 -6
- package/app/components/settings/LocalModelEndpointsPanel.vue +5 -7
- package/app/components/settings/McpAuthorizeScreen.vue +8 -3
- package/app/components/settings/McpOAuthCallbackScreen.vue +2 -1
- package/app/components/settings/ModelConfigurationPanel.vue +45 -17
- package/app/components/settings/ObservabilityConnectionPanel.vue +4 -15
- package/app/components/settings/OpenRouterCatalogPanel.vue +8 -24
- package/app/components/settings/PackageRegistriesPanel.vue +2 -6
- package/app/components/settings/ProviderConnectionTab.vue +3 -7
- package/app/components/settings/RiskPolicyPanel.vue +4 -16
- package/app/components/settings/SharedStacksPanel.vue +8 -18
- package/app/components/settings/TaskTypeSuppressionsPanel.vue +10 -6
- package/app/components/settings/UsageSettings.vue +11 -2
- package/app/components/settings/UserSecretsSection.vue +5 -7
- package/app/components/settings/WorkspaceMetadataSettings.vue +9 -9
- package/app/components/settings/WorkspaceSettingsPanel.vue +3 -11
- package/app/components/skills/ReviewSkillQueue.vue +7 -3
- package/app/components/skills/SkillLibraryManager.vue +20 -18
- package/app/components/slack/SlackPanel.vue +5 -8
- package/app/components/spec/ServiceSpecWindow.vue +32 -29
- package/app/components/tasks/BugHuntModal.vue +23 -19
- package/app/components/tasks/ContextIssuePicker.vue +2 -2
- package/app/components/tasks/TaskContextIssues.vue +4 -5
- package/app/components/tasks/TaskImportModal.vue +10 -8
- package/app/components/tasks/TaskSourceConnectModal.vue +11 -11
- package/app/components/testing/TestReportWindow.vue +6 -12
- package/app/components/tutorial/TutorialCatalogue.vue +7 -3
- package/app/components/tutorial/TutorialOverlay.vue +2 -1
- package/app/components/tutorial/TutorialPrompt.vue +7 -3
- package/app/components/vcs/GitLabConnect.vue +2 -6
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +9 -4
- package/app/composables/toastTitleKeys.spec.ts +143 -0
- package/app/composables/useActionToast.spec.ts +71 -0
- package/app/composables/useActionToast.ts +101 -0
- package/app/composables/useBlockDeletion.ts +3 -6
- package/app/composables/useConfirmAction.ts +5 -3
- package/app/composables/useContextLinking.spec.ts +3 -0
- package/app/composables/useContextLinking.ts +11 -16
- package/app/composables/useCopyToClipboard.ts +4 -3
- package/app/composables/useNavContributions.ts +4 -5
- package/app/composables/usePipelineErrorToast.spec.ts +24 -0
- package/app/composables/usePipelineErrorToast.ts +26 -2
- package/app/composables/usePipelineLibraryActions.ts +8 -9
- package/app/pages/index.vue +3 -2
- package/app/stores/board/context.ts +4 -3
- package/app/stores/board/placement.ts +8 -20
- package/app/stores/board/removal.ts +4 -13
- package/app/stores/board.spec.ts +10 -1
- package/app/stores/board.ts +3 -2
- package/app/utils/bootstrapSteps.ts +11 -2
- package/app/utils/pipelineRender.ts +21 -8
- package/i18n/locales/de.json +12 -30
- package/i18n/locales/en.json +12 -30
- package/i18n/locales/es.json +12 -30
- package/i18n/locales/fr.json +12 -30
- package/i18n/locales/he.json +12 -30
- package/i18n/locales/it.json +12 -30
- package/i18n/locales/ja.json +12 -30
- package/i18n/locales/pl.json +12 -30
- package/i18n/locales/tr.json +12 -30
- package/i18n/locales/uk.json +12 -30
- package/package.json +1 -1
|
@@ -29,11 +29,13 @@ import type {
|
|
|
29
29
|
ReviewItemStatus,
|
|
30
30
|
} from '~/types/requirements'
|
|
31
31
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
32
|
+
import Spinner from '~/components/common/Spinner.vue'
|
|
33
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
32
34
|
|
|
33
35
|
const board = useBoardStore()
|
|
34
36
|
const requirements = useRequirementsStore()
|
|
35
37
|
const models = useModelsStore()
|
|
36
|
-
const
|
|
38
|
+
const actionToast = useActionToast()
|
|
37
39
|
const { present } = usePipelineErrorToast()
|
|
38
40
|
const { t } = useI18n()
|
|
39
41
|
const access = useWorkspaceAccess()
|
|
@@ -574,18 +576,18 @@ async function requestRecommendations() {
|
|
|
574
576
|
// ran inline and the recommendations are already settled. Tell the human which actually
|
|
575
577
|
// happened rather than always promising a background callback.
|
|
576
578
|
const stillGenerating = (updated?.recommendations ?? []).some((r) => r.status === 'pending')
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
579
|
+
if (stillGenerating) {
|
|
580
|
+
actionToast.info('requirements.toast.preparingRecommendations', {
|
|
581
|
+
params: { count: n },
|
|
582
|
+
plural: n,
|
|
583
|
+
description: t('requirements.toast.preparingRecommendationsDescription'),
|
|
584
|
+
})
|
|
585
|
+
} else {
|
|
586
|
+
actionToast.success('requirements.toast.recommendationsReady', {
|
|
587
|
+
params: { count: n },
|
|
588
|
+
plural: n,
|
|
589
|
+
})
|
|
590
|
+
}
|
|
589
591
|
} catch (e) {
|
|
590
592
|
present(e, 'requirements.errors.requestRecommendations')
|
|
591
593
|
}
|
|
@@ -634,10 +636,8 @@ async function incorporate(feedback?: string) {
|
|
|
634
636
|
showRedo.value = false
|
|
635
637
|
// The fold + re-review now run in the durable driver. Hand the user back to the board;
|
|
636
638
|
// a notification calls them back only if the re-review needs more input.
|
|
637
|
-
toast.
|
|
638
|
-
title: t('requirements.toast.incorporating'),
|
|
639
|
+
actionToast.info('requirements.toast.incorporating', {
|
|
639
640
|
description: t('requirements.toast.incorporatingDescription'),
|
|
640
|
-
icon: 'i-lucide-wand-sparkles',
|
|
641
641
|
})
|
|
642
642
|
close()
|
|
643
643
|
}
|
|
@@ -647,15 +647,16 @@ async function reReview() {
|
|
|
647
647
|
try {
|
|
648
648
|
const updated = await requirements.reReview(blockId.value)
|
|
649
649
|
const newFindings = requirements.openCount(updated)
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
650
|
+
if (updated.status === 'incorporated') {
|
|
651
|
+
actionToast.success('requirements.toast.reviewerSatisfied')
|
|
652
|
+
} else if (updated.status === 'exceeded') {
|
|
653
|
+
actionToast.warning('requirements.toast.iterationLimitReached')
|
|
654
|
+
} else {
|
|
655
|
+
actionToast.info('requirements.toast.newFindings', {
|
|
656
|
+
params: { count: newFindings },
|
|
657
|
+
plural: newFindings,
|
|
658
|
+
})
|
|
659
|
+
}
|
|
659
660
|
} catch (e) {
|
|
660
661
|
present(e, 'requirements.errors.reReview')
|
|
661
662
|
}
|
|
@@ -667,7 +668,7 @@ async function proceed() {
|
|
|
667
668
|
try {
|
|
668
669
|
await flushDrafts()
|
|
669
670
|
await requirements.proceed(blockId.value)
|
|
670
|
-
|
|
671
|
+
actionToast.info('requirements.toast.proceeding')
|
|
671
672
|
} catch (e) {
|
|
672
673
|
present(e, 'requirements.errors.proceed')
|
|
673
674
|
} finally {
|
|
@@ -681,12 +682,12 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
681
682
|
try {
|
|
682
683
|
await requirements.resolveExceeded(blockId.value, choice)
|
|
683
684
|
if (choice === 'stop-reset') {
|
|
684
|
-
|
|
685
|
+
actionToast.info('requirements.toast.taskReset')
|
|
685
686
|
close()
|
|
686
687
|
} else if (choice === 'proceed') {
|
|
687
|
-
|
|
688
|
+
actionToast.info('requirements.toast.proceeding')
|
|
688
689
|
} else {
|
|
689
|
-
|
|
690
|
+
actionToast.info('requirements.toast.extraRoundGranted')
|
|
690
691
|
}
|
|
691
692
|
} catch (e) {
|
|
692
693
|
present(e, 'requirements.errors.resolveReview')
|
|
@@ -734,20 +735,24 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
734
735
|
|
|
735
736
|
<!-- empty state — the reviewer runs automatically as the first pipeline
|
|
736
737
|
gate step, so there's nothing to do here until then -->
|
|
737
|
-
<
|
|
738
|
+
<EmptyState
|
|
738
739
|
v-if="!review && !busy && !loading"
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
740
|
+
icon="i-lucide-list-checks"
|
|
741
|
+
:title="t('requirements.empty')"
|
|
742
|
+
/>
|
|
743
|
+
|
|
744
|
+
<!-- initial fetch on open -->
|
|
745
|
+
<div v-else-if="loading && !busy && !review" class="flex flex-col gap-3">
|
|
746
|
+
<USkeleton v-for="n in 3" :key="n" class="h-20 w-full rounded-lg" />
|
|
742
747
|
</div>
|
|
743
748
|
|
|
744
|
-
<!--
|
|
749
|
+
<!-- a reviewer pass running -->
|
|
745
750
|
<div
|
|
746
|
-
v-else-if="
|
|
751
|
+
v-else-if="busy && !review"
|
|
747
752
|
class="flex items-center justify-center gap-2 p-8 text-sm text-muted"
|
|
748
753
|
>
|
|
749
|
-
<
|
|
750
|
-
{{
|
|
754
|
+
<Spinner class="h-4 w-4" />
|
|
755
|
+
{{ t('requirements.reviewing') }}
|
|
751
756
|
</div>
|
|
752
757
|
|
|
753
758
|
<template v-else-if="review">
|
|
@@ -777,7 +782,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
777
782
|
v-else-if="working"
|
|
778
783
|
class="mb-4 flex items-center gap-2 rounded-lg border border-primary/60 bg-primary/10 p-4 text-sm text-primary"
|
|
779
784
|
>
|
|
780
|
-
<
|
|
785
|
+
<Spinner class="h-5 w-5 shrink-0" />
|
|
781
786
|
<span v-if="incorporating">
|
|
782
787
|
{{ t('requirements.working.incorporating') }}
|
|
783
788
|
</span>
|
|
@@ -978,7 +983,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
978
983
|
v-if="pendingRecFor(item)"
|
|
979
984
|
class="mt-2 flex items-center gap-1.5 text-xs text-primary"
|
|
980
985
|
>
|
|
981
|
-
<
|
|
986
|
+
<Spinner class="h-3.5 w-3.5" />
|
|
982
987
|
{{ t('requirements.generatingSuggestion') }}
|
|
983
988
|
</div>
|
|
984
989
|
<template v-else-if="readyRecFor(item)">
|
|
@@ -18,10 +18,11 @@ import type {
|
|
|
18
18
|
} from '~/types/sandbox'
|
|
19
19
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
20
20
|
import IconButton from '~/components/common/IconButton.vue'
|
|
21
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
21
22
|
|
|
22
23
|
const ui = useUiStore()
|
|
23
24
|
const store = useSandboxStore()
|
|
24
|
-
const
|
|
25
|
+
const actionToast = useActionToast()
|
|
25
26
|
const { present } = usePipelineErrorToast()
|
|
26
27
|
const { t } = useI18n()
|
|
27
28
|
|
|
@@ -82,13 +83,9 @@ async function promote(version: SandboxPromptVersion) {
|
|
|
82
83
|
promoting.value = version.id
|
|
83
84
|
try {
|
|
84
85
|
await store.promotePrompt(version)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
icon: 'i-lucide-rocket',
|
|
89
|
-
})
|
|
90
|
-
} catch {
|
|
91
|
-
toast.add({ title: t('sandbox.prompts.promoteFailed'), color: 'error' })
|
|
86
|
+
actionToast.success('sandbox.prompts.promoted', { params: { agent: version.agentKind } })
|
|
87
|
+
} catch (error) {
|
|
88
|
+
present(error, 'sandbox.prompts.promoteFailed')
|
|
92
89
|
} finally {
|
|
93
90
|
promoting.value = null
|
|
94
91
|
}
|
|
@@ -193,9 +190,9 @@ async function createAndRun() {
|
|
|
193
190
|
},
|
|
194
191
|
})
|
|
195
192
|
name.value = ''
|
|
196
|
-
|
|
193
|
+
actionToast.info('sandbox.toast.running')
|
|
197
194
|
await store.launch(created.id)
|
|
198
|
-
|
|
195
|
+
actionToast.success('sandbox.toast.complete')
|
|
199
196
|
} catch (e) {
|
|
200
197
|
present(e, 'sandbox.toast.runFailed')
|
|
201
198
|
}
|
|
@@ -255,7 +252,7 @@ async function saveVersion() {
|
|
|
255
252
|
savingPrompt.value = true
|
|
256
253
|
try {
|
|
257
254
|
await store.saveVersion(editing.value.id, editText.value)
|
|
258
|
-
|
|
255
|
+
actionToast.success('sandbox.toast.versionSaved')
|
|
259
256
|
editing.value = null
|
|
260
257
|
} catch (e) {
|
|
261
258
|
present(e, 'sandbox.toast.saveFailed')
|
|
@@ -282,8 +279,12 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
282
279
|
:ui="{ content: 'max-w-5xl' }"
|
|
283
280
|
>
|
|
284
281
|
<template #body>
|
|
285
|
-
<div v-if="store.loading" class="
|
|
286
|
-
<
|
|
282
|
+
<div v-if="store.loading" class="space-y-4">
|
|
283
|
+
<USkeleton class="h-8 w-full" />
|
|
284
|
+
<div class="grid gap-4 lg:grid-cols-2">
|
|
285
|
+
<USkeleton class="h-80 w-full rounded-lg" />
|
|
286
|
+
<USkeleton class="h-80 w-full rounded-lg" />
|
|
287
|
+
</div>
|
|
287
288
|
</div>
|
|
288
289
|
|
|
289
290
|
<div
|
|
@@ -405,9 +406,12 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
405
406
|
/>
|
|
406
407
|
<span class="truncate">{{ m.label }}</span>
|
|
407
408
|
</label>
|
|
408
|
-
<
|
|
409
|
-
|
|
410
|
-
|
|
409
|
+
<EmptyState
|
|
410
|
+
v-if="!store.selectableModels.length"
|
|
411
|
+
compact
|
|
412
|
+
icon="i-lucide-cpu"
|
|
413
|
+
:title="t('sandbox.builder.noModels')"
|
|
414
|
+
/>
|
|
411
415
|
</div>
|
|
412
416
|
</div>
|
|
413
417
|
|
|
@@ -429,9 +433,12 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
429
433
|
/>
|
|
430
434
|
<span class="truncate">{{ f.name }}</span>
|
|
431
435
|
</label>
|
|
432
|
-
<
|
|
433
|
-
|
|
434
|
-
|
|
436
|
+
<EmptyState
|
|
437
|
+
v-if="!kindFixtures.length"
|
|
438
|
+
compact
|
|
439
|
+
icon="i-lucide-clipboard-list"
|
|
440
|
+
:title="t('sandbox.builder.noFixtures')"
|
|
441
|
+
/>
|
|
435
442
|
</div>
|
|
436
443
|
</div>
|
|
437
444
|
|
|
@@ -577,9 +584,12 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
577
584
|
<span class="truncate text-toned">{{ x.name }}</span>
|
|
578
585
|
<UBadge variant="soft" size="xs">{{ EXPERIMENT_STATUS_LABEL[x.status] }}</UBadge>
|
|
579
586
|
</UButton>
|
|
580
|
-
<
|
|
581
|
-
|
|
582
|
-
|
|
587
|
+
<EmptyState
|
|
588
|
+
v-if="!store.experiments.length"
|
|
589
|
+
compact
|
|
590
|
+
icon="i-lucide-flask-conical"
|
|
591
|
+
:title="t('sandbox.results.empty')"
|
|
592
|
+
/>
|
|
583
593
|
</div>
|
|
584
594
|
</div>
|
|
585
595
|
</div>
|
|
@@ -718,9 +728,11 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
718
728
|
}}
|
|
719
729
|
</p>
|
|
720
730
|
</div>
|
|
721
|
-
<
|
|
722
|
-
|
|
723
|
-
|
|
731
|
+
<EmptyState
|
|
732
|
+
v-if="!store.fixtures.length"
|
|
733
|
+
icon="i-lucide-clipboard-list"
|
|
734
|
+
:title="t('sandbox.fixtures.empty')"
|
|
735
|
+
/>
|
|
724
736
|
</div>
|
|
725
737
|
</div>
|
|
726
738
|
</template>
|
|
@@ -11,6 +11,7 @@ import AccountFragmentSettings from '~/components/layout/AccountFragmentSettings
|
|
|
11
11
|
import AccountSkillSettings from '~/components/layout/AccountSkillSettings.vue'
|
|
12
12
|
import AccountFoundationalSettings from '~/components/layout/AccountFoundationalSettings.vue'
|
|
13
13
|
import AccountRiskPolicySettings from '~/components/layout/AccountRiskPolicySettings.vue'
|
|
14
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
14
15
|
|
|
15
16
|
const { t } = useI18n()
|
|
16
17
|
const ui = useUiStore()
|
|
@@ -60,9 +61,11 @@ const tabs = computed(() => [
|
|
|
60
61
|
<template>
|
|
61
62
|
<UModal v-model:open="open" :title="t('settings.account.title')" :ui="{ content: 'max-w-3xl' }">
|
|
62
63
|
<template #body>
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
<EmptyState
|
|
65
|
+
v-if="!accounts.activeAccountId"
|
|
66
|
+
icon="i-lucide-building-2"
|
|
67
|
+
:title="t('settings.account.noAccount')"
|
|
68
|
+
/>
|
|
66
69
|
<UTabs
|
|
67
70
|
v-else
|
|
68
71
|
v-model="activeTab"
|
|
@@ -74,7 +74,7 @@ function boundLabel(key: PublicApiKey): string | null {
|
|
|
74
74
|
? t('settings.apiTokens.list.boundToYou')
|
|
75
75
|
: t('settings.apiTokens.list.boundToOther', { user: key.actsAsUserId })
|
|
76
76
|
}
|
|
77
|
-
const
|
|
77
|
+
const actionToast = useActionToast()
|
|
78
78
|
const { present } = usePipelineErrorToast()
|
|
79
79
|
const { confirmAction, toastDone } = useConfirmAction()
|
|
80
80
|
|
|
@@ -152,11 +152,7 @@ async function createToken() {
|
|
|
152
152
|
label.value = ''
|
|
153
153
|
scope.value = 'write'
|
|
154
154
|
identity.value = 'system'
|
|
155
|
-
toast.
|
|
156
|
-
title: t('settings.apiTokens.toast.created'),
|
|
157
|
-
icon: 'i-lucide-check',
|
|
158
|
-
color: 'success',
|
|
159
|
-
})
|
|
155
|
+
actionToast.success('settings.apiTokens.toast.created')
|
|
160
156
|
} catch (e) {
|
|
161
157
|
present(e, 'settings.apiTokens.toast.createFailed')
|
|
162
158
|
} finally {
|
|
@@ -8,7 +8,7 @@ import { computed, reactive, ref, watch, type Ref } from 'vue'
|
|
|
8
8
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
9
9
|
|
|
10
10
|
const { t, n } = useI18n()
|
|
11
|
-
const
|
|
11
|
+
const actionToast = useActionToast()
|
|
12
12
|
const { present } = usePipelineErrorToast()
|
|
13
13
|
|
|
14
14
|
const settingsStore = useWorkspaceSettingsStore()
|
|
@@ -32,7 +32,7 @@ async function runSave(saving: Ref<boolean>, save: () => Promise<unknown>) {
|
|
|
32
32
|
saving.value = true
|
|
33
33
|
try {
|
|
34
34
|
await save()
|
|
35
|
-
|
|
35
|
+
actionToast.success('settings.workspaceSettings.toast.budgetSaved')
|
|
36
36
|
try {
|
|
37
37
|
await useWorkspaceStore().refresh()
|
|
38
38
|
} catch {
|
|
@@ -20,7 +20,7 @@ import ToolServerChecklist from '~/components/settings/ToolServerChecklist.vue'
|
|
|
20
20
|
|
|
21
21
|
const { t, d } = useI18n()
|
|
22
22
|
const store = useCapabilityCredentialsStore()
|
|
23
|
-
const
|
|
23
|
+
const actionToast = useActionToast()
|
|
24
24
|
const { confirmAction, toastDone } = useConfirmAction()
|
|
25
25
|
|
|
26
26
|
// Which declaring capability wants a key. An exhaustive Record over the wire union, so a new
|
|
@@ -85,11 +85,7 @@ async function saveKey(key: string) {
|
|
|
85
85
|
try {
|
|
86
86
|
await store.save(key, value)
|
|
87
87
|
drafts[key] = ''
|
|
88
|
-
toast.
|
|
89
|
-
title: t('settings.capabilityCredentials.toast.saved', { key }),
|
|
90
|
-
icon: 'i-lucide-check',
|
|
91
|
-
color: 'success',
|
|
92
|
-
})
|
|
88
|
+
actionToast.success('settings.capabilityCredentials.toast.saved', { params: { key } })
|
|
93
89
|
} catch (e) {
|
|
94
90
|
present(e, 'settings.capabilityCredentials.toast.saveFailed')
|
|
95
91
|
} finally {
|
|
@@ -18,7 +18,7 @@ type CloudflareConfig = CloudflareHandlerConfig['cloudflare']
|
|
|
18
18
|
|
|
19
19
|
const { t } = useI18n()
|
|
20
20
|
const infra = useInfraConfigStore()
|
|
21
|
-
const
|
|
21
|
+
const actionToast = useActionToast()
|
|
22
22
|
const { present } = usePipelineErrorToast()
|
|
23
23
|
const { confirmAction } = useConfirmAction()
|
|
24
24
|
|
|
@@ -101,11 +101,7 @@ async function save() {
|
|
|
101
101
|
})
|
|
102
102
|
token.value = ''
|
|
103
103
|
editing.value = false
|
|
104
|
-
|
|
105
|
-
title: t('settings.infrastructure.handler.saved'),
|
|
106
|
-
icon: 'i-lucide-check',
|
|
107
|
-
color: 'success',
|
|
108
|
-
})
|
|
104
|
+
actionToast.success('settings.infrastructure.handler.saved')
|
|
109
105
|
} catch (e) {
|
|
110
106
|
present(e, 'settings.infrastructure.handler.saveFailed')
|
|
111
107
|
} finally {
|
|
@@ -133,7 +129,7 @@ async function remove() {
|
|
|
133
129
|
busy.value = true
|
|
134
130
|
try {
|
|
135
131
|
await infra.unregisterHandler('cloudflare')
|
|
136
|
-
|
|
132
|
+
actionToast.success('settings.infrastructure.handler.removed')
|
|
137
133
|
} catch (e) {
|
|
138
134
|
present(e, 'settings.infrastructure.handler.saveFailed')
|
|
139
135
|
} finally {
|
|
@@ -15,6 +15,7 @@ import { isSelectable } from '~/stores/models'
|
|
|
15
15
|
import { uid } from '~/utils/catalog'
|
|
16
16
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
17
17
|
import IconButton from '~/components/common/IconButton.vue'
|
|
18
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
18
19
|
|
|
19
20
|
const { t } = useI18n()
|
|
20
21
|
const groups = useConsensusGroupsStore()
|
|
@@ -291,9 +292,12 @@ async function remove(group: ConsensusGroup) {
|
|
|
291
292
|
</div>
|
|
292
293
|
</div>
|
|
293
294
|
</div>
|
|
294
|
-
<
|
|
295
|
-
|
|
296
|
-
|
|
295
|
+
<EmptyState
|
|
296
|
+
v-else
|
|
297
|
+
compact
|
|
298
|
+
icon="i-lucide-users"
|
|
299
|
+
:title="t('settings.consensusGroups.list.empty')"
|
|
300
|
+
/>
|
|
297
301
|
</template>
|
|
298
302
|
|
|
299
303
|
<!-- ===== editor ===== -->
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { computed, reactive, ref } from 'vue'
|
|
8
8
|
import type { CustomManifestType } from '@cat-factory/contracts'
|
|
9
9
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
10
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
10
11
|
|
|
11
12
|
const { t } = useI18n()
|
|
12
13
|
const infra = useInfraConfigStore()
|
|
@@ -140,9 +141,12 @@ async function remove(type: CustomManifestType) {
|
|
|
140
141
|
</div>
|
|
141
142
|
</li>
|
|
142
143
|
</ul>
|
|
143
|
-
<
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
<EmptyState
|
|
145
|
+
v-else
|
|
146
|
+
compact
|
|
147
|
+
icon="i-lucide-boxes"
|
|
148
|
+
:title="t('settings.infrastructure.customType.empty')"
|
|
149
|
+
/>
|
|
146
150
|
|
|
147
151
|
<!-- Add / edit a workspace-defined type. -->
|
|
148
152
|
<div class="space-y-2 border-t border-default pt-3">
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
const { t } = useI18n()
|
|
25
25
|
const infra = useInfraConfigStore()
|
|
26
26
|
const settingsStore = useWorkspaceSettingsStore()
|
|
27
|
-
const
|
|
27
|
+
const actionToast = useActionToast()
|
|
28
28
|
const { present } = usePipelineErrorToast()
|
|
29
29
|
|
|
30
30
|
onMounted(() => {
|
|
@@ -90,7 +90,7 @@ async function save() {
|
|
|
90
90
|
defaultProvisionType: selection.value.type,
|
|
91
91
|
defaultProvisionManifestId: selection.value.manifestId,
|
|
92
92
|
})
|
|
93
|
-
|
|
93
|
+
actionToast.success('settings.defaultProvision.saved')
|
|
94
94
|
} catch (e) {
|
|
95
95
|
present(e, 'settings.defaultProvision.saveFailed')
|
|
96
96
|
} finally {
|
|
@@ -36,7 +36,7 @@ const { t } = useI18n()
|
|
|
36
36
|
const infra = useInfraConfigStore()
|
|
37
37
|
const auth = useAuthStore()
|
|
38
38
|
const ui = useUiStore()
|
|
39
|
-
const
|
|
39
|
+
const actionToast = useActionToast()
|
|
40
40
|
const { present } = usePipelineErrorToast()
|
|
41
41
|
const { confirmAction } = useConfirmAction()
|
|
42
42
|
|
|
@@ -403,20 +403,16 @@ async function removeCustom() {
|
|
|
403
403
|
}
|
|
404
404
|
|
|
405
405
|
function toastSaved() {
|
|
406
|
-
|
|
407
|
-
title: t('settings.infrastructure.handler.saved'),
|
|
408
|
-
icon: 'i-lucide-check',
|
|
409
|
-
color: 'success',
|
|
410
|
-
})
|
|
406
|
+
actionToast.success('settings.infrastructure.handler.saved')
|
|
411
407
|
}
|
|
412
408
|
function toastRemoved() {
|
|
413
|
-
|
|
409
|
+
actionToast.success('settings.infrastructure.handler.removed')
|
|
414
410
|
}
|
|
415
411
|
</script>
|
|
416
412
|
|
|
417
413
|
<template>
|
|
418
414
|
<!-- Only render the configurator once the handler bundle has actually resolved (available
|
|
419
|
-
=== true). While it's still being probed (null) show
|
|
415
|
+
=== true). While it's still being probed (null) show skeleton sections instead of flashing
|
|
420
416
|
the full form, and render nothing when the integration is off (false). -->
|
|
421
417
|
<div v-if="infra.available === true" class="space-y-5">
|
|
422
418
|
<p class="text-xs text-muted">{{ t('settings.infrastructure.handler.intro') }}</p>
|
|
@@ -629,7 +625,8 @@ function toastRemoved() {
|
|
|
629
625
|
</div>
|
|
630
626
|
</section>
|
|
631
627
|
</div>
|
|
632
|
-
<
|
|
633
|
-
|
|
634
|
-
|
|
628
|
+
<div v-else-if="infra.available === null" class="space-y-5">
|
|
629
|
+
<USkeleton class="h-4 w-2/3" />
|
|
630
|
+
<USkeleton v-for="n in 3" :key="n" class="h-24 w-full rounded-lg" />
|
|
631
|
+
</div>
|
|
635
632
|
</template>
|
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
import { computed, onMounted, ref, watch } from 'vue'
|
|
18
18
|
import type { TaskSourceKind, TaskSourceState, TrackerKind } from '~/types/domain'
|
|
19
19
|
import TaskSourceCard from '~/components/settings/TaskSourceCard.vue'
|
|
20
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
20
21
|
|
|
21
22
|
const { t } = useI18n()
|
|
22
23
|
const tracker = useTrackerStore()
|
|
23
24
|
const tasks = useTasksStore()
|
|
24
25
|
const ui = useUiStore()
|
|
25
|
-
const
|
|
26
|
+
const actionToast = useActionToast()
|
|
26
27
|
const { present } = usePipelineErrorToast()
|
|
27
28
|
|
|
28
29
|
// --- filing tracker + writeback (one Save, persisted on tracker settings) -----
|
|
@@ -114,11 +115,7 @@ async function save() {
|
|
|
114
115
|
writebackResolveOnMerge: resolveOnMerge.value,
|
|
115
116
|
writebackQuestionsOnPark: questionsOnPark.value,
|
|
116
117
|
})
|
|
117
|
-
toast.
|
|
118
|
-
title: t('settings.issueTracker.toast.saved'),
|
|
119
|
-
icon: 'i-lucide-check',
|
|
120
|
-
color: 'success',
|
|
121
|
-
})
|
|
118
|
+
actionToast.success('settings.issueTracker.toast.saved')
|
|
122
119
|
} catch (e) {
|
|
123
120
|
present(e, 'settings.issueTracker.toast.saveFailed')
|
|
124
121
|
} finally {
|
|
@@ -379,9 +376,12 @@ async function checkSetup(source: TaskSourceKind) {
|
|
|
379
376
|
@remedy="openRemedy(source)"
|
|
380
377
|
/>
|
|
381
378
|
|
|
382
|
-
<
|
|
383
|
-
|
|
384
|
-
|
|
379
|
+
<EmptyState
|
|
380
|
+
v-if="tasks.sources.length === 0"
|
|
381
|
+
compact
|
|
382
|
+
icon="i-lucide-list-todo"
|
|
383
|
+
:title="t('settings.issueTracker.linking.none')"
|
|
384
|
+
/>
|
|
385
385
|
</section>
|
|
386
386
|
|
|
387
387
|
<!-- 3. Writeback ---------------------------------------------------------->
|
|
@@ -13,7 +13,7 @@ import { reactive, ref, watch } from 'vue'
|
|
|
13
13
|
|
|
14
14
|
const { t } = useI18n()
|
|
15
15
|
const store = useLocalSettingsStore()
|
|
16
|
-
const
|
|
16
|
+
const actionToast = useActionToast()
|
|
17
17
|
const { present } = usePipelineErrorToast()
|
|
18
18
|
|
|
19
19
|
const saving = ref(false)
|
|
@@ -60,11 +60,7 @@ async function save() {
|
|
|
60
60
|
},
|
|
61
61
|
checkout: { workspaceRoot: draft.workspaceRoot.trim() || '/workspace', cleanKeep },
|
|
62
62
|
})
|
|
63
|
-
toast.
|
|
64
|
-
title: t('settings.localMode.toast.saved'),
|
|
65
|
-
icon: 'i-lucide-check',
|
|
66
|
-
color: 'success',
|
|
67
|
-
})
|
|
63
|
+
actionToast.success('settings.localMode.toast.saved')
|
|
68
64
|
} catch (e) {
|
|
69
65
|
present(e, 'settings.localMode.toast.saveFailed')
|
|
70
66
|
} finally {
|
|
@@ -23,7 +23,7 @@ import IconButton from '~/components/common/IconButton.vue'
|
|
|
23
23
|
const { t } = useI18n()
|
|
24
24
|
const ui = useUiStore()
|
|
25
25
|
const store = useLocalModelsStore()
|
|
26
|
-
const
|
|
26
|
+
const actionToast = useActionToast()
|
|
27
27
|
const { present } = usePipelineErrorToast()
|
|
28
28
|
const { confirm } = useConfirm()
|
|
29
29
|
|
|
@@ -230,12 +230,10 @@ async function save() {
|
|
|
230
230
|
models: selected.value.map((id) => ({ id, ...modalityOf(imageInput.value[id]) })),
|
|
231
231
|
})
|
|
232
232
|
apiKey.value = ''
|
|
233
|
-
toast.
|
|
234
|
-
|
|
233
|
+
actionToast.success('settings.localModelEndpoints.toast.saved', {
|
|
234
|
+
params: {
|
|
235
235
|
name: LOCAL_RUNNER_LABELS[provider.value],
|
|
236
|
-
}
|
|
237
|
-
icon: 'i-lucide-check',
|
|
238
|
-
color: 'success',
|
|
236
|
+
},
|
|
239
237
|
})
|
|
240
238
|
} catch (e) {
|
|
241
239
|
present(e, 'settings.localModelEndpoints.toast.saveFailed')
|
|
@@ -261,7 +259,7 @@ async function remove(p: LocalRunner) {
|
|
|
261
259
|
// The row is gone from the store, so re-seeding the draft it was showing yields the
|
|
262
260
|
// fresh-runner defaults: the same reset, without a second copy of what a reset means.
|
|
263
261
|
if (provider.value === p) seedDraft(p)
|
|
264
|
-
|
|
262
|
+
actionToast.success('settings.localModelEndpoints.toast.removed')
|
|
265
263
|
} catch (e) {
|
|
266
264
|
present(e, 'settings.localModelEndpoints.toast.removeFailed')
|
|
267
265
|
} finally {
|
|
@@ -145,9 +145,14 @@ function backToApp() {
|
|
|
145
145
|
data-testid="mcp-authorize"
|
|
146
146
|
>
|
|
147
147
|
<div class="w-full max-w-md rounded-xl border border-default bg-default/80 p-8 backdrop-blur">
|
|
148
|
-
<
|
|
149
|
-
<
|
|
150
|
-
|
|
148
|
+
<div v-if="screen === 'loading'" class="flex flex-col items-center">
|
|
149
|
+
<USkeleton class="mb-3 h-10 w-10 rounded-full" />
|
|
150
|
+
<USkeleton class="mb-2 h-6 w-3/4" />
|
|
151
|
+
<USkeleton class="mb-6 h-4 w-full" />
|
|
152
|
+
<USkeleton class="mb-4 h-8 w-full" />
|
|
153
|
+
<USkeleton class="mb-6 h-16 w-full" />
|
|
154
|
+
<USkeleton class="h-8 w-full" />
|
|
155
|
+
</div>
|
|
151
156
|
|
|
152
157
|
<template v-else-if="screen === 'failed'">
|
|
153
158
|
<UIcon name="i-lucide-alert-triangle" class="mx-auto mb-3 h-10 w-10 text-app-error-400" />
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { onMounted, ref } from 'vue'
|
|
3
|
+
import Spinner from '~/components/common/Spinner.vue'
|
|
3
4
|
|
|
4
5
|
// Where a vendor's authorization server sends the operator's browser back to after they approve a
|
|
5
6
|
// remote MCP tool server (`/mcp-oauth-callback?code=…&state=…`).
|
|
@@ -69,7 +70,7 @@ function backToApp() {
|
|
|
69
70
|
class="w-full max-w-sm rounded-xl border border-default bg-default/80 p-8 text-center backdrop-blur"
|
|
70
71
|
>
|
|
71
72
|
<template v-if="state === 'working'">
|
|
72
|
-
<
|
|
73
|
+
<Spinner class="mx-auto mb-3 h-10 w-10 text-primary" />
|
|
73
74
|
<h1 class="mb-1 text-lg font-semibold text-highlighted">
|
|
74
75
|
{{ t('settings.toolServers.oauth.callback.working') }}
|
|
75
76
|
</h1>
|