Explain agent startup failures in plain words (#31932)

* fix(terminal): explain agent startup failures in plain words

* fix(i18n): use the established Japanese agent label

* fix(terminal): preserve uncertainty in startup error messages

* Reuse pane agent identity and bound startup toast work

* test: render startup notices with shipped locale catalogs
This commit is contained in:
Brennan Benson
2026-10-23 15:40:18 -07:00
committed by GitHub
parent 8586fc761d
commit 20b78bbd15
15 changed files with 315 additions and 81 deletions
@@ -11,9 +11,11 @@ import { agentLaunchPaneNoticeText } from './agent-launch-pane-notice-text'
*/
export function AgentLaunchPaneNotice({
refusal,
agentId,
tabId
}: {
refusal: AgentLaunchPaneOutcome
agentId?: string | null
tabId: string
}): React.JSX.Element {
const prompt = agentLaunchPanePrompt(tabId)
@@ -22,7 +24,7 @@ export function AgentLaunchPaneNotice({
data-agent-launch-pane-notice={refusal.kind}
className="pointer-events-auto absolute inset-x-3 bottom-3 z-50 flex items-start justify-between gap-3 rounded-md border border-border bg-popover px-3.5 py-2.5 text-xs text-popover-foreground"
>
<span className="min-w-0">{agentLaunchPaneNoticeText(refusal)}</span>
<span className="min-w-0">{agentLaunchPaneNoticeText(refusal, agentId)}</span>
{prompt ? (
<Button
variant="outline"
@@ -42,11 +44,13 @@ export function AgentLaunchPaneNotice({
/** The notice in the active pane, when that pane's error is a launch's. */
export function AgentLaunchPaneNoticePortal({
refusal,
agentId,
isActive,
pane,
tabId
}: {
refusal: AgentLaunchPaneOutcome | null
agentId?: string | null
isActive: boolean
pane: { id: number; container: HTMLElement } | null | undefined
tabId: string
@@ -55,7 +59,7 @@ export function AgentLaunchPaneNoticePortal({
return null
}
return createPortal(
<AgentLaunchPaneNotice refusal={refusal} tabId={tabId} />,
<AgentLaunchPaneNotice refusal={refusal} agentId={agentId} tabId={tabId} />,
pane.container,
`agent-launch-pane-notice-${pane.id}`
)
@@ -13,6 +13,7 @@ vi.mock('@/lib/client-environment-info', () => ({
}))
import { i18n } from '@/i18n/i18n'
import { appendPaneTerminalError, terminalErrorForPane } from './terminal-error-accumulation'
import {
TerminalErrorToast,
@@ -69,6 +70,111 @@ describe('isSshReconnectOwnedTerminalError', () => {
})
describe('humanizeTerminalError', () => {
it('bounds startup row work linearly through accumulated toast renders at N and 10N', () => {
const tokenMatches = vi.spyOn(String.prototype, 'match')
const translations = vi.spyOn(i18n, 't')
try {
for (const kind of ['startup', 'mixed', 'unmatched'] as const) {
let view: ReturnType<typeof render> | undefined
for (const rowCount of [2, 20]) {
const rows = Array.from({ length: rowCount }, (_, index) =>
kind === 'startup' || (kind === 'mixed' && index % 2 === 0)
? `Attempt ${index}: agent_session_exited_during_start`
: `Paste failed ${index}.`
)
const midpoint = rowCount / 2
const errors = appendPaneTerminalError(
appendPaneTerminalError({}, 1, rows.slice(0, midpoint).join('\n')),
1,
rows.slice(midpoint).join('\n')
)
const error = terminalErrorForPane(null, errors, 1)
expect(error).toBe(rows.join('\n'))
if (error === null) {
throw new Error('Accumulated error missing')
}
tokenMatches.mockClear()
translations.mockClear()
const toast = React.createElement(TerminalErrorToast, {
error,
agentId: 'codex',
paneOnClient: false,
onDismiss: vi.fn()
})
if (view) {
view.rerender(toast)
} else {
view = render(toast)
}
const tokenChecks = tokenMatches.mock.calls.filter(
([pattern]) =>
pattern instanceof RegExp && pattern.source.includes('agent_(?:session|launch)_')
).length
const startupTranslations = translations.mock.calls.filter(
([key]) =>
typeof key === 'string' &&
key.startsWith('auto.components.terminal.pane.AgentLaunchPaneNotice.')
).length
const matchingRows = kind === 'startup' ? rowCount : kind === 'mixed' ? midpoint : 0
// Classification and adaptation each visit a row at most once; known exits use two templates.
expect(tokenChecks).toBeGreaterThanOrEqual(rowCount)
expect(tokenChecks).toBeLessThanOrEqual(2 * rowCount)
if (kind === 'startup') {
expect(tokenChecks).toBe(2 * rowCount)
}
expect(startupTranslations).toBe(2 * matchingRows)
expect(
view.container.textContent?.match(/Codex exited while starting\./g) ?? []
).toHaveLength(matchingRows)
expect(view.container.querySelector('a') !== null).toBe(kind !== 'startup')
expect(view.container.textContent).not.toContain('agent_session_exited_during_start')
}
view?.unmount()
}
} finally {
tokenMatches.mockRestore()
translations.mockRestore()
}
})
it.each([false, true])(
'explains a known exit and retains reporting for independent errors: %s',
(mixed) => {
const code = 'agent_session_exited_during_start'
const footer = '---\nOrca: 1.4.232\nOS: win32 10.0 (x64)\nShell: cmd.exe'
const view = render(
React.createElement(TerminalErrorToast, {
error: `Error invoking remote method 'pty:spawn': Error: ${code}${mixed ? '\nPaste failed.' : ''}\n\n${footer}`,
agentId: 'codex',
paneOnClient: false,
onDismiss: vi.fn()
})
)
const text = view.container.textContent ?? ''
expect(text).toContain(
'Codex exited while starting. Run it in a terminal in this folder to see why, then try again.'
)
expect(text).not.toContain(code)
if (mixed) {
expect(text).toContain('Paste failed.')
}
expect(view.container.querySelectorAll('a')).toHaveLength(mixed ? 1 : 0)
}
)
it.each([
'agent_session_operation_unknown',
'agent_session_claim_unavailable',
'agent_launch_future_failure'
])('preserves uncertainty for a startup string without proof of failure: %s', (code) => {
const text = humanizeTerminalError(
`Error invoking remote method 'pty:spawn': Error: ${code}`,
'codex'
)
expect(text).toBe("Couldn't confirm Codex started. Check its terminal before trying again.")
})
it('replaces the pane-owner-unverified code with actionable copy', () => {
const humanized = humanizeTerminalError('terminal_pane_owner_unverified')
expect(humanized).not.toContain('terminal_pane_owner_unverified')
@@ -6,6 +6,7 @@ import {
isFolderWorkspacePathError
} from '@/lib/folder-workspace-path-status'
import { Button } from '@/components/ui/button'
import { agentLaunchErrorText, isAgentLaunchOnlyError } from './agent-launch-pane-notice-text'
import {
hasClientEnvironmentFooter,
stripClientEnvironmentFooter
@@ -153,11 +154,13 @@ function isSshHostStateTerminalError(error: string): boolean {
}
/** Swaps raw daemon-boundary codes for copy a user can act on. */
export function humanizeTerminalError(error: string): string {
export function humanizeTerminalError(error: string, agentId?: string | null): string {
if (isSshSignInRequiredTerminalError(error)) {
return describeSshSignInRequiredTerminalError(error)
}
let humanized = humanizeFolderWorkspacePathErrors(localizeTerminalSpawnHints(error))
let humanized = humanizeFolderWorkspacePathErrors(
localizeTerminalSpawnHints(agentLaunchErrorText(error, agentId) ?? error)
)
if (humanized.includes(PANE_OWNER_UNVERIFIED_MARKER)) {
const explanation = isPaneOwnerUnverifiedError(humanized)
? translate(
@@ -220,6 +223,7 @@ export function humanizeTerminalError(error: string): string {
export function TerminalErrorToast({
error,
agentId,
paneOnClient = true,
onDismiss,
onRestartDaemon,
@@ -227,6 +231,7 @@ export function TerminalErrorToast({
onOpenNewTerminal
}: {
error: string
agentId?: string | null
/** False for a pane on an SSH or remote host, or one whose host is not yet known. */
paneOnClient?: boolean
onDismiss: () => void
@@ -245,9 +250,10 @@ export function TerminalErrorToast({
!ssh &&
!paneOwnerUnverified &&
!showDaemonRestart &&
!isAgentLaunchOnlyError(error) &&
!isExplainedTerminalError(error) &&
!isFolderWorkspacePathOnlyError(error)
const humanizedError = humanizeTerminalError(error)
const humanizedError = humanizeTerminalError(error, agentId)
// Why: the toast appends its own linked request, so the host's plain-text one would repeat it.
const displayError = showIssueLink
? withoutTerminalSpawnIssueRequest(humanizedError)
@@ -37,6 +37,7 @@ export function TerminalPaneSurface({
controller: TerminalPaneController
}): React.JSX.Element {
const {
activeAgentId,
activePane,
activePaneCanContinueInNewSession,
activePaneCanResumeInChat,
@@ -188,6 +189,7 @@ export function TerminalPaneSurface({
<TerminalPaneCodexRestartPortals controller={controller} />
<AgentLaunchPaneNoticePortal
refusal={visibleLaunchRefusal}
agentId={activeAgentId}
isActive={isActive}
pane={activePane}
tabId={tabId}
@@ -198,6 +200,7 @@ export function TerminalPaneSurface({
? createPortal(
<TerminalErrorToast
error={visibleTerminalError}
agentId={activeAgentId}
paneOnClient={paneOnClient}
onDismiss={dismissTerminalError}
onRestartDaemon={() => daemonActions.setPending('restart')}
@@ -1,6 +1,8 @@
import { translate } from '@/i18n/i18n'
import type { AgentLaunchPaneOutcome } from '../../../../shared/agent-launch-pane-verdict'
import { stripClientEnvironmentFooter } from '../../../../shared/client-environment-info'
import type { TerminalTab } from '../../../../shared/terminal-tab-types'
import { tuiAgentDisplayName } from '../../../../shared/tui-agent-display-names'
/** What the pane shows, if its tab keeps a final launch outcome for this leaf. */
export function agentLaunchPaneOutcomeForLeaf(
@@ -12,39 +14,94 @@ export function agentLaunchPaneOutcomeForLeaf(
}
/** The recorded reason in words a user can act on; null when it names nothing they can fix. */
function notStartedReason(code: string): string | null {
function notStartedReason(code: string, agent: string): string | null {
if (code.includes('ENOENT')) {
return translate(
'auto.components.terminal.pane.AgentLaunchPaneNotice.commandNotFound',
"Its command wasn't found on this machine."
"{{agent}} couldn't start because its command wasn't found on this machine.",
{ agent }
)
}
if (code === 'agent_session_exited_during_start') {
return translate(
'auto.components.terminal.pane.AgentLaunchPaneNotice.exitedDuringStart',
'It exited while starting.'
'{{agent}} exited while starting.',
{ agent }
)
}
if (code === 'worktree_not_found') {
return translate(
'auto.components.terminal.pane.AgentLaunchPaneNotice.workspaceGone',
'Its workspace is no longer available.'
"{{agent}} couldn't start because its workspace is no longer available.",
{ agent }
)
}
return null
}
export function agentLaunchPaneNoticeText(refusal: AgentLaunchPaneOutcome): string {
export function agentLaunchPaneNoticeText(
refusal: AgentLaunchPaneOutcome,
agentId?: string | null
): string {
const agent =
tuiAgentDisplayName(agentId ?? '') ??
translate('auto.components.terminal.pane.AgentLaunchPaneNotice.agent', 'The agent')
if (refusal.kind === 'unconfirmed') {
return translate(
'auto.components.terminal.pane.AgentLaunchPaneNotice.unconfirmed',
"Couldn't confirm the agent started."
"Couldn't confirm {{agent}} started. Check its terminal before trying again.",
{ agent }
)
}
const lead = translate(
'auto.components.terminal.pane.AgentLaunchPaneNotice.notStarted',
"The agent couldn't start."
)
const reason = notStartedReason(refusal.code)
return reason ? `${lead} ${reason}` : lead
const reason =
notStartedReason(refusal.code, agent) ??
translate(
'auto.components.terminal.pane.AgentLaunchPaneNotice.notStarted',
"{{agent}} couldn't start.",
{ agent }
)
const action =
refusal.code === 'worktree_not_found'
? translate(
'auto.components.terminal.pane.AgentLaunchPaneNotice.restoreWorkspace',
'Restore the workspace folder or open an available workspace, then try again.'
)
: translate(
'auto.components.terminal.pane.AgentLaunchPaneNotice.tryInTerminal',
'Run it in a terminal in this folder to see why, then try again.'
)
return `${reason} ${action}`
}
function startupCode(line: string): string | undefined {
return line.match(/\b(?:agent_(?:session|launch)_[a-z0-9_]+|worktree_not_found)\b/)?.[0]
}
export function isAgentLaunchOnlyError(error: string): boolean {
const lines = stripClientEnvironmentFooter(error)
.split('\n')
.filter((line) => line.trim().length > 0)
return lines.length > 0 && lines.every((line) => startupCode(line) !== undefined)
}
/** Older hosts send startup reasons as strings, sometimes wrapped in an IPC error. */
export function agentLaunchErrorText(error: string, agentId?: string | null): string | null {
let found = false
const text = error
.split('\n')
.map((line) => {
const code = startupCode(line)
if (!code) {
return line
}
found = true
// Only these producer contracts prove failure without an attempt's typed host outcome.
const outcome: AgentLaunchPaneOutcome =
code === 'agent_session_exited_during_start' || code === 'worktree_not_found'
? { kind: 'not-started', code }
: { kind: 'unconfirmed' }
return agentLaunchPaneNoticeText(outcome, agentId)
})
.join('\n')
return found ? text : null
}
@@ -1,32 +1,68 @@
import { describe, expect, it, vi } from 'vitest'
// @vitest-environment happy-dom
const CATALOG: Record<string, string> = {
'auto.components.terminal.pane.AgentLaunchPaneNotice.notStarted': '智能体无法启动。',
'auto.components.terminal.pane.AgentLaunchPaneNotice.unconfirmed': '无法确认智能体已启动。',
'auto.components.terminal.pane.AgentLaunchPaneNotice.exitedDuringStart': '它在启动时退出了。'
}
vi.mock('@/i18n/i18n', () => ({
translate: (key: string, fallback: string) => CATALOG[key] ?? fallback
}))
import React from 'react'
import { cleanup, render } from '@testing-library/react'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { i18n, setRendererUiLanguage } from '@/i18n/i18n'
import { AgentLaunchPaneNotice } from './AgentLaunchPaneNotice'
import { TerminalErrorToast } from './TerminalErrorToast'
import { agentLaunchPaneOutcomeForLeaf } from './agent-launch-pane-notice-text'
const { agentLaunchPaneNoticeText, agentLaunchPaneOutcomeForLeaf } =
await import('./agent-launch-pane-notice-text')
afterEach(async () => {
cleanup()
await i18n.changeLanguage('en')
})
describe("the pane of a launch whose agent isn't running", () => {
it("says it couldn't start, in the viewer's language, with a reason they can act on", () => {
expect(
agentLaunchPaneNoticeText({ kind: 'not-started', code: 'agent_session_exited_during_start' })
).toBe('智能体无法启动。 它在启动时退出了。')
})
it('never shows a host error code', () => {
expect(
agentLaunchPaneNoticeText({ kind: 'not-started', code: 'agent_launch_pane_already_live' })
).toBe('智能体无法启动。')
})
it("says it can't confirm, never that it failed, when nobody knows", () => {
expect(agentLaunchPaneNoticeText({ kind: 'unconfirmed' })).toBe('无法确认智能体已启动。')
describe('localized startup failure surfaces', () => {
it.each([
{
language: 'en',
exit: 'Codex exited while starting. Run it in a terminal in this folder to see why, then try again.',
workspace:
"Codex couldn't start because its workspace is no longer available. Restore the workspace folder or open an available workspace, then try again.",
unknown: "Couldn't confirm Codex started. Check its terminal before trying again."
},
{
language: 'zh',
exit: 'Codex 在启动时退出了。 请在此文件夹的终端中运行它以查看原因,然后重试。',
workspace:
'无法启动 Codex,因为其工作区已不可用。 请恢复工作区文件夹或打开可用的工作区,然后重试。',
unknown: '无法确认 Codex 已启动。请先检查其终端,再重试。'
}
] as const)('renders both real mappings with the shipped $language catalog', async (copy) => {
await setRendererUiLanguage(copy.language)
for (const [code, expected, refusal] of [
[
'agent_session_exited_during_start',
copy.exit,
{ kind: 'not-started', code: 'agent_session_exited_during_start' }
],
['worktree_not_found', copy.workspace, { kind: 'not-started', code: 'worktree_not_found' }],
['agent_session_operation_unknown', copy.unknown, { kind: 'unconfirmed' }]
] as const) {
const toast = render(
React.createElement(TerminalErrorToast, {
error: `Error invoking remote method 'pty:spawn': Error: ${code}`,
agentId: 'codex',
paneOnClient: false,
onDismiss: vi.fn()
})
)
const pane = render(
React.createElement(AgentLaunchPaneNotice, {
refusal,
agentId: 'codex',
tabId: 'localized-startup-failure'
})
)
expect(toast.container.querySelector('span')?.textContent).toBe(expected)
expect(pane.container.querySelector('span')?.textContent).toBe(expected)
expect(toast.container.querySelector('a')).toBeNull()
expect(toast.container.textContent).not.toContain(code)
expect(pane.container.textContent).not.toContain(code)
toast.unmount()
pane.unmount()
}
})
})
@@ -184,6 +184,7 @@ function mountSurface(
2: { left: 220, top: 0, width: 200 }
},
renamingPaneId: null,
activeAgentId: null,
renameInputRef: { current: null },
paneTitleBackground: 'transparent',
activatePaneTitleInteraction: activate,
@@ -168,9 +168,8 @@ export function useTerminalPaneProjection(controller: TerminalPaneMobileControll
}) ?? resolveTitleAgentForLeaf(leafId)
)
}
const activePaneCanContinueInNewSession = canContinueAgentSessionInNewSession(
resolveAgentForLeaf(activePane?.leafId ?? null)
)
const activeAgentId = resolveAgentForLeaf(activePane?.leafId ?? null)
const activePaneCanContinueInNewSession = canContinueAgentSessionInNewSession(activeAgentId)
const contextMenuCanContinueInNewSession = canContinueAgentSessionInNewSession(
resolveAgentForLeaf(contextMenuLeafId)
)
@@ -224,6 +223,7 @@ export function useTerminalPaneProjection(controller: TerminalPaneMobileControll
chatPaneLaunchAgent,
chatPaneOwnsTabWideLaunchDraft,
activePaneIsChatLeaf,
activeAgentId,
resolveAgentForLeaf,
activePaneCanContinueInNewSession,
contextMenuCanContinueInNewSession,
+8 -5
View File
@@ -3794,12 +3794,15 @@
"restoring": "Restoring terminal…"
},
"AgentLaunchPaneNotice": {
"commandNotFound": "Its command wasn't found on this machine.",
"agent": "The agent",
"commandNotFound": "{{agent}} couldn't start because its command wasn't found on this machine.",
"copyPrompt": "Copy prompt",
"exitedDuringStart": "It exited while starting.",
"notStarted": "The agent couldn't start.",
"unconfirmed": "Couldn't confirm the agent started.",
"workspaceGone": "Its workspace is no longer available."
"exitedDuringStart": "{{agent}} exited while starting.",
"notStarted": "{{agent}} couldn't start.",
"restoreWorkspace": "Restore the workspace folder or open an available workspace, then try again.",
"tryInTerminal": "Run it in a terminal in this folder to see why, then try again.",
"unconfirmed": "Couldn't confirm {{agent}} started. Check its terminal before trying again.",
"workspaceGone": "{{agent}} couldn't start because its workspace is no longer available."
},
"TerminalSleepingPaneOverlay": {
"pausedDetail": "Automatic restores are paused because the host stopped unexpectedly. Your session is saved.",
+8 -5
View File
@@ -3557,12 +3557,15 @@
"54f29b7c0d": "Cargando host…"
},
"AgentLaunchPaneNotice": {
"commandNotFound": "Su comando no se encontró en este equipo.",
"agent": "El agente",
"commandNotFound": "{{agent}} no pudo iniciarse porque no se encontró su comando en este equipo.",
"copyPrompt": "Copiar prompt",
"exitedDuringStart": "Se cerró mientras se iniciaba.",
"notStarted": "El agente no pudo iniciarse.",
"unconfirmed": "No se pudo confirmar que el agente se iniciara.",
"workspaceGone": "Su espacio de trabajo ya no está disponible."
"exitedDuringStart": "{{agent}} se cerró durante el inicio.",
"notStarted": "{{agent}} no pudo iniciarse.",
"restoreWorkspace": "Restaura la carpeta del espacio de trabajo o abre un espacio de trabajo disponible y vuelve a intentarlo.",
"tryInTerminal": "Ejecútalo en una terminal en esta carpeta para ver el motivo y vuelve a intentarlo.",
"unconfirmed": "No se pudo confirmar que {{agent}} se haya iniciado. Revisa su terminal antes de volver a intentarlo.",
"workspaceGone": "{{agent}} no pudo iniciarse porque su espacio de trabajo ya no está disponible."
},
"TerminalSleepingPaneOverlay": {
"pausedDetail": "Las restauraciones automáticas están en pausa porque el host se detuvo de forma inesperada. Tu sesión está guardada.",
+8 -5
View File
@@ -3701,12 +3701,15 @@
"restoring": "Restauration du terminal…"
},
"AgentLaunchPaneNotice": {
"commandNotFound": "Sa commande est introuvable sur cette machine.",
"agent": "L’agent",
"commandNotFound": "{{agent}} n’a pas pu démarrer car sa commande est introuvable sur cet ordinateur.",
"copyPrompt": "Copier le prompt",
"exitedDuringStart": "Il s'est arrêté pendant le démarrage.",
"notStarted": "L'agent n'a pas pu démarrer.",
"unconfirmed": "Impossible de confirmer que l'agent a démarré.",
"workspaceGone": "Son espace de travail n'est plus disponible."
"exitedDuringStart": "{{agent}} s’est arrêté pendant le démarrage.",
"notStarted": "{{agent}} n’a pas pu démarrer.",
"restoreWorkspace": "Restaurez le dossier de l’espace de travail ou ouvrez un espace de travail disponible, puis réessayez.",
"tryInTerminal": "Lancez-le dans un terminal dans ce dossier pour en connaître la raison, puis réessayez.",
"unconfirmed": "Impossible de confirmer le démarrage de {{agent}}. Vérifiez son terminal avant de réessayer.",
"workspaceGone": "{{agent}} n’a pas pu démarrer car son espace de travail n’est plus disponible."
},
"TerminalSleepingPaneOverlay": {
"pausedDetail": "Les restaurations automatiques sont en pause car l'hôte s'est arrêté de façon inattendue. Votre session est enregistrée.",
+8 -5
View File
@@ -3542,12 +3542,15 @@
"restoring": "ターミナルを復元中…"
},
"AgentLaunchPaneNotice": {
"commandNotFound": "このマシンでコマンドが見つかりませんでした。",
"agent": "Agent",
"commandNotFound": "このマシンでコマンドが見つからないため、{{agent}} を起動できませんでした。",
"copyPrompt": "プロンプトをコピー",
"exitedDuringStart": "起動中に終了しました。",
"notStarted": "Agent を起動できませんでした。",
"unconfirmed": "Agent が起動したか確認できませんでした。",
"workspaceGone": "ワークスペースは利用できなくなりました。"
"exitedDuringStart": "{{agent}} は起動中に終了しました。",
"notStarted": "{{agent}} を起動できませんでした。",
"restoreWorkspace": "ワークスペースのフォルダーを復元するか、利用可能なワークスペースを開いてから、もう一度お試しください。",
"tryInTerminal": "このフォルダーのターミナルで実行して原因を確認し、再試行してください。",
"unconfirmed": "{{agent}} が起動したか確認できませんでした。再試行する前にターミナルを確認してください。",
"workspaceGone": "ワークスペースが利用できなくなったため、{{agent}} を起動できませんでした。"
},
"TerminalSleepingPaneOverlay": {
"pausedDetail": "ホストが予期せず停止したため、自動復元は一時停止しています。セッションは保存されています。",
+8 -5
View File
@@ -3542,12 +3542,15 @@
"restoring": "터미널 복원 중…"
},
"AgentLaunchPaneNotice": {
"commandNotFound": "이 컴퓨터에서 명령을 찾을 수 없습니다.",
"agent": "에이전트",
"commandNotFound": "이 컴퓨터에서 명령을 찾을 수 없어 {{agent}} 시작에 실패했습니다.",
"copyPrompt": "프롬프트 복사",
"exitedDuringStart": "시작하는 중에 종료되었습니다.",
"notStarted": "에이전트를 시작하지 못했습니다.",
"unconfirmed": "에이전트가 시작되었는지 확인하지 못했습니다.",
"workspaceGone": "작업 공간을 더 이상 사용할 수 없습니다."
"exitedDuringStart": "{{agent}} 시작 중 종료되었습니다.",
"notStarted": "{{agent}} 시작에 실패했습니다.",
"restoreWorkspace": "워크스페이스 폴더를 복원하거나 사용 가능한 워크스페이스를 연 다음 다시 시도하세요.",
"tryInTerminal": "이 폴더의 터미널에서 실행하여 원인을 확인한 후 다시 시도하세요.",
"unconfirmed": "{{agent}} 시작 여부를 확인할 수 없습니다. 다시 시도하기 전에 터미널을 확인하세요.",
"workspaceGone": "워크스페이스를 더 이상 사용할 수 없어 {{agent}} 시작에 실패했습니다."
},
"TerminalSleepingPaneOverlay": {
"pausedDetail": "호스트가 예기치 않게 중지되어 자동 복원이 일시 중지되었습니다. 세션이 저장되었습니다.",
+8 -5
View File
@@ -15700,12 +15700,15 @@
"restoring": "Restaurando terminal…"
},
"AgentLaunchPaneNotice": {
"commandNotFound": "O comando dele não foi encontrado nesta máquina.",
"agent": "O agente",
"commandNotFound": "Não foi possível iniciar {{agent}} porque seu comando não foi encontrado neste computador.",
"copyPrompt": "Copiar prompt",
"exitedDuringStart": "Ele encerrou durante a inicialização.",
"notStarted": "Não foi possível iniciar o agente.",
"unconfirmed": "Não foi possível confirmar que o agente iniciou.",
"workspaceGone": "O espaço de trabalho dele não está mais disponível."
"exitedDuringStart": "{{agent}} foi encerrado durante a inicialização.",
"notStarted": "Não foi possível iniciar {{agent}}.",
"restoreWorkspace": "Restaure a pasta do espaço de trabalho ou abra um espaço de trabalho disponível e tente novamente.",
"tryInTerminal": "Execute-o em um terminal nesta pasta para descobrir o motivo e tente novamente.",
"unconfirmed": "Não foi possível confirmar que {{agent}} iniciou. Verifique seu terminal antes de tentar novamente.",
"workspaceGone": "Não foi possível iniciar {{agent}} porque seu espaço de trabalho não está mais disponível."
},
"TerminalSleepingPaneOverlay": {
"pausedDetail": "As restaurações automáticas estão pausadas porque o host parou inesperadamente. Sua sessão está salva.",
+8 -5
View File
@@ -3542,12 +3542,15 @@
"restoring": "正在恢复终端…"
},
"AgentLaunchPaneNotice": {
"commandNotFound": "在此计算机上找不到其命令。",
"agent": "智能体",
"commandNotFound": "无法启动 {{agent}},因为在此计算机上找不到其命令。",
"copyPrompt": "复制提示",
"exitedDuringStart": "它在启动时退出了。",
"notStarted": "智能体无法启动。",
"unconfirmed": "无法确认智能体已启动。",
"workspaceGone": "其工作区已不可用。"
"exitedDuringStart": "{{agent}} 在启动时退出了。",
"notStarted": "无法启动 {{agent}}。",
"restoreWorkspace": "请恢复工作区文件夹或打开可用的工作区,然后重试。",
"tryInTerminal": "请在此文件夹的终端中运行它以查看原因,然后重试。",
"unconfirmed": "无法确认 {{agent}} 已启动。请先检查其终端,再重试。",
"workspaceGone": "无法启动 {{agent}},因为其工作区已不可用。"
},
"TerminalSleepingPaneOverlay": {
"pausedDetail": "由于主机意外停止,自动恢复已暂停。您的会话已保存。",