@cat-factory/app 0.132.0 → 0.134.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.
@@ -1,3 +1,4 @@
1
+ import { shallowRef } from 'vue'
1
2
  import type {
2
3
  AgentArchetype,
3
4
  AgentCategory,
@@ -304,10 +305,44 @@ export function isProducerCompanion(kind: string): boolean {
304
305
  return COMPANION_KINDS.has(kind)
305
306
  }
306
307
 
307
- export const AGENT_BY_KIND: Record<AgentKind, AgentArchetype> = Object.fromEntries(
308
- [...AGENT_ARCHETYPES, ...COMPANION_ARCHETYPES].map((a) => [a.kind, a]),
308
+ /**
309
+ * The BUILT-IN palette + companion catalog, keyed by kind. Frozen and never
310
+ * mutated: custom (deployment/consumer) kinds no longer reach into this const —
311
+ * they flow through the modular `agentKinds` slot / the workspace-capability
312
+ * remote manifest and land in {@link customAgentKindMeta} instead (slice 2 of
313
+ * the modular-vue adoption). Freezing turns any stray write into a loud runtime
314
+ * error rather than silently conflating built-ins with custom kinds.
315
+ */
316
+ export const AGENT_BY_KIND: Record<AgentKind, AgentArchetype> = Object.freeze(
317
+ Object.fromEntries([...AGENT_ARCHETYPES, ...COMPANION_ARCHETYPES].map((a) => [a.kind, a])),
309
318
  ) as Record<AgentKind, AgentArchetype>
310
319
 
320
+ /**
321
+ * Reactive read-model of the deployment's CUSTOM agent kinds (consumer-slot +
322
+ * backend remote-manifest), kept in sync by the agents store from the resolved
323
+ * modular `agentKinds` slot. The slot/manifest is the source of truth; this
324
+ * `shallowRef` is its synchronous projection so the pure kind-meta lookups below
325
+ * ({@link agentKindMeta} / {@link isKnownAgentKind}) resolve a custom kind — and
326
+ * re-render when the catalog changes — WITHOUT importing the store (which would
327
+ * be circular) or mutating {@link AGENT_BY_KIND}. Empty until the store first
328
+ * populates it, so an unknown custom kind degrades to the generic fallback,
329
+ * exactly as before registration.
330
+ */
331
+ const customAgentKindMeta = shallowRef<Record<string, AgentArchetype>>({})
332
+
333
+ /**
334
+ * Replace the custom-kind projection (called only by the agents store, whenever
335
+ * its merged custom catalog changes). Whole-map replace, not per-key mutation.
336
+ */
337
+ export function setCustomAgentKindMeta(map: Record<string, AgentArchetype>): void {
338
+ customAgentKindMeta.value = map
339
+ }
340
+
341
+ /** Test-only: clear the custom-kind projection so a spec starts from built-ins only. */
342
+ export function __resetCustomAgentKindMetaForTest(): void {
343
+ customAgentKindMeta.value = {}
344
+ }
345
+
311
346
  /**
312
347
  * Agent kinds eligible for the optional consensus mechanism (the pipeline builder shows an
313
348
  * "Enable Consensus" toggle for these). Mirrors the backend default-eligible set assigned by
@@ -596,30 +631,36 @@ const FALLBACK_AGENT_META: Omit<AgentArchetype, 'kind'> = {
596
631
  }
597
632
 
598
633
  /**
599
- * Resolve display metadata for ANY agent kind — a palette archetype (incl. custom
600
- * agents registered into {@link AGENT_BY_KIND}), an engine system kind, or an
601
- * unknown one ALWAYS returning a usable icon/label/color. This is the single
602
- * lookup every pipeline / run renderer should use so a kind missing from the
603
- * archetype map (e.g. `ci`/`merger`/`blueprints` in a seeded pipeline) can never
604
- * blow up a component with an undefined access.
634
+ * Resolve display metadata for ANY agent kind — a built-in palette archetype
635
+ * ({@link AGENT_BY_KIND}), an engine system kind ({@link SYSTEM_AGENT_META}), a
636
+ * deployment CUSTOM kind (projected from the modular `agentKinds` slot into
637
+ * {@link customAgentKindMeta} by the agents store), or an unknown one ALWAYS
638
+ * returning a usable icon/label/color. This is the single lookup every pipeline
639
+ * / run renderer should use so a kind missing from the archetype map (e.g.
640
+ * `ci`/`merger`/`blueprints` in a seeded pipeline) can never blow up a component
641
+ * with an undefined access. Reading `customAgentKindMeta` reactively means a
642
+ * component computed re-runs when the custom catalog changes.
605
643
  */
606
644
  export function agentKindMeta(kind: string): AgentArchetype {
607
645
  return (
608
646
  AGENT_BY_KIND[kind as AgentKind] ??
609
- SYSTEM_AGENT_META[kind] ?? { kind: kind as AgentKind, ...FALLBACK_AGENT_META }
647
+ SYSTEM_AGENT_META[kind] ??
648
+ customAgentKindMeta.value[kind] ?? { kind: kind as AgentKind, ...FALLBACK_AGENT_META }
610
649
  )
611
650
  }
612
651
 
613
652
  /**
614
- * Whether an agent kind is actually known to this build — a palette archetype or companion
615
- * ({@link AGENT_BY_KIND}, which deployment custom kinds are merged into via
616
- * `useAgentsStore().registerCustomKinds`), or an engine system/gate kind
617
- * ({@link SYSTEM_AGENT_META}). Unlike {@link agentKindMeta} (which always returns a usable
618
- * fallback so renderers never crash), this returns `false` for an unknown kind — used to flag
619
- * a pipeline that references a nonexistent agent. Call AFTER custom kinds are registered.
653
+ * Whether an agent kind is actually known to this build — a built-in palette
654
+ * archetype or companion ({@link AGENT_BY_KIND}), an engine system/gate kind
655
+ * ({@link SYSTEM_AGENT_META}), or a deployment CUSTOM kind projected from the
656
+ * modular `agentKinds` slot ({@link customAgentKindMeta}). Unlike
657
+ * {@link agentKindMeta} (which always returns a usable fallback so renderers
658
+ * never crash), this returns `false` for an unknown kind used to flag a
659
+ * pipeline that references a nonexistent agent. Call AFTER the workspace
660
+ * snapshot has hydrated the custom kinds.
620
661
  */
621
662
  export function isKnownAgentKind(kind: string): boolean {
622
- return kind in AGENT_BY_KIND || kind in SYSTEM_AGENT_META
663
+ return kind in AGENT_BY_KIND || kind in SYSTEM_AGENT_META || kind in customAgentKindMeta.value
623
664
  }
624
665
 
625
666
  type BlockTypeMeta = { label: string; icon: string; accent: string }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/app",
3
- "version": "0.132.0",
3
+ "version": "0.134.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",
@@ -18,11 +18,11 @@
18
18
  "access": "public"
19
19
  },
20
20
  "dependencies": {
21
- "@modular-frontend/core": "^0.1.0",
22
- "@modular-vue/core": "^1.0.1",
21
+ "@modular-frontend/core": "^0.2.0",
22
+ "@modular-vue/core": "^1.1.0",
23
23
  "@modular-vue/nuxt": "^0.1.1",
24
- "@modular-vue/runtime": "^1.0.1",
25
- "@modular-vue/vue": "^1.0.0",
24
+ "@modular-vue/runtime": "^1.1.0",
25
+ "@modular-vue/vue": "^1.1.0",
26
26
  "@nuxt/ui": "^4.9.0",
27
27
  "@nuxtjs/i18n": "^10.4.1",
28
28
  "@pinia/nuxt": "^0.11.3",
@@ -39,7 +39,7 @@
39
39
  "valibot": "^1.4.2",
40
40
  "vue": "3.5.40",
41
41
  "wretch": "^3.0.9",
42
- "@cat-factory/contracts": "0.147.1"
42
+ "@cat-factory/contracts": "0.148.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@toad-contracts/testing": "0.3.2",