Files
orca/src/shared/account-runtime-capabilities.ts
T
Neil abce679f88 feat(accounts): add Claude and Codex accounts on a remote server from a paired client (#31461)
* feat(accounts): add Claude and Codex accounts to a remote server from a paired client

The server runs the login (Claude's pasted-code sign-in, Codex's device
code) and keeps the credentials; the client only opens the page and
relays the code. New capability-negotiated accounts.hostSignIn* methods;
older servers degrade to an update message.

Fixes #20009

* fix(accounts): settle host sign-ins by the login's outcome, pin pairing, guard stdin

Review fixes: a cancel the login refused still reports the added account;
the client pins each flow to its pairing revision; Claude's stdin EPIPE no
longer crashes the host; both sides accept only the provider's sign-in
host; pasted codes reject whitespace; a host-side supersede says so; Codex
cancels its own login handle; opt-in real-CLI test.

* fix(accounts): keep an early Cancel, retry polls through the host's window, scan Claude stdout only

A Cancel clicked before the host answers the start is applied once it does;
the client keeps polling through a short outage until the host would have
ended the flow; Claude's link is read from stdout only; a timeout after the
code was sent keeps its own message.

* test(accounts): name the stdin sender and allow its stream write in the persistence ratchet

* fix(accounts): register each Add Account attempt before its first await

One attempt per click owns the pairing pin, the cancel flag and the host's
flow, so a Cancel during the capability check or the start is never lost;
polls retry only lost answers; the stdout forwarder is removed on cleanup.

* refactor(accounts): drive the client sign-in as one explicit state machine per server and provider

checking -> starting -> following -> settled, with Cancel as a flag the run
loop delivers once the host names its flow and re-asks after any answer
until the host takes it. A second Add joins the running attempt; a Cancel
the server could not be told about is surfaced; retry policy tested.

* fix(accounts): retry a lost start answer, and report a cancelled sign-in as cancelled however it ends

* fix(accounts): Cancel reaches the server a sign-in runs on, and a typed code stays with its flow

The host picker can move while a sign-in runs: Cancel now targets the
running server sign-in (or the desktop's own login when none runs), and
the pasted-code form is keyed by server and flow.

* fix(accounts): run at most one server sign-in per provider, so Cancel has one meaning

* fix(accounts): the server sign-in prompt owns its Cancel

Cancel for a server sign-in now lives in the prompt bound to that server,
which also reappears with its Cancel when Settings reopens mid-sign-in; the
header Cancel is only for this desktop's own login.

* fix(accounts): hide the desktop-login Cancel while a server sign-in runs; narrow the prompt's status

* fix(accounts): keep the desktop-login Cancel in local scope even while a server sign-in runs

* fix(accounts): the header Cancel follows the running addition, wherever Settings now points

Each Add Account records where it is signing in. Cancel stops that
sign-in, on a server or this desktop, and is hidden only where that
server's own prompt already offers Cancel.
2026-10-21 03:16:45 -07:00

25 lines
1.5 KiB
TypeScript

export const CODEX_RESET_CREDIT_RUNTIME_CAPABILITY = 'accounts.codex-reset-credit.v1' as const
export const ACCOUNT_IMPORT_RUNTIME_CAPABILITY = 'accounts.import-host-credentials.v1' as const
// Why: `orca account add claude` signs in to an account folder the host creates first.
export const CLAUDE_SIGN_IN_RUNTIME_CAPABILITY = 'accounts.claude-sign-in.v1' as const
export const ANTIGRAVITY_ACCOUNTS_RUNTIME_CAPABILITY = 'accounts.antigravity-native.v1' as const
// Why separate: a host that serves the terminal accounts may predate the chat sign-in's methods.
export const ANTIGRAVITY_CHAT_SIGN_IN_RUNTIME_CAPABILITY =
'accounts.antigravity-chat-sign-in.v1' as const
export const DATA_ACCOUNT_RUNTIME_CAPABILITY = 'accounts.managed-data-profiles.v1' as const
// Why: MiniMax and GLM Coding Plan keys saved on the host its usage poller reads.
export const USAGE_CREDENTIALS_RUNTIME_CAPABILITY = 'accounts.usage-credentials.v1' as const
// Why: a paired client adds a Claude/Codex account whose login runs on this host (#20009).
export const HOST_ACCOUNT_SIGN_IN_RUNTIME_CAPABILITY = 'accounts.host-sign-in.v1' as const
export const ACCOUNT_RUNTIME_CAPABILITIES = [
ACCOUNT_IMPORT_RUNTIME_CAPABILITY,
CLAUDE_SIGN_IN_RUNTIME_CAPABILITY,
ANTIGRAVITY_ACCOUNTS_RUNTIME_CAPABILITY,
ANTIGRAVITY_CHAT_SIGN_IN_RUNTIME_CAPABILITY,
DATA_ACCOUNT_RUNTIME_CAPABILITY,
CODEX_RESET_CREDIT_RUNTIME_CAPABILITY,
USAGE_CREDENTIALS_RUNTIME_CAPABILITY,
HOST_ACCOUNT_SIGN_IN_RUNTIME_CAPABILITY
] as const