@cat-factory/app 0.232.0 → 0.232.2

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.
@@ -107,12 +107,17 @@ const boardItems = computed<DropdownMenuItem[][]>(() => [
107
107
  // manages membership can see at a glance which boards are scoped vs open to the account.
108
108
  icon: w.accessMode === 'restricted' ? 'i-lucide-lock' : 'i-lucide-layout-dashboard',
109
109
  trailingIcon: w.id === workspace.workspaceId ? 'i-lucide-check' : undefined,
110
+ // Addressable per board id: which board a row opens is the one thing about this menu a test
111
+ // (or a screen reader's user testing a switch) cannot get from the label, which is a name a
112
+ // person chose and two boards may share.
113
+ 'data-testid': `board-option-${w.id}`,
110
114
  onSelect: () => void switchBoard(w.id),
111
115
  })),
112
116
  [
113
117
  {
114
118
  label: t('layout.boardSwitcher.board.new'),
115
119
  icon: 'i-lucide-plus',
120
+ 'data-testid': 'board-new',
116
121
  onSelect: () => openPrompt('board'),
117
122
  },
118
123
  // Rename/delete of the active board is `settings.manage` — omit for a member/viewer,
@@ -290,6 +295,8 @@ async function submitPrompt() {
290
295
  class="flex w-full items-center gap-2 rounded-lg border border-slate-800 bg-slate-900/60 px-2.5 py-1.5 text-start transition hover:bg-slate-800/60"
291
296
  :class="collapsed ? 'justify-center' : ''"
292
297
  :disabled="busy"
298
+ data-testid="board-switcher"
299
+ :data-board-id="workspace.workspaceId ?? ''"
293
300
  >
294
301
  <UIcon name="i-lucide-layout-dashboard" class="h-4 w-4 shrink-0 text-indigo-400" />
295
302
  <span v-if="!collapsed" class="truncate text-sm font-medium text-white">
@@ -86,6 +86,7 @@ function toggle(id: string) {
86
86
  type="button"
87
87
  class="flex w-full items-center gap-2.5 rounded-lg border border-slate-700 bg-slate-800/60 p-2 text-start transition hover:border-slate-500 hover:bg-slate-800"
88
88
  :title="a.description"
89
+ :data-testid="`palette-agent-${a.kind}`"
89
90
  @click="$emit('add', a.kind)"
90
91
  >
91
92
  <div
@@ -304,9 +304,13 @@ async function copyOutput() {
304
304
  <template>
305
305
  <Teleport to="body">
306
306
  <Transition name="reader-fade">
307
+ <!-- `data-agent-kind` names WHICH step this window is scoped to, as the kind rather than as
308
+ the heading beside it: the heading is a translated display label, so it is the wrong
309
+ thing to read for anything that needs to know which agent's step is open. -->
307
310
  <div
308
311
  v-if="open && step && agent"
309
312
  data-testid="step-detail"
313
+ :data-agent-kind="step?.agentKind"
310
314
  class="fixed inset-0 z-50 flex max-h-[100dvh] bg-slate-950/96 backdrop-blur-sm"
311
315
  role="dialog"
312
316
  aria-modal="true"
@@ -521,6 +521,7 @@ async function clone(p: Pipeline) {
521
521
  :placeholder="t('pipeline.builder.namePlaceholder')"
522
522
  size="sm"
523
523
  class="mb-2"
524
+ data-testid="pipeline-builder-name"
524
525
  />
525
526
 
526
527
  <!-- Purpose: the pipeline's use-case classifier. Drives which task pickers offer it (a
@@ -621,6 +622,9 @@ async function clone(p: Pipeline) {
621
622
  :key="unit.index"
622
623
  class="flex flex-col gap-2 rounded-lg border border-slate-700 bg-slate-800/60 p-2"
623
624
  :class="{ 'opacity-50': pipelines.draftEnabled[unit.index] === false }"
625
+ data-testid="pipeline-draft-step"
626
+ :data-agent-kind="unit.kind"
627
+ :data-gated="pipelines.draftGates[unit.index] === true"
624
628
  >
625
629
  <div class="flex items-center gap-1.5">
626
630
  <span class="w-4 shrink-0 text-center text-[10px] text-slate-500">{{
@@ -686,6 +690,7 @@ async function clone(p: Pipeline) {
686
690
  ? t('pipeline.builder.approvalRemoveTooltip')
687
691
  : t('pipeline.builder.approvalAddTooltip')
688
692
  "
693
+ data-testid="pipeline-step-gate"
689
694
  @click="pipelines.toggleDraftGate(unit.index)"
690
695
  />
691
696
  <!-- Consensus: run this step through the multi-model mechanism (eligible
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/app",
3
- "version": "0.232.0",
3
+ "version": "0.232.2",
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.40",
42
42
  "wretch": "^3.0.9",
43
- "@cat-factory/contracts": "0.249.0"
43
+ "@cat-factory/contracts": "0.250.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@toad-contracts/testing": "0.3.2",