@cat-factory/app 0.229.0 → 0.231.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/README.md +1 -1
- package/app/components/auth/LoginScreen.vue +107 -20
- package/app/components/board/AddTaskModal.vue +1 -0
- package/app/components/board/nodes/TaskCard.vue +1 -0
- package/app/components/inputGate/InputGateNotice.vue +3 -0
- package/app/components/judge/JudgeResultView.vue +13 -0
- package/app/components/panels/inspector/TaskExecution.vue +1 -0
- package/app/components/requirements/RequirementsReviewWindow.vue +8 -0
- package/app/docs/consumer-extensions.md +2 -2
- package/app/stores/auth/mothership.ts +27 -1
- package/app/stores/auth/session.ts +11 -0
- package/app/stores/auth/ssoError.spec.ts +64 -0
- package/app/stores/auth.ts +36 -3
- package/app/utils/sso.spec.ts +39 -0
- package/app/utils/sso.ts +41 -0
- package/i18n/locales/de.json +20 -1
- package/i18n/locales/en.json +26 -1
- package/i18n/locales/es.json +20 -1
- package/i18n/locales/fr.json +20 -1
- package/i18n/locales/he.json +20 -1
- package/i18n/locales/it.json +20 -1
- package/i18n/locales/ja.json +20 -1
- package/i18n/locales/pl.json +20 -1
- package/i18n/locales/tr.json +20 -1
- package/i18n/locales/uk.json +20 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -583,7 +583,7 @@ event left to restore it.
|
|
|
583
583
|
All user-facing SPA copy goes through `@nuxtjs/i18n`; never hard-code a display string. This
|
|
584
584
|
layer ships the base `en` locale, and a downstream deployment overrides by dropping its own files
|
|
585
585
|
(the per-layer deep-merge is the override seam, consumer wins key by key). Migration status:
|
|
586
|
-
[`docs/localization.md`](../../docs/localization.md).
|
|
586
|
+
[`docs/internal/localization.md`](../../docs/internal/localization.md).
|
|
587
587
|
|
|
588
588
|
- `i18n/locales/<locale>.json`: the catalogs (the v9+ `i18n/` convention, NOT `app/locales/`).
|
|
589
589
|
- `i18n/i18n.config.ts`: runtime vue-i18n behaviour only (fallback locale, the plural
|
|
@@ -4,29 +4,37 @@ import { apiErrorEnvelope } from '~/composables/api/errors'
|
|
|
4
4
|
import SecretInput from '~/components/common/SecretInput.vue'
|
|
5
5
|
import type { VcsProvider } from '~/types/domain'
|
|
6
6
|
import { VCS_PROVIDER_ICONS, VCS_PROVIDER_LABELS, VCS_PROVIDER_TOKEN_URLS } from '~/utils/vcs'
|
|
7
|
+
import { SSO_ERROR_MESSAGE_KEYS } from '~/utils/sso'
|
|
7
8
|
|
|
8
9
|
const auth = useAuthStore()
|
|
9
10
|
const { t } = useI18n()
|
|
10
11
|
|
|
11
|
-
// Local-mode source-control PAT login.
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
// constants rather than catalog keys — the
|
|
16
|
-
// token" link prefers the server's
|
|
17
|
-
// descriptor's URL is the fallback.
|
|
12
|
+
// Local-mode source-control PAT login. A configured token lives server-side and is selected by
|
|
13
|
+
// PROVIDER (no token is typed into the browser); a deployment that holds none can be handed one
|
|
14
|
+
// here, and it becomes both this sign-in and the credential the deployment operates with. The
|
|
15
|
+
// brand labels / icons / token-settings URLs are the shared provider descriptors in `~/utils/vcs`
|
|
16
|
+
// (brand names stay verbatim across locales, so they are constants rather than catalog keys — the
|
|
17
|
+
// same convention as ApiKeysSection). The "create a token" link prefers the server's
|
|
18
|
+
// scopes-preselected deep link (`patLogin.setupUrls`); the descriptor's URL is the fallback.
|
|
18
19
|
type PatProvider = VcsProvider
|
|
20
|
+
/** Every provider a token page exists for — the fallback link set when none can be installed. */
|
|
19
21
|
const ALL_PROVIDERS: PatProvider[] = ['github', 'gitlab']
|
|
20
22
|
const PROVIDER_LABELS = VCS_PROVIDER_LABELS
|
|
21
23
|
const PROVIDER_ICONS = VCS_PROVIDER_ICONS
|
|
22
24
|
const PROVIDER_TOKEN_URLS = VCS_PROVIDER_TOKEN_URLS
|
|
23
25
|
|
|
24
26
|
const patLoginCfg = computed(() => auth.localMode?.patLogin)
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
+
// Providers whose token the deployment already holds: one-click sign-in. A provider without one
|
|
28
|
+
// gets no button — it is offered in the paste form below instead.
|
|
27
29
|
const configuredProviders = computed<PatProvider[]>(
|
|
28
30
|
() => (patLoginCfg.value?.configured ?? []) as PatProvider[],
|
|
29
31
|
)
|
|
32
|
+
// Providers the server will ACCEPT a token for from here. Empty when `.env` owns the credential
|
|
33
|
+
// (it wins, so a pasted token would be ignored) or nothing can seal one — the notice then falls
|
|
34
|
+
// back to telling the developer where the token actually has to go.
|
|
35
|
+
const installableProviders = computed<PatProvider[]>(
|
|
36
|
+
() => (patLoginCfg.value?.installable ?? []) as PatProvider[],
|
|
37
|
+
)
|
|
30
38
|
const isLocalMode = computed(() => auth.localMode?.enabled === true)
|
|
31
39
|
const hasConfiguredPat = computed(() => configuredProviders.value.length > 0)
|
|
32
40
|
// Mothership mode: identity + org data live on a hosted mothership, so the primary sign-in is a
|
|
@@ -124,13 +132,27 @@ const showOAuthDivider = computed(
|
|
|
124
132
|
() => auth.providers.password && (auth.providers.github || auth.providers.google),
|
|
125
133
|
)
|
|
126
134
|
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
|
|
135
|
+
// Enterprise SSO. Led with, above the consumer providers, because on a deployment that configures
|
|
136
|
+
// it that is the intended way in — a person arriving at an org's board should not have to find
|
|
137
|
+
// their company's button under two they must not use. The label is the operator's own wording
|
|
138
|
+
// (it names their IdP), so it is rendered verbatim rather than through the catalog.
|
|
139
|
+
const ssoLabel = computed(() => auth.sso?.label ?? '')
|
|
140
|
+
// Translated copy for a refused round-trip, keyed off the machine-readable reason the backend
|
|
141
|
+
// handed back. Each reason has its own wording because the remedies differ: a missing directory
|
|
142
|
+
// group is something the user takes to IT, a failed code exchange is the operator's own config.
|
|
143
|
+
const ssoErrorMessage = computed(() =>
|
|
144
|
+
auth.ssoError ? t(SSO_ERROR_MESSAGE_KEYS[auth.ssoError]) : null,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
// Paste-a-token sign-in. The user supplies a source-control PAT and the server resolves it to an
|
|
148
|
+
// account. What it MEANS differs per facade, which is why the providers come from two places:
|
|
149
|
+
// - hosted (remote node): the user's OWN token, held to the login/org/domain allowlist. GitHub
|
|
150
|
+
// always, GitLab when configured, on both hosted facades (Node + Worker).
|
|
151
|
+
// - local: the token also becomes the DEPLOYMENT's credential, so the server names the providers
|
|
152
|
+
// it will accept one for (`installable`) — empty once `.env` owns it.
|
|
153
|
+
// One form serves both; the local-only hint below says what the token is additionally used for.
|
|
132
154
|
const remotePatProviders = computed<PatProvider[]>(() =>
|
|
133
|
-
isLocalMode.value ?
|
|
155
|
+
isLocalMode.value ? installableProviders.value : (auth.patProviders as PatProvider[]),
|
|
134
156
|
)
|
|
135
157
|
const remotePatProvider = ref<PatProvider>('github')
|
|
136
158
|
watch(
|
|
@@ -157,6 +179,16 @@ async function submitRemotePat() {
|
|
|
157
179
|
}
|
|
158
180
|
}
|
|
159
181
|
|
|
182
|
+
// Only divide SSO from what follows when something actually follows it.
|
|
183
|
+
const showSsoDivider = computed(
|
|
184
|
+
() =>
|
|
185
|
+
auth.providers.sso &&
|
|
186
|
+
(auth.providers.github ||
|
|
187
|
+
auth.providers.google ||
|
|
188
|
+
auth.providers.password ||
|
|
189
|
+
remotePatProviders.value.length > 0),
|
|
190
|
+
)
|
|
191
|
+
|
|
160
192
|
// A remote deployment (node service / Worker) that advertises no sign-in method at all:
|
|
161
193
|
// no OAuth, no password, no PAT, and not local mode. The auth gate still routes here (a
|
|
162
194
|
// remote facade has no anonymous tier), so instead of a blank card we explain that
|
|
@@ -167,6 +199,7 @@ const noSignInMethod = computed(
|
|
|
167
199
|
!auth.providers.github &&
|
|
168
200
|
!auth.providers.google &&
|
|
169
201
|
!auth.providers.password &&
|
|
202
|
+
!auth.providers.sso &&
|
|
170
203
|
remotePatProviders.value.length === 0,
|
|
171
204
|
)
|
|
172
205
|
</script>
|
|
@@ -227,16 +260,24 @@ const noSignInMethod = computed(
|
|
|
227
260
|
{{ t('auth.localMode.continueWithConfigured', { provider: PROVIDER_LABELS[p] }) }}
|
|
228
261
|
</UButton>
|
|
229
262
|
|
|
230
|
-
<!--
|
|
263
|
+
<!-- The deployment holds no token. When one can be installed from here the notice says
|
|
264
|
+
so and the create-token links feed the form below; when it can't (`.env` owns the
|
|
265
|
+
credential, or nothing can seal one) it names where the token has to go instead. -->
|
|
231
266
|
<template v-if="!hasConfiguredPat">
|
|
232
267
|
<UAlert
|
|
233
268
|
color="warning"
|
|
234
269
|
variant="subtle"
|
|
235
270
|
icon="i-lucide-key-round"
|
|
236
271
|
:title="t('auth.localMode.noPatTitle')"
|
|
237
|
-
:description="
|
|
272
|
+
:description="
|
|
273
|
+
installableProviders.length > 0
|
|
274
|
+
? t('auth.localMode.setupBody')
|
|
275
|
+
: t('auth.localMode.noPatBody')
|
|
276
|
+
"
|
|
238
277
|
/>
|
|
239
|
-
|
|
278
|
+
<!-- Only when nothing can be installed here: the paste form below carries its own
|
|
279
|
+
per-provider link, so showing these too would offer the same thing twice. -->
|
|
280
|
+
<div v-if="installableProviders.length === 0" class="flex flex-wrap gap-3 px-1">
|
|
240
281
|
<a
|
|
241
282
|
v-for="p in ALL_PROVIDERS"
|
|
242
283
|
:key="p"
|
|
@@ -261,6 +302,41 @@ const noSignInMethod = computed(
|
|
|
261
302
|
<span class="h-px flex-1 bg-slate-800" />
|
|
262
303
|
</div>
|
|
263
304
|
|
|
305
|
+
<!-- A refused SSO round-trip: name the rule that refused, don't return the user to an
|
|
306
|
+
unchanged sign-in button. -->
|
|
307
|
+
<UAlert
|
|
308
|
+
v-if="ssoErrorMessage && mode !== 'forgot'"
|
|
309
|
+
class="mb-4"
|
|
310
|
+
color="error"
|
|
311
|
+
variant="subtle"
|
|
312
|
+
icon="i-lucide-shield-x"
|
|
313
|
+
:title="t('auth.sso.failedTitle')"
|
|
314
|
+
:description="ssoErrorMessage"
|
|
315
|
+
data-testid="sso-error"
|
|
316
|
+
/>
|
|
317
|
+
|
|
318
|
+
<!-- Enterprise SSO: the deployment's OWN identity provider, led with where configured. -->
|
|
319
|
+
<div v-if="auth.providers.sso && mode !== 'forgot'" class="mb-2 space-y-2">
|
|
320
|
+
<UButton
|
|
321
|
+
block
|
|
322
|
+
size="lg"
|
|
323
|
+
color="primary"
|
|
324
|
+
icon="i-lucide-building-2"
|
|
325
|
+
data-testid="sso-signin"
|
|
326
|
+
@click="auth.loginWithSso(invite)"
|
|
327
|
+
>
|
|
328
|
+
{{ t('auth.sso.continueWith', { provider: ssoLabel }) }}
|
|
329
|
+
</UButton>
|
|
330
|
+
</div>
|
|
331
|
+
|
|
332
|
+
<div
|
|
333
|
+
v-if="showSsoDivider && mode !== 'forgot'"
|
|
334
|
+
class="my-4 flex items-center gap-3 text-xs text-slate-500"
|
|
335
|
+
>
|
|
336
|
+
<span class="h-px flex-1 bg-slate-800" /> {{ t('auth.login.or') }}
|
|
337
|
+
<span class="h-px flex-1 bg-slate-800" />
|
|
338
|
+
</div>
|
|
339
|
+
|
|
264
340
|
<!-- OAuth providers -->
|
|
265
341
|
<div v-if="mode !== 'forgot'" class="space-y-2">
|
|
266
342
|
<UButton
|
|
@@ -364,10 +440,16 @@ const noSignInMethod = computed(
|
|
|
364
440
|
</p>
|
|
365
441
|
</form>
|
|
366
442
|
|
|
367
|
-
<!--
|
|
443
|
+
<!-- Paste-a-token sign-in: your own PAT on a hosted node; on local mode the token this
|
|
444
|
+
deployment will operate with (see `remotePatProviders`). -->
|
|
368
445
|
<template v-if="remotePatProviders.length > 0 && mode !== 'forgot'">
|
|
369
446
|
<div
|
|
370
|
-
v-if="
|
|
447
|
+
v-if="
|
|
448
|
+
auth.providers.github ||
|
|
449
|
+
auth.providers.google ||
|
|
450
|
+
auth.providers.password ||
|
|
451
|
+
hasConfiguredPat
|
|
452
|
+
"
|
|
371
453
|
class="my-4 flex items-center gap-3 text-xs text-slate-500"
|
|
372
454
|
>
|
|
373
455
|
<span class="h-px flex-1 bg-slate-800" /> {{ t('auth.login.or') }}
|
|
@@ -412,6 +494,11 @@ const noSignInMethod = computed(
|
|
|
412
494
|
>
|
|
413
495
|
{{ t('auth.login.signInWithPat', { provider: PROVIDER_LABELS[remotePatProvider] }) }}
|
|
414
496
|
</UButton>
|
|
497
|
+
<!-- Local mode only: say what else the token is for BEFORE it is handed over, since it
|
|
498
|
+
becomes the credential every agent step on this machine clones and pushes with. -->
|
|
499
|
+
<p v-if="isLocalMode" class="px-1 text-xs text-slate-400">
|
|
500
|
+
{{ t('auth.localMode.tokenBecomesCredential') }}
|
|
501
|
+
</p>
|
|
415
502
|
<p class="px-1 text-center">
|
|
416
503
|
<a
|
|
417
504
|
:href="tokenCreateUrl(remotePatProvider)"
|
|
@@ -406,6 +406,7 @@ function selectTask() {
|
|
|
406
406
|
:icon="!runnable ? 'i-lucide-lock' : sandboxed ? 'i-lucide-shield' : 'i-lucide-play'"
|
|
407
407
|
:loading="starting"
|
|
408
408
|
:disabled="!runnable || starting"
|
|
409
|
+
data-testid="task-start"
|
|
409
410
|
:title="
|
|
410
411
|
!runnable
|
|
411
412
|
? t('board.task.waitingOn', { deps: unmet.map((d) => d.title).join(', ') })
|
|
@@ -148,6 +148,9 @@ async function resolve(choice: 'recheck' | 'proceed') {
|
|
|
148
148
|
v-for="issue in issues"
|
|
149
149
|
:key="`${issue.code}:${issue.field?.key ?? ''}`"
|
|
150
150
|
class="flex items-start gap-2 text-xs"
|
|
151
|
+
data-testid="input-gate-issue"
|
|
152
|
+
:data-issue-code="issue.code"
|
|
153
|
+
:data-issue-severity="issue.severity"
|
|
151
154
|
>
|
|
152
155
|
<UBadge
|
|
153
156
|
:color="issue.severity === 'blocking' ? 'warning' : 'neutral'"
|
|
@@ -170,6 +170,17 @@ async function act(choice: 'proceed' | 'bounce' | 'stop') {
|
|
|
170
170
|
</span>
|
|
171
171
|
</div>
|
|
172
172
|
|
|
173
|
+
<!-- The rubric asked for a model this deployment cannot serve, so something else scored
|
|
174
|
+
the work. Only this case is shown: a pin that was honoured says nothing the model
|
|
175
|
+
name doesn't, and being overridden by the task's own choice is the normal outcome. -->
|
|
176
|
+
<p
|
|
177
|
+
v-if="judge.modelPin?.status === 'unavailable'"
|
|
178
|
+
class="mt-2 rounded-md border border-amber-500/30 bg-amber-500/5 px-3 py-2 text-[12px] leading-relaxed text-amber-200"
|
|
179
|
+
data-testid="judge-model-pin"
|
|
180
|
+
>
|
|
181
|
+
{{ t('judge.modelPinUnavailable', { model: judge.modelPin.requested }) }}
|
|
182
|
+
</p>
|
|
183
|
+
|
|
173
184
|
<!-- Why the judge did nothing, when it did nothing. A skipped judge must never read
|
|
174
185
|
like a clean pass. -->
|
|
175
186
|
<p
|
|
@@ -288,6 +299,8 @@ async function act(choice: 'proceed' | 'bounce' | 'stop') {
|
|
|
288
299
|
v-for="round in rounds"
|
|
289
300
|
:key="round.round"
|
|
290
301
|
class="flex flex-wrap items-center gap-2 rounded-md border border-slate-800 bg-slate-950/40 px-3 py-1.5 text-[12px] text-slate-300"
|
|
302
|
+
data-testid="judge-round"
|
|
303
|
+
:data-round-disposition="round.disposition"
|
|
291
304
|
>
|
|
292
305
|
<span class="text-slate-500">{{ t('judge.round', { round: round.round }) }}</span>
|
|
293
306
|
<span class="font-medium text-slate-100">{{
|
|
@@ -373,6 +373,7 @@ async function mergePr() {
|
|
|
373
373
|
<button
|
|
374
374
|
type="button"
|
|
375
375
|
class="flex min-w-0 cursor-pointer items-center gap-2 text-start transition hover:text-white"
|
|
376
|
+
data-testid="run-step-open"
|
|
376
377
|
:title="
|
|
377
378
|
s.output
|
|
378
379
|
? t('inspector.execution.viewDetailsOutput')
|
|
@@ -708,6 +708,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
708
708
|
<div
|
|
709
709
|
v-if="incorporated"
|
|
710
710
|
class="mb-4 flex items-center gap-2 rounded-lg border border-emerald-900/60 bg-emerald-950/30 p-4 text-sm text-emerald-300"
|
|
711
|
+
data-testid="requirements-settled"
|
|
711
712
|
>
|
|
712
713
|
<UIcon name="i-lucide-circle-check" class="h-5 w-5 shrink-0" />
|
|
713
714
|
{{ t('requirements.settled') }}
|
|
@@ -760,6 +761,9 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
760
761
|
<div
|
|
761
762
|
class="rounded-lg border border-slate-800 bg-slate-900/60 p-3"
|
|
762
763
|
:class="{ 'opacity-60': item.status === 'dismissed' }"
|
|
764
|
+
data-testid="requirements-finding"
|
|
765
|
+
:data-finding-status="item.status"
|
|
766
|
+
:data-finding-severity="item.severity"
|
|
763
767
|
>
|
|
764
768
|
<div class="flex items-start gap-2">
|
|
765
769
|
<UIcon
|
|
@@ -831,6 +835,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
831
835
|
size="xs"
|
|
832
836
|
:icon="opt.icon"
|
|
833
837
|
:disabled="frozen"
|
|
838
|
+
:data-testid="`requirements-mode-${opt.mode}`"
|
|
834
839
|
@click="setMode(item, opt.mode)"
|
|
835
840
|
>
|
|
836
841
|
{{ t(opt.labelKey) }}
|
|
@@ -881,6 +886,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
881
886
|
class="mt-2 w-full"
|
|
882
887
|
:placeholder="t('requirements.answerPlaceholder')"
|
|
883
888
|
:disabled="frozen"
|
|
889
|
+
data-testid="requirements-answer"
|
|
884
890
|
@blur="persistDraft(item)"
|
|
885
891
|
/>
|
|
886
892
|
<p
|
|
@@ -1170,6 +1176,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
1170
1176
|
:loading="acting"
|
|
1171
1177
|
:disabled="!access.canExecuteRuns.value"
|
|
1172
1178
|
:title="access.canExecuteRuns.value ? undefined : t('access.noRunExecute')"
|
|
1179
|
+
data-testid="requirements-proceed"
|
|
1173
1180
|
@click="proceed"
|
|
1174
1181
|
>
|
|
1175
1182
|
{{ t('requirements.actions.proceedNothing') }}
|
|
@@ -1183,6 +1190,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
1183
1190
|
:loading="reworking"
|
|
1184
1191
|
:disabled="!canIncorporate || !access.canExecuteRuns.value"
|
|
1185
1192
|
:title="access.canExecuteRuns.value ? undefined : t('access.noRunExecute')"
|
|
1193
|
+
data-testid="requirements-incorporate"
|
|
1186
1194
|
@click="incorporate()"
|
|
1187
1195
|
>
|
|
1188
1196
|
{{ t('requirements.actions.incorporateAnswers') }}
|
|
@@ -213,8 +213,8 @@ suite can address a row and the caption inside it.
|
|
|
213
213
|
Together, `fields` + `defaultFragmentIds` + `defaultPipelineId` are what turns a task type from a
|
|
214
214
|
badge into a **reusable operation**: a canned unit of work an org runs repeatedly with per-case
|
|
215
215
|
input, whose collected values reach every agent's prompt. See
|
|
216
|
-
[`docs/
|
|
217
|
-
|
|
216
|
+
[`backend/docs/reusable-operations.md`](../../../../backend/docs/reusable-operations.md) and the
|
|
217
|
+
`org:introduce-api` worked example in `backend/internal/example-custom-agent`.
|
|
218
218
|
|
|
219
219
|
The **same type can be delivered from the backend** instead of code-shipped: register it on the
|
|
220
220
|
deployment's app-owned `TaskTypeRegistry` and it arrives in the workspace snapshot's
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Ref } from 'vue'
|
|
2
|
+
import { SSO_ERROR_FRAGMENT_KEY, parseSsoErrorReason } from '@cat-factory/contracts'
|
|
2
3
|
import type { LocalModeConfig } from '@cat-factory/contracts'
|
|
3
4
|
import type { AuthUser } from '~/types/domain'
|
|
5
|
+
import type { SsoLoginFailure } from '~/utils/sso'
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Shared reactive state + injected dependencies the auth-store redirect factory closes over.
|
|
@@ -13,6 +15,8 @@ export interface AuthRedirectContext {
|
|
|
13
15
|
token: Ref<string | null>
|
|
14
16
|
localMode: Ref<LocalModeConfig | null>
|
|
15
17
|
mothershipError: Ref<string | null>
|
|
18
|
+
/** Why the last enterprise-SSO round-trip produced no session, when one was refused. */
|
|
19
|
+
ssoError: Ref<SsoLoginFailure | null>
|
|
16
20
|
/** Apply a freshly-minted token + user (the session factory's setter). */
|
|
17
21
|
applySession: (result: { token: string; user: AuthUser }) => void
|
|
18
22
|
}
|
|
@@ -23,7 +27,7 @@ export interface AuthRedirectContext {
|
|
|
23
27
|
* mode — exchanging a returning MOTHERSHIP session for a local one.
|
|
24
28
|
*/
|
|
25
29
|
export function createAuthRedirectActions(ctx: AuthRedirectContext) {
|
|
26
|
-
const { api, token, localMode, mothershipError, applySession } = ctx
|
|
30
|
+
const { api, token, localMode, mothershipError, ssoError, applySession } = ctx
|
|
27
31
|
|
|
28
32
|
/** Pull a token handed back in the post-login URL fragment (#token=…). */
|
|
29
33
|
function consumeRedirectToken() {
|
|
@@ -35,6 +39,27 @@ export function createAuthRedirectActions(ctx: AuthRedirectContext) {
|
|
|
35
39
|
history.replaceState(null, '', window.location.pathname + window.location.search)
|
|
36
40
|
}
|
|
37
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Pull the reason a REFUSED enterprise-SSO round-trip handed back (`#sso_error=<reason>`), the
|
|
44
|
+
* sibling of the `#token=` a successful one sets.
|
|
45
|
+
*
|
|
46
|
+
* A fragment rather than a query for the same reason the token is: it never reaches a server log
|
|
47
|
+
* or a `Referer`, and the reason names the deployment's own admission rules. Stripped from the
|
|
48
|
+
* URL afterwards so a reload doesn't resurrect a stale failure.
|
|
49
|
+
*/
|
|
50
|
+
function consumeSsoError() {
|
|
51
|
+
if (typeof window === 'undefined') return
|
|
52
|
+
const match = new RegExp(`(?:^#|[#&])${SSO_ERROR_FRAGMENT_KEY}=([^&]+)`).exec(
|
|
53
|
+
window.location.hash,
|
|
54
|
+
)
|
|
55
|
+
if (!match) return
|
|
56
|
+
// An unrecognised value came from a newer backend than this build: reported as `unknown`
|
|
57
|
+
// rather than rendered raw, and never dropped — the user clicked a button and is owed an
|
|
58
|
+
// answer about why they are back here.
|
|
59
|
+
ssoError.value = parseSsoErrorReason(decodeURIComponent(match[1]!)) ?? 'unknown'
|
|
60
|
+
history.replaceState(null, '', window.location.pathname + window.location.search)
|
|
61
|
+
}
|
|
62
|
+
|
|
38
63
|
/**
|
|
39
64
|
* Mothership mode: when the mothership OAuth redirect returns here (flagged
|
|
40
65
|
* `?mothership_connect=1`), the URL fragment carries a MOTHERSHIP session — not a local one.
|
|
@@ -101,6 +126,7 @@ export function createAuthRedirectActions(ctx: AuthRedirectContext) {
|
|
|
101
126
|
|
|
102
127
|
return {
|
|
103
128
|
consumeRedirectToken,
|
|
129
|
+
consumeSsoError,
|
|
104
130
|
maybeConnectMothership,
|
|
105
131
|
signInViaMothership,
|
|
106
132
|
maybeAcceptInvite,
|
|
@@ -44,6 +44,16 @@ export function createAuthSessionActions(ctx: AuthSessionContext) {
|
|
|
44
44
|
window.location.href = `${apiBase}/auth/google/login?${redirectTarget(invite)}`
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Send the browser to the deployment's OWN identity provider (enterprise SSO), returning here
|
|
49
|
+
* after. One entry point whichever IdP is configured: the backend resolves the provider from its
|
|
50
|
+
* discovery document, so there is nothing per-vendor for the SPA to know.
|
|
51
|
+
*/
|
|
52
|
+
function loginWithSso(invite?: string) {
|
|
53
|
+
if (typeof window === 'undefined') return
|
|
54
|
+
window.location.href = `${apiBase}/auth/sso/login?${redirectTarget(invite)}`
|
|
55
|
+
}
|
|
56
|
+
|
|
47
57
|
/** Apply a freshly-minted token + user (from password signup/login). */
|
|
48
58
|
function applySession(result: { token: string; user: AuthUser }) {
|
|
49
59
|
token.value = result.token
|
|
@@ -107,6 +117,7 @@ export function createAuthSessionActions(ctx: AuthSessionContext) {
|
|
|
107
117
|
applySession,
|
|
108
118
|
login,
|
|
109
119
|
loginWithGoogle,
|
|
120
|
+
loginWithSso,
|
|
110
121
|
signup,
|
|
111
122
|
passwordLogin,
|
|
112
123
|
patLogin,
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ref } from 'vue'
|
|
2
|
+
import { beforeEach, describe, expect, it } from 'vitest'
|
|
3
|
+
import { createAuthRedirectActions } from './mothership'
|
|
4
|
+
import type { SsoLoginFailure } from '~/utils/sso'
|
|
5
|
+
|
|
6
|
+
// The other half of the SSO refusal contract: the backend lands the browser here with a
|
|
7
|
+
// machine-readable reason in the fragment, and this is what turns it into state the login screen
|
|
8
|
+
// renders. Worth pinning because the failure mode is silent — a reason the SPA drops leaves the
|
|
9
|
+
// user back on the same sign-in button with no explanation for the click that just failed.
|
|
10
|
+
|
|
11
|
+
/** Point `window.location` + `history` at a URL the consumer can read and rewrite. */
|
|
12
|
+
function setUrl(path: string): void {
|
|
13
|
+
history.replaceState(null, '', path)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function actions() {
|
|
17
|
+
const ssoError = ref<SsoLoginFailure | null>(null)
|
|
18
|
+
const factory = createAuthRedirectActions({
|
|
19
|
+
api: {} as never,
|
|
20
|
+
token: ref<string | null>(null),
|
|
21
|
+
localMode: ref(null),
|
|
22
|
+
mothershipError: ref<string | null>(null),
|
|
23
|
+
ssoError,
|
|
24
|
+
applySession: () => {},
|
|
25
|
+
})
|
|
26
|
+
return { ...factory, ssoError }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe('consumeSsoError', () => {
|
|
30
|
+
beforeEach(() => setUrl('/'))
|
|
31
|
+
|
|
32
|
+
it('reads a known reason off the fragment', () => {
|
|
33
|
+
setUrl('/#sso_error=group_required')
|
|
34
|
+
const a = actions()
|
|
35
|
+
a.consumeSsoError()
|
|
36
|
+
expect(a.ssoError.value).toBe('group_required')
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('strips the fragment so a reload does not resurrect a stale failure', () => {
|
|
40
|
+
setUrl('/board?ws=ws_1#sso_error=state_invalid')
|
|
41
|
+
actions().consumeSsoError()
|
|
42
|
+
expect(window.location.hash).toBe('')
|
|
43
|
+
// The rest of the URL is left alone.
|
|
44
|
+
expect(window.location.pathname + window.location.search).toBe('/board?ws=ws_1')
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('reports an unrecognised reason as `unknown` rather than dropping it', () => {
|
|
48
|
+
// A reason from a NEWER backend than this build. Rendering the raw wire token to a user is
|
|
49
|
+
// wrong; showing nothing after a failed sign-in is worse.
|
|
50
|
+
setUrl('/#sso_error=reason_from_the_future')
|
|
51
|
+
const a = actions()
|
|
52
|
+
a.consumeSsoError()
|
|
53
|
+
expect(a.ssoError.value).toBe('unknown')
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('leaves the state untouched when the fragment carries no SSO error', () => {
|
|
57
|
+
setUrl('/#token=abc')
|
|
58
|
+
const a = actions()
|
|
59
|
+
a.consumeSsoError()
|
|
60
|
+
expect(a.ssoError.value).toBeNull()
|
|
61
|
+
// The session token is another consumer's to read, so the fragment must survive.
|
|
62
|
+
expect(window.location.hash).toBe('#token=abc')
|
|
63
|
+
})
|
|
64
|
+
})
|
package/app/stores/auth.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
BackendMisconfigured,
|
|
3
3
|
InfrastructureCapabilities,
|
|
4
4
|
LocalModeConfig,
|
|
5
|
+
SsoConfigView,
|
|
5
6
|
} from '@cat-factory/contracts'
|
|
6
7
|
import { defineStore } from 'pinia'
|
|
7
8
|
import { computed, ref } from 'vue'
|
|
@@ -9,6 +10,7 @@ import type { AuthUser } from '~/types/domain'
|
|
|
9
10
|
import { retryWhileBackendUnreachable } from '~/utils/backendReady'
|
|
10
11
|
import { createAuthSessionActions } from '~/stores/auth/session'
|
|
11
12
|
import { createAuthRedirectActions } from '~/stores/auth/mothership'
|
|
13
|
+
import type { SsoLoginFailure } from '~/utils/sso'
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* "Login with GitHub" session state. The backend mints a signed session token
|
|
@@ -31,7 +33,20 @@ export const useAuthStore = defineStore(
|
|
|
31
33
|
/** Whether the backend requires authentication. */
|
|
32
34
|
const required = ref(false)
|
|
33
35
|
/** Which login providers the backend offers (drives the login UI). */
|
|
34
|
-
const providers = ref({ github: false, password: false, google: false })
|
|
36
|
+
const providers = ref({ github: false, password: false, google: false, sso: false })
|
|
37
|
+
/**
|
|
38
|
+
* Presentation for the deployment's OWN identity provider (enterprise SSO) — its
|
|
39
|
+
* operator-supplied label and protocol. Null unless `providers.sso` is set. The label names
|
|
40
|
+
* the operator's IdP, so it is the one piece of login copy the SPA renders verbatim rather
|
|
41
|
+
* than through the catalog.
|
|
42
|
+
*/
|
|
43
|
+
const sso = ref<SsoConfigView | null>(null)
|
|
44
|
+
/**
|
|
45
|
+
* Why the last enterprise-SSO sign-in produced no session, when one was refused. Captured
|
|
46
|
+
* from the `#sso_error=` fragment on boot so the login screen can name the rule that refused
|
|
47
|
+
* instead of returning the user to an unchanged sign-in button.
|
|
48
|
+
*/
|
|
49
|
+
const ssoError = ref<SsoLoginFailure | null>(null)
|
|
35
50
|
/**
|
|
36
51
|
* Source-control providers a HOSTED facade (remote node) accepts a user-supplied PAT for.
|
|
37
52
|
* Drives the login screen's "sign in with a PAT" option on non-local deployments. Empty on
|
|
@@ -134,14 +149,29 @@ export const useAuthStore = defineStore(
|
|
|
134
149
|
user,
|
|
135
150
|
autoLoginProvider,
|
|
136
151
|
})
|
|
137
|
-
const {
|
|
138
|
-
|
|
152
|
+
const {
|
|
153
|
+
consumeRedirectToken,
|
|
154
|
+
consumeSsoError,
|
|
155
|
+
maybeConnectMothership,
|
|
156
|
+
signInViaMothership,
|
|
157
|
+
maybeAcceptInvite,
|
|
158
|
+
} = createAuthRedirectActions({
|
|
159
|
+
api,
|
|
160
|
+
token,
|
|
161
|
+
localMode,
|
|
162
|
+
mothershipError,
|
|
163
|
+
ssoError,
|
|
164
|
+
applySession,
|
|
165
|
+
})
|
|
139
166
|
|
|
140
167
|
/** Resolve auth state: capture any redirect token, then check the backend. */
|
|
141
168
|
async function bootstrap() {
|
|
142
169
|
// A returning mothership-connect redirect is handled first (it carries a mothership session,
|
|
143
170
|
// which must be exchanged — not stored as a local token by `consumeRedirectToken`).
|
|
144
171
|
if (!(await maybeConnectMothership())) consumeRedirectToken()
|
|
172
|
+
// A refused SSO round-trip returns a reason instead of a token, and it must be read BEFORE
|
|
173
|
+
// the config call: the login screen renders from the same settled state either way.
|
|
174
|
+
consumeSsoError()
|
|
145
175
|
try {
|
|
146
176
|
// Tolerate a cold-start race: when the SPA and backend boot together, this first call
|
|
147
177
|
// can beat the backend's listener by a second or two. Retry a not-listening-yet socket
|
|
@@ -149,6 +179,7 @@ export const useAuthStore = defineStore(
|
|
|
149
179
|
const config = await retryWhileBackendUnreachable(() => api.getAuthConfig())
|
|
150
180
|
required.value = config.enabled
|
|
151
181
|
if (config.providers) providers.value = config.providers
|
|
182
|
+
sso.value = config.sso ?? null
|
|
152
183
|
patProviders.value = config.patLogin?.providers ?? []
|
|
153
184
|
testingNoAuth.value = config.testingNoAuth ?? false
|
|
154
185
|
localMode.value = config.localMode ?? null
|
|
@@ -211,6 +242,8 @@ export const useAuthStore = defineStore(
|
|
|
211
242
|
user,
|
|
212
243
|
required,
|
|
213
244
|
providers,
|
|
245
|
+
sso,
|
|
246
|
+
ssoError,
|
|
214
247
|
patProviders,
|
|
215
248
|
testingNoAuth,
|
|
216
249
|
localMode,
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { SSO_ERROR_REASONS } from '@cat-factory/contracts'
|
|
3
|
+
import en from '../../i18n/locales/en.json'
|
|
4
|
+
import { SSO_ERROR_MESSAGE_KEYS } from './sso'
|
|
5
|
+
|
|
6
|
+
// The copy side of the SSO refusal contract. The `Record<SsoLoginFailure, string>` type already
|
|
7
|
+
// forces every reason to name a key, but a key is only a STRING: nothing there checks it exists in
|
|
8
|
+
// the catalog, and a typo renders the raw key path to a user who just failed to sign in. That is
|
|
9
|
+
// the assertion the type and the locale-parity guard structurally cannot make between them (parity
|
|
10
|
+
// compares locales to each other, so a key missing from ALL of them is parity-clean).
|
|
11
|
+
|
|
12
|
+
/** Resolve a dotted i18n key against the catalog, or undefined when it names nothing. */
|
|
13
|
+
function lookup(key: string): unknown {
|
|
14
|
+
return key
|
|
15
|
+
.split('.')
|
|
16
|
+
.reduce<unknown>(
|
|
17
|
+
(node, part) =>
|
|
18
|
+
node && typeof node === 'object' ? (node as Record<string, unknown>)[part] : undefined,
|
|
19
|
+
en,
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe('SSO_ERROR_MESSAGE_KEYS', () => {
|
|
24
|
+
it('covers every wire reason EXACTLY once, plus the newer-backend fallback', () => {
|
|
25
|
+
// Derived from the vocabulary the backend actually ships rather than a pinned count, so a
|
|
26
|
+
// reason added there fails here until it has wording instead of silently rendering nothing.
|
|
27
|
+
expect(Object.keys(SSO_ERROR_MESSAGE_KEYS).sort()).toEqual(
|
|
28
|
+
[...SSO_ERROR_REASONS, 'unknown'].sort(),
|
|
29
|
+
)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('names a key that resolves to real copy for every reason', () => {
|
|
33
|
+
for (const [reason, key] of Object.entries(SSO_ERROR_MESSAGE_KEYS)) {
|
|
34
|
+
const copy = lookup(key)
|
|
35
|
+
expect(typeof copy, `${reason} -> ${key}`).toBe('string')
|
|
36
|
+
expect(copy as string, `${reason} -> ${key}`).not.toBe('')
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
})
|
package/app/utils/sso.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type SsoErrorReason } from '@cat-factory/contracts'
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Enterprise SSO presentation, in ONE place — the same convention as `utils/vcs.ts`.
|
|
5
|
+
//
|
|
6
|
+
// The backend does not localize prose (CLAUDE.md's i18n rule): a refused SSO round-trip lands
|
|
7
|
+
// back here with a machine-readable reason, and this module is where each reason becomes copy.
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A failed SSO sign-in as the SPA models it: one of the wire reasons, or `unknown`.
|
|
12
|
+
*
|
|
13
|
+
* `unknown` is not a wire value — it is what a reason from a NEWER backend than this build reads
|
|
14
|
+
* as. Without it the alternatives are rendering the raw wire token to a user or showing nothing
|
|
15
|
+
* at all after a failed sign-in, and the second is the worse one: the user clicked the button and
|
|
16
|
+
* came back to the same button.
|
|
17
|
+
*/
|
|
18
|
+
export type SsoLoginFailure = SsoErrorReason | 'unknown'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The copy key per failure. An exhaustive `Record`, so a member added to the wire vocabulary
|
|
22
|
+
* fails this typecheck until it has wording — the drift guard the `UNAVAILABLE_REASONS` pattern
|
|
23
|
+
* establishes.
|
|
24
|
+
*
|
|
25
|
+
* The wording split matters more than it looks: `group_required` and `domain_not_allowed` are
|
|
26
|
+
* things the USER takes to their IT team, while `exchange_failed` and `token_invalid` are
|
|
27
|
+
* OPERATOR faults in the deployment's own configuration. One "sign-in failed" for all four sends
|
|
28
|
+
* every user to the wrong place.
|
|
29
|
+
*/
|
|
30
|
+
export const SSO_ERROR_MESSAGE_KEYS: Record<SsoLoginFailure, string> = {
|
|
31
|
+
state_invalid: 'auth.sso.errors.stateInvalid',
|
|
32
|
+
provider_denied: 'auth.sso.errors.providerDenied',
|
|
33
|
+
exchange_failed: 'auth.sso.errors.exchangeFailed',
|
|
34
|
+
token_invalid: 'auth.sso.errors.tokenInvalid',
|
|
35
|
+
subject_missing: 'auth.sso.errors.subjectMissing',
|
|
36
|
+
group_required: 'auth.sso.errors.groupRequired',
|
|
37
|
+
domain_not_allowed: 'auth.sso.errors.domainNotAllowed',
|
|
38
|
+
email_required: 'auth.sso.errors.emailRequired',
|
|
39
|
+
provider_unreachable: 'auth.sso.errors.providerUnreachable',
|
|
40
|
+
unknown: 'auth.sso.errors.unknown',
|
|
41
|
+
}
|
package/i18n/locales/de.json
CHANGED
|
@@ -3644,7 +3644,9 @@
|
|
|
3644
3644
|
"continueWithConfigured": "Mit konfiguriertem {provider}-PAT anmelden",
|
|
3645
3645
|
"noPatTitle": "Kein Versionsverwaltungs-Token konfiguriert",
|
|
3646
3646
|
"noPatBody": "Setzen Sie GITHUB_PAT oder GITLAB_PAT in Ihrer .env, um sich mit einem Personal Access Token anzumelden, und starten Sie dann den Server neu.",
|
|
3647
|
+
"setupBody": "Erstellen Sie einen Personal Access Token und fügen Sie ihn unten ein. Er meldet Sie an und wird zum Token, mit dem diese Installation klont, pusht und merged.",
|
|
3647
3648
|
"createToken": "Einen {provider}-Token erstellen ↗",
|
|
3649
|
+
"tokenBecomesCredential": "Dieser Token wird auf diesem Rechner gespeichert und für jeden Clone, Push, PR und Merge der Agenten verwendet.",
|
|
3648
3650
|
"orDivider": "oder",
|
|
3649
3651
|
"failed": "Anmeldung fehlgeschlagen. Prüfen Sie, ob der konfigurierte Token gültig ist, und versuchen Sie es erneut."
|
|
3650
3652
|
},
|
|
@@ -3675,10 +3677,26 @@
|
|
|
3675
3677
|
"signInFailed": "Anmeldung fehlgeschlagen. Prüfen Sie Ihre Angaben und versuchen Sie es erneut.",
|
|
3676
3678
|
"genericError": "Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.",
|
|
3677
3679
|
"notConfiguredTitle": "Authentifizierung ist nicht konfiguriert",
|
|
3678
|
-
"notConfiguredBody": "Für dieses Deployment ist keine Anmeldemethode aktiviert, daher können Sie sich nicht anmelden oder auf Ihre Workspaces zugreifen. Ein Administrator muss einen Authentifizierungs-Provider konfigurieren (GitHub- oder Google-OAuth oder E-Mail-/Passwort-Anmeldung).",
|
|
3680
|
+
"notConfiguredBody": "Für dieses Deployment ist keine Anmeldemethode aktiviert, daher können Sie sich nicht anmelden oder auf Ihre Workspaces zugreifen. Ein Administrator muss einen Authentifizierungs-Provider konfigurieren (Single Sign-on über den Identitätsprovider Ihrer Organisation, GitHub- oder Google-OAuth oder E-Mail-/Passwort-Anmeldung).",
|
|
3679
3681
|
"patPlaceholder": "{provider} Personal Access Token",
|
|
3680
3682
|
"signInWithPat": "Mit {provider}-PAT anmelden"
|
|
3681
3683
|
},
|
|
3684
|
+
"sso": {
|
|
3685
|
+
"continueWith": "Mit {provider} fortfahren",
|
|
3686
|
+
"failedTitle": "Single Sign-on wurde nicht abgeschlossen",
|
|
3687
|
+
"errors": {
|
|
3688
|
+
"stateInvalid": "Dieser Anmeldeversuch ist abgelaufen oder wurde bereits verwendet. Beginnen Sie erneut auf dieser Seite.",
|
|
3689
|
+
"providerDenied": "Ihr Identitätsprovider hat die Anmeldung abgelehnt. Falls Sie sie nicht selbst abgebrochen haben, fragen Sie Ihre IT-Abteilung, ob diese Anwendung Ihnen zugewiesen ist.",
|
|
3690
|
+
"exchangeFailed": "Dieses Deployment konnte den Austausch mit Ihrem Identitätsprovider nicht abschließen. Ein Administrator muss das Single-Sign-on-Client-Secret und die Redirect-URL prüfen.",
|
|
3691
|
+
"tokenInvalid": "Die Antwort Ihres Identitätsproviders konnte nicht verifiziert werden. Ein Administrator muss die Single-Sign-on-Konfiguration dieses Deployments prüfen.",
|
|
3692
|
+
"subjectMissing": "Ihr Identitätsprovider hat keine Benutzerkennung zurückgegeben, daher konnte kein Konto ermittelt werden. Ein Administrator muss prüfen, welche Claims freigegeben werden.",
|
|
3693
|
+
"groupRequired": "Die Anmeldung hat funktioniert, aber Sie sind in keiner Verzeichnisgruppe, die dieses Deployment nutzen darf. Bitten Sie Ihre IT-Abteilung, Sie hinzuzufügen.",
|
|
3694
|
+
"domainNotAllowed": "Ihre E-Mail-Domain darf sich bei diesem Deployment nicht anmelden. Fragen Sie Ihre IT-Abteilung, welches Konto Sie verwenden sollen.",
|
|
3695
|
+
"emailRequired": "Dieses Deployment beschränkt die Anmeldung auf bestimmte E-Mail-Domains, aber Ihr Identitätsprovider hat keine verifizierte E-Mail-Adresse freigegeben. Ein Administrator muss den E-Mail-Claim aktivieren.",
|
|
3696
|
+
"providerUnreachable": "Ihr Identitätsprovider hat beim Abschluss der Anmeldung nicht geantwortet, möglicherweise ist er oder die Verbindung zu ihm gestört. Versuchen Sie es in einem Moment erneut und informieren Sie einen Administrator, falls es weiterhin auftritt.",
|
|
3697
|
+
"unknown": "Single Sign-on ist aus einem Grund fehlgeschlagen, den diese Version nicht kennt. Versuchen Sie es erneut und informieren Sie einen Administrator, falls es weiterhin auftritt."
|
|
3698
|
+
}
|
|
3699
|
+
},
|
|
3682
3700
|
"resetPassword": {
|
|
3683
3701
|
"title": "Passwort zurücksetzen",
|
|
3684
3702
|
"subtitle": "Wählen Sie ein neues Passwort für Ihren Account.",
|
|
@@ -5551,6 +5569,7 @@
|
|
|
5551
5569
|
"threshold": "Schwellenwert {threshold}",
|
|
5552
5570
|
"thresholdHint": "Der Wert, den dieser Schritt erreichen musste, aus der Merge-Policy der Aufgabe. Darunter schickt der Judge die Arbeit mit seinen Befunden als Nacharbeit an den erzeugenden Schritt zurück oder parkt den Lauf für Sie, wenn kein Versuchsbudget mehr übrig ist.",
|
|
5553
5571
|
"rubricOverridden": "Raster des Arbeitsbereichs",
|
|
5572
|
+
"modelPinUnavailable": "Diese Prüfung wurde für das Modell {model} geschrieben, das diese Installation nicht ausführen kann. Die Arbeit wurde daher von einem anderen Modell bewertet.",
|
|
5554
5573
|
"reworkRounds": "Überarbeitung {spent}/{budget}",
|
|
5555
5574
|
"findingsHeading": "Was das Bewertungsraster beanstandet hat",
|
|
5556
5575
|
"roundsHeading": "Prüfrunden",
|
package/i18n/locales/en.json
CHANGED
|
@@ -1884,7 +1884,9 @@
|
|
|
1884
1884
|
"continueWithConfigured": "Sign in with configured {provider} PAT",
|
|
1885
1885
|
"noPatTitle": "No source-control token configured",
|
|
1886
1886
|
"noPatBody": "Set GITHUB_PAT or GITLAB_PAT in your .env to sign in with a personal access token, then restart the server.",
|
|
1887
|
+
"setupBody": "Create a personal access token and paste it below. It signs you in and becomes the token this deployment clones, pushes and merges with.",
|
|
1887
1888
|
"createToken": "Create a {provider} token ↗",
|
|
1889
|
+
"tokenBecomesCredential": "This token is stored on this machine and used for every clone, push, PR and merge the agents make.",
|
|
1888
1890
|
"orDivider": "or",
|
|
1889
1891
|
"failed": "Sign-in failed. Check that the configured token is valid and try again."
|
|
1890
1892
|
},
|
|
@@ -1918,10 +1920,32 @@
|
|
|
1918
1920
|
"signInFailed": "Sign-in failed. Check your details and try again.",
|
|
1919
1921
|
"genericError": "Something went wrong. Please try again.",
|
|
1920
1922
|
"notConfiguredTitle": "Authentication isn't configured",
|
|
1921
|
-
"notConfiguredBody": "This deployment has no sign-in method enabled, so you can't sign in or access your workspaces. An administrator needs to configure an authentication provider (GitHub or Google OAuth, or email and password login).",
|
|
1923
|
+
"notConfiguredBody": "This deployment has no sign-in method enabled, so you can't sign in or access your workspaces. An administrator needs to configure an authentication provider (single sign-on through your organization's identity provider, GitHub or Google OAuth, or email and password login).",
|
|
1922
1924
|
"patPlaceholder": "{provider} personal access token",
|
|
1923
1925
|
"signInWithPat": "Sign in with {provider} PAT"
|
|
1924
1926
|
},
|
|
1927
|
+
"sso": {
|
|
1928
|
+
"continueWith": "Continue with {provider}",
|
|
1929
|
+
"@continueWith": {
|
|
1930
|
+
"description": "Sign-in button for the deployment's own identity provider (enterprise SSO). {provider} is the operator-configured label (AUTH_SSO_LABEL) naming their IdP, e.g. \"Acme SSO\" or \"Okta\" - it is a proper noun supplied at runtime, so never translate the interpolated value."
|
|
1931
|
+
},
|
|
1932
|
+
"failedTitle": "Single sign-on didn't complete",
|
|
1933
|
+
"@failedTitle": {
|
|
1934
|
+
"description": "Title of the alert shown when an enterprise single-sign-on round-trip came back without a session. The per-reason detail underneath is the matching `errors.*` message."
|
|
1935
|
+
},
|
|
1936
|
+
"errors": {
|
|
1937
|
+
"stateInvalid": "That sign-in attempt has expired or was already used. Start again from this page.",
|
|
1938
|
+
"providerDenied": "Your identity provider refused the sign-in. If you didn't cancel it yourself, ask your IT team whether this application is assigned to you.",
|
|
1939
|
+
"exchangeFailed": "This deployment couldn't complete the exchange with your identity provider. An administrator needs to check its single sign-on client secret and redirect URL.",
|
|
1940
|
+
"tokenInvalid": "The response from your identity provider couldn't be verified. An administrator needs to check this deployment's single sign-on configuration.",
|
|
1941
|
+
"subjectMissing": "Your identity provider didn't return a user identifier, so no account could be resolved. An administrator needs to check which claims it releases.",
|
|
1942
|
+
"groupRequired": "Your sign-in worked, but you aren't in a directory group that's allowed to use this deployment. Ask your IT team to add you.",
|
|
1943
|
+
"domainNotAllowed": "Your email domain isn't allowed to sign in to this deployment. Ask your IT team which account to use.",
|
|
1944
|
+
"emailRequired": "This deployment restricts sign-in by email domain, but your identity provider didn't release a verified email address. An administrator needs to enable the email claim.",
|
|
1945
|
+
"providerUnreachable": "Your identity provider didn't respond while your sign-in was being completed, so it or the network to it may be down. Try again in a moment, and tell an administrator if it keeps happening.",
|
|
1946
|
+
"unknown": "Single sign-on failed for a reason this version doesn't recognise. Try again, and tell an administrator if it keeps happening."
|
|
1947
|
+
}
|
|
1948
|
+
},
|
|
1925
1949
|
"resetPassword": {
|
|
1926
1950
|
"title": "Reset password",
|
|
1927
1951
|
"subtitle": "Choose a new password for your account.",
|
|
@@ -4910,6 +4934,7 @@
|
|
|
4910
4934
|
"threshold": "threshold {threshold}",
|
|
4911
4935
|
"thresholdHint": "The score this step had to reach, taken from the task's merge policy. Below it the judge sends the work back to the step that produced it, with its findings as rework, or parks the run for you when no attempt budget is left.",
|
|
4912
4936
|
"rubricOverridden": "workspace rubric",
|
|
4937
|
+
"modelPinUnavailable": "This review was written for the {model} model, which this deployment cannot run, so another model scored the work.",
|
|
4913
4938
|
"reworkRounds": "rework {spent}/{budget}",
|
|
4914
4939
|
"findingsHeading": "What the rubric flagged",
|
|
4915
4940
|
"roundsHeading": "Review rounds",
|
package/i18n/locales/es.json
CHANGED
|
@@ -1789,7 +1789,9 @@
|
|
|
1789
1789
|
"continueWithConfigured": "Inicia sesión con el PAT de {provider} configurado",
|
|
1790
1790
|
"noPatTitle": "No hay ningún token de control de versiones configurado",
|
|
1791
1791
|
"noPatBody": "Define GITHUB_PAT o GITLAB_PAT en tu .env para iniciar sesión con un token de acceso personal y reinicia el servidor.",
|
|
1792
|
+
"setupBody": "Crea un token de acceso personal y pégalo abajo. Inicia tu sesión y pasa a ser el token con el que esta instalación clona, publica y fusiona.",
|
|
1792
1793
|
"createToken": "Crear un token de {provider} ↗",
|
|
1794
|
+
"tokenBecomesCredential": "Este token se guarda en esta máquina y se usa en cada clonado, push, PR y fusión que hacen los agentes.",
|
|
1793
1795
|
"orDivider": "o",
|
|
1794
1796
|
"failed": "Error al iniciar sesión. Comprueba que el token configurado sea válido e inténtalo de nuevo."
|
|
1795
1797
|
},
|
|
@@ -1820,10 +1822,26 @@
|
|
|
1820
1822
|
"signInFailed": "Error al iniciar sesión. Revisa tus datos e inténtalo de nuevo.",
|
|
1821
1823
|
"genericError": "Algo salió mal. Inténtalo de nuevo.",
|
|
1822
1824
|
"notConfiguredTitle": "La autenticación no está configurada",
|
|
1823
|
-
"notConfiguredBody": "Este despliegue no tiene ningún método de inicio de sesión habilitado, por lo que no puedes iniciar sesión ni acceder a tus espacios de trabajo. Un administrador debe configurar un proveedor de autenticación (OAuth de GitHub o Google, o inicio de sesión con correo y contraseña).",
|
|
1825
|
+
"notConfiguredBody": "Este despliegue no tiene ningún método de inicio de sesión habilitado, por lo que no puedes iniciar sesión ni acceder a tus espacios de trabajo. Un administrador debe configurar un proveedor de autenticación (inicio de sesión único mediante el proveedor de identidad de tu organización, OAuth de GitHub o Google, o inicio de sesión con correo y contraseña).",
|
|
1824
1826
|
"patPlaceholder": "Token de acceso personal de {provider}",
|
|
1825
1827
|
"signInWithPat": "Iniciar sesión con un PAT de {provider}"
|
|
1826
1828
|
},
|
|
1829
|
+
"sso": {
|
|
1830
|
+
"continueWith": "Continuar con {provider}",
|
|
1831
|
+
"failedTitle": "El inicio de sesión único no se completó",
|
|
1832
|
+
"errors": {
|
|
1833
|
+
"stateInvalid": "Ese intento de inicio de sesión ha caducado o ya se usó. Vuelve a empezar desde esta página.",
|
|
1834
|
+
"providerDenied": "Tu proveedor de identidad rechazó el inicio de sesión. Si no lo cancelaste tú, pregunta a tu equipo de TI si esta aplicación está asignada a ti.",
|
|
1835
|
+
"exchangeFailed": "Este despliegue no pudo completar el intercambio con tu proveedor de identidad. Un administrador debe revisar el secreto de cliente y la URL de redirección del inicio de sesión único.",
|
|
1836
|
+
"tokenInvalid": "No se pudo verificar la respuesta de tu proveedor de identidad. Un administrador debe revisar la configuración de inicio de sesión único de este despliegue.",
|
|
1837
|
+
"subjectMissing": "Tu proveedor de identidad no devolvió un identificador de usuario, por lo que no se pudo resolver ninguna cuenta. Un administrador debe revisar qué claims publica.",
|
|
1838
|
+
"groupRequired": "Te has autenticado correctamente, pero no perteneces a ningún grupo del directorio autorizado a usar este despliegue. Pide a tu equipo de TI que te añada.",
|
|
1839
|
+
"domainNotAllowed": "Tu dominio de correo no tiene permitido iniciar sesión en este despliegue. Pregunta a tu equipo de TI qué cuenta debes usar.",
|
|
1840
|
+
"emailRequired": "Este despliegue restringe el inicio de sesión por dominio de correo, pero tu proveedor de identidad no publicó una dirección de correo verificada. Un administrador debe habilitar el claim de correo.",
|
|
1841
|
+
"providerUnreachable": "Tu proveedor de identidad no respondió mientras se completaba el inicio de sesión, por lo que puede estar caído o sin conexión. Vuelve a intentarlo en un momento y avisa a un administrador si sigue ocurriendo.",
|
|
1842
|
+
"unknown": "El inicio de sesión único falló por un motivo que esta versión no reconoce. Inténtalo de nuevo y avisa a un administrador si sigue ocurriendo."
|
|
1843
|
+
}
|
|
1844
|
+
},
|
|
1827
1845
|
"resetPassword": {
|
|
1828
1846
|
"title": "Restablecer contraseña",
|
|
1829
1847
|
"subtitle": "Elige una nueva contraseña para tu cuenta.",
|
|
@@ -4693,6 +4711,7 @@
|
|
|
4693
4711
|
"threshold": "umbral {threshold}",
|
|
4694
4712
|
"thresholdHint": "La puntuacion que este paso tenia que alcanzar, tomada de la politica de fusion de la tarea. Por debajo, el juez devuelve el trabajo al paso que lo produjo con sus hallazgos como retrabajo, o aparca la ejecucion para ti cuando ya no queda presupuesto de intentos.",
|
|
4695
4713
|
"rubricOverridden": "rúbrica del espacio de trabajo",
|
|
4714
|
+
"modelPinUnavailable": "Esta revisión se escribió para el modelo {model}, que esta instalación no puede ejecutar, así que otro modelo puntuó el trabajo.",
|
|
4696
4715
|
"reworkRounds": "revisión {spent}/{budget}",
|
|
4697
4716
|
"findingsHeading": "Lo que señaló la rúbrica",
|
|
4698
4717
|
"roundsHeading": "Rondas de revisión",
|
package/i18n/locales/fr.json
CHANGED
|
@@ -1789,7 +1789,9 @@
|
|
|
1789
1789
|
"continueWithConfigured": "Se connecter avec le PAT {provider} configuré",
|
|
1790
1790
|
"noPatTitle": "Aucun jeton de gestion de versions configuré",
|
|
1791
1791
|
"noPatBody": "Définissez GITHUB_PAT ou GITLAB_PAT dans votre .env pour vous connecter avec un jeton d'accès personnel, puis redémarrez le serveur.",
|
|
1792
|
+
"setupBody": "Créez un jeton d'accès personnel et collez-le ci-dessous. Il vous connecte et devient le jeton avec lequel cette installation clone, pousse et fusionne.",
|
|
1792
1793
|
"createToken": "Créer un jeton {provider} ↗",
|
|
1794
|
+
"tokenBecomesCredential": "Ce jeton est stocké sur cette machine et utilisé pour chaque clone, push, PR et fusion des agents.",
|
|
1793
1795
|
"orDivider": "ou",
|
|
1794
1796
|
"failed": "Échec de la connexion. Vérifiez que le jeton configuré est valide et réessayez."
|
|
1795
1797
|
},
|
|
@@ -1820,10 +1822,26 @@
|
|
|
1820
1822
|
"signInFailed": "Échec de la connexion. Vérifiez vos informations et réessayez.",
|
|
1821
1823
|
"genericError": "Une erreur s'est produite. Veuillez réessayer.",
|
|
1822
1824
|
"notConfiguredTitle": "L'authentification n'est pas configurée",
|
|
1823
|
-
"notConfiguredBody": "Ce déploiement n'a aucune méthode de connexion activée, vous ne pouvez donc pas vous connecter ni accéder à vos espaces de travail. Un administrateur doit configurer un fournisseur d'authentification (OAuth GitHub ou Google, ou connexion par e-mail et mot de passe).",
|
|
1825
|
+
"notConfiguredBody": "Ce déploiement n'a aucune méthode de connexion activée, vous ne pouvez donc pas vous connecter ni accéder à vos espaces de travail. Un administrateur doit configurer un fournisseur d'authentification (authentification unique via le fournisseur d'identité de votre organisation, OAuth GitHub ou Google, ou connexion par e-mail et mot de passe).",
|
|
1824
1826
|
"patPlaceholder": "Jeton d'accès personnel {provider}",
|
|
1825
1827
|
"signInWithPat": "Se connecter avec un PAT {provider}"
|
|
1826
1828
|
},
|
|
1829
|
+
"sso": {
|
|
1830
|
+
"continueWith": "Continuer avec {provider}",
|
|
1831
|
+
"failedTitle": "L'authentification unique n'a pas abouti",
|
|
1832
|
+
"errors": {
|
|
1833
|
+
"stateInvalid": "Cette tentative de connexion a expiré ou a déjà été utilisée. Recommencez depuis cette page.",
|
|
1834
|
+
"providerDenied": "Votre fournisseur d'identité a refusé la connexion. Si vous ne l'avez pas annulée vous-même, demandez à votre service informatique si cette application vous est attribuée.",
|
|
1835
|
+
"exchangeFailed": "Ce déploiement n'a pas pu finaliser l'échange avec votre fournisseur d'identité. Un administrateur doit vérifier le secret client et l'URL de redirection de l'authentification unique.",
|
|
1836
|
+
"tokenInvalid": "La réponse de votre fournisseur d'identité n'a pas pu être vérifiée. Un administrateur doit vérifier la configuration de l'authentification unique de ce déploiement.",
|
|
1837
|
+
"subjectMissing": "Votre fournisseur d'identité n'a pas renvoyé d'identifiant utilisateur, aucun compte n'a donc pu être résolu. Un administrateur doit vérifier les claims qu'il expose.",
|
|
1838
|
+
"groupRequired": "Votre connexion a réussi, mais vous n'appartenez à aucun groupe de l'annuaire autorisé à utiliser ce déploiement. Demandez à votre service informatique de vous ajouter.",
|
|
1839
|
+
"domainNotAllowed": "Votre domaine de messagerie n'est pas autorisé à se connecter à ce déploiement. Demandez à votre service informatique quel compte utiliser.",
|
|
1840
|
+
"emailRequired": "Ce déploiement limite la connexion à certains domaines de messagerie, mais votre fournisseur d'identité n'a pas transmis d'adresse e-mail vérifiée. Un administrateur doit activer le claim e-mail.",
|
|
1841
|
+
"providerUnreachable": "Votre fournisseur d'identité n'a pas répondu pendant la finalisation de la connexion : lui-même ou le réseau qui y mène est peut-être indisponible. Réessayez dans un instant et prévenez un administrateur si cela persiste.",
|
|
1842
|
+
"unknown": "L'authentification unique a échoué pour une raison que cette version ne reconnaît pas. Réessayez et prévenez un administrateur si le problème persiste."
|
|
1843
|
+
}
|
|
1844
|
+
},
|
|
1827
1845
|
"resetPassword": {
|
|
1828
1846
|
"title": "Réinitialiser le mot de passe",
|
|
1829
1847
|
"subtitle": "Choisissez un nouveau mot de passe pour votre compte.",
|
|
@@ -4693,6 +4711,7 @@
|
|
|
4693
4711
|
"threshold": "seuil {threshold}",
|
|
4694
4712
|
"thresholdHint": "Le score que cette etape devait atteindre, issu de la politique de fusion de la tache. En dessous, le juge renvoie le travail a l'etape qui l'a produit avec ses constats a reprendre, ou met l'execution en attente pour vous quand il ne reste plus de budget de tentatives.",
|
|
4695
4713
|
"rubricOverridden": "grille de l'espace de travail",
|
|
4714
|
+
"modelPinUnavailable": "Cette revue a été écrite pour le modèle {model}, que ce déploiement ne peut pas exécuter : un autre modèle a donc noté le travail.",
|
|
4696
4715
|
"reworkRounds": "reprise {spent}/{budget}",
|
|
4697
4716
|
"findingsHeading": "Ce que la grille a signalé",
|
|
4698
4717
|
"roundsHeading": "Tours de revue",
|
package/i18n/locales/he.json
CHANGED
|
@@ -1789,7 +1789,9 @@
|
|
|
1789
1789
|
"continueWithConfigured": "התחבר באמצעות PAT מוגדר של {provider}",
|
|
1790
1790
|
"noPatTitle": "לא הוגדר טוקן לבקרת מקור",
|
|
1791
1791
|
"noPatBody": "הגדר את GITHUB_PAT או GITLAB_PAT בקובץ ה-.env שלך כדי להתחבר עם טוקן גישה אישי, ואז הפעל מחדש את השרת.",
|
|
1792
|
+
"setupBody": "צור טוקן גישה אישי והדבק אותו למטה. הוא מחבר אותך וגם הופך לטוקן שבו ההתקנה הזו משכפלת, דוחפת וממזגת.",
|
|
1792
1793
|
"createToken": "צור טוקן {provider} ↗",
|
|
1794
|
+
"tokenBecomesCredential": "הטוקן נשמר במחשב הזה ומשמש לכל שכפול, דחיפה, PR ומיזוג שהסוכנים מבצעים.",
|
|
1793
1795
|
"orDivider": "או",
|
|
1794
1796
|
"failed": "ההתחברות נכשלה. ודא שהטוקן המוגדר תקף ונסה שוב."
|
|
1795
1797
|
},
|
|
@@ -1820,10 +1822,26 @@
|
|
|
1820
1822
|
"signInFailed": "ההתחברות נכשלה. בדוק את הפרטים שלך ונסה שוב.",
|
|
1821
1823
|
"genericError": "משהו השתבש. אנא נסה שוב.",
|
|
1822
1824
|
"notConfiguredTitle": "האימות אינו מוגדר",
|
|
1823
|
-
"notConfiguredBody": "בפריסה זו לא מופעלת אף שיטת התחברות, ולכן לא ניתן להתחבר או לגשת למרחבי העבודה שלך. מנהל המערכת צריך להגדיר ספק אימות (GitHub או Google OAuth, או התחברות עם אימייל וסיסמה).",
|
|
1825
|
+
"notConfiguredBody": "בפריסה זו לא מופעלת אף שיטת התחברות, ולכן לא ניתן להתחבר או לגשת למרחבי העבודה שלך. מנהל המערכת צריך להגדיר ספק אימות (התחברות מאוחדת דרך ספק הזהויות של הארגון שלכם, GitHub או Google OAuth, או התחברות עם אימייל וסיסמה).",
|
|
1824
1826
|
"patPlaceholder": "אסימון גישה אישי של {provider}",
|
|
1825
1827
|
"signInWithPat": "התחברות עם PAT של {provider}"
|
|
1826
1828
|
},
|
|
1829
|
+
"sso": {
|
|
1830
|
+
"continueWith": "המשך עם {provider}",
|
|
1831
|
+
"failedTitle": "ההתחברות המאוחדת לא הושלמה",
|
|
1832
|
+
"errors": {
|
|
1833
|
+
"stateInvalid": "ניסיון ההתחברות הזה פג או שכבר נעשה בו שימוש. התחילו מחדש מדף זה.",
|
|
1834
|
+
"providerDenied": "ספק הזהויות שלכם דחה את ההתחברות. אם לא ביטלתם אותה בעצמכם, בדקו עם צוות ה-IT אם היישום הזה מוקצה לכם.",
|
|
1835
|
+
"exchangeFailed": "הפריסה הזו לא הצליחה להשלים את ההחלפה עם ספק הזהויות שלכם. מנהל המערכת צריך לבדוק את סוד הלקוח ואת כתובת ההפניה של ההתחברות המאוחדת.",
|
|
1836
|
+
"tokenInvalid": "לא ניתן היה לאמת את התשובה מספק הזהויות שלכם. מנהל המערכת צריך לבדוק את הגדרות ההתחברות המאוחדת של הפריסה.",
|
|
1837
|
+
"subjectMissing": "ספק הזהויות לא החזיר מזהה משתמש, ולכן לא ניתן היה לאתר חשבון. מנהל המערכת צריך לבדוק אילו claims הוא חושף.",
|
|
1838
|
+
"groupRequired": "ההתחברות הצליחה, אך אינכם חברים בקבוצת ספרייה שמורשית להשתמש בפריסה הזו. בקשו מצוות ה-IT להוסיף אתכם.",
|
|
1839
|
+
"domainNotAllowed": "הדומיין של האימייל שלכם אינו מורשה להתחבר לפריסה הזו. בדקו עם צוות ה-IT באיזה חשבון להשתמש.",
|
|
1840
|
+
"emailRequired": "הפריסה הזו מגבילה התחברות לפי דומיין אימייל, אך ספק הזהויות לא חשף כתובת אימייל מאומתת. מנהל המערכת צריך להפעיל את claim האימייל.",
|
|
1841
|
+
"providerUnreachable": "ספק הזהויות שלך לא הגיב בעת השלמת ההתחברות, ולכן ייתכן שהוא או הרשת אליו אינם זמינים. נסו שוב בעוד רגע, ואם התקלה חוזרת דווחו למנהל המערכת.",
|
|
1842
|
+
"unknown": "ההתחברות המאוחדת נכשלה מסיבה שגרסה זו אינה מזהה. נסו שוב, ואם התקלה חוזרת עדכנו את מנהל המערכת."
|
|
1843
|
+
}
|
|
1844
|
+
},
|
|
1827
1845
|
"resetPassword": {
|
|
1828
1846
|
"title": "אפס סיסמה",
|
|
1829
1847
|
"subtitle": "בחר סיסמה חדשה לחשבונך.",
|
|
@@ -4693,6 +4711,7 @@
|
|
|
4693
4711
|
"threshold": "סף {threshold}",
|
|
4694
4712
|
"thresholdHint": "הציון שהשלב הזה היה צריך להגיע אליו, לפי מדיניות המיזוג של המשימה. מתחת לכך השופט מחזיר את העבודה לשלב שיצר אותה, עם הממצאים לתיקון, או משהה עבורכם את ההרצה כשלא נותר תקציב ניסיונות.",
|
|
4695
4713
|
"rubricOverridden": "מחוון סביבת העבודה",
|
|
4714
|
+
"modelPinUnavailable": "הביקורת הזו נכתבה עבור המודל {model}, שהפריסה הזו לא יכולה להריץ, ולכן מודל אחר ניקד את העבודה.",
|
|
4696
4715
|
"reworkRounds": "עיבוד מחדש {spent}/{budget}",
|
|
4697
4716
|
"findingsHeading": "מה שהמחוון סימן",
|
|
4698
4717
|
"roundsHeading": "סבבי בדיקה",
|
package/i18n/locales/it.json
CHANGED
|
@@ -3644,7 +3644,9 @@
|
|
|
3644
3644
|
"continueWithConfigured": "Accedi con il PAT {provider} configurato",
|
|
3645
3645
|
"noPatTitle": "Nessun token di controllo del codice sorgente configurato",
|
|
3646
3646
|
"noPatBody": "Imposta GITHUB_PAT o GITLAB_PAT nel tuo file .env per accedere con un personal access token, poi riavvia il server.",
|
|
3647
|
+
"setupBody": "Crea un personal access token e incollalo qui sotto. Ti autentica e diventa il token con cui questa installazione clona, pubblica e unisce.",
|
|
3647
3648
|
"createToken": "Crea un token {provider} ↗",
|
|
3649
|
+
"tokenBecomesCredential": "Questo token viene salvato su questa macchina e usato per ogni clone, push, PR e merge degli agenti.",
|
|
3648
3650
|
"orDivider": "oppure",
|
|
3649
3651
|
"failed": "Accesso non riuscito. Verifica che il token configurato sia valido e riprova."
|
|
3650
3652
|
},
|
|
@@ -3675,10 +3677,26 @@
|
|
|
3675
3677
|
"signInFailed": "Accesso non riuscito. Controlla i tuoi dati e riprova.",
|
|
3676
3678
|
"genericError": "Qualcosa è andato storto. Riprova.",
|
|
3677
3679
|
"notConfiguredTitle": "L'autenticazione non è configurata",
|
|
3678
|
-
"notConfiguredBody": "Questo deployment non ha alcun metodo di accesso abilitato, quindi non puoi accedere o utilizzare i tuoi workspace. Un amministratore deve configurare un provider di autenticazione (OAuth GitHub o Google, oppure accesso con email e password).",
|
|
3680
|
+
"notConfiguredBody": "Questo deployment non ha alcun metodo di accesso abilitato, quindi non puoi accedere o utilizzare i tuoi workspace. Un amministratore deve configurare un provider di autenticazione (accesso unico tramite il provider di identità della tua organizzazione, OAuth GitHub o Google, oppure accesso con email e password).",
|
|
3679
3681
|
"patPlaceholder": "personal access token {provider}",
|
|
3680
3682
|
"signInWithPat": "Accedi con il PAT {provider}"
|
|
3681
3683
|
},
|
|
3684
|
+
"sso": {
|
|
3685
|
+
"continueWith": "Continua con {provider}",
|
|
3686
|
+
"failedTitle": "L'accesso unico non è stato completato",
|
|
3687
|
+
"errors": {
|
|
3688
|
+
"stateInvalid": "Questo tentativo di accesso è scaduto o è già stato usato. Riprova da questa pagina.",
|
|
3689
|
+
"providerDenied": "Il tuo provider di identità ha rifiutato l'accesso. Se non l'hai annullato tu, chiedi al team IT se questa applicazione ti è stata assegnata.",
|
|
3690
|
+
"exchangeFailed": "Questo deployment non ha potuto completare lo scambio con il tuo provider di identità. Un amministratore deve verificare il client secret e l'URL di reindirizzamento dell'accesso unico.",
|
|
3691
|
+
"tokenInvalid": "Non è stato possibile verificare la risposta del tuo provider di identità. Un amministratore deve controllare la configurazione dell'accesso unico di questo deployment.",
|
|
3692
|
+
"subjectMissing": "Il tuo provider di identità non ha restituito un identificatore utente, quindi non è stato possibile risolvere alcun account. Un amministratore deve controllare quali claim vengono esposti.",
|
|
3693
|
+
"groupRequired": "L'accesso è riuscito, ma non appartieni a nessun gruppo della directory autorizzato a usare questo deployment. Chiedi al team IT di aggiungerti.",
|
|
3694
|
+
"domainNotAllowed": "Il tuo dominio email non è autorizzato ad accedere a questo deployment. Chiedi al team IT quale account usare.",
|
|
3695
|
+
"emailRequired": "Questo deployment limita l'accesso per dominio email, ma il tuo provider di identità non ha esposto un indirizzo email verificato. Un amministratore deve abilitare il claim email.",
|
|
3696
|
+
"providerUnreachable": "Il tuo provider di identità non ha risposto durante il completamento dell'accesso, quindi potrebbe non essere raggiungibile. Riprova tra un momento e avvisa un amministratore se il problema persiste.",
|
|
3697
|
+
"unknown": "L'accesso unico è fallito per un motivo che questa versione non riconosce. Riprova e avvisa un amministratore se il problema persiste."
|
|
3698
|
+
}
|
|
3699
|
+
},
|
|
3682
3700
|
"resetPassword": {
|
|
3683
3701
|
"title": "Reimposta password",
|
|
3684
3702
|
"subtitle": "Scegli una nuova password per il tuo account.",
|
|
@@ -5551,6 +5569,7 @@
|
|
|
5551
5569
|
"threshold": "soglia {threshold}",
|
|
5552
5570
|
"thresholdHint": "Il punteggio che questo step doveva raggiungere, preso dalla policy di merge dell'attivita. Al di sotto il giudice rimanda il lavoro allo step che lo ha prodotto, con i suoi rilievi da correggere, oppure mette in pausa l'esecuzione per te quando non resta budget di tentativi.",
|
|
5553
5571
|
"rubricOverridden": "rubrica dello spazio di lavoro",
|
|
5572
|
+
"modelPinUnavailable": "Questa revisione è stata scritta per il modello {model}, che questa installazione non può eseguire, quindi il lavoro è stato valutato da un altro modello.",
|
|
5554
5573
|
"reworkRounds": "revisione {spent}/{budget}",
|
|
5555
5574
|
"findingsHeading": "Cosa ha segnalato la rubrica",
|
|
5556
5575
|
"roundsHeading": "Cicli di revisione",
|
package/i18n/locales/ja.json
CHANGED
|
@@ -1789,7 +1789,9 @@
|
|
|
1789
1789
|
"continueWithConfigured": "設定済みの {provider} PAT でサインイン",
|
|
1790
1790
|
"noPatTitle": "ソース管理トークンが設定されていません",
|
|
1791
1791
|
"noPatBody": ".env に GITHUB_PAT または GITLAB_PAT を設定するとパーソナルアクセストークンでサインインできます。設定後、サーバーを再起動してください。",
|
|
1792
|
+
"setupBody": "パーソナルアクセストークンを作成して下に貼り付けてください。サインインに使われるとともに、この環境がクローン・プッシュ・マージに使うトークンになります。",
|
|
1792
1793
|
"createToken": "{provider} トークンを作成 ↗",
|
|
1794
|
+
"tokenBecomesCredential": "このトークンはこのマシンに保存され、エージェントによるクローン・プッシュ・PR・マージのすべてに使われます。",
|
|
1793
1795
|
"orDivider": "または",
|
|
1794
1796
|
"failed": "サインインに失敗しました。設定されたトークンが有効か確認して、もう一度お試しください。"
|
|
1795
1797
|
},
|
|
@@ -1820,10 +1822,26 @@
|
|
|
1820
1822
|
"signInFailed": "サインインに失敗しました。入力内容を確認して、もう一度お試しください。",
|
|
1821
1823
|
"genericError": "問題が発生しました。もう一度お試しください。",
|
|
1822
1824
|
"notConfiguredTitle": "認証が設定されていません",
|
|
1823
|
-
"notConfiguredBody": "
|
|
1825
|
+
"notConfiguredBody": "このデプロイにはサインイン方法が有効になっていないため、サインインやワークスペースへのアクセスができません。管理者が認証プロバイダー(組織の ID プロバイダーによるシングルサインオン、GitHub または Google の OAuth、あるいはメールアドレスとパスワードによるログイン)を設定する必要があります。",
|
|
1824
1826
|
"patPlaceholder": "{provider} のパーソナルアクセストークン",
|
|
1825
1827
|
"signInWithPat": "{provider} の PAT でサインイン"
|
|
1826
1828
|
},
|
|
1829
|
+
"sso": {
|
|
1830
|
+
"continueWith": "{provider} で続行",
|
|
1831
|
+
"failedTitle": "シングルサインオンを完了できませんでした",
|
|
1832
|
+
"errors": {
|
|
1833
|
+
"stateInvalid": "このサインイン試行は期限切れか、すでに使用されています。このページからやり直してください。",
|
|
1834
|
+
"providerDenied": "ID プロバイダーがサインインを拒否しました。ご自身でキャンセルしていない場合は、このアプリケーションが割り当てられているか IT 部門に確認してください。",
|
|
1835
|
+
"exchangeFailed": "このデプロイは ID プロバイダーとの交換を完了できませんでした。管理者がシングルサインオンのクライアントシークレットとリダイレクト URL を確認する必要があります。",
|
|
1836
|
+
"tokenInvalid": "ID プロバイダーからの応答を検証できませんでした。管理者がこのデプロイのシングルサインオン設定を確認する必要があります。",
|
|
1837
|
+
"subjectMissing": "ID プロバイダーがユーザー識別子を返さなかったため、アカウントを特定できませんでした。管理者が公開しているクレームを確認する必要があります。",
|
|
1838
|
+
"groupRequired": "サインインは成功しましたが、このデプロイの利用を許可されたディレクトリグループに所属していません。IT 部門に追加を依頼してください。",
|
|
1839
|
+
"domainNotAllowed": "お使いのメールドメインはこのデプロイへのサインインを許可されていません。どのアカウントを使うべきか IT 部門に確認してください。",
|
|
1840
|
+
"emailRequired": "このデプロイはメールドメインでサインインを制限していますが、ID プロバイダーが検証済みのメールアドレスを公開しませんでした。管理者がメールクレームを有効にする必要があります。",
|
|
1841
|
+
"providerUnreachable": "サインインの完了中に ID プロバイダーから応答がありませんでした。プロバイダー自体か、そこへのネットワークが停止している可能性があります。少し待ってからもう一度お試しいただき、繰り返す場合は管理者にお知らせください。",
|
|
1842
|
+
"unknown": "このバージョンが認識できない理由でシングルサインオンに失敗しました。もう一度お試しいただき、繰り返す場合は管理者にご連絡ください。"
|
|
1843
|
+
}
|
|
1844
|
+
},
|
|
1827
1845
|
"resetPassword": {
|
|
1828
1846
|
"title": "パスワードをリセット",
|
|
1829
1847
|
"subtitle": "アカウントの新しいパスワードを選択してください。",
|
|
@@ -4693,6 +4711,7 @@
|
|
|
4693
4711
|
"threshold": "しきい値 {threshold}",
|
|
4694
4712
|
"thresholdHint": "このステップが達成すべきスコアで、タスクのマージポリシーから取られます。これを下回ると、ジャッジは指摘事項を手戻りとして生成元のステップに差し戻すか、試行回数の予算が尽きている場合は実行を保留してあなたの判断を待ちます。",
|
|
4695
4713
|
"rubricOverridden": "ワークスペースのルーブリック",
|
|
4714
|
+
"modelPinUnavailable": "このレビューは {model} モデル向けに書かれていますが、このデプロイでは実行できないため、別のモデルが作業を採点しました。",
|
|
4696
4715
|
"reworkRounds": "手戻り {spent}/{budget}",
|
|
4697
4716
|
"findingsHeading": "ルーブリックが指摘した点",
|
|
4698
4717
|
"roundsHeading": "レビューの回数",
|
package/i18n/locales/pl.json
CHANGED
|
@@ -1789,7 +1789,9 @@
|
|
|
1789
1789
|
"continueWithConfigured": "Zaloguj się skonfigurowanym tokenem PAT {provider}",
|
|
1790
1790
|
"noPatTitle": "Nie skonfigurowano tokenu systemu kontroli wersji",
|
|
1791
1791
|
"noPatBody": "Ustaw GITHUB_PAT lub GITLAB_PAT w pliku .env, aby zalogować się za pomocą osobistego tokenu dostępu, a następnie zrestartuj serwer.",
|
|
1792
|
+
"setupBody": "Utwórz osobisty token dostępu i wklej go poniżej. Zaloguje Cię i stanie się tokenem, którym ta instalacja klonuje, wypycha zmiany i scala.",
|
|
1792
1793
|
"createToken": "Utwórz token {provider} ↗",
|
|
1794
|
+
"tokenBecomesCredential": "Token jest zapisywany na tym komputerze i używany przy każdym klonowaniu, wypchnięciu, PR i scaleniu wykonywanym przez agentów.",
|
|
1793
1795
|
"orDivider": "lub",
|
|
1794
1796
|
"failed": "Logowanie nie powiodło się. Sprawdź, czy skonfigurowany token jest prawidłowy, i spróbuj ponownie."
|
|
1795
1797
|
},
|
|
@@ -1820,10 +1822,26 @@
|
|
|
1820
1822
|
"signInFailed": "Logowanie nie powiodło się. Sprawdź swoje dane i spróbuj ponownie.",
|
|
1821
1823
|
"genericError": "Coś poszło nie tak. Spróbuj ponownie.",
|
|
1822
1824
|
"notConfiguredTitle": "Uwierzytelnianie nie jest skonfigurowane",
|
|
1823
|
-
"notConfiguredBody": "To wdrożenie nie ma włączonej żadnej metody logowania, więc nie możesz się zalogować ani uzyskać dostępu do swoich przestrzeni roboczych. Administrator musi skonfigurować dostawcę uwierzytelniania (OAuth GitHub lub Google albo logowanie e-mailem i hasłem).",
|
|
1825
|
+
"notConfiguredBody": "To wdrożenie nie ma włączonej żadnej metody logowania, więc nie możesz się zalogować ani uzyskać dostępu do swoich przestrzeni roboczych. Administrator musi skonfigurować dostawcę uwierzytelniania (logowanie jednokrotne przez dostawcę tożsamości Twojej organizacji, OAuth GitHub lub Google albo logowanie e-mailem i hasłem).",
|
|
1824
1826
|
"patPlaceholder": "Osobisty token dostępu {provider}",
|
|
1825
1827
|
"signInWithPat": "Zaloguj się tokenem PAT {provider}"
|
|
1826
1828
|
},
|
|
1829
|
+
"sso": {
|
|
1830
|
+
"continueWith": "Kontynuuj z {provider}",
|
|
1831
|
+
"failedTitle": "Nie udało się ukończyć logowania jednokrotnego",
|
|
1832
|
+
"errors": {
|
|
1833
|
+
"stateInvalid": "Ta próba logowania wygasła lub została już użyta. Zacznij ponownie z tej strony.",
|
|
1834
|
+
"providerDenied": "Twój dostawca tożsamości odrzucił logowanie. Jeśli nie anulowałeś go samodzielnie, zapytaj zespół IT, czy ta aplikacja jest do Ciebie przypisana.",
|
|
1835
|
+
"exchangeFailed": "To wdrożenie nie mogło zakończyć wymiany z dostawcą tożsamości. Administrator musi sprawdzić sekret klienta i adres przekierowania logowania jednokrotnego.",
|
|
1836
|
+
"tokenInvalid": "Nie udało się zweryfikować odpowiedzi dostawcy tożsamości. Administrator musi sprawdzić konfigurację logowania jednokrotnego tego wdrożenia.",
|
|
1837
|
+
"subjectMissing": "Dostawca tożsamości nie zwrócił identyfikatora użytkownika, więc nie udało się ustalić konta. Administrator musi sprawdzić, które oświadczenia (claims) są udostępniane.",
|
|
1838
|
+
"groupRequired": "Logowanie się udało, ale nie należysz do żadnej grupy katalogowej uprawnionej do korzystania z tego wdrożenia. Poproś zespół IT o dodanie Cię.",
|
|
1839
|
+
"domainNotAllowed": "Twoja domena e-mail nie ma uprawnień do logowania w tym wdrożeniu. Zapytaj zespół IT, którego konta użyć.",
|
|
1840
|
+
"emailRequired": "To wdrożenie ogranicza logowanie do wybranych domen e-mail, ale dostawca tożsamości nie udostępnił zweryfikowanego adresu e-mail. Administrator musi włączyć oświadczenie e-mail.",
|
|
1841
|
+
"providerUnreachable": "Twój dostawca tożsamości nie odpowiedział podczas kończenia logowania, więc on sam lub połączenie z nim może być niedostępne. Spróbuj ponownie po chwili, a jeśli problem się powtarza, powiadom administratora.",
|
|
1842
|
+
"unknown": "Logowanie jednokrotne nie powiodło się z powodu, którego ta wersja nie rozpoznaje. Spróbuj ponownie, a jeśli problem się powtarza, powiadom administratora."
|
|
1843
|
+
}
|
|
1844
|
+
},
|
|
1827
1845
|
"resetPassword": {
|
|
1828
1846
|
"title": "Zresetuj hasło",
|
|
1829
1847
|
"subtitle": "Wybierz nowe hasło do swojego konta.",
|
|
@@ -4693,6 +4711,7 @@
|
|
|
4693
4711
|
"threshold": "próg {threshold}",
|
|
4694
4712
|
"thresholdHint": "Wynik, który ten krok musiał osiągnąć, wzięty z polityki scalania zadania. Poniżej sędzia odsyła pracę do kroku, który ją wytworzył, przekazując swoje uwagi do poprawy, albo wstrzymuje przebieg i czeka na Ciebie, gdy skończy się budżet prób.",
|
|
4695
4713
|
"rubricOverridden": "rubryka przestrzeni roboczej",
|
|
4714
|
+
"modelPinUnavailable": "Ta ocena została napisana dla modelu {model}, którego to wdrożenie nie może uruchomić, więc pracę ocenił inny model.",
|
|
4696
4715
|
"reworkRounds": "poprawki {spent}/{budget}",
|
|
4697
4716
|
"findingsHeading": "Co zgłosiła rubryka",
|
|
4698
4717
|
"roundsHeading": "Rundy przeglądu",
|
package/i18n/locales/tr.json
CHANGED
|
@@ -1789,7 +1789,9 @@
|
|
|
1789
1789
|
"continueWithConfigured": "Yapılandırılmış {provider} PAT ile oturum aç",
|
|
1790
1790
|
"noPatTitle": "Yapılandırılmış kaynak denetimi token'ı yok",
|
|
1791
1791
|
"noPatBody": "Kişisel erişim token'ı ile oturum açmak için .env dosyanızda GITHUB_PAT veya GITLAB_PAT ayarlayın, ardından sunucuyu yeniden başlatın.",
|
|
1792
|
+
"setupBody": "Bir kişisel erişim token’ı oluşturup aşağıya yapıştırın. Hem oturumunuzu açar hem de bu kurulumun klonlama, push ve birleştirme işlemlerinde kullandığı token olur.",
|
|
1792
1793
|
"createToken": "{provider} token'ı oluştur ↗",
|
|
1794
|
+
"tokenBecomesCredential": "Bu token bu makinede saklanır ve ajanların yaptığı her klonlama, push, PR ve birleştirmede kullanılır.",
|
|
1793
1795
|
"orDivider": "veya",
|
|
1794
1796
|
"failed": "Oturum açma başarısız. Yapılandırılan token'ın geçerli olduğunu kontrol edip tekrar deneyin."
|
|
1795
1797
|
},
|
|
@@ -1820,10 +1822,26 @@
|
|
|
1820
1822
|
"signInFailed": "Oturum açma başarısız. Bilgilerinizi kontrol edip tekrar deneyin.",
|
|
1821
1823
|
"genericError": "Bir şeyler ters gitti. Lütfen tekrar deneyin.",
|
|
1822
1824
|
"notConfiguredTitle": "Kimlik doğrulama yapılandırılmamış",
|
|
1823
|
-
"notConfiguredBody": "Bu dağıtımda etkin bir oturum açma yöntemi yok, bu nedenle oturum açamaz veya çalışma alanlarınıza erişemezsiniz. Bir yönetici, bir kimlik doğrulama sağlayıcısı (GitHub veya Google OAuth ya da e-posta ve parola ile oturum açma) yapılandırmalıdır.",
|
|
1825
|
+
"notConfiguredBody": "Bu dağıtımda etkin bir oturum açma yöntemi yok, bu nedenle oturum açamaz veya çalışma alanlarınıza erişemezsiniz. Bir yönetici, bir kimlik doğrulama sağlayıcısı (kuruluşunuzun kimlik sağlayıcısı üzerinden tek oturum açma, GitHub veya Google OAuth ya da e-posta ve parola ile oturum açma) yapılandırmalıdır.",
|
|
1824
1826
|
"patPlaceholder": "{provider} kişisel erişim belirteci",
|
|
1825
1827
|
"signInWithPat": "{provider} PAT ile oturum aç"
|
|
1826
1828
|
},
|
|
1829
|
+
"sso": {
|
|
1830
|
+
"continueWith": "{provider} ile devam et",
|
|
1831
|
+
"failedTitle": "Tek oturum açma tamamlanamadı",
|
|
1832
|
+
"errors": {
|
|
1833
|
+
"stateInvalid": "Bu oturum açma denemesinin süresi doldu veya daha önce kullanıldı. Bu sayfadan yeniden başlayın.",
|
|
1834
|
+
"providerDenied": "Kimlik sağlayıcınız oturum açmayı reddetti. İptal eden siz değilseniz, bu uygulamanın size atanıp atanmadığını BT ekibinize sorun.",
|
|
1835
|
+
"exchangeFailed": "Bu dağıtım, kimlik sağlayıcınızla değişimi tamamlayamadı. Bir yöneticinin tek oturum açma istemci parolasını ve yönlendirme adresini kontrol etmesi gerekiyor.",
|
|
1836
|
+
"tokenInvalid": "Kimlik sağlayıcınızdan gelen yanıt doğrulanamadı. Bir yöneticinin bu dağıtımın tek oturum açma yapılandırmasını kontrol etmesi gerekiyor.",
|
|
1837
|
+
"subjectMissing": "Kimlik sağlayıcınız bir kullanıcı tanımlayıcısı döndürmedi, bu nedenle hiçbir hesap çözümlenemedi. Bir yöneticinin hangi taleplerin (claims) paylaşıldığını kontrol etmesi gerekiyor.",
|
|
1838
|
+
"groupRequired": "Oturum açma başarılı oldu, ancak bu dağıtımı kullanmasına izin verilen bir dizin grubunda değilsiniz. BT ekibinizden sizi eklemesini isteyin.",
|
|
1839
|
+
"domainNotAllowed": "E-posta alan adınızın bu dağıtımda oturum açma izni yok. Hangi hesabı kullanmanız gerektiğini BT ekibinize sorun.",
|
|
1840
|
+
"emailRequired": "Bu dağıtım oturum açmayı e-posta alan adına göre kısıtlıyor, ancak kimlik sağlayıcınız doğrulanmış bir e-posta adresi paylaşmadı. Bir yöneticinin e-posta talebini etkinleştirmesi gerekiyor.",
|
|
1841
|
+
"providerUnreachable": "Oturum açma işlemi tamamlanırken kimlik sağlayıcınız yanıt vermedi; sağlayıcı ya da ona giden ağ çalışmıyor olabilir. Biraz sonra yeniden deneyin, sorun sürerse bir yöneticiye bildirin.",
|
|
1842
|
+
"unknown": "Tek oturum açma, bu sürümün tanımadığı bir nedenle başarısız oldu. Tekrar deneyin ve sorun sürerse bir yöneticiye bildirin."
|
|
1843
|
+
}
|
|
1844
|
+
},
|
|
1827
1845
|
"resetPassword": {
|
|
1828
1846
|
"title": "Parolayı sıfırla",
|
|
1829
1847
|
"subtitle": "Hesabınız için yeni bir parola seçin.",
|
|
@@ -4693,6 +4711,7 @@
|
|
|
4693
4711
|
"threshold": "eşik {threshold}",
|
|
4694
4712
|
"thresholdHint": "Bu adımın ulaşması gereken puan; görevin birleştirme politikasından alınır. Altında kaldığında hakem, bulgularını yeniden çalışma olarak ekleyip işi üreten adıma geri gönderir; deneme bütçesi kalmadıysa çalıştırmayı sizin için beklemeye alır.",
|
|
4695
4713
|
"rubricOverridden": "çalışma alanı ölçütü",
|
|
4714
|
+
"modelPinUnavailable": "Bu inceleme {model} modeli için yazıldı ancak bu kurulum onu çalıştıramıyor, bu yüzden işi başka bir model puanladı.",
|
|
4696
4715
|
"reworkRounds": "yeniden çalışma {spent}/{budget}",
|
|
4697
4716
|
"findingsHeading": "Ölçütün işaretledikleri",
|
|
4698
4717
|
"roundsHeading": "İnceleme turları",
|
package/i18n/locales/uk.json
CHANGED
|
@@ -1789,7 +1789,9 @@
|
|
|
1789
1789
|
"continueWithConfigured": "Увійти за допомогою налаштованого PAT {provider}",
|
|
1790
1790
|
"noPatTitle": "Токен системи контролю версій не налаштовано",
|
|
1791
1791
|
"noPatBody": "Установіть GITHUB_PAT або GITLAB_PAT у файлі .env, щоб увійти за допомогою особистого токена доступу, потім перезапустіть сервер.",
|
|
1792
|
+
"setupBody": "Створіть особистий токен доступу та вставте його нижче. Він виконає вхід і стане токеном, яким ця інсталяція клонує, надсилає зміни та зливає гілки.",
|
|
1792
1793
|
"createToken": "Створити токен {provider} ↗",
|
|
1794
|
+
"tokenBecomesCredential": "Токен зберігається на цій машині й використовується для кожного клонування, надсилання, PR та злиття, які роблять агенти.",
|
|
1793
1795
|
"orDivider": "або",
|
|
1794
1796
|
"failed": "Не вдалося увійти. Перевірте, що налаштований токен дійсний, і спробуйте ще раз."
|
|
1795
1797
|
},
|
|
@@ -1820,10 +1822,26 @@
|
|
|
1820
1822
|
"signInFailed": "Не вдалося увійти. Перевірте свої дані та спробуйте ще раз.",
|
|
1821
1823
|
"genericError": "Щось пішло не так. Спробуйте ще раз.",
|
|
1822
1824
|
"notConfiguredTitle": "Автентифікацію не налаштовано",
|
|
1823
|
-
"notConfiguredBody": "У цьому розгортанні не ввімкнено жодного способу входу, тому ви не можете увійти чи отримати доступ до своїх робочих просторів. Адміністратор має налаштувати постачальника автентифікації (OAuth GitHub або Google чи вхід за електронною поштою та паролем).",
|
|
1825
|
+
"notConfiguredBody": "У цьому розгортанні не ввімкнено жодного способу входу, тому ви не можете увійти чи отримати доступ до своїх робочих просторів. Адміністратор має налаштувати постачальника автентифікації (єдиний вхід через постачальника ідентифікації вашої організації, OAuth GitHub або Google чи вхід за електронною поштою та паролем).",
|
|
1824
1826
|
"patPlaceholder": "Особистий токен доступу {provider}",
|
|
1825
1827
|
"signInWithPat": "Увійти за допомогою PAT {provider}"
|
|
1826
1828
|
},
|
|
1829
|
+
"sso": {
|
|
1830
|
+
"continueWith": "Продовжити з {provider}",
|
|
1831
|
+
"failedTitle": "Єдиний вхід не завершено",
|
|
1832
|
+
"errors": {
|
|
1833
|
+
"stateInvalid": "Ця спроба входу застаріла або вже була використана. Почніть знову з цієї сторінки.",
|
|
1834
|
+
"providerDenied": "Ваш постачальник ідентифікації відмовив у вході. Якщо ви не скасовували його самостійно, запитайте у своєї ІТ-команди, чи призначено вам цей застосунок.",
|
|
1835
|
+
"exchangeFailed": "Це розгортання не змогло завершити обмін із вашим постачальником ідентифікації. Адміністратор має перевірити клієнтський секрет і URL перенаправлення єдиного входу.",
|
|
1836
|
+
"tokenInvalid": "Не вдалося перевірити відповідь вашого постачальника ідентифікації. Адміністратор має перевірити налаштування єдиного входу цього розгортання.",
|
|
1837
|
+
"subjectMissing": "Постачальник ідентифікації не повернув ідентифікатора користувача, тому обліковий запис не вдалося визначити. Адміністратор має перевірити, які claims він передає.",
|
|
1838
|
+
"groupRequired": "Вхід відбувся успішно, але ви не належите до жодної групи каталогу, якій дозволено користуватися цим розгортанням. Попросіть ІТ-команду додати вас.",
|
|
1839
|
+
"domainNotAllowed": "Вашому домену електронної пошти не дозволено входити до цього розгортання. Запитайте в ІТ-команди, який обліковий запис використати.",
|
|
1840
|
+
"emailRequired": "Це розгортання обмежує вхід за доменом електронної пошти, але ваш постачальник ідентифікації не передав підтвердженої адреси. Адміністратор має увімкнути claim електронної пошти.",
|
|
1841
|
+
"providerUnreachable": "Ваш постачальник ідентифікації не відповів під час завершення входу, тож він або мережа до нього можуть бути недоступні. Спробуйте ще раз за мить, а якщо це повторюється, повідомте адміністратора.",
|
|
1842
|
+
"unknown": "Єдиний вхід не вдався з причини, якої ця версія не розпізнає. Спробуйте ще раз, а якщо проблема повторюється, повідомте адміністратора."
|
|
1843
|
+
}
|
|
1844
|
+
},
|
|
1827
1845
|
"resetPassword": {
|
|
1828
1846
|
"title": "Скинути пароль",
|
|
1829
1847
|
"subtitle": "Виберіть новий пароль для свого облікового запису.",
|
|
@@ -4693,6 +4711,7 @@
|
|
|
4693
4711
|
"threshold": "поріг {threshold}",
|
|
4694
4712
|
"thresholdHint": "Оцінка, якої мав досягти цей крок, узята з політики злиття завдання. Нижче за неї суддя повертає роботу до кроку, що її створив, разом зі своїми зауваженнями на доопрацювання, або ставить запуск на паузу для вас, коли бюджет спроб вичерпано.",
|
|
4695
4713
|
"rubricOverridden": "рубрика робочого простору",
|
|
4714
|
+
"modelPinUnavailable": "Цю перевірку написано для моделі {model}, яку це розгортання не може запустити, тож роботу оцінила інша модель.",
|
|
4696
4715
|
"reworkRounds": "доопрацювання {spent}/{budget}",
|
|
4697
4716
|
"findingsHeading": "Що позначила рубрика",
|
|
4698
4717
|
"roundsHeading": "Раунди перевірки",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.231.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",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"valibot": "^1.4.2",
|
|
41
41
|
"vue": "3.5.40",
|
|
42
42
|
"wretch": "^3.0.9",
|
|
43
|
-
"@cat-factory/contracts": "0.
|
|
43
|
+
"@cat-factory/contracts": "0.248.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@toad-contracts/testing": "0.3.2",
|