@cat-factory/app 0.51.0 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/components/layout/SideBar.vue +7 -3
- package/app/components/layout/TranslationWarningBanner.vue +13 -9
- package/app/components/settings/InfrastructureWindow.vue +10 -5
- package/app/components/testing/TestReportWindow.vue +79 -2
- package/i18n/locales/en.json +7 -0
- package/i18n/locales/es.json +8 -1
- package/i18n/locales/fr.json +8 -1
- package/i18n/locales/pl.json +8 -1
- package/i18n/locales/uk.json +8 -1
- package/package.json +2 -2
|
@@ -24,11 +24,15 @@ const auth = useAuthStore()
|
|
|
24
24
|
const providerConnections = useProviderConnectionsStore()
|
|
25
25
|
const ui = useUiStore()
|
|
26
26
|
|
|
27
|
-
// The Infrastructure menu (agent-container execution + test environments)
|
|
28
|
-
//
|
|
29
|
-
//
|
|
27
|
+
// The Infrastructure menu (agent-container execution + test environments) shows whenever the
|
|
28
|
+
// deployment reports its infrastructure capability — every facade populates `auth.infrastructure`
|
|
29
|
+
// (it drives the execution-backend selector), so there is always an execution + test-env backend
|
|
30
|
+
// to view, even on a Worker/Node deployment with no runner-pool/environment connection registered.
|
|
31
|
+
// The old provider-availability/local-mode signals stay as a defensive fallback for a backend that
|
|
32
|
+
// (somehow) omits the descriptor.
|
|
30
33
|
const showInfrastructure = computed(
|
|
31
34
|
() =>
|
|
35
|
+
auth.infrastructure != null ||
|
|
32
36
|
auth.localMode?.enabled === true ||
|
|
33
37
|
providerConnections.isAvailable('runner-pool') ||
|
|
34
38
|
providerConnections.isAvailable('environment'),
|
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { useLocalStorage } from '@vueuse/core'
|
|
3
|
+
import { computed } from 'vue'
|
|
3
4
|
|
|
4
5
|
// Shown whenever the active locale is NOT English: the non-English catalogs are
|
|
5
6
|
// community/AI-provided and may be inaccurate, so warn the user and point them at the
|
|
6
7
|
// repository to report mistakes or open a fix PR. Rendered as a slim full-width strip at
|
|
7
8
|
// the very top (distinct from the centered config-warning cards below it, so they don't
|
|
8
|
-
// overlap).
|
|
9
|
+
// overlap). Dismissal is persisted per-locale in localStorage: once dismissed for a locale
|
|
10
|
+
// it stays hidden across reloads, but switching to a different (separately-translated)
|
|
11
|
+
// locale shows it again, since that catalog is a fresh, independently-translated context.
|
|
9
12
|
const REPO_URL = 'https://github.com/kibertoad/cat-factory'
|
|
10
13
|
|
|
11
14
|
const { t, locale } = useI18n()
|
|
12
15
|
|
|
13
|
-
const
|
|
14
|
-
const show = computed(() => locale.value !== 'en' && !
|
|
16
|
+
const dismissedLocales = useLocalStorage<string[]>('cat-factory:translation-warning-dismissed', [])
|
|
17
|
+
const show = computed(() => locale.value !== 'en' && !dismissedLocales.value.includes(locale.value))
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
19
|
+
function dismiss() {
|
|
20
|
+
if (!dismissedLocales.value.includes(locale.value)) {
|
|
21
|
+
dismissedLocales.value = [...dismissedLocales.value, locale.value]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
20
24
|
</script>
|
|
21
25
|
|
|
22
26
|
<template>
|
|
@@ -51,7 +55,7 @@ watch(locale, () => {
|
|
|
51
55
|
size="xs"
|
|
52
56
|
icon="i-lucide-x"
|
|
53
57
|
:aria-label="t('language.warning.dismiss')"
|
|
54
|
-
@click="
|
|
58
|
+
@click="dismiss"
|
|
55
59
|
/>
|
|
56
60
|
</div>
|
|
57
61
|
</Transition>
|
|
@@ -29,9 +29,12 @@ const open = computed({
|
|
|
29
29
|
|
|
30
30
|
const isLocal = computed(() => auth.localMode?.enabled === true)
|
|
31
31
|
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
// The tabs are driven by the deployment's infrastructure capability (every facade reports
|
|
33
|
+
// execution + test-env backends), NOT the optional provider-connection probes — the execution-
|
|
34
|
+
// backend selector must show even when no runner-pool / environment connection is registered.
|
|
35
|
+
// The connect form inside each tab still gates on its own probe (see the template).
|
|
36
|
+
const agentsAvailable = computed(() => (auth.infrastructure?.execution.available.length ?? 0) > 0)
|
|
37
|
+
const envsAvailable = computed(() => (auth.infrastructure?.testEnv.available.length ?? 0) > 0)
|
|
35
38
|
|
|
36
39
|
const tabs = computed(() => {
|
|
37
40
|
const out: { value: ProviderConnectionKind; label: string; icon: string; slot: string }[] = []
|
|
@@ -102,7 +105,8 @@ watch([tabs, () => store.loaded], () => {
|
|
|
102
105
|
<div class="space-y-4">
|
|
103
106
|
<!-- Where agent containers run (writable in local mode; read-only elsewhere). -->
|
|
104
107
|
<ExecutionBackendSelector axis="execution" />
|
|
105
|
-
|
|
108
|
+
<!-- The runner-pool connect form only when that integration is enabled. -->
|
|
109
|
+
<ProviderConnectionTab v-if="store.isAvailable('runner-pool')" kind="runner-pool" />
|
|
106
110
|
<!-- Local mode: the warm-pool + checkout reuse ARE the host agent-container
|
|
107
111
|
runtime, so they live here rather than in a separate menu. -->
|
|
108
112
|
<section v-if="isLocal" class="border-t border-slate-800 pt-4">
|
|
@@ -117,7 +121,8 @@ watch([tabs, () => store.loaded], () => {
|
|
|
117
121
|
<div class="space-y-4">
|
|
118
122
|
<!-- Where Tester environments run (writable in local mode; read-only elsewhere). -->
|
|
119
123
|
<ExecutionBackendSelector axis="testEnv" />
|
|
120
|
-
|
|
124
|
+
<!-- The environment-provider connect form only when that integration is enabled. -->
|
|
125
|
+
<ProviderConnectionTab v-if="store.isAvailable('environment')" kind="environment" />
|
|
121
126
|
</div>
|
|
122
127
|
</template>
|
|
123
128
|
</UTabs>
|
|
@@ -23,7 +23,7 @@ import ProvisioningLogsDrawer from '~/components/provisioning/ProvisioningLogsDr
|
|
|
23
23
|
|
|
24
24
|
const board = useBoardStore()
|
|
25
25
|
const execution = useExecutionStore()
|
|
26
|
-
const { t, d } = useI18n()
|
|
26
|
+
const { t, d, n } = useI18n()
|
|
27
27
|
|
|
28
28
|
// Per-window blob cache for the captured screenshots; revoked on unmount.
|
|
29
29
|
const blobs = useArtifactBlobs()
|
|
@@ -58,6 +58,14 @@ const executionId = computed(() => instance.value?.id ?? null)
|
|
|
58
58
|
// The infra-attempts log drawer is opened on demand (it fetches the per-run log rows).
|
|
59
59
|
const showProvisioning = ref(false)
|
|
60
60
|
|
|
61
|
+
// The in-container docker-compose dependency stand-up record (local-infra tester): whether
|
|
62
|
+
// the dependencies came up + the captured `docker compose up` logs. Unlike the provisioning
|
|
63
|
+
// drawer above (the orchestrator-side container/env spin-up), this is the stand-up that runs
|
|
64
|
+
// INSIDE the container — the highest-signal artifact when local infra fails to come up.
|
|
65
|
+
const infraSetup = computed(() => testState.value?.infraSetup ?? null)
|
|
66
|
+
// The captured stand-up logs are shown on demand (they can be long).
|
|
67
|
+
const showInfraSetupLogs = ref(false)
|
|
68
|
+
|
|
61
69
|
const screenshots = computed<TestScreenshot[]>(() => report.value?.screenshots ?? [])
|
|
62
70
|
// Resolve each capture into an object URL for the gallery + lightbox. The shared cache
|
|
63
71
|
// dedupes, so the lightbox reuses what the thumbnails fetched. (The reference design is not
|
|
@@ -338,7 +346,7 @@ const GROUP_STATUS_META: Record<ScenarioGroup['status'], { icon: string; text: s
|
|
|
338
346
|
environment. A no-infra tester (no container, no env) has no infra attempts
|
|
339
347
|
either, so we don't render an empty header + a log toggle over nothing. -->
|
|
340
348
|
<section
|
|
341
|
-
v-if="step && (step.container || stepEnvironment)"
|
|
349
|
+
v-if="step && (step.container || stepEnvironment || infraSetup)"
|
|
342
350
|
data-testid="tester-infrastructure"
|
|
343
351
|
class="space-y-3"
|
|
344
352
|
>
|
|
@@ -347,6 +355,75 @@ const GROUP_STATUS_META: Record<ScenarioGroup['status'], { icon: string; text: s
|
|
|
347
355
|
</h3>
|
|
348
356
|
<StepContainerStatus :step="step" :run-failed="runFailed" />
|
|
349
357
|
<EnvironmentStatusPanel v-if="stepEnvironment" :environment="stepEnvironment" />
|
|
358
|
+
|
|
359
|
+
<!-- In-container docker-compose dependency stand-up (local-infra tester): the
|
|
360
|
+
outcome + the captured `docker compose up` logs. This is the stand-up that
|
|
361
|
+
runs INSIDE the container, so its output isn't in the provisioning drawer
|
|
362
|
+
below — it's the highest-signal artifact when local infra fails to start. -->
|
|
363
|
+
<div
|
|
364
|
+
v-if="infraSetup"
|
|
365
|
+
data-testid="tester-infra-setup"
|
|
366
|
+
class="rounded-lg border px-3 py-2"
|
|
367
|
+
:class="
|
|
368
|
+
infraSetup.started
|
|
369
|
+
? 'border-slate-800 bg-slate-900/60'
|
|
370
|
+
: 'border-rose-500/40 bg-rose-500/10'
|
|
371
|
+
"
|
|
372
|
+
>
|
|
373
|
+
<div class="flex items-center gap-2">
|
|
374
|
+
<UIcon
|
|
375
|
+
:name="infraSetup.started ? 'i-lucide-container' : 'i-lucide-circle-x'"
|
|
376
|
+
class="h-3.5 w-3.5 shrink-0"
|
|
377
|
+
:class="infraSetup.started ? 'text-emerald-400' : 'text-rose-400'"
|
|
378
|
+
/>
|
|
379
|
+
<span class="text-[13px] font-medium text-slate-200">
|
|
380
|
+
{{ infraSetup.started ? t('testing.standup.up') : t('testing.standup.failed') }}
|
|
381
|
+
</span>
|
|
382
|
+
<span
|
|
383
|
+
v-if="infraSetup.durationMs != null"
|
|
384
|
+
class="ml-auto text-[11px] text-slate-500"
|
|
385
|
+
>
|
|
386
|
+
{{
|
|
387
|
+
t('testing.standup.took', {
|
|
388
|
+
seconds: n(infraSetup.durationMs / 1000, 'decimal'),
|
|
389
|
+
})
|
|
390
|
+
}}
|
|
391
|
+
</span>
|
|
392
|
+
</div>
|
|
393
|
+
<p v-if="infraSetup.composePath" class="mt-1 font-mono text-[11px] text-slate-500">
|
|
394
|
+
{{ infraSetup.composePath }}
|
|
395
|
+
</p>
|
|
396
|
+
<p
|
|
397
|
+
v-if="infraSetup.error"
|
|
398
|
+
class="mt-1 text-[12px] leading-snug text-rose-300"
|
|
399
|
+
data-testid="tester-infra-setup-error"
|
|
400
|
+
>
|
|
401
|
+
{{ infraSetup.error }}
|
|
402
|
+
</p>
|
|
403
|
+
<template v-if="infraSetup.logs">
|
|
404
|
+
<UButton
|
|
405
|
+
:icon="showInfraSetupLogs ? 'i-lucide-chevron-up' : 'i-lucide-scroll-text'"
|
|
406
|
+
variant="ghost"
|
|
407
|
+
size="xs"
|
|
408
|
+
class="mt-1.5"
|
|
409
|
+
data-testid="tester-infra-setup-logs-toggle"
|
|
410
|
+
@click="showInfraSetupLogs = !showInfraSetupLogs"
|
|
411
|
+
>
|
|
412
|
+
{{
|
|
413
|
+
showInfraSetupLogs
|
|
414
|
+
? t('testing.standup.hideLogs')
|
|
415
|
+
: t('testing.standup.showLogs')
|
|
416
|
+
}}
|
|
417
|
+
</UButton>
|
|
418
|
+
<pre
|
|
419
|
+
v-if="showInfraSetupLogs"
|
|
420
|
+
data-testid="tester-infra-setup-logs"
|
|
421
|
+
class="mt-2 max-h-64 overflow-auto rounded bg-slate-950/70 p-2 font-mono text-[11px] leading-relaxed text-slate-300"
|
|
422
|
+
>{{ infraSetup.logs }}</pre
|
|
423
|
+
>
|
|
424
|
+
</template>
|
|
425
|
+
</div>
|
|
426
|
+
|
|
350
427
|
<div v-if="executionId">
|
|
351
428
|
<UButton
|
|
352
429
|
:icon="showProvisioning ? 'i-lucide-chevron-up' : 'i-lucide-scroll-text'"
|
package/i18n/locales/en.json
CHANGED
|
@@ -2999,6 +2999,13 @@
|
|
|
2999
2999
|
},
|
|
3000
3000
|
"environment": "Environment",
|
|
3001
3001
|
"infrastructure": "Infrastructure",
|
|
3002
|
+
"standup": {
|
|
3003
|
+
"up": "Dependencies started",
|
|
3004
|
+
"failed": "Dependencies failed to start",
|
|
3005
|
+
"took": "Took {seconds}s",
|
|
3006
|
+
"showLogs": "Show stand-up logs",
|
|
3007
|
+
"hideLogs": "Hide stand-up logs"
|
|
3008
|
+
},
|
|
3002
3009
|
"footer": "Scenarios are the areas the Tester chose to exercise (its spec acceptance scenarios). Outcomes and concerns are grouped under them by name.",
|
|
3003
3010
|
"@screenshotAlt": {
|
|
3004
3011
|
"description": "Alt text for a captured screenshot thumbnail; {view} is the screen/view name. The literal word 'screenshot' should be localized."
|
package/i18n/locales/es.json
CHANGED
|
@@ -2912,7 +2912,14 @@
|
|
|
2912
2912
|
},
|
|
2913
2913
|
"environment": "Entorno",
|
|
2914
2914
|
"footer": "Los escenarios son las áreas que el Tester decidió ejercitar (sus escenarios de aceptación de la especificación). Los resultados y las incidencias se agrupan bajo ellos por nombre.",
|
|
2915
|
-
"infrastructure": "Infraestructura"
|
|
2915
|
+
"infrastructure": "Infraestructura",
|
|
2916
|
+
"standup": {
|
|
2917
|
+
"up": "Dependencias iniciadas",
|
|
2918
|
+
"failed": "No se pudieron iniciar las dependencias",
|
|
2919
|
+
"took": "Tardó {seconds}s",
|
|
2920
|
+
"showLogs": "Mostrar registros de arranque",
|
|
2921
|
+
"hideLogs": "Ocultar registros de arranque"
|
|
2922
|
+
}
|
|
2916
2923
|
},
|
|
2917
2924
|
"visualConfirm": {
|
|
2918
2925
|
"ariaLabel": "Confirmación visual",
|
package/i18n/locales/fr.json
CHANGED
|
@@ -2912,7 +2912,14 @@
|
|
|
2912
2912
|
},
|
|
2913
2913
|
"environment": "Environnement",
|
|
2914
2914
|
"footer": "Les scénarios sont les domaines que le Testeur a choisi d'éprouver (ses scénarios d'acceptation de la spécification). Les résultats et les réserves y sont regroupés par nom.",
|
|
2915
|
-
"infrastructure": "Infrastructure"
|
|
2915
|
+
"infrastructure": "Infrastructure",
|
|
2916
|
+
"standup": {
|
|
2917
|
+
"up": "Dépendances démarrées",
|
|
2918
|
+
"failed": "Échec du démarrage des dépendances",
|
|
2919
|
+
"took": "Durée : {seconds}s",
|
|
2920
|
+
"showLogs": "Afficher les journaux de démarrage",
|
|
2921
|
+
"hideLogs": "Masquer les journaux de démarrage"
|
|
2922
|
+
}
|
|
2916
2923
|
},
|
|
2917
2924
|
"visualConfirm": {
|
|
2918
2925
|
"ariaLabel": "Confirmation visuelle",
|
package/i18n/locales/pl.json
CHANGED
|
@@ -2912,7 +2912,14 @@
|
|
|
2912
2912
|
},
|
|
2913
2913
|
"environment": "Środowisko",
|
|
2914
2914
|
"footer": "Scenariusze to obszary, które Tester postanowił sprawdzić (jego scenariusze akceptacyjne ze specyfikacji). Wyniki i zastrzeżenia są pod nimi grupowane według nazwy.",
|
|
2915
|
-
"infrastructure": "Infrastruktura"
|
|
2915
|
+
"infrastructure": "Infrastruktura",
|
|
2916
|
+
"standup": {
|
|
2917
|
+
"up": "Zależności uruchomione",
|
|
2918
|
+
"failed": "Nie udało się uruchomić zależności",
|
|
2919
|
+
"took": "Czas: {seconds}s",
|
|
2920
|
+
"showLogs": "Pokaż dzienniki uruchamiania",
|
|
2921
|
+
"hideLogs": "Ukryj dzienniki uruchamiania"
|
|
2922
|
+
}
|
|
2916
2923
|
},
|
|
2917
2924
|
"visualConfirm": {
|
|
2918
2925
|
"ariaLabel": "Potwierdzenie wizualne",
|
package/i18n/locales/uk.json
CHANGED
|
@@ -2912,7 +2912,14 @@
|
|
|
2912
2912
|
},
|
|
2913
2913
|
"environment": "Середовище",
|
|
2914
2914
|
"footer": "Сценарії — це області, які Тестувальник вирішив перевірити (його сценарії приймання зі специфікації). Результати та зауваження групуються під ними за назвою.",
|
|
2915
|
-
"infrastructure": "Інфраструктура"
|
|
2915
|
+
"infrastructure": "Інфраструктура",
|
|
2916
|
+
"standup": {
|
|
2917
|
+
"up": "Залежності запущено",
|
|
2918
|
+
"failed": "Не вдалося запустити залежності",
|
|
2919
|
+
"took": "Час: {seconds}s",
|
|
2920
|
+
"showLogs": "Показати журнали запуску",
|
|
2921
|
+
"hideLogs": "Сховати журнали запуску"
|
|
2922
|
+
}
|
|
2916
2923
|
},
|
|
2917
2924
|
"visualConfirm": {
|
|
2918
2925
|
"ariaLabel": "Візуальне підтвердження",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.52.0",
|
|
4
4
|
"description": "Reusable Nuxt layer for the Agent Architecture Board SPA (components, stores, composables, pages). Consume it from a thin deployment app via `extends: ['@cat-factory/app']` and point it at your backend with NUXT_PUBLIC_API_BASE. See deploy/frontend for an example.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -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.
|
|
37
|
+
"@cat-factory/contracts": "0.54.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@toad-contracts/testing": "0.3.2",
|