@cat-factory/app 0.258.1 → 0.259.1

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.
@@ -0,0 +1,74 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { readEnvironmentAgainstClock } from './OutcomeSummaryWindow.logic'
3
+ import type { OutcomeEnvironment } from '~/utils/runOutcome'
4
+
5
+ /**
6
+ * The one thing the outcome card decides for itself: whether the TTL the payload carries has
7
+ * lapsed, and what that changes. The reduction behind the card is clock-free on purpose, so this
8
+ * is the only place a reader is told an environment is past its expiry, and the failure it
9
+ * guards is the section's worst one: a green "Live" badge and a working-looking button on a row
10
+ * whose own expiry date is in the past.
11
+ */
12
+ const NOW = 1_700_000_000_000
13
+
14
+ const env = (overrides: Partial<OutcomeEnvironment> = {}): OutcomeEnvironment => ({
15
+ url: 'https://preview.test',
16
+ state: 'live',
17
+ origin: 'deployer',
18
+ expiresAt: null,
19
+ retained: false,
20
+ frameId: 'frm_own',
21
+ environmentId: 'env_1',
22
+ detail: null,
23
+ ...overrides,
24
+ })
25
+
26
+ describe('readEnvironmentAgainstClock', () => {
27
+ it('offers a live environment whose TTL has not lapsed', () => {
28
+ const row = readEnvironmentAgainstClock(env({ expiresAt: NOW + 60_000 }), NOW)
29
+ expect(row).toMatchObject({ state: 'live', lapsed: false, openable: true })
30
+ })
31
+
32
+ it('withholds the link once the TTL has lapsed, and says the environment expired', () => {
33
+ const row = readEnvironmentAgainstClock(env({ expiresAt: NOW - 1 }), NOW)
34
+ expect(row).toMatchObject({ state: 'expired', lapsed: true, openable: false })
35
+ // The URL survives the lapse: it is what names the environment and what an operator greps.
36
+ expect(row.url).toBe('https://preview.test')
37
+ })
38
+
39
+ // A run with no disposer and no further polls keeps a `provisioning` row forever, and one
40
+ // whose TTL then lapsed never came up and never will.
41
+ it('applies the lapse to an environment still coming up', () => {
42
+ const row = readEnvironmentAgainstClock(env({ state: 'provisioning', expiresAt: NOW - 1 }), NOW)
43
+ expect(row).toMatchObject({ state: 'expired', lapsed: true, openable: false })
44
+ })
45
+
46
+ // The clock may only answer the question the payload left open. Where a producer already said
47
+ // WHERE the environment went, that word is the more specific one and it stands.
48
+ it('never overwrites a state that already names where the environment went', () => {
49
+ for (const state of ['failed', 'reclaimed', 'reclaiming'] as const) {
50
+ const row = readEnvironmentAgainstClock(env({ state, expiresAt: NOW - 1 }), NOW)
51
+ expect(row).toMatchObject({ state, lapsed: false, openable: false })
52
+ }
53
+ })
54
+
55
+ // `useNowTick` reads 0 until the card mounts, and every instant in history is "past" the epoch.
56
+ it('makes no clock-derived claim before the card has a clock', () => {
57
+ const row = readEnvironmentAgainstClock(env({ expiresAt: NOW - 1 }), 0)
58
+ expect(row).toMatchObject({ state: 'live', lapsed: false, openable: true })
59
+ })
60
+
61
+ it('offers nothing to click for a live environment that has no URL yet', () => {
62
+ const row = readEnvironmentAgainstClock(env({ url: null }), NOW)
63
+ expect(row).toMatchObject({ state: 'live', openable: false })
64
+ })
65
+
66
+ // A run that recorded no TTL is not an expired one: absent and lapsed are opposite facts.
67
+ it('leaves a row carrying no TTL exactly as the payload states it', () => {
68
+ expect(readEnvironmentAgainstClock(env(), NOW)).toMatchObject({
69
+ state: 'live',
70
+ lapsed: false,
71
+ openable: true,
72
+ })
73
+ })
74
+ })
@@ -0,0 +1,63 @@
1
+ // What the outcome card's environment rows say once a CLOCK is applied to them, extracted from
2
+ // `OutcomeSummaryWindow.vue` so the rule can be asserted without mounting the card (see
3
+ // `OutcomeSummaryWindow.logic.spec.ts`).
4
+ //
5
+ // The reduction that produces those rows (`composeRunOutcome`) is deliberately clock-free: the
6
+ // SPA composes it live off its own store and `GET /api/v1/runs/:runId/outcome` composes it
7
+ // server-side, and a rule that read a clock would let the two disagree about one run for as long
8
+ // as their clocks differ. What the payload carries instead is the TTL INSTANT.
9
+ //
10
+ // Somebody still has to say what that instant means now, and it has to be the surface with the
11
+ // clock. Left unapplied, a run whose environment the TTL sweep reclaimed hours ago renders a
12
+ // green "Live" badge and an enabled Open button beside an expiry date in the past: three claims
13
+ // on one row, of which the date is the only true one.
14
+
15
+ import type { OutcomeEnvironment, OutcomeEnvironmentState } from '~/utils/runOutcome'
16
+
17
+ /**
18
+ * The states that describe an environment still STANDING, and so the only ones a lapsed TTL
19
+ * changes what they say.
20
+ *
21
+ * `failed`, `reclaimed` and `reclaiming` already name where the environment went or what is
22
+ * happening to it. A clock may not overwrite those with a less specific word: an environment
23
+ * that never came up did not then expire, and saying so would send a reader looking for a TTL
24
+ * where a provisioning failure is the thing to fix.
25
+ */
26
+ const STANDING_ENVIRONMENT_STATES = new Set<OutcomeEnvironmentState>(['live', 'provisioning'])
27
+
28
+ /** One environment row as the card renders it: the payload's own fields, read against a clock. */
29
+ export interface OutcomeEnvironmentRow extends OutcomeEnvironment {
30
+ /** True when the row's TTL has lapsed against `nowMs` while it still claimed to be standing. */
31
+ lapsed: boolean
32
+ /** Whether the card offers the row as something to click. */
33
+ openable: boolean
34
+ }
35
+
36
+ /**
37
+ * Apply the reader's clock to one environment row.
38
+ *
39
+ * `nowMs` of 0 means the card has not ticked yet (`useNowTick` reads 0 until mounted). No clock
40
+ * means no clock-derived claim: the row reads exactly as the payload states it rather than
41
+ * having every TTL lapse against the epoch.
42
+ */
43
+ export function readEnvironmentAgainstClock(
44
+ entry: OutcomeEnvironment,
45
+ nowMs: number,
46
+ ): OutcomeEnvironmentRow {
47
+ const lapsed =
48
+ nowMs > 0 &&
49
+ entry.expiresAt != null &&
50
+ entry.expiresAt <= nowMs &&
51
+ STANDING_ENVIRONMENT_STATES.has(entry.state)
52
+ const state = lapsed ? 'expired' : entry.state
53
+ return {
54
+ ...entry,
55
+ state,
56
+ lapsed,
57
+ // A link is offered ONLY for a `live` row: an environment that has been reclaimed, has
58
+ // expired or never came up still shows its URL (an operator greps for it, and it says which
59
+ // environment the row is about) and must not be something a designer clicks expecting to see
60
+ // the change.
61
+ openable: state === 'live' && Boolean(entry.url),
62
+ }
63
+ }
@@ -16,9 +16,12 @@
16
16
  // judged against, which turns the tester's requirement IDS into the TITLES a reader came for.
17
17
  import { computed, onUnmounted, ref, watch } from 'vue'
