- {translate(
- 'auto.components.settings.AccountsPane.72b36ea174',
- 'Optional. Orca can use your normal Claude login; add accounts only if you want quick switching without moving chat sessions.'
- )}
-
-
-
-
+
+
+ {translate('auto.components.settings.AccountsPane.26ef4b55be', 'Claude')}
+
+ }
description={translate(
- 'accounts.claude.profileSwitching',
- 'Switching applies to the next Claude you start in any tab.'
+ 'auto.components.settings.AccountsPane.72b36ea174',
+ 'Optional. Orca can use your normal Claude login; add accounts only if you want quick switching without moving chat sessions.'
)}
- keywords={['claude', 'account', 'rate limit', 'status bar', 'quota']}
- className="space-y-3 py-2"
>
-
-
-
-
- {isRemoteAccountScope
- ? translate(
- 'accounts.remoteScopeAccountsAddHere',
- 'Showing accounts managed by {{value0}}. New accounts sign in there; you finish in this device’s browser.',
- { value0: accountRuntimeSentenceLabel }
- )
- : translate(
- 'auto.components.settings.AccountsPane.c0a52abfc5',
- 'Showing accounts for {{value0}}. New accounts are added there.',
- { value0: accountRuntimeSentenceLabel }
- )}
-
-
-
-
-
- {!isRemoteAccountScope && canOfferClaudeSignInLink(accountRuntime.runtime) ? (
- void addClaudeAccount(true)}
- />
- ) : null}
-
- {/* Follow the running addition; hide Cancel only when its server prompt already offers it. */}
- {claudeAction === 'adding' && !accountAdditionShownInPrompt('claude', accountOwner) ? (
-
- ) : null}
-
- {translate(
- 'accounts.claude.systemDefaultIsSaved',
- 'System default is signed in as {{value0}}, which is also a saved account. An earlier Orca version may have copied that login there. If it is not your own login, select System default and run claude /login.',
- { value0: systemDefaultEmail }
- )}
+ {isRemoteAccountScope
+ ? translate(
+ 'accounts.remoteScopeAccountsAddHere',
+ 'Showing accounts managed by {{value0}}. New accounts sign in there; you finish in this device’s browser.',
+ { value0: accountRuntimeSentenceLabel }
+ )
+ : translate(
+ 'auto.components.settings.AccountsPane.c0a52abfc5',
+ 'Showing accounts for {{value0}}. New accounts are added there.',
+ { value0: accountRuntimeSentenceLabel }
+ )}
-
+
+
+
+ {!isRemoteAccountScope && canOfferClaudeSignInLink(accountRuntime.runtime) ? (
+ void addClaudeAccount(true)}
+ />
+ ) : null}
+
+ {/* Follow the running addition; hide Cancel only when its server prompt already offers it. */}
+ {claudeAction === 'adding' &&
+ !accountAdditionShownInPrompt('claude', accountOwner) ? (
+
+ ) : null}
+
- {isRemoteAccountScope
- ? translate(
- 'auto.components.settings.AccountsPane.remoteEmptyClaudeAccounts',
- 'No managed Claude accounts on {{value0}}. It uses its system default Claude login; add accounts on that server.',
- { value0: accountRuntimeSentenceLabel }
- )
- : translate(
- 'auto.components.settings.AccountsPane.3fe7862418',
- "No managed Claude accounts for {{value0}}. Orca will use that environment's system default Claude login until you add one here.",
+
+
+
+ {systemDefaultIsSaved ? (
+
+
+ {translate(
+ 'accounts.claude.systemDefaultIsSaved',
+ 'System default is signed in as {{value0}}, which is also a saved account. An earlier Orca version may have copied that login there. If it is not your own login, select System default and run claude /login.',
+ { value0: systemDefaultEmail }
+ )}
+
- {translate(
- 'auto.components.settings.AccountsPane.cedfab35ab',
- 'Optional. Orca can use your normal Codex login; add accounts only if you want quick switching in Orca.'
- )}
-
-
- {isRemoteAccountScope
- ? translate(
- 'auto.components.settings.AccountsPane.remoteScopeAuthContext',
- 'Each account keeps its own sign-in context on {{value0}}.',
- { value0: accountRuntimeSentenceLabel }
- )
- : translate(
- 'auto.components.settings.AccountsPane.340d6f7a85',
- 'Each account keeps its own local sign-in context in Orca. Account auth stays on this device.'
+
+
+
+ {translate('auto.components.settings.AccountsPane.ef91cfa06b', 'Codex')}
+
+ }
+ description={
+ <>
+
+ {translate(
+ 'auto.components.settings.AccountsPane.cedfab35ab',
+ 'Optional. Orca can use your normal Codex login; add accounts only if you want quick switching in Orca.'
)}
-
-
-
-
- {systemCodexMissingSignIn
- ? translate(
- 'auto.components.settings.AccountsPane.codexSystemDefaultNeedsSignIn',
- 'No Codex sign-in was found for {{value0}}.',
- { value0: accountRuntimeSentenceLabel }
- )
- : activeCodexAccountId
- ? translate(
- 'auto.components.settings.AccountsPane.75ca9b718e',
- 'Codex reported that the active account needs a fresh sign-in. Re-authenticate it before starting new Codex sessions.'
- )
- : translate(
- 'auto.components.settings.AccountsPane.e4a28e8894',
- 'Codex reported that the {{value0}} login needs a fresh sign-in. Sign in again before starting new Codex sessions.',
- { value0: accountRuntimeSentenceLabel }
- )}
-
- ) : null}
- {codexConfigSyncWarning ? (
-
-
-
- {codexConfigSyncWarning === 'managed-home-unavailable'
- ? translate(
- 'auto.components.settings.AccountsPane.codexConfigSyncManagedHomeUnavailable',
- 'Orca could not read this account’s Codex files just now, so settings may not be syncing. This usually clears on its own — antivirus or a backup tool briefly locks them.'
- )
- : codexConfigSyncWarning === 'missing-source'
- ? translate(
- 'auto.components.settings.AccountsPane.codexConfigSyncMissingSource',
- 'Codex is still using the settings it last synced because {{value0}} is missing. Restore that file to resume syncing.',
- { value0: codexConfigSync?.systemConfigPath ?? '' }
- )
- : codexConfigSyncWarning === 'blank-source'
- ? translate(
- 'auto.components.settings.AccountsPane.codexConfigSyncBlankSource',
- 'Codex is still using the settings it last synced because {{value0}} is empty. That is expected while a synced folder finishes downloading.',
- { value0: codexConfigSync?.systemConfigPath ?? '' }
- )
- : translate(
- 'auto.components.settings.AccountsPane.codexConfigSyncUnreadableSource',
- "Codex is still using the settings it last synced because {{value0}} could not be read. Check that file's permissions.",
- { value0: codexConfigSync?.systemConfigPath ?? '' }
- )}
-
-
- ) : null}
-
-
-
-
+
{isRemoteAccountScope
? translate(
- 'accounts.remoteScopeAccountsAddHere',
- 'Showing accounts managed by {{value0}}. New accounts sign in there; you finish in this device’s browser.',
+ 'auto.components.settings.AccountsPane.remoteScopeAuthContext',
+ 'Each account keeps its own sign-in context on {{value0}}.',
{ value0: accountRuntimeSentenceLabel }
)
: translate(
- 'auto.components.settings.AccountsPane.c0a52abfc5',
- 'Showing accounts for {{value0}}. New accounts are added there.',
- { value0: accountRuntimeSentenceLabel }
+ 'auto.components.settings.AccountsPane.340d6f7a85',
+ 'Each account keeps its own local sign-in context in Orca. Account auth stays on this device.'
)}
-
+
+
+ {systemCodexMissingSignIn
+ ? translate(
+ 'auto.components.settings.AccountsPane.codexSystemDefaultNeedsSignIn',
+ 'No Codex sign-in was found for {{value0}}.',
+ { value0: accountRuntimeSentenceLabel }
+ )
+ : activeCodexAccountId
+ ? translate(
+ 'auto.components.settings.AccountsPane.75ca9b718e',
+ 'Codex reported that the active account needs a fresh sign-in. Re-authenticate it before starting new Codex sessions.'
+ )
+ : translate(
+ 'auto.components.settings.AccountsPane.e4a28e8894',
+ 'Codex reported that the {{value0}} login needs a fresh sign-in. Sign in again before starting new Codex sessions.',
+ { value0: accountRuntimeSentenceLabel }
+ )}
+
+
+ ) : null}
+ {codexConfigSyncWarning ? (
+
+
+
+ {codexConfigSyncWarning === 'managed-home-unavailable'
+ ? translate(
+ 'auto.components.settings.AccountsPane.codexConfigSyncManagedHomeUnavailable',
+ 'Orca could not read this account’s Codex files just now, so settings may not be syncing. This usually clears on its own — antivirus or a backup tool briefly locks them.'
+ )
+ : codexConfigSyncWarning === 'missing-source'
+ ? translate(
+ 'auto.components.settings.AccountsPane.codexConfigSyncMissingSource',
+ 'Codex is still using the settings it last synced because {{value0}} is missing. Restore that file to resume syncing.',
+ { value0: codexConfigSync?.systemConfigPath ?? '' }
+ )
+ : codexConfigSyncWarning === 'blank-source'
+ ? translate(
+ 'auto.components.settings.AccountsPane.codexConfigSyncBlankSource',
+ 'Codex is still using the settings it last synced because {{value0}} is empty. That is expected while a synced folder finishes downloading.',
+ { value0: codexConfigSync?.systemConfigPath ?? '' }
+ )
+ : translate(
+ 'auto.components.settings.AccountsPane.codexConfigSyncUnreadableSource',
+ "Codex is still using the settings it last synced because {{value0}} could not be read. Check that file's permissions.",
+ { value0: codexConfigSync?.systemConfigPath ?? '' }
+ )}
+
+
+ ) : null}
+
+
+
+
+ {isRemoteAccountScope
+ ? translate(
+ 'accounts.remoteScopeAccountsAddHere',
+ 'Showing accounts managed by {{value0}}. New accounts sign in there; you finish in this device’s browser.',
+ { value0: accountRuntimeSentenceLabel }
+ )
+ : translate(
+ 'auto.components.settings.AccountsPane.c0a52abfc5',
+ 'Showing accounts for {{value0}}. New accounts are added there.',
+ { value0: accountRuntimeSentenceLabel }
+ )}
+
-
- {systemCodexNeedsSignIn
- ? systemCodexMissingSignIn
- ? translate(
- 'auto.components.settings.AccountsPane.codexSystemDefaultNeedsSignIn',
- 'No Codex sign-in was found for {{value0}}.',
- { value0: accountRuntimeSentenceLabel }
- )
- : translate(
- 'auto.components.settings.AccountsPane.fd62f37c24',
- 'Codex reported this {{value0}} login is out of date.',
- { value0: accountRuntimeSentenceLabel }
- )
- : getCodexSystemDefaultSubtitle(systemCodexIdentity, accountRuntimeSentenceLabel)}
-
-
-
- {visibleCodexAccounts.length === 0 ? (
-
- {isRemoteAccountScope
- ? translate(
- 'auto.components.settings.AccountsPane.remoteEmptyCodexAccounts',
- 'No managed Codex accounts on {{value0}}. It uses its system default Codex login; add accounts on that server.',
- { value0: accountRuntimeSentenceLabel }
- )
- : translate(
- 'auto.components.settings.AccountsPane.b4c9450319',
- "No managed Codex accounts for {{value0}}. Orca will use that environment's system default Codex login until you add one here.",
- { value0: accountRuntimeSentenceLabel }
- )}
-
+
+ {systemCodexNeedsSignIn
+ ? systemCodexMissingSignIn
+ ? translate(
+ 'auto.components.settings.AccountsPane.codexSystemDefaultNeedsSignIn',
+ 'No Codex sign-in was found for {{value0}}.',
+ { value0: accountRuntimeSentenceLabel }
+ )
+ : translate(
+ 'auto.components.settings.AccountsPane.fd62f37c24',
+ 'Codex reported this {{value0}} login is out of date.',
+ { value0: accountRuntimeSentenceLabel }
+ )
+ : getCodexSystemDefaultSubtitle(
+ systemCodexIdentity,
+ accountRuntimeSentenceLabel
+ )}
+
+
+
+ {visibleCodexAccounts.length === 0 ? (
+
+ {isRemoteAccountScope
+ ? translate(
+ 'auto.components.settings.AccountsPane.remoteEmptyCodexAccounts',
+ 'No managed Codex accounts on {{value0}}. It uses its system default Codex login; add accounts on that server.',
+ { value0: accountRuntimeSentenceLabel }
+ )
+ : translate(
+ 'auto.components.settings.AccountsPane.b4c9450319',
+ "No managed Codex accounts for {{value0}}. Orca will use that environment's system default Codex login until you add one here.",
+ { value0: accountRuntimeSentenceLabel }
+ )}
+
- {translate(
- 'accounts.antigravity.signIn',
- 'Start agy on this host and complete its browser sign-in, then save the current account. To add a different account, use /logout in agy and sign in again.'
- )}{' '}
-
- {translate('accounts.antigravity.docs', 'Sign-in instructions')}
-
-
+ {translate(
+ 'accounts.antigravity.signIn',
+ 'Start agy on this host and complete its browser sign-in, then save the current account. To add a different account, use /logout in agy and sign in again.'
+ )}{' '}
+
+ {translate('accounts.antigravity.docs', 'Sign-in instructions')}
+
- {windowsHost
- ? translate(
- 'accounts.antigravity.windowsSessions',
- 'Select applies and verifies the host default agy credential. Command choices and later account changes are handled by agy. Existing sessions may keep their previous account.'
- )
- : translate(
- 'accounts.antigravity.sessions',
- 'Selection applies to new agy sessions on this host. Existing sessions may keep their previous account.'
- )}
-
+ {windowsHost
+ ? translate(
+ 'accounts.antigravity.windowsSessions',
+ 'Select applies and verifies the host default agy credential. Command choices and later account changes are handled by agy. Existing sessions may keep their previous account.'
+ )
+ : translate(
+ 'accounts.antigravity.sessions',
+ 'Selection applies to new agy sessions on this host. Existing sessions may keep their previous account.'
+ )}
+
- {translate(
- 'auto.components.settings.CursorAccountsSection.subtitle',
- 'Shows your Cursor plan usage from the sign-in already on this computer. Orca only reads it — it never changes your Cursor login.'
- )}
-
- {translate(
- 'auto.components.settings.CursorAccountsSection.signedOut',
- 'No Cursor sign-in found on this computer'
- )}
-
-
- {translate(
- 'auto.components.settings.CursorAccountsSection.signedOutHelp',
- 'Sign in with Cursor IDE, or run cursor-agent login in a terminal, then click Refresh usage here.'
- )}
-
+ {tokenFresh
+ ? sourceLabel
+ ? translate(
+ 'auto.components.settings.CursorAccountsSection.signedInFrom',
+ 'Signed in. Orca reads the session stored in {{source}}.',
+ { source: sourceLabel }
+ )
+ : translate(
+ 'auto.components.settings.CursorAccountsSection.signedInGeneric',
+ 'Signed in. Orca reads the Cursor session stored on this computer.'
+ )
+ : translate(
+ 'auto.components.settings.CursorAccountsSection.expired',
+ 'Sign-in expired — run cursor-agent login on the computer running Orca, then click Refresh usage.'
+ )}
+
+ >
+ ) : (
+ <>
+
+ {translate(
+ 'auto.components.settings.CursorAccountsSection.signedOut',
+ 'No Cursor sign-in found on this computer'
+ )}
+
+
+ {translate(
+ 'auto.components.settings.CursorAccountsSection.signedOutHelp',
+ 'Sign in with Cursor IDE, or run cursor-agent login in a terminal, then click Refresh usage here.'
+ )}
+
- {tokenFresh
- ? translate(
- 'auto.components.settings.GrokAccountsSection.b36fa2c908',
- 'Signed in. Orca reads the Grok CLI session stored on disk.'
- )
- : translate(
- 'auto.components.settings.GrokAccountsSection.f08c41de73',
- 'Session expired — run grok on the computer running Orca and wait for it to start. If prompted, complete sign-in, then click Refresh usage. No chat message is needed.'
+ {translate('auto.components.settings.GrokAccountsSection.ad47a33f72', 'Loading…')}
+
+ {tokenFresh
+ ? translate(
+ 'auto.components.settings.GrokAccountsSection.b36fa2c908',
+ 'Signed in. Orca reads the Grok CLI session stored on disk.'
+ )
+ : translate(
+ 'auto.components.settings.GrokAccountsSection.f08c41de73',
+ 'Session expired — run grok on the computer running Orca and wait for it to start. If prompted, complete sign-in, then click Refresh usage. No chat message is needed.'
+ )}
+
+ >
+ ) : (
+ <>
+
+ {translate(
+ 'auto.components.settings.GrokAccountsSection.e5f6a7b8c9',
+ 'Not signed in to Grok CLI'
+ )}
+
+
+ {translate(
+ 'auto.components.settings.GrokAccountsSection.f6a7b8c9d0',
+ 'In a terminal, run grok login, then click Refresh usage here.'
+ )}
+
- {translate(
- 'accounts.managedData.description',
- 'Add accounts by running this command in a terminal on the Orca host. Selection applies to new explicit agent launches on that host; direct SSH relay and Windows-hosted WSL launches use their own credentials.'
+ : translate('auto.lib.agent.catalog.fc80296033', 'Devin')
+ }
+ description={translate(
+ 'accounts.managedData.description',
+ 'Add accounts by running this command in a terminal on the Orca host. Selection applies to new explicit agent launches on that host; direct SSH relay and Windows-hosted WSL launches use their own credentials.'
+ )}
+ >
+
- {translate(
- 'auto.components.settings.AccountsPane.973741a871',
- 'Keep existing Gemini CLI sessions available. Gemini credentials do not sign you into Antigravity.'
- )}
-
-
-
-
+
+
+ {translate('auto.components.settings.AccountsPane.0c64dc2a64', 'Gemini CLI (legacy)')}
+
+ }
description={translate(
- 'auto.components.settings.AccountsPane.d676c41fc6',
- 'Extracts OAuth credentials from your local Gemini CLI installation to authenticate with Google. This uses credentials issued to the Gemini CLI app, not Orca. May break if Google updates the CLI. Use at your own risk.'
+ 'auto.components.settings.AccountsPane.973741a871',
+ 'Keep existing Gemini CLI sessions available. Gemini credentials do not sign you into Antigravity.'
)}
- keywords={[
- 'gemini',
- 'cli',
- 'oauth',
- 'credentials',
- 'experimental',
- 'rate limit',
- 'status bar'
- ]}
- className="flex items-center justify-between gap-4 py-2"
>
-
- {translate(
- 'auto.components.settings.AccountsPane.62ab430f94',
- "Paste the full Cookie header from your browser's DevTools → Network → any opencode.ai request, including __Host-console_session (e.g."
- )}{' '}
-
- {translate(
- 'auto.components.settings.AccountsPane.37b4b4a3f7',
- 'auth=…; __Host-console_session=…'
- )}
-
- {translate(
- 'auto.components.settings.AccountsPane.d5267cce63',
- '). The auth cookie still covers workspace discovery; auth alone is not enough for usage. OpenCode Go auth is web-based and shared across Windows and WSL terminals.'
- )}
-
+ {translate(
+ 'auto.components.settings.AccountsPane.62ab430f94',
+ "Paste the full Cookie header from your browser's DevTools → Network → any opencode.ai request, including __Host-console_session (e.g."
+ )}{' '}
+
+ {translate(
+ 'auto.components.settings.AccountsPane.37b4b4a3f7',
+ 'auth=…; __Host-console_session=…'
+ )}
+
+ {translate(
+ 'auto.components.settings.AccountsPane.d5267cce63',
+ '). The auth cookie still covers workspace discovery; auth alone is not enough for usage. OpenCode Go auth is web-based and shared across Windows and WSL terminals.'
+ )}
+
- {translate(
- 'auto.components.settings.ZcodePlanAccountsSection.subtitle',
- 'Track Z.AI or Zhipu (BigModel) GLM Coding Plan usage in the status bar. Save the plan API key here — no ZCode CLI setup needed.'
- )}
-
- {translate(
- 'auto.components.settings.ZcodePlanAccountsSection.detailsUnavailable',
- 'Plan credential details are only readable on the computer running Orca.'
- )}
-
- {hostLabel === null
- ? translate(
- 'auto.components.settings.ZcodePlanAccountsSection.keyStoredHelp',
- 'Stored locally and sent only to the selected site for usage refreshes. It takes priority over the ZCode CLI sign-in.'
- )
- : translate(
- 'auto.components.settings.ZcodePlanAccountsSection.keyStoredOnHostHelp',
- 'Stored on {{host}} and sent from there only to the selected site for usage refreshes. It takes priority over the ZCode CLI sign-in.',
- { host: hostLabel }
- )}
-
- {hostLabel === null
- ? translate(
- 'auto.components.settings.ZcodePlanAccountsSection.usingCliHelp',
- 'Orca reads the selected Coding Plan from the ZCode CLI credential store on this computer. Save an API key below to link the plan here instead.'
- )
- : translate(
- 'auto.components.settings.ZcodePlanAccountsSection.usingCliOnHostHelp',
- 'Orca reads the selected Coding Plan from the ZCode CLI credential store on {{host}}. Save an API key below to link the plan there instead.',
- { host: hostLabel }
- )}
-
- {hostLabel === null
- ? translate(
- 'auto.components.settings.ZcodePlanAccountsSection.notConfiguredHelp',
- 'Save the plan API key below, or sign in with the ZCode CLI on this computer.'
- )
- : translate(
- 'auto.components.settings.ZcodePlanAccountsSection.notConfiguredOnHostHelp',
- 'Save the plan API key below, or sign in with the ZCode CLI on {{host}}.',
- { host: hostLabel }
- )}
-
- {translate(
- 'auto.components.settings.ZcodePlanAccountsSection.hostOnly',
- 'Change the plan site and API key in the desktop app on the computer running Orca.'
- )}
-
- ) : null}
-
-
+ }
description={translate(
- 'auto.components.settings.ZcodePlanAccountsSection.siteDescription',
- 'Pick the console your Coding Plan belongs to: Z.AI for the international site, Zhipu BigModel for the mainland site.'
+ 'auto.components.settings.ZcodePlanAccountsSection.subtitle',
+ 'Track Z.AI or Zhipu (BigModel) GLM Coding Plan usage in the status bar. Save the plan API key here — no ZCode CLI setup needed.'
)}
- keywords={SEARCH_KEYWORDS}
- className="space-y-2"
- >
-
- {translate('auto.components.settings.ZcodePlanAccountsSection.siteTitle', 'Plan site')}
-
-
-
-
-
-
+ {translate(
+ 'auto.components.settings.ZcodePlanAccountsSection.detailsUnavailable',
+ 'Plan credential details are only readable on the computer running Orca.'
+ )}
+
+ {hostLabel === null
+ ? translate(
+ 'auto.components.settings.ZcodePlanAccountsSection.keyStoredHelp',
+ 'Stored locally and sent only to the selected site for usage refreshes. It takes priority over the ZCode CLI sign-in.'
+ )
+ : translate(
+ 'auto.components.settings.ZcodePlanAccountsSection.keyStoredOnHostHelp',
+ 'Stored on {{host}} and sent from there only to the selected site for usage refreshes. It takes priority over the ZCode CLI sign-in.',
+ { host: hostLabel }
+ )}
+
+ {hostLabel === null
+ ? translate(
+ 'auto.components.settings.ZcodePlanAccountsSection.usingCliHelp',
+ 'Orca reads the selected Coding Plan from the ZCode CLI credential store on this computer. Save an API key below to link the plan here instead.'
+ )
+ : translate(
+ 'auto.components.settings.ZcodePlanAccountsSection.usingCliOnHostHelp',
+ 'Orca reads the selected Coding Plan from the ZCode CLI credential store on {{host}}. Save an API key below to link the plan there instead.',
+ { host: hostLabel }
+ )}
+
+ {hostLabel === null
+ ? translate(
+ 'auto.components.settings.ZcodePlanAccountsSection.notConfiguredHelp',
+ 'Save the plan API key below, or sign in with the ZCode CLI on this computer.'
+ )
+ : translate(
+ 'auto.components.settings.ZcodePlanAccountsSection.notConfiguredOnHostHelp',
+ 'Save the plan API key below, or sign in with the ZCode CLI on {{host}}.',
+ { host: hostLabel }
+ )}
+
- {translate(
- 'auto.components.settings.ZcodePlanAccountsSection.keyHelp',
- 'The same key your coding tools use for the plan (for example Claude Code with ANTHROPIC_BASE_URL pointed at the site). Switching the site above changes which host receives it.'
- )}
-
+ {translate(
+ 'auto.components.settings.ZcodePlanAccountsSection.hostOnly',
+ 'Change the plan site and API key in the desktop app on the computer running Orca.'
+ )}
+
+ {translate(
+ 'auto.components.settings.ZcodePlanAccountsSection.keyHelp',
+ 'The same key your coding tools use for the plan (for example Claude Code with ANTHROPIC_BASE_URL pointed at the site). Switching the site above changes which host receives it.'
+ )}
+
- {translate(
- 'auto.components.settings.ExperimentalPane.ca2219fe5e',
- 'Shows a small animated pet pinned to the bottom-right corner. Pick a character (Claudino, OpenCode, Gremlin) or upload your own PNG, APNG, GIF, WebP, JPG, or SVG from the status-bar pet menu. Hide it any time from the same menu without disabling this setting.'
+ {showPet ? (
+
+
+ {translate(
+ 'auto.components.settings.ExperimentalPane.ca2219fe5e',
+ 'Shows a small animated pet pinned to the bottom-right corner. Pick a character (Claudino, OpenCode, Gremlin) or upload your own PNG, APNG, GIF, WebP, JPG, or SVG from the status-bar pet menu. Hide it any time from the same menu without disabling this setting.'
+ )}
+
+ {translate(
+ 'auto.components.settings.ExperimentalPane.a20d5ea365',
+ 'Keeps a pane-level highlight visible after terminal bell or agent-completion events until you interact with that pane. Experimental while we tune the signal.'
+ )}
+
+
+
-
- {translate(
- 'auto.components.settings.ExperimentalPane.a20d5ea365',
- 'Keeps a pane-level highlight visible after terminal bell or agent-completion events until you interact with that pane. Experimental while we tune the signal.'
- )}
-
- {translate(
- 'auto.components.settings.ExperimentalPane.agentHibernation.copy',
- 'Stops idle background agent terminals after the configured idle window and resumes supported sessions when you open them again. Agent sleep preserves launch options for agents started by Orca. Manually started agents may resume with your current Orca defaults. Experimental while we tune the safety model.'
- )}
-
+ {translate(
+ 'auto.components.settings.ExperimentalPane.agentHibernation.copy',
+ 'Stops idle background agent terminals after the configured idle window and resumes supported sessions when you open them again. Agent sleep preserves launch options for agents started by Orca. Manually started agents may resume with your current Orca defaults. Experimental while we tune the safety model.'
+ )}
+
+
+
-
- {translate(
- 'auto.components.settings.ExperimentalPane.newWorktreeCardStyle.copy',
- 'Preview updated worktree-card layout, metadata placement, card-display menu options, and status presentation.'
- )}
-
- {translate(
- 'auto.components.settings.artifacts.signInTitle',
- 'Sign in to share artifacts'
- )}
-
-
- {translate(
- 'auto.components.settings.artifacts.signInDescription',
- 'Use your Orca account to upload artifacts and manage their public links.'
- )}
-
-
-
- {authStatus?.state === 'reconnect-required'
- ? translate('auto.components.settings.artifacts.signInAgain', 'Sign in again')
- : translate('auto.components.settings.artifacts.signIn', 'Sign in to Orca')}
-
-
-
- ) : null}
-
-
-
- {translate('auto.components.settings.artifacts.howToTitle', 'How to use Artifacts')}
-
+ {translate(
+ 'auto.components.settings.artifacts.signInTitle',
+ 'Sign in to share artifacts'
)}
-
-
+
+
+ {translate(
+ 'auto.components.settings.artifacts.signInDescription',
+ 'Use your Orca account to upload artifacts and manage their public links.'
+ )}
+
+
+
+ {authStatus?.state === 'reconnect-required'
+ ? translate('auto.components.settings.artifacts.signInAgain', 'Sign in again')
+ : translate('auto.components.settings.artifacts.signIn', 'Sign in to Orca')}
+
+
+
+ ) : null}
+
+
+
- {translate(
- 'auto.components.settings.automations.howItWorksDescription',
- 'Schedule agent work once, then let Orca create each run and keep its results together.'
- )}
-
+ {translate(
+ 'auto.components.settings.automations.runStepDescription',
+ 'The selected agent gets a fresh workspace when the schedule is due.'
+ )}
+
+ {translate(
+ 'auto.components.settings.automations.reviewStepDescription',
+ 'Inspect recent runs and continue the work whenever you need to.'
+ )}
+
- {translate(
- 'auto.components.settings.automations.runStepDescription',
- 'The selected agent gets a fresh workspace when the schedule is due.'
- )}
-
- {translate(
- 'auto.components.settings.automations.reviewStepDescription',
- 'Inspect recent runs and continue the work whenever you need to.'
- )}
-
- {translate(
- 'auto.components.settings.CliSection.outsideOrcaDescription',
- 'Orca terminals already have `orca`. Turn this on to use `orca` from other terminals outside Orca.'
- )}
-
- {status.pathDirectory}{' '}
- {translate(
- 'auto.components.settings.CliSection.7f2747f7dd',
- 'is not currently visible on PATH for this shell.'
- )}
-
+ {status.pathDirectory}{' '}
+ {translate(
+ 'auto.components.settings.CliSection.7f2747f7dd',
+ 'is not currently visible on PATH for this shell.'
)}
{translate(
- 'auto.components.settings.CliSection.installFailureConflictRemedy',
- 'Remove {{value0}} and register again if it is no longer needed.',
- { value0: installFailure.conflictCommandPath }
+ 'auto.components.settings.CliSection.a2b13efa94',
+ 'Failed to register `{{value0}}` in PATH.',
+ { value0: commandName }
)}
- ) : null}
-
- ) : null}
+
{installFailure.reason}
+ {installFailure.conflictCommandPath ? (
+
+ {translate(
+ 'auto.components.settings.CliSection.installFailureConflictRemedy',
+ 'Remove {{value0}} and register again if it is no longer needed.',
+ { value0: installFailure.conflictCommandPath }
+ )}
+
- {translate(
- 'auto.components.settings.DeveloperPermissionsPane.6326a4c5cc',
- 'Use these controls when a CLI, local app, or automation tool needs macOS privacy access. Orca does not ask at startup.'
- )}
-
- {translate(
- 'auto.components.settings.IntegrationsPane.1683acbac4',
- 'Connect the source hosts Orca can use for pull requests, merge requests, checks, and review status.'
- )}
-
- {translate(
- 'auto.components.settings.IntegrationsPane.3ba07f933b',
- 'Connect issue trackers Orca can use to browse tasks and start workspaces with linked context.'
- )}
-
- {translate(
- 'auto.components.settings.MobileEmulatorAgentControlRow.ff4b7e65d6',
- 'Let coding agents control the active mobile emulator with Orca CLI commands.'
- )}
-
-
-
-
-
+
+
-
+
)
}
diff --git a/src/renderer/src/components/settings/mobile/emulator/MobileEmulatorSettingsPane.tsx b/src/renderer/src/components/settings/mobile/emulator/MobileEmulatorSettingsPane.tsx
index eaf4cf9499c..45f292a2c32 100644
--- a/src/renderer/src/components/settings/mobile/emulator/MobileEmulatorSettingsPane.tsx
+++ b/src/renderer/src/components/settings/mobile/emulator/MobileEmulatorSettingsPane.tsx
@@ -10,6 +10,7 @@ import { EmulatorOpeningSettings } from './EmulatorOpeningSettings'
import { MobileEmulatorAgentControlRow } from './MobileEmulatorAgentControlRow'
import { MobileEmulatorAvailabilityDetails } from './MobileEmulatorAvailabilityDetails'
import { SearchableSetting } from '../../section-layout/SearchableSetting'
+import { SettingsGroup } from '../../section-layout/SettingsGroup'
import { SettingsSwitchRow } from '../../form-controls/SettingsFormControls'
import { getMobileEmulatorSearchEntries } from './mobile-emulator-search'
import { translate } from '@/i18n/i18n'
@@ -135,90 +136,92 @@ export function MobileEmulatorSettingsPane({
const devices = availability?.devices ?? []
return (
-
- {translate(
- 'auto.components.settings.RepositoryHooksSection.8567127a40',
- 'Scripts that run when worktrees are created or archived. Local scripts are stored on this machine; `orca.yaml` scripts are shared with your team.'
+ description={translate(
+ 'auto.components.settings.RepositoryHooksSection.30d555acd2',
+ 'Local and shared scripts that run after a new worktree is created.'
)}
-
- {translate(
- 'auto.components.settings.WorktreeSymlinksSection.7ff265071d',
- 'When a new worktree is created, each path listed here is APFS clone-copied on macOS when possible, otherwise symlinked from the primary checkout.'
- )}
-
- {translate(
- 'auto.components.settings.McpConfigSection.96f5609b04',
- 'Inspect MCP server definitions that agents can use while working in this repo.'
- )}
-
+
+ {translate(
+ 'auto.components.settings.McpConfigSection.96f5609b04',
+ 'Inspect MCP server definitions that agents can use while working in this repo.'
+ )}
{connectionId ? (
-
+
{translate(
'auto.components.settings.McpConfigSection.6bac9ddfc6',
'SSH repos are read through the remote filesystem. Starter creation is limited to the workspace root config.'
)}
-
)
diff --git a/src/renderer/src/components/settings/section-layout/SettingsGroup.tsx b/src/renderer/src/components/settings/section-layout/SettingsGroup.tsx
new file mode 100644
index 00000000000..ad935379f36
--- /dev/null
+++ b/src/renderer/src/components/settings/section-layout/SettingsGroup.tsx
@@ -0,0 +1,72 @@
+import type React from 'react'
+import { cn } from '@/lib/utils'
+
+type SettingsGroupProps = {
+ title?: React.ReactNode
+ description?: React.ReactNode
+ action?: React.ReactNode
+ children?: React.ReactNode
+ className?: string
+ bodyClassName?: string
+ onHeaderClick?: (event: React.MouseEvent) => void
+}
+
+// Title sits outside the card so each group's start and end read at a glance.
+export function SettingsGroup({
+ title,
+ description,
+ action,
+ children,
+ className,
+ bodyClassName,
+ onHeaderClick
+}: SettingsGroupProps): React.JSX.Element {
+ return (
+
+ {title ? (
+
+ ) : null}
+
[data-settings-group-body]:empty]:hidden',
+ bodyClassName
+ )}
+ >
+ {/* A row inside another row (a sub-field) draws no rule; each outermost row draws one and the card clips the first. */}
+
+ {children}
+
+
+
+ )
+}
+
+// Shared so lists that must keep row identity across groups can draw the same header.
+export function SettingsGroupHeader({
+ title,
+ description,
+ action,
+ className,
+ onClick
+}: Pick & {
+ onClick?: (event: React.MouseEvent) => void
+}): React.JSX.Element {
+ return (
+
+
+
{title}
+ {description ?
{description}
: null}
+
+ {action ?
{action}
: null}
+
+ )
+}
diff --git a/src/renderer/src/components/settings/section-layout/SettingsSection.tsx b/src/renderer/src/components/settings/section-layout/SettingsSection.tsx
index 381b785ab09..d6035cad492 100644
--- a/src/renderer/src/components/settings/section-layout/SettingsSection.tsx
+++ b/src/renderer/src/components/settings/section-layout/SettingsSection.tsx
@@ -18,6 +18,8 @@ type SettingsSectionProps = {
children?: React.ReactNode
className?: string
bodyClassName?: string
+ /** Pane is built from SettingsGroup cards, so the body drops its own card. Fixed per pane, never query-dependent. */
+ grouped?: boolean
badge?: string
badgeAccessory?: React.ReactNode
forceVisible?: boolean
@@ -40,6 +42,7 @@ export function SettingsSection({
children,
className,
bodyClassName,
+ grouped = false,
badge,
badgeAccessory,
forceVisible = false,
@@ -86,10 +89,11 @@ export function SettingsSection({
{headerAction ?
{headerAction}
: null}
- {/* Contain row groups in a distinct band so they cannot read as sidebar continuations. */}
diff --git a/src/renderer/src/components/settings/section-layout/SettingsSectionStack.tsx b/src/renderer/src/components/settings/section-layout/SettingsSectionStack.tsx
index 678de7c1942..5193ceb2308 100644
--- a/src/renderer/src/components/settings/section-layout/SettingsSectionStack.tsx
+++ b/src/renderer/src/components/settings/section-layout/SettingsSectionStack.tsx
@@ -1,23 +1,10 @@
import type { ReactElement } from 'react'
-import { Separator } from '../../ui/separator'
-// Key by section identity, not filtered index, so query edits cannot remount surviving sections and lose drafts or repeat loads.
+// Render sections by their own keys, not filtered index, so query edits cannot remount surviving sections and lose drafts or repeat loads.
export function SettingsSectionStack({
- sections,
- spacing
+ sections
}: {
sections: readonly (ReactElement | null)[]
- spacing: 'section' | 'group'
}): ReactElement {
- const visibleSections = sections.filter((section): section is ReactElement => section !== null)
- return (
- <>
- {visibleSections.map((section, index) => (
-
- {translate(
- 'auto.components.settings.LinearAgentSkillGuide.setupBody',
- 'All three are required for the full Tasks + agent loop. First-time path is also under Task Sources.'
- )}
-
@@ -242,6 +237,6 @@ export function LinearAgentSkillGuide({
-
+
)
}
diff --git a/src/renderer/src/components/settings/skills/linear/LinearAgentSkillNotes.tsx b/src/renderer/src/components/settings/skills/linear/LinearAgentSkillNotes.tsx
index fcf13e0df76..c2614d5667b 100644
--- a/src/renderer/src/components/settings/skills/linear/LinearAgentSkillNotes.tsx
+++ b/src/renderer/src/components/settings/skills/linear/LinearAgentSkillNotes.tsx
@@ -1,31 +1,24 @@
import { getLinearGuideNotes } from './linear-agent-skill-guide-content'
import { translate } from '@/i18n/i18n'
+import { SettingsGroup } from '../../section-layout/SettingsGroup'
export function LinearAgentSkillNotes(): React.JSX.Element {
const notes = getLinearGuideNotes()
return (
-
-
-
- {translate('auto.components.settings.LinearAgentSkillGuide.notesTitle', 'Good to know')}
-
-
- {translate(
- 'auto.components.settings.LinearAgentSkillGuide.notesIntro',
- 'Quick reminders once Linear is connected and the skill is installed.'
- )}
-
- {translate(
- 'auto.components.settings.shareSkills.linkDescription',
- 'Shared bundles are not searchable or listed in Orca. The link is the credential, so send it only to people you trust.'
- )}
-
-
-
-
+ void updateSettings({ agentSkillSharingEnabled: !agentSharingEnabled })}
- />
-
- {!isWebClient ? (
+ >
void updateSettings({ showSkillsButton: !settings?.showSkillsButton })}
+ description={
+ isWebClient
+ ? translate(
+ 'auto.components.settings.shareSkills.allowAgentPublishingWebDescription',
+ 'Desktop only. Open Settings → Share Skills on the host device to change this setting.'
+ )
+ : translate(
+ 'auto.components.settings.shareSkills.allowAgentPublishingDescription',
+ 'Let commands publish explicitly named installed skills. Skill folders can contain scripts, configuration, or secrets, so this is off by default.'
+ )
+ }
+ checked={agentSharingEnabled}
+ disabled={isWebClient}
+ onChange={() => void updateSettings({ agentSkillSharingEnabled: !agentSharingEnabled })}
/>
- ) : null}
-
- {!signedIn ? (
-
-
-
- {translate(
- 'auto.components.settings.shareSkills.signInTitle',
- 'Sign in to share skills'
- )}
-
-
- {isWebClient
- ? translate(
- 'auto.components.settings.shareSkills.signInWebDescription',
- 'Publishing and link management are available in the Orca desktop app.'
- )
- : translate(
- 'auto.components.settings.shareSkills.signInDescription',
- 'Use your Orca account to publish bundles and manage their links. Recipients do not need an account.'
- )}
-
-
- {!isWebClient ? (
-
- {authStatus?.state === 'reconnect-required'
- ? translate('auto.components.settings.shareSkills.signInAgain', 'Sign in again')
- : translate('auto.components.settings.shareSkills.signIn', 'Sign in to Orca')}
-
- ) : null}
- {!isWebClient ? : null}
-
- ) : null}
-
- {/* Keep unbounded link inventory on its publishing page; Settings retains the preference and navigation. */}
- {signedIn && !isWebClient ? (
-
-
- {translate(
- 'auto.components.settings.shareSkills.activeLinksDescription',
- 'Only people with a link can open it. Unshare a link to block future inspection and installs.'
- )}
-
- {translate('auto.components.settings.shareSkills.howToTitle', 'How to share skills')}
-
-
- {translate(
- 'auto.components.settings.shareSkills.howToDescription',
- 'Publish one skill or a bundle such as a collection of 30 skills behind one link.'
- )}
-
+ {translate(
+ 'auto.components.settings.shareSkills.signInTitle',
+ 'Sign in to share skills'
+ )}
+
+
+ {isWebClient
+ ? translate(
+ 'auto.components.settings.shareSkills.signInWebDescription',
+ 'Publishing and link management are available in the Orca desktop app.'
+ )
+ : translate(
+ 'auto.components.settings.shareSkills.signInDescription',
+ 'Use your Orca account to publish bundles and manage their links. Recipients do not need an account.'
+ )}
+
+
+ {!isWebClient ? (
+
+ {authStatus?.state === 'reconnect-required'
+ ? translate('auto.components.settings.shareSkills.signInAgain', 'Sign in again')
+ : translate('auto.components.settings.shareSkills.signIn', 'Sign in to Orca')}
+
+ ) : null}
+ {!isWebClient ? : null}
+
+ ) : null}
+
+ {/* Keep unbounded link inventory on its publishing page; Settings retains the preference and navigation. */}
+ {signedIn && !isWebClient ? (
+
+
+ {translate(
+ 'auto.components.settings.shareSkills.activeLinksDescription',
+ 'Only people with a link can open it. Unshare a link to block future inspection and installs.'
+ )}
+
) : null}
diff --git a/src/renderer/src/components/settings/tasks/TasksPane.tsx b/src/renderer/src/components/settings/tasks/TasksPane.tsx
index 20bf758f639..f7ec6a4af55 100644
--- a/src/renderer/src/components/settings/tasks/TasksPane.tsx
+++ b/src/renderer/src/components/settings/tasks/TasksPane.tsx
@@ -13,7 +13,6 @@ import { LinearIcon } from '@/components/icons/LinearIcon'
import { Button } from '@/components/ui/button'
import { useAppStore } from '@/store/index'
import { SearchableSetting } from '../section-layout/SearchableSetting'
-import { SettingsSubsectionHeader } from '../form-controls/SettingsFormControls'
import { CodeHostSetupSteps, JiraSetupSteps } from './TaskSourceSimpleSetup'
import { TaskSourceLinearSetup } from './TaskSourceLinearSetup'
import { TaskSourceProviderCard } from './TaskSourceProviderCard'
@@ -29,6 +28,7 @@ import { getTasksPaneSearchKeywords } from './tasks-search'
import { useIntegrationProviderStatusRefresh } from '../../../hooks/use-integration-provider-status-refresh'
import { useTaskSourceProviderReadiness } from './use-task-source-provider-readiness'
import { translate } from '@/i18n/i18n'
+import { SettingsGroup } from '../section-layout/SettingsGroup'
type TasksPaneProps = {
settings: GlobalSettings
@@ -141,128 +141,121 @@ export function TasksPane({ settings, updateSettings }: TasksPaneProps): React.J
}
return (
-
-
-
-
- {stalledVisible.length > 0 ? (
-
-
- {translate(
- 'auto.components.settings.TasksPane.incompleteBannerTitle',
- 'Some visible providers still need setup'
- )}
-
-
- {stalledVisible.includes('linear')
- ? translate(
- 'auto.components.settings.TasksPane.incompleteBannerBodyWithLinear',
- 'Hide providers you do not use, or expand a card and finish its steps. For Linear: API access, the agent skill, and Show in Tasks.'
- )
- : translate(
- 'auto.components.settings.TasksPane.incompleteBannerBody',
- 'Hide providers you do not use, or expand a card and finish its steps.'
- )}
-
+ {translate(
+ 'auto.components.settings.TasksPane.incompleteBannerTitle',
+ 'Some visible providers still need setup'
+ )}
+
+
+ {stalledVisible.includes('linear')
+ ? translate(
+ 'auto.components.settings.TasksPane.incompleteBannerBodyWithLinear',
+ 'Hide providers you do not use, or expand a card and finish its steps. For Linear: API access, the agent skill, and Show in Tasks.'
+ )
+ : translate(
+ 'auto.components.settings.TasksPane.incompleteBannerBody',
+ 'Hide providers you do not use, or expand a card and finish its steps.'
)}
-
- )
- })}
-
+
+
+ ) : null}
-
- {translate(
- 'auto.components.settings.TasksPane.integrationsHint',
- 'Credentials for all providers also live under'
- )}{' '}
- openIntegrations()}
- >
- {translate('auto.components.settings.TasksPane.integrationsLink', 'Integrations')}
-
- {translate(
- 'auto.components.settings.TasksPane.skillHint',
- '. After Linear is connected, usage examples stay under Settings → Linear.'
- )}
-
+ {translate(
+ 'auto.components.settings.TerminalPane.scrollSpeed.helper',
+ 'Adjust how wheel input feels in scrollback and in mouse-aware terminal apps.'
+ )}
+
- {translate(
- 'auto.components.settings.TerminalPane.scrollSpeed.helper',
- 'Adjust how wheel input feels in scrollback and in mouse-aware terminal apps.'
- )}
-
- {translate(
- 'auto.components.settings.ManageSessionsSection.7c4889a724',
- 'Recover from a frozen or misbehaving terminal by killing sessions or restarting the underlying daemon.'
- )}
-
-
-
+
-
+
)
}
diff --git a/src/renderer/src/components/settings/updates/GeneralUpdateSettingsSection.test.tsx b/src/renderer/src/components/settings/updates/GeneralUpdateSettingsSection.test.tsx
new file mode 100644
index 00000000000..a19388dfbd8
--- /dev/null
+++ b/src/renderer/src/components/settings/updates/GeneralUpdateSettingsSection.test.tsx
@@ -0,0 +1,44 @@
+// @vitest-environment happy-dom
+
+import { act, cleanup, fireEvent, render, screen } from '@testing-library/react'
+import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
+import { useAppStore } from '../../../store'
+import { TooltipProvider } from '../../ui/tooltip'
+import { GeneralUpdateSettingsSection } from './GeneralUpdateSettingsSection'
+
+vi.mock('./ReleaseChannelSection', () => ({
+ ReleaseChannelSection: () =>