@cat-factory/app 0.58.3 → 0.58.5

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,14 +1,14 @@
1
1
  <script setup lang="ts">
2
2
  import { computed, ref } from 'vue'
3
- import type { Block, CloudProvider, InstanceSize } from '~/types/domain'
3
+ import type { Block, CloudProvider, InstanceSize, ProvisionType } from '~/types/domain'
4
4
  import RepoTreeBrowser from '~/components/github/RepoTreeBrowser.vue'
5
5
 
6
- // Service-level (frame) configuration: where the Tester's local-mode infra comes
7
- // from (a docker-compose path, or an explicit "no infra dependencies" toggle — a
8
- // Tester pipeline can't start until one is set), plus the cloud provider + instance
9
- // size the service's container jobs run on. Autodiscovery suggests a compose path
10
- // when the service is added; it can be set/changed here later or browsed for in
11
- // the backing repository.
6
+ // Service-level (frame) configuration: the service-owned PROVISIONING — the provision
7
+ // TYPE this service produces (`infraless` / `docker-compose` / `kubernetes` / `custom`)
8
+ // plus, for docker-compose, the in-repo compose path the Tester stands up and the
9
+ // cloud provider + instance size the service's container jobs run on. The WORKSPACE
10
+ // configures HOW each type is handled (the engine + connection), so this view only owns
11
+ // the "what + where". Autodiscovery suggests a compose path when the service is added.
12
12
  const props = defineProps<{
13
13
  block: Block
14
14
  // Repo backing this service, supplied by the add-service modal when the block is
@@ -22,33 +22,33 @@ const github = useGitHubStore()
22
22
  const services = useServicesStore()
23
23
  const { t } = useI18n()
24
24
 
25
- const composePath = computed(() => props.block.testComposePath ?? '')
26
- const noInfra = computed(() => props.block.noInfraDependencies === true)
25
+ // The service's declared provision type (absent treated as `infraless`: no environment
26
+ // is stood up for the Tester). Switching type preserves the compose path so toggling away
27
+ // and back doesn't lose it.
28
+ const provisionType = computed<ProvisionType>(() => props.block.provisioning?.type ?? 'infraless')
29
+ const composePath = computed(() => props.block.provisioning?.composePath ?? '')
30
+
31
+ const PROVISION_TYPES = computed<{ value: ProvisionType; label: string }[]>(() => [
32
+ { value: 'infraless', label: t('inspector.testConfig.provisionTypes.infraless') },
33
+ { value: 'docker-compose', label: t('inspector.testConfig.provisionTypes.docker-compose') },
34
+ { value: 'kubernetes', label: t('inspector.testConfig.provisionTypes.kubernetes') },
35
+ { value: 'custom', label: t('inspector.testConfig.provisionTypes.custom') },
36
+ ])
27
37
 
28
- // The default test environment a task under this service is spawned with. `local`
29
- // stands the dependencies up via docker-compose (or "no infra"); `ephemeral` runs
30
- // against a provisioned environment. A task can override it per-task in its agent
31
- // settings. Absent ⇒ the built-in `ephemeral`.
32
- type TestEnvironment = 'local' | 'ephemeral'
33
- const TEST_ENVIRONMENTS = computed<{ value: TestEnvironment; label: string; hint: string }[]>(
34
- () => [
35
- {
36
- value: 'ephemeral',
37
- label: t('inspector.testConfig.env.ephemeral'),
38
- hint: t('inspector.testConfig.env.ephemeralHint'),
39
- },
40
- {
41
- value: 'local',
42
- label: t('inspector.testConfig.env.local'),
43
- hint: t('inspector.testConfig.env.localHint'),
38
+ function setProvisionType(type: ProvisionType) {
39
+ // Carry the compose path across a switch so it isn't lost when toggling type.
40
+ board.updateBlock(props.block.id, {
41
+ provisioning: {
42
+ type,
43
+ ...(type === 'docker-compose' && composePath.value ? { composePath: composePath.value } : {}),
44
44
  },
45
- ],
46
- )
47
- const effectiveTestEnv = computed<TestEnvironment>(
48
- () => props.block.defaultTestEnvironment ?? 'ephemeral',
49
- )
50
- function setDefaultTestEnv(value: TestEnvironment) {
51
- board.updateBlock(props.block.id, { defaultTestEnvironment: value })
45
+ })
46
+ }
47
+
48
+ function setComposePath(value: string) {
49
+ board.updateBlock(props.block.id, {
50
+ provisioning: { type: 'docker-compose', composePath: value.trim() },
51
+ })
52
52
  }
53
53
 
54
54
  // The provisioning hints (cloud provider + instance size) are advisory inputs to the
@@ -86,13 +86,6 @@ const effectiveProvider = computed<CloudProvider>(
86
86
  () => props.block.cloudProvider ?? accounts.activeAccount?.defaultCloudProvider ?? 'cloudflare',
87
87
  )
88
88
 
89
- function setComposePath(value: string) {
90
- board.updateBlock(props.block.id, { testComposePath: value.trim() })
91
- }
92
- function toggleNoInfra(value: boolean) {
93
- board.updateBlock(props.block.id, { noInfraDependencies: value })
94
- }
95
-
96
89
  const PROVIDERS = computed<{ value: CloudProvider; label: string }[]>(() => [
97
90
  { value: 'cloudflare', label: 'Cloudflare' },
98
91
  { value: 'docker', label: t('inspector.testConfig.providers.docker') },
@@ -114,8 +107,6 @@ function setProvider(value: CloudProvider) {
114
107
  function setSize(value: InstanceSize) {
115
108
  board.updateBlock(props.block.id, { instanceSize: value })
116
109
  }
117
-
118
- const missingInfra = computed(() => !noInfra.value && composePath.value.trim() === '')
119
110
  </script>
120
111
 
121
112
  <template>
@@ -125,26 +116,25 @@ const missingInfra = computed(() => !noInfra.value && composePath.value.trim() =
125
116
  </div>
126
117
 
127
118
  <div class="space-y-1">
128
- <span class="text-[11px] text-slate-400">{{ t('inspector.testConfig.defaultEnv') }}</span>
119
+ <span class="text-[11px] text-slate-400">{{ t('inspector.testConfig.provisionType') }}</span>
129
120
  <div class="flex flex-wrap gap-1">
130
121
  <UButton
131
- v-for="e in TEST_ENVIRONMENTS"
132
- :key="e.value"
133
- :color="effectiveTestEnv === e.value ? 'primary' : 'neutral'"
134
- :variant="effectiveTestEnv === e.value ? 'soft' : 'ghost'"
122
+ v-for="p in PROVISION_TYPES"
123
+ :key="p.value"
124
+ :color="provisionType === p.value ? 'primary' : 'neutral'"
125
+ :variant="provisionType === p.value ? 'soft' : 'ghost'"
135
126
  size="xs"
136
- :title="e.hint"
137
- @click="setDefaultTestEnv(e.value)"
127
+ @click="setProvisionType(p.value)"
138
128
  >
139
- {{ e.label }}
129
+ {{ p.label }}
140
130
  </UButton>
141
131
  </div>
142
132
  <p class="text-[11px] leading-snug text-slate-500">
143
- {{ t('inspector.testConfig.defaultEnvHint') }}
133
+ {{ t('inspector.testConfig.provisionTypeHint') }}
144
134
  </p>
145
135
  </div>
146
136
 
147
- <div class="space-y-1">
137
+ <div v-if="provisionType === 'docker-compose'" class="space-y-1">
148
138
  <label class="text-[11px] text-slate-400">{{ t('inspector.testConfig.composePath') }}</label>
149
139
  <div class="flex items-center gap-1">
150
140
  <UInput
@@ -152,7 +142,6 @@ const missingInfra = computed(() => !noInfra.value && composePath.value.trim() =
152
142
  size="xs"
153
143
  class="flex-1"
154
144
  placeholder="docker-compose.yml"
155
- :disabled="noInfra"
156
145
  @blur="(e: FocusEvent) => setComposePath((e.target as HTMLInputElement).value)"
157
146
  @keydown.enter="
158
147
  (e: KeyboardEvent) => setComposePath((e.target as HTMLInputElement).value)
@@ -164,7 +153,6 @@ const missingInfra = computed(() => !noInfra.value && composePath.value.trim() =
164
153
  variant="soft"
165
154
  color="neutral"
166
155
  icon="i-lucide-folder-search"
167
- :disabled="noInfra"
168
156
  :title="t('inspector.testConfig.browseRepo')"
169
157
  @click="openBrowse"
170
158
  />
@@ -205,18 +193,6 @@ const missingInfra = computed(() => !noInfra.value && composePath.value.trim() =
205
193
  </template>
206
194
  </UModal>
207
195
 
208
- <label class="flex items-center gap-2 text-[11px] text-slate-400">
209
- <UCheckbox
210
- :model-value="noInfra"
211
- @update:model-value="(v: boolean | 'indeterminate') => toggleNoInfra(v === true)"
212
- />
213
- {{ t('inspector.testConfig.noInfra') }}
214
- </label>
215
-
216
- <p v-if="missingInfra" class="text-[11px] leading-snug text-amber-500">
217
- {{ t('inspector.testConfig.missingInfra') }}
218
- </p>
219
-
220
196
  <!-- Provisioning hints: advisory inputs to the ephemeral-environment provisioner.
221
197
  Collapsed by default — most services never tune them. -->
222
198
  <div class="border-t border-slate-800 pt-2">
@@ -5,7 +5,7 @@ import { useAgentConfigStore } from '~/stores/agentConfig'
5
5
  import { useExecutionStore } from '~/stores/execution'
6
6
 
7
7
  // Task-level configuration contributed by the agents in this task's selected
8
- // pipeline (e.g. the Tester's environment: local vs ephemeral). Each value is
8
+ // pipeline (e.g. the Playwright agent's e2e target: CI vs ephemeral). Each value is
9
9
  // editable until its contributing agent's step starts, then it freezes (the run is
10
10
  // already consuming it). Persisted as a sparse id→value map on the block.
11
11
  const props = defineProps<{ block: Block }>()
@@ -30,33 +30,6 @@ const descriptors = computed(() => {
30
30
 
31
31
  const run = computed(() => execution.getByBlock(props.block.id))
32
32
 
33
- // The Tester's environment descriptor inherits its default from the service frame this
34
- // task lives under (set in the service inspector); a task only overrides it by clicking.
35
- // Walk up the parent chain (frame → module → task) to find that default.
36
- const serviceDefaultTestEnv = computed<'local' | 'ephemeral' | undefined>(() => {
37
- let cur: Block | undefined = props.block
38
- for (let i = 0; i < 8 && cur; i++) {
39
- if (cur.level === 'frame') return cur.defaultTestEnvironment
40
- if (!cur.parentId) break
41
- cur = board.getBlock(cur.parentId)
42
- }
43
- return undefined
44
- })
45
-
46
- /** The effective default for a descriptor — the inherited service value for the Tester's
47
- * environment, otherwise the descriptor's own static default. */
48
- function effectiveDefault(d: { id: string; default: string }): string {
49
- if (d.id === 'tester.environment' && serviceDefaultTestEnv.value) {
50
- return serviceDefaultTestEnv.value
51
- }
52
- return d.default
53
- }
54
-
55
- /** Whether a descriptor's shown value is inherited (not explicitly pinned on this task). */
56
- function isInherited(d: { id: string }): boolean {
57
- return d.id === 'tester.environment' && props.block.agentConfig?.[d.id] === undefined
58
- }
59
-
60
33
  /** A descriptor freezes once its contributing agent's step has left `pending`. */
61
34
  function isFrozen(agentKind: string): boolean {
62
35
  const steps = run.value?.steps
@@ -84,9 +57,6 @@ function setValue(id: string, value: string) {
84
57
  <div class="flex items-center justify-between">
85
58
  <span class="text-[11px] text-slate-400">{{ d.label }}</span>
86
59
  <div class="flex items-center gap-1.5">
87
- <span v-if="isInherited(d)" class="text-[10px] text-slate-500">{{
88
- t('inspector.agentConfig.inherited')
89
- }}</span>
90
60
  <UIcon
91
61
  v-if="isFrozen(d.agentKind)"
92
62
  name="i-lucide-lock"
@@ -99,8 +69,8 @@ function setValue(id: string, value: string) {
99
69
  <UButton
100
70
  v-for="opt in d.options"
101
71
  :key="opt.value"
102
- :color="valueOf(d.id, effectiveDefault(d)) === opt.value ? 'primary' : 'neutral'"
103
- :variant="valueOf(d.id, effectiveDefault(d)) === opt.value ? 'soft' : 'ghost'"
72
+ :color="valueOf(d.id, d.default) === opt.value ? 'primary' : 'neutral'"
73
+ :variant="valueOf(d.id, d.default) === opt.value ? 'soft' : 'ghost'"
104
74
  size="xs"
105
75
  :disabled="isFrozen(d.agentKind)"
106
76
  @click="setValue(d.id, opt.value)"
@@ -117,12 +117,18 @@ const poolConfigurable = computed(
117
117
  providerConnections.isAvailable(connectionKind.value),
118
118
  )
119
119
 
120
- // The delegation flag is a genuine per-workspace toggle ONLY in local mode.
121
- const writable = computed(() => isLocal.value && (cap.value?.available.length ?? 0) > 1)
120
+ // The delegation flag is a genuine per-workspace toggle ONLY in local mode, and ONLY on the
121
+ // execution axis: the Tester's environment is now driven by the SERVICE's declared provision
122
+ // type + per-type workspace handlers (no per-workspace test-env delegation toggle), so the
123
+ // testEnv axis is registration-driven (read-only "Active: …" + the connect forms) until the
124
+ // per-type infra configurator lands. See docs/initiatives/per-service-provision-types.md.
125
+ const writable = computed(
126
+ () => isLocal.value && props.axis === 'execution' && (cap.value?.available.length ?? 0) > 1,
127
+ )
122
128
  const delegated = computed(() =>
123
129
  props.axis === 'execution'
124
130
  ? settings.settings.delegateAgentsToRunnerPool
125
- : settings.settings.delegateTestEnvToProvider,
131
+ : connectionRegistered.value,
126
132
  )
127
133
 
128
134
  // The effective active backend (matches the prior ExecutionBackendSelector logic): local
@@ -214,11 +220,8 @@ const saving = ref(false)
214
220
  async function setDelegate(value: boolean) {
215
221
  saving.value = true
216
222
  try {
217
- await settings.update(
218
- props.axis === 'execution'
219
- ? { delegateAgentsToRunnerPool: value }
220
- : { delegateTestEnvToProvider: value },
221
- )
223
+ // Only reachable on the execution axis (`writable` is false for testEnv now).
224
+ await settings.update({ delegateAgentsToRunnerPool: value })
222
225
  } catch (e) {
223
226
  toast.add({
224
227
  title: t('settings.infrastructure.updateFailed'),
@@ -65,6 +65,21 @@ const tabs = computed(() => [
65
65
  },
66
66
  ])
67
67
 
68
+ // Tab strip styling: the labels must always fit (never truncate) and the strip must never
69
+ // scroll. So we let the list WRAP onto a second row when the viewport is too narrow
70
+ // (`flex-wrap`), keep each trigger at its content width (`shrink-0`, undoing the theme's
71
+ // `min-w-0`+`truncate` that otherwise ellipsises labels), and drop the sliding `indicator`
72
+ // for a per-trigger bottom border. reka's indicator only tracks `offsetLeft` (not
73
+ // `offsetTop`), so it mis-renders once tabs wrap; a border on each active trigger underlines
74
+ // the right row regardless. A transparent border on every trigger keeps the rows from
75
+ // shifting when the active one gains its colour.
76
+ const tabsUi = {
77
+ root: 'gap-4',
78
+ list: 'flex-wrap gap-y-1',
79
+ trigger: 'shrink-0 border-b-2 border-transparent data-[state=active]:border-primary',
80
+ indicator: 'hidden',
81
+ }
82
+
68
83
  const TASK_TYPES: CreateTaskType[] = ['feature', 'bug', 'document', 'spike']
69
84
 
70
85
  // Per-task-type label for the "Max {type} tasks" inputs. An exhaustive Record keyed off
@@ -203,12 +218,7 @@ async function saveBudget() {
203
218
  <IntegrationBackTitle :title="t('settings.workspaceSettings.title')" @back="back" />
204
219
  </template>
205
220
  <template #body>
206
- <UTabs
207
- v-model="activeTab"
208
- :items="tabs"
209
- variant="link"
210
- :ui="{ root: 'gap-4', list: 'overflow-x-auto' }"
211
- >
221
+ <UTabs v-model="activeTab" :items="tabs" variant="link" :ui="tabsUi">
212
222
  <!-- Workspace -->
213
223
  <template #workspace>
214
224
  <div class="space-y-6">
@@ -13,7 +13,6 @@ const DEFAULTS: WorkspaceSettings = {
13
13
  artifactRetentionDays: 14,
14
14
  kaizenEnabled: true,
15
15
  delegateAgentsToRunnerPool: false,
16
- delegateTestEnvToProvider: false,
17
16
  spendCurrency: null,
18
17
  spendMonthlyLimit: null,
19
18
  }
@@ -27,6 +27,7 @@ export type {
27
27
  PullRequestRef,
28
28
  CloudProvider,
29
29
  InstanceSize,
30
+ ProvisionType,
30
31
  AgentConfigOption,
31
32
  AgentConfigDescriptor,
32
33
  TestConcernSeverity,
@@ -424,13 +424,13 @@
424
424
  },
425
425
  "testConfig": {
426
426
  "title": "Test infrastructure",
427
- "defaultEnv": "Default test environment",
428
- "defaultEnvHint": "The default tasks under this service are spawned with. Each task can override it in its agent settings.",
429
- "env": {
430
- "ephemeral": "Ephemeral environment",
431
- "ephemeralHint": "tests run against a provisioned env",
432
- "local": "Local (docker-compose)",
433
- "localHint": "the Tester stands deps up locally"
427
+ "provisionType": "Provision type",
428
+ "provisionTypeHint": "How this service stands up its environment for the Tester. The workspace configures how each type is handled (the engine + connection).",
429
+ "provisionTypes": {
430
+ "infraless": "No infrastructure",
431
+ "docker-compose": "Docker Compose",
432
+ "kubernetes": "Kubernetes",
433
+ "custom": "Custom"
434
434
  },
435
435
  "composePath": "docker-compose path",
436
436
  "browseRepo": "Browse the repository for the compose file",
@@ -440,8 +440,6 @@
440
440
  "selected": "Selected: {path}",
441
441
  "noFileSelected": "No file selected.",
442
442
  "useThisFile": "Use this file",
443
- "noInfra": "No infra dependencies (the Tester spins nothing up)",
444
- "missingInfra": "Set a docker-compose path or enable no infra dependencies, otherwise a pipeline with a Tester won't start.",
445
443
  "provisioningTitle": "Ephemeral environment provisioning",
446
444
  "provisioningHint": "A hint for provisioning this service's ephemeral test environment: which cloud provider to deploy to and how large an instance to request. Ignored for local (docker-compose) testing.",
447
445
  "cloudProvider": "Cloud provider",
@@ -387,13 +387,13 @@
387
387
  },
388
388
  "testConfig": {
389
389
  "title": "Infraestructura de pruebas",
390
- "defaultEnv": "Entorno de pruebas predeterminado",
391
- "defaultEnvHint": "El entorno predeterminado con el que se generan las tareas de este servicio. Cada tarea puede anularlo en su configuración de agente.",
392
- "env": {
393
- "ephemeral": "Entorno efímero",
394
- "ephemeralHint": "las pruebas se ejecutan contra un entorno aprovisionado",
395
- "local": "Local (docker-compose)",
396
- "localHint": "el Tester levanta las dependencias localmente"
390
+ "provisionType": "Tipo de aprovisionamiento",
391
+ "provisionTypeHint": "Cómo este servicio levanta su entorno para el Tester. El espacio de trabajo configura cómo se gestiona cada tipo (el motor + la conexión).",
392
+ "provisionTypes": {
393
+ "infraless": "Sin infraestructura",
394
+ "docker-compose": "Docker Compose",
395
+ "kubernetes": "Kubernetes",
396
+ "custom": "Personalizado"
397
397
  },
398
398
  "composePath": "Ruta de docker-compose",
399
399
  "browseRepo": "Explorar el repositorio en busca del archivo de compose",
@@ -403,8 +403,6 @@
403
403
  "selected": "Seleccionado: {path}",
404
404
  "noFileSelected": "Ningún archivo seleccionado.",
405
405
  "useThisFile": "Usar este archivo",
406
- "noInfra": "Sin dependencias de infraestructura (el Tester no levanta nada)",
407
- "missingInfra": "Define una ruta de docker-compose o habilita sin dependencias de infraestructura; de lo contrario, un pipeline con un Tester no se iniciará.",
408
406
  "provisioningTitle": "Aprovisionamiento del entorno efímero",
409
407
  "provisioningHint": "Una indicación para aprovisionar el entorno de pruebas efímero de este servicio: en qué proveedor de nube desplegar y qué tamaño de instancia solicitar. Se ignora en las pruebas locales (docker-compose).",
410
408
  "cloudProvider": "Proveedor de nube",
@@ -387,13 +387,13 @@
387
387
  },
388
388
  "testConfig": {
389
389
  "title": "Infrastructure de test",
390
- "defaultEnv": "Environnement de test par défaut",
391
- "defaultEnvHint": "Celui avec lequel les tâches par défaut de ce service sont créées. Chaque tâche peut le remplacer dans ses paramètres d'agent.",
392
- "env": {
393
- "ephemeral": "Environnement éphémère",
394
- "ephemeralHint": "les tests s'exécutent sur un environnement provisionné",
395
- "local": "Local (docker-compose)",
396
- "localHint": "le Testeur met en place les dépendances localement"
390
+ "provisionType": "Type de provisionnement",
391
+ "provisionTypeHint": "Comment ce service met en place son environnement pour le Tester. L'espace de travail configure la gestion de chaque type (le moteur + la connexion).",
392
+ "provisionTypes": {
393
+ "infraless": "Aucune infrastructure",
394
+ "docker-compose": "Docker Compose",
395
+ "kubernetes": "Kubernetes",
396
+ "custom": "Personnalisé"
397
397
  },
398
398
  "composePath": "Chemin docker-compose",
399
399
  "browseRepo": "Parcourir le dépôt pour trouver le fichier compose",
@@ -403,8 +403,6 @@
403
403
  "selected": "Sélectionné : {path}",
404
404
  "noFileSelected": "Aucun fichier sélectionné.",
405
405
  "useThisFile": "Utiliser ce fichier",
406
- "noInfra": "Aucune dépendance d'infrastructure (le Testeur ne met rien en place)",
407
- "missingInfra": "Définissez un chemin docker-compose ou activez l'absence de dépendances d'infrastructure, sinon un pipeline avec un Testeur ne démarrera pas.",
408
406
  "provisioningTitle": "Provisionnement de l'environnement éphémère",
409
407
  "provisioningHint": "Une indication pour provisionner l'environnement de test éphémère de ce service : quel fournisseur cloud cibler et quelle taille d'instance demander. Ignoré pour les tests locaux (docker-compose).",
410
408
  "cloudProvider": "Fournisseur cloud",
@@ -387,13 +387,13 @@
387
387
  },
388
388
  "testConfig": {
389
389
  "title": "תשתית בדיקות",
390
- "defaultEnv": "סביבת בדיקות ברירת מחדל",
391
- "defaultEnvHint": "ברירת המחדל שאיתה נוצרות המשימות תחת שירות זה. כל משימה יכולה לעקוף אותה בהגדרות הסוכן שלה.",
392
- "env": {
393
- "ephemeral": "סביבה זמנית",
394
- "ephemeralHint": "הבדיקות רצות מול סביבה שהוקצתה",
395
- "local": "מקומי (docker-compose)",
396
- "localHint": "ה-Tester מקים את התלויות מקומית"
390
+ "provisionType": "סוג ההקצאה",
391
+ "provisionTypeHint": "כיצד שירות זה מקים את הסביבה שלו עבור ה-Tester. סביבת העבודה מגדירה כיצד מטופל כל סוג (המנוע + החיבור).",
392
+ "provisionTypes": {
393
+ "infraless": "ללא תשתית",
394
+ "docker-compose": "Docker Compose",
395
+ "kubernetes": "Kubernetes",
396
+ "custom": "מותאם אישית"
397
397
  },
398
398
  "composePath": "נתיב docker-compose",
399
399
  "browseRepo": "עיין במאגר עבור קובץ ה-compose",
@@ -403,8 +403,6 @@
403
403
  "selected": "נבחר: {path}",
404
404
  "noFileSelected": "לא נבחר קובץ.",
405
405
  "useThisFile": "השתמש בקובץ זה",
406
- "noInfra": "אין תלויות תשתית (ה-Tester אינו מקים דבר)",
407
- "missingInfra": "הגדר נתיב docker-compose או הפעל ללא תלויות תשתית, אחרת פייפליין עם Tester לא יתחיל.",
408
406
  "provisioningTitle": "הקצאת סביבת בדיקות זמנית",
409
407
  "provisioningHint": "רמז להקצאת סביבת הבדיקות הזמנית של שירות זה: לאיזה ספק ענן לפרוס וכמה גדול מופע לבקש. מתעלם בבדיקות מקומיות (docker-compose).",
410
408
  "cloudProvider": "ספק ענן",
@@ -387,13 +387,13 @@
387
387
  },
388
388
  "testConfig": {
389
389
  "title": "テストインフラ",
390
- "defaultEnv": "デフォルトのテスト環境",
391
- "defaultEnvHint": "このサービス配下のタスクが生成されるデフォルトの環境です。各タスクはエージェント設定で上書きできます。",
392
- "env": {
393
- "ephemeral": "エフェメラル環境",
394
- "ephemeralHint": "プロビジョニングされた環境に対してテストを実行します",
395
- "local": "ローカル (docker-compose)",
396
- "localHint": "Tester が依存関係をローカルで立ち上げます"
390
+ "provisionType": "プロビジョニングの種類",
391
+ "provisionTypeHint": "このサービスが Tester 用の環境をどのように立ち上げるか。各種類の扱い方(エンジンと接続)はワークスペースで設定します。",
392
+ "provisionTypes": {
393
+ "infraless": "インフラなし",
394
+ "docker-compose": "Docker Compose",
395
+ "kubernetes": "Kubernetes",
396
+ "custom": "カスタム"
397
397
  },
398
398
  "composePath": "docker-compose のパス",
399
399
  "browseRepo": "リポジトリ内の compose ファイルを参照",
@@ -403,8 +403,6 @@
403
403
  "selected": "選択中: {path}",
404
404
  "noFileSelected": "ファイルが選択されていません。",
405
405
  "useThisFile": "このファイルを使用",
406
- "noInfra": "インフラ依存なし (Tester は何も立ち上げません)",
407
- "missingInfra": "docker-compose のパスを設定するか、インフラ依存なしを有効にしてください。そうしないと Tester を含むパイプラインは開始しません。",
408
406
  "provisioningTitle": "エフェメラルテスト環境のプロビジョニング",
409
407
  "provisioningHint": "このサービスのエフェメラルテスト環境をプロビジョニングするためのヒント: どのクラウドプロバイダーにデプロイするか、どの程度の大きさのインスタンスを要求するか。ローカル (docker-compose) テストでは無視されます。",
410
408
  "cloudProvider": "クラウドプロバイダー",
@@ -387,13 +387,13 @@
387
387
  },
388
388
  "testConfig": {
389
389
  "title": "Infrastruktura testowa",
390
- "defaultEnv": "Domyślne środowisko testowe",
391
- "defaultEnvHint": "Środowisko, z którym uruchamiane domyślnie zadania w tej usłudze. Każde zadanie może je nadpisać w swoich ustawieniach agenta.",
392
- "env": {
393
- "ephemeral": "Środowisko efemeryczne",
394
- "ephemeralHint": "testy uruchamiane wobec udostępnionego środowiska",
395
- "local": "Lokalne (docker-compose)",
396
- "localHint": "Tester stawia zależności lokalnie"
390
+ "provisionType": "Typ provisioningu",
391
+ "provisionTypeHint": "Jak ta usługa uruchamia swoje środowisko dla Testera. Obszar roboczy konfiguruje sposób obsługi każdego typu (silnik + połączenie).",
392
+ "provisionTypes": {
393
+ "infraless": "Bez infrastruktury",
394
+ "docker-compose": "Docker Compose",
395
+ "kubernetes": "Kubernetes",
396
+ "custom": "Niestandardowy"
397
397
  },
398
398
  "composePath": "Ścieżka docker-compose",
399
399
  "browseRepo": "Przeglądaj repozytorium w poszukiwaniu pliku compose",
@@ -403,8 +403,6 @@
403
403
  "selected": "Wybrano: {path}",
404
404
  "noFileSelected": "Nie wybrano pliku.",
405
405
  "useThisFile": "Użyj tego pliku",
406
- "noInfra": "Brak zależności infrastrukturalnych (Tester niczego nie stawia)",
407
- "missingInfra": "Ustaw ścieżkę docker-compose lub włącz brak zależności infrastrukturalnych, w przeciwnym razie potok z Testerem się nie uruchomi.",
408
406
  "provisioningTitle": "Udostępnianie środowiska efemerycznego",
409
407
  "provisioningHint": "Wskazówka dotycząca udostępniania efemerycznego środowiska testowego tej usługi: do którego dostawcy chmury wdrożyć i jak duży zażądać instancji. Ignorowane przy testach lokalnych (docker-compose).",
410
408
  "cloudProvider": "Dostawca chmury",
@@ -387,13 +387,13 @@
387
387
  },
388
388
  "testConfig": {
389
389
  "title": "Test altyapısı",
390
- "defaultEnv": "Varsayılan test ortamı",
391
- "defaultEnvHint": "Bu servisin altındaki görevlerin oluşturulduğu varsayılan ortam. Her görev kendi ajan ayarlarında bunu geçersiz kılabilir.",
392
- "env": {
393
- "ephemeral": "Geçici ortam",
394
- "ephemeralHint": "testler sağlanan bir ortama karşı çalışır",
395
- "local": "Yerel (docker-compose)",
396
- "localHint": "Tester bağımlılıkları yerel olarak ayağa kaldırır"
390
+ "provisionType": "Sağlama türü",
391
+ "provisionTypeHint": "Bu hizmetin Tester için ortamını nasıl ayağa kaldırdığı. Her türün nasıl ele alınacağını (motor + bağlantı) çalışma alanı yapılandırır.",
392
+ "provisionTypes": {
393
+ "infraless": "Altyapısız",
394
+ "docker-compose": "Docker Compose",
395
+ "kubernetes": "Kubernetes",
396
+ "custom": "Özel"
397
397
  },
398
398
  "composePath": "docker-compose yolu",
399
399
  "browseRepo": "compose dosyası için depoya göz at",
@@ -403,8 +403,6 @@
403
403
  "selected": "Seçildi: {path}",
404
404
  "noFileSelected": "Dosya seçilmedi.",
405
405
  "useThisFile": "Bu dosyayı kullan",
406
- "noInfra": "Altyapı bağımlılığı yok (Tester hiçbir şey ayağa kaldırmaz)",
407
- "missingInfra": "Bir docker-compose yolu ayarlayın veya altyapı bağımlılığı yok seçeneğini etkinleştirin, aksi halde Tester içeren bir pipeline başlamaz.",
408
406
  "provisioningTitle": "Geçici ortam sağlama",
409
407
  "provisioningHint": "Bu servisin geçici test ortamını sağlamak için bir ipucu: hangi bulut sağlayıcısına dağıtılacağı ve ne kadar büyük bir örnek isteneceği. Yerel (docker-compose) testleri için yok sayılır.",
410
408
  "cloudProvider": "Bulut sağlayıcı",
@@ -387,13 +387,13 @@
387
387
  },
388
388
  "testConfig": {
389
389
  "title": "Тестова інфраструктура",
390
- "defaultEnv": "Типове тестове середовище",
391
- "defaultEnvHint": "Середовище, з яким за замовчуванням створюються завдання цього сервісу. Кожне завдання може перевизначити його в налаштуваннях агента.",
392
- "env": {
393
- "ephemeral": "Тимчасове середовище",
394
- "ephemeralHint": "тести виконуються в наданому середовищі",
395
- "local": "Локально (docker-compose)",
396
- "localHint": "Тестувальник піднімає залежності локально"
390
+ "provisionType": "Тип провіженінгу",
391
+ "provisionTypeHint": "Як ця служба піднімає своє середовище для Tester. Робочий простір налаштовує, як обробляється кожен тип (рушій + підключення).",
392
+ "provisionTypes": {
393
+ "infraless": "Без інфраструктури",
394
+ "docker-compose": "Docker Compose",
395
+ "kubernetes": "Kubernetes",
396
+ "custom": "Власний"
397
397
  },
398
398
  "composePath": "Шлях docker-compose",
399
399
  "browseRepo": "Переглянути репозиторій у пошуках файлу compose",
@@ -403,8 +403,6 @@
403
403
  "selected": "Вибрано: {path}",
404
404
  "noFileSelected": "Файл не вибрано.",
405
405
  "useThisFile": "Використати цей файл",
406
- "noInfra": "Без інфраструктурних залежностей (Тестувальник нічого не піднімає)",
407
- "missingInfra": "Вкажіть шлях docker-compose або увімкніть відсутність інфраструктурних залежностей, інакше конвеєр з Тестувальником не запуститься.",
408
406
  "provisioningTitle": "Надання тимчасового середовища",
409
407
  "provisioningHint": "Підказка для надання тимчасового тестового середовища цього сервісу: до якого хмарного провайдера розгортати та яку величину інстансу запитувати. Ігнорується для локального (docker-compose) тестування.",
410
408
  "cloudProvider": "Хмарний провайдер",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/app",
3
- "version": "0.58.3",
3
+ "version": "0.58.5",
4
4
  "description": "Reusable Nuxt layer for the Agent Architecture Board SPA (components, stores, composables, pages). Consume it from a thin deployment app via `extends: ['@cat-factory/app']` and point it at your backend with NUXT_PUBLIC_API_BASE. See deploy/frontend for an example.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,7 +34,7 @@
34
34
  "valibot": "^1.4.2",
35
35
  "vue": "^3.5.39",
36
36
  "wretch": "^3.0.9",
37
- "@cat-factory/contracts": "0.61.0"
37
+ "@cat-factory/contracts": "0.62.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@toad-contracts/testing": "0.3.2",