18
18
  import type {
19
+ EnvironmentsGap,
19
20
  OutcomeCheckKind,
20
21
  OutcomeCheckState,
21
22
  OutcomeDisposition,
23
+ OutcomeEnvironmentOrigin,
24
+ OutcomeEnvironmentState,
22
25
  OutcomeSource,
23
26
  OutcomeSpecJoin,
24
27
  OutcomeVisual,
@@ -35,6 +38,8 @@ import { REPRODUCTION_STATUS_KEYS } from '~/utils/reproduction'
35
38
  import type { RequirementVerdictStatus, TestConcernSeverity } from '~/types/domain'
36
39
  import type { TestEnvironment } from '@cat-factory/contracts'
37
40
  import { useArtifactBlobs } from '~/composables/useArtifactBlobs'
41
+ import { useNowTick } from '~/composables/useStepTimer'
42
+ import { readEnvironmentAgainstClock } from '~/components/outcome/OutcomeSummaryWindow.logic'
38
43
  import ArtifactLightbox from '~/components/media/ArtifactLightbox.vue'
39
44
  import ResultWindowShell from '~/components/panels/ResultWindowShell.vue'
40
45
  import MarkdownProse from '~/components/common/MarkdownProse.vue'
@@ -46,7 +51,12 @@ const documents = useDocumentsStore()
46
51
  const execution = useExecutionStore()
47
52
  const serviceSpec = useServiceSpecStore()
48
53
  const ui = useUiStore()
49
- const { t } = useI18n()
54
+ const { t, d } = useI18n()
55
+
56
+ // The wall clock this card reads a TTL against. Coarse on purpose: an environment's expiry is
57
+ // the only thing here that moves with time, and a per-second tick would re-render the whole card
58
+ // for a boundary that matters at minute granularity.
59
+ const nowTick = useNowTick(30_000)
50
60
 
51
61
  // Per-window blob cache for the captured views; revoked on unmount so the (large) image bytes
52
62
  // don't outlive the card.
@@ -136,6 +146,38 @@ const SOURCES_GAP_KEYS: Record<SourcesGap, string> = {
136
146
  run_unavailable: RUN_UNAVAILABLE_KEY,
137
147
  none_linked: 'outcome.sources.gap.none_linked',
138
148
  }
149
+ const ENVIRONMENTS_GAP_KEYS: Record<EnvironmentsGap, string> = {
150
+ run_unavailable: RUN_UNAVAILABLE_KEY,
151
+ no_environment_step: 'outcome.environments.gap.no_environment_step',
152
+ not_provisioned: 'outcome.environments.gap.not_provisioned',
153
+ infraless: 'outcome.environments.gap.infraless',
154
+ }
155
+ const ENVIRONMENT_STATE_KEYS: Record<OutcomeEnvironmentState, string> = {
156
+ live: 'outcome.environments.state.live',
157
+ provisioning: 'outcome.environments.state.provisioning',
158
+ failed: 'outcome.environments.state.failed',
159
+ reclaiming: 'outcome.environments.state.reclaiming',
160
+ reclaimed: 'outcome.environments.state.reclaimed',
161
+ expired: 'outcome.environments.state.expired',
162
+ }
163
+ const ENVIRONMENT_STATE_COLOR: Record<OutcomeEnvironmentState, BadgeColor> = {
164
+ live: 'success',
165
+ provisioning: 'info',
166
+ failed: 'error',
167
+ reclaiming: 'neutral',
168
+ reclaimed: 'neutral',
169
+ expired: 'neutral',
170
+ }
171
+ /**
172
+ * Where the row came from, said out loud. `projected` is the one that changes what a reader
173
+ * should conclude (nothing has settled yet, so this row can still move), and the three are
174
+ * mapped exhaustively so a new producer cannot ship as a blank line.
175
+ */
176
+ const ENVIRONMENT_ORIGIN_KEYS: Record<OutcomeEnvironmentOrigin, string> = {
177
+ deployer: 'outcome.environments.origin.deployer',
178
+ human_test: 'outcome.environments.origin.human_test',
179
+ projected: 'outcome.environments.origin.projected',
180
+ }
139
181
  const VISUALS_GAP_KEYS: Record<VisualsGap, string> = {
140
182
  run_unavailable: RUN_UNAVAILABLE_KEY,
141
183
  no_visual_step: 'outcome.visuals.gap.no_visual_step',
@@ -337,6 +379,28 @@ const sourceRows = computed(() => {
337
379
  }))
338
380
  })
339
381
 
382
+ /**
383
+ * The environments the run stood up, with everything the row needs resolved once.
384
+ *
385
+ * The TTL is applied HERE rather than in the reduction, and that division is deliberate: the
386
+ * payload is clock-free so the endpoint's answer and this card's live composition cannot
387
+ * disagree about one run, and this surface is the one with a clock to say what the instant it
388
+ * carries means now. The rule itself lives in `OutcomeSummaryWindow.logic.ts`, where it is
389
+ * asserted without mounting the card.
390
+ *
391
+ * The frame is named by its BLOCK title where the board has it. A frame id says nothing to the
392
+ * person this card is for, so an unresolvable one renders as no label rather than as an id.
393
+ */
394
+ const environmentRows = computed(() => {
395
+ const environments = outcome.value?.environments
396
+ if (!environments || environments.status !== 'reported') return []
397
+ return environments.entries.map((entry, index) => ({
398
+ ...readEnvironmentAgainstClock(entry, nowTick.value),
399
+ key: `${index}:${entry.environmentId ?? entry.url ?? entry.frameId ?? 'env'}`,
400
+ service: entry.frameId ? (board.getBlock(entry.frameId)?.title ?? null) : null,
401
+ }))
402
+ })
403
+
340
404
  /** Drill into the full test report (this card is the summary, never a replacement for it). */
