@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
package/app/pages/index.vue
CHANGED
|
@@ -17,6 +17,7 @@ import GitHubOnboarding from '~/components/github/GitHubOnboarding.vue'
|
|
|
17
17
|
import CommandBar from '~/components/layout/CommandBar.vue'
|
|
18
18
|
import PersonalCredentialModal from '~/components/providers/PersonalCredentialModal.vue'
|
|
19
19
|
import ConfirmDialog from '~/components/common/ConfirmDialog.vue'
|
|
20
|
+
import Spinner from '~/components/common/Spinner.vue'
|
|
20
21
|
import { defineAsyncView } from '~/utils/asyncView'
|
|
21
22
|
import KeyboardShortcutsHelp from '~/components/common/KeyboardShortcutsHelp.vue'
|
|
22
23
|
|
|
@@ -438,7 +439,7 @@ watch(
|
|
|
438
439
|
v-if="workspace.ready && githubProbePending"
|
|
439
440
|
class="m-auto flex flex-col items-center gap-3 text-muted"
|
|
440
441
|
>
|
|
441
|
-
<
|
|
442
|
+
<Spinner class="h-8 w-8" />
|
|
442
443
|
<span class="text-sm">{{ $t('app.loading') }}</span>
|
|
443
444
|
</div>
|
|
444
445
|
|
|
@@ -567,7 +568,7 @@ watch(
|
|
|
567
568
|
|
|
568
569
|
<!-- Initial load -->
|
|
569
570
|
<div v-else class="m-auto flex flex-col items-center gap-3 text-muted">
|
|
570
|
-
<
|
|
571
|
+
<Spinner class="h-8 w-8" />
|
|
571
572
|
<span class="text-sm">{{ $t('app.loadingBoard') }}</span>
|
|
572
573
|
</div>
|
|
573
574
|
</div>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Ref } from 'vue'
|
|
2
2
|
import type { Block } from '~/types/domain'
|
|
3
|
+
import type { ActionToast } from '~/composables/useActionToast'
|
|
3
4
|
|
|
4
5
|
/** A detached subtree captured before an optimistic delete, restored on failure. */
|
|
5
6
|
export interface RemovalSnapshot {
|
|
@@ -31,7 +32,7 @@ export const UNDO_WINDOW_MS = 6000
|
|
|
31
32
|
* the `board` store setup and threaded into {@link createBoardMutations} / {@link createBoardRemoval}
|
|
32
33
|
* so the split operations stay behaviourally identical to the original single-closure store — the
|
|
33
34
|
* factories are cohesive extractions purely to keep each function within the size budget, not new
|
|
34
|
-
* seams. `api`/`
|
|
35
|
+
* seams. `api`/`actionToast`/`tr`/`present` are the store's own resolved handles (a store runs outside a
|
|
35
36
|
* component `setup`, so `tr` bridges to the Nuxt app's global i18n instance).
|
|
36
37
|
*/
|
|
37
38
|
export interface BoardWriteContext {
|
|
@@ -41,10 +42,10 @@ export interface BoardWriteContext {
|
|
|
41
42
|
pendingRemovals: Map<string, PendingRemoval>
|
|
42
43
|
pendingDoomed: Set<string>
|
|
43
44
|
api: ReturnType<typeof useApi>
|
|
44
|
-
|
|
45
|
+
actionToast: ActionToast
|
|
45
46
|
tr: (key: string, params?: Record<string, unknown>) => string
|
|
46
47
|
/**
|
|
47
|
-
* The SPA's one failure-toast funnel (`usePipelineErrorToast().present`), threaded like `
|
|
48
|
+
* The SPA's one failure-toast funnel (`usePipelineErrorToast().present`), threaded like `actionToast`
|
|
48
49
|
* because it is resolved in the store setup. Every rolled-back write reports through it rather
|
|
49
50
|
* than building its own `{ title, description: err.message }`, so a board failure reads the same
|
|
50
51
|
* as every other one: translated copy, and the raw detail copyable behind the disclosure.
|
|
@@ -35,7 +35,7 @@ function blockAsPatchable(block: Block): PatchSnapshot {
|
|
|
35
35
|
* in-closure functions, and the split is purely to keep every function within the size budget.
|
|
36
36
|
*/
|
|
37
37
|
export function createBoardPlacement(ctx: BoardWriteContext) {
|
|
38
|
-
const { blocks, getBlock, upsert, api,
|
|
38
|
+
const { blocks, getBlock, upsert, api, actionToast, tr, present } = ctx
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* Move a block into a new container at a new local position. Drag-reparent commits
|
|
@@ -78,19 +78,12 @@ export function createBoardPlacement(ctx: BoardWriteContext) {
|
|
|
78
78
|
// Offer an undo back to the previous container (a drag overshoot is easy). The undo
|
|
79
79
|
// move is itself non-undoable so the toast doesn't ping-pong.
|
|
80
80
|
if (opts.undoable && prevParentId) {
|
|
81
|
-
toast.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
{
|
|
88
|
-
label: tr('common.undo'),
|
|
89
|
-
icon: 'i-lucide-undo-2',
|
|
90
|
-
onClick: () =>
|
|
91
|
-
void reparentBlock(id, prevParentId, prevPosition, { undoable: false }),
|
|
92
|
-
},
|
|
93
|
-
],
|
|
81
|
+
actionToast.success('board.toast.moved', {
|
|
82
|
+
params: { name },
|
|
83
|
+
undo: {
|
|
84
|
+
run: () => void reparentBlock(id, prevParentId, prevPosition, { undoable: false }),
|
|
85
|
+
windowMs: UNDO_WINDOW_MS,
|
|
86
|
+
},
|
|
94
87
|
})
|
|
95
88
|
}
|
|
96
89
|
} catch (e) {
|
|
@@ -102,12 +95,7 @@ export function createBoardPlacement(ctx: BoardWriteContext) {
|
|
|
102
95
|
// translated prose, so map it here; anything else keeps the raw message as the last resort.
|
|
103
96
|
const refusal = moveRefusalKey(e)
|
|
104
97
|
if (refusal) {
|
|
105
|
-
toast.
|
|
106
|
-
title: tr('board.toast.moveFailed'),
|
|
107
|
-
description: tr(refusal),
|
|
108
|
-
icon: 'i-lucide-triangle-alert',
|
|
109
|
-
color: 'error',
|
|
110
|
-
})
|
|
98
|
+
actionToast.error('board.toast.moveFailed', { description: tr(refusal) })
|
|
111
99
|
} else present(e, 'board.toast.moveFailed')
|
|
112
100
|
}
|
|
113
101
|
}
|
|
@@ -11,7 +11,7 @@ import { UNDO_WINDOW_MS } from './context'
|
|
|
11
11
|
* stays internal — it is only wired into the delete toast's undo action.
|
|
12
12
|
*/
|
|
13
13
|
export function createBoardRemoval(ctx: BoardWriteContext) {
|
|
14
|
-
const { blocks, getBlock, pendingRemovals, pendingDoomed, api,
|
|
14
|
+
const { blocks, getBlock, pendingRemovals, pendingDoomed, api, actionToast, present } = ctx
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Optimistically drop a block and its descendants from the cache, returning a
|
|
@@ -148,18 +148,9 @@ export function createBoardRemoval(ctx: BoardWriteContext) {
|
|
|
148
148
|
const timer = setTimeout(() => void finalize(), UNDO_WINDOW_MS)
|
|
149
149
|
pendingRemovals.set(id, { snap, timer, wsId })
|
|
150
150
|
|
|
151
|
-
toast.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
color: 'neutral',
|
|
155
|
-
duration: UNDO_WINDOW_MS,
|
|
156
|
-
actions: [
|
|
157
|
-
{
|
|
158
|
-
label: tr('common.undo'),
|
|
159
|
-
icon: 'i-lucide-undo-2',
|
|
160
|
-
onClick: () => undoRemove(id),
|
|
161
|
-
},
|
|
162
|
-
],
|
|
151
|
+
actionToast.success('board.toast.deleted', {
|
|
152
|
+
params: { name: block.title },
|
|
153
|
+
undo: { run: () => undoRemove(id), windowMs: UNDO_WINDOW_MS },
|
|
163
154
|
})
|
|
164
155
|
}
|
|
165
156
|
|
package/app/stores/board.spec.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { setActivePinia, createPinia } from 'pinia'
|
|
|
3
3
|
import type { Block, BlockStatus } from '~/types/domain'
|
|
4
4
|
import { useBoardStore } from '~/stores/board'
|
|
5
5
|
import { useWorkspaceStore } from '~/stores/workspace'
|
|
6
|
+
import { UNDO_WINDOW_MS } from '~/stores/board/context'
|
|
6
7
|
import { EMPTY_FRAME_SIZE } from '~/utils/framePlacement'
|
|
7
8
|
import { frameContentSize, laneBodyHeightIn, LANE_GEOMETRY } from '~/utils/laneGeometry'
|
|
8
9
|
|
|
@@ -591,9 +592,17 @@ describe('board store deferred delete + undo', () => {
|
|
|
591
592
|
})
|
|
592
593
|
|
|
593
594
|
it('undo cancels the pending delete and restores the subtree', async () => {
|
|
594
|
-
const { store, removeSpy, actions } = setup(async () => {})
|
|
595
|
+
const { store, removeSpy, addSpy, actions } = setup(async () => {})
|
|
595
596
|
store.hydrate([frame('f1'), moduleBlock('m1', 'f1'), task('t1', 'm1')])
|
|
596
597
|
store.removeBlock('f1')
|
|
598
|
+
// The toast stays exactly as long as the delete is held open, or its Undo would undo nothing.
|
|
599
|
+
expect(addSpy).toHaveBeenCalledWith(
|
|
600
|
+
expect.objectContaining({
|
|
601
|
+
title: 'board.toast.deleted',
|
|
602
|
+
color: 'success',
|
|
603
|
+
duration: UNDO_WINDOW_MS,
|
|
604
|
+
}),
|
|
605
|
+
)
|
|
597
606
|
expect(actions).toHaveLength(1)
|
|
598
607
|
actions[0]!.onClick()
|
|
599
608
|
expect(store.getBlock('f1')?.id).toBe('f1')
|
package/app/stores/board.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { defineStore } from 'pinia'
|
|
|
2
2
|
import { ref } from 'vue'
|
|
3
3
|
import type { Block } from '~/types/domain'
|
|
4
4
|
import { useBlockQueries } from '~/composables/useBlockQueries'
|
|
5
|
+
import { useActionToast } from '~/composables/useActionToast'
|
|
5
6
|
import type { PendingRemoval } from '~/stores/board/context'
|
|
6
7
|
import { createBoardMutations } from '~/stores/board/mutations'
|
|
7
8
|
import { createBoardPlacement } from '~/stores/board/placement'
|
|
@@ -19,7 +20,7 @@ import { createBoardRemoval } from '~/stores/board/removal'
|
|
|
19
20
|
*/
|
|
20
21
|
export const useBoardStore = defineStore('board', () => {
|
|
21
22
|
const api = useApi()
|
|
22
|
-
const
|
|
23
|
+
const actionToast = useActionToast()
|
|
23
24
|
// Stores run outside a component `setup`, so resolve translations through the Nuxt app's
|
|
24
25
|
// global i18n instance (the same handle `plugins/locale.client.ts` uses) rather than
|
|
25
26
|
// `useI18n()`, which requires an active component instance.
|
|
@@ -148,7 +149,7 @@ export const useBoardStore = defineStore('board', () => {
|
|
|
148
149
|
pendingRemovals,
|
|
149
150
|
pendingDoomed,
|
|
150
151
|
api,
|
|
151
|
-
|
|
152
|
+
actionToast,
|
|
152
153
|
tr,
|
|
153
154
|
present: usePipelineErrorToast().present,
|
|
154
155
|
}
|
|
@@ -9,9 +9,11 @@ import type { BootstrapStepState } from '@cat-factory/contracts'
|
|
|
9
9
|
// every instance: the step list renders on every in-progress, parked and failed bootstrap card on
|
|
10
10
|
// the board, plus the inspector and the failure card.
|
|
11
11
|
|
|
12
|
-
/** How one step state renders: its icon,
|
|
12
|
+
/** How one step state renders: its icon, whether it spins (through `<Spinner :spinning>`), the
|
|
13
|
+
* icon's tone, and the label's. */
|
|
13
14
|
export interface BootstrapStepStyle {
|
|
14
15
|
icon: string
|
|
16
|
+
spin: boolean
|
|
15
17
|
iconClass: string
|
|
16
18
|
labelClass: string
|
|
17
19
|
}
|
|
@@ -24,36 +26,43 @@ export interface BootstrapStepStyle {
|
|
|
24
26
|
export const BOOTSTRAP_STEP_STYLE: Record<BootstrapStepState, BootstrapStepStyle> = {
|
|
25
27
|
pending: {
|
|
26
28
|
icon: 'i-lucide-circle',
|
|
29
|
+
spin: false,
|
|
27
30
|
iconClass: 'text-dimmed',
|
|
28
31
|
labelClass: 'text-dimmed',
|
|
29
32
|
},
|
|
30
33
|
running: {
|
|
31
34
|
icon: 'i-lucide-loader-circle',
|
|
32
|
-
|
|
35
|
+
spin: true,
|
|
36
|
+
iconClass: 'text-app-warning-400',
|
|
33
37
|
labelClass: 'text-app-warning-100',
|
|
34
38
|
},
|
|
35
39
|
awaiting_review: {
|
|
36
40
|
icon: 'i-lucide-user-check',
|
|
41
|
+
spin: false,
|
|
37
42
|
iconClass: 'text-app-warning-400',
|
|
38
43
|
labelClass: 'text-app-warning-100',
|
|
39
44
|
},
|
|
40
45
|
done: {
|
|
41
46
|
icon: 'i-lucide-check-circle-2',
|
|
47
|
+
spin: false,
|
|
42
48
|
iconClass: 'text-app-success-400',
|
|
43
49
|
labelClass: 'text-muted',
|
|
44
50
|
},
|
|
45
51
|
failed: {
|
|
46
52
|
icon: 'i-lucide-alert-triangle',
|
|
53
|
+
spin: false,
|
|
47
54
|
iconClass: 'text-app-error-400',
|
|
48
55
|
labelClass: 'text-app-error-200',
|
|
49
56
|
},
|
|
50
57
|
stopped: {
|
|
51
58
|
icon: 'i-lucide-circle-stop',
|
|
59
|
+
spin: false,
|
|
52
60
|
iconClass: 'text-muted',
|
|
53
61
|
labelClass: 'text-toned',
|
|
54
62
|
},
|
|
55
63
|
unknown: {
|
|
56
64
|
icon: 'i-lucide-help-circle',
|
|
65
|
+
spin: false,
|
|
57
66
|
iconClass: 'text-muted',
|
|
58
67
|
labelClass: 'text-muted',
|
|
59
68
|
},
|
|
@@ -341,14 +341,27 @@ function describeUnhandledSkipReason(reason: never): string {
|
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
/**
|
|
344
|
-
*
|
|
345
|
-
* while the run is live: once the run has failed, a step left mid-flight (its item
|
|
346
|
-
*
|
|
347
|
-
|
|
344
|
+
* Whether a subtask-item status icon spins (`<Spinner :spinning>`). An in-progress item spins only
|
|
345
|
+
* while the run is live: once the run has failed, a step left mid-flight (its item state still
|
|
346
|
+
* `in_progress`) keeps its colour but stops spinning, matching the frozen failure card.
|
|
347
|
+
*/
|
|
348
|
+
export function subtaskIconSpins(status: string, runFailed: boolean): boolean {
|
|
349
|
+
return status === 'in_progress' && !runFailed
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/** The tone of a subtask-item status icon: in-progress is primary, completed is emerald, the rest
|
|
353
|
+
* muted. Pair it with {@link subtaskIconSpins}. */
|
|
354
|
+
export function subtaskIconTone(status: string): string {
|
|
355
|
+
if (status === 'in_progress') return 'text-primary'
|
|
356
|
+
return status === 'completed' ? 'text-app-success-400' : 'text-dimmed'
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Tone plus a hand-written spin, for `board/nodes/TaskPipelineMini.vue` alone. That file is held
|
|
361
|
+
* out of the feedback-states slice (#2252) while the task-card rework rewrites it; when it moves
|
|
362
|
+
* to `<Spinner :spinning="subtaskIconSpins(...)">`, delete this and its `PENDING` entry in
|
|
363
|
+
* `scripts/check-frontend-feedback.mjs`.
|
|
348
364
|
*/
|
|
349
365
|
export function subtaskIconClass(status: string, runFailed: boolean): string[] {
|
|
350
|
-
return [
|
|
351
|
-
status === 'in_progress' ? (runFailed ? 'text-primary' : 'animate-spin text-primary') : '',
|
|
352
|
-
status === 'completed' ? 'text-app-success-400' : 'text-dimmed',
|
|
353
|
-
]
|
|
366
|
+
return [subtaskIconTone(status), subtaskIconSpins(status, runFailed) ? 'animate-spin' : '']
|
|
354
367
|
}
|
package/i18n/locales/de.json
CHANGED
|
@@ -53,7 +53,6 @@
|
|
|
53
53
|
"intro": "Jedes Preset legt für jeden Agenten ein {baseModel} fest, mit optionalen Overrides je Agent. Ein an einer einzelnen Aufgabe angeheftetes Modell überschreibt weiterhin das Preset.",
|
|
54
54
|
"introBaseModel": "Basismodell",
|
|
55
55
|
"newPreset": "Neues Preset",
|
|
56
|
-
"loadingCatalog": "Modellkatalog wird geladen…",
|
|
57
56
|
"default": "Standard",
|
|
58
57
|
"setDefaultTitle": "Als Workspace-Standard festlegen",
|
|
59
58
|
"editTitle": "Preset bearbeiten",
|
|
@@ -62,7 +61,8 @@
|
|
|
62
61
|
"basePrefix": "Basis:",
|
|
63
62
|
"overrideCount": "{count} Override | {count} Overrides",
|
|
64
63
|
"empty": "Noch keine Presets. Erstelle eines, um Modelle deinen Agenten zuzuordnen.",
|
|
65
|
-
"customRouteOrder": "eigene Routen-Reihenfolge"
|
|
64
|
+
"customRouteOrder": "eigene Routen-Reihenfolge",
|
|
65
|
+
"catalogFailed": "Der Modellkatalog wurde nicht geladen. Versuchen Sie es erneut, um die Presets zu sehen."
|
|
66
66
|
},
|
|
67
67
|
"editor": {
|
|
68
68
|
"useBaseModel": "Basismodell verwenden",
|
|
@@ -82,7 +82,8 @@
|
|
|
82
82
|
"deleteFailed": "Preset konnte nicht gelöscht werden",
|
|
83
83
|
"nameRequiredTitle": "Name erforderlich",
|
|
84
84
|
"nameRequiredBody": "Gib dem Preset einen Namen.",
|
|
85
|
-
"saveFailed": "Preset konnte nicht gespeichert werden"
|
|
85
|
+
"saveFailed": "Preset konnte nicht gespeichert werden",
|
|
86
|
+
"catalogFailed": "Modellkatalog konnte nicht geladen werden"
|
|
86
87
|
},
|
|
87
88
|
"routes": {
|
|
88
89
|
"direct": "Die eigene Provider-API des Modells",
|
|
@@ -237,7 +238,6 @@
|
|
|
237
238
|
"overrideActive": "Aktiv",
|
|
238
239
|
"personalOverrideHint": "Überschreibe den Workspace-Handler für diesen Provisioning-Typ auf deiner eigenen Maschine. Pro Benutzer gespeichert.",
|
|
239
240
|
"removeOverride": "Override entfernen",
|
|
240
|
-
"loading": "Infrastruktureinstellungen werden geladen…",
|
|
241
241
|
"kubeNoun": "der Kubernetes-Handler",
|
|
242
242
|
"kubeOverrideNoun": "der Kubernetes-Override",
|
|
243
243
|
"customNoun": "dieser Handler",
|
|
@@ -416,7 +416,6 @@
|
|
|
416
416
|
},
|
|
417
417
|
"taskTypeSuppressions": {
|
|
418
418
|
"intro": "Wählen Sie aus, welche wiederverwendbaren Operationen dieses Deployments auf diesem Board angeboten werden. Wird eine ausgeblendet, verschwindet sie hier aus der Aufgabenauswahl und das Anlegen von Arbeit darunter wird abgelehnt; andere Boards bleiben unberührt.",
|
|
419
|
-
"loading": "Operationen werden geladen…",
|
|
420
419
|
"empty": "Dieses Deployment registriert keine wiederverwendbaren Operationen.",
|
|
421
420
|
"offer": "Auf diesem Board anbieten",
|
|
422
421
|
"saveFailed": "Die angebotenen Operationen konnten nicht geändert werden"
|
|
@@ -1025,9 +1024,7 @@
|
|
|
1025
1024
|
"toast": {
|
|
1026
1025
|
"connected": "OpenRouter-Schlüssel verbunden",
|
|
1027
1026
|
"connectFailed": "Schlüssel konnte nicht verbunden werden",
|
|
1028
|
-
"rejected": "OpenRouter hat den Schlüssel abgelehnt.",
|
|
1029
1027
|
"unreachable": "OpenRouter konnte nicht erreicht werden",
|
|
1030
|
-
"connectFirst": "Verbinde zuerst einen OpenRouter-Schlüssel.",
|
|
1031
1028
|
"saved": "OpenRouter-Katalog gespeichert",
|
|
1032
1029
|
"saveFailed": "Katalog konnte nicht gespeichert werden"
|
|
1033
1030
|
}
|
|
@@ -3675,7 +3672,6 @@
|
|
|
3675
3672
|
"connect": {
|
|
3676
3673
|
"yourInstallations": "Ihre Installationen",
|
|
3677
3674
|
"refresh": "Aktualisieren",
|
|
3678
|
-
"lookingForInstallations": "Suche nach Installationen…",
|
|
3679
3675
|
"noInstallations": "Noch keine Installationen für die App gefunden. Installieren Sie sie unten oder verbinden Sie per ID.",
|
|
3680
3676
|
"installationMeta": "{targetType} · Installation {id}",
|
|
3681
3677
|
"linked": "verknüpft",
|
|
@@ -3702,14 +3698,12 @@
|
|
|
3702
3698
|
"resync": "Neu synchronisieren",
|
|
3703
3699
|
"backfill": "Backfill",
|
|
3704
3700
|
"disconnect": "Trennen",
|
|
3705
|
-
"loading": "Wird geladen…",
|
|
3706
3701
|
"tabs": {
|
|
3707
3702
|
"repos": "Repositorys",
|
|
3708
3703
|
"issues": "Issues"
|
|
3709
3704
|
},
|
|
3710
3705
|
"linkedToBoard": "Mit diesem Board verknüpft",
|
|
3711
3706
|
"manageRepos": "Repos verwalten",
|
|
3712
|
-
"loadingRepos": "Repositorys werden geladen…",
|
|
3713
3707
|
"private": "privat",
|
|
3714
3708
|
"saveSelection": "Auswahl speichern",
|
|
3715
3709
|
"noLinkedRepos": "Noch keine Repositorys verknüpft. Verwenden Sie \"Repos verwalten\", um auszuwählen, welche Repositorys dieses Board verfolgt.",
|
|
@@ -3792,7 +3786,6 @@
|
|
|
3792
3786
|
},
|
|
3793
3787
|
"repoTree": {
|
|
3794
3788
|
"root": "root",
|
|
3795
|
-
"loading": "Wird geladen…",
|
|
3796
3789
|
"noSubdirectories": "Keine Unterverzeichnisse hier.",
|
|
3797
3790
|
"empty": "Nichts hier.",
|
|
3798
3791
|
"select": "Auswählen",
|
|
@@ -3875,8 +3868,6 @@
|
|
|
3875
3868
|
"exportJson": "JSON exportieren",
|
|
3876
3869
|
"exportHint": "Einen LLM-freundlichen JSON-Export dieses Laufs herunterladen",
|
|
3877
3870
|
"closeEsc": "Schließen (Esc)",
|
|
3878
|
-
"loadingActivity": "Modellaktivität wird geladen…",
|
|
3879
|
-
"loadingContext": "Bereitgestellter Kontext wird geladen…",
|
|
3880
3871
|
"noCalls": "Für diesen Lauf wurden keine Modellaufrufe aufgezeichnet.",
|
|
3881
3872
|
"noContext": "Für diesen Lauf ist kein Agent-Kontext gespeichert. Er wird pro Dispatch erfasst, wenn im Workspace 'Vollständigen Agent-Kontext speichern' aktiviert ist.",
|
|
3882
3873
|
"contextError": "Der bereitgestellte Kontext konnte nicht geladen werden.",
|
|
@@ -3968,7 +3959,6 @@
|
|
|
3968
3959
|
"details": "Details"
|
|
3969
3960
|
},
|
|
3970
3961
|
"webSearch": "Websuche",
|
|
3971
|
-
"loadingSearch": "Websuchen werden geladen…",
|
|
3972
3962
|
"noSearch": "Für diesen Lauf wurden keine Websuchen aufgezeichnet. Anfragen werden erfasst, wenn die Websuche läuft und im Workspace 'Vollständigen Agent-Kontext speichern' aktiviert ist.",
|
|
3973
3963
|
"search": {
|
|
3974
3964
|
"available": "Verfügbar",
|
|
@@ -4007,7 +3997,6 @@
|
|
|
4007
3997
|
"toolCalls": {
|
|
4008
3998
|
"title": "Werkzeugaufrufe",
|
|
4009
3999
|
"subtitle": "was die Agenten getan haben, in der Reihenfolge, in der sie es taten",
|
|
4010
|
-
"loading": "Werkzeugaufrufe werden geladen…",
|
|
4011
4000
|
"error": "Die Werkzeugaufrufe konnten nicht geladen werden.",
|
|
4012
4001
|
"none": "Für diesen Lauf wurden keine Werkzeugaufrufe aufgezeichnet.",
|
|
4013
4002
|
"noneMatching": "Keine Werkzeugaufrufe entsprechen diesem Filter.",
|
|
@@ -4028,7 +4017,6 @@
|
|
|
4028
4017
|
"title": "Plattform-Observability",
|
|
4029
4018
|
"refresh": "Aktualisieren",
|
|
4030
4019
|
"close": "Schließen",
|
|
4031
|
-
"loading": "Plattformzustand wird geladen…",
|
|
4032
4020
|
"retry": "Erneut versuchen",
|
|
4033
4021
|
"window": {
|
|
4034
4022
|
"oneHour": "Letzte Stunde",
|
|
@@ -4109,7 +4097,6 @@
|
|
|
4109
4097
|
"reports": {
|
|
4110
4098
|
"title": "Berichte",
|
|
4111
4099
|
"refresh": "Aktualisieren",
|
|
4112
|
-
"loading": "Berichte werden geladen…",
|
|
4113
4100
|
"retry": "Erneut versuchen",
|
|
4114
4101
|
"error": "Berichte konnten nicht geladen werden.",
|
|
4115
4102
|
"period": "{from} bis {to}",
|
|
@@ -4353,7 +4340,8 @@
|
|
|
4353
4340
|
"scopes": "Du wirst um folgende Berechtigungen gebeten: {scopes}",
|
|
4354
4341
|
"fallback": "Lieber ein Token? Nutze stattdessen die Felder unten.",
|
|
4355
4342
|
"failed": "Die Anmeldung bei {source} konnte nicht gestartet werden"
|
|
4356
|
-
}
|
|
4343
|
+
},
|
|
4344
|
+
"disconnectFailed": "Trennen nicht möglich"
|
|
4357
4345
|
},
|
|
4358
4346
|
"spawn": {
|
|
4359
4347
|
"title": "Struktur-Vorschau",
|
|
@@ -4501,7 +4489,8 @@
|
|
|
4501
4489
|
"updateConnection": "Verbindung aktualisieren",
|
|
4502
4490
|
"connect": "Verbinden",
|
|
4503
4491
|
"oauthButton": "Mit {label} verbinden",
|
|
4504
|
-
"oauthOr": "oder mit einem API-Schlüssel verbinden"
|
|
4492
|
+
"oauthOr": "oder mit einem API-Schlüssel verbinden",
|
|
4493
|
+
"disconnectFailed": "Trennen nicht möglich"
|
|
4505
4494
|
}
|
|
4506
4495
|
},
|
|
4507
4496
|
"bugHunt": {
|
|
@@ -4610,12 +4599,10 @@
|
|
|
4610
4599
|
"guidedReview": {
|
|
4611
4600
|
"title": "Geführtes Review",
|
|
4612
4601
|
"titleFor": "{repo} #{number}: {title}",
|
|
4613
|
-
"loading": "Review wird geladen…",
|
|
4614
4602
|
"outOfDate": "Live-Updates sind fehlgeschlagen, daher ist diese Ansicht möglicherweise veraltet.",
|
|
4615
4603
|
"openFromTask": "Mit geführtem Review erkunden",
|
|
4616
4604
|
"picker": {
|
|
4617
4605
|
"intro": "Wähle ein Repository und einen Pull Request. Du erhältst einen Überblick über die Änderung und kannst in separaten Threads Fragen dazu stellen.",
|
|
4618
|
-
"loading": "Repositories werden geladen…",
|
|
4619
4606
|
"noRepos": "Mit diesem Workspace sind noch keine Repositories verknüpft.",
|
|
4620
4607
|
"repo": "Repository",
|
|
4621
4608
|
"openPulls": "Offene Pull Requests",
|
|
@@ -5120,7 +5107,6 @@
|
|
|
5120
5107
|
"answerVerb": "Beantworten",
|
|
5121
5108
|
"dismissVerb": "verwerfen",
|
|
5122
5109
|
"empty": "Noch keine Prüfung. Der Prüfer läuft automatisch als erster Schritt, wenn die Pipeline dieser Aufgabe startet.",
|
|
5123
|
-
"loadingReview": "Prüfung wird geladen…",
|
|
5124
5110
|
"reviewing": "Anforderungen werden geprüft…",
|
|
5125
5111
|
"settled": "Die Anforderungen sind festgelegt. Das folgende Dokument verwendet jeder nachgelagerte Agentenschritt.",
|
|
5126
5112
|
"exceeded": {
|
|
@@ -5836,7 +5822,6 @@
|
|
|
5836
5822
|
"awaiting": "{total} Kandidaten wurden erzeugt und warten auf den Vergleich."
|
|
5837
5823
|
},
|
|
5838
5824
|
"asset": {
|
|
5839
|
-
"loading": "Datei wird geladen …",
|
|
5840
5825
|
"loadFailed": "Die gespeicherte Datei konnte nicht geladen werden.",
|
|
5841
5826
|
"retry": "Erneut versuchen",
|
|
5842
5827
|
"open": "Öffnen",
|
|
@@ -5862,7 +5847,6 @@
|
|
|
5862
5847
|
"introChoose": "Wählen",
|
|
5863
5848
|
"introDismiss": "verwerfen",
|
|
5864
5849
|
"empty": "Noch kein Brainstorm. Es läuft automatisch, wenn die Pipeline dieser Aufgabe den Brainstorm-Schritt erreicht.",
|
|
5865
|
-
"loading": "Brainstorm wird geladen…",
|
|
5866
5850
|
"generating": "Optionen werden generiert…",
|
|
5867
5851
|
"settledBanner": "Der {doc} ist festgelegt. Das folgende Dokument verwendet die nächste Phase.",
|
|
5868
5852
|
"exceeded": {
|
|
@@ -5946,7 +5930,6 @@
|
|
|
5946
5930
|
"introAnswer": "Beantworten",
|
|
5947
5931
|
"introDismiss": "verwerfen",
|
|
5948
5932
|
"empty": "Noch keine Prüfung. Der Prüfer läuft automatisch als erster Schritt, wenn die Pipeline dieser Aufgabe startet.",
|
|
5949
|
-
"loadingReview": "Prüfung wird geladen…",
|
|
5950
5933
|
"triaging": "Bug-Report wird triagiert…",
|
|
5951
5934
|
"converged": "Der Bug-Report ist geklärt. Der folgende Bericht verwendet jeder nachgelagerte Agentenschritt.",
|
|
5952
5935
|
"capHeading": "Das {max}-Iterationen-Limit wurde mit noch offenen Befunden erreicht.",
|
|
@@ -6213,7 +6196,6 @@
|
|
|
6213
6196
|
}
|
|
6214
6197
|
},
|
|
6215
6198
|
"common": {
|
|
6216
|
-
"loading": "Wird geladen…",
|
|
6217
6199
|
"save": "Speichern",
|
|
6218
6200
|
"cancel": "Abbrechen",
|
|
6219
6201
|
"retry": "Erneut versuchen",
|
|
@@ -6534,6 +6516,9 @@
|
|
|
6534
6516
|
"title": "Diese Ansicht konnte nicht geladen werden",
|
|
6535
6517
|
"body": "Ihr Code konnte nicht geladen werden. Meist wurde die Anwendung aktualisiert, während dieser Tab geöffnet war, sodass die angeforderten Dateien nicht mehr auf dem Server liegen. Laden Sie neu, um die aktuelle Version zu erhalten.",
|
|
6536
6518
|
"reload": "Neu laden"
|
|
6519
|
+
},
|
|
6520
|
+
"reported": {
|
|
6521
|
+
"description": "Der Vorgang lief und meldete einen Fehler. „Details anzeigen“ zeigt, was er gemeldet hat."
|
|
6537
6522
|
}
|
|
6538
6523
|
},
|
|
6539
6524
|
"slack": {
|
|
@@ -6850,7 +6835,6 @@
|
|
|
6850
6835
|
"consensus": {
|
|
6851
6836
|
"titlePrefix": "Konsens",
|
|
6852
6837
|
"participantCount": "keine Teilnehmer | ein Teilnehmer | {count} Teilnehmer",
|
|
6853
|
-
"loading": "Konsens-Sitzung wird geladen…",
|
|
6854
6838
|
"empty": "Für diesen Schritt wurde noch keine Konsens-Sitzung ausgeführt.",
|
|
6855
6839
|
"failed": "Konsens fehlgeschlagen: {error}",
|
|
6856
6840
|
"unknownError": "unbekannter Fehler",
|
|
@@ -6882,7 +6866,6 @@
|
|
|
6882
6866
|
},
|
|
6883
6867
|
"spec": {
|
|
6884
6868
|
"title": "Anforderungen",
|
|
6885
|
-
"loading": "Spezifikation wird geladen…",
|
|
6886
6869
|
"error": "Die Spezifikation konnte nicht geladen werden. Versuche, dieses Fenster erneut zu öffnen.",
|
|
6887
6870
|
"overview": "Übersicht",
|
|
6888
6871
|
"noFeatureGroups": "Keine Feature-Gruppen",
|
|
@@ -7072,8 +7055,7 @@
|
|
|
7072
7055
|
},
|
|
7073
7056
|
"shot": {
|
|
7074
7057
|
"failed": "Fehlgeschlagen",
|
|
7075
|
-
"failedToLoad": "Laden fehlgeschlagen"
|
|
7076
|
-
"loading": "Wird geladen…"
|
|
7058
|
+
"failedToLoad": "Laden fehlgeschlagen"
|
|
7077
7059
|
},
|
|
7078
7060
|
"screenshotAlt": "{view} (Screenshot)",
|
|
7079
7061
|
"screenshots": "Screenshots",
|