@cat-factory/app 0.200.0 → 0.200.3

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,11 +1,16 @@
1
1
  <script setup lang="ts">
2
2
  // Repo sources of foundational-service definitions (backend/docs/adr/0031-foundational-services.md).
3
- // Two link shapes, and the choice is the whole reason this form has a mode switch:
3
+ // Three link shapes, and the choice is the whole reason this form has a mode switch:
4
4
  // - `directory` — every immediate subdirectory of the linked path is a service, identified by
5
5
  // its `service.md`, with its contract files beside it. The "we keep our specs in a repo" case.
6
+ // - `folder` — the whole of one folder (optionally its subfolders too) is the contract set of
7
+ // the ONE service the link names. The "here is our spec directory" case.
6
8
  // - `files` — an explicit list of contract files, all describing the ONE service the link
7
- // names. The "just point at my openapi.yaml" case, where there is no directory convention to
8
- // adopt which is why the link itself must supply the identity, and the form demands it.
9
+ // names. The "just point at my openapi.yaml" case.
10
+ // `folder` and `files` both name their service on the link (there is no `service.md` convention to
11
+ // read identity from, which is why the form demands it), and differ in WHEN the file set is
12
+ // decided: `files` pins the paths, `folder` rediscovers them on every sync — so a spec directory
13
+ // that grows wants the folder shape.
9
14
  // Mirrors the skill library's sources UI: with the GitHub App connected the user searches a repo
10
15
  // and browses to a path; otherwise the manual owner/name fields are the fallback.
11
16
  import { computed, reactive, ref, watch } from 'vue'
@@ -63,6 +68,7 @@ const mode = ref<FoundationalServiceSourceMode>('directory')
63
68
  const repoId = ref<number | undefined>(undefined)
64
69
  const repo = ref<GitHubAvailableRepo | undefined>(undefined)
65
70
  const dirPath = ref<string | undefined>(undefined)
71
+ const recursive = ref(false)
66
72
  const filePaths = ref<string[]>([])
67
73
  const gitRef = ref('')
68
74
  const manual = reactive({ repoOwner: '', repoName: '', dirPath: '', filePaths: '' })