341
405
  function openTestReport() {
342
406
  if (instance.value) ui.openTestEvidence(instance.value.id)
@@ -681,6 +745,78 @@ function openTestReport() {
681
745
  </template>
682
746
  </section>
683
747
 
748
+ <!-- Where to go and look: the running preview, which is the verification a person who does
749
+ not read diffs starts from. Beside the captured views on purpose: the shots are what
750
+ this run saw, this is the thing itself. -->
751
+ <section class="mb-5" data-testid="outcome-environments">
752
+ <h3 class="mb-1.5 text-[11px] font-semibold uppercase tracking-wide text-slate-500">
753
+ {{ t('outcome.environments.title') }}
754
+ </h3>
755
+ <template v-if="outcome.environments.status === 'reported'">
756
+ <div
757
+ v-for="row in environmentRows"
758
+ :key="row.key"
759
+ class="mb-2 rounded-md border border-slate-800 bg-slate-950/40 px-2.5 py-2 last:mb-0"
760
+ data-testid="outcome-environment"
761
+ :data-state="row.state"
762
+ >
763
+ <div class="flex flex-wrap items-center gap-2">
764
+ <UBadge :color="ENVIRONMENT_STATE_COLOR[row.state]" variant="subtle" size="sm">
765
+ {{ t(ENVIRONMENT_STATE_KEYS[row.state]) }}
766
+ </UBadge>
767
+ <span v-if="row.service" class="truncate text-[12px] text-slate-300">
768
+ {{ row.service }}
769
+ </span>
770
+ <span class="text-[11px] text-slate-500">
771
+ {{ t(ENVIRONMENT_ORIGIN_KEYS[row.origin]) }}
772
+ </span>
773
+ </div>
774
+ <UButton
775
+ v-if="row.openable"
776
+ :to="row.url ?? undefined"
777
+ target="_blank"
778
+ rel="noopener"
779
+ external
780
+ color="primary"
781
+ variant="soft"
782
+ size="xs"
783
+ class="mt-1.5"
784
+ icon="i-lucide-external-link"
785
+ data-testid="outcome-environment-open"
786
+ >
787
+ {{ t('outcome.environments.open') }}
788
+ </UButton>
789
+ <p
790
+ v-else-if="row.url"
791
+ class="mt-1.5 break-all text-[12px] text-slate-500"
792
+ data-testid="outcome-environment-url"
793
+ >
794
+ {{ row.url }}
795
+ </p>
796
+ <p v-if="row.retained" class="mt-1 text-[11px] text-slate-400">
797
+ {{ t('outcome.environments.retained') }}
798
+ </p>
799
+ <p v-if="row.expiresAt" class="mt-1 text-[11px] text-slate-500">
800
+ {{
801
+ row.lapsed
802
+ ? t('outcome.environments.expired', { date: d(new Date(row.expiresAt), 'long') })
803
+ : t('outcome.environments.expires', { date: d(new Date(row.expiresAt), 'long') })
804
+ }}
805
+ </p>
806
+ <p
807
+ v-if="row.detail"
808
+ class="mt-1 break-words text-[12px] leading-relaxed text-slate-500"
809
+ data-testid="outcome-environment-detail"
810
+ >
811
+ {{ row.detail }}
812
+ </p>
813
+ </div>
814
+ </template>
815
+ <p v-else class="text-[13px] italic leading-relaxed text-slate-500">
816
+ {{ t(ENVIRONMENTS_GAP_KEYS[outcome.environments.gap]) }}
817
+ </p>
818
+ </section>
819
+
684
820
  <!-- The machine checks, listed only where one actually recorded a verdict. -->
685
821
  <section v-if="checkRows.length" data-testid="outcome-checks">
686
822
  <h3 class="mb-1.5 text-[11px] font-semibold uppercase tracking-wide text-slate-500">
@@ -28,6 +28,7 @@ export const REASON_KEY: Record<ToolServerUnavailableReason, string> = {
28
28
  transport_unsupported: 'panels.stepDetail.toolServers.reason.transportUnsupported',
29
29
  missing_secret: 'panels.stepDetail.toolServers.reason.missingSecret',
30
30
  reserved_secret: 'panels.stepDetail.toolServers.reason.reservedSecret',
31
+ unusable_secret: 'panels.stepDetail.toolServers.reason.unusableSecret',
31
32
  oauth_not_connected: 'panels.stepDetail.toolServers.reason.oauthNotConnected',
32
33
  oauth_token_failed: 'panels.stepDetail.toolServers.reason.oauthTokenFailed',
33
34
  over_budget: 'panels.stepDetail.toolServers.reason.overBudget',
@@ -59,6 +60,7 @@ export const REMEDY_KEY: Record<ToolServerUnavailableReason, string> = {
59
60
  transport_unsupported: 'panels.stepDetail.toolServers.remedy.transportUnsupported',
60
61
  missing_secret: 'panels.stepDetail.toolServers.remedy.missingSecret',
61
62
  reserved_secret: 'panels.stepDetail.toolServers.remedy.reservedSecret',
63
+ unusable_secret: 'panels.stepDetail.toolServers.remedy.unusableSecret',
62
64
  oauth_not_connected: 'panels.stepDetail.toolServers.remedy.oauthNotConnected',
63
65
  oauth_token_failed: 'panels.stepDetail.toolServers.remedy.oauthTokenFailed',
64
66
  over_budget: 'panels.stepDetail.toolServers.remedy.overBudget',
@@ -40,6 +40,7 @@ const STATUS_LABELS = computed<Record<ToolServerProbeStatus, string>>(() => ({
40
40
  ok: t('settings.toolServers.status.ok'),
41
41
  credentials_missing: t('settings.toolServers.status.credentialsMissing'),
42
42
  credential_refused: t('settings.toolServers.status.credentialRefused'),
43
+ credential_unusable: t('settings.toolServers.status.credentialUnusable'),
43
44
  oauth_not_connected: t('settings.toolServers.status.oauthNotConnected'),
44
45
  oauth_token_failed: t('settings.toolServers.status.oauthTokenFailed'),
45
46
  unreachable: t('settings.toolServers.status.unreachable'),
@@ -347,6 +348,16 @@ async function runProbe(id: string) {
347
348
  })
348
349
  }}
349
350
  </p>
351
+ <p
352
+ v-if="resultFor(server.id)!.unusableCredentials?.length"
353
+ class="text-[11px] text-red-400"
354
+ >
355
+ {{
356
+ t('settings.toolServers.unusableCredentials', {
357
+ keys: resultFor(server.id)!.unusableCredentials!.join(', '),
358
+ })
359
+ }}
360
+ </p>
350
361
 
351
362
  <!-- Raw backend prose is DETAIL behind a disclosure, never the primary description. It is
352
363
  already scrubbed through `redactSecrets` at the emit site. -->
@@ -24,6 +24,10 @@ export type {
24
24
  OutcomeCheckState,
25
25
  OutcomeConcern,
26
26
  OutcomeDisposition,
27
+ OutcomeEnvironment,
28
+ OutcomeEnvironments,
29
+ OutcomeEnvironmentOrigin,
30
+ OutcomeEnvironmentState,
27
31
  OutcomePullRequest,
28
32
  OutcomeRequirement,
29
33
  OutcomeRequirements,
@@ -33,6 +37,7 @@ export type {
33
37
  OutcomeTests,
34
38
  OutcomeVisual,
35
39
  OutcomeVisuals,
40
+ EnvironmentsGap,
36
41
  RequirementsGap,
37
42
  RunOutcome,
38
43
  RunUnavailableGap,
@@ -656,6 +656,7 @@
656
656
  "ok": "Hat geantwortet",
657
657
  "credentialsMissing": "Keine Zugangsdaten",
658
658
  "credentialRefused": "Zugangsdaten abgelehnt",
659
+ "credentialUnusable": "Zugangsdaten nicht zustellbar",
659
660
  "oauthNotConnected": "Nicht verbunden",
660
661
  "oauthTokenFailed": "Verbindung funktioniert nicht mehr",
661
662
  "unreachable": "Keine Antwort",
@@ -669,6 +670,7 @@
669
670
  "allowedToolsUnchecked": "Die Werkzeugliste war zu lang, um sie vollständig zu lesen, daher konnten die eingeschränkten Namen nicht geprüft werden.",
670
671
  "unresolvedCredentials": "Für {keys} wurde nichts aufgelöst. Trage den Wert unten ein oder setze ihn in der Umgebung der Installation.",
671
672
  "refusedCredentials": "{keys} benennt eine Variable, die zur Konfiguration der Plattform selbst gehört, und wird daher nie aufgelöst. Ändere die Deklaration im Code der Installation.",
673
+ "unusableCredentials": "{keys} benennt keinen Header, daher erreicht der Wert einen HTTP-Server nie. Ergänze im Code der Installation den Header, mit dem sich der Server authentifiziert.",
672
674
  "httpStatus": "HTTP {status}",
673
675
  "showDetails": "Details anzeigen",
674
676
  "hideDetails": "Details verbergen",
@@ -1991,6 +1993,7 @@
1991
1993
  "transportUnsupported": "war nicht verfügbar: die Agenten-CLI dieses Schritts erreicht Server dieser Art nicht.",
1992
1994
  "missingSecret": "war nicht verfügbar: eine benötigte Zugangsinformation ist für dieses Board nicht hinterlegt.",
1993
1995
  "reservedSecret": "war nicht verfügbar: er verlangt eine Variable, die zur Konfiguration der Plattform gehört; die Deklaration muss geändert werden.",
1996
+ "unusableSecret": "war nicht verfügbar: eine seiner deklarierten Zugangsdaten erreicht ihn nicht, er wäre also ohne Authentifizierung gelaufen.",
1994
1997
  "oauthNotConnected": "war nicht verfügbar: dieses Board wurde noch nicht damit verbunden.",
1995
1998
  "oauthTokenFailed": "war nicht verfügbar: die Verbindung liefert kein Zugriffstoken mehr.",
1996
1999
  "overBudget": "war nicht verfügbar: dieser Agent deklariert mehr Tool-Server, als ein Lauf mitführt.",
@@ -2001,6 +2004,7 @@
2001
2004
  "transportUnsupported": "Deklarieren Sie dafür einen stdio-Server, oder führen Sie den Schritt auf einer Agenten-CLI aus, die HTTP-Server erreicht.",
2002
2005
  "missingSecret": "Hinterlegen Sie die genannte Zugangsinformation entweder als Umgebungsvariable des Deployments oder im Infrastruktur-Fenster unter den Capability-Zugangsdaten.",
2003
2006
  "reservedSecret": "Ändern Sie die Deklaration auf einen anderen Schlüssel; das Setzen dieser Variablen hilft gerade nicht.",
2007
+ "unusableSecret": "Korrigiere die Deklaration im Code der Installation: Die Zugangsdaten eines entfernten Servers reisen in einem Header, die eines lokalen werden in den Serverprozess injiziert.",
2004
2008
  "oauthNotConnected": "Verbinden Sie dieses Board im Infrastruktur-Fenster damit. Ein Deployment ohne ENCRYPTION_KEY hat keinen Ort für eine Berechtigung, das muss ein Betreiber also zuerst setzen.",
2005
2009
  "oauthTokenFailed": "Verbinden Sie es im Infrastruktur-Fenster neu, oder warten Sie die Störung des Anbieters ab.",
2006
2010
  "overBudget": "Kürzen Sie, was der Agent deklariert, damit ein Lauf alles mitführen kann."
@@ -6410,6 +6414,31 @@
6410
6414
  "none_captured": "Die Oberfläche sollte aufgenommen werden, es wurde aber keine Ansicht erfasst."
6411
6415
  }
6412
6416
  },
6417
+ "environments": {
6418
+ "title": "Live-Umgebung",
6419
+ "open": "Live-Umgebung öffnen",
6420
+ "retained": "Diese Umgebung soll den Lauf überdauern.",
6421
+ "expires": "Läuft am {date} ab",
6422
+ "expired": "Abgelaufen am {date}",
6423
+ "state": {
6424
+ "live": "Live",
6425
+ "provisioning": "Wird bereitgestellt",
6426
+ "failed": "Kam nie hoch",
6427
+ "reclaiming": "Wird abgebaut",
6428
+ "reclaimed": "Abgebaut",
6429
+ "expired": "Abgelaufen"
6430
+ },
6431
+ "origin": {
6432
+ "deployer": "Von diesem Lauf bereitgestellt",
6433
+ "human_test": "Für den manuellen Test bereitgestellt",
6434
+ "projected": "Der Lauf arbeitet noch, das kann sich also noch ändern"
6435
+ },
6436
+ "gap": {
6437
+ "no_environment_step": "In dieser Pipeline stellt nichts eine Umgebung bereit, es gibt also nichts zu öffnen.",
6438
+ "not_provisioned": "Eine Umgebung sollte bereitgestellt werden, bisher wurde aber keine erfasst.",
6439
+ "infraless": "Dieser Service deklariert keine eigene Umgebung, es wurde also nichts bereitgestellt."
6440
+ }
6441
+ },
6413
6442
  "checks": {
6414
6443
  "title": "Prüfungen",
6415
6444
  "row": "{kind}: {state}",
@@ -1537,6 +1537,7 @@
1537
1537
  "transportUnsupported": "was not available: the agent CLI this step ran on cannot reach this kind of server.",
1538
1538
  "missingSecret": "was not available: a credential it needs is not set for this board.",
1539
1539
  "reservedSecret": "was not available: it asks for a variable the platform's own configuration owns, so the declaration has to change.",
1540
+ "unusableSecret": "was not available: a credential it declares cannot reach it, so the server would have run unauthenticated.",
1540
1541
  "oauthNotConnected": "was not available: nobody has connected this board to it yet.",
1541
1542
  "oauthTokenFailed": "was not available: the connection stopped producing an access token.",
1542
1543
  "overBudget": "was not available: this agent declares more tool servers than one run carries.",
@@ -1547,6 +1548,7 @@
1547
1548
  "transportUnsupported": "Declare a stdio server for it, or run the step on an agent CLI that reaches HTTP servers.",
1548
1549
  "missingSecret": "Set the credential it names, either as a deployment environment variable or under capability credentials in the Infrastructure window.",
1549
1550
  "reservedSecret": "Change the declaration to ask for another key; setting that variable is exactly what will not help.",
1551
+ "unusableSecret": "Fix the declaration in the deployment's code: a remote server's credential rides a header, and a local one is injected into the server's own process.",
1550
1552
  "oauthNotConnected": "Connect this board to it from the Infrastructure window. A deployment with no ENCRYPTION_KEY has nowhere to keep a grant, so an operator has to set that first.",
1551
1553
  "oauthTokenFailed": "Reconnect it from the Infrastructure window, or wait out the vendor's outage.",
1552
1554
  "overBudget": "Trim what the agent declares, so one run can carry all of it."
@@ -3347,6 +3349,7 @@
3347
3349
  "ok": "Answered",
3348
3350
  "credentialsMissing": "No credential",
3349
3351
  "credentialRefused": "Credential refused",
3352
+ "credentialUnusable": "Credential cannot be sent",
3350
3353
  "oauthNotConnected": "Not connected",
3351
3354
  "oauthTokenFailed": "Connection stopped working",
3352
3355
  "unreachable": "No answer",
@@ -3360,6 +3363,7 @@
3360
3363
  "allowedToolsUnchecked": "The tool list was too long to read in full, so the narrowed names could not be checked.",
3361
3364
  "unresolvedCredentials": "Nothing resolved for {keys}. Fill it in below, or set it in the deployment's environment.",
3362
3365
  "refusedCredentials": "{keys} names a variable the platform's own configuration owns, so it is never resolved. Change the declaration in the deployment's code.",
3366
+ "unusableCredentials": "{keys} names no header, so an HTTP server never receives it. Add the header the server authenticates with, in the deployment's code.",
3363
3367
  "httpStatus": "HTTP {status}",
3364
3368
  "showDetails": "Show details",
3365
3369
  "hideDetails": "Hide details",
@@ -6125,6 +6129,31 @@
6125
6129
  "none_captured": "The interface was meant to be captured, but no view was."
6126
6130
  }
6127
6131
  },
6132
+ "environments": {
6133
+ "title": "Live environment",
6134
+ "open": "Open the live environment",
6135
+ "retained": "This environment is meant to outlive the run.",
6136
+ "expires": "Expires {date}",
6137
+ "expired": "Expired {date}",
6138
+ "state": {
6139
+ "live": "Live",
6140
+ "provisioning": "Coming up",
6141
+ "failed": "Never came up",
6142
+ "reclaiming": "Being torn down",
6143
+ "reclaimed": "Torn down",
6144
+ "expired": "Expired"
6145
+ },
6146
+ "origin": {
6147
+ "deployer": "Stood up by this run",
6148
+ "human_test": "Stood up for the hands-on test",
6149
+ "projected": "The run is still working, so this can still change"
6150
+ },
6151
+ "gap": {
6152
+ "no_environment_step": "Nothing in this pipeline stands an environment up, so there is nothing to open.",
6153
+ "not_provisioned": "An environment was meant to be stood up, and none has been recorded yet.",
6154
+ "infraless": "This service declares no environment of its own, so nothing was stood up."
6155
+ }
6156
+ },
6128
6157
  "checks": {
6129
6158
  "title": "Checks",
6130
6159
  "row": "{kind}: {state}",
@@ -1446,6 +1446,7 @@
1446
1446
  "transportUnsupported": "no estuvo disponible: la CLI del agente de este paso no puede alcanzar este tipo de servidor.",
1447
1447
  "missingSecret": "no estuvo disponible: falta en este tablero una credencial que necesita.",
1448
1448
  "reservedSecret": "no estuvo disponible: pide una variable que pertenece a la configuración de la plataforma, así que hay que cambiar la declaración.",
1449
+ "unusableSecret": "no estuvo disponible: una credencial que declara no puede llegarle, así que el servidor habría funcionado sin autenticar.",
1449
1450
  "oauthNotConnected": "no estuvo disponible: nadie ha conectado este tablero con él todavía.",
1450
1451
  "oauthTokenFailed": "no estuvo disponible: la conexión dejó de producir un token de acceso.",
1451
1452
  "overBudget": "no estuvo disponible: este agente declara más servidores de los que lleva una ejecución.",
@@ -1456,6 +1457,7 @@
1456
1457
  "transportUnsupported": "Declara un servidor stdio para él, o ejecuta el paso en una CLI de agente que alcance servidores HTTP.",
1457
1458
  "missingSecret": "Configura la credencial que nombra, ya sea como variable de entorno del despliegue o en las credenciales de capacidades, en la ventana de Infraestructura.",
1458
1459
  "reservedSecret": "Cambia la declaración para que pida otra clave; definir esa variable es justo lo que no ayudará.",
1460
+ "unusableSecret": "Corrige la declaración en el código de la instalación: la credencial de un servidor remoto viaja en una cabecera y la de uno local se inyecta en el proceso del servidor.",
1459
1461
  "oauthNotConnected": "Conecta este tablero con él desde la ventana de Infraestructura. Un despliegue sin ENCRYPTION_KEY no tiene dónde guardar una concesión, así que un operador debe configurarla primero.",
1460
1462
  "oauthTokenFailed": "Vuelve a conectarlo desde la ventana de Infraestructura, o espera a que pase la caída del proveedor.",
1461
1463
  "overBudget": "Recorta lo que declara el agente, para que una ejecución pueda llevarlo todo."
@@ -3087,6 +3089,7 @@
3087
3089
  "ok": "Respondió",
3088
3090
  "credentialsMissing": "Sin credencial",
3089
3091
  "credentialRefused": "Credencial rechazada",
3092
+ "credentialUnusable": "Credencial no enviable",
3090
3093
  "oauthNotConnected": "Sin conexión",
3091
3094
  "oauthTokenFailed": "La conexión dejó de funcionar",
3092
3095
  "unreachable": "Sin respuesta",
@@ -3100,6 +3103,7 @@
3100
3103
  "allowedToolsUnchecked": "La lista de herramientas era demasiado larga para leerla completa, así que no se pudieron comprobar los nombres limitados.",
3101
3104
  "unresolvedCredentials": "No se resolvió nada para {keys}. Rellénalo abajo o defínelo en el entorno de la instalación.",
3102
3105
  "refusedCredentials": "{keys} nombra una variable que pertenece a la configuración de la propia plataforma, así que nunca se resuelve. Cambia la declaración en el código de la instalación.",
3106
+ "unusableCredentials": "{keys} no nombra ninguna cabecera, así que un servidor HTTP nunca lo recibe. Añade en el código de la instalación la cabecera con la que se autentica el servidor.",
3103
3107
  "httpStatus": "HTTP {status}",
3104
3108
  "showDetails": "Ver detalles",
3105
3109
  "hideDetails": "Ocultar detalles",
@@ -5847,6 +5851,31 @@
5847
5851
  "none_captured": "La interfaz debía capturarse, pero no se capturó ninguna vista."
5848
5852
  }
5849
5853
  },
5854
+ "environments": {
5855
+ "title": "Entorno en vivo",
5856
+ "open": "Abrir el entorno en vivo",
5857
+ "retained": "Este entorno está pensado para seguir existiendo después de la ejecución.",
5858
+ "expires": "Caduca el {date}",
5859
+ "expired": "Caducó el {date}",
5860
+ "state": {
5861
+ "live": "En vivo",
5862
+ "provisioning": "Levantándose",
5863
+ "failed": "Nunca llegó a levantarse",
5864
+ "reclaiming": "Desmontándose",
5865
+ "reclaimed": "Desmontado",
5866
+ "expired": "Caducado"
5867
+ },
5868
+ "origin": {
5869
+ "deployer": "Levantado por esta ejecución",
5870
+ "human_test": "Levantado para la prueba manual",
5871
+ "projected": "La ejecución sigue en curso, así que esto aún puede cambiar"
5872
+ },
5873
+ "gap": {
5874
+ "no_environment_step": "Nada en esta canalización levanta un entorno, así que no hay nada que abrir.",
5875
+ "not_provisioned": "Debía levantarse un entorno y todavía no se ha registrado ninguno.",
5876
+ "infraless": "Este servicio no declara ningún entorno propio, así que no se levantó nada."
5877
+ }
5878
+ },
5850
5879
  "checks": {
5851
5880
  "title": "Comprobaciones",
5852
5881
  "row": "{kind}: {state}",
@@ -1446,6 +1446,7 @@
1446
1446
  "transportUnsupported": "n'était pas disponible : la CLI d'agent de cette étape ne peut pas atteindre ce type de serveur.",
1447
1447
  "missingSecret": "n'était pas disponible : un identifiant dont il a besoin n'est pas renseigné pour ce tableau.",
1448
1448
  "reservedSecret": "n'était pas disponible : il demande une variable qui appartient à la configuration de la plateforme, la déclaration doit donc changer.",
1449
+ "unusableSecret": "n’était pas disponible : un identifiant qu’il déclare ne peut pas lui parvenir, le serveur aurait donc tourné sans authentification.",
1449
1450
  "oauthNotConnected": "n'était pas disponible : personne n'a encore connecté ce tableau à ce serveur.",
1450
1451
  "oauthTokenFailed": "n'était pas disponible : la connexion ne produit plus de jeton d'accès.",
1451
1452
  "overBudget": "n'était pas disponible : cet agent déclare plus de serveurs d'outils qu'une exécution n'en transporte.",
@@ -1456,6 +1457,7 @@
1456
1457
  "transportUnsupported": "Déclarez un serveur stdio à sa place, ou exécutez l’étape sur une CLI d’agent qui atteint les serveurs HTTP.",
1457
1458
  "missingSecret": "Renseignez l’identifiant qu’il nomme, soit comme variable d’environnement du déploiement, soit dans les identifiants de capacités, depuis la fenêtre Infrastructure.",
1458
1459
  "reservedSecret": "Modifiez la déclaration pour demander une autre clé ; définir cette variable est précisément ce qui n’aidera pas.",
1460
+ "unusableSecret": "Corrigez la déclaration dans le code du déploiement : l’identifiant d’un serveur distant voyage dans un en-tête, celui d’un serveur local est injecté dans son processus.",
1459
1461
  "oauthNotConnected": "Connectez ce tableau à ce serveur depuis la fenêtre Infrastructure. Un déploiement sans ENCRYPTION_KEY n’a nulle part où conserver une autorisation : un opérateur doit d’abord la définir.",
1460
1462
  "oauthTokenFailed": "Reconnectez-le depuis la fenêtre Infrastructure, ou attendez la fin de la panne du fournisseur.",
1461
1463
  "overBudget": "Réduisez ce que l’agent déclare, pour qu’une exécution puisse tout transporter."
@@ -3087,6 +3089,7 @@
3087
3089
  "ok": "A répondu",
3088
3090
  "credentialsMissing": "Aucun identifiant",
3089
3091
  "credentialRefused": "Identifiant refusé",
3092
+ "credentialUnusable": "Identifiant non transmissible",
3090
3093
  "oauthNotConnected": "Non connecté",
3091
3094
  "oauthTokenFailed": "La connexion ne fonctionne plus",
3092
3095
  "unreachable": "Aucune réponse",
@@ -3100,6 +3103,7 @@
3100
3103
  "allowedToolsUnchecked": "La liste d’outils était trop longue pour être lue en entier, les noms restreints n’ont donc pas pu être vérifiés.",
3101
3104
  "unresolvedCredentials": "Rien n’a été résolu pour {keys}. Renseignez la valeur ci-dessous, ou définissez-la dans l’environnement du déploiement.",
3102
3105
  "refusedCredentials": "{keys} désigne une variable qui appartient à la configuration de la plateforme elle-même : elle n’est jamais résolue. Modifiez la déclaration dans le code du déploiement.",
3106
+ "unusableCredentials": "{keys} ne désigne aucun en-tête : un serveur HTTP ne le reçoit donc jamais. Ajoutez dans le code du déploiement l’en-tête avec lequel le serveur s’authentifie.",
3103
3107
  "httpStatus": "HTTP {status}",
3104
3108
  "showDetails": "Afficher les détails",
3105
3109
  "hideDetails": "Masquer les détails",
@@ -5847,6 +5851,31 @@
5847
5851
  "none_captured": "L'interface devait être capturée, mais aucune vue ne l'a été."
5848
5852
  }
5849
5853
  },
5854
+ "environments": {
5855
+ "title": "Environnement en ligne",
5856
+ "open": "Ouvrir l'environnement en ligne",
5857
+ "retained": "Cet environnement est censé survivre à l’exécution.",
5858
+ "expires": "Expire le {date}",
5859
+ "expired": "Expiré le {date}",
5860
+ "state": {
5861
+ "live": "En ligne",
5862
+ "provisioning": "En cours de création",
5863
+ "failed": "Jamais démarré",
5864
+ "reclaiming": "En cours de suppression",
5865
+ "reclaimed": "Supprimé",
5866
+ "expired": "Expiré"
5867
+ },
5868
+ "origin": {
5869
+ "deployer": "Créé par cette exécution",
5870
+ "human_test": "Créé pour le test manuel",
5871
+ "projected": "L'exécution est toujours en cours, cela peut encore changer"
5872
+ },
5873
+ "gap": {
5874
+ "no_environment_step": "Rien dans ce pipeline ne crée d'environnement, il n'y a donc rien à ouvrir.",
5875
+ "not_provisioned": "Un environnement devait être créé et aucun n'a encore été enregistré.",
5876
+ "infraless": "Ce service ne déclare aucun environnement propre, rien n'a donc été créé."
5877
+ }
5878
+ },
5850
5879
  "checks": {
5851
5880
  "title": "Contrôles",
5852
5881
  "row": "{kind} : {state}",
@@ -1446,6 +1446,7 @@
1446
1446
  "transportUnsupported": "לא היה זמין: ממשק הסוכן שבו רץ השלב הזה אינו יכול להגיע לשרת מסוג זה.",
1447
1447
  "missingSecret": "לא היה זמין: אישור גישה שהוא צריך אינו מוגדר עבור הלוח הזה.",
1448
1448
  "reservedSecret": "לא היה זמין: הוא מבקש משתנה ששייך לתצורת הפלטפורמה עצמה, ולכן יש לשנות את ההצהרה.",
1449
+ "unusableSecret": "לא היה זמין: אחד מפרטי ההזדהות שהוא מצהיר עליהם אינו יכול להגיע אליו, ולכן השרת היה פועל ללא אימות.",
1449
1450
  "oauthNotConnected": "לא היה זמין: איש עדיין לא חיבר את הלוח הזה אליו.",
1450
1451
  "oauthTokenFailed": "לא היה זמין: החיבור הפסיק להנפיק אסימון גישה.",
1451
1452
  "overBudget": "לא היה זמין: הסוכן הזה מצהיר על יותר שרתי כלים ממה שריצה אחת נושאת.",
@@ -1456,6 +1457,7 @@
1456
1457
  "transportUnsupported": "הצהירו עבורו שרת stdio, או הריצו את השלב על ממשק סוכן שמגיע לשרתי HTTP.",
1457
1458
  "missingSecret": "הגדירו את אישור הגישה שהוא מבקש, בין כמשתנה סביבה של הפריסה ובין באישורי היכולות בחלון התשתית.",
1458
1459
  "reservedSecret": "שנו את ההצהרה כך שתבקש מפתח אחר; הגדרת המשתנה הזה היא בדיוק מה שלא יעזור.",
1460
+ "unusableSecret": "תקנו את ההצהרה בקוד ההתקנה: פרטי ההזדהות של שרת מרוחק נשלחים בכותרת, ושל שרת מקומי מוזרקים לתהליך של השרת.",
1459
1461
  "oauthNotConnected": "חברו את הלוח הזה אליו מחלון התשתית. בפריסה ללא ENCRYPTION_KEY אין היכן לשמור הרשאה, ולכן מפעיל צריך להגדיר אותו קודם.",
1460
1462
  "oauthTokenFailed": "חברו אותו מחדש מחלון התשתית, או המתינו לסיום התקלה אצל הספק.",
1461
1463
  "overBudget": "צמצמו את מה שהסוכן מצהיר עליו, כדי שריצה אחת תוכל לשאת הכול."
@@ -3228,6 +3230,7 @@
3228
3230
  "ok": "השיב",
3229
3231
  "credentialsMissing": "אין פרטי הזדהות",
3230
3232
  "credentialRefused": "פרטי ההזדהות נדחו",
3233
+ "credentialUnusable": "לא ניתן לשלוח את פרטי ההזדהות",
3231
3234
  "oauthNotConnected": "לא מחובר",
3232
3235
  "oauthTokenFailed": "החיבור הפסיק לעבוד",
3233
3236
  "unreachable": "אין תשובה",
@@ -3241,6 +3244,7 @@
3241
3244
  "allowedToolsUnchecked": "רשימת הכלים הייתה ארוכה מכדי לקרוא אותה במלואה, ולכן לא ניתן היה לבדוק את השמות המוגבלים.",
3242
3245
  "unresolvedCredentials": "לא אותר דבר עבור {keys}. מלאו את הערך למטה, או הגדירו אותו בסביבת ההתקנה.",
3243
3246
  "refusedCredentials": "{keys} מציין משתנה שהוא חלק מהתצורה של הפלטפורמה עצמה, ולכן הוא לעולם אינו מאותר. שנו את ההצהרה בקוד ההתקנה.",
3247
+ "unusableCredentials": "{keys} אינו מציין כותרת, ולכן שרת HTTP לעולם אינו מקבל אותו. הוסיפו בקוד ההתקנה את הכותרת שבה השרת מזדהה.",
3244
3248
  "httpStatus": "HTTP {status}",
3245
3249
  "showDetails": "הצגת פרטים",
3246
3250
  "hideDetails": "הסתרת פרטים",
@@ -5847,6 +5851,31 @@
5847
5851
  "none_captured": "הממשק היה אמור להיות מצולם, אך שום תצוגה לא נלכדה."
5848
5852
  }
5849
5853
  },
