cloud CLI: machine access exec takes the machine exec route when a provider has no client sessions
Leo, 2026-11-04: "and moving off swift into rust for next's cloud" / "you guys should be willing to remove code rewrite do large scale refactors".
Step M11 of cmuxterm-hq plans/cloud/ARCHITECTURE-2026-11.md: the CLI's Cloud verbs, so that the CLI journey (cloud-journey.ts --cmux, #35103) runs on the CLI's own code.
cmux machine access exec mints a provider client session, and a VM API machine has none: its mint answers 501 cloud.provider.unsupported. #35642 and #35716 handled that inside the journey, by spotting the CLI's error and running the command through the journey's own HTTP code. This PR moves the fallback into the CLI and deletes the journey's copy:
cmux machine access exec: when the mint answerscloud.provider.unsupported, the command runs through the cmux API's machine exec route (POST /v1/cloud/machines/{machine}/exec, cmux-platformMachineGuest.ts, as the work user). It sends the same bearer and team headers and prints the same--jsonand human output as a direct exec. The credential is redacted from the output, and a refusal prints only a code from the command's known table.access newstill fails on such a machine, because a session is what it makes.cloud-journey.ts:cliExecNeedsDirectFallback,cliExecWithFallback(used only by its own test) andcliExec's fallback state are removed, along with their tests. With--cmux, every exec is now the CLI's. The journey without--cmuxkeeps its direct client-session/exec-route path.
The exec route is not in cmux-platform's spec yet (manaflow-ai/cmux-platform#825). Until it is, the call goes through the existing reqwest client, not cmux-cloud-client.
Checks (fleet, cmux-ci test)
cargo test -p cmux-tui --bin cmux-tui cloud_client_session: the existing tests and 3 new ones (exec_on_a_machine_without_client_sessions_runs_through_the_machine_exec_route,a_refused_machine_exec_route_prints_only_a_known_code,create_on_a_machine_without_client_sessions_still_fails).bun test scripts/cmux-next/cloud-journey.test.ts.
Agent session: agent session
🤖 Generated with Claude Code
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
cmux machine access exec now runs through the cmux API's machine exec route when the provider has no client sessions, instead of failing with an unsupported error. The journey's fallback logic is removed, so every exec under --cmux goes through the CLI.
- Exec on a VM API machine uses
POST /v1/cloud/machines/{machine}/execas the work user, with the same headers, output modes, and exit codes as a direct exec; credentials are redacted from output. - Only the machine's creator reaches this route: the platform refuses a teammate's mint with
auth.forbiddenbefore asking the provider, and a test pins that anot_creatormint never sends an exec request. - The route's own refusal codes (
vm_not_found,vm_forbidden,vm_not_running,vm_unavailable,vm_busy,vm_output_too_large) are printable known codes, andaccess newstill fails on such machines. - The journey passes the exec line through unchanged instead of wrapping it in
sh -c. cloud-journey.tsdropscliExecNeedsDirectFallback,cliExecWithFallback, and their tests; the journey without--cmuxkeeps its existing client-session path.- The exec route call goes through the existing reqwest client because it is not yet in cmux-platform's spec.