@@ -77,9 +83,21 @@ watch(repoId, () => {
77
83
 
78
84
  const modeItems = computed(() => [
79
85
  { value: 'directory' as const, label: t('foundational.sources.mode.directory') },
86
+ { value: 'folder' as const, label: t('foundational.sources.mode.folder') },
80
87
  { value: 'files' as const, label: t('foundational.sources.mode.files') },
81
88
  ])
82
89
 
90
+ // An exhaustive Record of STATIC literal keys, not a key assembled from `mode` — the typed-key
91
+ // check cannot see a runtime-built key, and this fails to compile the day a fourth mode lands.
92
+ const modeHints = computed<Record<FoundationalServiceSourceMode, string>>(() => ({
93
+ directory: t('foundational.sources.mode.directoryHint'),
94
+ folder: t('foundational.sources.mode.folderHint'),
95
+ files: t('foundational.sources.mode.filesHint'),
96
+ }))
97
+
98
+ /** Both single-service modes name their service on the link; only `files` enumerates paths. */
99
+ const namesService = computed(() => mode.value === 'folder' || mode.value === 'files')
100
+
83
101
  const ownerName = computed<{ owner: string; name: string } | null>(() => {
84
102
  if (githubReady.value) {
85
103
  return repo.value ? { owner: repo.value.owner, name: repo.value.name } : null
@@ -99,18 +117,20 @@ const linkedFiles = computed(() =>
99
117
  .filter(Boolean),
100
118
  )
101
119
 
102
- // A `files` source names the service its files describe — the backend refuses the link
103
- // otherwise, so the button is disabled rather than letting the user discover it as a 422.
120
+ // A `folder`/`files` source names the service its contracts describe — the backend refuses the
121
+ // link otherwise, so the button is disabled rather than letting the user discover it as a 422.
104
122
  const valid = computed(() => {
105
123
  if (!ownerName.value) return false
106
- if (mode.value !== 'files') return true
107
- return Boolean(named.serviceId.trim() && named.serviceName.trim() && linkedFiles.value.length)
124
+ if (!namesService.value) return true
125
+ if (!named.serviceId.trim() || !named.serviceName.trim()) return false
126
+ return mode.value !== 'files' || linkedFiles.value.length > 0
108
127
  })
109
128
 
110
129
  function resetDraft() {
111
130
  repoId.value = undefined
112
131
  repo.value = undefined
113
132
  dirPath.value = undefined
133
+ recursive.value = false
114
134
  filePaths.value = []
115
135
  gitRef.value = ''
116
136
  Object.assign(manual, { repoOwner: '', repoName: '', dirPath: '', filePaths: '' })
@@ -134,9 +154,10 @@ async function link() {
134
154
  gitRef: gitRef.value.trim() || undefined,
135
155
  mode: mode.value,
136
156
  dirPath: (githubReady.value ? dirPath.value : manual.dirPath.trim()) || undefined,
137
- ...(mode.value === 'files'
157
+ ...(mode.value === 'folder' ? { recursive: recursive.value } : {}),
158
+ ...(mode.value === 'files' ? { filePaths: linkedFiles.value } : {}),
159
+ ...(namesService.value
138
160
  ? {
139
- filePaths: linkedFiles.value,
140
161
  serviceId: named.serviceId.trim(),
141
162
  serviceName: named.serviceName.trim(),
142
163
  serviceSummary: named.serviceSummary.trim() || undefined,
@@ -157,13 +178,22 @@ async function sync(id: string) {
157
178
  await withRow(`sync:${id}`, async () => {
158
179
  try {
159
180
  const result = await catalog.syncSource(id)
181
+ // A folder link that quietly produced fewer contracts than its author expected has no
182
+ // other explanation available to them, so the losses ride the same toast as the counts.
183
+ const notes: string[] = []
184
+ if (result.skippedFiles > 0)
185
+ notes.push(
186
+ t('foundational.toast.syncSkipped', { count: result.skippedFiles }, result.skippedFiles),
187
+ )
188
+ if (result.truncated) notes.push(t('foundational.toast.syncTruncated'))
160
189
  toast.add({
161
190
  title: t('foundational.toast.synced', {
162
191
  updated: result.upserted,
163
192
  removed: result.tombstoned,
164
193
  }),
194
+ ...(notes.length ? { description: notes.join(' ') } : {}),
165
195
  icon: 'i-lucide-refresh-cw',
166
- color: 'info',
196
+ color: result.truncated ? 'warning' : 'info',
167
197
  })
168
198
  } catch (e) {
169
199
  notifyError(t('foundational.toast.syncFailed'), e)
@@ -223,14 +253,26 @@ async function unlink(id: string) {
223
253
  {{ s.repoOwner }}/{{ s.repoName }}<span class="text-slate-500">/{{ s.dirPath }}</span>
224
254
  </span>
225
255
  <p class="text-xs text-slate-500">
226
- {{
227
- s.mode === 'files'
228
- ? t('foundational.sources.metaFiles', {
229
- service: s.serviceName ?? s.serviceId ?? '',
230
- count: s.filePaths.length,
231
- })
232
- : t('foundational.sources.metaDirectory')
233
- }}
256
+ <template v-if="s.mode === 'files'">
257
+ {{
258
+ t('foundational.sources.metaFiles', {
259
+ service: s.serviceName ?? s.serviceId ?? '',
260
+ count: s.filePaths.length,
261
+ })
262
+ }}
263
+ </template>
264
+ <template v-else-if="s.mode === 'folder'">
265
+ {{
266
+ s.recursive
267
+ ? t('foundational.sources.metaFolderRecursive', {
268
+ service: s.serviceName ?? s.serviceId ?? '',
269
+ })
270
+ : t('foundational.sources.metaFolder', {
271
+ service: s.serviceName ?? s.serviceId ?? '',
272
+ })
273
+ }}
274
+ </template>
275
+ <template v-else>{{ t('foundational.sources.metaDirectory') }}</template>
234
276
  </p>
235
277
  <p class="text-xs text-slate-500">
236
278
  {{
@@ -295,13 +337,7 @@ async function unlink(id: string) {
295
337
  <p class="mb-2 text-sm font-medium">{{ t('foundational.sources.linkTitle') }}</p>
296
338
  <div class="flex flex-col gap-2">
297
339
  <URadioGroup v-model="mode" :items="modeItems" orientation="horizontal" size="sm" />
298
- <p class="text-xs text-slate-500">
299
- {{
300
- mode === 'files'
301
- ? t('foundational.sources.mode.filesHint')
302
- : t('foundational.sources.mode.directoryHint')
303
- }}
304
- </p>
340
+ <p class="text-xs text-slate-500">{{ modeHints[mode] }}</p>
305
341
 
306
342
  <!-- Connected: search a repo, then browse to the folder / pick the contract files -->
307
343
  <template v-if="githubReady">
@@ -359,9 +395,20 @@ async function unlink(id: string) {
359
395
  />
360
396
  </template>
361
397
 
362
- <!-- `files` mode carries no directory convention to read identity from, so the link
363
- supplies it. -->
364
- <template v-if="mode === 'files'">
398
+ <!-- Subfolders are opt-in: a folder link pointed near a repo root would otherwise walk
399
+ far more of the tree than its author meant to offer. -->
400
+ <USwitch
401
+ v-if="mode === 'folder'"
402
+ v-model="recursive"
403
+ size="sm"
404
+ :label="t('foundational.sources.recursive')"
405
+ :description="t('foundational.sources.recursiveHint')"
406
+ data-testid="foundational-source-recursive"
407
+ />
408
+
409
+ <!-- Neither single-service mode has a directory convention to read identity from, so the
410
+ link supplies it. -->
411
+ <template v-if="namesService">
365
412
  <div class="flex gap-2">
366
413
  <UInput
367
414
  v-model="named.serviceId"
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- // Account-tier repo-sourced Claude Skills library (docs/initiatives/repo-skills.md): a team
2
+ // Account-tier repo-sourced Claude Skills library (ADR 0024): a team
3
3
  // authors skills in a repo (`<skill>/SKILL.md` + resources), the account syncs them into a
4
4
  // catalog shared across its workspaces, and a pipeline `skill` step runs one. A body-only
5
5
  // section rendered in the "Skills" tab of AccountSettingsPanel; available for ALL account types.
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- // Repo-sourced Claude Skills library manager (docs/initiatives/repo-skills.md), for the account
2
+ // Repo-sourced Claude Skills library manager (ADR 0024), for the account
3
3
  // tier (skills are a single tier — shared across the account's workspaces). Link repo directories
4
4
  // of `<skill>/SKILL.md` folders, resync them (with a "changes available" badge), and review the
5
5
  // synced skill catalog a pipeline `skill` step picks from. Mirrors the fragment library's
@@ -10,7 +10,7 @@ import type { LinkSkillSourceInput } from '~/types/domain'
10
10
  import type { ApiContext } from './context'
11
11
 
12
12
  /**
13
- * The repo-sourced Claude Skills library (docs/initiatives/repo-skills.md). Skills live in ONE
13
+ * The repo-sourced Claude Skills library (ADR 0024). Skills live in ONE
14
14
  * tier — the account, shared across its workspaces — so every route is account-scoped
15
15
  * (`/accounts/:accountId/...`), unlike the two-tier fragment library.
16
16
  */
@@ -224,6 +224,10 @@ const CONFLICT_INFO: Record<Exclude<ConflictReason, BespokeConflictReason>, Conf
224
224
  titleKey: 'errors.conflict.title.foundational_service_exists',
225
225
  descriptionKey: 'errors.conflict.description.foundational_service_exists',
226
226
  },
227
+ binary_output_service_invalid: {
228
+ titleKey: 'errors.conflict.title.binary_output_service_invalid',
229
+ descriptionKey: 'errors.conflict.description.binary_output_service_invalid',
230
+ },
227
231
  foundational_service_not_inherited: {
228
232
  titleKey: 'errors.conflict.title.foundational_service_not_inherited',
229
233
  descriptionKey: 'errors.conflict.description.foundational_service_not_inherited',
@@ -10,7 +10,7 @@ import { useSingleFlightProbe } from '~/composables/useSingleFlightProbe'
10
10
  import { useSkillsStore } from '~/stores/skills'
11
11
 
12
12
  /**
13
- * The repo-sourced Claude Skills library for one account (docs/initiatives/repo-skills.md),
13
+ * The repo-sourced Claude Skills library for one account (ADR 0024),
14
14
  * used by the account-settings management surface. Holds the account's synced skill catalog
15
15
  * (full detail) and its linked repo sources, and drives link / sync / status / unlink. Skills
16
16
  * are a single account tier (no workspace tier), so — unlike the fragment library — there is no
@@ -8,7 +8,7 @@ const summary = (id: string, name = id): SkillSummary => ({ id, name, descriptio
8
8
  /**
9
9
  * The skill picker spans two stores: the snapshot-hydrated `useSkillsStore` (the catalog the
10
10
  * builder's `USelect` binds against) and the per-step `skillId` helpers on `usePipelinesStore`.
11
- * These pin the behaviours the builder relies on (docs/initiatives/repo-skills.md slice 3).
11
+ * These pin the behaviours the builder relies on (ADR 0024 slice 3).
12
12
  */
13
13
  describe('skills picker store — snapshot-hydrated catalog', () => {
14
14
  it('hydrate is a straight replace (a later hydrate does not merge with the earlier one)', () => {
@@ -3,7 +3,7 @@ import { ref } from 'vue'
3
3
  import type { SkillSummary } from '~/types/domain'
4
4
 
5
5
  /**
6
- * The account's repo-sourced Claude Skills catalog (docs/initiatives/repo-skills.md slice 3),
6
+ * The account's repo-sourced Claude Skills catalog (ADR 0024 slice 3),
7
7
  * hydrated from the workspace snapshot as lightweight `{ id, name, description }` summaries.
8
8
  * Drives the pipeline builder's per-step skill picker: a `skill` step binds its
9
9
  * `stepOptions.skillId` to one of these. Skills live in ONE tier (the account, shared across its
@@ -1,5 +1,5 @@
1
1
  // ---------------------------------------------------------------------------
2
- // Repo-sourced Claude Skills library (docs/initiatives/repo-skills.md). Mirrors
2
+ // Repo-sourced Claude Skills library (ADR 0024). Mirrors
3
3
  // the `@cat-factory/contracts` skill-library schemas: the account skill catalog
4
4
  // (shared across the account's workspaces), the repo sources that feed it, and the
5
5
  // lightweight per-skill summary carried in the workspace snapshot for the picker.
@@ -4289,12 +4289,16 @@
4289
4289
  "metaSynced": "synchronisiert {date} · Ref {ref}",
4290
4290
  "metaNever": "nie synchronisiert · Ref {ref}",
4291
4291
  "metaFiles": "{service} · {count} Vertragsdateien",
4292
+ "metaFolder": "{service} · Verträge aus diesem Ordner",
4293
+ "metaFolderRecursive": "{service} · Verträge aus diesem Ordner und seinen Unterordnern",
4292
4294
  "metaDirectory": "ein Dienst je Unterverzeichnis",
4293
4295
  "changes": "Änderungen",
4294
4296
  "check": "Auf Änderungen prüfen",
4295
4297
  "sync": "Erneut synchronisieren",
4296
4298
  "unlink": "Verknüpfung lösen",
4297
4299
  "selectedDir": "Verzeichnis:",
4300
+ "recursive": "Unterordner einbeziehen",
4301
+ "recursiveHint": "Auch Vertragsdateien unterhalb des verknüpften Ordners lesen.",
4298
4302
  "selectedFiles": "Ausgewählte Dateien: {count}",
4299
4303
  "wholeRepo": "Gesamtes Repository (Wurzel).",
4300
4304
  "ownerPlaceholder": "Owner",
@@ -4308,8 +4312,10 @@
4308
4312
  "serviceSummaryPlaceholder": "einzeilige Zusammenfassung (optional)",
4309
4313
  "mode": {
4310
4314
  "directory": "Ein Ordner mit Diensten",
4315
+ "folder": "Ganzer Ordner mit Verträgen, ein Dienst",
4311
4316
  "files": "Bestimmte Dateien, ein Dienst",
4312
4317
  "directoryHint": "Jedes Unterverzeichnis des verknüpften Pfads ist ein Dienst, beschrieben durch eine service.md mit den Vertragsdateien daneben.",
4318
+ "folderHint": "Jede Vertragsdatei im verknüpften Ordner beschreibt den einen Dienst, den du hier benennst; später hinzugefügte Dateien werden bei der nächsten Synchronisierung übernommen.",
4313
4319
  "filesHint": "Die aufgeführten Dateien beschreiben alle den einen Dienst, den du hier benennst. Nutze das, wenn es keine Ordnerkonvention gibt."
4314
4320
  }
4315
4321
  },
@@ -4338,6 +4344,8 @@
4338
4344
  "sourceLinked": "Repo verknüpft & synchronisiert",
4339
4345
  "linkSourceFailed": "Repo konnte nicht verknüpft werden",
4340
4346
  "synced": "Synchronisiert: {updated} aktualisiert, {removed} entfernt",
4347
+ "syncSkipped": "{count} Datei sah wie ein Vertrag aus, war aber nicht verwendbar. | {count} Dateien sahen wie Verträge aus, waren aber nicht verwendbar.",
4348
+ "syncTruncated": "Der Ordner enthält mehr, als eine Synchronisierung aufnehmen kann; es wurde nur ein Teil gelesen.",
4341
4349
  "syncFailed": "Repo konnte nicht synchronisiert werden",
4342
4350
  "changesAvailable": "Stromaufwärts liegen Änderungen vor",
4343
4351
  "upToDate": "Bereits aktuell",
@@ -4855,6 +4863,7 @@
4855
4863
  "pipeline_schedule_requires_recurring": "Wiederkehrender Zeitplan braucht diese Pipeline",
4856
4864
  "pipeline_schedule_intake_unconfigured": "Zeitplan ohne Ticket-Erfassung",
4857
4865
  "foundational_service_exists": "Basisdienst existiert bereits",
4866
+ "binary_output_service_invalid": "Dienst für Binärausgaben nicht auflösbar",
4858
4867
  "foundational_service_not_inherited": "Dieses Board hat den Dienst registriert"
4859
4868
  },
4860
4869
  "description": {
@@ -4885,6 +4894,7 @@
4885
4894
  "pipeline_schedule_requires_recurring": "Ein wiederkehrender Zeitplan verweist noch auf diese Pipeline. Sie nur einmalig zu machen würde jeden künftigen Lauf unterbrechen. Lösen Sie zuerst diesen Zeitplan.",
4886
4895
  "pipeline_schedule_intake_unconfigured": "Ein Bug-Intake-Schritt bezieht seine Arbeit aus der Ticket-Erfassung des Zeitplans, und der verknüpfte Zeitplan hat keine. Konfigurieren Sie zuerst die Ticket-Erfassung im Zeitplan.",
4887
4896
  "foundational_service_exists": "Ein Basisdienst mit dieser ID ist in diesem Bereich bereits registriert. Öffnen Sie den vorhandenen Eintrag und bearbeiten Sie ihn — zwei Dienste können sich keine ID teilen, denn die ID ist der Name, den ein Architekt in seinem Entwurf verwendet.",
4897
+ "binary_output_service_invalid": "Ein Schritt, der Binärausgaben erzeugt, wählt einen Basisdienst aus, den der Katalog dieses Workspace nicht auflösen kann: Die ID ist unbekannt, oder der gewählte Speicherdienst trägt nicht die Fähigkeit asset-storage. Korrigieren Sie die Auswahl des Schritts oder registrieren Sie den Dienst und starten Sie erneut.",
4888
4898
  "foundational_service_not_inherited": "Abwählen gilt für einen vom Konto geerbten Dienst. Diese ID ist von diesem Board registriert, es gibt also nichts abzuwählen - lösche stattdessen den eigenen Eintrag des Boards."
4889
4899
  },
4890
4900
  "action": {
@@ -603,6 +603,7 @@
603
603
  "pipeline_schedule_requires_recurring": "Recurring schedule needs this pipeline",
604
604
  "pipeline_schedule_intake_unconfigured": "Schedule has no issue intake",
605
605
  "foundational_service_exists": "Foundational service already exists",
606
+ "binary_output_service_invalid": "Binary output service can't be resolved",
606
607
  "foundational_service_not_inherited": "This board registered that service"
607
608
  },
608
609
  "description": {
@@ -636,6 +637,7 @@
636
637
  "pipeline_schedule_requires_recurring": "A recurring schedule still points at this pipeline, so making it one-off only would break every future run it starts. Detach that schedule first.",
637
638
  "pipeline_schedule_intake_unconfigured": "A bug intake step draws its work from the schedule issue intake settings, and the attached schedule has none. Configure issue intake on the schedule first.",
638
639
  "foundational_service_exists": "A foundational service with this id is already registered at this scope. Open the existing entry and edit it — two services cannot share an id, because the id is what an architect names in its design.",
640
+ "binary_output_service_invalid": "A step that generates binary outputs selects a foundational service this workspace's catalog can't resolve: the id is unknown, or the chosen storage service doesn't carry the asset-storage capability. Fix the step's selection or register the service, then start again.",
639
641
  "foundational_service_not_inherited": "Opting out applies to a service inherited from the account. This id is registered by this board, so there is nothing to opt out of - delete the board's own entry instead."
640
642
  },
641
643
  "action": {
@@ -5495,12 +5497,16 @@
5495
5497
  "metaSynced": "synced {date} · ref {ref}",
5496
5498
  "metaNever": "never synced · ref {ref}",
5497
5499
  "metaFiles": "{service} · {count} contract files",
5500
+ "metaFolder": "{service} · contracts from this folder",
5501
+ "metaFolderRecursive": "{service} · contracts from this folder and its subfolders",
5498
5502
  "metaDirectory": "one service per subdirectory",
5499
5503
  "changes": "Changes",
5500
5504
  "check": "Check for changes",
5501
5505
  "sync": "Resync",
5502
5506
  "unlink": "Unlink",
5503
5507
  "selectedDir": "Directory:",
5508
+ "recursive": "Include subfolders",
5509
+ "recursiveHint": "Also read contract files nested below the linked folder.",
5504
5510
  "selectedFiles": "Files picked: {count}",
5505
5511
  "wholeRepo": "Whole repository (root).",
5506
5512
  "ownerPlaceholder": "owner",
@@ -5514,8 +5520,10 @@
5514
5520
  "serviceSummaryPlaceholder": "one-line summary (optional)",
5515
5521
  "mode": {
5516
5522
  "directory": "A folder of services",
5523
+ "folder": "Whole folder of contracts, one service",
5517
5524
  "files": "Specific files, one service",
5518
5525
  "directoryHint": "Every subdirectory of the linked path is one service, described by a service.md with its contract files beside it.",
5526
+ "folderHint": "Every contract file in the linked folder describes the one service you name here, and files added later are picked up on the next sync.",
5519
5527
  "filesHint": "The listed files all describe the one service you name here. Use this when there is no folder convention to adopt."
5520
5528
  }
5521
5529
  },
@@ -5544,6 +5552,8 @@
5544
5552
  "sourceLinked": "Repo linked & synced",
5545
5553
  "linkSourceFailed": "Could not link the repo",
5546
5554
  "synced": "Synced: {updated} updated, {removed} removed",
5555
+ "syncSkipped": "{count} file looked like a contract but could not be used. | {count} files looked like contracts but could not be used.",
5556
+ "syncTruncated": "The folder holds more than one sync can take, so only part of it was read.",
5547
5557
  "syncFailed": "Could not sync the repo",
5548
5558
  "changesAvailable": "Changes available upstream",
5549
5559
  "upToDate": "Already up to date",
@@ -546,6 +546,7 @@
546
546
  "pipeline_schedule_requires_recurring": "Una programación recurrente necesita esta canalización",
547
547
  "pipeline_schedule_intake_unconfigured": "La programación no tiene entrada de incidencias",
548
548
  "foundational_service_exists": "El servicio fundacional ya existe",
549
+ "binary_output_service_invalid": "No se puede resolver el servicio de salidas binarias",
549
550
  "foundational_service_not_inherited": "Este tablero registró ese servicio"
550
551
  },
551
552
  "description": {
@@ -576,6 +577,7 @@
576
577
  "pipeline_schedule_requires_recurring": "Una programación recurrente todavía apunta a esta canalización, así que limitarla a un solo uso rompería cada ejecución futura. Desvincule primero esa programación.",
577
578
  "pipeline_schedule_intake_unconfigured": "Un paso de entrada de errores toma su trabajo de la entrada de incidencias de la programación, y la programación vinculada no la tiene. Configure la entrada de incidencias en la programación primero.",
578
579
  "foundational_service_exists": "Ya hay un servicio fundacional con este identificador registrado en este ámbito. Abre la entrada existente y edítala: dos servicios no pueden compartir un identificador, porque es el nombre que un arquitecto usa en su diseño.",
580
+ "binary_output_service_invalid": "Un paso que genera salidas binarias selecciona un servicio fundacional que el catálogo de este espacio de trabajo no puede resolver: el identificador es desconocido, o el servicio de almacenamiento elegido no tiene la capacidad asset-storage. Corrige la selección del paso o registra el servicio y vuelve a iniciarlo.",
579
581
  "foundational_service_not_inherited": "La exclusión se aplica a un servicio heredado de la cuenta. Este id está registrado por este tablero, así que no hay nada que excluir: elimina la entrada propia del tablero."
580
582
  },
581
583
  "action": {
@@ -5246,12 +5248,16 @@
5246
5248
  "metaSynced": "sincronizado {date} · ref {ref}",
5247
5249
  "metaNever": "nunca sincronizado · ref {ref}",
5248
5250
  "metaFiles": "{service} · {count} archivos de contrato",
5251
+ "metaFolder": "{service} · contratos de esta carpeta",
5252
+ "metaFolderRecursive": "{service} · contratos de esta carpeta y sus subcarpetas",
5249
5253
  "metaDirectory": "un servicio por subdirectorio",
5250
5254
  "changes": "Cambios",
5251
5255
  "check": "Buscar cambios",
5252
5256
  "sync": "Volver a sincronizar",
5253
5257
  "unlink": "Desvincular",
5254
5258
  "selectedDir": "Directorio:",
5259
+ "recursive": "Incluir subcarpetas",
5260
+ "recursiveHint": "Leer también los archivos de contrato anidados bajo la carpeta vinculada.",
5255
5261
  "selectedFiles": "Archivos elegidos: {count}",
5256
5262
  "wholeRepo": "Todo el repositorio (raíz).",
5257
5263
  "ownerPlaceholder": "propietario",
@@ -5265,8 +5271,10 @@
5265
5271
  "serviceSummaryPlaceholder": "resumen de una línea (opcional)",
5266
5272
  "mode": {
5267
5273
  "directory": "Una carpeta de servicios",
5274
+ "folder": "Carpeta entera de contratos, un servicio",
5268
5275
  "files": "Archivos concretos, un servicio",
5269
5276
  "directoryHint": "Cada subdirectorio de la ruta vinculada es un servicio, descrito por un service.md con sus archivos de contrato al lado.",
5277
+ "folderHint": "Cada archivo de contrato de la carpeta vinculada describe el único servicio que nombras aquí, y los archivos que se añadan después se recogen en la siguiente sincronización.",
5270
5278
  "filesHint": "Los archivos listados describen el único servicio que nombras aquí. Úsalo cuando no haya una convención de carpetas que adoptar."
5271
5279
  }
5272
5280
  },
@@ -5295,6 +5303,8 @@
5295
5303
  "sourceLinked": "Repositorio vinculado y sincronizado",
5296
5304
  "linkSourceFailed": "No se pudo vincular el repositorio",
5297
5305
  "synced": "Sincronizado: {updated} actualizados, {removed} eliminados",
5306
+ "syncSkipped": "{count} archivo parecía un contrato pero no se pudo usar. | {count} archivos parecían contratos pero no se pudieron usar.",
5307
+ "syncTruncated": "La carpeta contiene más de lo que cabe en una sincronización, así que solo se leyó una parte.",
5298
5308
  "syncFailed": "No se pudo sincronizar el repositorio",
5299
5309
  "changesAvailable": "Hay cambios en el origen",
5300
5310
  "upToDate": "Ya está actualizado",
@@ -546,6 +546,7 @@
546
546
  "pipeline_schedule_requires_recurring": "Une planification récurrente exige ce pipeline",
547
547
  "pipeline_schedule_intake_unconfigured": "La planification n'a pas de collecte de tickets",
548
548
  "foundational_service_exists": "Ce service fondamental existe déjà",
549
+ "binary_output_service_invalid": "Service des sorties binaires introuvable",
549
550
  "foundational_service_not_inherited": "Ce tableau a enregistré ce service"
550
551
  },
551
552
  "description": {
@@ -576,6 +577,7 @@
576
577
  "pipeline_schedule_requires_recurring": "Une planification récurrente pointe encore vers ce pipeline. Le limiter à une exécution unique casserait chaque exécution future. Détachez d'abord cette planification.",
577
578
  "pipeline_schedule_intake_unconfigured": "Une étape de collecte de bogues tire son travail des réglages de collecte de tickets de la planification, et la planification associée n'en a aucun. Configurez d'abord la collecte de tickets sur la planification.",
578
579
  "foundational_service_exists": "Un service fondamental portant cet identifiant est déjà enregistré dans cette portée. Ouvrez l’entrée existante et modifiez-la : deux services ne peuvent pas partager un identifiant, car c’est le nom qu’un architecte emploie dans sa conception.",
580
+ "binary_output_service_invalid": "Une étape qui génère des sorties binaires sélectionne un service fondamental que le catalogue de cet espace de travail ne peut pas résoudre : l’identifiant est inconnu, ou le service de stockage choisi ne porte pas la capacité asset-storage. Corrigez la sélection de l’étape ou enregistrez le service, puis relancez.",
579
581
  "foundational_service_not_inherited": "L'écartement s'applique à un service hérité du compte. Cet identifiant est enregistré par ce tableau : il n'y a donc rien à écarter - supprimez plutôt l'entrée propre au tableau."
580
582
  },
581
583
  "action": {
@@ -5246,12 +5248,16 @@
5246
5248
  "metaSynced": "synchronisé le {date} · réf {ref}",
5247
5249
  "metaNever": "jamais synchronisé · réf {ref}",
5248
5250
  "metaFiles": "{service} · {count} fichiers de contrat",
5251
+ "metaFolder": "{service} · contrats de ce dossier",
5252
+ "metaFolderRecursive": "{service} · contrats de ce dossier et de ses sous-dossiers",
5249
5253
  "metaDirectory": "un service par sous-répertoire",
5250
5254
  "changes": "Changements",
5251
5255
  "check": "Vérifier les changements",
5252
5256
  "sync": "Resynchroniser",
5253
5257
  "unlink": "Délier",
5254
5258
  "selectedDir": "Répertoire :",
5259
+ "recursive": "Inclure les sous-dossiers",
5260
+ "recursiveHint": "Lire aussi les fichiers de contrat imbriqués sous le dossier lié.",
5255
5261
  "selectedFiles": "Fichiers choisis : {count}",
5256
5262
  "wholeRepo": "Dépôt entier (racine).",
5257
5263
  "ownerPlaceholder": "propriétaire",
@@ -5265,8 +5271,10 @@
5265
5271
  "serviceSummaryPlaceholder": "résumé d'une ligne (facultatif)",
5266
5272
  "mode": {
5267
5273
  "directory": "Un dossier de services",
5274
+ "folder": "Dossier entier de contrats, un seul service",
5268
5275
  "files": "Des fichiers précis, un seul service",
5269
5276
  "directoryHint": "Chaque sous-répertoire du chemin lié est un service, décrit par un service.md avec ses fichiers de contrat à côté.",
5277
+ "folderHint": "Chaque fichier de contrat du dossier lié décrit l'unique service que vous nommez ici, et les fichiers ajoutés ensuite sont repris à la synchronisation suivante.",
5270
5278
  "filesHint": "Les fichiers listés décrivent tous l'unique service que vous nommez ici. À utiliser quand il n'y a pas de convention de dossiers à adopter."
5271
5279
  }
5272
5280
  },
@@ -5295,6 +5303,8 @@
5295
5303
  "sourceLinked": "Dépôt lié et synchronisé",
5296
5304
  "linkSourceFailed": "Impossible de lier le dépôt",
5297
5305
  "synced": "Synchronisé : {updated} mis à jour, {removed} retirés",
5306
+ "syncSkipped": "{count} fichier ressemblait à un contrat mais n'a pas pu être utilisé. | {count} fichiers ressemblaient à des contrats mais n'ont pas pu être utilisés.",
5307
+ "syncTruncated": "Le dossier contient plus que ce qu'une synchronisation peut prendre : seule une partie a été lue.",
5298
5308
  "syncFailed": "Impossible de synchroniser le dépôt",
5299
5309
  "changesAvailable": "Des changements sont disponibles en amont",
5300
5310
  "upToDate": "Déjà à jour",
@@ -546,6 +546,7 @@
546
546
  "pipeline_schedule_requires_recurring": "תזמון חוזר זקוק לצינור הזה",
547
547
  "pipeline_schedule_intake_unconfigured": "לתזמון אין קליטת פניות",
548
548
  "foundational_service_exists": "שירות תשתית כזה כבר קיים",
549
+ "binary_output_service_invalid": "לא ניתן לזהות את השירות לפלט בינארי",
549
550
  "foundational_service_not_inherited": "הלוח הזה רשם את השירות"
550
551
  },
551
552
  "description": {
@@ -576,6 +577,7 @@
576
577
  "pipeline_schedule_requires_recurring": "תזמון חוזר עדיין מפנה לצינור הזה, ולכן הפיכתו לחד פעמי בלבד תשבור כל הרצה עתידית. נתקו קודם את התזמון ההוא.",
577
578
  "pipeline_schedule_intake_unconfigured": "שלב קליטת באגים שואב את עבודתו מהגדרות קליטת הפניות של התזמון, ולתזמון המקושר אין כאלה. הגדירו קודם קליטת פניות בתזמון.",
578
579
  "foundational_service_exists": "שירות תשתית עם מזהה זה כבר רשום בהיקף הזה. פתחו את הרשומה הקיימת וערכו אותה — שני שירותים אינם יכולים לחלוק מזהה, מפני שהמזהה הוא השם שארכיטקט מציין בתכנון שלו.",
580
+ "binary_output_service_invalid": "שלב שמייצר פלט בינארי בוחר שירות תשתית שהקטלוג של סביבת העבודה אינו יכול לזהות: המזהה אינו מוכר, או ששירות האחסון שנבחר אינו נושא את היכולת asset-storage. תקנו את הבחירה בשלב או רשמו את השירות, ואז התחילו מחדש.",
579
581
  "foundational_service_not_inherited": "החרגה חלה על שירות שנורש מהחשבון. המזהה הזה רשום על ידי הלוח הזה, ולכן אין מה להחריג - מחקו במקום זאת את הרשומה של הלוח עצמו."
580
582
  },
581
583
  "action": {
@@ -5257,12 +5259,16 @@
5257
5259
  "metaSynced": "סונכרן {date} · ref {ref}",
5258
5260
  "metaNever": "מעולם לא סונכרן · ref {ref}",
5259
5261
  "metaFiles": "{service} · {count} קבצי חוזה",
5262
+ "metaFolder": "{service} · חוזים מתיקייה זו",
5263
+ "metaFolderRecursive": "{service} · חוזים מתיקייה זו ומתיקיות המשנה שלה",
5260
5264
  "metaDirectory": "שירות אחד לכל תיקיית משנה",
5261
5265
  "changes": "שינויים",
5262
5266
  "check": "בדיקת שינויים",
5263
5267
  "sync": "סנכרון מחדש",
5264
5268
  "unlink": "ניתוק",
5265
5269
  "selectedDir": "תיקייה:",
5270
+ "recursive": "לכלול תיקיות משנה",
5271
+ "recursiveHint": "לקרוא גם קבצי חוזה המקוננים מתחת לתיקייה המקושרת.",
5266
5272
  "selectedFiles": "קבצים שנבחרו: {count}",
5267
5273
  "wholeRepo": "כל המאגר (השורש).",
5268
5274
  "ownerPlaceholder": "בעלים",
@@ -5276,8 +5282,10 @@
5276
5282
  "serviceSummaryPlaceholder": "תקציר בשורה אחת (רשות)",
5277
5283
  "mode": {
5278
5284
  "directory": "תיקייה של שירותים",
5285
+ "folder": "תיקייה שלמה של חוזים, שירות אחד",
5279
5286
  "files": "קבצים מסוימים, שירות אחד",
5280
5287
  "directoryHint": "כל תיקיית משנה בנתיב המקושר היא שירות, המתואר בקובץ service.md עם קבצי החוזה לצידו.",
5288
+ "folderHint": "כל קובץ חוזה בתיקייה המקושרת מתאר את השירות היחיד שאתם מציינים כאן, וקבצים שיתווספו בהמשך ייקלטו בסנכרון הבא.",
5281
5289
  "filesHint": "כל הקבצים ברשימה מתארים את השירות היחיד שאתם מציינים כאן. השתמשו בזה כשאין מוסכמת תיקיות לאמץ."
5282
5290
  }
5283
5291
  },
@@ -5306,6 +5314,8 @@
5306
5314
  "sourceLinked": "המאגר קושר וסונכרן",
5307
5315
  "linkSourceFailed": "לא ניתן היה לקשר את המאגר",
5308
5316
  "synced": "סונכרן: {updated} עודכנו, {removed} הוסרו",
5317
+ "syncSkipped": "קובץ אחד נראה כמו חוזה אך לא ניתן היה להשתמש בו. | {count} קבצים נראו כמו חוזים אך לא ניתן היה להשתמש בהם.",
5318
+ "syncTruncated": "התיקייה מכילה יותר ממה שסנכרון אחד יכול לקלוט, ולכן נקרא רק חלק ממנה.",
5309
5319
  "syncFailed": "לא ניתן היה לסנכרן את המאגר",
5310
5320
  "changesAvailable": "יש שינויים במקור",
5311
5321
  "upToDate": "כבר מעודכן",
@@ -4289,12 +4289,16 @@
4289
4289
  "metaSynced": "sincronizzato {date} · ref {ref}",
4290
4290
  "metaNever": "mai sincronizzato · ref {ref}",
4291
4291
  "metaFiles": "{service} · {count} file di contratto",
4292
+ "metaFolder": "{service} · contratti da questa cartella",
4293
+ "metaFolderRecursive": "{service} · contratti da questa cartella e dalle sue sottocartelle",
4292
4294
  "metaDirectory": "un servizio per sottocartella",
4293
4295
  "changes": "Modifiche",
4294
4296
  "check": "Cerca modifiche",
4295
4297
  "sync": "Risincronizza",
4296
4298
  "unlink": "Scollega",
4297
4299
  "selectedDir": "Cartella:",
4300
+ "recursive": "Includi le sottocartelle",
4301
+ "recursiveHint": "Leggi anche i file di contratto annidati sotto la cartella collegata.",
4298
4302
  "selectedFiles": "File scelti: {count}",
4299
4303
  "wholeRepo": "Intero repository (radice).",
4300
4304
  "ownerPlaceholder": "proprietario",
@@ -4308,8 +4312,10 @@
4308
4312
  "serviceSummaryPlaceholder": "riepilogo di una riga (facoltativo)",
4309
4313
  "mode": {
4310
4314
  "directory": "Una cartella di servizi",
4315
+ "folder": "Intera cartella di contratti, un solo servizio",
4311
4316
  "files": "File specifici, un solo servizio",
4312
4317
  "directoryHint": "Ogni sottocartella del percorso collegato è un servizio, descritto da un service.md con accanto i suoi file di contratto.",
4318
+ "folderHint": "Ogni file di contratto nella cartella collegata descrive l'unico servizio che indichi qui, e i file aggiunti in seguito vengono raccolti alla sincronizzazione successiva.",
4313
4319
  "filesHint": "I file elencati descrivono tutti l'unico servizio che indichi qui. Usalo quando non c'è una convenzione di cartelle da adottare."
4314
4320
  }
4315
4321
  },
@@ -4338,6 +4344,8 @@
4338
4344
  "sourceLinked": "Repository collegato e sincronizzato",
4339
4345
  "linkSourceFailed": "Impossibile collegare il repository",
4340
4346
  "synced": "Sincronizzato: {updated} aggiornati, {removed} rimossi",
4347
+ "syncSkipped": "{count} file sembrava un contratto ma non è stato utilizzabile. | {count} file sembravano contratti ma non sono stati utilizzabili.",
4348
+ "syncTruncated": "La cartella contiene più di quanto una sincronizzazione possa prendere, quindi ne è stata letta solo una parte.",
4341
4349
  "syncFailed": "Impossibile sincronizzare il repository",
4342
4350
  "changesAvailable": "Sono disponibili modifiche a monte",
4343
4351
  "upToDate": "Già aggiornato",
@@ -4855,6 +4863,7 @@
4855
4863
  "pipeline_schedule_requires_recurring": "Una pianificazione ricorrente richiede questa pipeline",
4856
4864
  "pipeline_schedule_intake_unconfigured": "La pianificazione non ha raccolta ticket",
4857
4865
  "foundational_service_exists": "Il servizio fondamentale esiste già",
4866
+ "binary_output_service_invalid": "Impossibile risolvere il servizio per gli output binari",
4858
4867
  "foundational_service_not_inherited": "Questa bacheca ha registrato quel servizio"
4859
4868
  },
4860
4869
  "description": {
@@ -4885,6 +4894,7 @@
4885
4894
  "pipeline_schedule_requires_recurring": "Una pianificazione ricorrente punta ancora a questa pipeline, quindi renderla solo una tantum interromperebbe ogni esecuzione futura. Scollega prima quella pianificazione.",
4886
4895
  "pipeline_schedule_intake_unconfigured": "Un passo di raccolta bug prende il lavoro dalle impostazioni di raccolta ticket della pianificazione, e la pianificazione collegata non le ha. Configura prima la raccolta ticket sulla pianificazione.",
4887
4896
  "foundational_service_exists": "Un servizio fondamentale con questo identificatore è già registrato in questo ambito. Apri la voce esistente e modificala: due servizi non possono condividere un identificatore, perché è il nome che un architetto indica nella sua progettazione.",
4897
+ "binary_output_service_invalid": "Un passaggio che genera output binari seleziona un servizio fondamentale che il catalogo di questo workspace non riesce a risolvere: l'identificatore è sconosciuto, oppure il servizio di archiviazione scelto non ha la capacità asset-storage. Correggi la selezione del passaggio o registra il servizio, poi riavvia.",
4888
4898
  "foundational_service_not_inherited": "L'esclusione vale per un servizio ereditato dall'account. Questo id è registrato da questa bacheca, quindi non c'è nulla da escludere: elimina invece la voce propria della bacheca."
4889
4899
  },
4890
4900
  "action": {
@@ -546,6 +546,7 @@
546
546
  "pipeline_schedule_requires_recurring": "定期スケジュールにこのパイプラインが必要です",
547
547
  "pipeline_schedule_intake_unconfigured": "スケジュールに課題取り込み設定がありません",
548
548
  "foundational_service_exists": "その基盤サービスはすでに存在します",
549
+ "binary_output_service_invalid": "バイナリ出力用のサービスを解決できません",
549
550
  "foundational_service_not_inherited": "このボードが登録したサービスです"
550
551
  },
551
552
  "description": {
@@ -576,6 +577,7 @@
576
577
  "pipeline_schedule_requires_recurring": "定期スケジュールがまだこのパイプラインを参照しているため、単発専用にすると今後の実行がすべて失敗します。先にそのスケジュールを解除してください。",
577
578
  "pipeline_schedule_intake_unconfigured": "バグ取り込みステップはスケジュールの課題取り込み設定から作業を取得しますが、関連付けられたスケジュールにその設定がありません。先にスケジュールで課題取り込みを設定してください。",
578
579
  "foundational_service_exists": "この ID の基盤サービスはこのスコープにすでに登録されています。既存のエントリを開いて編集してください。ID は設計でアーキテクトが指定する名前なので、2 つのサービスが同じ ID を共有することはできません。",
580
+ "binary_output_service_invalid": "バイナリ出力を生成するステップが、このワークスペースのカタログでは解決できない基盤サービスを選択しています。ID が不明か、選択した保存先サービスに asset-storage ケイパビリティがありません。ステップの選択を修正するかサービスを登録して、もう一度開始してください。",
579
581
  "foundational_service_not_inherited": "除外はアカウントから継承したサービスに対する操作です。この ID はこのボード自身が登録しているため、除外するものがありません。代わりにボード自身のエントリを削除してください。"
580
582
  },
581
583
  "action": {
@@ -5258,12 +5260,16 @@
5258
5260
  "metaSynced": "同期日時 {date} · ref {ref}",
5259
5261
  "metaNever": "未同期 · ref {ref}",
5260
5262
  "metaFiles": "{service} · コントラクトファイル {count} 件",
5263
+ "metaFolder": "{service} · このフォルダのコントラクト",
5264
+ "metaFolderRecursive": "{service} · このフォルダとサブフォルダのコントラクト",
5261
5265
  "metaDirectory": "サブディレクトリごとに 1 サービス",
5262
5266
  "changes": "変更あり",
5263
5267
  "check": "変更を確認",
5264
5268
  "sync": "再同期",
5265
5269
  "unlink": "連携解除",
5266
5270
  "selectedDir": "ディレクトリ:",
5271
+ "recursive": "サブフォルダを含める",
5272
+ "recursiveHint": "連携したフォルダの下にネストされたコントラクトファイルも読み込みます。",
5267
5273
  "selectedFiles": "選択したファイル: {count}",
5268
5274
  "wholeRepo": "リポジトリ全体(ルート)。",
5269
5275
  "ownerPlaceholder": "オーナー",
@@ -5277,8 +5283,10 @@
5277
5283
  "serviceSummaryPlaceholder": "1 行の要約(任意)",
5278
5284
  "mode": {
5279
5285
  "directory": "サービスをまとめたフォルダ",
5286
+ "folder": "フォルダ全体のコントラクト、1 サービス",
5280
5287
  "files": "特定のファイル、1 サービス",
5281
5288
  "directoryHint": "連携したパスの各サブディレクトリが 1 つのサービスで、service.md で説明され、その横にコントラクトファイルが置かれます。",
5289
+ "folderHint": "連携したフォルダ内のすべてのコントラクトファイルが、ここで指定する 1 つのサービスを説明します。後から追加されたファイルは次回の同期で取り込まれます。",
5282
5290
  "filesHint": "列挙したファイルはすべて、ここで指定する 1 つのサービスを説明します。従うべきフォルダ規約がない場合に使います。"
5283
5291
  }
5284
5292
  },
@@ -5307,6 +5315,8 @@
5307
5315
  "sourceLinked": "リポジトリを連携して同期しました",
5308
5316
  "linkSourceFailed": "リポジトリを連携できませんでした",
5309
5317
  "synced": "同期完了: {updated} 件更新、{removed} 件削除",
5318
+ "syncSkipped": "コントラクトらしき {count} 件のファイルを利用できませんでした。 | コントラクトらしき {count} 件のファイルを利用できませんでした。",
5319
+ "syncTruncated": "フォルダの内容が 1 回の同期で扱える量を超えているため、一部のみ読み込みました。",
5310
5320
  "syncFailed": "リポジトリを同期できませんでした",
5311
5321
  "changesAvailable": "上流に変更があります",
5312
5322
  "upToDate": "すでに最新です",
@@ -546,6 +546,7 @@
546
546
  "pipeline_schedule_requires_recurring": "Harmonogram cykliczny wymaga tego potoku",
547
547
  "pipeline_schedule_intake_unconfigured": "Harmonogram nie ma pobierania zgłoszeń",
548
548
  "foundational_service_exists": "Usługa fundamentalna już istnieje",
549
+ "binary_output_service_invalid": "Nie można rozpoznać usługi dla wyników binarnych",
549
550
  "foundational_service_not_inherited": "Ta tablica zarejestrowała tę usługę"
550
551
  },
551
552
  "description": {
@@ -576,6 +577,7 @@
576
577
  "pipeline_schedule_requires_recurring": "Harmonogram cykliczny nadal wskazuje ten potok, więc ograniczenie go do jednorazowego zepsułoby każde przyszłe uruchomienie. Najpierw odłącz ten harmonogram.",
577
578
  "pipeline_schedule_intake_unconfigured": "Krok pobierania błędów czerpie pracę z ustawień pobierania zgłoszeń harmonogramu, a powiązany harmonogram ich nie ma. Najpierw skonfiguruj pobieranie zgłoszeń w harmonogramie.",
578
579
  "foundational_service_exists": "Usługa fundamentalna o tym identyfikatorze jest już zarejestrowana w tym zakresie. Otwórz istniejący wpis i go edytuj — dwie usługi nie mogą współdzielić identyfikatora, ponieważ to jego nazwą architekt posługuje się w projekcie.",
580
+ "binary_output_service_invalid": "Krok generujący wyniki binarne wybiera usługę fundamentalną, której katalog tego obszaru roboczego nie może rozpoznać: identyfikator jest nieznany albo wybrana usługa przechowywania nie ma zdolności asset-storage. Popraw wybór w kroku lub zarejestruj usługę, a następnie uruchom ponownie.",
579
581
  "foundational_service_not_inherited": "Wyłączenie dotyczy usługi dziedziczonej z konta. Ten identyfikator jest zarejestrowany przez tę tablicę, więc nie ma czego wyłączać - usuń zamiast tego własny wpis tablicy."
580
582
  },
581
583
  "action": {
@@ -5246,12 +5248,16 @@
5246
5248
  "metaSynced": "zsynchronizowano {date} · ref {ref}",
5247
5249
  "metaNever": "nigdy nie synchronizowano · ref {ref}",
5248
5250
  "metaFiles": "{service} · {count} plików kontraktów",
5251
+ "metaFolder": "{service} · kontrakty z tego folderu",
5252
+ "metaFolderRecursive": "{service} · kontrakty z tego folderu i jego podfolderów",
5249
5253
  "metaDirectory": "jedna usługa na podkatalog",
5250
5254
  "changes": "Zmiany",
5251
5255
  "check": "Sprawdź zmiany",
5252
5256
  "sync": "Zsynchronizuj ponownie",
5253
5257
  "unlink": "Odłącz",
5254
5258
  "selectedDir": "Katalog:",
5259
+ "recursive": "Uwzględnij podfoldery",
5260
+ "recursiveHint": "Czytaj także pliki kontraktów zagnieżdżone poniżej powiązanego folderu.",
5255
5261
  "selectedFiles": "Wybrane pliki: {count}",
5256
5262
  "wholeRepo": "Całe repozytorium (katalog główny).",
5257
5263
  "ownerPlaceholder": "właściciel",
@@ -5265,8 +5271,10 @@
5265
5271
  "serviceSummaryPlaceholder": "jednozdaniowe streszczenie (opcjonalne)",
5266
5272
  "mode": {
5267
5273
  "directory": "Katalog z usługami",
5274
+ "folder": "Cały folder kontraktów, jedna usługa",
5268
5275
  "files": "Wybrane pliki, jedna usługa",
5269
5276
  "directoryHint": "Każdy podkatalog powiązanej ścieżki to jedna usługa, opisana plikiem service.md, obok którego leżą jej pliki kontraktów.",
5277
+ "folderHint": "Każdy plik kontraktu w powiązanym folderze opisuje tę jedną usługę, którą tu nazywasz, a pliki dodane później zostaną pobrane przy następnej synchronizacji.",
5270
5278
  "filesHint": "Wymienione pliki opisują tę jedną usługę, którą tu nazywasz. Użyj tego, gdy nie ma konwencji katalogów do przyjęcia."
5271
5279
  }
5272
5280
  },
@@ -5295,6 +5303,8 @@
5295
5303
  "sourceLinked": "Repozytorium powiązane i zsynchronizowane",
5296
5304
  "linkSourceFailed": "Nie udało się powiązać repozytorium",
5297
5305
  "synced": "Zsynchronizowano: {updated} zaktualizowanych, {removed} usuniętych",
5306
+ "syncSkipped": "{count} plik wyglądał jak kontrakt, ale nie dało się go użyć. | {count} pliki wyglądały jak kontrakty, ale nie dało się ich użyć. | {count} plików wyglądało jak kontrakty, ale nie dało się ich użyć.",
5307
+ "syncTruncated": "Folder zawiera więcej, niż mieści jedna synchronizacja, więc odczytano tylko jego część.",
5298
5308
  "syncFailed": "Nie udało się zsynchronizować repozytorium",
5299
5309
  "changesAvailable": "W źródle są zmiany",
5300
5310
  "upToDate": "Już aktualne",
@@ -546,6 +546,7 @@
546
546
  "pipeline_schedule_requires_recurring": "Yinelenen bir zamanlama bu hatta ihtiyaç duyuyor",
547
547
  "pipeline_schedule_intake_unconfigured": "Zamanlamada sorun alımı yok",
548
548
  "foundational_service_exists": "Temel hizmet zaten var",
549
+ "binary_output_service_invalid": "İkili çıktı hizmeti çözümlenemiyor",
549
550
  "foundational_service_not_inherited": "Bu hizmeti bu pano kaydetti"
550
551
  },
551
552
  "description": {
@@ -576,6 +577,7 @@
576
577
  "pipeline_schedule_requires_recurring": "Yinelenen bir zamanlama hâlâ bu hattı gösteriyor, bu yüzden yalnızca tek seferlik yapmak gelecekteki her çalışmayı bozar. Önce o zamanlamayı ayırın.",
577
578
  "pipeline_schedule_intake_unconfigured": "Hata alımı adımı işini zamanlamanın sorun alımı ayarlarından alır ve bağlı zamanlamada bu ayar yok. Önce zamanlamada sorun alımını yapılandırın.",
578
579
  "foundational_service_exists": "Bu kimliğe sahip bir temel hizmet bu kapsamda zaten kayıtlı. Var olan kaydı açıp düzenleyin — iki hizmet aynı kimliği paylaşamaz, çünkü kimlik bir mimarın tasarımında andığı addır.",
580
+ "binary_output_service_invalid": "İkili çıktılar üreten bir adım, bu çalışma alanının kataloğunda çözümlenemeyen bir temel hizmet seçiyor: kimlik bilinmiyor ya da seçilen depolama hizmeti asset-storage yeteneğini taşımıyor. Adımın seçimini düzeltin veya hizmeti kaydedin, sonra yeniden başlatın.",
579
581
  "foundational_service_not_inherited": "Devre dışı bırakma, hesaptan devralınan bir hizmet için geçerlidir. Bu kimlik bu pano tarafından kaydedilmiş, dolayısıyla devre dışı bırakılacak bir şey yok - bunun yerine panonun kendi kaydını silin."
580
582
  },
581
583
  "action": {
@@ -5258,12 +5260,16 @@
5258
5260
  "metaSynced": "eşitlendi {date} · ref {ref}",
5259
5261
  "metaNever": "hiç eşitlenmedi · ref {ref}",
5260
5262
  "metaFiles": "{service} · {count} sözleşme dosyası",
5263
+ "metaFolder": "{service} · bu klasördeki sözleşmeler",
5264
+ "metaFolderRecursive": "{service} · bu klasördeki ve alt klasörlerindeki sözleşmeler",
5261
5265
  "metaDirectory": "her alt dizin için bir hizmet",
5262
5266
  "changes": "Değişiklikler",
5263
5267
  "check": "Değişiklikleri denetle",
5264
5268
  "sync": "Yeniden eşitle",
5265
5269
  "unlink": "Bağlantıyı kaldır",
5266
5270
  "selectedDir": "Dizin:",
5271
+ "recursive": "Alt klasörleri dahil et",
5272
+ "recursiveHint": "Bağlanan klasörün altında yer alan sözleşme dosyalarını da oku.",
5267
5273
  "selectedFiles": "Seçilen dosyalar: {count}",
5268
5274
  "wholeRepo": "Tüm depo (kök).",
5269
5275
  "ownerPlaceholder": "sahip",
@@ -5277,8 +5283,10 @@
5277
5283
  "serviceSummaryPlaceholder": "tek satırlık özet (isteğe bağlı)",
5278
5284
  "mode": {
5279
5285
  "directory": "Hizmetlerin bulunduğu bir klasör",
5286
+ "folder": "Sözleşmelerin tamamının bulunduğu klasör, tek hizmet",
5280
5287
  "files": "Belirli dosyalar, tek hizmet",
5281
5288
  "directoryHint": "Bağlanan yolun her alt dizini bir hizmettir; bir service.md ile tanımlanır ve sözleşme dosyaları onun yanında durur.",
5289
+ "folderHint": "Bağlanan klasördeki her sözleşme dosyası burada adlandırdığınız tek hizmeti tanımlar; sonradan eklenen dosyalar bir sonraki eşitlemede alınır.",
5282
5290
  "filesHint": "Listelenen dosyaların tamamı burada adlandırdığınız tek hizmeti tanımlar. Benimsenecek bir klasör düzeni yoksa bunu kullanın."
5283
5291
  }
5284
5292
  },
@@ -5307,6 +5315,8 @@
5307
5315
  "sourceLinked": "Depo bağlandı ve eşitlendi",
5308
5316
  "linkSourceFailed": "Depo bağlanamadı",
5309
5317
  "synced": "Eşitlendi: {updated} güncellendi, {removed} kaldırıldı",
5318
+ "syncSkipped": "{count} dosya sözleşmeye benziyordu ama kullanılamadı. | {count} dosya sözleşmeye benziyordu ama kullanılamadı.",
5319
+ "syncTruncated": "Klasör tek bir eşitlemenin alabileceğinden fazlasını içeriyor, bu yüzden yalnızca bir kısmı okundu.",
5310
5320
  "syncFailed": "Depo eşitlenemedi",
5311
5321
  "changesAvailable": "Kaynakta değişiklikler var",
5312
5322
  "upToDate": "Zaten güncel",
@@ -546,6 +546,7 @@
546
546
  "pipeline_schedule_requires_recurring": "Повторюваний розклад потребує цього конвеєра",
547
547
  "pipeline_schedule_intake_unconfigured": "У розкладі немає збору звернень",
548
548
  "foundational_service_exists": "Базовий сервіс уже існує",
549
+ "binary_output_service_invalid": "Не вдається розпізнати сервіс для бінарних результатів",
549
550
  "foundational_service_not_inherited": "Цей сервіс зареєструвала ця дошка"
550
551
  },
551
552
  "description": {
@@ -576,6 +577,7 @@
576
577
  "pipeline_schedule_requires_recurring": "Повторюваний розклад досі посилається на цей конвеєр, тож зробити його лише одноразовим зламало б кожен майбутній запуск. Спершу відʼєднайте цей розклад.",
577
578
  "pipeline_schedule_intake_unconfigured": "Крок збору помилок бере роботу з налаштувань збору звернень у розкладі, а привʼязаний розклад їх не має. Спершу налаштуйте збір звернень у розкладі.",
578
579
  "foundational_service_exists": "Базовий сервіс із цим ідентифікатором уже зареєстровано в цій області. Відкрийте наявний запис і відредагуйте його — два сервіси не можуть мати спільний ідентифікатор, бо саме його архітектор називає у своєму проєкті.",
580
+ "binary_output_service_invalid": "Крок, що генерує бінарні результати, вибирає базовий сервіс, який каталог цього робочого простору не може розпізнати: ідентифікатор невідомий або вибраний сервіс зберігання не має здатності asset-storage. Виправте вибір у кроці або зареєструйте сервіс і запустіть знову.",
579
581
  "foundational_service_not_inherited": "Вимкнення стосується сервісу, успадкованого від облікового запису. Цей ідентифікатор зареєстровано цією дошкою, тож вимикати нічого - натомість видаліть власний запис дошки."
580
582
  },
581
583
  "action": {
@@ -5246,12 +5248,16 @@
5246
5248
  "metaSynced": "синхронізовано {date} · ref {ref}",
5247
5249
  "metaNever": "ніколи не синхронізовано · ref {ref}",
5248
5250
  "metaFiles": "{service} · {count} файлів контрактів",
5251
+ "metaFolder": "{service} · контракти з цієї теки",
5252
+ "metaFolderRecursive": "{service} · контракти з цієї теки та її підтек",
5249
5253
  "metaDirectory": "один сервіс на підкаталог",
5250
5254
  "changes": "Зміни",
5251
5255
  "check": "Перевірити зміни",
5252
5256
  "sync": "Синхронізувати знову",
5253
5257
  "unlink": "Від'єднати",
5254
5258
  "selectedDir": "Каталог:",
5259
+ "recursive": "Включати підтеки",
5260
+ "recursiveHint": "Читати також файли контрактів, вкладені під приєднаною текою.",
5255
5261
  "selectedFiles": "Обрані файли: {count}",
5256
5262
  "wholeRepo": "Увесь репозиторій (корінь).",
5257
5263
  "ownerPlaceholder": "власник",
@@ -5265,8 +5271,10 @@
5265
5271
  "serviceSummaryPlaceholder": "однорядковий опис (необов'язково)",
5266
5272
  "mode": {
5267
5273
  "directory": "Каталог із сервісами",
5274
+ "folder": "Уся тека контрактів, один сервіс",
5268
5275
  "files": "Окремі файли, один сервіс",
5269
5276
  "directoryHint": "Кожен підкаталог приєднаного шляху - це один сервіс, описаний файлом service.md, поруч з яким лежать його файли контрактів.",
5277
+ "folderHint": "Кожен файл контракту в приєднаній теці описує той єдиний сервіс, який ви тут називаєте, а файли, додані згодом, буде підхоплено під час наступної синхронізації.",
5270
5278
  "filesHint": "Усі перелічені файли описують той єдиний сервіс, який ви тут називаєте. Використовуйте це, коли немає угоди про каталоги."
5271
5279
  }
5272
5280
  },
@@ -5295,6 +5303,8 @@
5295
5303
  "sourceLinked": "Репозиторій приєднано та синхронізовано",
5296
5304
  "linkSourceFailed": "Не вдалося приєднати репозиторій",
5297
5305
  "synced": "Синхронізовано: {updated} оновлено, {removed} вилучено",
5306
+ "syncSkipped": "{count} файл був схожий на контракт, але його не вдалося використати. | {count} файли були схожі на контракти, але їх не вдалося використати. | {count} файлів були схожі на контракти, але їх не вдалося використати.",
5307
+ "syncTruncated": "Тека містить більше, ніж вміщає одна синхронізація, тому прочитано лише її частину.",
5298
5308
  "syncFailed": "Не вдалося синхронізувати репозиторій",
5299
5309
  "changesAvailable": "У джерелі є зміни",
5300
5310
  "upToDate": "Уже актуально",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/app",
3
- "version": "0.200.0",
3
+ "version": "0.200.3",
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.206.0"
43
+ "@cat-factory/contracts": "0.208.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@toad-contracts/testing": "0.3.2",