5854
+ "environments": {
5855
+ "title": "סביבה פעילה",
5856
+ "open": "פתיחת הסביבה הפעילה",
5857
+ "retained": "סביבה זו נועדה להישאר קיימת גם לאחר סיום ההרצה.",
5858
+ "expires": "פג תוקף ב־{date}",
5859
+ "expired": "פג תוקף ב-{date}",
5860
+ "state": {
5861
+ "live": "פעילה",
5862
+ "provisioning": "עולה",
5863
+ "failed": "מעולם לא עלתה",
5864
+ "reclaiming": "בפירוק",
5865
+ "reclaimed": "פורקה",
5866
+ "expired": "פג תוקף"
5867
+ },
5868
+ "origin": {
5869
+ "deployer": "הוקמה על ידי ההרצה הזו",
5870
+ "human_test": "הוקמה לצורך בדיקה ידנית",
5871
+ "projected": "ההרצה עדיין נמשכת, ולכן זה עשוי להשתנות"
5872
+ },
5873
+ "gap": {
5874
+ "no_environment_step": "שום שלב בצינור הזה אינו מקים סביבה, ולכן אין מה לפתוח.",
5875
+ "not_provisioned": "הייתה אמורה לקום סביבה, ועדיין לא נרשמה אף אחת.",
5876
+ "infraless": "השירות הזה אינו מגדיר סביבה משלו, ולכן לא הוקם דבר."
5877
+ }
5878
+ },
5850
5879
  "checks": {
5851
5880
  "title": "בדיקות",
5852
5881
  "row": "{kind}: {state}",
@@ -656,6 +656,7 @@
656
656
  "ok": "Ha risposto",
657
657
  "credentialsMissing": "Nessuna credenziale",
658
658
  "credentialRefused": "Credenziale rifiutata",
659
+ "credentialUnusable": "Credenziale non inviabile",
659
660
  "oauthNotConnected": "Non collegato",
660
661
  "oauthTokenFailed": "Il collegamento ha smesso di funzionare",
661
662
  "unreachable": "Nessuna risposta",
@@ -669,6 +670,7 @@
669
670
  "allowedToolsUnchecked": "L’elenco degli strumenti era troppo lungo per leggerlo tutto, quindi i nomi limitati non hanno potuto essere verificati.",
670
671
  "unresolvedCredentials": "Nulla è stato risolto per {keys}. Inseriscilo qui sotto, oppure impostalo nell’ambiente dell’installazione.",
671
672
  "refusedCredentials": "{keys} nomina una variabile che appartiene alla configurazione della piattaforma stessa, quindi non viene mai risolta. Modifica la dichiarazione nel codice dell’installazione.",
673
+ "unusableCredentials": "{keys} non nomina alcuna intestazione, quindi un server HTTP non la riceve mai. Aggiungi nel codice dell’installazione l’intestazione con cui il server si autentica.",
672
674
  "httpStatus": "HTTP {status}",
673
675
  "showDetails": "Mostra dettagli",
674
676
  "hideDetails": "Nascondi dettagli",
@@ -1991,6 +1993,7 @@
1991
1993
  "transportUnsupported": "non era disponibile: la CLI dell'agente di questo passo non riesce a raggiungere server di questo tipo.",
1992
1994
  "missingSecret": "non era disponibile: una credenziale che gli serve non è impostata per questa lavagna.",
1993
1995
  "reservedSecret": "non era disponibile: chiede una variabile che appartiene alla configurazione della piattaforma, quindi va cambiata la dichiarazione.",
1996
+ "unusableSecret": "non era disponibile: una credenziale che dichiara non può raggiungerlo, quindi il server sarebbe partito senza autenticazione.",
1994
1997
  "oauthNotConnected": "non era disponibile: nessuno ha ancora collegato questa lavagna al server.",
1995
1998
  "oauthTokenFailed": "non era disponibile: la connessione ha smesso di produrre un token di accesso.",
1996
1999
  "overBudget": "non era disponibile: questo agente dichiara più server di strumenti di quanti ne porti una singola esecuzione.",
@@ -2001,6 +2004,7 @@
2001
2004
  "transportUnsupported": "Dichiara un server stdio al suo posto, oppure esegui il passo su una CLI dell'agente che raggiunge i server HTTP.",
2002
2005
  "missingSecret": "Imposta la credenziale che indica, come variabile d'ambiente del deployment oppure nelle credenziali delle capability, dalla finestra Infrastruttura.",
2003
2006
  "reservedSecret": "Cambia la dichiarazione perché chieda un'altra chiave; impostare quella variabile è proprio ciò che non aiuterà.",
2007
+ "unusableSecret": "Correggi la dichiarazione nel codice dell’installazione: la credenziale di un server remoto viaggia in un’intestazione, quella di uno locale viene iniettata nel processo del server.",
2004
2008
  "oauthNotConnected": "Collega questa lavagna al server dalla finestra Infrastruttura. Un deployment senza ENCRYPTION_KEY non ha dove conservare una concessione, quindi un operatore deve impostarla prima.",
2005
2009
  "oauthTokenFailed": "Ricollegalo dalla finestra Infrastruttura, oppure attendi la fine del disservizio del fornitore.",
2006
2010
  "overBudget": "Riduci ciò che l'agente dichiara, così una singola esecuzione può portarlo tutto."
@@ -6410,6 +6414,31 @@
6410
6414
  "none_captured": "L'interfaccia doveva essere catturata, ma non è stata catturata alcuna vista."
6411
6415
  }
