Repository navigation
cmux-tui: start-chat plan answers the folder's repo; start-chat ensure gets the workspace machine - #30414
Conversation
…e gets the workspace's machine from the platform
The plan reads the chat folder's GitHub origin as repo and echoes the
cloud environment cloud.startChat chose. ensure posts
/v1/workspaces/{W}/machine under the plan's create_key with repo, ref and
environment, so the machine boots from the repository's set-up snapshot
once it is ready (cmuxterm-hq#5846, item 2).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3b729bb81a4ace643a60
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3b729bb81a4ace643a60
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Shipped in:
|
|
Review (subagent claude-opus-5-5 medium): SHIP at 87cad70 (Router-review refused: the review router already had 2 reviews running.) No finding is blocking. Checked: it compiles (visibility, Follow-ups (fixed forward in the Swift wiring PR):
|
…ing git Review follow-ups on #30414: an empty or relative folder answers no repo; no git process (no inherited GIT_* variables, no Command Line Tools prompt, nothing to time out); subfolders and worktrees find their repository; github.com in any case and with a user; a 404 with a generic not_found code reads as unavailable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3b729bb81a4ace643a60
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3b729bb81a4ace643a60
…and a generic 404 The previous commit's tests for these did not apply; add them and drop an unneeded super:: qualification. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3b729bb81a4ace643a60
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3b729bb81a4ace643a60
|
Found 15 test failures on Blacksmith runners: Failures
...and 5 more test failures. View all on Blacksmith: run 41285718699, run 41285718732
|
|
Review (subagent claude-opus-5-5 medium): SHIP at addc257 Supersedes the SHIP at 87cad70. That head failed to compile on CI ( Follow-ups: the legacy |
There was a problem hiding this comment.
3 issues found across 4 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="cmux-tui/crates/cmux-tui/src/link/start_chat_cli.rs">
<violation number="1" location="cmux-tui/crates/cmux-tui/src/link/start_chat_cli.rs:336">
P2: `github_repo` rejects valid GitHub remotes with explicit transport ports, such as `https://github.com:443/owner/repo` and `ssh://git@github.com:22/owner/repo`. Parse the authority and port separately, normalizing HTTPS `443` and ignoring SSH transport ports, so `plan` can identify the repository for zero-setup boot.
(Based on your team's feedback about GitHub remote port normalization.)</violation>
<violation number="2" location="cmux-tui/crates/cmux-tui/src/link/start_chat_cli.rs:361">
P2: `ensure` silently ignores unknown flags, so a misspelled `--environment` can create the machine in the default environment. Reject any flag not in the `ensure` vocabulary before sending the request.</violation>
<violation number="3" location="cmux-tui/crates/cmux-tui/src/link/start_chat_cli.rs:427">
P2: `percent_segment` leaves `.` unescaped, so workspace IDs `.` or `..` are normalized by URL parsing and can target a different platform route. Percent-encode dots (or reject dot-segment workspace IDs) before building the request path.</violation>
</file>
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
| Some(rest) => { | ||
| let (host, path) = rest.split_once('/')?; | ||
| let host = host.rsplit('@').next()?; | ||
| host.eq_ignore_ascii_case("github.com").then_some(path)? |
There was a problem hiding this comment.
P2: github_repo rejects valid GitHub remotes with explicit transport ports, such as https://github.com:443/owner/repo and ssh://git@github.com:22/owner/repo. Parse the authority and port separately, normalizing HTTPS 443 and ignoring SSH transport ports, so plan can identify the repository for zero-setup boot.
(Based on your team's feedback about GitHub remote port normalization.)
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At cmux-tui/crates/cmux-tui/src/link/start_chat_cli.rs, line 336:
<comment>`github_repo` rejects valid GitHub remotes with explicit transport ports, such as `https://github.com:443/owner/repo` and `ssh://git@github.com:22/owner/repo`. Parse the authority and port separately, normalizing HTTPS `443` and ignoring SSH transport ports, so `plan` can identify the repository for zero-setup boot.
(Based on your team's feedback about GitHub remote port normalization.) </comment>
<file context>
@@ -227,10 +246,227 @@ pub(super) fn plan(ledger: &Path, request: &str) -> Value {
+ Some(rest) => {
+ let (host, path) = rest.split_once('/')?;
+ let host = host.rsplit('@').next()?;
+ host.eq_ignore_ascii_case("github.com").then_some(path)?
+ }
+ None => {
</file context>
| } | ||
|
|
||
| impl Ensure { | ||
| fn of(flags: &Flags) -> Option<Self> { |
There was a problem hiding this comment.
P2: ensure silently ignores unknown flags, so a misspelled --environment can create the machine in the default environment. Reject any flag not in the ensure vocabulary before sending the request.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At cmux-tui/crates/cmux-tui/src/link/start_chat_cli.rs, line 361:
<comment>`ensure` silently ignores unknown flags, so a misspelled `--environment` can create the machine in the default environment. Reject any flag not in the `ensure` vocabulary before sending the request.</comment>
<file context>
@@ -227,10 +246,227 @@ pub(super) fn plan(ledger: &Path, request: &str) -> Value {
+}
+
+impl Ensure {
+ fn of(flags: &Flags) -> Option<Self> {
+ let optional = |name: &str| match flags.all(name).as_slice() {
+ [] => Some(None),
</file context>
| segment | ||
| .bytes() | ||
| .map(|byte| match byte { | ||
| b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'.' | b'_' | b'~' => { |
There was a problem hiding this comment.
P2: percent_segment leaves . unescaped, so workspace IDs . or .. are normalized by URL parsing and can target a different platform route. Percent-encode dots (or reject dot-segment workspace IDs) before building the request path.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At cmux-tui/crates/cmux-tui/src/link/start_chat_cli.rs, line 427:
<comment>`percent_segment` leaves `.` unescaped, so workspace IDs `.` or `..` are normalized by URL parsing and can target a different platform route. Percent-encode dots (or reject dot-segment workspace IDs) before building the request path.</comment>
<file context>
@@ -227,10 +246,227 @@ pub(super) fn plan(ledger: &Path, request: &str) -> Value {
+ segment
+ .bytes()
+ .map(|byte| match byte {
+ b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'.' | b'_' | b'~' => {
+ (byte as char).to_string()
+ }
</file context>
| b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'.' | b'_' | b'~' => { | |
| b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'~' => { |
|
This PR made the Rust panic ratchet red on feat-cmux-next: cmux-tui |
…ads use get The ratchet at the merge with feat-cmux-next e27f116 (18cef5a, job 9d666b02dcb4c69dbfc147f0) is still red: cmux-tui indexing_slicing 849 > 831. The 18 new hits after #30414 come from: - d8e1b7c (#29234) cli/terminal_talk/send.rs stage_failure: 2 - 9f5e2e1 (#30634) link/seed_cli.rs: 13, link/mod.rs `&args[1..]`: 1 - 7b30784 (#30664) link/machine_pin.rs: 1, link/mod.rs `&args[2..]`: 1 Each is now a get / pointer-free get read, `JsonSet::set` for the one write, and `args.get(n..)` for the slices (the branch runs only when `args.get(n - 1)` matched, so the slice is always there). A missing key read through get gives None where indexing gave Null: `as_str()` and `as_bool()` see the same, and json! writes None as null. No behavior change; the baseline is not raised.
…0414, #29234, #30634, #30664 and #30574 use checked forms (#30661) * base red: panic ratchet, #30414's new index and string slices in start_chat_cli use checked forms The Rust panic ratchet is red on feat-cmux-next at 7e0a0f2 (tip watcher job 21c6ba0ebda787821cc7bc4b): cmux-tui indexing_slicing 833 > 831 and string_slice 84 > 82. All four hits are from 0507fc4 (#30414) in cmux-tui/src/link/start_chat_cli.rs: - valid_environment: `id[4..]` -> `id.get(4..)`; the id already starts with the ASCII "env_", so the slice is always Some and the same. - github_repo: `&url[scheme.len()..]` -> `split_at_checked`, None in exactly the cases where the `get(..scheme.len())` before it was None. - Ensure::body: `body["ref"] = ..`, `body["environment"] = ..` -> `JsonSet::set` on the same object literal (same insert). No behavior change; the baseline is not raised. * base red: panic ratchet, #29234's, #30634's and #30664's new index reads use get The ratchet at the merge with feat-cmux-next e27f116 (18cef5a, job 9d666b02dcb4c69dbfc147f0) is still red: cmux-tui indexing_slicing 849 > 831. The 18 new hits after #30414 come from: - d8e1b7c (#29234) cli/terminal_talk/send.rs stage_failure: 2 - 9f5e2e1 (#30634) link/seed_cli.rs: 13, link/mod.rs `&args[1..]`: 1 - 7b30784 (#30664) link/machine_pin.rs: 1, link/mod.rs `&args[2..]`: 1 Each is now a get / pointer-free get read, `JsonSet::set` for the one write, and `args.get(n..)` for the slices (the branch runs only when `args.get(n - 1)` matched, so the slice is always there). A missing key read through get gives None where indexing gave Null: `as_str()` and `as_bool()` see the same, and json! writes None as null. No behavior change; the baseline is not raised. * base red: panic ratchet, #30574's new index reads in start_chat_cli use get #30574 (93772c4) landed after the e27f116 merge and added four Value index reads in start-chat plan (line["machine"], ["created"], ["snapshot"], ["environment"]). They are now get reads: a missing key is None where indexing gave Null, as_str() sees the same and json! writes None as null. No behavior change.
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Summary
Client half of zero-setup hot start (cmuxterm-hq#5846, item 2): the first Cloud send of a chat gets a workspace machine that boots from the repository's set-up snapshot once it is ready.
cmux link start-chat planreads the chat folder's GitHuboriginremote (a new optionallocalfield in the request) and answersrepo(owner/name, or null). It also echoesenvironment, the cloud environmentcloud.startChatchose (an optionalenv_...that the environment sheet sets, Cloud: edit environment setup from the chat #30359).cmux link start-chat ensure --workspace W --key K --repo OWNER/NAME [--ref R] [--environment env_...] [--platform URL], with the cmux credential on stdin. It sendsPOST /v1/workspaces/{W}/machineto the cmux platform, with the plan'screate_keyasclientKey(a retry gets the same machine), plusrepo,refandenvironment. It prints one JSON line:{"ok":true,"machine","team","created","snapshot","environment":{"id","status"}}, or the platform's error code (for examplecloud_environment.not_found).cli/machine_join.rsshares its platform client (Platform,platform_origin,CallError) with the link module, gains apostcall, and lists the workspace-machine error codes as known codes.The App still makes machines via
cloud.createMachine. A follow-up wiresCloudStartChat+Machine.swiftto callensurewhen the plan has arepo. That needsCloudMoveCLIto pass the token on stdin, asAddDeviceServicesdoes.Testing
link/start_chat_cli/tests.rs: parsing GitHub remote URLs,planagainst a real git folder (no origin → null, then an scp-style origin), theensureflags and body, and how platform answers and errors map to its line.cmux-ci test -- cargo test -p cmux-tui start_chat(result in a comment below).Observed / Not run
Changelog
none
🤖 Generated with Claude Code
Agent session: agent session