@cat-factory/app 0.77.0 → 0.78.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/IntegrationsHub.vue +23 -0
- package/app/components/panels/AgentStepDetail.vue +41 -0
- package/app/components/panels/inspector/FrontendBindingsResolved.vue +111 -0
- package/app/components/panels/inspector/FrontendConfig.vue +8 -0
- package/app/components/settings/PackageRegistriesPanel.vue +222 -0
- package/app/composables/api/environments.ts +10 -0
- package/app/composables/api/packageRegistries.ts +24 -0
- package/app/composables/useApi.ts +4 -0
- package/app/pages/index.vue +4 -0
- package/app/stores/environments.ts +52 -0
- package/app/stores/packageRegistries.ts +66 -0
- package/app/stores/ui.ts +13 -0
- package/app/types/domain.ts +2 -0
- package/app/types/packageRegistries.ts +13 -0
- package/i18n/locales/en.json +36 -0
- package/i18n/locales/es.json +36 -0
- package/i18n/locales/fr.json +36 -0
- package/i18n/locales/he.json +36 -0
- package/i18n/locales/ja.json +36 -0
- package/i18n/locales/pl.json +36 -0
- package/i18n/locales/tr.json +36 -0
- package/i18n/locales/uk.json +36 -0
- package/package.json +2 -2
|
@@ -20,6 +20,7 @@ const documents = useDocumentsStore()
|
|
|
20
20
|
const tasks = useTasksStore()
|
|
21
21
|
const tracker = useTrackerStore()
|
|
22
22
|
const releaseHealth = useReleaseHealthStore()
|
|
23
|
+
const packageRegistries = usePackageRegistriesStore()
|
|
23
24
|
const userSecrets = useUserSecretsStore()
|
|
24
25
|
const apiKeys = useApiKeysStore()
|
|
25
26
|
const workspace = useWorkspaceStore()
|
|
@@ -49,6 +50,7 @@ watch(
|
|
|
49
50
|
if (isOpen) {
|
|
50
51
|
query.value = ''
|
|
51
52
|
void releaseHealth.ensureLoaded().catch(() => {})
|
|
53
|
+
void packageRegistries.ensureLoaded().catch(() => {})
|
|
52
54
|
void userSecrets.load().catch(() => {})
|
|
53
55
|
// Drives the OpenRouter row's "Key connected" badge.
|
|
54
56
|
if (workspace.workspaceId) void apiKeys.load(workspace.workspaceId).catch(() => {})
|
|
@@ -256,6 +258,27 @@ const groups = computed<IntegrationGroup[]>(() => {
|
|
|
256
258
|
})
|
|
257
259
|
}
|
|
258
260
|
|
|
261
|
+
// --- Development (private package registries) -------------------------------
|
|
262
|
+
// Gated like observability: hidden until a probe confirms the module is wired
|
|
263
|
+
// (`available === true`), so an unconfigured backend doesn't show a dead row.
|
|
264
|
+
if (packageRegistries.available) {
|
|
265
|
+
const hasEntries = packageRegistries.entries.length > 0
|
|
266
|
+
out.push({
|
|
267
|
+
title: t('layout.integrationsHub.groups.development'),
|
|
268
|
+
items: [
|
|
269
|
+
{
|
|
270
|
+
key: 'package-registries',
|
|
271
|
+
icon: 'i-lucide-package',
|
|
272
|
+
label: t('layout.integrationsHub.items.packageRegistries.label'),
|
|
273
|
+
description: t('layout.integrationsHub.items.packageRegistries.description'),
|
|
274
|
+
status: hasEntries ? t('layout.integrationsHub.status.connected') : undefined,
|
|
275
|
+
connected: hasEntries,
|
|
276
|
+
onClick: () => go(ui.openPackageRegistries),
|
|
277
|
+
},
|
|
278
|
+
],
|
|
279
|
+
})
|
|
280
|
+
}
|
|
281
|
+
|
|
259
282
|
// NOTE: Infrastructure (agent-container execution + Tester environments + the local-mode
|
|
260
283
|
// warm pool/checkout) is no longer listed here — it moved to its OWN top-level navbar menu
|
|
261
284
|
// (SideBar → "Infrastructure" → the tabbed Infrastructure window). See `ui.openInfrastructure`.
|
|
@@ -7,6 +7,8 @@ import StepRestartControl from '~/components/panels/StepRestartControl.vue'
|
|
|
7
7
|
import StepMetadataCard from '~/components/panels/StepMetadataCard.vue'
|
|
8
8
|
import StepTestReport from '~/components/panels/StepTestReport.vue'
|
|
9
9
|
import EnvironmentStatusPanel from '~/components/environments/EnvironmentStatusPanel.vue'
|
|
10
|
+
import FrontendBindingsResolved from '~/components/panels/inspector/FrontendBindingsResolved.vue'
|
|
11
|
+
import { UI_TESTER_AGENT_KIND } from '@cat-factory/contracts'
|
|
10
12
|
import ProvisioningLogsDrawer from '~/components/provisioning/ProvisioningLogsDrawer.vue'
|
|
11
13
|
import IterationCapPrompt from '~/components/pipeline/IterationCapPrompt.vue'
|
|
12
14
|
import { useStepTimer } from '~/composables/useStepTimer'
|
|
@@ -58,6 +60,24 @@ const testPhase = computed(() => step.value?.test ?? null)
|
|
|
58
60
|
// coder consume it), so the panel shows its spinning-up/running/shutdown/errored state.
|
|
59
61
|
const stepEnvironment = computed(() => step.value?.environment ?? null)
|
|
60
62
|
|
|
63
|
+
// For a frontend UI-test step (`tester-ui`): the enclosing `frontend` frame's backend-binding
|
|
64
|
+
// config, so the detail can project how each env var resolved (live URL | mocked) — rendered from
|
|
65
|
+
// the FROZEN bindings the engine stamped on the run (`instance.frontendBindings`), so a finished
|
|
66
|
+
// run shows what it actually drove against rather than re-resolving against current live state.
|
|
67
|
+
const frontendFrame = computed(() => (block.value ? board.serviceOf(block.value) : undefined))
|
|
68
|
+
const isFrontendFrame = computed(() => frontendFrame.value?.type === 'frontend')
|
|
69
|
+
const frontendConfig = computed(() =>
|
|
70
|
+
step.value?.agentKind === UI_TESTER_AGENT_KIND && isFrontendFrame.value
|
|
71
|
+
? (frontendFrame.value!.frontendConfig ?? null)
|
|
72
|
+
: null,
|
|
73
|
+
)
|
|
74
|
+
// The frozen start-time resolution the tester ran against (absent for a non-frontend / pre-6b run).
|
|
75
|
+
const frontendBindings = computed(() => instance.value?.frontendBindings ?? [])
|
|
76
|
+
// The run-start advisories the engine stamped on the run (duplicate env vars / partially-mocked
|
|
77
|
+
// services) are a whole-RUN fact, so surface them on ANY step detail of a frontend-frame run, not
|
|
78
|
+
// only the `tester-ui` step — a duplicate-env-var note shouldn't be invisible from the coder step.
|
|
79
|
+
const runNotes = computed(() => (isFrontendFrame.value ? (instance.value?.notes ?? []) : []))
|
|
80
|
+
|
|
61
81
|
// The run's infrastructure attempts (container/runner/env spin-up + tear-down), behind
|
|
62
82
|
// a toggle. This is the surface that makes the per-run `container` log rows + the
|
|
63
83
|
// executionId filter visible — most useful when the run failed to start a container.
|
|
@@ -345,6 +365,27 @@ async function copyOutput() {
|
|
|
345
365
|
errored + the exact error), when this step runs against one -->
|
|
346
366
|
<EnvironmentStatusPanel v-if="stepEnvironment" :environment="stepEnvironment" />
|
|
347
367
|
|
|
368
|
+
<!-- frontend UI-test: how the frame's backend bindings resolved (env var →
|
|
369
|
+
live URL | mocked) + the run-start advisories (duplicate env vars /
|
|
370
|
+
partially-mocked services) the engine stamped on the run. Rendered from the
|
|
371
|
+
FROZEN start-time bindings so a finished run shows what it actually drove
|
|
372
|
+
against, not a live re-resolution. -->
|
|
373
|
+
<FrontendBindingsResolved
|
|
374
|
+
v-if="frontendConfig"
|
|
375
|
+
:config="frontendConfig"
|
|
376
|
+
:resolved="frontendBindings"
|
|
377
|
+
/>
|
|
378
|
+
<ul v-if="runNotes.length" class="space-y-1" data-testid="run-notes">
|
|
379
|
+
<li
|
|
380
|
+
v-for="(note, i) in runNotes"
|
|
381
|
+
:key="i"
|
|
382
|
+
class="flex items-start gap-1.5 text-[11px] leading-snug text-amber-300/80"
|
|
383
|
+
>
|
|
384
|
+
<UIcon name="i-lucide-info" class="mt-0.5 h-3.5 w-3.5 shrink-0" />
|
|
385
|
+
<span>{{ note }}</span>
|
|
386
|
+
</li>
|
|
387
|
+
</ul>
|
|
388
|
+
|
|
348
389
|
<!-- this run's infrastructure attempts (container/runner/env spin-up +
|
|
349
390
|
tear-down): the surface for the per-run container log rows + the exact
|
|
350
391
|
provider error, behind a toggle (most useful on a failed-to-start run) -->
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, onMounted } from 'vue'
|
|
3
|
+
import {
|
|
4
|
+
duplicateBindingEnvVars,
|
|
5
|
+
resolveFrontendBindings,
|
|
6
|
+
type FrontendBackendBinding,
|
|
7
|
+
type FrontendConfig,
|
|
8
|
+
type ResolvedFrontendBinding,
|
|
9
|
+
} from '@cat-factory/contracts'
|
|
10
|
+
|
|
11
|
+
// The resolution of a frontend frame's backend bindings — each env var → a bound service's live
|
|
12
|
+
// ephemeral URL, or WireMock. Two modes, same view:
|
|
13
|
+
// - **Live** (frame inspector, `resolved` omitted): resolves against the workspace's CURRENT env
|
|
14
|
+
// handles (fetched once via the environments store), so the operator sees how a run would
|
|
15
|
+
// resolve RIGHT NOW. Feeds the SAME pure helpers the backend uses so it can't drift.
|
|
16
|
+
// - **Projected** (`tester-ui` run/step detail, `resolved` provided): renders the FROZEN
|
|
17
|
+
// start-time bindings the engine stamped on the run, so a finished run shows what it ACTUALLY
|
|
18
|
+
// drove against — truthful even after the underlying envs are torn down (no live re-read).
|
|
19
|
+
// Also surfaces the duplicate-env-var misconfiguration in live mode (projected mode leaves that to
|
|
20
|
+
// the run-start note, which owns the frozen advisory).
|
|
21
|
+
const props = defineProps<{ config: FrontendConfig; resolved?: ResolvedFrontendBinding[] }>()
|
|
22
|
+
|
|
23
|
+
const environments = useEnvironmentsStore()
|
|
24
|
+
const board = useBoardStore()
|
|
25
|
+
const { t } = useI18n()
|
|
26
|
+
|
|
27
|
+
const projected = computed(() => props.resolved !== undefined)
|
|
28
|
+
|
|
29
|
+
// Live mode refreshes the env handles when this view opens so a just-provisioned service shows as
|
|
30
|
+
// live; a projected snapshot needs no live read.
|
|
31
|
+
onMounted(() => {
|
|
32
|
+
if (!projected.value) void environments.load()
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// The duplicate advisory is config-derived; in projected mode the run-start note owns it (frozen
|
|
36
|
+
// at start), so don't re-derive it here against a possibly-since-edited config.
|
|
37
|
+
const duplicates = computed(() => (projected.value ? [] : duplicateBindingEnvVars(props.config)))
|
|
38
|
+
|
|
39
|
+
// Each resolved binding + the display metadata a bare {envVar, serviceUrl} can't carry: whether
|
|
40
|
+
// a mocked upstream was a `mock` source or a `service` with no live env, and the bound service's
|
|
41
|
+
// title. Joined off the LAST config binding per envVar (matching `resolveFrontendBindings`'
|
|
42
|
+
// last-wins dedup), so the extra labels stay in step with the canonical resolution.
|
|
43
|
+
const rows = computed(() => {
|
|
44
|
+
const resolved =
|
|
45
|
+
props.resolved ??
|
|
46
|
+
resolveFrontendBindings(props.config, environments.liveServiceEnvUrls(props.config))
|
|
47
|
+
const lastByEnvVar = new Map<string, FrontendBackendBinding>()
|
|
48
|
+
for (const b of props.config.backendBindings) {
|
|
49
|
+
const key = b.envVar.trim()
|
|
50
|
+
if (key) lastByEnvVar.set(key, b)
|
|
51
|
+
}
|
|
52
|
+
return resolved.map((r) => {
|
|
53
|
+
const source = lastByEnvVar.get(r.envVar)?.source
|
|
54
|
+
const serviceFrameId = source?.kind === 'service' ? source.serviceBlockId : undefined
|
|
55
|
+
return {
|
|
56
|
+
envVar: r.envVar,
|
|
57
|
+
serviceUrl: r.serviceUrl,
|
|
58
|
+
kind: r.serviceUrl ? 'live' : source?.kind === 'service' ? 'service-offline' : 'mock',
|
|
59
|
+
serviceTitle: serviceFrameId
|
|
60
|
+
? (board.getBlock(serviceFrameId)?.title ?? serviceFrameId)
|
|
61
|
+
: undefined,
|
|
62
|
+
} as const
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<template>
|
|
68
|
+
<div v-if="rows.length || duplicates.length" class="space-y-1.5" data-testid="frontend-resolved">
|
|
69
|
+
<div class="text-[11px] font-semibold uppercase tracking-wide text-slate-500">
|
|
70
|
+
{{ t('inspector.frontendConfig.resolved.title') }}
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<p
|
|
74
|
+
v-if="duplicates.length"
|
|
75
|
+
class="text-[11px] leading-snug text-amber-300/80"
|
|
76
|
+
data-testid="frontend-resolved-duplicates"
|
|
77
|
+
>
|
|
78
|
+
{{ t('inspector.frontendConfig.resolved.duplicateWarning', { vars: duplicates.join(', ') }) }}
|
|
79
|
+
</p>
|
|
80
|
+
|
|
81
|
+
<ul v-if="rows.length" class="space-y-0.5">
|
|
82
|
+
<li
|
|
83
|
+
v-for="row in rows"
|
|
84
|
+
:key="row.envVar"
|
|
85
|
+
class="flex items-baseline gap-1.5 text-[11px] leading-snug"
|
|
86
|
+
data-testid="frontend-resolved-row"
|
|
87
|
+
>
|
|
88
|
+
<span
|
|
89
|
+
class="mt-1 h-1.5 w-1.5 shrink-0 rounded-full"
|
|
90
|
+
:class="{
|
|
91
|
+
'bg-emerald-400': row.kind === 'live',
|
|
92
|
+
'bg-amber-400': row.kind === 'service-offline',
|
|
93
|
+
'bg-slate-500': row.kind === 'mock',
|
|
94
|
+
}"
|
|
95
|
+
/>
|
|
96
|
+
<span class="font-mono text-slate-300">{{ row.envVar }}</span>
|
|
97
|
+
<span class="text-slate-600">→</span>
|
|
98
|
+
<template v-if="row.kind === 'live'">
|
|
99
|
+
<span class="truncate font-mono text-emerald-300/90">{{ row.serviceUrl }}</span>
|
|
100
|
+
<span v-if="row.serviceTitle" class="text-slate-500">({{ row.serviceTitle }})</span>
|
|
101
|
+
</template>
|
|
102
|
+
<span v-else-if="row.kind === 'service-offline'" class="text-amber-300/80">
|
|
103
|
+
{{ t('inspector.frontendConfig.resolved.serviceOffline', { service: row.serviceTitle }) }}
|
|
104
|
+
</span>
|
|
105
|
+
<span v-else class="text-slate-500">
|
|
106
|
+
{{ t('inspector.frontendConfig.resolved.mock') }}
|
|
107
|
+
</span>
|
|
108
|
+
</li>
|
|
109
|
+
</ul>
|
|
110
|
+
</div>
|
|
111
|
+
</template>
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
FrontendServeMode,
|
|
11
11
|
PreviewStatus,
|
|
12
12
|
} from '~/types/domain'
|
|
13
|
+
import FrontendBindingsResolved from '~/components/panels/inspector/FrontendBindingsResolved.vue'
|
|
13
14
|
|
|
14
15
|
// Frontend-frame (`type: 'frontend'`) configuration: how to build, serve, and mock this
|
|
15
16
|
// frontend for a self-contained UI test (+ an optional browsable preview on local/node),
|
|
@@ -625,6 +626,13 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
625
626
|
<div v-else class="text-[11px] text-slate-500">
|
|
626
627
|
{{ t('inspector.frontendConfig.bindings.empty') }}
|
|
627
628
|
</div>
|
|
629
|
+
|
|
630
|
+
<!-- How the bindings resolve RIGHT NOW: each env var → a bound service's live ephemeral
|
|
631
|
+
URL, or WireMock — plus the duplicate-env-var warning. The same view a UI-test run
|
|
632
|
+
would resolve against (shared helpers), so what you see is what a run will drive. -->
|
|
633
|
+
<div class="border-t border-slate-800/60 pt-2">
|
|
634
|
+
<FrontendBindingsResolved :config="config" />
|
|
635
|
+
</div>
|
|
628
636
|
</div>
|
|
629
637
|
</div>
|
|
630
638
|
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// Private package registries — the workspace's npm-registry entries (npm private
|
|
3
|
+
// orgs, GitHub Packages) that agent containers use to resolve private dependencies
|
|
4
|
+
// on checkout. Tokens are write-only: the list renders from the redacted summary
|
|
5
|
+
// (vendor + scopes + token tail) and an entry is edited by deleting + re-adding.
|
|
6
|
+
// Opened from the Integrations hub.
|
|
7
|
+
import { computed, reactive, ref, watch } from 'vue'
|
|
8
|
+
import type { PackageRegistryVendor } from '~/types/packageRegistries'
|
|
9
|
+
import IntegrationBackTitle from '~/components/layout/IntegrationBackTitle.vue'
|
|
10
|
+
|
|
11
|
+
const { t } = useI18n()
|
|
12
|
+
const ui = useUiStore()
|
|
13
|
+
const store = usePackageRegistriesStore()
|
|
14
|
+
const toast = useToast()
|
|
15
|
+
const { confirmAction, toastDone } = useConfirmAction()
|
|
16
|
+
|
|
17
|
+
const open = computed({
|
|
18
|
+
get: () => ui.packageRegistriesOpen,
|
|
19
|
+
set: (v: boolean) => (v ? ui.openPackageRegistries() : ui.closePackageRegistries()),
|
|
20
|
+
})
|
|
21
|
+
const back = useIntegrationBack(open)
|
|
22
|
+
|
|
23
|
+
// The registry vendors a workspace can connect. Fixed set — the host derives from the
|
|
24
|
+
// vendor server-side, so it renders read-only here. Vendor names stay verbatim.
|
|
25
|
+
const VENDORS: { value: PackageRegistryVendor; label: string; host: string }[] = [
|
|
26
|
+
{ value: 'npmjs', label: 'npm (npmjs.com)', host: 'registry.npmjs.org' },
|
|
27
|
+
{ value: 'github-packages', label: 'GitHub Packages', host: 'npm.pkg.github.com' },
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
const form = reactive({
|
|
31
|
+
vendor: 'npmjs' as PackageRegistryVendor,
|
|
32
|
+
scopes: '',
|
|
33
|
+
token: '',
|
|
34
|
+
})
|
|
35
|
+
const busy = ref(false)
|
|
36
|
+
|
|
37
|
+
const vendorHost = computed(() => VENDORS.find((v) => v.value === form.vendor)?.host ?? '')
|
|
38
|
+
|
|
39
|
+
function vendorLabel(vendor: PackageRegistryVendor): string {
|
|
40
|
+
return VENDORS.find((v) => v.value === vendor)?.label ?? vendor
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Parse the comma/space-separated scopes input into `@org` entries. */
|
|
44
|
+
const parsedScopes = computed(() =>
|
|
45
|
+
form.scopes
|
|
46
|
+
.split(/[\s,]+/)
|
|
47
|
+
.map((s) => s.trim())
|
|
48
|
+
.filter(Boolean)
|
|
49
|
+
.map((s) => (s.startsWith('@') ? s : `@${s}`)),
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
function notifyError(title: string, e: unknown) {
|
|
53
|
+
toast.add({
|
|
54
|
+
title,
|
|
55
|
+
description: e instanceof Error ? e.message : String(e),
|
|
56
|
+
icon: 'i-lucide-triangle-alert',
|
|
57
|
+
color: 'error',
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
watch(
|
|
62
|
+
open,
|
|
63
|
+
async (isOpen) => {
|
|
64
|
+
if (!isOpen) return
|
|
65
|
+
try {
|
|
66
|
+
await store.ensureLoaded()
|
|
67
|
+
} catch (e) {
|
|
68
|
+
notifyError(t('settings.packageRegistries.toast.loadFailed'), e)
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{ immediate: true },
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
async function addEntry() {
|
|
75
|
+
busy.value = true
|
|
76
|
+
try {
|
|
77
|
+
await store.add({
|
|
78
|
+
ecosystem: 'npm',
|
|
79
|
+
vendor: form.vendor,
|
|
80
|
+
scopes: parsedScopes.value,
|
|
81
|
+
token: form.token.trim(),
|
|
82
|
+
})
|
|
83
|
+
form.scopes = ''
|
|
84
|
+
form.token = ''
|
|
85
|
+
toast.add({
|
|
86
|
+
title: t('settings.packageRegistries.toast.added'),
|
|
87
|
+
icon: 'i-lucide-check',
|
|
88
|
+
color: 'success',
|
|
89
|
+
})
|
|
90
|
+
} catch (e) {
|
|
91
|
+
notifyError(t('settings.packageRegistries.toast.addFailed'), e)
|
|
92
|
+
} finally {
|
|
93
|
+
busy.value = false
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function removeEntry(entryId: string) {
|
|
98
|
+
const noun = t('settings.packageRegistries.entryNoun')
|
|
99
|
+
if (!(await confirmAction('remove', noun))) return
|
|
100
|
+
busy.value = true
|
|
101
|
+
try {
|
|
102
|
+
await store.remove(entryId)
|
|
103
|
+
toastDone('remove', noun)
|
|
104
|
+
} catch (e) {
|
|
105
|
+
notifyError(t('settings.packageRegistries.toast.removeFailed'), e)
|
|
106
|
+
} finally {
|
|
107
|
+
busy.value = false
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
</script>
|
|
111
|
+
|
|
112
|
+
<template>
|
|
113
|
+
<UModal
|
|
114
|
+
v-model:open="open"
|
|
115
|
+
:title="t('settings.packageRegistries.title')"
|
|
116
|
+
:ui="{ content: 'max-w-lg' }"
|
|
117
|
+
>
|
|
118
|
+
<template #title>
|
|
119
|
+
<IntegrationBackTitle :title="t('settings.packageRegistries.title')" @back="back" />
|
|
120
|
+
</template>
|
|
121
|
+
<template #body>
|
|
122
|
+
<div class="space-y-4" data-testid="package-registries-panel">
|
|
123
|
+
<p class="text-sm text-slate-400">
|
|
124
|
+
{{ t('settings.packageRegistries.intro') }}
|
|
125
|
+
</p>
|
|
126
|
+
|
|
127
|
+
<section
|
|
128
|
+
v-if="store.entries.length"
|
|
129
|
+
class="space-y-2 rounded-lg border border-slate-700 p-3"
|
|
130
|
+
>
|
|
131
|
+
<h3 class="text-sm font-semibold">
|
|
132
|
+
{{ t('settings.packageRegistries.list.heading') }}
|
|
133
|
+
</h3>
|
|
134
|
+
<div
|
|
135
|
+
v-for="entry in store.entries"
|
|
136
|
+
:key="entry.id"
|
|
137
|
+
class="flex items-center justify-between gap-2 rounded-md border border-slate-800 px-3 py-2"
|
|
138
|
+
>
|
|
139
|
+
<div class="min-w-0 space-y-1">
|
|
140
|
+
<div class="flex items-center gap-2">
|
|
141
|
+
<span class="text-sm font-medium">{{ vendorLabel(entry.vendor) }}</span>
|
|
142
|
+
<span class="text-[11px] text-slate-500">
|
|
143
|
+
{{ t('settings.packageRegistries.list.tokenTail', { tail: entry.tokenTail }) }}
|
|
144
|
+
</span>
|
|
145
|
+
</div>
|
|
146
|
+
<div class="flex flex-wrap gap-1">
|
|
147
|
+
<UBadge
|
|
148
|
+
v-for="scope in entry.scopes"
|
|
149
|
+
:key="scope"
|
|
150
|
+
color="neutral"
|
|
151
|
+
variant="soft"
|
|
152
|
+
size="sm"
|
|
153
|
+
>
|
|
154
|
+
{{ scope }}
|
|
155
|
+
</UBadge>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
<UButton
|
|
159
|
+
color="error"
|
|
160
|
+
variant="ghost"
|
|
161
|
+
icon="i-lucide-trash-2"
|
|
162
|
+
size="sm"
|
|
163
|
+
:loading="busy"
|
|
164
|
+
:data-testid="`package-registry-delete-${entry.id}`"
|
|
165
|
+
:aria-label="t('settings.packageRegistries.list.remove')"
|
|
166
|
+
@click="removeEntry(entry.id)"
|
|
167
|
+
/>
|
|
168
|
+
</div>
|
|
169
|
+
</section>
|
|
170
|
+
|
|
171
|
+
<section class="space-y-3 rounded-lg border border-slate-700 p-3">
|
|
172
|
+
<h3 class="text-sm font-semibold">
|
|
173
|
+
{{ t('settings.packageRegistries.add.heading') }}
|
|
174
|
+
</h3>
|
|
175
|
+
|
|
176
|
+
<UFormField :label="t('settings.packageRegistries.add.vendor')">
|
|
177
|
+
<USelect
|
|
178
|
+
v-model="form.vendor"
|
|
179
|
+
:items="VENDORS"
|
|
180
|
+
value-key="value"
|
|
181
|
+
class="w-full"
|
|
182
|
+
data-testid="package-registry-vendor"
|
|
183
|
+
/>
|
|
184
|
+
</UFormField>
|
|
185
|
+
<p class="text-[11px] text-slate-500">
|
|
186
|
+
{{ t('settings.packageRegistries.add.host', { host: vendorHost }) }}
|
|
187
|
+
</p>
|
|
188
|
+
|
|
189
|
+
<UFormField
|
|
190
|
+
:label="t('settings.packageRegistries.add.scopes')"
|
|
191
|
+
:help="t('settings.packageRegistries.add.scopesHelp')"
|
|
192
|
+
>
|
|
193
|
+
<UInput
|
|
194
|
+
v-model="form.scopes"
|
|
195
|
+
placeholder="@my-org, @my-other-org"
|
|
196
|
+
class="w-full"
|
|
197
|
+
data-testid="package-registry-scopes"
|
|
198
|
+
/>
|
|
199
|
+
</UFormField>
|
|
200
|
+
|
|
201
|
+
<UFormField :label="t('settings.packageRegistries.add.token')">
|
|
202
|
+
<UInput
|
|
203
|
+
v-model="form.token"
|
|
204
|
+
type="password"
|
|
205
|
+
class="w-full"
|
|
206
|
+
data-testid="package-registry-token"
|
|
207
|
+
/>
|
|
208
|
+
</UFormField>
|
|
209
|
+
|
|
210
|
+
<UButton
|
|
211
|
+
:loading="busy"
|
|
212
|
+
:disabled="!parsedScopes.length || !form.token.trim()"
|
|
213
|
+
data-testid="package-registry-save"
|
|
214
|
+
@click="addEntry"
|
|
215
|
+
>
|
|
216
|
+
{{ t('settings.packageRegistries.add.save') }}
|
|
217
|
+
</UButton>
|
|
218
|
+
</section>
|
|
219
|
+
</div>
|
|
220
|
+
</template>
|
|
221
|
+
</UModal>
|
|
222
|
+
</template>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { listEnvironmentsContract } from '@cat-factory/contracts'
|
|
2
|
+
import type { ApiContext } from './context'
|
|
3
|
+
|
|
4
|
+
/** Ephemeral environments: the workspace's live env handles (used to resolve frontend bindings). */
|
|
5
|
+
export function environmentsApi({ send, ws }: ApiContext) {
|
|
6
|
+
return {
|
|
7
|
+
listEnvironments: (workspaceId: string) =>
|
|
8
|
+
send(listEnvironmentsContract, { pathPrefix: ws(workspaceId) }),
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addPackageRegistryContract,
|
|
3
|
+
deletePackageRegistryContract,
|
|
4
|
+
listPackageRegistriesContract,
|
|
5
|
+
} from '@cat-factory/contracts'
|
|
6
|
+
import type { AddPackageRegistryInput } from '~/types/packageRegistries'
|
|
7
|
+
import type { ApiContext } from './context'
|
|
8
|
+
|
|
9
|
+
/** Private package registries: the workspace's entries agent containers install with. */
|
|
10
|
+
export function packageRegistriesApi({ send, ws }: ApiContext) {
|
|
11
|
+
return {
|
|
12
|
+
listPackageRegistries: (workspaceId: string) =>
|
|
13
|
+
send(listPackageRegistriesContract, { pathPrefix: ws(workspaceId) }),
|
|
14
|
+
|
|
15
|
+
addPackageRegistry: (workspaceId: string, body: AddPackageRegistryInput) =>
|
|
16
|
+
send(addPackageRegistryContract, { pathPrefix: ws(workspaceId), body }),
|
|
17
|
+
|
|
18
|
+
deletePackageRegistry: (workspaceId: string, entryId: string) =>
|
|
19
|
+
send(deletePackageRegistryContract, {
|
|
20
|
+
pathPrefix: ws(workspaceId),
|
|
21
|
+
pathParams: { entryId },
|
|
22
|
+
}),
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -18,11 +18,13 @@ import { kaizenApi } from './api/kaizen'
|
|
|
18
18
|
import { localSettingsApi } from './api/localSettings'
|
|
19
19
|
import { modelsApi } from './api/models'
|
|
20
20
|
import { notificationsApi } from './api/notifications'
|
|
21
|
+
import { packageRegistriesApi } from './api/packageRegistries'
|
|
21
22
|
import { presetsApi } from './api/presets'
|
|
22
23
|
import { providerConnectionsApi } from './api/providerConnections'
|
|
23
24
|
import { provisioningLogsApi } from './api/provisioningLogs'
|
|
24
25
|
import { recurringApi } from './api/recurring'
|
|
25
26
|
import { previewApi } from './api/preview'
|
|
27
|
+
import { environmentsApi } from './api/environments'
|
|
26
28
|
import { releaseHealthApi } from './api/releaseHealth'
|
|
27
29
|
import { sandboxApi } from './api/sandbox'
|
|
28
30
|
import { reviewsApi } from './api/reviews'
|
|
@@ -112,7 +114,9 @@ export function useApi() {
|
|
|
112
114
|
...infraHandlersApi(ctx),
|
|
113
115
|
...provisioningLogsApi(ctx),
|
|
114
116
|
...releaseHealthApi(ctx),
|
|
117
|
+
...packageRegistriesApi(ctx),
|
|
115
118
|
...previewApi(ctx),
|
|
119
|
+
...environmentsApi(ctx),
|
|
116
120
|
...recurringApi(ctx),
|
|
117
121
|
...sandboxApi(ctx),
|
|
118
122
|
...githubApi(ctx),
|
package/app/pages/index.vue
CHANGED
|
@@ -85,6 +85,9 @@ const AccountSettingsPanel = defineAsyncComponent(
|
|
|
85
85
|
const ObservabilityConnectionPanel = defineAsyncComponent(
|
|
86
86
|
() => import('~/components/settings/ObservabilityConnectionPanel.vue'),
|
|
87
87
|
)
|
|
88
|
+
const PackageRegistriesPanel = defineAsyncComponent(
|
|
89
|
+
() => import('~/components/settings/PackageRegistriesPanel.vue'),
|
|
90
|
+
)
|
|
88
91
|
const InfrastructureWindow = defineAsyncComponent(
|
|
89
92
|
() => import('~/components/settings/InfrastructureWindow.vue'),
|
|
90
93
|
)
|
|
@@ -356,6 +359,7 @@ watch(
|
|
|
356
359
|
<WorkspaceSettingsPanel v-if="ui.workspaceSettingsOpen" />
|
|
357
360
|
<AccountSettingsPanel v-if="ui.accountSettingsOpen" />
|
|
358
361
|
<ObservabilityConnectionPanel v-if="ui.observabilityConnectionOpen" />
|
|
362
|
+
<PackageRegistriesPanel v-if="ui.packageRegistriesOpen" />
|
|
359
363
|
<InfrastructureWindow v-if="ui.infrastructureOpen" />
|
|
360
364
|
<ModelConfigurationPanel v-if="ui.modelConfigOpen" />
|
|
361
365
|
<LocalModelEndpointsPanel v-if="ui.localModelsOpen" />
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { defineStore } from 'pinia'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import {
|
|
4
|
+
boundServiceFrameIds,
|
|
5
|
+
indexLiveServiceEnvUrls,
|
|
6
|
+
type FrontendConfig,
|
|
7
|
+
} from '@cat-factory/contracts'
|
|
8
|
+
import type { EnvironmentHandle } from '~/types/domain'
|
|
9
|
+
import { useWorkspaceStore } from '~/stores/workspace'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The workspace's live ephemeral-environment handles, fetched on demand from
|
|
13
|
+
* `GET /workspaces/:ws/environments`. Used to resolve a `frontend` frame's backend bindings to
|
|
14
|
+
* their live service URLs (the SPA mirror of the backend's `AgentContextBuilder` resolution) — so
|
|
15
|
+
* the inspector and the run/step detail can show each `envVar → live URL | mocked` the SAME way a
|
|
16
|
+
* UI-test run would. Kept as a thin, load-on-open cache (no snapshot delivery, no self-poll):
|
|
17
|
+
* the callers refresh it when the frontend inspector / a UI-test step detail opens.
|
|
18
|
+
*/
|
|
19
|
+
export const useEnvironmentsStore = defineStore('environments', () => {
|
|
20
|
+
const api = useApi()
|
|
21
|
+
|
|
22
|
+
/** The last-fetched env handles for the current workspace. */
|
|
23
|
+
const handles = ref<EnvironmentHandle[]>([])
|
|
24
|
+
/** A load is in flight (drives an optional spinner). */
|
|
25
|
+
const loading = ref(false)
|
|
26
|
+
|
|
27
|
+
/** (Re)load the workspace's environment handles; failures leave the last-known list. */
|
|
28
|
+
async function load(): Promise<void> {
|
|
29
|
+
const ws = useWorkspaceStore()
|
|
30
|
+
loading.value = true
|
|
31
|
+
try {
|
|
32
|
+
handles.value = await api.listEnvironments(ws.requireId())
|
|
33
|
+
} catch {
|
|
34
|
+
// Transient: keep the last-known handles rather than blanking the resolved view.
|
|
35
|
+
} finally {
|
|
36
|
+
loading.value = false
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The live `serviceFrameId → url` map for exactly the service FRAMES a frontend config binds —
|
|
42
|
+
* the same newest-wins, ready-with-URL indexing the backend applies (`indexLiveServiceEnvUrls`),
|
|
43
|
+
* so the SPA's resolved-binding view can't drift from what a run would resolve.
|
|
44
|
+
*/
|
|
45
|
+
function liveServiceEnvUrls(
|
|
46
|
+
config: Pick<FrontendConfig, 'backendBindings'>,
|
|
47
|
+
): Map<string, string> {
|
|
48
|
+
return indexLiveServiceEnvUrls(handles.value, boundServiceFrameIds(config))
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return { handles, loading, load, liveServiceEnvUrls }
|
|
52
|
+
})
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { defineStore } from 'pinia'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import type { AddPackageRegistryInput, PackageRegistryEntryView } from '~/types/packageRegistries'
|
|
4
|
+
import { useWorkspaceStore } from '~/stores/workspace'
|
|
5
|
+
import { apiErrorStatus } from '~/composables/api/errors'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The workspace's private package-registry entries (npm private orgs, GitHub
|
|
9
|
+
* Packages) that agent containers install with. Tokens are write-only — the store
|
|
10
|
+
* only ever holds the redacted summary views. Loaded on demand (the registries
|
|
11
|
+
* panel + the Integrations hub badge), not from the snapshot.
|
|
12
|
+
*/
|
|
13
|
+
export const usePackageRegistriesStore = defineStore('packageRegistries', () => {
|
|
14
|
+
const api = useApi()
|
|
15
|
+
|
|
16
|
+
const entries = ref<PackageRegistryEntryView[]>([])
|
|
17
|
+
const loading = ref(false)
|
|
18
|
+
// Mirrors the backend's opt-in gate (the module 503s when the encryption key is
|
|
19
|
+
// absent): `null` until first probed, then `true`/`false`. The hub hides its
|
|
20
|
+
// registries entry point when this is false.
|
|
21
|
+
const available = ref<boolean | null>(null)
|
|
22
|
+
let inFlight: Promise<void> | null = null
|
|
23
|
+
|
|
24
|
+
/** Force a refresh of the entry list (used after an add/remove). */
|
|
25
|
+
async function load() {
|
|
26
|
+
const ws = useWorkspaceStore()
|
|
27
|
+
loading.value = true
|
|
28
|
+
try {
|
|
29
|
+
entries.value = (await api.listPackageRegistries(ws.requireId())).entries
|
|
30
|
+
available.value = true
|
|
31
|
+
} catch (err) {
|
|
32
|
+
if (apiErrorStatus(err) === 503) {
|
|
33
|
+
// A definitive 503 means the integration is unconfigured (no encryption key on
|
|
34
|
+
// the backend): hide the UI entry points and stop probing.
|
|
35
|
+
available.value = false
|
|
36
|
+
entries.value = []
|
|
37
|
+
}
|
|
38
|
+
// Any other failure (transient 5xx / network) is left untouched: it must not hide
|
|
39
|
+
// an already-available panel nor cache a false "unavailable". `available` stays
|
|
40
|
+
// `null` when never probed, so `ensureLoaded` remains retryable on the next open.
|
|
41
|
+
} finally {
|
|
42
|
+
loading.value = false
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Load once and share the result (coalescing concurrent callers); `load()` refreshes. */
|
|
47
|
+
async function ensureLoaded() {
|
|
48
|
+
if (available.value !== null) return
|
|
49
|
+
if (!inFlight) inFlight = load().finally(() => (inFlight = null))
|
|
50
|
+
return inFlight
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function add(input: AddPackageRegistryInput) {
|
|
54
|
+
const ws = useWorkspaceStore()
|
|
55
|
+
entries.value = (await api.addPackageRegistry(ws.requireId(), input)).entries
|
|
56
|
+
available.value = true
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function remove(entryId: string) {
|
|
60
|
+
const ws = useWorkspaceStore()
|
|
61
|
+
await api.deletePackageRegistry(ws.requireId(), entryId)
|
|
62
|
+
entries.value = entries.value.filter((entry) => entry.id !== entryId)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return { entries, loading, available, load, ensureLoaded, add, remove }
|
|
66
|
+
})
|
package/app/stores/ui.ts
CHANGED
|
@@ -153,6 +153,9 @@ export const useUiStore = defineStore('ui', () => {
|
|
|
153
153
|
// today, pluggable). NB: distinct from `observabilityInstanceId` below, which is the
|
|
154
154
|
// LLM per-call observability panel.
|
|
155
155
|
const observabilityConnectionOpen = ref(false)
|
|
156
|
+
// Private package registries: the workspace's npm/GitHub-Packages entries agent
|
|
157
|
+
// containers install with. Opened from the Integrations hub.
|
|
158
|
+
const packageRegistriesOpen = ref(false)
|
|
156
159
|
// The single tabbed Infrastructure window — a TOP-LEVEL navbar destination (no longer
|
|
157
160
|
// reached via the Integrations hub). Two topical tabs: "Agent containers" (the execution
|
|
158
161
|
// backend + self-hosted runner pool, plus the local-mode warm pool/checkout) and "Test
|
|
@@ -561,6 +564,13 @@ export const useUiStore = defineStore('ui', () => {
|
|
|
561
564
|
function closeObservabilityConnection() {
|
|
562
565
|
observabilityConnectionOpen.value = false
|
|
563
566
|
}
|
|
567
|
+
function openPackageRegistries() {
|
|
568
|
+
resetHubReturn()
|
|
569
|
+
packageRegistriesOpen.value = true
|
|
570
|
+
}
|
|
571
|
+
function closePackageRegistries() {
|
|
572
|
+
packageRegistriesOpen.value = false
|
|
573
|
+
}
|
|
564
574
|
// Top-level navbar entry into the Infrastructure window. No hub-return marker (it isn't
|
|
565
575
|
// reached from the Integrations hub), so the window shows no "Back to Integrations" control.
|
|
566
576
|
function openInfrastructure(tab: 'environment' | 'runner-pool' = 'runner-pool') {
|
|
@@ -791,6 +801,7 @@ export const useUiStore = defineStore('ui', () => {
|
|
|
791
801
|
accountSettingsTab,
|
|
792
802
|
accountSettingsScrollTarget,
|
|
793
803
|
observabilityConnectionOpen,
|
|
804
|
+
packageRegistriesOpen,
|
|
794
805
|
infrastructureOpen,
|
|
795
806
|
infrastructureTab,
|
|
796
807
|
openInfrastructure,
|
|
@@ -880,6 +891,8 @@ export const useUiStore = defineStore('ui', () => {
|
|
|
880
891
|
setAccountSettingsTab,
|
|
881
892
|
openObservabilityConnection,
|
|
882
893
|
closeObservabilityConnection,
|
|
894
|
+
openPackageRegistries,
|
|
895
|
+
closePackageRegistries,
|
|
883
896
|
openProviderConnection,
|
|
884
897
|
closeProviderConnection,
|
|
885
898
|
k3sSetupPrefill,
|
package/app/types/domain.ts
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Private package-registry settings shapes. Per-workspace registry entries (npm
|
|
2
|
+
// private orgs, GitHub Packages) whose tokens are write-only — the list view only
|
|
3
|
+
// ever carries the non-secret summary (vendor + scopes + token tail).
|
|
4
|
+
//
|
|
5
|
+
// All wire shapes are sourced from @cat-factory/contracts (single source of truth).
|
|
6
|
+
|
|
7
|
+
export type {
|
|
8
|
+
PackageEcosystem,
|
|
9
|
+
PackageRegistryVendor,
|
|
10
|
+
AddPackageRegistryInput,
|
|
11
|
+
PackageRegistryEntryView,
|
|
12
|
+
PackageRegistryListView,
|
|
13
|
+
} from '@cat-factory/contracts'
|
package/i18n/locales/en.json
CHANGED
|
@@ -544,6 +544,12 @@
|
|
|
544
544
|
"failed": "Failed",
|
|
545
545
|
"stopped": "Not running"
|
|
546
546
|
}
|
|
547
|
+
},
|
|
548
|
+
"resolved": {
|
|
549
|
+
"title": "Resolves to",
|
|
550
|
+
"duplicateWarning": "Used on more than one binding, so only the last applies: {vars}.",
|
|
551
|
+
"serviceOffline": "{service}: no live environment (mocked)",
|
|
552
|
+
"mock": "Mock (WireMock)"
|
|
547
553
|
}
|
|
548
554
|
},
|
|
549
555
|
"serviceConnections": {
|
|
@@ -1491,6 +1497,7 @@
|
|
|
1491
1497
|
"documents": "Documents",
|
|
1492
1498
|
"taskTrackers": "Task trackers",
|
|
1493
1499
|
"observability": "Observability",
|
|
1500
|
+
"development": "Development",
|
|
1494
1501
|
"personal": "Personal (only you)"
|
|
1495
1502
|
},
|
|
1496
1503
|
"items": {
|
|
@@ -1528,6 +1535,10 @@
|
|
|
1528
1535
|
"label": "Post-release health",
|
|
1529
1536
|
"description": "Watch monitors and SLOs after a release ships (Datadog)."
|
|
1530
1537
|
},
|
|
1538
|
+
"packageRegistries": {
|
|
1539
|
+
"label": "Private package registries",
|
|
1540
|
+
"description": "npm and GitHub Packages tokens agents use to install private dependencies."
|
|
1541
|
+
},
|
|
1531
1542
|
"githubPat": {
|
|
1532
1543
|
"label": "My GitHub token",
|
|
1533
1544
|
"description": "A personal access token used for runs you start (pushes, PRs, CI, merge)."
|
|
@@ -2025,6 +2036,31 @@
|
|
|
2025
2036
|
"connectionNoun": "the observability connection",
|
|
2026
2037
|
"incidentNoun": "the incident provider"
|
|
2027
2038
|
},
|
|
2039
|
+
"packageRegistries": {
|
|
2040
|
+
"title": "Private package registries",
|
|
2041
|
+
"intro": "Connect the private registries your repositories install from. Agents receive them when they check out a repository, so private dependencies resolve during installs. Tokens are write-only: to change one, remove the entry and add it again.",
|
|
2042
|
+
"entryNoun": "registry entry",
|
|
2043
|
+
"list": {
|
|
2044
|
+
"heading": "Connected registries",
|
|
2045
|
+
"tokenTail": "token …{tail}",
|
|
2046
|
+
"remove": "Remove entry"
|
|
2047
|
+
},
|
|
2048
|
+
"add": {
|
|
2049
|
+
"heading": "Add a registry",
|
|
2050
|
+
"vendor": "Registry",
|
|
2051
|
+
"host": "The token is sent only to {host}.",
|
|
2052
|
+
"scopes": "Package scopes",
|
|
2053
|
+
"scopesHelp": "Comma-separated npm scopes",
|
|
2054
|
+
"token": "Access token",
|
|
2055
|
+
"save": "Add registry"
|
|
2056
|
+
},
|
|
2057
|
+
"toast": {
|
|
2058
|
+
"loadFailed": "Could not load package registries",
|
|
2059
|
+
"added": "Registry added",
|
|
2060
|
+
"addFailed": "Could not add the registry",
|
|
2061
|
+
"removeFailed": "Could not remove the registry entry"
|
|
2062
|
+
}
|
|
2063
|
+
},
|
|
2028
2064
|
"localMode": {
|
|
2029
2065
|
"title": "Local mode",
|
|
2030
2066
|
"intro": "Tuning for the local container runner, stored on this machine's deployment (it replaced the {poolVars} / {harnessVars} env vars). Saving resizes the warm pool live, no restart needed; in-flight runs keep the container they already hold.",
|
package/i18n/locales/es.json
CHANGED
|
@@ -501,6 +501,12 @@
|
|
|
501
501
|
"failed": "Error",
|
|
502
502
|
"stopped": "No iniciada"
|
|
503
503
|
}
|
|
504
|
+
},
|
|
505
|
+
"resolved": {
|
|
506
|
+
"title": "Se resuelve a",
|
|
507
|
+
"duplicateWarning": "Usado en más de un binding, por lo que solo se aplica el último: {vars}.",
|
|
508
|
+
"serviceOffline": "{service}: sin entorno activo (simulado)",
|
|
509
|
+
"mock": "Mock (WireMock)"
|
|
504
510
|
}
|
|
505
511
|
},
|
|
506
512
|
"serviceConnections": {
|
|
@@ -1438,6 +1444,7 @@
|
|
|
1438
1444
|
"documents": "Documentos",
|
|
1439
1445
|
"taskTrackers": "Rastreadores de tareas",
|
|
1440
1446
|
"observability": "Observabilidad",
|
|
1447
|
+
"development": "Desarrollo",
|
|
1441
1448
|
"personal": "Personal (solo tú)"
|
|
1442
1449
|
},
|
|
1443
1450
|
"items": {
|
|
@@ -1475,6 +1482,10 @@
|
|
|
1475
1482
|
"label": "Salud posterior al lanzamiento",
|
|
1476
1483
|
"description": "Vigila los monitores y SLO después de publicar una versión (Datadog)."
|
|
1477
1484
|
},
|
|
1485
|
+
"packageRegistries": {
|
|
1486
|
+
"label": "Registros privados de paquetes",
|
|
1487
|
+
"description": "Tokens de npm y GitHub Packages que los agentes usan para instalar dependencias privadas."
|
|
1488
|
+
},
|
|
1478
1489
|
"githubPat": {
|
|
1479
1490
|
"label": "Mi token de GitHub",
|
|
1480
1491
|
"description": "Un token de acceso personal usado para las ejecuciones que inicias (pushes, PR, CI, fusión)."
|
|
@@ -1854,6 +1865,31 @@
|
|
|
1854
1865
|
"connectionNoun": "la conexión de observabilidad",
|
|
1855
1866
|
"incidentNoun": "el proveedor de incidencias"
|
|
1856
1867
|
},
|
|
1868
|
+
"packageRegistries": {
|
|
1869
|
+
"title": "Registros privados de paquetes",
|
|
1870
|
+
"intro": "Conecta los registros privados desde los que instalan tus repositorios. Los agentes los reciben al hacer checkout de un repositorio, de modo que las dependencias privadas se resuelven durante la instalación. Los tokens son de solo escritura: para cambiar uno, elimina la entrada y vuelve a agregarla.",
|
|
1871
|
+
"entryNoun": "entrada de registro",
|
|
1872
|
+
"list": {
|
|
1873
|
+
"heading": "Registros conectados",
|
|
1874
|
+
"tokenTail": "token …{tail}",
|
|
1875
|
+
"remove": "Eliminar entrada"
|
|
1876
|
+
},
|
|
1877
|
+
"add": {
|
|
1878
|
+
"heading": "Agregar un registro",
|
|
1879
|
+
"vendor": "Registro",
|
|
1880
|
+
"host": "El token solo se envía a {host}.",
|
|
1881
|
+
"scopes": "Ámbitos de paquetes",
|
|
1882
|
+
"scopesHelp": "Ámbitos de npm separados por comas",
|
|
1883
|
+
"token": "Token de acceso",
|
|
1884
|
+
"save": "Agregar registro"
|
|
1885
|
+
},
|
|
1886
|
+
"toast": {
|
|
1887
|
+
"loadFailed": "No se pudieron cargar los registros de paquetes",
|
|
1888
|
+
"added": "Registro agregado",
|
|
1889
|
+
"addFailed": "No se pudo agregar el registro",
|
|
1890
|
+
"removeFailed": "No se pudo eliminar la entrada del registro"
|
|
1891
|
+
}
|
|
1892
|
+
},
|
|
1857
1893
|
"localMode": {
|
|
1858
1894
|
"title": "Modo local",
|
|
1859
1895
|
"intro": "Ajustes del ejecutor de contenedores local, almacenados en el despliegue de esta máquina (reemplazó las variables de entorno {poolVars} / {harnessVars}). Guardar redimensiona el grupo en caliente en vivo, sin necesidad de reiniciar; las ejecuciones en curso conservan el contenedor que ya tienen.",
|
package/i18n/locales/fr.json
CHANGED
|
@@ -501,6 +501,12 @@
|
|
|
501
501
|
"failed": "Échec",
|
|
502
502
|
"stopped": "Non démarré"
|
|
503
503
|
}
|
|
504
|
+
},
|
|
505
|
+
"resolved": {
|
|
506
|
+
"title": "Résolution actuelle",
|
|
507
|
+
"duplicateWarning": "Utilisé sur plusieurs liaisons, seule la dernière s'applique : {vars}.",
|
|
508
|
+
"serviceOffline": "{service} : aucun environnement actif (simulé)",
|
|
509
|
+
"mock": "Mock (WireMock)"
|
|
504
510
|
}
|
|
505
511
|
},
|
|
506
512
|
"serviceConnections": {
|
|
@@ -1438,6 +1444,7 @@
|
|
|
1438
1444
|
"documents": "Documents",
|
|
1439
1445
|
"taskTrackers": "Outils de suivi des tâches",
|
|
1440
1446
|
"observability": "Observabilité",
|
|
1447
|
+
"development": "Développement",
|
|
1441
1448
|
"personal": "Personnel (vous uniquement)"
|
|
1442
1449
|
},
|
|
1443
1450
|
"items": {
|
|
@@ -1475,6 +1482,10 @@
|
|
|
1475
1482
|
"label": "Santé après publication",
|
|
1476
1483
|
"description": "Surveillez les moniteurs et les SLO après la publication d'une version (Datadog)."
|
|
1477
1484
|
},
|
|
1485
|
+
"packageRegistries": {
|
|
1486
|
+
"label": "Registres de paquets privés",
|
|
1487
|
+
"description": "Jetons npm et GitHub Packages que les agents utilisent pour installer les dépendances privées."
|
|
1488
|
+
},
|
|
1478
1489
|
"githubPat": {
|
|
1479
1490
|
"label": "Mon jeton GitHub",
|
|
1480
1491
|
"description": "Un jeton d'accès personnel utilisé pour les exécutions que vous lancez (pushes, PR, CI, fusion)."
|
|
@@ -1854,6 +1865,31 @@
|
|
|
1854
1865
|
"connectionNoun": "la connexion d’observabilité",
|
|
1855
1866
|
"incidentNoun": "le fournisseur d’incidents"
|
|
1856
1867
|
},
|
|
1868
|
+
"packageRegistries": {
|
|
1869
|
+
"title": "Registres de paquets privés",
|
|
1870
|
+
"intro": "Connectez les registres privés depuis lesquels vos dépôts installent leurs dépendances. Les agents les reçoivent lors du checkout d'un dépôt, afin que les dépendances privées se résolvent pendant l'installation. Les jetons sont en écriture seule : pour en changer un, supprimez l'entrée puis ajoutez-la de nouveau.",
|
|
1871
|
+
"entryNoun": "entrée de registre",
|
|
1872
|
+
"list": {
|
|
1873
|
+
"heading": "Registres connectés",
|
|
1874
|
+
"tokenTail": "jeton …{tail}",
|
|
1875
|
+
"remove": "Supprimer l'entrée"
|
|
1876
|
+
},
|
|
1877
|
+
"add": {
|
|
1878
|
+
"heading": "Ajouter un registre",
|
|
1879
|
+
"vendor": "Registre",
|
|
1880
|
+
"host": "Le jeton n'est envoyé qu'à {host}.",
|
|
1881
|
+
"scopes": "Portées de paquets",
|
|
1882
|
+
"scopesHelp": "Portées npm séparées par des virgules",
|
|
1883
|
+
"token": "Jeton d'accès",
|
|
1884
|
+
"save": "Ajouter le registre"
|
|
1885
|
+
},
|
|
1886
|
+
"toast": {
|
|
1887
|
+
"loadFailed": "Impossible de charger les registres de paquets",
|
|
1888
|
+
"added": "Registre ajouté",
|
|
1889
|
+
"addFailed": "Impossible d'ajouter le registre",
|
|
1890
|
+
"removeFailed": "Impossible de supprimer l'entrée du registre"
|
|
1891
|
+
}
|
|
1892
|
+
},
|
|
1857
1893
|
"localMode": {
|
|
1858
1894
|
"title": "Mode local",
|
|
1859
1895
|
"intro": "Réglage de l'exécuteur de conteneurs local, stocké sur le déploiement de cette machine (il a remplacé les variables d'environnement {poolVars} / {harnessVars}). L'enregistrement redimensionne le pool à chaud en direct, sans redémarrage nécessaire; les exécutions en cours conservent le conteneur qu'elles détiennent déjà.",
|
package/i18n/locales/he.json
CHANGED
|
@@ -501,6 +501,12 @@
|
|
|
501
501
|
"failed": "נכשל",
|
|
502
502
|
"stopped": "לא פועל"
|
|
503
503
|
}
|
|
504
|
+
},
|
|
505
|
+
"resolved": {
|
|
506
|
+
"title": "מתפרש כעת אל",
|
|
507
|
+
"duplicateWarning": "בשימוש ביותר מקישור אחד, ולכן רק האחרון חל: {vars}.",
|
|
508
|
+
"serviceOffline": "{service}: אין סביבה פעילה (מדומה)",
|
|
509
|
+
"mock": "Mock (WireMock)"
|
|
504
510
|
}
|
|
505
511
|
},
|
|
506
512
|
"serviceConnections": {
|
|
@@ -1438,6 +1444,7 @@
|
|
|
1438
1444
|
"documents": "מסמכים",
|
|
1439
1445
|
"taskTrackers": "עוקבי משימות",
|
|
1440
1446
|
"observability": "תצפיתיות",
|
|
1447
|
+
"development": "פיתוח",
|
|
1441
1448
|
"personal": "אישי (רק אתה)"
|
|
1442
1449
|
},
|
|
1443
1450
|
"items": {
|
|
@@ -1475,6 +1482,10 @@
|
|
|
1475
1482
|
"label": "בריאות לאחר שחרור",
|
|
1476
1483
|
"description": "עקוב אחר מוניטורים ו-SLO לאחר שחרור גרסה (Datadog)."
|
|
1477
1484
|
},
|
|
1485
|
+
"packageRegistries": {
|
|
1486
|
+
"label": "מאגרי חבילות פרטיים",
|
|
1487
|
+
"description": "אסימוני npm ו-GitHub Packages שסוכנים משתמשים בהם להתקנת תלויות פרטיות."
|
|
1488
|
+
},
|
|
1478
1489
|
"githubPat": {
|
|
1479
1490
|
"label": "אסימון ה-GitHub שלי",
|
|
1480
1491
|
"description": "אסימון גישה אישי המשמש להרצות שאתה מתחיל (דחיפות, PR, CI, מיזוג)."
|
|
@@ -1974,6 +1985,31 @@
|
|
|
1974
1985
|
"connectionNoun": "חיבור התצפיתיות",
|
|
1975
1986
|
"incidentNoun": "ספק התקריות"
|
|
1976
1987
|
},
|
|
1988
|
+
"packageRegistries": {
|
|
1989
|
+
"title": "מאגרי חבילות פרטיים",
|
|
1990
|
+
"intro": "חברו את המאגרים הפרטיים שמהם הריפוזיטוריים שלכם מתקינים. הסוכנים מקבלים אותם בעת משיכת ריפוזיטורי, כך שתלויות פרטיות נפתרות בזמן ההתקנה. האסימונים הם לכתיבה בלבד: כדי לשנות אסימון, הסירו את הרשומה והוסיפו אותה מחדש.",
|
|
1991
|
+
"entryNoun": "רשומת מאגר",
|
|
1992
|
+
"list": {
|
|
1993
|
+
"heading": "מאגרים מחוברים",
|
|
1994
|
+
"tokenTail": "אסימון …{tail}",
|
|
1995
|
+
"remove": "הסרת רשומה"
|
|
1996
|
+
},
|
|
1997
|
+
"add": {
|
|
1998
|
+
"heading": "הוספת מאגר",
|
|
1999
|
+
"vendor": "מאגר",
|
|
2000
|
+
"host": "האסימון נשלח רק אל {host}.",
|
|
2001
|
+
"scopes": "היקפי חבילות",
|
|
2002
|
+
"scopesHelp": "היקפי npm מופרדים בפסיקים",
|
|
2003
|
+
"token": "אסימון גישה",
|
|
2004
|
+
"save": "הוספת מאגר"
|
|
2005
|
+
},
|
|
2006
|
+
"toast": {
|
|
2007
|
+
"loadFailed": "טעינת מאגרי החבילות נכשלה",
|
|
2008
|
+
"added": "המאגר נוסף",
|
|
2009
|
+
"addFailed": "הוספת המאגר נכשלה",
|
|
2010
|
+
"removeFailed": "הסרת רשומת המאגר נכשלה"
|
|
2011
|
+
}
|
|
2012
|
+
},
|
|
1977
2013
|
"localMode": {
|
|
1978
2014
|
"title": "מצב מקומי",
|
|
1979
2015
|
"intro": "כוונון עבור מריץ הקונטיינרים המקומי, נשמר בפריסה של מכונה זו (הוא החליף את משתני הסביבה {poolVars} / {harnessVars}). שמירה משנה את גודל המאגר החם בזמן אמת, ללא צורך באתחול מחדש; הרצות פעילות שומרות את הקונטיינר שהן כבר מחזיקות.",
|
package/i18n/locales/ja.json
CHANGED
|
@@ -501,6 +501,12 @@
|
|
|
501
501
|
"failed": "失敗",
|
|
502
502
|
"stopped": "停止中"
|
|
503
503
|
}
|
|
504
|
+
},
|
|
505
|
+
"resolved": {
|
|
506
|
+
"title": "現在の解決先",
|
|
507
|
+
"duplicateWarning": "複数のバインディングで使用されているため、最後のもののみが適用されます: {vars}。",
|
|
508
|
+
"serviceOffline": "{service}: 稼働環境なし(モック)",
|
|
509
|
+
"mock": "モック (WireMock)"
|
|
504
510
|
}
|
|
505
511
|
},
|
|
506
512
|
"serviceConnections": {
|
|
@@ -1438,6 +1444,7 @@
|
|
|
1438
1444
|
"documents": "ドキュメント",
|
|
1439
1445
|
"taskTrackers": "タスクトラッカー",
|
|
1440
1446
|
"observability": "オブザーバビリティ",
|
|
1447
|
+
"development": "開発",
|
|
1441
1448
|
"personal": "個人(あなたのみ)"
|
|
1442
1449
|
},
|
|
1443
1450
|
"items": {
|
|
@@ -1475,6 +1482,10 @@
|
|
|
1475
1482
|
"label": "リリース後のヘルス",
|
|
1476
1483
|
"description": "リリース後にモニターと SLO を監視します (Datadog)。"
|
|
1477
1484
|
},
|
|
1485
|
+
"packageRegistries": {
|
|
1486
|
+
"label": "プライベートパッケージレジストリ",
|
|
1487
|
+
"description": "エージェントがプライベート依存関係のインストールに使う npm と GitHub Packages のトークン。"
|
|
1488
|
+
},
|
|
1478
1489
|
"githubPat": {
|
|
1479
1490
|
"label": "マイ GitHub トークン",
|
|
1480
1491
|
"description": "自分が開始した実行 (push、PR、CI、マージ) に使用するパーソナルアクセストークン。"
|
|
@@ -1976,6 +1987,31 @@
|
|
|
1976
1987
|
"connectionNoun": "オブザーバビリティ接続",
|
|
1977
1988
|
"incidentNoun": "インシデントプロバイダー"
|
|
1978
1989
|
},
|
|
1990
|
+
"packageRegistries": {
|
|
1991
|
+
"title": "プライベートパッケージレジストリ",
|
|
1992
|
+
"intro": "リポジトリが依存関係をインストールするプライベートレジストリを接続します。エージェントはリポジトリのチェックアウト時にこれらを受け取り、インストール時にプライベート依存関係を解決できます。トークンは書き込み専用です。変更するにはエントリを削除してから追加し直してください。",
|
|
1993
|
+
"entryNoun": "レジストリエントリ",
|
|
1994
|
+
"list": {
|
|
1995
|
+
"heading": "接続済みのレジストリ",
|
|
1996
|
+
"tokenTail": "トークン …{tail}",
|
|
1997
|
+
"remove": "エントリを削除"
|
|
1998
|
+
},
|
|
1999
|
+
"add": {
|
|
2000
|
+
"heading": "レジストリを追加",
|
|
2001
|
+
"vendor": "レジストリ",
|
|
2002
|
+
"host": "トークンは {host} にのみ送信されます。",
|
|
2003
|
+
"scopes": "パッケージスコープ",
|
|
2004
|
+
"scopesHelp": "カンマ区切りの npm スコープ",
|
|
2005
|
+
"token": "アクセストークン",
|
|
2006
|
+
"save": "レジストリを追加"
|
|
2007
|
+
},
|
|
2008
|
+
"toast": {
|
|
2009
|
+
"loadFailed": "パッケージレジストリを読み込めませんでした",
|
|
2010
|
+
"added": "レジストリを追加しました",
|
|
2011
|
+
"addFailed": "レジストリを追加できませんでした",
|
|
2012
|
+
"removeFailed": "レジストリエントリを削除できませんでした"
|
|
2013
|
+
}
|
|
2014
|
+
},
|
|
1979
2015
|
"localMode": {
|
|
1980
2016
|
"title": "ローカルモード",
|
|
1981
2017
|
"intro": "ローカルコンテナランナーの調整設定で、このマシンのデプロイに保存されます ({poolVars} / {harnessVars} 環境変数を置き換えました)。保存するとウォームプールがライブでサイズ変更され、再起動は不要です。実行中のランは、すでに保持しているコンテナをそのまま使います。",
|
package/i18n/locales/pl.json
CHANGED
|
@@ -501,6 +501,12 @@
|
|
|
501
501
|
"failed": "Błąd",
|
|
502
502
|
"stopped": "Nie uruchomiono"
|
|
503
503
|
}
|
|
504
|
+
},
|
|
505
|
+
"resolved": {
|
|
506
|
+
"title": "Rozwiązuje się na",
|
|
507
|
+
"duplicateWarning": "Użyte w więcej niż jednym powiązaniu, więc obowiązuje tylko ostatnie: {vars}.",
|
|
508
|
+
"serviceOffline": "{service}: brak działającego środowiska (zamockowane)",
|
|
509
|
+
"mock": "Mock (WireMock)"
|
|
504
510
|
}
|
|
505
511
|
},
|
|
506
512
|
"serviceConnections": {
|
|
@@ -1438,6 +1444,7 @@
|
|
|
1438
1444
|
"documents": "Dokumenty",
|
|
1439
1445
|
"taskTrackers": "Narzędzia do śledzenia zadań",
|
|
1440
1446
|
"observability": "Obserwowalność",
|
|
1447
|
+
"development": "Programowanie",
|
|
1441
1448
|
"personal": "Osobiste (tylko Ty)"
|
|
1442
1449
|
},
|
|
1443
1450
|
"items": {
|
|
@@ -1475,6 +1482,10 @@
|
|
|
1475
1482
|
"label": "Kondycja po wydaniu",
|
|
1476
1483
|
"description": "Obserwuj monitory i SLO po wdrożeniu wydania (Datadog)."
|
|
1477
1484
|
},
|
|
1485
|
+
"packageRegistries": {
|
|
1486
|
+
"label": "Prywatne rejestry pakietów",
|
|
1487
|
+
"description": "Tokeny npm i GitHub Packages, których agenci używają do instalowania prywatnych zależności."
|
|
1488
|
+
},
|
|
1478
1489
|
"githubPat": {
|
|
1479
1490
|
"label": "Mój token GitHub",
|
|
1480
1491
|
"description": "Osobisty token dostępu używany do uruchomień, które rozpoczynasz (pushe, PR-y, CI, scalanie)."
|
|
@@ -1854,6 +1865,31 @@
|
|
|
1854
1865
|
"connectionNoun": "połączenie obserwowalności",
|
|
1855
1866
|
"incidentNoun": "dostawcę incydentów"
|
|
1856
1867
|
},
|
|
1868
|
+
"packageRegistries": {
|
|
1869
|
+
"title": "Prywatne rejestry pakietów",
|
|
1870
|
+
"intro": "Połącz prywatne rejestry, z których instalują Twoje repozytoria. Agenci otrzymują je przy pobieraniu repozytorium, dzięki czemu prywatne zależności rozwiązują się podczas instalacji. Tokeny są tylko do zapisu: aby zmienić token, usuń wpis i dodaj go ponownie.",
|
|
1871
|
+
"entryNoun": "wpis rejestru",
|
|
1872
|
+
"list": {
|
|
1873
|
+
"heading": "Połączone rejestry",
|
|
1874
|
+
"tokenTail": "token …{tail}",
|
|
1875
|
+
"remove": "Usuń wpis"
|
|
1876
|
+
},
|
|
1877
|
+
"add": {
|
|
1878
|
+
"heading": "Dodaj rejestr",
|
|
1879
|
+
"vendor": "Rejestr",
|
|
1880
|
+
"host": "Token jest wysyłany tylko do {host}.",
|
|
1881
|
+
"scopes": "Zakresy pakietów",
|
|
1882
|
+
"scopesHelp": "Zakresy npm oddzielone przecinkami",
|
|
1883
|
+
"token": "Token dostępu",
|
|
1884
|
+
"save": "Dodaj rejestr"
|
|
1885
|
+
},
|
|
1886
|
+
"toast": {
|
|
1887
|
+
"loadFailed": "Nie udało się wczytać rejestrów pakietów",
|
|
1888
|
+
"added": "Rejestr dodany",
|
|
1889
|
+
"addFailed": "Nie udało się dodać rejestru",
|
|
1890
|
+
"removeFailed": "Nie udało się usunąć wpisu rejestru"
|
|
1891
|
+
}
|
|
1892
|
+
},
|
|
1857
1893
|
"localMode": {
|
|
1858
1894
|
"title": "Tryb lokalny",
|
|
1859
1895
|
"intro": "Strojenie lokalnego uruchamiacza kontenerów, przechowywane we wdrożeniu tej maszyny (zastąpiło zmienne środowiskowe {poolVars} / {harnessVars}). Zapisanie zmienia rozmiar ciepłej puli na żywo, bez potrzeby restartu; trwające uruchomienia zachowują kontener, który już mają.",
|
package/i18n/locales/tr.json
CHANGED
|
@@ -501,6 +501,12 @@
|
|
|
501
501
|
"failed": "Başarısız",
|
|
502
502
|
"stopped": "Başlatılmadı"
|
|
503
503
|
}
|
|
504
|
+
},
|
|
505
|
+
"resolved": {
|
|
506
|
+
"title": "Şu anda çözümleniyor",
|
|
507
|
+
"duplicateWarning": "Birden fazla bağlamada kullanılıyor, bu yüzden yalnızca sonuncusu geçerli: {vars}.",
|
|
508
|
+
"serviceOffline": "{service}: çalışan ortam yok (taklit ediliyor)",
|
|
509
|
+
"mock": "Mock (WireMock)"
|
|
504
510
|
}
|
|
505
511
|
},
|
|
506
512
|
"serviceConnections": {
|
|
@@ -1438,6 +1444,7 @@
|
|
|
1438
1444
|
"documents": "Belgeler",
|
|
1439
1445
|
"taskTrackers": "Görev izleyiciler",
|
|
1440
1446
|
"observability": "Gözlemlenebilirlik",
|
|
1447
|
+
"development": "Geliştirme",
|
|
1441
1448
|
"personal": "Kişisel (yalnızca siz)"
|
|
1442
1449
|
},
|
|
1443
1450
|
"items": {
|
|
@@ -1475,6 +1482,10 @@
|
|
|
1475
1482
|
"label": "Sürüm sonrası sağlık",
|
|
1476
1483
|
"description": "Bir sürüm yayınlandıktan sonra monitörleri ve SLO'ları izleyin (Datadog)."
|
|
1477
1484
|
},
|
|
1485
|
+
"packageRegistries": {
|
|
1486
|
+
"label": "Özel paket kayıt defterleri",
|
|
1487
|
+
"description": "Aracıların özel bağımlılıkları yüklemek için kullandığı npm ve GitHub Packages token'ları."
|
|
1488
|
+
},
|
|
1478
1489
|
"githubPat": {
|
|
1479
1490
|
"label": "GitHub token'ım",
|
|
1480
1491
|
"description": "Başlattığınız çalıştırmalar için kullanılan kişisel erişim token'ı (push'lar, PR'lar, CI, birleştirme)."
|
|
@@ -1976,6 +1987,31 @@
|
|
|
1976
1987
|
"connectionNoun": "gözlemlenebilirlik bağlantısı",
|
|
1977
1988
|
"incidentNoun": "olay sağlayıcısı"
|
|
1978
1989
|
},
|
|
1990
|
+
"packageRegistries": {
|
|
1991
|
+
"title": "Özel paket kayıt defterleri",
|
|
1992
|
+
"intro": "Depolarınızın yükleme yaptığı özel kayıt defterlerini bağlayın. Aracılar bir depoyu çekerken bunları alır, böylece özel bağımlılıklar yükleme sırasında çözülür. Token'lar yalnızca yazılırdır: birini değiştirmek için girdiyi silin ve yeniden ekleyin.",
|
|
1993
|
+
"entryNoun": "kayıt defteri girdisi",
|
|
1994
|
+
"list": {
|
|
1995
|
+
"heading": "Bağlı kayıt defterleri",
|
|
1996
|
+
"tokenTail": "token …{tail}",
|
|
1997
|
+
"remove": "Girdiyi kaldır"
|
|
1998
|
+
},
|
|
1999
|
+
"add": {
|
|
2000
|
+
"heading": "Kayıt defteri ekle",
|
|
2001
|
+
"vendor": "Kayıt defteri",
|
|
2002
|
+
"host": "Token yalnızca {host} adresine gönderilir.",
|
|
2003
|
+
"scopes": "Paket kapsamları",
|
|
2004
|
+
"scopesHelp": "Virgülle ayrılmış npm kapsamları",
|
|
2005
|
+
"token": "Erişim token'ı",
|
|
2006
|
+
"save": "Kayıt defteri ekle"
|
|
2007
|
+
},
|
|
2008
|
+
"toast": {
|
|
2009
|
+
"loadFailed": "Paket kayıt defterleri yüklenemedi",
|
|
2010
|
+
"added": "Kayıt defteri eklendi",
|
|
2011
|
+
"addFailed": "Kayıt defteri eklenemedi",
|
|
2012
|
+
"removeFailed": "Kayıt defteri girdisi kaldırılamadı"
|
|
2013
|
+
}
|
|
2014
|
+
},
|
|
1979
2015
|
"localMode": {
|
|
1980
2016
|
"title": "Yerel mod",
|
|
1981
2017
|
"intro": "Yerel konteyner çalıştırıcısı için ayarlar, bu makinenin dağıtımında saklanır ({poolVars} / {harnessVars} ortam değişkenlerinin yerini aldı). Kaydetmek sıcak havuzu anında yeniden boyutlandırır, yeniden başlatma gerekmez; devam eden çalıştırmalar zaten tuttukları konteyneri korur.",
|
package/i18n/locales/uk.json
CHANGED
|
@@ -501,6 +501,12 @@
|
|
|
501
501
|
"failed": "Помилка",
|
|
502
502
|
"stopped": "Не запущено"
|
|
503
503
|
}
|
|
504
|
+
},
|
|
505
|
+
"resolved": {
|
|
506
|
+
"title": "Розв'язується як",
|
|
507
|
+
"duplicateWarning": "Використано в кількох прив'язках, тож застосовується лише остання: {vars}.",
|
|
508
|
+
"serviceOffline": "{service}: немає активного середовища (мок)",
|
|
509
|
+
"mock": "Mock (WireMock)"
|
|
504
510
|
}
|
|
505
511
|
},
|
|
506
512
|
"serviceConnections": {
|
|
@@ -1438,6 +1444,7 @@
|
|
|
1438
1444
|
"documents": "Документи",
|
|
1439
1445
|
"taskTrackers": "Трекери завдань",
|
|
1440
1446
|
"observability": "Спостережуваність",
|
|
1447
|
+
"development": "Розробка",
|
|
1441
1448
|
"personal": "Особисте (лише ви)"
|
|
1442
1449
|
},
|
|
1443
1450
|
"items": {
|
|
@@ -1475,6 +1482,10 @@
|
|
|
1475
1482
|
"label": "Стан після випуску",
|
|
1476
1483
|
"description": "Стежте за моніторами й SLO після випуску версії (Datadog)."
|
|
1477
1484
|
},
|
|
1485
|
+
"packageRegistries": {
|
|
1486
|
+
"label": "Приватні реєстри пакетів",
|
|
1487
|
+
"description": "Токени npm і GitHub Packages, які агенти використовують для встановлення приватних залежностей."
|
|
1488
|
+
},
|
|
1478
1489
|
"githubPat": {
|
|
1479
1490
|
"label": "Мій токен GitHub",
|
|
1480
1491
|
"description": "Особистий токен доступу, який використовується для запусків, що ви розпочинаєте (pushes, PR-и, CI, злиття)."
|
|
@@ -1854,6 +1865,31 @@
|
|
|
1854
1865
|
"connectionNoun": "з’єднання спостережуваності",
|
|
1855
1866
|
"incidentNoun": "постачальника інцидентів"
|
|
1856
1867
|
},
|
|
1868
|
+
"packageRegistries": {
|
|
1869
|
+
"title": "Приватні реєстри пакетів",
|
|
1870
|
+
"intro": "Підключіть приватні реєстри, з яких встановлюють ваші репозиторії. Агенти отримують їх під час отримання репозиторію, тож приватні залежності розв'язуються під час встановлення. Токени доступні лише для запису: щоб змінити токен, видаліть запис і додайте його знову.",
|
|
1871
|
+
"entryNoun": "запис реєстру",
|
|
1872
|
+
"list": {
|
|
1873
|
+
"heading": "Підключені реєстри",
|
|
1874
|
+
"tokenTail": "токен …{tail}",
|
|
1875
|
+
"remove": "Видалити запис"
|
|
1876
|
+
},
|
|
1877
|
+
"add": {
|
|
1878
|
+
"heading": "Додати реєстр",
|
|
1879
|
+
"vendor": "Реєстр",
|
|
1880
|
+
"host": "Токен надсилається лише до {host}.",
|
|
1881
|
+
"scopes": "Скоупи пакетів",
|
|
1882
|
+
"scopesHelp": "Скоупи npm через кому",
|
|
1883
|
+
"token": "Токен доступу",
|
|
1884
|
+
"save": "Додати реєстр"
|
|
1885
|
+
},
|
|
1886
|
+
"toast": {
|
|
1887
|
+
"loadFailed": "Не вдалося завантажити реєстри пакетів",
|
|
1888
|
+
"added": "Реєстр додано",
|
|
1889
|
+
"addFailed": "Не вдалося додати реєстр",
|
|
1890
|
+
"removeFailed": "Не вдалося видалити запис реєстру"
|
|
1891
|
+
}
|
|
1892
|
+
},
|
|
1857
1893
|
"localMode": {
|
|
1858
1894
|
"title": "Локальний режим",
|
|
1859
1895
|
"intro": "Налаштування локального запускача контейнерів, збережене на розгортанні цієї машини (воно замінило змінні середовища {poolVars} / {harnessVars}). Збереження змінює розмір теплого пулу наживо, без потреби в перезапуску; поточні запуски зберігають контейнер, який вони вже утримують.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.78.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.84.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@toad-contracts/testing": "0.3.2",
|