6412
6416
  },
6417
+ "environments": {
6418
+ "title": "Ambiente attivo",
6419
+ "open": "Apri l'ambiente attivo",
6420
+ "retained": "Questo ambiente è pensato per sopravvivere all’esecuzione.",
6421
+ "expires": "Scade il {date}",
6422
+ "expired": "Scaduto il {date}",
6423
+ "state": {
6424
+ "live": "Attivo",
6425
+ "provisioning": "In avvio",
6426
+ "failed": "Mai avviato",
6427
+ "reclaiming": "In dismissione",
6428
+ "reclaimed": "Dismesso",
6429
+ "expired": "Scaduto"
6430
+ },
6431
+ "origin": {
6432
+ "deployer": "Avviato da questa esecuzione",
6433
+ "human_test": "Avviato per il test manuale",
6434
+ "projected": "L'esecuzione è ancora in corso, quindi può ancora cambiare"
6435
+ },
6436
+ "gap": {
6437
+ "no_environment_step": "In questa pipeline nulla avvia un ambiente, quindi non c'è niente da aprire.",
6438
+ "not_provisioned": "Doveva essere avviato un ambiente e finora non ne è stato registrato nessuno.",
6439
+ "infraless": "Questo servizio non dichiara un ambiente proprio, quindi non è stato avviato nulla."
6440
+ }
6441
+ },
6413
6442
  "checks": {
6414
6443
  "title": "Controlli",
6415
6444
  "row": "{kind}: {state}",
@@ -1446,6 +1446,7 @@
1446
1446
  "transportUnsupported": "は利用できませんでした: このステップを実行したエージェント CLI はこの種類のサーバーに接続できません。",
1447
1447
  "missingSecret": "は利用できませんでした: 必要な認証情報がこのボードに設定されていません。",
1448
1448
  "reservedSecret": "は利用できませんでした: プラットフォーム自身の設定が使う変数を要求しているため、宣言側を変更する必要があります。",
1449
+ "unusableSecret": "は利用できませんでした: 宣言された認証情報がサーバーに届かないため、認証なしで動作することになります。",
1449
1450
  "oauthNotConnected": "は利用できませんでした: このボードはまだ接続されていません。",
1450
1451
  "oauthTokenFailed": "は利用できませんでした: 接続からアクセストークンが発行されなくなりました。",
1451
1452
  "overBudget": "は利用できませんでした: このエージェントは 1 回の実行が運べる数を超えるツールサーバーを宣言しています。",
@@ -1456,6 +1457,7 @@
1456
1457
  "transportUnsupported": "このサーバー用に stdio サーバーを宣言するか、HTTP サーバーに接続できるエージェント CLI でステップを実行してください。",
1457
1458
  "missingSecret": "要求されている認証情報を、デプロイの環境変数として設定するか、インフラストラクチャ ウィンドウのケイパビリティ認証情報で設定してください。",
1458
1459
  "reservedSecret": "別のキーを要求するよう宣言を変更してください。その変数を設定しても解決しません。",
1460
+ "unusableSecret": "デプロイのコードで宣言を修正してください。リモートサーバーの認証情報はヘッダーで送られ、ローカルサーバーのものはサーバープロセスに注入されます。",
1459
1461
  "oauthNotConnected": "インフラストラクチャ ウィンドウからこのボードを接続してください。ENCRYPTION_KEY のないデプロイには許可を保管する場所がないため、まず運用者がそれを設定する必要があります。",
1460
1462
  "oauthTokenFailed": "インフラストラクチャ ウィンドウから接続し直すか、提供元の障害が収まるのを待ってください。",
1461
1463
  "overBudget": "1 回の実行ですべて運べるよう、このエージェントの宣言を減らしてください。"
@@ -3228,6 +3230,7 @@
3228
3230
  "ok": "応答あり",
3229
3231
  "credentialsMissing": "認証情報なし",
3230
3232
  "credentialRefused": "認証情報を拒否",
3233
+ "credentialUnusable": "認証情報を送信できません",
3231
3234
  "oauthNotConnected": "未接続",
3232
3235
  "oauthTokenFailed": "接続が機能しなくなりました",
3233
3236
  "unreachable": "応答なし",
@@ -3241,6 +3244,7 @@
3241
3244
  "allowedToolsUnchecked": "ツール一覧が長すぎて全部を読み取れなかったため、絞り込んだ名前は確認できませんでした。",
3242
3245
  "unresolvedCredentials": "{keys} の値が解決できませんでした。下で入力するか、デプロイの環境変数に設定してください。",
3243
3246
  "refusedCredentials": "{keys} はプラットフォーム自身の設定に属する変数名なので、決して解決されません。デプロイのコード側の宣言を変更してください。",
3247
+ "unusableCredentials": "{keys} はヘッダーを指定していないため、HTTP サーバーには決して届きません。デプロイのコードで、サーバーが認証に使うヘッダーを指定してください。",
3244
3248
  "httpStatus": "HTTP {status}",
3245
3249
  "showDetails": "詳細を表示",
3246
3250
  "hideDetails": "詳細を隠す",
@@ -5847,6 +5851,31 @@
5847
5851
  "none_captured": "画面を取得する予定でしたが、ビューは取得されませんでした。"
5848
5852
  }
