@cat-factory/app 0.105.0 → 0.106.0
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.
|
@@ -19,8 +19,15 @@ const initiative = computed(() => initiatives.forBlock(props.block.id))
|
|
|
19
19
|
|
|
20
20
|
const status = computed<InitiativeStatus>(() => initiative.value?.status ?? 'planning')
|
|
21
21
|
|
|
22
|
-
// The
|
|
23
|
-
|
|
22
|
+
// The planning pipeline runnable on this initiative block: its preset descriptor's
|
|
23
|
+
// `planningPipelineId` (a preset picks its own planning pipeline — the generic preset keeps
|
|
24
|
+
// `pl_initiative`). `planningPipelineIdFor` returns null for a named preset that hasn't hydrated,
|
|
25
|
+
// so "Run planning" stays disabled rather than launching the wrong (generic interviewer) pipeline.
|
|
26
|
+
// The engine's runnable guard still enforces that only an initiative-shaped pipeline runs here.
|
|
27
|
+
const planningPipeline = computed(() => {
|
|
28
|
+
const id = initiatives.planningPipelineIdFor(initiative.value)
|
|
29
|
+
return id ? pipelines.pipelines.find((p) => p.id === id) : undefined
|
|
30
|
+
})
|
|
24
31
|
const running = computed(() => !!props.block.executionId)
|
|
25
32
|
|
|
26
33
|
// The interviewer has parked the planning run with questions awaiting answers.
|
package/app/stores/initiative.ts
CHANGED
|
@@ -3,9 +3,13 @@ import { computed, ref } from 'vue'
|
|
|
3
3
|
import type {
|
|
4
4
|
Initiative,
|
|
5
5
|
InitiativeExecutionPolicy,
|
|
6
|
+
InitiativePresetDescriptor,
|
|
6
7
|
PromoteInitiativeFollowUpInput,
|
|
7
8
|
UpdateInitiativeItemInput,
|
|
8
9
|
} from '~/types/domain'
|
|
10
|
+
|
|
11
|
+
/** The built-in generic preset id (mirrors kernel's `GENERIC_INITIATIVE_PRESET_ID`). */
|
|
12
|
+
const GENERIC_PRESET_ID = 'preset_generic'
|
|
9
13
|
import { useWorkspaceStore } from '~/stores/workspace'
|
|
10
14
|
import { useBoardStore } from '~/stores/board'
|
|
11
15
|
|
|
@@ -30,6 +34,13 @@ export const useInitiativesStore = defineStore('initiatives', () => {
|
|
|
30
34
|
const byBlock = ref<Record<string, Initiative>>({})
|
|
31
35
|
/** True while a create call is in flight (the modal's submit spinner). */
|
|
32
36
|
const creating = ref(false)
|
|
37
|
+
/**
|
|
38
|
+
* The registered initiative-preset descriptors from the snapshot (built-in generic + any a
|
|
39
|
+
* deployment mixed in). Drives the create picker and — already today — which planning pipeline
|
|
40
|
+
* "Run planning" starts. Empty until a snapshot hydrates it; the SPA falls back to the generic
|
|
41
|
+
* pipeline when a preset can't be resolved.
|
|
42
|
+
*/
|
|
43
|
+
const presets = ref<InitiativePresetDescriptor[]>([])
|
|
33
44
|
|
|
34
45
|
const all = computed(() => Object.values(byBlock.value))
|
|
35
46
|
|
|
@@ -37,6 +48,25 @@ export const useInitiativesStore = defineStore('initiatives', () => {
|
|
|
37
48
|
return byBlock.value[blockId] ?? null
|
|
38
49
|
}
|
|
39
50
|
|
|
51
|
+
/** Resolve a preset descriptor by id (defaulting to the generic preset), or null when unknown. */
|
|
52
|
+
function presetById(presetId: string | undefined): InitiativePresetDescriptor | null {
|
|
53
|
+
return presets.value.find((p) => p.id === (presetId ?? GENERIC_PRESET_ID)) ?? null
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The planning pipeline id to start for an initiative: its preset descriptor's
|
|
58
|
+
* `planningPipelineId`. No preset (or the built-in generic) → `pl_initiative`, which is always in
|
|
59
|
+
* the catalog. For a NAMED preset we return `null` (not the generic pipeline) when presets
|
|
60
|
+
* haven't hydrated or the snapshot omitted this descriptor — so the caller keeps "Run planning"
|
|
61
|
+
* disabled rather than silently launching the interviewer over an already-seeded skip-interview
|
|
62
|
+
* initiative.
|
|
63
|
+
*/
|
|
64
|
+
function planningPipelineIdFor(initiative: Initiative | null): string | null {
|
|
65
|
+
const presetId = initiative?.presetId
|
|
66
|
+
if (!presetId || presetId === GENERIC_PRESET_ID) return 'pl_initiative'
|
|
67
|
+
return presetById(presetId)?.planningPipelineId ?? null
|
|
68
|
+
}
|
|
69
|
+
|
|
40
70
|
/**
|
|
41
71
|
* Rebuild the cache from a snapshot (the hydrate fan-out). The snapshot is authoritative
|
|
42
72
|
* for EXISTENCE (entities it omits are dropped — they were deleted), but NOT for freshness:
|
|
@@ -56,6 +86,12 @@ export const useInitiativesStore = defineStore('initiatives', () => {
|
|
|
56
86
|
byBlock.value = map
|
|
57
87
|
}
|
|
58
88
|
|
|
89
|
+
/** Replace the registered preset descriptors from a snapshot (idempotent on reload). */
|
|
90
|
+
function hydratePresets(next: InitiativePresetDescriptor[] | undefined) {
|
|
91
|
+
if (next === undefined) return
|
|
92
|
+
presets.value = next
|
|
93
|
+
}
|
|
94
|
+
|
|
59
95
|
/** Patch from a live `initiative` stream event or a call response (newest rev wins). */
|
|
60
96
|
function upsert(initiative: Initiative) {
|
|
61
97
|
const existing = byBlock.value[initiative.blockId]
|
|
@@ -237,13 +273,17 @@ export const useInitiativesStore = defineStore('initiatives', () => {
|
|
|
237
273
|
return {
|
|
238
274
|
available,
|
|
239
275
|
byBlock,
|
|
276
|
+
presets,
|
|
240
277
|
all,
|
|
241
278
|
creating,
|
|
242
279
|
resuming,
|
|
243
280
|
controlling,
|
|
244
281
|
curating,
|
|
245
282
|
forBlock,
|
|
283
|
+
presetById,
|
|
284
|
+
planningPipelineIdFor,
|
|
246
285
|
hydrate,
|
|
286
|
+
hydratePresets,
|
|
247
287
|
upsert,
|
|
248
288
|
create,
|
|
249
289
|
load,
|
package/app/stores/workspace.ts
CHANGED
|
@@ -131,6 +131,9 @@ export const useWorkspaceStore = defineStore(
|
|
|
131
131
|
useServiceFragmentDefaultsStore().hydrate(snapshot.serviceFragmentDefaults?.fragmentIds)
|
|
132
132
|
useRecurringPipelinesStore().hydrate(snapshot.recurringPipelines ?? [])
|
|
133
133
|
useInitiativesStore().hydrate(snapshot.initiatives)
|
|
134
|
+
// Registered initiative presets (built-in generic + any a deployment mixed in): drive the
|
|
135
|
+
// create picker and which planning pipeline "Run planning" starts. Workspace-independent.
|
|
136
|
+
useInitiativesStore().hydratePresets(snapshot.initiativePresets)
|
|
134
137
|
useTrackerStore().hydrate(snapshot.trackerSettings)
|
|
135
138
|
useServicesStore().hydrate(snapshot.mounts ?? [], snapshot.serviceCatalog ?? [])
|
|
136
139
|
// Merge the deployment's registered custom agent kinds into the palette catalog so a
|
package/app/types/initiative.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.106.0",
|
|
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",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"valibot": "^1.4.2",
|
|
35
35
|
"vue": "3.5.39",
|
|
36
36
|
"wretch": "^3.0.9",
|
|
37
|
-
"@cat-factory/contracts": "0.
|
|
37
|
+
"@cat-factory/contracts": "0.116.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@toad-contracts/testing": "0.3.2",
|