@cat-factory/app 0.311.1 → 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 +70 -5
- package/app/app.config.ts +6 -18
- 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 +4 -7
- 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/AsyncViewError.vue +1 -1
- 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 +15 -9
- 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/SideBar.vue +1 -1
- 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/ResultWindowShell.vue +1 -1
- 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
|
@@ -10,7 +10,7 @@ import SecretInput from '~/components/common/SecretInput.vue'
|
|
|
10
10
|
const { t } = useI18n()
|
|
11
11
|
const personal = usePersonalSubscriptionsStore()
|
|
12
12
|
const ui = useUiStore()
|
|
13
|
-
const
|
|
13
|
+
const actionToast = useActionToast()
|
|
14
14
|
const { present } = usePipelineErrorToast()
|
|
15
15
|
|
|
16
16
|
const password = ref('')
|
|
@@ -67,11 +67,7 @@ async function submit() {
|
|
|
67
67
|
busy.value = true
|
|
68
68
|
try {
|
|
69
69
|
await pending.value.retry(password.value)
|
|
70
|
-
toast.
|
|
71
|
-
title: t('providers.personalCredential.toast.started'),
|
|
72
|
-
icon: 'i-lucide-check',
|
|
73
|
-
color: 'success',
|
|
74
|
-
})
|
|
70
|
+
actionToast.success('providers.personalCredential.toast.started')
|
|
75
71
|
} catch (e) {
|
|
76
72
|
// A fresh 428 (e.g. still-wrong password) re-arms `pending`, keeping the modal open.
|
|
77
73
|
present(e, 'providers.personalCredential.toast.startFailed')
|
|
@@ -13,7 +13,7 @@ const personal = usePersonalSubscriptionsStore()
|
|
|
13
13
|
const auth = useAuthStore()
|
|
14
14
|
const workspace = useWorkspaceStore()
|
|
15
15
|
const models = useModelsStore()
|
|
16
|
-
const
|
|
16
|
+
const actionToast = useActionToast()
|
|
17
17
|
const { present } = usePipelineErrorToast()
|
|
18
18
|
const { t, d } = useI18n()
|
|
19
19
|
const { confirm } = useConfirm()
|
|
@@ -173,11 +173,7 @@ async function connect() {
|
|
|
173
173
|
// points at models this subscription doesn't cover, reactively surfaces the
|
|
174
174
|
// preset-mismatch prompt (with its "pick a different preset" link).
|
|
175
175
|
if (workspace.workspaceId) await models.refresh(workspace.workspaceId)
|
|
176
|
-
toast.
|
|
177
|
-
title: t('personalSubscriptions.toast.connected', { vendor: vendorName }),
|
|
178
|
-
icon: 'i-lucide-check',
|
|
179
|
-
color: 'success',
|
|
180
|
-
})
|
|
176
|
+
actionToast.success('personalSubscriptions.toast.connected', { params: { vendor: vendorName } })
|
|
181
177
|
} catch (e) {
|
|
182
178
|
present(e, 'personalSubscriptions.toast.connectFailed')
|
|
183
179
|
} finally {
|
|
@@ -199,7 +195,7 @@ async function disconnect(v: SubscriptionVendor) {
|
|
|
199
195
|
// Removing the subscription may drop the workspace's last usable model — refresh so the
|
|
200
196
|
// AI-readiness banners re-evaluate (mirrors the API-key flow).
|
|
201
197
|
if (workspace.workspaceId) await models.refresh(workspace.workspaceId)
|
|
202
|
-
|
|
198
|
+
actionToast.success('personalSubscriptions.toast.disconnected')
|
|
203
199
|
} catch (e) {
|
|
204
200
|
present(e, 'personalSubscriptions.toast.disconnectFailed')
|
|
205
201
|
}
|
|
@@ -15,7 +15,7 @@ const { t, n } = useI18n()
|
|
|
15
15
|
const ui = useUiStore()
|
|
16
16
|
const workspace = useWorkspaceStore()
|
|
17
17
|
const creds = useVendorCredentialsStore()
|
|
18
|
-
const
|
|
18
|
+
const actionToast = useActionToast()
|
|
19
19
|
const { present } = usePipelineErrorToast()
|
|
20
20
|
const { confirm } = useConfirm()
|
|
21
21
|
|
|
@@ -127,11 +127,7 @@ async function add() {
|
|
|
127
127
|
})
|
|
128
128
|
token.value = ''
|
|
129
129
|
label.value = ''
|
|
130
|
-
toast.
|
|
131
|
-
title: t('providers.vendorCredentials.toast.connected'),
|
|
132
|
-
icon: 'i-lucide-check',
|
|
133
|
-
color: 'success',
|
|
134
|
-
})
|
|
130
|
+
actionToast.success('providers.vendorCredentials.toast.connected')
|
|
135
131
|
} catch (e) {
|
|
136
132
|
present(e, 'providers.vendorCredentials.toast.connectFailed')
|
|
137
133
|
} finally {
|
|
@@ -23,6 +23,7 @@ import type {
|
|
|
23
23
|
ProvisioningSubsystem,
|
|
24
24
|
} from '~/types/provisioningLogs'
|
|
25
25
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
26
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
26
27
|
|
|
27
28
|
const props = defineProps<{
|
|
28
29
|
subsystem?: ProvisioningSubsystem
|
|
@@ -132,12 +133,15 @@ function when(epochMs: number): string {
|
|
|
132
133
|
</div>
|
|
133
134
|
|
|
134
135
|
<p v-if="state.error" class="px-3 py-2 text-xs text-app-error-300">{{ state.error }}</p>
|
|
135
|
-
<
|
|
136
|
-
v-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
<div v-else-if="state.loading && state.entries.length === 0" class="space-y-2 px-3 py-2">
|
|
137
|
+
<USkeleton v-for="n in 3" :key="n" class="h-8 w-full" />
|
|
138
|
+
</div>
|
|
139
|
+
<EmptyState
|
|
140
|
+
v-else-if="state.entries.length === 0"
|
|
141
|
+
compact
|
|
142
|
+
icon="i-lucide-scroll-text"
|
|
143
|
+
:title="t('provisioning.empty')"
|
|
144
|
+
/>
|
|
141
145
|
|
|
142
146
|
<ul v-else class="max-h-80 divide-y divide-default overflow-auto">
|
|
143
147
|
<li v-for="entry in state.entries" :key="entry.id" class="px-3 py-2">
|
|
@@ -11,6 +11,7 @@ import ResultWindowShell from '~/components/panels/ResultWindowShell.vue'
|
|
|
11
11
|
import StepRunMeta from '~/components/panels/StepRunMeta.vue'
|
|
12
12
|
import CopyButton from '~/components/common/CopyButton.vue'
|
|
13
13
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
14
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
14
15
|
|
|
15
16
|
const board = useBoardStore()
|
|
16
17
|
const execution = useExecutionStore()
|
|
@@ -136,13 +137,7 @@ const STATUS_META = computed<
|
|
|
136
137
|
</template>
|
|
137
138
|
<div class="flex min-h-0 flex-1">
|
|
138
139
|
<div class="min-w-0 flex-1 overflow-y-auto px-5 py-4">
|
|
139
|
-
<
|
|
140
|
-
v-if="!ralph"
|
|
141
|
-
class="flex h-full flex-col items-center justify-center gap-2 text-center text-muted"
|
|
142
|
-
>
|
|
143
|
-
<UIcon :name="meta.icon" class="h-8 w-8 opacity-40" />
|
|
144
|
-
<p class="text-sm">{{ t('ralph.noActivity') }}</p>
|
|
145
|
-
</div>
|
|
140
|
+
<EmptyState v-if="!ralph" class="h-full" :icon="meta.icon" :title="t('ralph.noActivity')" />
|
|
146
141
|
|
|
147
142
|
<template v-else>
|
|
148
143
|
<!-- The completion criterion. -->
|
|
@@ -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>
|