5849
5853
  },
5854
+ "environments": {
5855
+ "title": "稼働中の環境",
5856
+ "open": "稼働中の環境を開く",
5857
+ "retained": "この環境は実行の終了後も残るように設定されています。",
5858
+ "expires": "{date} に期限切れ",
5859
+ "expired": "{date} に期限切れ",
5860
+ "state": {
5861
+ "live": "稼働中",
5862
+ "provisioning": "起動中",
5863
+ "failed": "起動できませんでした",
5864
+ "reclaiming": "破棄中",
5865
+ "reclaimed": "破棄済み",
5866
+ "expired": "期限切れ"
5867
+ },
5868
+ "origin": {
5869
+ "deployer": "この実行が用意した環境",
5870
+ "human_test": "手動テスト用に用意した環境",
5871
+ "projected": "実行がまだ続いているため、この内容は変わる可能性があります"
5872
+ },
5873
+ "gap": {
5874
+ "no_environment_step": "このパイプラインには環境を用意する処理がないため、開けるものはありません。",
5875
+ "not_provisioned": "環境が用意されるはずですが、まだ何も記録されていません。",
5876
+ "infraless": "このサービスは独自の環境を宣言していないため、何も用意されていません。"
5877
+ }
5878
+ },
5850
5879
  "checks": {
5851
5880
  "title": "チェック",
5852
5881
  "row": "{kind}: {state}",
@@ -1446,6 +1446,7 @@
1446
1446
  "transportUnsupported": "nie był dostępny: CLI agenta, na którym działał ten krok, nie dosięga serwera tego rodzaju.",
1447
1447
  "missingSecret": "nie był dostępny: potrzebne mu poświadczenie nie jest ustawione dla tej tablicy.",
1448
1448
  "reservedSecret": "nie był dostępny: prosi o zmienną należącą do konfiguracji samej platformy, więc trzeba zmienić deklarację.",
1449
+ "unusableSecret": "nie był dostępny: zadeklarowane dane uwierzytelniające nie mogą do niego dotrzeć, więc serwer działałby bez uwierzytelnienia.",
1449
1450
  "oauthNotConnected": "nie był dostępny: nikt jeszcze nie połączył z nim tej tablicy.",
1450
1451
  "oauthTokenFailed": "nie był dostępny: połączenie przestało wydawać token dostępu.",
1451
1452
  "overBudget": "nie był dostępny: ten agent deklaruje więcej serwerów narzędzi, niż niesie jedno uruchomienie.",
@@ -1456,6 +1457,7 @@
1456
1457
  "transportUnsupported": "Zadeklaruj dla niego serwer stdio albo uruchom krok na CLI agenta, które dosięga serwerów HTTP.",
1457
1458
  "missingSecret": "Ustaw wskazane poświadczenie jako zmienną środowiskową wdrożenia albo w poświadczeniach możliwości, w oknie Infrastruktura.",
1458
1459
  "reservedSecret": "Zmień deklarację tak, by prosiła o inny klucz; ustawienie tej zmiennej to właśnie to, co nie pomoże.",
1460
+ "unusableSecret": "Popraw deklarację w kodzie instalacji: dane uwierzytelniające serwera zdalnego jadą w nagłówku, a lokalnego są wstrzykiwane do procesu serwera.",
1459
1461
  "oauthNotConnected": "Połącz tę tablicę z serwerem w oknie Infrastruktura. Wdrożenie bez ENCRYPTION_KEY nie ma gdzie przechować zgody, więc operator musi ją najpierw ustawić.",
1460
1462
  "oauthTokenFailed": "Połącz go ponownie w oknie Infrastruktura albo przeczekaj awarię dostawcy.",
1461
1463
  "overBudget": "Skróć to, co deklaruje agent, aby jedno uruchomienie uniosło całość."
@@ -3087,6 +3089,7 @@
3087
3089
  "ok": "Odpowiedział",
3088
3090
  "credentialsMissing": "Brak danych uwierzytelniających",
3089
3091
  "credentialRefused": "Dane uwierzytelniające odrzucone",
3092
+ "credentialUnusable": "Nie można wysłać danych uwierzytelniających",
3090
3093
  "oauthNotConnected": "Niepołączony",
3091
3094
  "oauthTokenFailed": "Połączenie przestało działać",
3092
3095
  "unreachable": "Brak odpowiedzi",
@@ -3100,6 +3103,7 @@
3100
3103
  "allowedToolsUnchecked": "Lista narzędzi była zbyt długa, by odczytać ją w całości, więc zawężonych nazw nie dało się sprawdzić.",
3101
3104
  "unresolvedCredentials": "Nic nie rozwiązano dla {keys}. Wpisz wartość poniżej albo ustaw ją w środowisku instalacji.",
3102
3105
  "refusedCredentials": "{keys} nazywa zmienną należącą do konfiguracji samej platformy, więc nigdy nie jest rozwiązywana. Zmień deklarację w kodzie instalacji.",
3106
+ "unusableCredentials": "{keys} nie nazywa żadnego nagłówka, więc serwer HTTP nigdy go nie otrzyma. Dodaj w kodzie instalacji nagłówek, którym serwer się uwierzytelnia.",
3103
3107
  "httpStatus": "HTTP {status}",
3104
3108
  "showDetails": "Pokaż szczegóły",
3105
3109
  "hideDetails": "Ukryj szczegóły",
@@ -5847,6 +5851,31 @@
5847
5851
  "none_captured": "Interfejs miał zostać zarejestrowany, ale nie zapisano żadnego widoku."
5848
5852
  }
