Cloud start: no visible login, one cached login per person, no remote_denied retry loop

Merged
TE
2d ago
+114-16

Leo, on his first Cloud chat in NIGHTLY 036f8aa5: "bro. we literally said we were gonna do is such that you literally dont need to log in." He got the modal "Set up Claude on cloud-chats-3? cmux will run claude setup-token in a visible local terminal", then a local terminal, a browser and a verification code.

Cause: a start whose account had no cached setup-token login under the selected team fell to confirmThenInstall: the modal, then CloudCredentialLogin.acquire in a visible terminal. The cache is keyed per user and team, so any team switch asked again.

Fix:

  • A start never opens a terminal or that modal. With no cached login for this person it passes nothing, and the chat's own "Sign in to Claude" card (acpmux agent_login, #33744: one click plus the provider's approve page) signs the machine in on the person's click. The start's record says why (no cached login: the chat's Sign in to Claude card).
  • The cached login is found under the selected team, else any of the account's other teams or its personal scope (CloudCredentialLogin.loadAny). One login per person. No Claude Code refresh token is read or copied (signing Leo out of Claude Code on his Mac would be worse).
  • A resync whose list-agents the link refuses (remote_denied: the Native carrier serves no list-agents) keeps its tree and stops, instead of failing and retrying. NIGHTLY logged 566 such refusals in 30 minutes. DaemonError.isRemoteDenied types it.

Pairs with #36044 (the folder copy over the owner's Native dial and the false "older cmux").

Agent session: agent session

🤖 Generated with Claude Code


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Cloud start no longer forces a visible login. Previously, starting a Cloud chat with no cached Claude login under the selected team opened the setup-token modal, a local terminal, a browser, and a verification code. Now a start passes nothing and lets the chat's own "Sign in to Claude" card handle login, and the start record notes why.

The cached login is reused across the account's teams and personal scope, so a team switch doesn't ask for sign-in again—one login per person. A bad cache entry under the selected team never hides a good one elsewhere, and Claude Code refresh tokens are never read or copied.

A start that isn't failed shows only the message and a Thinking line, so it reads like a local first turn; the steps appear only on failure. A remembered machine that is gone is dropped and a new one is made, and a paused machine resumes at once instead of waiting for it to run first.

A resync whose list-agents the link refuses (remote_denied) keeps its tree and stops instead of failing and retrying, which previously logged hundreds of refusals in 30 minutes.