Composer Cloud: Cloud as where a new chat runs, its folder default and start progress (fold of #26801, #26920, #26921)
Folds #26801, #26920 and #26921 into one PR, with their original commits kept (merged onto current feat-cmux-next, conflicts resolved in the merge commit). It stacks on #28111 (cloud.startChat first send), whose commits are in this branch until it lands; after that, an update-branch leaves only this PR's own diff (about 1,560 lines).
Leo: "where is everything cloud related? what are our goals, etc, why do we even have hundreds of things unmerged?" / "a lot of this stuff shouldn't require so much deliberation" / "are prs slowing us down or are they necessary / why dont we work on a big ol' branch".
What it does
- #26801: Cloud is a row at the top of the environment picker's Cloud section, as where a new chat runs. Picking it drops a saved environment and refocuses the prompt. Sending runs
cloud.startChat, which copies the folder the chip names to the person's Cloud machine and opens the chat there. A Cloud pick that isn't offered right now is refused and keeps the prompt. One start runs at a time from a page. The gallery has the two other designs beside the shipped row. - #26920: a new chat's run location defaults to where the newest chat in its folder ran. A carried-over Cloud is a default the folder may undo, and it doesn't change while a start is out.
- #26921: a chat starting in Cloud shows its progress under the message (machine, folder, opening), using the design-token spacing. The host pushes each step to the page's card.
Why one PR, not three
The three are one stack, each built on the last. #26920's default reads the run mode #26801 adds, and #26921's card is fed from #26801's start. Landed apart, each would need its own rebase over 1,795 base commits and its own review of the same files. Together they are about 1,560 lines. The Auto row (#26940/#26941) is a real seam and goes in its own PR on top of this one.
Conflicts resolved against current base
App.tsx: base moved the NewTabScreen block above the history branch.onCloud,cloudStatusandcloudPickedNotOfferedwere ported to its new place, and the old-position block was dropped.ComposerContext.tsx: kept base's waiting-machine face (waitingName) beside the Cloud face.EnvironmentPicker.tsx: kept base'scloseOnTrustAskeffect.NewTabScreen.tsx: base's auth gate and command intercept come first inaskChat, then Cloud. Kept base'splusRefusednotice and folder strip.CloudStartChat.swift: the progressreport(...)sits before #28111'sstart.seed(cwd:), so the model still goes to the Cloud chat.Localizable.xcstrings: base's table plus this PR's 10 keys (no duplicates).
Design spec
leo-workspace design/composer.md and design/environment-picker.md (rule 3). #28620 (This Mac's name) is a separate change on the same picker; where both touch the same files, both are kept.
Screenshots
The before/after screenshots (light and dark) are in #26801, #26920 and #26921. The UI is unchanged from those heads apart from the conflict resolution above.
Reds
Compared by test name against base. The 21-language string tables (112 missing in ActionCatalog/CmuxHome) are red on base too. The rest are noted in comments.
Agent session: agent session
š¤ Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Makes Cloud a run location for new chats, behind Labs: the environment picker's Cloud row makes the first send a cloud.startChat that copies the chat's folder to a Cloud machine and opens the chat there, with no machine, size, or environment prompt.
Start safety
- A send is pinned to the machine and destination its first try took, so a retry reopens the same chat instead of duplicating it or overwriting its work.
- The host picks this person's free machine, never the team's or lane-pool VMs; a new one is created under the send's key.
- A first send that fails on a revoked OAuth token goes again once, 2 seconds later, on the chat's first turn only.
- While a start is out, neither the composer nor the New Tab box takes anything ā no typing, paste, file drop, or dictation ā so nothing mid-start is lost when the tab closes on success.
Folder and progress
- Only a folder inside the pane's roots is copied, each send into its own place under the work root; anything else is refused before the hold and gesture.
- With Do not work in a project picked, a Cloud send names no folder and is refused before the hold ("Cloud isn't available for this chat") with the prompt kept, so the host never copies a repo the person declined.
- A new chat's run location defaults to where its folder's newest chat ran ā a Cloud start's own copy counts in that history ā so a folder last run in Cloud opens new chats with Cloud picked until the folder undoes it.
- A Cloud start shows its progress under the message (step, folder, machine, secrets, network) as the host pushes each step, in small-radius chips.