5849
5853
  },
5854
+ "environments": {
5855
+ "title": "Działające środowisko",
5856
+ "open": "Otwórz działające środowisko",
5857
+ "retained": "To środowisko ma istnieć dłużej niż samo uruchomienie.",
5858
+ "expires": "Wygasa {date}",
5859
+ "expired": "Wygasło {date}",
5860
+ "state": {
5861
+ "live": "Działa",
5862
+ "provisioning": "Uruchamiane",
5863
+ "failed": "Nigdy nie wystartowało",
5864
+ "reclaiming": "Usuwane",
5865
+ "reclaimed": "Usunięte",
5866
+ "expired": "Wygasło"
5867
+ },
5868
+ "origin": {
5869
+ "deployer": "Uruchomione przez ten przebieg",
5870
+ "human_test": "Uruchomione na potrzeby testu ręcznego",
5871
+ "projected": "Przebieg wciąż trwa, więc to może się jeszcze zmienić"
5872
+ },
5873
+ "gap": {
5874
+ "no_environment_step": "Nic w tym potoku nie uruchamia środowiska, więc nie ma czego otworzyć.",
5875
+ "not_provisioned": "Środowisko miało zostać uruchomione, ale żadnego jeszcze nie zapisano.",
5876
+ "infraless": "Ta usługa nie deklaruje własnego środowiska, więc nic nie zostało uruchomione."
5877
+ }
5878
+ },
5850
5879
  "checks": {
5851
5880
  "title": "Sprawdzenia",
5852
5881
  "row": "{kind}: {state}",
@@ -1446,6 +1446,7 @@
1446
1446
  "transportUnsupported": "kullanılamadı: bu adımın çalıştığı ajan CLI'si bu türden bir sunucuya erişemiyor.",
1447
1447
  "missingSecret": "kullanılamadı: ihtiyaç duyduğu kimlik bilgisi bu pano için ayarlanmamış.",
1448
1448
  "reservedSecret": "kullanılamadı: platformun kendi yapılandırmasına ait bir değişken istiyor, bu yüzden bildirimin değişmesi gerekiyor.",
1449
+ "unusableSecret": "kullanılamadı: bildirdiği bir kimlik bilgisi ona ulaşamıyor, bu yüzden sunucu kimlik doğrulaması olmadan çalışacaktı.",
1449
1450
  "oauthNotConnected": "kullanılamadı: bu panoyu henüz kimse ona bağlamadı.",
1450
1451
  "oauthTokenFailed": "kullanılamadı: bağlantı artık erişim jetonu üretmiyor.",
1451
1452
  "overBudget": "kullanılamadı: bu ajan tek bir çalıştırmanın taşıdığından fazla araç sunucusu bildiriyor.",
@@ -1456,6 +1457,7 @@
1456
1457
  "transportUnsupported": "Onun için bir stdio sunucusu bildirin ya da adımı HTTP sunucularına erişen bir ajan CLI'sinde çalıştırın.",
1457
1458
  "missingSecret": "Adı geçen kimlik bilgisini dağıtımın ortam değişkeni olarak ya da Altyapı penceresindeki yetenek kimlik bilgilerinde ayarlayın.",
1458
1459
  "reservedSecret": "Bildirimi başka bir anahtar isteyecek şekilde değiştirin; o değişkeni ayarlamak tam da yardımcı olmayacak şeydir.",
1460
+ "unusableSecret": "Kurulumun kodundaki bildirimi düzeltin: uzak bir sunucunun kimlik bilgisi bir başlıkta taşınır, yerel olanınki sunucunun sürecine enjekte edilir.",
1459
1461
  "oauthNotConnected": "Bu panoyu Altyapı penceresinden ona bağlayın. ENCRYPTION_KEY olmayan bir dağıtımda izni saklayacak bir yer yoktur, bu yüzden önce bir operatörün bunu ayarlaması gerekir.",
1460
1462
  "oauthTokenFailed": "Altyapı penceresinden yeniden bağlayın ya da sağlayıcının kesintisinin geçmesini bekleyin.",
1461
1463
  "overBudget": "Tek bir çalıştırma hepsini taşıyabilsin diye ajanın bildirdiklerini kısaltın."
@@ -3228,6 +3230,7 @@
3228
3230
  "ok": "Yanıt verdi",
3229
3231
  "credentialsMissing": "Kimlik bilgisi yok",
3230
3232
  "credentialRefused": "Kimlik bilgisi reddedildi",
3233
+ "credentialUnusable": "Kimlik bilgisi gönderilemiyor",
3231
3234
  "oauthNotConnected": "Bağlı değil",
3232
3235
  "oauthTokenFailed": "Bağlantı çalışmayı bıraktı",
3233
3236
  "unreachable": "Yanıt yok",
@@ -3241,6 +3244,7 @@
3241
3244
  "allowedToolsUnchecked": "Araç listesi tümüyle okunacak kadar kısa değildi, bu yüzden sınırlanan adlar denetlenemedi.",
3242
3245
  "unresolvedCredentials": "{keys} için hiçbir değer çözülmedi. Aşağıda doldurun ya da kurulumun ortamında tanımlayın.",
3243
3246
  "refusedCredentials": "{keys}, platformun kendi yapılandırmasına ait bir değişkeni adlandırıyor, bu yüzden asla çözülmez. Kurulumun kodundaki bildirimi değiştirin.",
3247
+ "unusableCredentials": "{keys} hiçbir başlık adlandırmıyor, bu yüzden bir HTTP sunucusuna asla ulaşmaz. Kurulumun kodunda, sunucunun kimlik doğrulamasında kullandığı başlığı ekleyin.",
3244
3248
  "httpStatus": "HTTP {status}",
3245
3249
  "showDetails": "Ayrıntıları göster",
3246
3250
  "hideDetails": "Ayrıntıları gizle",
@@ -5847,6 +5851,31 @@
5847
5851
  "none_captured": "Arayüzün yakalanması gerekiyordu ama hiçbir görünüm yakalanmadı."
5848
5852
  }
