@cat-factory/app 0.228.1 → 0.230.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/auth/LoginScreen.vue +59 -0
- 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/components/settings/McpOAuthCallbackScreen.vue +103 -0
- package/app/components/settings/ToolServerChecklist.vue +111 -0
- package/app/composables/api/toolServers.ts +23 -1
- package/app/pages/mcp-oauth-callback.vue +7 -0
- 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/stores/toolServers.ts +57 -1
- package/app/types/toolServers.ts +2 -0
- package/app/utils/sso.spec.ts +39 -0
- package/app/utils/sso.ts +41 -0
- package/i18n/locales/de.json +44 -2
- package/i18n/locales/en.json +50 -2
- package/i18n/locales/es.json +44 -2
- package/i18n/locales/fr.json +44 -2
- package/i18n/locales/he.json +44 -2
- package/i18n/locales/it.json +44 -2
- package/i18n/locales/ja.json +44 -2
- package/i18n/locales/pl.json +44 -2
- package/i18n/locales/tr.json +44 -2
- package/i18n/locales/uk.json +44 -2
- package/package.json +2 -2
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,
|
|
@@ -25,6 +25,9 @@ export const useToolServersStore = defineStore('toolServers', () => {
|
|
|
25
25
|
// operator just asked for.
|
|
26
26
|
const results = ref<Record<string, ToolServerProbeResult>>({})
|
|
27
27
|
const probing = ref<string | null>(null)
|
|
28
|
+
// The server whose OAuth grant is being connected or disconnected, so one row's button spins and
|
|
29
|
+
// the rest stay clickable — the same shape `probing` has, and for the same reason.
|
|
30
|
+
const connecting = ref<string | null>(null)
|
|
28
31
|
const loading = ref(false)
|
|
29
32
|
// The backend's two definitive refusals: no `secrets.manage` (403), and — unlike the credential
|
|
30
33
|
// store — never a 503, since the inventory needs no encryption key to project a registry. `null`
|
|
@@ -108,5 +111,58 @@ export const useToolServersStore = defineStore('toolServers', () => {
|
|
|
108
111
|
}
|
|
109
112
|
}
|
|
110
113
|
|
|
111
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Start an OAuth grant and hand the browser to the vendor.
|
|
116
|
+
*
|
|
117
|
+
* A full-page navigation rather than a popup: the operator has to sign in at a third party, and a
|
|
118
|
+
* popup is what a browser blocks and a password manager cannot fill. Nothing is stored here — the
|
|
119
|
+
* vendor redirects back to `/mcp-oauth-callback`, which finishes the grant over the authenticated
|
|
120
|
+
* API and returns here, so the connection state comes from the row rather than from anything this
|
|
121
|
+
* store guessed across a navigation that leaves the app entirely.
|
|
122
|
+
*/
|
|
123
|
+
async function connectOAuth(id: string) {
|
|
124
|
+
const ws = useWorkspaceStore()
|
|
125
|
+
connecting.value = id
|
|
126
|
+
try {
|
|
127
|
+
const { url } = await api.startToolServerOAuth(ws.requireId(), id)
|
|
128
|
+
window.location.href = url
|
|
129
|
+
} finally {
|
|
130
|
+
connecting.value = null
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Drop the workspace's grant, then re-read so the row's state comes from the backend rather than
|
|
136
|
+
* from an optimistic edit: a disconnect is the one action whose whole point is that the server
|
|
137
|
+
* stops being usable, and a row that looked connected for another second would be the misreport
|
|
138
|
+
* this panel exists to prevent.
|
|
139
|
+
*/
|
|
140
|
+
async function disconnectOAuth(id: string) {
|
|
141
|
+
const ws = useWorkspaceStore()
|
|
142
|
+
connecting.value = id
|
|
143
|
+
try {
|
|
144
|
+
await api.disconnectToolServerOAuth(ws.requireId(), id)
|
|
145
|
+
// The stored probe result described a server this board could still reach. It cannot now.
|
|
146
|
+
const { [id]: _dropped, ...rest } = results.value
|
|
147
|
+
results.value = rest
|
|
148
|
+
} finally {
|
|
149
|
+
connecting.value = null
|
|
150
|
+
}
|
|
151
|
+
await load()
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
view,
|
|
156
|
+
results,
|
|
157
|
+
probing,
|
|
158
|
+
connecting,
|
|
159
|
+
loading,
|
|
160
|
+
available,
|
|
161
|
+
hasSurface,
|
|
162
|
+
load,
|
|
163
|
+
ensureLoaded,
|
|
164
|
+
probe,
|
|
165
|
+
connectOAuth,
|
|
166
|
+
disconnectOAuth,
|
|
167
|
+
}
|
|
112
168
|
})
|
package/app/types/toolServers.ts
CHANGED
|
@@ -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
|
@@ -624,6 +624,27 @@
|
|
|
624
624
|
"servableHarnessesNone": "Keine Agenten-CLI kann diesen Transport bedienen, daher greift dieser Server in keinem Lauf.",
|
|
625
625
|
"allowedTools": "Eingeschränkt auf: {tools}",
|
|
626
626
|
"credentials": "Zugangsdaten: {keys}",
|
|
627
|
+
"oauth": {
|
|
628
|
+
"connected": "Verbunden",
|
|
629
|
+
"notConnected": "Nicht verbunden",
|
|
630
|
+
"machineGrant": "Meldet sich als dieses Deployment an",
|
|
631
|
+
"connectedBy": "Verbunden von {user}",
|
|
632
|
+
"scopes": "Gewährt: {scopes}",
|
|
633
|
+
"notRefreshable": "Der Anbieter hat kein Refresh-Token ausgestellt, daher muss diese Verbindung neu hergestellt werden, sobald das Zugriffstoken abläuft.",
|
|
634
|
+
"lastError": "Die letzte Token-Erneuerung ist fehlgeschlagen: {detail}",
|
|
635
|
+
"connect": "Verbinden",
|
|
636
|
+
"reconnect": "Neu verbinden",
|
|
637
|
+
"disconnect": "Trennen",
|
|
638
|
+
"callback": {
|
|
639
|
+
"working": "Verbindung wird abgeschlossen …",
|
|
640
|
+
"done": "Mit {server} verbunden",
|
|
641
|
+
"doneHint": "Die Läufe dieses Boards können den Werkzeugserver jetzt mit dem Konto nutzen, mit dem Sie sich angemeldet haben.",
|
|
642
|
+
"back": "Zurück zur App",
|
|
643
|
+
"failedTitle": "Die Verbindung konnte nicht abgeschlossen werden",
|
|
644
|
+
"failed": "Die Autorisierung konnte nicht abgeschlossen werden. Starten Sie die Verbindung im Infrastruktur-Fenster erneut.",
|
|
645
|
+
"missingParams": "In diesem Link fehlen die vom Anbieter zurückgesendeten Werte, daher gibt es nichts abzuschließen. Starten Sie die Verbindung erneut."
|
|
646
|
+
}
|
|
647
|
+
},
|
|
627
648
|
"test": "Testen",
|
|
628
649
|
"notProbeable": {
|
|
629
650
|
"stdio": "Läuft im Container des Agenten und kann von hier aus nicht getestet werden.",
|
|
@@ -634,6 +655,8 @@
|
|
|
634
655
|
"ok": "Hat geantwortet",
|
|
635
656
|
"credentialsMissing": "Keine Zugangsdaten",
|
|
636
657
|
"credentialRefused": "Zugangsdaten abgelehnt",
|
|
658
|
+
"oauthNotConnected": "Nicht verbunden",
|
|
659
|
+
"oauthTokenFailed": "Verbindung funktioniert nicht mehr",
|
|
637
660
|
"unreachable": "Keine Antwort",
|
|
638
661
|
"httpError": "Anfrage abgewiesen",
|
|
639
662
|
"protocolError": "Kein MCP-Server",
|
|
@@ -650,7 +673,9 @@
|
|
|
650
673
|
"hideDetails": "Details verbergen",
|
|
651
674
|
"toast": {
|
|
652
675
|
"loadFailed": "Die Werkzeugserver konnten nicht geladen werden",
|
|
653
|
-
"probeFailed": "Der Werkzeugserver konnte nicht getestet werden"
|
|
676
|
+
"probeFailed": "Der Werkzeugserver konnte nicht getestet werden",
|
|
677
|
+
"connectFailed": "Die Verbindung konnte nicht gestartet werden",
|
|
678
|
+
"disconnectFailed": "Der Werkzeugserver konnte nicht getrennt werden"
|
|
654
679
|
}
|
|
655
680
|
},
|
|
656
681
|
"capabilityCredentials": {
|
|
@@ -3650,10 +3675,26 @@
|
|
|
3650
3675
|
"signInFailed": "Anmeldung fehlgeschlagen. Prüfen Sie Ihre Angaben und versuchen Sie es erneut.",
|
|
3651
3676
|
"genericError": "Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.",
|
|
3652
3677
|
"notConfiguredTitle": "Authentifizierung ist nicht konfiguriert",
|
|
3653
|
-
"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).",
|
|
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 (Single Sign-on über den Identitätsprovider Ihrer Organisation, GitHub- oder Google-OAuth oder E-Mail-/Passwort-Anmeldung).",
|
|
3654
3679
|
"patPlaceholder": "{provider} Personal Access Token",
|
|
3655
3680
|
"signInWithPat": "Mit {provider}-PAT anmelden"
|
|
3656
3681
|
},
|
|
3682
|
+
"sso": {
|
|
3683
|
+
"continueWith": "Mit {provider} fortfahren",
|
|
3684
|
+
"failedTitle": "Single Sign-on wurde nicht abgeschlossen",
|
|
3685
|
+
"errors": {
|
|
3686
|
+
"stateInvalid": "Dieser Anmeldeversuch ist abgelaufen oder wurde bereits verwendet. Beginnen Sie erneut auf dieser Seite.",
|
|
3687
|
+
"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.",
|
|
3688
|
+
"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.",
|
|
3689
|
+
"tokenInvalid": "Die Antwort Ihres Identitätsproviders konnte nicht verifiziert werden. Ein Administrator muss die Single-Sign-on-Konfiguration dieses Deployments prüfen.",
|
|
3690
|
+
"subjectMissing": "Ihr Identitätsprovider hat keine Benutzerkennung zurückgegeben, daher konnte kein Konto ermittelt werden. Ein Administrator muss prüfen, welche Claims freigegeben werden.",
|
|
3691
|
+
"groupRequired": "Die Anmeldung hat funktioniert, aber Sie sind in keiner Verzeichnisgruppe, die dieses Deployment nutzen darf. Bitten Sie Ihre IT-Abteilung, Sie hinzuzufügen.",
|
|
3692
|
+
"domainNotAllowed": "Ihre E-Mail-Domain darf sich bei diesem Deployment nicht anmelden. Fragen Sie Ihre IT-Abteilung, welches Konto Sie verwenden sollen.",
|
|
3693
|
+
"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.",
|
|
3694
|
+
"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.",
|
|
3695
|
+
"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."
|
|
3696
|
+
}
|
|
3697
|
+
},
|
|
3657
3698
|
"resetPassword": {
|
|
3658
3699
|
"title": "Passwort zurücksetzen",
|
|
3659
3700
|
"subtitle": "Wählen Sie ein neues Passwort für Ihren Account.",
|
|
@@ -5526,6 +5567,7 @@
|
|
|
5526
5567
|
"threshold": "Schwellenwert {threshold}",
|
|
5527
5568
|
"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.",
|
|
5528
5569
|
"rubricOverridden": "Raster des Arbeitsbereichs",
|
|
5570
|
+
"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.",
|
|
5529
5571
|
"reworkRounds": "Überarbeitung {spent}/{budget}",
|
|
5530
5572
|
"findingsHeading": "Was das Bewertungsraster beanstandet hat",
|
|
5531
5573
|
"roundsHeading": "Prüfrunden",
|
package/i18n/locales/en.json
CHANGED
|
@@ -1918,10 +1918,32 @@
|
|
|
1918
1918
|
"signInFailed": "Sign-in failed. Check your details and try again.",
|
|
1919
1919
|
"genericError": "Something went wrong. Please try again.",
|
|
1920
1920
|
"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).",
|
|
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 (single sign-on through your organization's identity provider, GitHub or Google OAuth, or email and password login).",
|
|
1922
1922
|
"patPlaceholder": "{provider} personal access token",
|
|
1923
1923
|
"signInWithPat": "Sign in with {provider} PAT"
|
|
1924
1924
|
},
|
|
1925
|
+
"sso": {
|
|
1926
|
+
"continueWith": "Continue with {provider}",
|
|
1927
|
+
"@continueWith": {
|
|
1928
|
+
"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."
|
|
1929
|
+
},
|
|
1930
|
+
"failedTitle": "Single sign-on didn't complete",
|
|
1931
|
+
"@failedTitle": {
|
|
1932
|
+
"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."
|
|
1933
|
+
},
|
|
1934
|
+
"errors": {
|
|
1935
|
+
"stateInvalid": "That sign-in attempt has expired or was already used. Start again from this page.",
|
|
1936
|
+
"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.",
|
|
1937
|
+
"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.",
|
|
1938
|
+
"tokenInvalid": "The response from your identity provider couldn't be verified. An administrator needs to check this deployment's single sign-on configuration.",
|
|
1939
|
+
"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.",
|
|
1940
|
+
"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.",
|
|
1941
|
+
"domainNotAllowed": "Your email domain isn't allowed to sign in to this deployment. Ask your IT team which account to use.",
|
|
1942
|
+
"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.",
|
|
1943
|
+
"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.",
|
|
1944
|
+
"unknown": "Single sign-on failed for a reason this version doesn't recognise. Try again, and tell an administrator if it keeps happening."
|
|
1945
|
+
}
|
|
1946
|
+
},
|
|
1925
1947
|
"resetPassword": {
|
|
1926
1948
|
"title": "Reset password",
|
|
1927
1949
|
"subtitle": "Choose a new password for your account.",
|
|
@@ -3125,6 +3147,27 @@
|
|
|
3125
3147
|
"servableHarnessesNone": "No agent CLI can serve this transport, so this server never applies to any run.",
|
|
3126
3148
|
"allowedTools": "Narrowed to: {tools}",
|
|
3127
3149
|
"credentials": "Credentials: {keys}",
|
|
3150
|
+
"oauth": {
|
|
3151
|
+
"connected": "Connected",
|
|
3152
|
+
"notConnected": "Not connected",
|
|
3153
|
+
"machineGrant": "Signs in as this deployment",
|
|
3154
|
+
"connectedBy": "Connected by {user}",
|
|
3155
|
+
"scopes": "Granted: {scopes}",
|
|
3156
|
+
"notRefreshable": "The vendor issued no refresh token, so this connection has to be made again once its access token expires.",
|
|
3157
|
+
"lastError": "The last token renewal failed: {detail}",
|
|
3158
|
+
"connect": "Connect",
|
|
3159
|
+
"reconnect": "Reconnect",
|
|
3160
|
+
"disconnect": "Disconnect",
|
|
3161
|
+
"callback": {
|
|
3162
|
+
"working": "Finishing the connection…",
|
|
3163
|
+
"done": "Connected to {server}",
|
|
3164
|
+
"doneHint": "This board's runs can now use the tool server as the account you signed in with.",
|
|
3165
|
+
"back": "Back to the app",
|
|
3166
|
+
"failedTitle": "The connection could not be finished",
|
|
3167
|
+
"failed": "The authorization could not be completed. Start the connection again from the Infrastructure window.",
|
|
3168
|
+
"missingParams": "This link is missing the values the vendor sends back, so there is nothing to complete. Start the connection again."
|
|
3169
|
+
}
|
|
3170
|
+
},
|
|
3128
3171
|
"test": "Test",
|
|
3129
3172
|
"notProbeable": {
|
|
3130
3173
|
"stdio": "Runs inside the agent's container, so it cannot be tested from here.",
|
|
@@ -3135,6 +3178,8 @@
|
|
|
3135
3178
|
"ok": "Answered",
|
|
3136
3179
|
"credentialsMissing": "No credential",
|
|
3137
3180
|
"credentialRefused": "Credential refused",
|
|
3181
|
+
"oauthNotConnected": "Not connected",
|
|
3182
|
+
"oauthTokenFailed": "Connection stopped working",
|
|
3138
3183
|
"unreachable": "No answer",
|
|
3139
3184
|
"httpError": "Rejected the request",
|
|
3140
3185
|
"protocolError": "Not an MCP server",
|
|
@@ -3151,7 +3196,9 @@
|
|
|
3151
3196
|
"hideDetails": "Hide details",
|
|
3152
3197
|
"toast": {
|
|
3153
3198
|
"loadFailed": "Could not load the tool servers",
|
|
3154
|
-
"probeFailed": "Could not test the tool server"
|
|
3199
|
+
"probeFailed": "Could not test the tool server",
|
|
3200
|
+
"connectFailed": "Could not start the connection",
|
|
3201
|
+
"disconnectFailed": "Could not disconnect the tool server"
|
|
3155
3202
|
}
|
|
3156
3203
|
},
|
|
3157
3204
|
"capabilityCredentials": {
|
|
@@ -4885,6 +4932,7 @@
|
|
|
4885
4932
|
"threshold": "threshold {threshold}",
|
|
4886
4933
|
"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.",
|
|
4887
4934
|
"rubricOverridden": "workspace rubric",
|
|
4935
|
+
"modelPinUnavailable": "This review was written for the {model} model, which this deployment cannot run, so another model scored the work.",
|
|
4888
4936
|
"reworkRounds": "rework {spent}/{budget}",
|
|
4889
4937
|
"findingsHeading": "What the rubric flagged",
|
|
4890
4938
|
"roundsHeading": "Review rounds",
|
package/i18n/locales/es.json
CHANGED
|
@@ -1820,10 +1820,26 @@
|
|
|
1820
1820
|
"signInFailed": "Error al iniciar sesión. Revisa tus datos e inténtalo de nuevo.",
|
|
1821
1821
|
"genericError": "Algo salió mal. Inténtalo de nuevo.",
|
|
1822
1822
|
"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).",
|
|
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 (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
1824
|
"patPlaceholder": "Token de acceso personal de {provider}",
|
|
1825
1825
|
"signInWithPat": "Iniciar sesión con un PAT de {provider}"
|
|
1826
1826
|
},
|
|
1827
|
+
"sso": {
|
|
1828
|
+
"continueWith": "Continuar con {provider}",
|
|
1829
|
+
"failedTitle": "El inicio de sesión único no se completó",
|
|
1830
|
+
"errors": {
|
|
1831
|
+
"stateInvalid": "Ese intento de inicio de sesión ha caducado o ya se usó. Vuelve a empezar desde esta página.",
|
|
1832
|
+
"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.",
|
|
1833
|
+
"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.",
|
|
1834
|
+
"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.",
|
|
1835
|
+
"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.",
|
|
1836
|
+
"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.",
|
|
1837
|
+
"domainNotAllowed": "Tu dominio de correo no tiene permitido iniciar sesión en este despliegue. Pregunta a tu equipo de TI qué cuenta debes usar.",
|
|
1838
|
+
"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.",
|
|
1839
|
+
"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.",
|
|
1840
|
+
"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."
|
|
1841
|
+
}
|
|
1842
|
+
},
|
|
1827
1843
|
"resetPassword": {
|
|
1828
1844
|
"title": "Restablecer contraseña",
|
|
1829
1845
|
"subtitle": "Elige una nueva contraseña para tu cuenta.",
|
|
@@ -2874,6 +2890,27 @@
|
|
|
2874
2890
|
"servableHarnessesNone": "Ninguna CLI de agente puede servir este transporte, así que este servidor nunca se aplica a una ejecución.",
|
|
2875
2891
|
"allowedTools": "Limitado a: {tools}",
|
|
2876
2892
|
"credentials": "Credenciales: {keys}",
|
|
2893
|
+
"oauth": {
|
|
2894
|
+
"connected": "Conectado",
|
|
2895
|
+
"notConnected": "Sin conexión",
|
|
2896
|
+
"machineGrant": "Se identifica como este despliegue",
|
|
2897
|
+
"connectedBy": "Conectado por {user}",
|
|
2898
|
+
"scopes": "Concedido: {scopes}",
|
|
2899
|
+
"notRefreshable": "El proveedor no emitió un token de actualización, así que habrá que volver a conectar cuando caduque el token de acceso.",
|
|
2900
|
+
"lastError": "La última renovación del token falló: {detail}",
|
|
2901
|
+
"connect": "Conectar",
|
|
2902
|
+
"reconnect": "Volver a conectar",
|
|
2903
|
+
"disconnect": "Desconectar",
|
|
2904
|
+
"callback": {
|
|
2905
|
+
"working": "Finalizando la conexión…",
|
|
2906
|
+
"done": "Conectado a {server}",
|
|
2907
|
+
"doneHint": "Las ejecuciones de este tablero ya pueden usar el servidor de herramientas con la cuenta con la que iniciaste sesión.",
|
|
2908
|
+
"back": "Volver a la aplicación",
|
|
2909
|
+
"failedTitle": "No se pudo finalizar la conexión",
|
|
2910
|
+
"failed": "No se pudo completar la autorización. Vuelve a iniciar la conexión desde la ventana de Infraestructura.",
|
|
2911
|
+
"missingParams": "A este enlace le faltan los valores que devuelve el proveedor, así que no hay nada que completar. Vuelve a iniciar la conexión."
|
|
2912
|
+
}
|
|
2913
|
+
},
|
|
2877
2914
|
"test": "Probar",
|
|
2878
2915
|
"notProbeable": {
|
|
2879
2916
|
"stdio": "Se ejecuta dentro del contenedor del agente, así que no puede probarse desde aquí.",
|
|
@@ -2884,6 +2921,8 @@
|
|
|
2884
2921
|
"ok": "Respondió",
|
|
2885
2922
|
"credentialsMissing": "Sin credencial",
|
|
2886
2923
|
"credentialRefused": "Credencial rechazada",
|
|
2924
|
+
"oauthNotConnected": "Sin conexión",
|
|
2925
|
+
"oauthTokenFailed": "La conexión dejó de funcionar",
|
|
2887
2926
|
"unreachable": "Sin respuesta",
|
|
2888
2927
|
"httpError": "Rechazó la solicitud",
|
|
2889
2928
|
"protocolError": "No es un servidor MCP",
|
|
@@ -2900,7 +2939,9 @@
|
|
|
2900
2939
|
"hideDetails": "Ocultar detalles",
|
|
2901
2940
|
"toast": {
|
|
2902
2941
|
"loadFailed": "No se pudieron cargar los servidores de herramientas",
|
|
2903
|
-
"probeFailed": "No se pudo probar el servidor de herramientas"
|
|
2942
|
+
"probeFailed": "No se pudo probar el servidor de herramientas",
|
|
2943
|
+
"connectFailed": "No se pudo iniciar la conexión",
|
|
2944
|
+
"disconnectFailed": "No se pudo desconectar el servidor de herramientas"
|
|
2904
2945
|
}
|
|
2905
2946
|
},
|
|
2906
2947
|
"capabilityCredentials": {
|
|
@@ -4668,6 +4709,7 @@
|
|
|
4668
4709
|
"threshold": "umbral {threshold}",
|
|
4669
4710
|
"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.",
|
|
4670
4711
|
"rubricOverridden": "rúbrica del espacio de trabajo",
|
|
4712
|
+
"modelPinUnavailable": "Esta revisión se escribió para el modelo {model}, que esta instalación no puede ejecutar, así que otro modelo puntuó el trabajo.",
|
|
4671
4713
|
"reworkRounds": "revisión {spent}/{budget}",
|
|
4672
4714
|
"findingsHeading": "Lo que señaló la rúbrica",
|
|
4673
4715
|
"roundsHeading": "Rondas de revisión",
|
package/i18n/locales/fr.json
CHANGED
|
@@ -1820,10 +1820,26 @@
|
|
|
1820
1820
|
"signInFailed": "Échec de la connexion. Vérifiez vos informations et réessayez.",
|
|
1821
1821
|
"genericError": "Une erreur s'est produite. Veuillez réessayer.",
|
|
1822
1822
|
"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).",
|
|
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 (authentification unique via le fournisseur d'identité de votre organisation, OAuth GitHub ou Google, ou connexion par e-mail et mot de passe).",
|
|
1824
1824
|
"patPlaceholder": "Jeton d'accès personnel {provider}",
|
|
1825
1825
|
"signInWithPat": "Se connecter avec un PAT {provider}"
|
|
1826
1826
|
},
|
|
1827
|
+
"sso": {
|
|
1828
|
+
"continueWith": "Continuer avec {provider}",
|
|
1829
|
+
"failedTitle": "L'authentification unique n'a pas abouti",
|
|
1830
|
+
"errors": {
|
|
1831
|
+
"stateInvalid": "Cette tentative de connexion a expiré ou a déjà été utilisée. Recommencez depuis cette page.",
|
|
1832
|
+
"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.",
|
|
1833
|
+
"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.",
|
|
1834
|
+
"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.",
|
|
1835
|
+
"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.",
|
|
1836
|
+
"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.",
|
|
1837
|
+
"domainNotAllowed": "Votre domaine de messagerie n'est pas autorisé à se connecter à ce déploiement. Demandez à votre service informatique quel compte utiliser.",
|
|
1838
|
+
"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.",
|
|
1839
|
+
"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.",
|
|
1840
|
+
"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."
|
|
1841
|
+
}
|
|
1842
|
+
},
|
|
1827
1843
|
"resetPassword": {
|
|
1828
1844
|
"title": "Réinitialiser le mot de passe",
|
|
1829
1845
|
"subtitle": "Choisissez un nouveau mot de passe pour votre compte.",
|
|
@@ -2874,6 +2890,27 @@
|
|
|
2874
2890
|
"servableHarnessesNone": "Aucune CLI d’agent ne peut servir ce transport, donc ce serveur ne s’applique à aucune exécution.",
|
|
2875
2891
|
"allowedTools": "Restreint à : {tools}",
|
|
2876
2892
|
"credentials": "Identifiants : {keys}",
|
|
2893
|
+
"oauth": {
|
|
2894
|
+
"connected": "Connecté",
|
|
2895
|
+
"notConnected": "Non connecté",
|
|
2896
|
+
"machineGrant": "S’authentifie en tant que ce déploiement",
|
|
2897
|
+
"connectedBy": "Connecté par {user}",
|
|
2898
|
+
"scopes": "Accordé : {scopes}",
|
|
2899
|
+
"notRefreshable": "Le fournisseur n’a pas émis de jeton de rafraîchissement : il faudra reconnecter dès que le jeton d’accès expirera.",
|
|
2900
|
+
"lastError": "Le dernier renouvellement du jeton a échoué : {detail}",
|
|
2901
|
+
"connect": "Connecter",
|
|
2902
|
+
"reconnect": "Reconnecter",
|
|
2903
|
+
"disconnect": "Déconnecter",
|
|
2904
|
+
"callback": {
|
|
2905
|
+
"working": "Finalisation de la connexion…",
|
|
2906
|
+
"done": "Connecté à {server}",
|
|
2907
|
+
"doneHint": "Les exécutions de ce tableau peuvent désormais utiliser le serveur d’outils avec le compte auquel vous vous êtes connecté.",
|
|
2908
|
+
"back": "Retour à l’application",
|
|
2909
|
+
"failedTitle": "La connexion n’a pas pu être finalisée",
|
|
2910
|
+
"failed": "L’autorisation n’a pas pu être menée à bien. Relancez la connexion depuis la fenêtre Infrastructure.",
|
|
2911
|
+
"missingParams": "Il manque à ce lien les valeurs renvoyées par le fournisseur, il n’y a donc rien à finaliser. Relancez la connexion."
|
|
2912
|
+
}
|
|
2913
|
+
},
|
|
2877
2914
|
"test": "Tester",
|
|
2878
2915
|
"notProbeable": {
|
|
2879
2916
|
"stdio": "Il s’exécute dans le conteneur de l’agent et ne peut donc pas être testé d’ici.",
|
|
@@ -2884,6 +2921,8 @@
|
|
|
2884
2921
|
"ok": "A répondu",
|
|
2885
2922
|
"credentialsMissing": "Aucun identifiant",
|
|
2886
2923
|
"credentialRefused": "Identifiant refusé",
|
|
2924
|
+
"oauthNotConnected": "Non connecté",
|
|
2925
|
+
"oauthTokenFailed": "La connexion ne fonctionne plus",
|
|
2887
2926
|
"unreachable": "Aucune réponse",
|
|
2888
2927
|
"httpError": "Requête rejetée",
|
|
2889
2928
|
"protocolError": "Pas un serveur MCP",
|
|
@@ -2900,7 +2939,9 @@
|
|
|
2900
2939
|
"hideDetails": "Masquer les détails",
|
|
2901
2940
|
"toast": {
|
|
2902
2941
|
"loadFailed": "Impossible de charger les serveurs d’outils",
|
|
2903
|
-
"probeFailed": "Impossible de tester le serveur d’outils"
|
|
2942
|
+
"probeFailed": "Impossible de tester le serveur d’outils",
|
|
2943
|
+
"connectFailed": "Impossible de démarrer la connexion",
|
|
2944
|
+
"disconnectFailed": "Impossible de déconnecter le serveur d’outils"
|
|
2904
2945
|
}
|
|
2905
2946
|
},
|
|
2906
2947
|
"capabilityCredentials": {
|
|
@@ -4668,6 +4709,7 @@
|
|
|
4668
4709
|
"threshold": "seuil {threshold}",
|
|
4669
4710
|
"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.",
|
|
4670
4711
|
"rubricOverridden": "grille de l'espace de travail",
|
|
4712
|
+
"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.",
|
|
4671
4713
|
"reworkRounds": "reprise {spent}/{budget}",
|
|
4672
4714
|
"findingsHeading": "Ce que la grille a signalé",
|
|
4673
4715
|
"roundsHeading": "Tours de revue",
|