@cat-factory/app 0.116.7 → 0.116.8

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.
@@ -8,8 +8,9 @@
8
8
  //
9
9
  // MONOREPO support: a repo flagged a monorepo can back SEVERAL services, each
10
10
  // pinned to a subdirectory. When the selected repo is a monorepo, the user
11
- // browses its tree and picks the service's directory before adding (and may add
12
- // more than one, a subset of the repo's services).
11
+ // browses its tree and multi-selects the service directories to add from ANY
12
+ // parent folder, in one pass then adds them all at once. Directories that
13
+ // already back a service on this board are shown but not selectable.
13
14
  import type { FrameRepoType, GitHubAvailableRepo } from '~/types/domain'
14
15
  import GitHubConnect from '~/components/github/GitHubConnect.vue'
15
16
  import RepoSearchEmpty from '~/components/github/RepoSearchEmpty.vue'
@@ -136,11 +137,39 @@ const repoMenuItems = computed(() => {
136
137
  // repo + requires a directory when it creates the service). A repo already flagged a
137
138
  // monorepo (it backs other services) seeds the toggle on when selected.
138
139
  const isMonorepo = ref(false)
139
- const selectedDirectory = ref<string | undefined>(undefined)
140
+ // The cart of monorepo service directories the user has picked (repo-root-relative),
141
+ // accumulated across the whole browse session so picks from different parent folders
142
+ // coexist. Added all at once (see `addServices`), unlike the one-at-a-time whole-repo add.
143
+ const selectedDirectories = ref<string[]>([])
144
+
145
+ // Directories in the selected repo that ALREADY back a service on this board — surfaced
146
+ // so the tree browser can disable them (adding one again would be a no-op). Derived from
147
+ // the org catalog filtered to this repo; a whole-repo service (null directory) is ignored.
148
+ const addedDirectories = computed<string[]>(() => {
149
+ if (selectedRepoId.value === undefined) return []
150
+ return services.catalog
151
+ .filter((s) => s.repoGithubId === selectedRepoId.value && s.directory)
152
+ .map((s) => normalizeRepoPath(s.directory as string))
153
+ })
154
+ const addedDirSet = computed(() => new Set(addedDirectories.value))
140
155
 
141
156
  function toggleMonorepo(value: boolean) {
142
157
  isMonorepo.value = value
143
- selectedDirectory.value = undefined
158
+ selectedDirectories.value = []
159
+ }
160
+
161
+ // Add/remove a directory from the cart. Guards against an already-added directory (the
162
+ // browser disables it, but keep the model authoritative).
163
+ function toggleDirectory(path: string) {
164
+ if (addedDirSet.value.has(normalizeRepoPath(path))) return
165
+ const i = selectedDirectories.value.indexOf(path)
166
+ if (i >= 0) selectedDirectories.value.splice(i, 1)
167
+ else selectedDirectories.value.push(path)
168
+ }
169
+
170
+ function removeSelected(path: string) {
171
+ const i = selectedDirectories.value.indexOf(path)
172
+ if (i >= 0) selectedDirectories.value.splice(i, 1)
144
173
  }
145
174
 
146
175
  // On repo change, capture the picked repo (from the volatile loaded list, before a later
@@ -152,13 +181,13 @@ watch(selectedRepoId, (id) => {
152
181
  if (found) selectedRepo.value = found
153
182
  }
154
183
  isMonorepo.value = selectedRepo.value?.isMonorepo === true
155
- selectedDirectory.value = undefined
184
+ selectedDirectories.value = []
156
185
  configuredBlockId.value = undefined
157
186
  })
158
187
 
159
188
  function resetSelection() {
160
189
  selectedRepoId.value = undefined
161
- selectedDirectory.value = undefined
190
+ selectedDirectories.value = []
162
191
  isMonorepo.value = false
163
192
  configuredBlockId.value = undefined
164
193
  resetRepoSearch()
@@ -186,12 +215,11 @@ function openManageInstall() {
186
215
  if (manageInstallUrl.value) window.open(manageInstallUrl.value, '_blank', 'noopener')
187
216
  }
188
217
 
189
- // The just-added service, kept on the board store so the user can configure it (test
190
- // infra + fragments) right here — the same controls as the inspector. A monorepo can
191
- // host several services, so adding another keeps the modal open; a whole-repo service
192
- // can only be added once (its repo is then on the board).
218
+ // The just-added whole-repo service, kept on the board store so the user can configure it
219
+ // (test infra + fragments) right here — the same controls as the inspector. Only the
220
+ // whole-repo flow surfaces this inline configure step; a monorepo adds several services at
221
+ // once and they're configured later in the inspector.
193
222
  const configuredBlockId = ref<string | undefined>(undefined)
194
- const configuredDirectory = ref<string | undefined>(undefined)
195
223
  const configuredBlock = computed(() =>
196
224
  configuredBlockId.value ? board.getBlock(configuredBlockId.value) : undefined,
197
225
  )
@@ -210,12 +238,21 @@ watch(
210
238
  { immediate: true },
211
239
  )
212
240
 
213
- // A monorepo service needs a chosen directory; a whole-repo service can be added once.
241
+ // A whole-repo service is added once (then configured inline). A monorepo instead
242
+ // multi-selects directories and adds them together via `addServices`.
214
243
  const canAdd = computed(
215
244
  () =>
216
245
  !needsGitHub.value &&
217
246
  selectedRepoId.value !== undefined &&
218
- (isMonorepo.value ? !!selectedDirectory.value : !configuredBlockId.value),
247
+ !isMonorepo.value &&
248
+ !configuredBlockId.value,
249
+ )
250
+ const canAddServices = computed(
251
+ () =>
252
+ !needsGitHub.value &&
253
+ selectedRepoId.value !== undefined &&
254
+ isMonorepo.value &&
255
+ selectedDirectories.value.length > 0,
219
256
  )
220
257
 
221
258
  async function add() {
@@ -223,8 +260,10 @@ async function add() {
223
260
  adding.value = true
224
261
  try {
225
262
  const block = await board.addServiceFromRepo(selectedRepoId.value, {
226
- directory: isMonorepo.value ? selectedDirectory.value : undefined,
227
- isMonorepo: isMonorepo.value,
263
+ // The switch is off, so import the whole repo as ONE service. Send the flag
264
+ // explicitly: a repo already flagged a monorepo (the toggle seeds on) must be
265
+ // un-flagged here, or the backend still requires a service subdirectory and rejects.
266
+ isMonorepo: false,
228
267
  type: selectedType.value,
229
268
  // Place the imported frame in free space (centred in view) instead of the
230
269
  // backend's default stagger, so it never overlaps an existing service.
@@ -235,15 +274,57 @@ async function add() {
235
274
  // Centre the camera on the newly imported service.
236
275
  await focusFrame(block.id)
237
276
  configuredBlockId.value = block.id
238
- configuredDirectory.value = isMonorepo.value ? selectedDirectory.value : undefined
239
277
  toast.add({
240
278
  title: t('github.addService.toast.addedTitle'),
241
279
  description: t('github.addService.toast.addedDescription', { title: block.title }),
242
280
  icon: 'i-lucide-check',
243
281
  color: 'success',
244
282
  })
245
- // Ready to pick another monorepo service (the just-added directory is taken).
246
- selectedDirectory.value = undefined
283
+ } catch (e) {
284
+ toast.add({
285
+ title: t('github.addService.toast.addFailedTitle'),
286
+ description: e instanceof Error ? e.message : String(e),
287
+ icon: 'i-lucide-triangle-alert',
288
+ color: 'error',
289
+ })
290
+ } finally {
291
+ adding.value = false
292
+ }
293
+ }
294
+
295
+ // Add every directory in the cart as its own service, in one action. Each add lays the
296
+ // frame out in free space (seeing the ones added earlier in the loop, so they don't
297
+ // overlap); the projection is refreshed and the camera centres on the last one. The
298
+ // just-added directories then move to `addedDirectories`, so the cart is cleared and the
299
+ // tree marks them "added" — ready to pick more (from any folder) or close.
300
+ async function addServices() {
301
+ if (!canAddServices.value || selectedRepoId.value === undefined) return
302
+ const dirs = selectedDirectories.value.filter((d) => !addedDirSet.value.has(normalizeRepoPath(d)))
303
+ if (dirs.length === 0) return
304
+ adding.value = true
305
+ try {
306
+ let lastBlock: Awaited<ReturnType<typeof board.addServiceFromRepo>> | undefined
307
+ for (const directory of dirs) {
308
+ lastBlock = await board.addServiceFromRepo(selectedRepoId.value, {
309
+ directory,
310
+ isMonorepo: true,
311
+ type: selectedType.value,
312
+ position: freeFramePosition(),
313
+ })
314
+ }
315
+ await github.load()
316
+ if (lastBlock) await focusFrame(lastBlock.id)
317
+ selectedDirectories.value = []
318
+ toast.add({
319
+ title: t('github.addService.toast.servicesAddedTitle'),
320
+ description: t(
321
+ 'github.addService.toast.servicesAddedDescription',
322
+ { count: dirs.length },
323
+ dirs.length,
324
+ ),
325
+ icon: 'i-lucide-check',
326
+ color: 'success',
327
+ })
247
328
  } catch (e) {
248
329
  toast.add({
249
330
  title: t('github.addService.toast.addFailedTitle'),
@@ -329,8 +410,9 @@ function done() {
329
410
  <USelect v-model="selectedType" :items="typeItems" value-key="value" class="w-full" />
330
411
  </UFormField>
331
412
 
332
- <!-- monorepo handling: flag + directory picker -->
333
- <div v-if="selectedRepoId !== undefined" class="space-y-3">
413
+ <!-- monorepo handling: flag + multi-directory picker (hidden once a whole-repo
414
+ service has been added and is being configured inline) -->
415
+ <div v-if="selectedRepoId !== undefined && !configuredBlock" class="space-y-3">
334
416
  <USwitch
335
417
  :model-value="isMonorepo"
336
418
  :label="t('github.addService.monorepoLabel')"
@@ -340,23 +422,65 @@ function done() {
340
422
 
341
423
  <div
342
424
  v-if="isMonorepo"
343
- class="rounded-md border border-slate-700/60 bg-slate-900/40 p-3"
425
+ class="space-y-3 rounded-md border border-slate-700/60 bg-slate-900/40 p-3"
344
426
  >
345
- <p class="mb-2 text-xs text-slate-400">
427
+ <p class="text-xs text-slate-400">
346
428
  {{ t('github.addService.monorepoBrowseHint') }}
347
429
  </p>
348
430
  <RepoTreeBrowser
349
- v-model="selectedDirectory"
350
431
  :repo-github-id="selectedRepoId!"
351
432
  mode="dir"
433
+ multiple
434
+ :selected-paths="selectedDirectories"
435
+ :added-paths="addedDirectories"
436
+ @toggle="toggleDirectory"
352
437
  />
353
- <p class="mt-2 truncate text-xs text-slate-400">
354
- <template v-if="selectedDirectory">
355
- {{ t('github.addService.serviceDirectory') }}
356
- <code class="text-slate-200">{{ selectedDirectory }}</code>
357
- </template>
358
- <template v-else>{{ t('github.addService.noDirectorySelected') }}</template>
359
- </p>
438
+
439
+ <!-- the selection cart + the add action sit right beside the tree, so the
440
+ picked services and the button that adds them are never scrolled apart -->
441
+ <div class="space-y-2 rounded-md border border-slate-800 bg-slate-950/40 p-2.5">
442
+ <p class="text-[11px] font-semibold uppercase tracking-wide text-slate-400">
443
+ {{ t('github.addService.selectedServices') }}
444
+ </p>
445
+ <div v-if="selectedDirectories.length" class="flex flex-wrap gap-1.5">
446
+ <span
447
+ v-for="dir in selectedDirectories"
448
+ :key="dir"
449
+ class="inline-flex items-center gap-1 rounded bg-slate-800 px-2 py-0.5 text-xs text-slate-200"
450
+ >
451
+ <code class="text-slate-200">{{ dir }}</code>
452
+ <button
453
+ type="button"
454
+ class="text-slate-400 hover:text-slate-100"
455
+ :aria-label="t('github.addService.removeService', { directory: dir })"
456
+ @click="removeSelected(dir)"
457
+ >
458
+ <UIcon name="i-lucide-x" class="h-3 w-3" />
459
+ </button>
460
+ </span>
461
+ </div>
462
+ <p v-else class="text-xs text-slate-500">
463
+ {{ t('github.addService.noServicesSelected') }}
464
+ </p>
465
+ <div class="flex justify-end">
466
+ <UButton
467
+ color="primary"
468
+ icon="i-lucide-plus"
469
+ size="sm"
470
+ :loading="adding"
471
+ :disabled="!canAddServices"
472
+ @click="addServices"
473
+ >
474
+ {{
475
+ t(
476
+ 'github.addService.addServices',
477
+ { count: selectedDirectories.length },
478
+ selectedDirectories.length,
479
+ )
480
+ }}
481
+ </UButton>
482
+ </div>
483
+ </div>
360
484
  </div>
361
485
  </div>
362
486
 
@@ -373,7 +497,7 @@ function done() {
373
497
  </div>
374
498
  <ServiceTestConfig
375
499
  :block="configuredBlock"
376
- :repo="{ githubId: selectedRepoId!, directory: configuredDirectory }"
500
+ :repo="{ githubId: selectedRepoId! }"
377
501
  default-open
378
502
  />
379
503
  <ServiceFragments :block="configuredBlock" default-open />
@@ -395,22 +519,27 @@ function done() {
395
519
  </div>
396
520
 
397
521
  <div class="flex justify-end gap-2">
398
- <UButton v-if="configuredBlock" color="neutral" variant="soft" size="sm" @click="done">
522
+ <!-- Monorepo adds via the cart's own button; the footer only closes. A
523
+ whole-repo add shows its "Add service" button until one is added, then
524
+ the inline configure panel + this Done. -->
525
+ <UButton
526
+ v-if="configuredBlock || isMonorepo"
527
+ color="neutral"
528
+ variant="soft"
529
+ size="sm"
530
+ @click="done"
531
+ >
399
532
  {{ t('github.addService.done') }}
400
533
  </UButton>
401
534
  <UButton
402
- v-if="!configuredBlock || isMonorepo"
535
+ v-if="!isMonorepo && !configuredBlock"
403
536
  color="primary"
404
537
  icon="i-lucide-plus"
405
538
  :loading="adding"
406
539
  :disabled="!canAdd"
407
540
  @click="add"
408
541
  >
409
- {{
410
- configuredBlock && isMonorepo
411
- ? t('github.addService.addAnother')
412
- : t('github.addService.add')
413
- }}
542
+ {{ t('github.addService.add') }}
414
543
  </UButton>
415
544
  </div>
416
545
  </template>
@@ -6,20 +6,37 @@
6
6
  // The selected path (relative to the repo root, as GitHub returns it) is exposed
7
7
  // via `v-model`. The component owns its own navigation/loading state so callers
8
8
  // just bind a repo id + mode; it self-loads on mount and when those change.
9
+ //
10
+ // `dir` mode additionally supports `multiple`: instead of the single `v-model`
11
+ // path, the caller passes the current `selectedPaths` (a cart) + `addedPaths`
12
+ // (directories already on the board, shown disabled) and handles the `toggle`
13
+ // event to add/remove a directory. This lets one browse session accumulate
14
+ // several services from ANY parent folder (the monorepo add flow) — navigating
15
+ // away never drops earlier picks.
9
16
  import type { RepoTreeEntry } from '~/types/domain'
10
17
 
11
18
  const props = withDefaults(
12
19
  defineProps<{
13
20
  repoGithubId: number
14
21
  mode?: 'dir' | 'file'
15
- /** Currently picked path (repo-root-relative), via v-model. */
22
+ /** Currently picked path (repo-root-relative), via v-model. Single-select only. */
16
23
  modelValue?: string
17
24
  /** Directory to open at (e.g. a monorepo service's subdirectory). */
18
25
  startPath?: string
26
+ /** `dir` mode: accumulate a set of picks (via `selectedPaths`/`toggle`) instead of one. */
27
+ multiple?: boolean
28
+ /** `dir` + `multiple`: the current cart of picked directories (repo-root-relative). */
29
+ selectedPaths?: string[]
30
+ /** `dir` + `multiple`: directories already on the board — listed but not selectable. */
31
+ addedPaths?: string[]
19
32
  }>(),
20
- { mode: 'dir', startPath: '' },
33
+ { mode: 'dir', startPath: '', multiple: false, selectedPaths: () => [], addedPaths: () => [] },
21
34
  )
22
- const emit = defineEmits<{ 'update:modelValue': [string | undefined] }>()
35
+ const emit = defineEmits<{
36
+ 'update:modelValue': [string | undefined]
37
+ /** `dir` + `multiple`: the user asked to add/remove this directory from the cart. */
38
+ toggle: [string]
39
+ }>()
23
40
 
24
41
  const { t } = useI18n()
25
42
  const github = useGitHubStore()
@@ -29,6 +46,15 @@ const currentPath = ref(props.startPath)
29
46
  const treeEntries = ref<RepoTreeEntry[]>([])
30
47
  const loading = ref(false)
31
48
 
49
+ const selectedSet = computed(() => new Set(props.selectedPaths.map(normalizeRepoPath)))
50
+ const addedSet = computed(() => new Set(props.addedPaths.map(normalizeRepoPath)))
51
+ function isAdded(path: string): boolean {
52
+ return props.multiple && addedSet.value.has(normalizeRepoPath(path))
53
+ }
54
+ function isPicked(path: string): boolean {
55
+ return props.multiple ? selectedSet.value.has(normalizeRepoPath(path)) : props.modelValue === path
56
+ }
57
+
32
58
  const dirEntries = computed(() => treeEntries.value.filter((e) => e.type === 'dir'))
33
59
  const fileEntries = computed(() => treeEntries.value.filter((e) => e.type === 'file'))
34
60
  const isEmpty = computed(() =>
@@ -63,7 +89,13 @@ async function browseTo(path: string) {
63
89
  }
64
90
 
65
91
  function pick(path: string) {
66
- emit('update:modelValue', path)
92
+ if (props.multiple) {
93
+ // Already-on-board directories are shown for orientation but can't be re-added.
94
+ if (addedSet.value.has(normalizeRepoPath(path))) return
95
+ emit('toggle', path)
96
+ } else {
97
+ emit('update:modelValue', path)
98
+ }
67
99
  }
68
100
 
69
101
  // Re-open at the start path whenever the repo (or requested root) changes.
@@ -124,18 +156,21 @@ watch(
124
156
  <UIcon name="i-lucide-folder" class="h-4 w-4 shrink-0 text-amber-400" />
125
157
  <span class="truncate">{{ entry.name }}</span>
126
158
  </button>
159
+ <span
160
+ v-if="mode === 'dir' && isAdded(entry.path)"
161
+ class="flex shrink-0 items-center gap-1 text-xs text-slate-500"
162
+ >
163
+ <UIcon name="i-lucide-check" class="h-3.5 w-3.5" />
164
+ {{ t('github.repoTree.added') }}
165
+ </span>
127
166
  <UButton
128
- v-if="mode === 'dir'"
167
+ v-else-if="mode === 'dir'"
129
168
  size="xs"
130
169
  variant="soft"
131
- :color="modelValue === entry.path ? 'primary' : 'neutral'"
170
+ :color="isPicked(entry.path) ? 'primary' : 'neutral'"
132
171
  @click="pick(entry.path)"
133
172
  >
134
- {{
135
- modelValue === entry.path
136
- ? t('github.repoTree.selected')
137
- : t('github.repoTree.select')
138
- }}
173
+ {{ isPicked(entry.path) ? t('github.repoTree.selected') : t('github.repoTree.select') }}
139
174
  </UButton>
140
175
  </li>
141
176
  <template v-if="mode === 'file'">
@@ -164,14 +199,21 @@ watch(
164
199
  </div>
165
200
 
166
201
  <!-- dir mode: pin the current folder without descending into a child -->
167
- <div v-if="mode === 'dir' && currentPath" class="mt-2 flex justify-end">
202
+ <div
203
+ v-if="mode === 'dir' && currentPath && !isAdded(currentPath)"
204
+ class="mt-2 flex justify-end"
205
+ >
168
206
  <UButton
169
207
  size="xs"
170
208
  variant="soft"
171
- :color="modelValue === currentPath ? 'primary' : 'neutral'"
209
+ :color="isPicked(currentPath) ? 'primary' : 'neutral'"
172
210
  @click="pick(currentPath)"
173
211
  >
174
- {{ t('github.repoTree.useThisFolder') }}
212
+ {{
213
+ multiple && isPicked(currentPath)
214
+ ? t('github.repoTree.selected')
215
+ : t('github.repoTree.useThisFolder')
216
+ }}
175
217
  </UButton>
176
218
  </div>
177
219
  </div>
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Normalise a repo-root-relative path to its canonical, slash-trimmed form.
3
+ *
4
+ * GitHub returns tree entry paths with no surrounding slashes, but a stored service
5
+ * `directory` may carry them, so both the monorepo directory picker and the tree
6
+ * browser normalise before comparing a picked/added directory against a tree entry.
7
+ */
8
+ export function normalizeRepoPath(p: string): string {
9
+ return p.replace(/^\/+|\/+$/g, '')
10
+ }
@@ -2523,20 +2523,23 @@
2523
2523
  },
2524
2524
  "monorepoLabel": "Dies ist ein Monorepo (beherbergt mehr als einen Service)",
2525
2525
  "monorepoDescription": "Fügen Sie mehrere Services aus einem Repo hinzu, jeder an ein Unterverzeichnis gebunden.",
2526
- "monorepoBrowseHint": "Durchsuchen Sie das Repository und wählen Sie das Verzeichnis des Service aus, den Sie hinzufügen möchten. Agents, die an diesem Service arbeiten, laufen innerhalb dieses Unterverzeichnisses.",
2527
- "serviceDirectory": "Service-Verzeichnis:",
2528
- "noDirectorySelected": "Noch kein Verzeichnis ausgewählt.",
2526
+ "monorepoBrowseHint": "Durchsuchen Sie das Repository und wählen Sie die Verzeichnisse der Services aus, die Sie hinzufügen möchten – aus jedem beliebigen Ordner. Agents, die an einem Service arbeiten, laufen innerhalb seines Unterverzeichnisses.",
2527
+ "selectedServices": "Ausgewählte Services",
2528
+ "noServicesSelected": "Noch keine Services ausgewählt. Wählen Sie oben Verzeichnisse aus.",
2529
+ "addServices": "{count} Service hinzufügen | {count} Services hinzufügen",
2530
+ "removeService": "{directory} entfernen",
2529
2531
  "addedConfigure": "{title} hinzugefügt, konfigurieren Sie es",
2530
2532
  "grantAccess": "Der App Zugriff auf ein Repo gewähren",
2531
2533
  "grantAccessTitle": "Öffnen Sie die Installationseinstellungen der App, um ihr Zugriff auf ein Repository zu gewähren",
2532
2534
  "refreshList": "Liste aktualisieren",
2533
2535
  "done": "Fertig",
2534
2536
  "add": "Service hinzufügen",
2535
- "addAnother": "Weiteren Service hinzufügen",
2536
2537
  "toast": {
2537
2538
  "addedTitle": "Service hinzugefügt",
2538
2539
  "addedDescription": "{title} ist auf dem Board, konfigurieren Sie es unten.",
2539
- "addFailedTitle": "Service konnte nicht hinzugefügt werden"
2540
+ "addFailedTitle": "Service konnte nicht hinzugefügt werden",
2541
+ "servicesAddedTitle": "Services hinzugefügt",
2542
+ "servicesAddedDescription": "{count} Service zum Board hinzugefügt. | {count} Services zum Board hinzugefügt."
2540
2543
  }
2541
2544
  },
2542
2545
  "repoTree": {
@@ -2546,6 +2549,7 @@
2546
2549
  "empty": "Nichts hier.",
2547
2550
  "select": "Auswählen",
2548
2551
  "selected": "Ausgewählt",
2552
+ "added": "Hinzugefügt",
2549
2553
  "useThisFolder": "Diesen Ordner verwenden",
2550
2554
  "errors": {
2551
2555
  "listDirectory": "Verzeichnis konnte nicht aufgelistet werden"
@@ -2983,20 +2983,29 @@
2983
2983
  },
2984
2984
  "monorepoLabel": "This is a monorepo (hosts more than one service)",
2985
2985
  "monorepoDescription": "Add several services from one repo, each pinned to a subdirectory.",
2986
- "monorepoBrowseHint": "Browse the repository and pick the directory of the service you want to add. Agents working on this service will run within that subdirectory.",
2987
- "serviceDirectory": "Service directory:",
2988
- "noDirectorySelected": "No directory selected yet.",
2986
+ "monorepoBrowseHint": "Browse the repository and select the directories of the services you want to add — from any folder. Agents working on a service run within its subdirectory.",
2987
+ "selectedServices": "Selected services",
2988
+ "noServicesSelected": "No services selected yet. Pick directories above.",
2989
+ "addServices": "Add {count} service | Add {count} services",
2990
+ "@addServices": {
2991
+ "description": "Count-driven button label; resolved via t(key, { count }, count) so {count} also drives the plural choice. Provide ALL plural forms your language needs (English has 2; Polish/Ukrainian need 3 - one/few/many - via the custom pluralRules in i18n.config.ts)."
2992
+ },
2993
+ "removeService": "Remove {directory}",
2989
2994
  "addedConfigure": "{title} added, configure it",
2990
2995
  "grantAccess": "Grant the App access to a repo",
2991
2996
  "grantAccessTitle": "Open the App's installation settings to grant it access to a repository",
2992
2997
  "refreshList": "Refresh list",
2993
2998
  "done": "Done",
2994
2999
  "add": "Add service",
2995
- "addAnother": "Add another service",
2996
3000
  "toast": {
2997
3001
  "addedTitle": "Service added",
2998
3002
  "addedDescription": "{title} is on the board, configure it below.",
2999
- "addFailedTitle": "Could not add service"
3003
+ "addFailedTitle": "Could not add service",
3004
+ "servicesAddedTitle": "Services added",
3005
+ "servicesAddedDescription": "{count} service added to the board. | {count} services added to the board.",
3006
+ "@servicesAddedDescription": {
3007
+ "description": "Count-driven toast; resolved via t(key, { count }, count) so {count} also drives the plural choice. Provide ALL plural forms your language needs (Polish/Ukrainian need 3 - one/few/many)."
3008
+ }
3000
3009
  }
3001
3010
  },
3002
3011
  "repoTree": {
@@ -3006,6 +3015,7 @@
3006
3015
  "empty": "Nothing here.",
3007
3016
  "select": "Select",
3008
3017
  "selected": "Selected",
3018
+ "added": "Added",
3009
3019
  "useThisFolder": "Use this folder",
3010
3020
  "errors": {
3011
3021
  "listDirectory": "Could not list directory"
@@ -2894,20 +2894,23 @@
2894
2894
  },
2895
2895
  "monorepoLabel": "Es un monorepo (aloja más de un servicio)",
2896
2896
  "monorepoDescription": "Añade varios servicios desde un repositorio, cada uno fijado a un subdirectorio.",
2897
- "monorepoBrowseHint": "Explora el repositorio y elige el directorio del servicio que quieres añadir. Los agentes que trabajen en este servicio se ejecutarán dentro de ese subdirectorio.",
2898
- "serviceDirectory": "Directorio del servicio:",
2899
- "noDirectorySelected": "Aún no se ha seleccionado ningún directorio.",
2897
+ "monorepoBrowseHint": "Explora el repositorio y selecciona los directorios de los servicios que quieres añadir, de cualquier carpeta. Los agentes que trabajen en un servicio se ejecutarán dentro de su subdirectorio.",
2898
+ "selectedServices": "Servicios seleccionados",
2899
+ "noServicesSelected": "Aún no hay servicios seleccionados. Elige directorios arriba.",
2900
+ "addServices": "Añadir {count} servicio | Añadir {count} servicios",
2901
+ "removeService": "Quitar {directory}",
2900
2902
  "addedConfigure": "{title} añadido, configúralo",
2901
2903
  "grantAccess": "Conceder a la App acceso a un repositorio",
2902
2904
  "grantAccessTitle": "Abrir la configuración de instalación de la App para concederle acceso a un repositorio",
2903
2905
  "refreshList": "Actualizar lista",
2904
2906
  "done": "Listo",
2905
2907
  "add": "Añadir servicio",
2906
- "addAnother": "Añadir otro servicio",
2907
2908
  "toast": {
2908
2909
  "addedTitle": "Servicio añadido",
2909
2910
  "addedDescription": "{title} está en el tablero, configúralo abajo.",
2910
- "addFailedTitle": "No se pudo añadir el servicio"
2911
+ "addFailedTitle": "No se pudo añadir el servicio",
2912
+ "servicesAddedTitle": "Servicios añadidos",
2913
+ "servicesAddedDescription": "{count} servicio añadido al tablero. | {count} servicios añadidos al tablero."
2911
2914
  },
2912
2915
  "repoType": "Tipo de repositorio",
2913
2916
  "repoTypeHint": "Qué es este repositorio: un servicio backend, una aplicación frontend, una biblioteca compartida o un repositorio de documentación (solo documentos/spikes)."
@@ -2919,6 +2922,7 @@
2919
2922
  "empty": "No hay nada aquí.",
2920
2923
  "select": "Seleccionar",
2921
2924
  "selected": "Seleccionado",
2925
+ "added": "Añadido",
2922
2926
  "useThisFolder": "Usar esta carpeta",
2923
2927
  "errors": {
2924
2928
  "listDirectory": "No se pudo listar el directorio"
@@ -2894,20 +2894,23 @@
2894
2894
  },
2895
2895
  "monorepoLabel": "Ceci est un monorepo (héberge plusieurs services)",
2896
2896
  "monorepoDescription": "Ajoutez plusieurs services depuis un même dépôt, chacun rattaché à un sous-répertoire.",
2897
- "monorepoBrowseHint": "Parcourez le dépôt et choisissez le répertoire du service que vous voulez ajouter. Les agents travaillant sur ce service s'exécuteront dans ce sous-répertoire.",
2898
- "serviceDirectory": "Répertoire du service :",
2899
- "noDirectorySelected": "Aucun répertoire sélectionné pour le moment.",
2897
+ "monorepoBrowseHint": "Parcourez le dépôt et sélectionnez les répertoires des services que vous voulez ajouter, depuis n'importe quel dossier. Les agents travaillant sur un service s'exécutent dans son sous-répertoire.",
2898
+ "selectedServices": "Services sélectionnés",
2899
+ "noServicesSelected": "Aucun service sélectionné pour le moment. Choisissez des répertoires ci-dessus.",
2900
+ "addServices": "Ajouter {count} service | Ajouter {count} services",
2901
+ "removeService": "Retirer {directory}",
2900
2902
  "addedConfigure": "{title} ajouté, configurez-le",
2901
2903
  "grantAccess": "Accorder à l'App l'accès à un dépôt",
2902
2904
  "grantAccessTitle": "Ouvrir les paramètres d'installation de l'App pour lui accorder l'accès à un dépôt",
2903
2905
  "refreshList": "Actualiser la liste",
2904
2906
  "done": "Terminé",
2905
2907
  "add": "Ajouter le service",
2906
- "addAnother": "Ajouter un autre service",
2907
2908
  "toast": {
2908
2909
  "addedTitle": "Service ajouté",
2909
2910
  "addedDescription": "{title} est sur le tableau, configurez-le ci-dessous.",
2910
- "addFailedTitle": "Impossible d'ajouter le service"
2911
+ "addFailedTitle": "Impossible d'ajouter le service",
2912
+ "servicesAddedTitle": "Services ajoutés",
2913
+ "servicesAddedDescription": "{count} service ajouté au tableau. | {count} services ajoutés au tableau."
2911
2914
  },
2912
2915
  "repoType": "Type de dépôt",
2913
2916
  "repoTypeHint": "Ce qu'est ce dépôt : un service backend, une application frontend, une bibliothèque partagée ou un dépôt de documentation (documents/spikes uniquement)."
@@ -2919,6 +2922,7 @@
2919
2922
  "empty": "Rien ici.",
2920
2923
  "select": "Sélectionner",
2921
2924
  "selected": "Sélectionné",
2925
+ "added": "Ajouté",
2922
2926
  "useThisFolder": "Utiliser ce dossier",
2923
2927
  "errors": {
2924
2928
  "listDirectory": "Impossible de lister le répertoire"
@@ -2905,20 +2905,23 @@
2905
2905
  },
2906
2906
  "monorepoLabel": "זהו מונורפו (מארח יותר משירות אחד)",
2907
2907
  "monorepoDescription": "הוסף כמה שירותים ממאגר אחד, כל אחד מוצמד לתת-ספרייה.",
2908
- "monorepoBrowseHint": "עיין במאגר ובחר את הספרייה של השירות שברצונך להוסיף. סוכנים העובדים על שירות זה ירוצו בתוך אותה תת-ספרייה.",
2909
- "serviceDirectory": "ספריית שירות:",
2910
- "noDirectorySelected": "לא נבחרה עדיין ספרייה.",
2908
+ "monorepoBrowseHint": "עיין במאגר ובחר את הספריות של השירותים שברצונך להוסיף — מכל תיקייה. סוכנים העובדים על שירות ירוצו בתוך תת-הספרייה שלו.",
2909
+ "selectedServices": "שירותים נבחרים",
2910
+ "noServicesSelected": "עדיין לא נבחרו שירותים. בחר ספריות למעלה.",
2911
+ "addServices": "הוסף שירות {count} | הוסף {count} שירותים",
2912
+ "removeService": "הסר {directory}",
2911
2913
  "addedConfigure": "{title} נוסף, הגדר אותו",
2912
2914
  "grantAccess": "הענק לאפליקציה גישה למאגר",
2913
2915
  "grantAccessTitle": "פתח את הגדרות ההתקנה של האפליקציה כדי להעניק לה גישה למאגר",
2914
2916
  "refreshList": "רענן רשימה",
2915
2917
  "done": "סיום",
2916
2918
  "add": "הוסף שירות",
2917
- "addAnother": "הוסף שירות נוסף",
2918
2919
  "toast": {
2919
2920
  "addedTitle": "השירות נוסף",
2920
2921
  "addedDescription": "{title} על הלוח, הגדר אותו למטה.",
2921
- "addFailedTitle": "לא ניתן היה להוסיף שירות"
2922
+ "addFailedTitle": "לא ניתן היה להוסיף שירות",
2923
+ "servicesAddedTitle": "השירותים נוספו",
2924
+ "servicesAddedDescription": "שירות {count} נוסף ללוח. | {count} שירותים נוספו ללוח."
2922
2925
  },
2923
2926
  "repoType": "סוג המאגר",
2924
2927
  "repoTypeHint": "מה המאגר הזה: שירות בק-אנד, אפליקציית פרונט-אנד, ספרייה משותפת או מאגר תיעוד (מסמכים/ספייקים בלבד)."
@@ -2930,6 +2933,7 @@
2930
2933
  "empty": "אין כאן כלום.",
2931
2934
  "select": "בחר",
2932
2935
  "selected": "נבחר",
2936
+ "added": "נוסף",
2933
2937
  "useThisFolder": "השתמש בתיקייה זו",
2934
2938
  "errors": {
2935
2939
  "listDirectory": "לא ניתן היה לרשום את הספרייה"
@@ -2523,20 +2523,23 @@
2523
2523
  },
2524
2524
  "monorepoLabel": "Questo è un monorepo (ospita più di un servizio)",
2525
2525
  "monorepoDescription": "Aggiungi più servizi da un unico repo, ciascuno ancorato a una sottodirectory.",
2526
- "monorepoBrowseHint": "Sfoglia il repository e scegli la directory del servizio che vuoi aggiungere. Gli agenti che lavorano su questo servizio verranno eseguiti all'interno di quella sottodirectory.",
2527
- "serviceDirectory": "Directory del servizio:",
2528
- "noDirectorySelected": "Nessuna directory ancora selezionata.",
2526
+ "monorepoBrowseHint": "Sfoglia il repository e seleziona le directory dei servizi che vuoi aggiungere, da qualsiasi cartella. Gli agenti che lavorano su un servizio verranno eseguiti all'interno della sua sottodirectory.",
2527
+ "selectedServices": "Servizi selezionati",
2528
+ "noServicesSelected": "Nessun servizio ancora selezionato. Scegli le directory sopra.",
2529
+ "addServices": "Aggiungi {count} servizio | Aggiungi {count} servizi",
2530
+ "removeService": "Rimuovi {directory}",
2529
2531
  "addedConfigure": "{title} aggiunto, configuralo",
2530
2532
  "grantAccess": "Concedi alla App l'accesso a un repo",
2531
2533
  "grantAccessTitle": "Apri le impostazioni di installazione della App per concederle l'accesso a un repository",
2532
2534
  "refreshList": "Aggiorna l'elenco",
2533
2535
  "done": "Fatto",
2534
2536
  "add": "Aggiungi servizio",
2535
- "addAnother": "Aggiungi un altro servizio",
2536
2537
  "toast": {
2537
2538
  "addedTitle": "Servizio aggiunto",
2538
2539
  "addedDescription": "{title} è sulla board, configuralo qui sotto.",
2539
- "addFailedTitle": "Impossibile aggiungere il servizio"
2540
+ "addFailedTitle": "Impossibile aggiungere il servizio",
2541
+ "servicesAddedTitle": "Servizi aggiunti",
2542
+ "servicesAddedDescription": "{count} servizio aggiunto alla board. | {count} servizi aggiunti alla board."
2540
2543
  }
2541
2544
  },
2542
2545
  "repoTree": {
@@ -2546,6 +2549,7 @@
2546
2549
  "empty": "Niente qui.",
2547
2550
  "select": "Seleziona",
2548
2551
  "selected": "Selezionata",
2552
+ "added": "Aggiunto",
2549
2553
  "useThisFolder": "Usa questa cartella",
2550
2554
  "errors": {
2551
2555
  "listDirectory": "Impossibile elencare la directory"
@@ -2906,20 +2906,23 @@
2906
2906
  },
2907
2907
  "monorepoLabel": "これはモノレポです (複数のサービスをホストしています)",
2908
2908
  "monorepoDescription": "1つのリポジトリから複数のサービスを追加し、それぞれをサブディレクトリに固定します。",
2909
- "monorepoBrowseHint": "リポジトリを参照し、追加したいサービスのディレクトリを選択してください。このサービスで作業するエージェントは、そのサブディレクトリ内で実行されます。",
2910
- "serviceDirectory": "サービスディレクトリ:",
2911
- "noDirectorySelected": "ディレクトリはまだ選択されていません。",
2909
+ "monorepoBrowseHint": "リポジトリを参照し、追加したいサービスのディレクトリを任意のフォルダから選択してください。サービスで作業するエージェントは、そのサブディレクトリ内で実行されます。",
2910
+ "selectedServices": "選択したサービス",
2911
+ "noServicesSelected": "サービスがまだ選択されていません。上でディレクトリを選択してください。",
2912
+ "addServices": "{count}件のサービスを追加 | {count}件のサービスを追加",
2913
+ "removeService": "{directory} を削除",
2912
2914
  "addedConfigure": "{title}を追加しました。設定してください",
2913
2915
  "grantAccess": "Appにリポジトリへのアクセス権を付与",
2914
2916
  "grantAccessTitle": "Appのインストール設定を開いて、リポジトリへのアクセス権を付与します",
2915
2917
  "refreshList": "リストを更新",
2916
2918
  "done": "完了",
2917
2919
  "add": "サービスを追加",
2918
- "addAnother": "別のサービスを追加",
2919
2920
  "toast": {
2920
2921
  "addedTitle": "サービスを追加しました",
2921
2922
  "addedDescription": "{title}がボードに追加されました。以下で設定してください。",
2922
- "addFailedTitle": "サービスを追加できませんでした"
2923
+ "addFailedTitle": "サービスを追加できませんでした",
2924
+ "servicesAddedTitle": "サービスを追加しました",
2925
+ "servicesAddedDescription": "{count}件のサービスをボードに追加しました。 | {count}件のサービスをボードに追加しました。"
2923
2926
  },
2924
2927
  "repoType": "リポジトリの種類",
2925
2928
  "repoTypeHint": "このリポジトリの種類: バックエンドサービス、フロントエンドアプリ、共有ライブラリ、またはドキュメントリポジトリ(ドキュメント/スパイクのみ)。"
@@ -2931,6 +2934,7 @@
2931
2934
  "empty": "ここには何もありません。",
2932
2935
  "select": "選択",
2933
2936
  "selected": "選択済み",
2937
+ "added": "追加済み",
2934
2938
  "useThisFolder": "このフォルダを使用",
2935
2939
  "errors": {
2936
2940
  "listDirectory": "ディレクトリを一覧表示できませんでした"
@@ -2894,20 +2894,23 @@
2894
2894
  },
2895
2895
  "monorepoLabel": "To jest monorepo (zawiera więcej niż jedną usługę)",
2896
2896
  "monorepoDescription": "Dodaj kilka usług z jednego repozytorium, każdą przypiętą do podkatalogu.",
2897
- "monorepoBrowseHint": "Przeglądaj repozytorium i wybierz katalog usługi, którą chcesz dodać. Agenci pracujący nad usługą będą działać w obrębie tego podkatalogu.",
2898
- "serviceDirectory": "Katalog usługi:",
2899
- "noDirectorySelected": "Nie wybrano jeszcze żadnego katalogu.",
2897
+ "monorepoBrowseHint": "Przeglądaj repozytorium i wybierz katalogi usług, które chcesz dodać — z dowolnego folderu. Agenci pracujący nad usługą działają w obrębie jej podkatalogu.",
2898
+ "selectedServices": "Wybrane usługi",
2899
+ "noServicesSelected": "Nie wybrano jeszcze żadnych usług. Wybierz katalogi powyżej.",
2900
+ "addServices": "Dodaj {count} usługę | Dodaj {count} usługi | Dodaj {count} usług",
2901
+ "removeService": "Usuń {directory}",
2900
2902
  "addedConfigure": "Dodano {title}, skonfiguruj",
2901
2903
  "grantAccess": "Przyznaj aplikacji dostęp do repozytorium",
2902
2904
  "grantAccessTitle": "Otwórz ustawienia instalacji aplikacji, aby przyznać jej dostęp do repozytorium",
2903
2905
  "refreshList": "Odśwież listę",
2904
2906
  "done": "Gotowe",
2905
2907
  "add": "Dodaj usługę",
2906
- "addAnother": "Dodaj kolejną usługę",
2907
2908
  "toast": {
2908
2909
  "addedTitle": "Dodano usługę",
2909
2910
  "addedDescription": "{title} jest na tablicy, skonfiguruj ją poniżej.",
2910
- "addFailedTitle": "Nie udało się dodać usługi"
2911
+ "addFailedTitle": "Nie udało się dodać usługi",
2912
+ "servicesAddedTitle": "Dodano usługi",
2913
+ "servicesAddedDescription": "Dodano {count} usługę do tablicy. | Dodano {count} usługi do tablicy. | Dodano {count} usług do tablicy."
2911
2914
  },
2912
2915
  "repoType": "Typ repozytorium",
2913
2916
  "repoTypeHint": "Czym jest to repozytorium: usługą backendową, aplikacją frontendową, współdzieloną biblioteką lub repozytorium dokumentacji (tylko dokumenty/spike'i)."
@@ -2919,6 +2922,7 @@
2919
2922
  "empty": "Pusto.",
2920
2923
  "select": "Wybierz",
2921
2924
  "selected": "Wybrano",
2925
+ "added": "Dodano",
2922
2926
  "useThisFolder": "Użyj tego folderu",
2923
2927
  "errors": {
2924
2928
  "listDirectory": "Nie udało się wyświetlić katalogu"
@@ -2906,20 +2906,23 @@
2906
2906
  },
2907
2907
  "monorepoLabel": "Bu bir monorepo (birden fazla servis barındırır)",
2908
2908
  "monorepoDescription": "Tek depodan, her biri bir alt dizine sabitlenmiş birkaç servis ekleyin.",
2909
- "monorepoBrowseHint": "Depoyu inceleyin ve eklemek istediğiniz servisin dizinini seçin. Bu servis üzerinde çalışan ajanlar o alt dizin içinde çalışır.",
2910
- "serviceDirectory": "Servis dizini:",
2911
- "noDirectorySelected": "Henüz dizin seçilmedi.",
2909
+ "monorepoBrowseHint": "Depoyu inceleyin ve eklemek istediğiniz servislerin dizinlerini herhangi bir klasörden seçin. Bir servis üzerinde çalışan ajanlar onun alt dizininde çalışır.",
2910
+ "selectedServices": "Seçili servisler",
2911
+ "noServicesSelected": "Henüz servis seçilmedi. Yukarıdan dizin seçin.",
2912
+ "addServices": "{count} servis ekle | {count} servis ekle",
2913
+ "removeService": "{directory} öğesini kaldır",
2912
2914
  "addedConfigure": "{title} eklendi, yapılandırın",
2913
2915
  "grantAccess": "App'e bir depoya erişim ver",
2914
2916
  "grantAccessTitle": "App'e bir depoya erişim vermek için kurulum ayarlarını açın",
2915
2917
  "refreshList": "Listeyi yenile",
2916
2918
  "done": "Tamam",
2917
2919
  "add": "Servis ekle",
2918
- "addAnother": "Başka bir servis ekle",
2919
2920
  "toast": {
2920
2921
  "addedTitle": "Servis eklendi",
2921
2922
  "addedDescription": "{title} panoda, aşağıdan yapılandırın.",
2922
- "addFailedTitle": "Servis eklenemedi"
2923
+ "addFailedTitle": "Servis eklenemedi",
2924
+ "servicesAddedTitle": "Servisler eklendi",
2925
+ "servicesAddedDescription": "{count} servis panoya eklendi. | {count} servis panoya eklendi."
2923
2926
  },
2924
2927
  "repoType": "Depo türü",
2925
2928
  "repoTypeHint": "Bu deponun türü: bir backend servisi, bir frontend uygulaması, paylaşılan bir kütüphane veya bir doküman deposu (yalnızca doküman/spike)."
@@ -2931,6 +2934,7 @@
2931
2934
  "empty": "Burada bir şey yok.",
2932
2935
  "select": "Seç",
2933
2936
  "selected": "Seçildi",
2937
+ "added": "Eklendi",
2934
2938
  "useThisFolder": "Bu klasörü kullan",
2935
2939
  "errors": {
2936
2940
  "listDirectory": "Dizin listelenemedi"
@@ -2894,20 +2894,23 @@
2894
2894
  },
2895
2895
  "monorepoLabel": "Це монорепозиторій (містить більше одного сервісу)",
2896
2896
  "monorepoDescription": "Додайте кілька сервісів з одного репозиторію, кожен прикріплений до підкаталогу.",
2897
- "monorepoBrowseHint": "Перегляньте репозиторій і виберіть каталог сервісу, який хочете додати. Агенти, що працюють над цим сервісом, виконуватимуться в межах цього підкаталогу.",
2898
- "serviceDirectory": "Каталог сервісу:",
2899
- "noDirectorySelected": "Каталог ще не вибрано.",
2897
+ "monorepoBrowseHint": "Перегляньте репозиторій і виберіть каталоги сервісів, які хочете додати — з будь-якої папки. Агенти, що працюють над сервісом, виконуються в межах його підкаталогу.",
2898
+ "selectedServices": "Вибрані сервіси",
2899
+ "noServicesSelected": "Сервіси ще не вибрано. Виберіть каталоги вище.",
2900
+ "addServices": "Додати {count} сервіс | Додати {count} сервіси | Додати {count} сервісів",
2901
+ "removeService": "Видалити {directory}",
2900
2902
  "addedConfigure": "{title} додано, налаштуйте",
2901
2903
  "grantAccess": "Надати застосунку доступ до репозиторію",
2902
2904
  "grantAccessTitle": "Відкрити налаштування встановлення застосунку, щоб надати йому доступ до репозиторію",
2903
2905
  "refreshList": "Оновити список",
2904
2906
  "done": "Готово",
2905
2907
  "add": "Додати сервіс",
2906
- "addAnother": "Додати ще один сервіс",
2907
2908
  "toast": {
2908
2909
  "addedTitle": "Сервіс додано",
2909
2910
  "addedDescription": "{title} на дошці, налаштуйте його нижче.",
2910
- "addFailedTitle": "Не вдалося додати сервіс"
2911
+ "addFailedTitle": "Не вдалося додати сервіс",
2912
+ "servicesAddedTitle": "Сервіси додано",
2913
+ "servicesAddedDescription": "Додано {count} сервіс до дошки. | Додано {count} сервіси до дошки. | Додано {count} сервісів до дошки."
2911
2914
  },
2912
2915
  "repoType": "Тип репозиторію",
2913
2916
  "repoTypeHint": "Що це за репозиторій: бекенд-сервіс, фронтенд-застосунок, спільна бібліотека або репозиторій документації (лише документи/спайки)."
@@ -2919,6 +2922,7 @@
2919
2922
  "empty": "Тут нічого немає.",
2920
2923
  "select": "Вибрати",
2921
2924
  "selected": "Вибрано",
2925
+ "added": "Додано",
2922
2926
  "useThisFolder": "Використати цю папку",
2923
2927
  "errors": {
2924
2928
  "listDirectory": "Не вдалося отримати список каталогу"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/app",
3
- "version": "0.116.7",
3
+ "version": "0.116.8",
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",