5849
5853
  },
5854
+ "environments": {
5855
+ "title": "Canlı ortam",
5856
+ "open": "Canlı ortamı aç",
5857
+ "retained": "Bu ortamın çalıştırma bittikten sonra da kalması amaçlanıyor.",
5858
+ "expires": "{date} tarihinde sona eriyor",
5859
+ "expired": "{date} tarihinde süresi doldu",
5860
+ "state": {
5861
+ "live": "Canlı",
5862
+ "provisioning": "Ayağa kalkıyor",
5863
+ "failed": "Hiç ayağa kalkmadı",
5864
+ "reclaiming": "Kaldırılıyor",
5865
+ "reclaimed": "Kaldırıldı",
5866
+ "expired": "Süresi doldu"
5867
+ },
5868
+ "origin": {
5869
+ "deployer": "Bu çalışma tarafından ayağa kaldırıldı",
5870
+ "human_test": "Elle yapılan test için ayağa kaldırıldı",
5871
+ "projected": "Çalışma sürüyor, bu yüzden bu durum değişebilir"
5872
+ },
5873
+ "gap": {
5874
+ "no_environment_step": "Bu hatta ortam ayağa kaldıran bir adım yok, açılacak bir şey de yok.",
5875
+ "not_provisioned": "Bir ortam ayağa kaldırılacaktı, ancak henüz hiçbiri kaydedilmedi.",
5876
+ "infraless": "Bu servis kendine ait bir ortam tanımlamıyor, bu yüzden hiçbir şey ayağa kaldırılmadı."
5877
+ }
5878
+ },
5850
5879
  "checks": {
5851
5880
  "title": "Denetimler",
5852
5881
  "row": "{kind}: {state}",
@@ -1446,6 +1446,7 @@
1446
1446
  "transportUnsupported": "був недоступний: CLI агента, на якому виконувався цей крок, не досягає сервера такого типу.",
1447
1447
  "missingSecret": "був недоступний: потрібні йому облікові дані не задані для цієї дошки.",
1448
1448
  "reservedSecret": "був недоступний: він просить змінну, що належить власній конфігурації платформи, тож потрібно змінити оголошення.",
1449
+ "unusableSecret": "був недоступний: оголошені облікові дані не можуть до нього дістатися, тож сервер працював би без автентифікації.",
1449
1450
  "oauthNotConnected": "був недоступний: цю дошку ще ніхто до нього не під’єднав.",
1450
1451
  "oauthTokenFailed": "був недоступний: з’єднання перестало видавати токен доступу.",
1451
1452
  "overBudget": "був недоступний: цей агент оголошує більше серверів інструментів, ніж несе один запуск.",
@@ -1456,6 +1457,7 @@
1456
1457
  "transportUnsupported": "Оголосіть для нього сервер stdio або виконайте крок на CLI агента, що досягає серверів HTTP.",
1457
1458
  "missingSecret": "Задайте названі облікові дані або як змінну середовища розгортання, або в облікових даних можливостей у вікні інфраструктури.",
1458
1459
  "reservedSecret": "Змініть оголошення так, щоб воно просило інший ключ; задати цю змінну це саме те, що не допоможе.",
1460
+ "unusableSecret": "Виправте оголошення в коді інсталяції: облікові дані віддаленого сервера їдуть у заголовку, а локального вставляються у процес сервера.",
1459
1461
  "oauthNotConnected": "Під’єднайте цю дошку до нього у вікні інфраструктури. Розгортання без ENCRYPTION_KEY не має де зберігати дозвіл, тож оператор має спершу задати його.",
1460
1462
  "oauthTokenFailed": "Під’єднайте його заново у вікні інфраструктури або перечекайте збій постачальника.",
1461
1463
  "overBudget": "Скоротіть те, що оголошує агент, щоб один запуск ніс усе."
@@ -3087,6 +3089,7 @@
3087
3089
  "ok": "Відповів",
3088
3090
  "credentialsMissing": "Немає облікових даних",
3089
3091
  "credentialRefused": "Облікові дані відхилено",
3092
+ "credentialUnusable": "Облікові дані неможливо надіслати",
3090
3093
  "oauthNotConnected": "Не під’єднано",
3091
3094
  "oauthTokenFailed": "З’єднання перестало працювати",
3092
3095
  "unreachable": "Немає відповіді",
@@ -3100,6 +3103,7 @@
3100
3103
  "allowedToolsUnchecked": "Список інструментів був завеликий, щоб прочитати його повністю, тож звужені назви перевірити не вдалося.",
3101
3104
  "unresolvedCredentials": "Для {keys} нічого не розв’язано. Введіть значення нижче або задайте його в середовищі інсталяції.",
3102
3105
  "refusedCredentials": "{keys} називає змінну, що належить власній конфігурації платформи, тож вона ніколи не розв’язується. Змініть оголошення в коді інсталяції.",
3106
+ "unusableCredentials": "{keys} не називає жодного заголовка, тож HTTP-сервер ніколи його не отримає. Додайте в коді інсталяції заголовок, яким сервер автентифікується.",
3103
3107
  "httpStatus": "HTTP {status}",
3104
3108
  "showDetails": "Показати деталі",
3105
3109
  "hideDetails": "Сховати деталі",
@@ -5847,6 +5851,31 @@
5847
5851
  "none_captured": "Інтерфейс мали зняти, але жодного екрана не збережено."
5848
5852
  }
5849
5853
  },
5854
+ "environments": {
5855
+ "title": "Робоче середовище",
5856
+ "open": "Відкрити робоче середовище",
5857
+ "retained": "Це середовище має існувати й після завершення запуску.",
5858
+ "expires": "Діє до {date}",
5859
+ "expired": "Термін дії минув {date}",
5860
+ "state": {
5861
+ "live": "Працює",
5862
+ "provisioning": "Розгортається",
5863
+ "failed": "Так і не запустилося",
5864
+ "reclaiming": "Згортається",
5865
+ "reclaimed": "Згорнуто",
5866
+ "expired": "Термін вичерпано"
5867
+ },
5868
+ "origin": {
5869
+ "deployer": "Розгорнуто цим запуском",
5870
+ "human_test": "Розгорнуто для ручного тестування",
5871
+ "projected": "Запуск ще триває, тож це може змінитися"
5872
+ },
5873
+ "gap": {
5874
+ "no_environment_step": "У цьому конвеєрі ніщо не розгортає середовище, тож відкривати нічого.",
5875
+ "not_provisioned": "Середовище мало розгорнутися, але поки що не зафіксовано жодного.",
5876
+ "infraless": "Ця служба не оголошує власного середовища, тож нічого не розгорталося."
5877
+ }
5878
+ },
5850
5879
  "checks": {
5851
5880
  "title": "Перевірки",
5852
5881
  "row": "{kind}: {state}",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/app",
3
- "version": "0.258.1",
3
+ "version": "0.259.1",
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.41",
42
42
  "wretch": "^3.0.9",
43
- "@cat-factory/contracts": "0.287.0"
43
+ "@cat-factory/contracts": "0.289.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@toad-contracts/testing": "0.3.2",