@cat-factory/app 0.261.2 → 0.261.4
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 +40 -0
- package/app/components/board/AddTaskModal.vue +10 -6
- package/app/components/board/AgentStopButton.vue +2 -5
- package/app/components/board/CreateInitiativeModal.vue +2 -7
- package/app/components/board/RecurringPipelineModal.vue +10 -6
- package/app/components/bootstrap/BootstrapModal.vue +5 -24
- package/app/components/brainstorm/BrainstormWindow.vue +7 -15
- package/app/components/clarity/ClarityReviewWindow.vue +7 -15
- package/app/components/documents/DocumentImportModal.vue +2 -6
- package/app/components/documents/DocumentSourceConnectModal.vue +3 -12
- package/app/components/documents/DocumentSyncState.vue +2 -7
- package/app/components/documents/DocumentTemplatesModal.vue +4 -19
- package/app/components/documents/SpawnPreviewModal.vue +3 -12
- package/app/components/foundational/FoundationalServiceCatalogList.vue +3 -11
- package/app/components/foundational/FoundationalServiceRegistry.vue +3 -11
- package/app/components/foundational/FoundationalServiceSources.vue +5 -13
- package/app/components/foundational/FoundationalSuppressions.vue +2 -6
- package/app/components/fragments/FragmentLibraryManager.vue +12 -20
- package/app/components/github/AddServiceFromRepoModal.vue +3 -12
- package/app/components/github/GitHubConnect.vue +4 -12
- package/app/components/github/GitHubPanel.vue +9 -17
- package/app/components/github/RepoTreeBrowser.vue +2 -7
- package/app/components/humanTest/HumanTestWindow.vue +2 -7
- package/app/components/initiative/InitiativeTrackerWindow.vue +2 -3
- package/app/components/layout/AccountAuditLog.vue +2 -7
- package/app/components/layout/AccountDeploymentSettings.vue +11 -51
- package/app/components/layout/AccountModelPolicySettings.vue +2 -5
- package/app/components/layout/AccountPlatformAlertSettings.vue +2 -5
- package/app/components/layout/AccountRunCredentialSettings.vue +2 -5
- package/app/components/layout/AccountTeamSettings.vue +9 -18
- package/app/components/layout/BoardSwitcher.vue +6 -14
- package/app/components/layout/BoardToolbar.vue +3 -10
- package/app/components/layout/NotificationsInbox.vue +3 -13
- package/app/components/layout/WorkspaceMembersSettings.vue +6 -15
- package/app/components/notifications/NotificationSettingsPanel.vue +3 -11
- package/app/components/panels/DecisionModal.vue +2 -7
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +4 -20
- package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +3 -11
- package/app/components/panels/inspector/ServiceTestSecrets.vue +3 -11
- package/app/components/panels/inspector/ServiceValidationConfig.vue +4 -12
- package/app/components/pipeline/PipelineBuilder.vue +4 -7
- package/app/components/providers/ApiKeysSection.vue +4 -15
- package/app/components/providers/PersonalCredentialModal.vue +2 -5
- package/app/components/providers/PersonalSubscriptionSection.vue +3 -10
- package/app/components/providers/VendorCredentialsModal.vue +5 -20
- package/app/components/requirements/RequirementsReviewWindow.vue +11 -19
- package/app/components/sandbox/SandboxPanel.vue +4 -18
- package/app/components/settings/ApiTokensPanel.vue +4 -12
- package/app/components/settings/BudgetSettings.vue +2 -5
- package/app/components/settings/CloudflareHandlerSection.vue +3 -12
- package/app/components/settings/ConsensusGroupsSection.vue +3 -12
- package/app/components/settings/CustomManifestTypeEditor.vue +3 -13
- package/app/components/settings/DefaultProvisionTypeSection.vue +2 -5
- package/app/components/settings/InfraHandlersConfigurator.vue +7 -14
- package/app/components/settings/InfrastructureBackendPicker.vue +2 -7
- package/app/components/settings/IssueTrackerPanel.vue +4 -18
- package/app/components/settings/LocalContainerPoolSettings.vue +2 -6
- package/app/components/settings/LocalModelEndpointsPanel.vue +3 -11
- package/app/components/settings/ModelConfigurationPanel.vue +13 -16
- package/app/components/settings/ModelPresetHealthModal.vue +3 -13
- package/app/components/settings/ObservabilityConnectionPanel.vue +6 -14
- package/app/components/settings/OpenRouterCatalogPanel.vue +3 -12
- package/app/components/settings/PackageRegistriesPanel.vue +4 -12
- package/app/components/settings/ProviderConnectionTab.vue +5 -13
- package/app/components/settings/RiskPolicyHealthModal.vue +2 -7
- package/app/components/settings/RiskPolicyPanel.vue +5 -13
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +2 -7
- package/app/components/settings/SharedStacksPanel.vue +10 -20
- package/app/components/settings/TaskTypeSuppressionsPanel.vue +3 -12
- package/app/components/settings/UserSecretsSection.vue +3 -11
- package/app/components/settings/WorkspaceMetadataSettings.vue +2 -6
- package/app/components/settings/WorkspaceSettingsPanel.vue +2 -6
- package/app/components/skills/SkillLibraryManager.vue +5 -13
- package/app/components/slack/SlackPanel.vue +7 -15
- package/app/components/tasks/BugHuntModal.vue +2 -6
- package/app/components/tasks/TaskImportModal.vue +2 -6
- package/app/components/tasks/TaskSourceConnectModal.vue +4 -18
- package/app/composables/useBlockDeletion.ts +2 -6
- package/app/composables/useCopyToClipboard.ts +7 -1
- package/app/composables/usePipelineErrorToast.spec.ts +76 -16
- package/app/composables/usePipelineErrorToast.ts +109 -50
- package/app/stores/board/context.ts +9 -2
- package/app/stores/board/dependencies.ts +3 -13
- package/app/stores/board/mutations.ts +2 -7
- package/app/stores/board/placement.ts +12 -25
- package/app/stores/board/removal.ts +2 -7
- package/app/stores/board.spec.ts +15 -8
- package/app/stores/board.ts +11 -1
- package/app/stores/recurringPipelines.ts +5 -11
- package/package.json +2 -2
|
@@ -31,8 +31,8 @@ export const UNDO_WINDOW_MS = 6000
|
|
|
31
31
|
* the `board` store setup and threaded into {@link createBoardMutations} / {@link createBoardRemoval}
|
|
32
32
|
* so the split operations stay behaviourally identical to the original single-closure store — the
|
|
33
33
|
* factories are cohesive extractions purely to keep each function within the size budget, not new
|
|
34
|
-
* seams. `api`/`toast`/`tr` are the store's own resolved handles (a store runs outside a
|
|
35
|
-
* `setup`, so `tr` bridges to the Nuxt app's global i18n instance).
|
|
34
|
+
* seams. `api`/`toast`/`tr`/`present` are the store's own resolved handles (a store runs outside a
|
|
35
|
+
* component `setup`, so `tr` bridges to the Nuxt app's global i18n instance).
|
|
36
36
|
*/
|
|
37
37
|
export interface BoardWriteContext {
|
|
38
38
|
blocks: Ref<Block[]>
|
|
@@ -43,4 +43,11 @@ export interface BoardWriteContext {
|
|
|
43
43
|
api: ReturnType<typeof useApi>
|
|
44
44
|
toast: ReturnType<typeof useToast>
|
|
45
45
|
tr: (key: string, params?: Record<string, unknown>) => string
|
|
46
|
+
/**
|
|
47
|
+
* The SPA's one failure-toast funnel (`usePipelineErrorToast().present`), threaded like `toast`
|
|
48
|
+
* because it is resolved in the store setup. Every rolled-back write reports through it rather
|
|
49
|
+
* than building its own `{ title, description: err.message }`, so a board failure reads the same
|
|
50
|
+
* as every other one: translated copy, and the raw detail copyable behind the disclosure.
|
|
51
|
+
*/
|
|
52
|
+
present: (error: unknown, titleKey?: string) => void
|
|
46
53
|
}
|
|
@@ -8,7 +8,7 @@ import type { BoardWriteContext } from './context'
|
|
|
8
8
|
* the split is purely to keep every function within the size budget.
|
|
9
9
|
*/
|
|
10
10
|
export function createBoardDependencies(ctx: BoardWriteContext) {
|
|
11
|
-
const { getBlock, upsert, api,
|
|
11
|
+
const { getBlock, upsert, api, present } = ctx
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Toggle a dependency edge target -> source (target dependsOn source). The backend
|
|
@@ -20,12 +20,7 @@ export function createBoardDependencies(ctx: BoardWriteContext) {
|
|
|
20
20
|
try {
|
|
21
21
|
upsert(await api.toggleDependency(useWorkspaceStore().requireId(), targetId, { sourceId }))
|
|
22
22
|
} catch (e) {
|
|
23
|
-
toast.
|
|
24
|
-
title: tr('board.toast.linkFailed'),
|
|
25
|
-
description: e instanceof Error ? e.message : String(e),
|
|
26
|
-
icon: 'i-lucide-triangle-alert',
|
|
27
|
-
color: 'error',
|
|
28
|
-
})
|
|
23
|
+
present(e, 'board.toast.linkFailed')
|
|
29
24
|
}
|
|
30
25
|
}
|
|
31
26
|
|
|
@@ -39,12 +34,7 @@ export function createBoardDependencies(ctx: BoardWriteContext) {
|
|
|
39
34
|
} catch (e) {
|
|
40
35
|
// Mirror `toggleDependency`: a failure must surface (and leave the edge visible) rather
|
|
41
36
|
// than rejecting unhandled with no feedback.
|
|
42
|
-
toast.
|
|
43
|
-
title: tr('board.toast.unlinkFailed'),
|
|
44
|
-
description: e instanceof Error ? e.message : String(e),
|
|
45
|
-
icon: 'i-lucide-triangle-alert',
|
|
46
|
-
color: 'error',
|
|
47
|
-
})
|
|
37
|
+
present(e, 'board.toast.unlinkFailed')
|
|
48
38
|
}
|
|
49
39
|
}
|
|
50
40
|
|
|
@@ -17,7 +17,7 @@ import type { BoardWriteContext } from './context'
|
|
|
17
17
|
* {@link createBoardPlacement}.
|
|
18
18
|
*/
|
|
19
19
|
export function createBoardMutations(ctx: BoardWriteContext) {
|
|
20
|
-
const { getBlock, upsert, api,
|
|
20
|
+
const { getBlock, upsert, api, present } = ctx
|
|
21
21
|
|
|
22
22
|
async function addBlock(type: BlockType, position: { x: number; y: number }): Promise<Block> {
|
|
23
23
|
const block = await api.addFrame(useWorkspaceStore().requireId(), { type, position })
|
|
@@ -127,12 +127,7 @@ export function createBoardMutations(ctx: BoardWriteContext) {
|
|
|
127
127
|
upsert(await api.assignToEpic(useWorkspaceStore().requireId(), taskId, { epicId }))
|
|
128
128
|
} catch (e) {
|
|
129
129
|
t.epicId = prev
|
|
130
|
-
toast.
|
|
131
|
-
title: tr('board.toast.epicFailed'),
|
|
132
|
-
description: e instanceof Error ? e.message : String(e),
|
|
133
|
-
icon: 'i-lucide-triangle-alert',
|
|
134
|
-
color: 'error',
|
|
135
|
-
})
|
|
130
|
+
present(e, 'board.toast.epicFailed')
|
|
136
131
|
}
|
|
137
132
|
}
|
|
138
133
|
|
|
@@ -34,7 +34,7 @@ function blockAsPatchable(block: Block): PatchSnapshot {
|
|
|
34
34
|
* in-closure functions, and the split is purely to keep every function within the size budget.
|
|
35
35
|
*/
|
|
36
36
|
export function createBoardPlacement(ctx: BoardWriteContext) {
|
|
37
|
-
const { blocks, getBlock, upsert, api, toast, tr } = ctx
|
|
37
|
+
const { blocks, getBlock, upsert, api, toast, tr, present } = ctx
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* Move a block into a new container at a new local position. Drag-reparent commits
|
|
@@ -94,12 +94,14 @@ export function createBoardPlacement(ctx: BoardWriteContext) {
|
|
|
94
94
|
// can act on rather than a fault. The backend sends the machine-readable reason and no
|
|
95
95
|
// translated prose, so map it here; anything else keeps the raw message as the last resort.
|
|
96
96
|
const refusal = moveRefusalKey(e)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
97
|
+
if (refusal) {
|
|
98
|
+
toast.add({
|
|
99
|
+
title: tr('board.toast.moveFailed'),
|
|
100
|
+
description: tr(refusal),
|
|
101
|
+
icon: 'i-lucide-triangle-alert',
|
|
102
|
+
color: 'error',
|
|
103
|
+
})
|
|
104
|
+
} else present(e, 'board.toast.moveFailed')
|
|
103
105
|
}
|
|
104
106
|
}
|
|
105
107
|
|
|
@@ -137,12 +139,7 @@ export function createBoardPlacement(ctx: BoardWriteContext) {
|
|
|
137
139
|
// Restore the pre-drag position — a rejected move must not leave the block at a
|
|
138
140
|
// spot the server never stored (a lie that survives until the next re-hydrate).
|
|
139
141
|
b.position = prevPosition
|
|
140
|
-
toast.
|
|
141
|
-
title: tr('board.toast.moveFailed'),
|
|
142
|
-
description: e instanceof Error ? e.message : String(e),
|
|
143
|
-
icon: 'i-lucide-triangle-alert',
|
|
144
|
-
color: 'error',
|
|
145
|
-
})
|
|
142
|
+
present(e, 'board.toast.moveFailed')
|
|
146
143
|
}
|
|
147
144
|
}
|
|
148
145
|
|
|
@@ -198,12 +195,7 @@ export function createBoardPlacement(ctx: BoardWriteContext) {
|
|
|
198
195
|
upsert(await api.resizeBlock(useWorkspaceStore().requireId(), id, bounds))
|
|
199
196
|
} catch (e) {
|
|
200
197
|
previewResize(id, from.position, from.size)
|
|
201
|
-
toast.
|
|
202
|
-
title: tr('board.toast.resizeFailed'),
|
|
203
|
-
description: e instanceof Error ? e.message : String(e),
|
|
204
|
-
icon: 'i-lucide-triangle-alert',
|
|
205
|
-
color: 'error',
|
|
206
|
-
})
|
|
198
|
+
present(e, 'board.toast.resizeFailed')
|
|
207
199
|
}
|
|
208
200
|
}
|
|
209
201
|
|
|
@@ -244,12 +236,7 @@ export function createBoardPlacement(ctx: BoardWriteContext) {
|
|
|
244
236
|
if (cur[key] === patch[key]) cur[key] = prev[key]
|
|
245
237
|
}
|
|
246
238
|
}
|
|
247
|
-
toast.
|
|
248
|
-
title: tr('board.toast.updateFailed'),
|
|
249
|
-
description: e instanceof Error ? e.message : String(e),
|
|
250
|
-
icon: 'i-lucide-triangle-alert',
|
|
251
|
-
color: 'error',
|
|
252
|
-
})
|
|
239
|
+
present(e, 'board.toast.updateFailed')
|
|
253
240
|
return false
|
|
254
241
|
}
|
|
255
242
|
}
|
|
@@ -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, toast, tr } = ctx
|
|
14
|
+
const { blocks, getBlock, pendingRemovals, pendingDoomed, api, toast, tr, present } = ctx
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Optimistically drop a block and its descendants from the cache, returning a
|
|
@@ -142,12 +142,7 @@ export function createBoardRemoval(ctx: BoardWriteContext) {
|
|
|
142
142
|
// switch must not inject the old subtree onto the workspace now on screen (it
|
|
143
143
|
// re-hydrates from the server there on the next refresh anyway).
|
|
144
144
|
if (useWorkspaceStore().workspaceId === pending.wsId) reattach(pending.snap)
|
|
145
|
-
toast.
|
|
146
|
-
title: tr('board.toast.deleteFailed'),
|
|
147
|
-
description: e instanceof Error ? e.message : String(e),
|
|
148
|
-
icon: 'i-lucide-triangle-alert',
|
|
149
|
-
color: 'error',
|
|
150
|
-
})
|
|
145
|
+
present(e, 'board.toast.deleteFailed')
|
|
151
146
|
}
|
|
152
147
|
}
|
|
153
148
|
const timer = setTimeout(() => void finalize(), UNDO_WINDOW_MS)
|
package/app/stores/board.spec.ts
CHANGED
|
@@ -246,11 +246,15 @@ describe('board store read getters', () => {
|
|
|
246
246
|
expect(() => store.previewMove('missing', { x: 1, y: 1 })).not.toThrow()
|
|
247
247
|
})
|
|
248
248
|
|
|
249
|
-
it('updateBlock restores the patched fields and
|
|
250
|
-
// Capture
|
|
251
|
-
//
|
|
249
|
+
it('updateBlock restores the patched fields and reports the failure when the write fails', async () => {
|
|
250
|
+
// Capture what the store surfaces on failure. Every rolled-back write drains into the shared
|
|
251
|
+
// failure funnel (`usePipelineErrorToast().present`) rather than building its own toast, so the
|
|
252
|
+
// assertion is on the funnel and on the TITLE KEY it was given. Re-stub before creating the
|
|
253
|
+
// store: it resolves both handles once at setup.
|
|
252
254
|
const addSpy = vi.fn()
|
|
255
|
+
const presentSpy = vi.fn()
|
|
253
256
|
vi.stubGlobal('useToast', () => ({ add: addSpy }))
|
|
257
|
+
vi.stubGlobal('usePipelineErrorToast', () => ({ present: presentSpy }))
|
|
254
258
|
setActivePinia(createPinia())
|
|
255
259
|
const s = useBoardStore()
|
|
256
260
|
s.hydrate([frame('f1', { title: 'Original', description: 'orig' })])
|
|
@@ -263,7 +267,7 @@ describe('board store read getters', () => {
|
|
|
263
267
|
)
|
|
264
268
|
expect(s.getBlock('f1')?.title).toBe('Original')
|
|
265
269
|
expect(s.getBlock('f1')?.description).toBe('orig')
|
|
266
|
-
expect(
|
|
270
|
+
expect(presentSpy).toHaveBeenCalledWith(expect.any(Error), 'board.toast.updateFailed')
|
|
267
271
|
})
|
|
268
272
|
|
|
269
273
|
it('updateBlock reports a no-op for a block that is not on the board', async () => {
|
|
@@ -428,6 +432,7 @@ describe('board store deferred delete + undo', () => {
|
|
|
428
432
|
function setup(removeImpl: () => Promise<void>) {
|
|
429
433
|
const removeSpy = vi.fn(removeImpl)
|
|
430
434
|
const addSpy = vi.fn()
|
|
435
|
+
const presentSpy = vi.fn()
|
|
431
436
|
const actions: ToastAction[] = []
|
|
432
437
|
vi.stubGlobal('useApi', () => ({ removeBlock: removeSpy }))
|
|
433
438
|
vi.stubGlobal('useToast', () => ({
|
|
@@ -436,9 +441,10 @@ describe('board store deferred delete + undo', () => {
|
|
|
436
441
|
if (t.actions) actions.push(...t.actions)
|
|
437
442
|
},
|
|
438
443
|
}))
|
|
444
|
+
vi.stubGlobal('usePipelineErrorToast', () => ({ present: presentSpy }))
|
|
439
445
|
setActivePinia(createPinia())
|
|
440
446
|
useWorkspaceStore().workspaceId = 'ws1'
|
|
441
|
-
return { store: useBoardStore(), removeSpy, addSpy, actions }
|
|
447
|
+
return { store: useBoardStore(), removeSpy, addSpy, presentSpy, actions }
|
|
442
448
|
}
|
|
443
449
|
|
|
444
450
|
beforeEach(() => {
|
|
@@ -500,14 +506,15 @@ describe('board store deferred delete + undo', () => {
|
|
|
500
506
|
expect(removeSpy).toHaveBeenCalledWith('ws1', 'f1')
|
|
501
507
|
})
|
|
502
508
|
|
|
503
|
-
it('restores the subtree and
|
|
504
|
-
const { store,
|
|
509
|
+
it('restores the subtree and reports the failure if the deferred delete fails', async () => {
|
|
510
|
+
const { store, presentSpy } = setup(() => Promise.reject(new Error('boom')))
|
|
505
511
|
store.hydrate([frame('f1'), task('t1', 'f1')])
|
|
506
512
|
store.removeBlock('f1')
|
|
507
513
|
await vi.runAllTimersAsync()
|
|
508
514
|
expect(store.getBlock('f1')?.id).toBe('f1')
|
|
509
515
|
expect(store.getBlock('t1')?.id).toBe('t1')
|
|
510
|
-
|
|
516
|
+
// Through the shared funnel, named by its title key (see `updateBlock`'s case above).
|
|
517
|
+
expect(presentSpy).toHaveBeenCalledWith(expect.any(Error), 'board.toast.deleteFailed')
|
|
511
518
|
})
|
|
512
519
|
|
|
513
520
|
it('does not reattach a failed deferred delete onto a different workspace', async () => {
|
package/app/stores/board.ts
CHANGED
|
@@ -141,7 +141,17 @@ export const useBoardStore = defineStore('board', () => {
|
|
|
141
141
|
// The write operations, split into cohesive factories sharing the state above (a size-only
|
|
142
142
|
// extraction — behaviour is identical to the former in-closure functions). `undoRemove` stays
|
|
143
143
|
// internal to the removal factory (only its delete toast wires it), so it is NOT re-exported.
|
|
144
|
-
const context = {
|
|
144
|
+
const context = {
|
|
145
|
+
blocks,
|
|
146
|
+
getBlock,
|
|
147
|
+
upsert,
|
|
148
|
+
pendingRemovals,
|
|
149
|
+
pendingDoomed,
|
|
150
|
+
api,
|
|
151
|
+
toast,
|
|
152
|
+
tr,
|
|
153
|
+
present: usePipelineErrorToast().present,
|
|
154
|
+
}
|
|
145
155
|
const mutations = createBoardMutations(context)
|
|
146
156
|
const placement = createBoardPlacement(context)
|
|
147
157
|
const { detach, reattach, removeBlock } = createBoardRemoval(context)
|
|
@@ -12,11 +12,10 @@ import { useBoardStore } from '~/stores/board'
|
|
|
12
12
|
*/
|
|
13
13
|
export const useRecurringPipelinesStore = defineStore('recurringPipelines', () => {
|
|
14
14
|
const api = useApi()
|
|
15
|
-
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
const
|
|
19
|
-
const tr = (key: string): string => (nuxtApp.$i18n as { t: (k: string) => string }).t(key)
|
|
15
|
+
// The failure funnel resolves its own translations through the Nuxt app's global i18n instance,
|
|
16
|
+
// which is what a store (running outside a component `setup`) needs, so this store no longer
|
|
17
|
+
// carries a `tr` bridge or a raw toast handle of its own.
|
|
18
|
+
const { present } = usePipelineErrorToast()
|
|
20
19
|
|
|
21
20
|
const schedules = ref<PipelineSchedule[]>([])
|
|
22
21
|
/** Lazily-loaded run history, keyed by schedule id. */
|
|
@@ -71,12 +70,7 @@ export const useRecurringPipelinesStore = defineStore('recurringPipelines', () =
|
|
|
71
70
|
} catch (e) {
|
|
72
71
|
schedules.value = prevSchedules
|
|
73
72
|
if (blockSnap) board.reattach(blockSnap)
|
|
74
|
-
toast.
|
|
75
|
-
title: tr('board.toast.recurringDeleteFailed'),
|
|
76
|
-
description: e instanceof Error ? e.message : String(e),
|
|
77
|
-
icon: 'i-lucide-triangle-alert',
|
|
78
|
-
color: 'error',
|
|
79
|
-
})
|
|
73
|
+
present(e, 'board.toast.recurringDeleteFailed')
|
|
80
74
|
}
|
|
81
75
|
}
|
|
82
76
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.261.
|
|
3
|
+
"version": "0.261.4",
|
|
4
4
|
"description": "Reusable Nuxt layer for the Agent Architecture Board SPA (components, stores, composables, pages). Consume it from a thin deployment app via `extends: ['@cat-factory/app']` and point it at your backend with NUXT_PUBLIC_API_BASE. See deploy/frontend for an example.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"valibot": "^1.4.2",
|
|
41
41
|
"vue": "3.5.41",
|
|
42
42
|
"wretch": "^3.0.9",
|
|
43
|
-
"@cat-factory/contracts": "0.
|
|
43
|
+
"@cat-factory/contracts": "0.293.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@toad-contracts/testing": "0.3.2",
|