Skip to content

Cloud start: the clone row shows the seed's live progress - #30655

Merged
teamleaderleo merged 10 commits into
feat-cmux-nextfrom
seed-start-copy
Nov 1, 2026
Merged

teamleaderleo merged 10 commits into
feat-cmux-nextfrom
seed-start-copy

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

Piece 4 of the Cloud project seed (leo-workspace design/cloud.md, "Getting the project onto the machine"), the clone row's live progress. Leo, on the start screen's line:

Your project folder is copied up.
we'll want to deal with the edge cases for this too

#30634 added cmux link seed push, #30812 made Cloud start and move use it, and #30517 gave the startup checklist its clone row with seed timing. This PR feeds the seed's own progress lines into that row while the copy runs. It is rebuilt on feat-cmux-next at #30517's merge. The seed_* clone timing and the failed answer forwarded before the guard are unchanged.

What the row shows

The page owns the words (CloudStartView.tsx, new cloudStartup.* keys in every locale; non-English copies marked needs_review):

  • upload: "Sending your changes (12 MB)";
  • the machine's job: "Cloning from GitHub · 41%", "Fetching from GitHub", "Applying your changes", "Checking out files", "Getting submodules", "Getting large files";
  • a copy: "Copying the folder instead · 1,204 of 8,310 files · 312 MB of 2.1 GB" (sizes and counts in the pane's language);
  • a finished copy shows only the check mark, plus "Copying the folder instead" if a seed fell back;
  • seed.needs_github: an "Install the cmux GitHub App to clone it next time" link under the row (https only). The real card is Cloud start: a real card for installing the cmux GitHub App when a seed needs it #30637.

The shared model (cloudStartProgress.ts):

  • clone.progress gains bytesTotal, filesDone and filesTotal;
  • clone gains fallback and installUrl;
  • the final answer keeps the live lines' fallback.

Swift stays thin, and CmuxNextApp does not grow

check-app-size --base: 117608 source lines before and after.

  • CmuxNextDaemon/Launch/StderrLines.swift: ProcessRunner.run(stderrLine:) hands the child's stderr over line by line. The child already writes to an unlinked temp file, not a pipe. A DispatchSource vnode watch on a dup'd descriptor reads appended bytes with pread.
    • Stop condition: at child exit the runner calls finish(). It drains to EOF on the reader's queue, delivers the last partial line, then cancels the source.
    • Cleanup: defer { cancel() } covers every throw or timeout, and the cancel handler closes the dup'd descriptor.
    • Lines are capped at 64 KiB. No timer, no polling.
  • CmuxNextCloud/Move/SeedProgress.swift:
    • parses {"progress":{...}} lines;
    • throttles them to one per 250 ms, with a phase change always going through;
    • carries a fallback's code and link onto the copy's lines;
    • feed runs the copy and forwards each value on the main actor through a newest-only stream, which ends when the copy returns or throws.
  • CmuxNextAgentPane: Step.cloneProgress and AgentPaneCloudStart.fields map a progress value to the page's clone fields.
  • CmuxNextApp: CloudStartChat wraps its existing copy in SeedProgress.feed, and CloudMoveCLI.startChatCopy passes stderrLine through. There is no as!.

The CSS is unchanged: the link reuses the row's detail and link classes, so there are no new design-token rows.

Tests

  • Web (cmux-ci test):
    • CloudStartView.test.tsx: the row's words for upload, clone, checkout, copy and complete, and the install link;
    • cloudStartProgress.test.ts: the new fields, the fallback kept into the final answer, a non-https link dropped;
    • check:design-tokens, check:catalog-keys, format, typecheck.
  • Swift: SeedProgressTests (parse, throttle, feed, field names) and cmux-ci compile-check --app --package CmuxNext.

Risk: this adds progress to a step that already runs. If no progress line arrives, the row shows #30517's state and timing as before.

Follow-ups: #30637 (the install card), #30741 (setup hint and status not wired), #30799 (resolved here: "complete" no longer shows raw).

Agent session: agent session

🤖 Generated with Claude Code

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

@github-actions github-actions Bot added the risk:high Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 4c24230: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr30655 -f ref=seed-start-copy -f platform=macos -f backend_mode=local

Gallery before/after for 4c24230: 16 states rendered, 14 images differ, 1165 more touched states not rendered. Images are in the run's artifact, not on this public PR; the independent review of this head reads them on its own, so the PR needs no hand-made screenshots of these states.

gh run download 41337551519 -R manaflow-ai/cmux -n gallery-advisory-30655-4c242306d353f3d56810bbb250e91050f3eafb2a (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.cloud-start/sent Apple System Colors changed 0.0083% own CloudStartView.tsx
agent-pane.cloud-start/sent Apple System Colors Light changed 0.0069% own CloudStartView.tsx
agent-pane.cloud-start/machine Apple System Colors Light changed 0.0054% own CloudStartView.tsx
agent-pane.cloud-start/machine Apple System Colors changed 0.0048% own CloudStartView.tsx
agent-pane.cloud-start/copying Apple System Colors changed 0.0052% own CloudStartView.tsx
agent-pane.cloud-start/copying Apple System Colors Light unchanged 0% own CloudStartView.tsx
agent-pane.cloud-start/opening Apple System Colors Light changed 0.0087% own CloudStartView.tsx
agent-pane.cloud-start/opening Apple System Colors changed 0.0029% own CloudStartView.tsx
agent-pane.cloud-start/failed Apple System Colors Light unchanged 0% own CloudStartView.tsx
agent-pane.cloud-start/failed Apple System Colors unchanged 0% own CloudStartView.tsx
agent-pane.cloud-start/checklist-machine Apple System Colors Light changed 0.0156% own CloudStartView.tsx
agent-pane.cloud-start/checklist-machine Apple System Colors changed 0.0117% own CloudStartView.tsx
agent-pane.cloud-start/checklist-clone Apple System Colors Light changed 0.0173% own CloudStartView.tsx
agent-pane.cloud-start/checklist-clone Apple System Colors changed 0.0148% own CloudStartView.tsx
agent-pane.cloud-start/checklist-setup-cached Apple System Colors Light changed 0.0171% own CloudStartView.tsx
agent-pane.cloud-start/checklist-setup-cached Apple System Colors changed 0.0154% own CloudStartView.tsx
agent-pane.url-chip/globe Apple System Colors Light unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/globe Apple System Colors unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/cached-favicon Apple System Colors Light unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/cached-favicon Apple System Colors unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/token-url Apple System Colors Light unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/token-url Apple System Colors unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/pull-request-polished Apple System Colors Light unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/pull-request-polished Apple System Colors unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/pull-request-polished-draft Apple System Colors Light unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/pull-request-polished-draft Apple System Colors unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/pull-request-polished-merged Apple System Colors Light unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/pull-request-polished-merged Apple System Colors unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/pull-request-polished-long-title Apple System Colors changed 0% names Localizable.xcstrings
agent-pane.url-chip/pull-request-polished-long-title Apple System Colors Light unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/pull-request-theme-colors Apple System Colors Light unchanged 0% names Localizable.xcstrings
agent-pane.url-chip/pull-request-theme-colors Apple System Colors unchanged 0% names Localizable.xcstrings

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

Passes: CI passes on 4c242306d3.

CI passes on 4c242306d3 (run 41337551540 attempt 1).

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

web and size checks: green

Default changes

This pull request changes 2 defaults at 4c242306d353 (what everyone gets without configuring anything):

  • tunable-source.CmuxNextAgentPane/AgentPaneCloudStart.swift:fields: (none) -> "b8cbf50a4b52bba4d3bc8ec3ee6c1e374ae1533a6e883c0b139a1097fe2c31f5"
  • tunable-source.CmuxNextDaemon/Launch/ProcessRunner.swift:run: "fd85888a316628139f184932acf01b821cdd687b99689d82f35a7f105427ea8b" -> "65f9d3d78c73f57e38003693e929d4a03280f2a8369015c2a2d20cffe082aea8"

Signed off on this commit by review (codex, router-review).

Merge receipt: merged as 1e336360af7f with these defaults changed, signed off by review (codex, router-review).

Regenerate the snapshot with python3 scripts/ci/defaults_guard.py snapshot.

Shipped in:

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

23 issues found across 31 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="webviews/src/agent-session/acpmux/CloudStartView.gallery.tsx">

<violation number="1" location="webviews/src/agent-session/acpmux/CloudStartView.gallery.tsx:69">
P2: `startedAt: 10_000` is 10 seconds after the epoch, so the running machine step shows an elapsed time of about 56 years, and it changes every second. Use a start time near the current clock, such as `Date.now() - 2_400`, so the fixture shows a short, realistic duration.</violation>

<violation number="2" location="webviews/src/agent-session/acpmux/CloudStartView.gallery.tsx:81">
P2: `startedAt: 10_000` on the running setup step gives an elapsed time of about 56 years that ticks every second. Use a recent start time instead, such as `Date.now() - 2_400`.</violation>
</file>

<file name="webviews/src/agent-session/acpmux/Localizable.xcstrings">

<violation number="1" location="webviews/src/agent-session/acpmux/Localizable.xcstrings:246068">
P2: The new `cloudStartup.*` entries are English text copied into every locale, not translations. Non-English users will see English in the clone row until these are translated. Either supply real translations or drop the non-English entries so the fallback is explicit.</violation>
</file>

<file name="webviews/src/agent-session/acpmux/cloudStart.css">

<violation number="1" location="webviews/src/agent-session/acpmux/cloudStart.css:40">
P2: This `.acpmux-cloud-start__mark` rule conflicts with the existing rule further down the file, which sets `width: 14px`. The later rule wins, so the `width: 18px` here is dead and the mark renders 14×20. Merge the two into one rule and keep a single width value.</violation>
</file>

<file name="cmux-tui/crates/cmux-tui/src/link/mod.rs">

<violation number="1" location="cmux-tui/crates/cmux-tui/src/link/mod.rs:123">
P3: The help for `cmux link seed` still lists only `seed plan`, because `seed --help` and bare `seed` route to `seed::run`. Route help through the new subcommand too, or list `push` and `clone` in the seed usage, so `seed push --help` is not an error exit.</violation>
</file>

<file name="cmux-tui/crates/cmux-tui-core/src/git_seed.rs">

<violation number="1" location="cmux-tui/crates/cmux-tui-core/src/git_seed.rs:54">
P3: A relative `CMUX_TEST_GIT_SEED_GITHUB` is ignored without any signal, so the daemon silently clones from real github.com. Fail loudly on a non-absolute value instead of filtering it out.</violation>
</file>

<file name="webviews/src/agent-session/acpmux/cloudStartProgress.ts">

<violation number="1" location="webviews/src/agent-session/acpmux/cloudStartProgress.ts:268">
P2: `logLine` keeps the start of `logTail` and drops its end. The newest setup output is the part worth showing, so truncate from the front and keep the last characters instead.</violation>
</file>

<file name="cmux-tui/crates/cmux-tui/src/link/sync_cli.rs">

<violation number="1" location="cmux-tui/crates/cmux-tui/src/link/sync_cli.rs:326">
P3: `upload` opens the bundle with only `O_NOFOLLOW`, so a FIFO swapped in at that path would block the open indefinitely. The existing `open` helper in this file adds `O_NONBLOCK` for this reason. Add the flag here to match it.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Sources/CmuxNextApp/Cloud/CloudMoveCLI.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextApp/Cloud/CloudMoveCLI.swift:212">
P2: These top-level reads (`received_bytes`, `objects`, `total_objects`, `environment_*`, `machine_*`, `harness_*`) match nothing `start-chat copy` prints. The copy answer carries only `seed_*` timing plus the forwarded push fields. The byte counts arrive on stderr progress instead. Drop the unemitted reads, or document where they come from, and correct the comment, which says only namespaced fields describe cloning.</violation>

<violation number="2" location="Packages/macOS/CmuxNext/Sources/CmuxNextApp/Cloud/CloudMoveCLI.swift:224">
P2: This parses `skipped_files` but never forwards it through the clone-row `Step`, so files left behind are silently omitted. Carry the list through the progress payload.</violation>
</file>

<file name="cmux-tui/crates/cmux-tui/src/link/seed_cli/record.rs">

<violation number="1" location="cmux-tui/crates/cmux-tui/src/link/seed_cli/record.rs:72">
P3: The new record persistence has no tests. A round-trip test for `save`/`load`, the 0600 mode, and the corrupt-record error would guard the `--since-last` gate.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Sources/CmuxNextAgentPane/AgentPaneCloudStart.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextAgentPane/AgentPaneCloudStart.swift:208">
P3: The `progress` signature now repeats every field of `AgentPaneCloudStart.Step` as a separate parameter. Pass a `Step` value instead, which removes the field-by-field forwarding in `progress(_ step: Step, to:)`.</violation>

<violation number="2" location="Packages/macOS/CmuxNext/Sources/CmuxNextAgentPane/AgentPaneCloudStart.swift:247">
P2: Stamping `initialized: true` on the `opening` step marks the harness and setup rows done before the harness has started. The web model defines `initialized` as true only after the harness starts. Send `initialized` only from the host's harness-started signal, not from the step name.</violation>
</file>

<file name="cmux-tui/crates/cmux-tui/tests/link_seed.rs">

<violation number="1" location="cmux-tui/crates/cmux-tui/tests/link_seed.rs:105">
P3: This test spawns the CLI without pinning `HOME` or `CFFIXED_USER_HOME` to a per-test temporary directory, unlike the sibling CLI tests. Set both on the child so it cannot touch the real home directory.

(Based on your team's feedback about isolating CLI test homes.)</violation>

<violation number="2" location="cmux-tui/crates/cmux-tui/tests/link_seed.rs:201">
P3: `files()` swallows read errors with `unwrap_or_default()`, so unreadable or binary files compare as equal empty strings. Use `.unwrap()` so the content comparison fails loudly.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Sources/CmuxNextApp/Cloud/CloudStartChat.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextApp/Cloud/CloudStartChat.swift:123">
P2: The progress steps omit `cloneStartedAt`, so each push replaces the clone row's `startedAt` with nothing and its duration disappears while the copy runs. Carry the seed's start time into these steps, or merge it on the page side.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Sources/CmuxNextApp/Cloud/SeedProgress.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextApp/Cloud/SeedProgress.swift:48">
P2: The throttle drops the final progress line when it arrives within 250 ms of the previous one, and nothing re-emits it. The CLI marks the last copy and upload lines as must-send, so the clone row can stay on a stale count. Let the reader pass end-of-work lines (files or bytes done equal to total) through the throttle.</violation>
</file>

<file name="webviews/src/agent-session/acpmux/CloudStartView.tsx">

<violation number="1" location="webviews/src/agent-session/acpmux/CloudStartView.tsx:136">
P3: This hardcoded English `aria-label` is not localized, and a plain div with no role ignores it. Remove the attribute, or give the container a role and a localized label.</violation>

<violation number="2" location="webviews/src/agent-session/acpmux/CloudStartView.tsx:136">
P2: The setup hint is plain text in both production mounts because neither passes `onOpenEnvironment`, so users cannot open the environment editor. Render an actionable control and wire it to a callback or a registered event listener.</violation>

<violation number="3" location="webviews/src/agent-session/acpmux/CloudStartView.tsx:139">
P3: The `rows` experiment arm now renders the same chips as the default arm, so its description no longer matches what it shows. Either restore the fact-row rendering for that arm or retire the arm and its CSS.</violation>

<violation number="4" location="webviews/src/agent-session/acpmux/CloudStartView.tsx:140">
P2: The `steps` arm visibly adds an unstyled numbered list of raw `machine`, `folder`, and `opening` labels beneath the new checklist; `aria-hidden` does not hide it visually. Remove this legacy list or hide it visually.</violation>
</file>

<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:156">
P3: A backward system-clock adjustment during a copy can make `seed_finished_at` earlier than `seed_started_at`, producing invalid clone timing and violating the new ordering assertion. Capture an `Instant` at the start and derive the finish timestamp from its monotonic elapsed duration.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Sources/CmuxNextAgentPane/AgentPaneCloudStart+Cloud.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextAgentPane/AgentPaneCloudStart+Cloud.swift:34">
P3: The public `Step` initializer omits the five newly added progress fields, forcing callers to construct the value and mutate it afterward. Add these fields to the initializer and assign them there.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

},
"checklist-setup-running": {
note: "The derived environment is still building its setup snapshot.",
props: { start: { ...begun, hasRepository: true, repository: "manaflow-ai/cmux", clone: { state: "done", ...timing }, setup: { state: "running", status: "building", startedAt: 10_000 } } },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: startedAt: 10_000 on the running setup step gives an elapsed time of about 56 years that ticks every second. Use a recent start time instead, such as Date.now() - 2_400.

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 webviews/src/agent-session/acpmux/CloudStartView.gallery.tsx, line 81:

<comment>`startedAt: 10_000` on the running setup step gives an elapsed time of about 56 years that ticks every second. Use a recent start time instead, such as `Date.now() - 2_400`.</comment>

<file context>
@@ -63,6 +64,34 @@ export default componentEntry<ComponentProps<typeof CloudStartView>>({
+    },
+    "checklist-setup-running": {
+      note: "The derived environment is still building its setup snapshot.",
+      props: { start: { ...begun, hasRepository: true, repository: "manaflow-ai/cmux", clone: { state: "done", ...timing }, setup: { state: "running", status: "building", startedAt: 10_000 } } },
+    },
+    "checklist-setup-failed": {
</file context>
Suggested change
props: { start: { ...begun, hasRepository: true, repository: "manaflow-ai/cmux", clone: { state: "done", ...timing }, setup: { state: "running", status: "building", startedAt: 10_000 } } },
props: { start: { ...begun, hasRepository: true, repository: "manaflow-ai/cmux", clone: { state: "done", ...timing }, setup: { state: "running", status: "building", startedAt: Date.now() - 2_400 } } },

},
"checklist-machine": {
note: "Cloud machine is being created; the machine step spins while later steps remain quiet.",
props: { start: { ...begun, machineStartedAt: 10_000, machine: known.machine } },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: startedAt: 10_000 is 10 seconds after the epoch, so the running machine step shows an elapsed time of about 56 years, and it changes every second. Use a start time near the current clock, such as Date.now() - 2_400, so the fixture shows a short, realistic duration.

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 webviews/src/agent-session/acpmux/CloudStartView.gallery.tsx, line 69:

<comment>`startedAt: 10_000` is 10 seconds after the epoch, so the running machine step shows an elapsed time of about 56 years, and it changes every second. Use a start time near the current clock, such as `Date.now() - 2_400`, so the fixture shows a short, realistic duration.</comment>

<file context>
@@ -63,6 +64,34 @@ export default componentEntry<ComponentProps<typeof CloudStartView>>({
     },
+    "checklist-machine": {
+      note: "Cloud machine is being created; the machine step spins while later steps remain quiet.",
+      props: { start: { ...begun, machineStartedAt: 10_000, machine: known.machine } },
+    },
+    "checklist-clone": {
</file context>
Suggested change
props: { start: { ...begun, machineStartedAt: 10_000, machine: known.machine } },
props: { start: { ...begun, machineStartedAt: Date.now() - 2_400, machine: known.machine } },

@@ -246064,7 +246064,31 @@
"tools.cmux.closedTabs": {"comment":"Agent pane: a cmux_exec script's (or a cmux MCP tool's) transcript row title, after it closed {n} tabs","extractionState":"manual","localizations":{"ar":{"variations":{"plural":{"zero":{"stringUnit":{"state":"needs_review","value":"تم إغلاق علامات تبويب: {n}"}},"one":{"stringUnit":{"state":"needs_review","value":"تم إغلاق علامات تبويب: {n}"}},"two":{"stringUnit":{"state":"needs_review","value":"تم إغلاق علامات تبويب: {n}"}},"few":{"stringUnit":{"state":"needs_review","value":"تم إغلاق علامات تبويب: {n}"}},"many":{"stringUnit":{"state":"needs_review","value":"تم إغلاق علامات تبويب: {n}"}},"other":{"stringUnit":{"state":"needs_review","value":"تم إغلاق علامات تبويب: {n}"}}}}},"bs":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Zatvorena {n} kartica"}},"few":{"stringUnit":{"state":"needs_review","value":"Zatvorene {n} kartice"}},"other":{"stringUnit":{"state":"needs_review","value":"Zatvoreno {n} kartica"}}}}},"da":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Lukkede {n} fane"}},"other":{"stringUnit":{"state":"needs_review","value":"Lukkede {n} faner"}}}}},"de":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{n} Tab geschlossen"}},"other":{"stringUnit":{"state":"needs_review","value":"{n} Tabs geschlossen"}}}}},"en":{"variations":{"plural":{"one":{"stringUnit":{"state":"translated","value":"Closed {n} tab"}},"other":{"stringUnit":{"state":"translated","value":"Closed {n} tabs"}}}}},"es":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Se cerró {n} pestaña"}},"many":{"stringUnit":{"state":"needs_review","value":"Se cerraron {n} pestañas"}},"other":{"stringUnit":{"state":"needs_review","value":"Se cerraron {n} pestañas"}}}}},"fr":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{n} onglet fermé"}},"many":{"stringUnit":{"state":"needs_review","value":"{n} onglets fermés"}},"other":{"stringUnit":{"state":"needs_review","value":"{n} onglets fermés"}}}}},"it":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Chiusa {n} scheda"}},"many":{"stringUnit":{"state":"needs_review","value":"Chiuse {n} schede"}},"other":{"stringUnit":{"state":"needs_review","value":"Chiuse {n} schede"}}}}},"ja":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"{n} 個のタブを閉じました"}}}}},"km":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"បានបិទផ្ទាំងរង {n}"}}}}},"ko":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"탭 {n}개 닫음"}}}}},"nb":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Lukket {n} fane"}},"other":{"stringUnit":{"state":"needs_review","value":"Lukket {n} faner"}}}}},"pl":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Zamknięto {n} kartę"}},"few":{"stringUnit":{"state":"needs_review","value":"Zamknięto {n} karty"}},"many":{"stringUnit":{"state":"needs_review","value":"Zamknięto {n} kart"}},"other":{"stringUnit":{"state":"needs_review","value":"Zamknięto {n} karty"}}}}},"pt-BR":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{n} aba fechada"}},"many":{"stringUnit":{"state":"needs_review","value":"{n} abas fechadas"}},"other":{"stringUnit":{"state":"needs_review","value":"{n} abas fechadas"}}}}},"ru":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Закрыта {n} вкладка"}},"few":{"stringUnit":{"state":"needs_review","value":"Закрыто {n} вкладки"}},"many":{"stringUnit":{"state":"needs_review","value":"Закрыто {n} вкладок"}},"other":{"stringUnit":{"state":"needs_review","value":"Закрыто {n} вкладки"}}}}},"th":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"ปิดแท็บ {n} แท็บแล้ว"}}}}},"tr":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{n} sekme kapatıldı"}},"other":{"stringUnit":{"state":"needs_review","value":"{n} sekme kapatıldı"}}}}},"uk":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Закрито {n} вкладку"}},"few":{"stringUnit":{"state":"needs_review","value":"Закрито {n} вкладки"}},"many":{"stringUnit":{"state":"needs_review","value":"Закрито {n} вкладок"}},"other":{"stringUnit":{"state":"needs_review","value":"Закрито {n} вкладки"}}}}},"vi":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"Đã đóng {n} tab"}}}}},"zh-Hans":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"已关闭 {n} 个标签页"}}}}},"zh-Hant":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"已關閉 {n} 個分頁"}}}}}}},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The new cloudStartup.* entries are English text copied into every locale, not translations. Non-English users will see English in the clone row until these are translated. Either supply real translations or drop the non-English entries so the fallback is explicit.

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 webviews/src/agent-session/acpmux/Localizable.xcstrings, line 246068:

<comment>The new `cloudStartup.*` entries are English text copied into every locale, not translations. Non-English users will see English in the clone row until these are translated. Either supply real translations or drop the non-English entries so the fallback is explicit.</comment>

<file context>
@@ -246064,7 +246064,31 @@
     "tools.cmux.andMore": {"comment":"Agent pane: a cmux_exec script's (or a cmux MCP tool's) transcript row title, a script's main step and how many other steps of its kind it took; {action} is the main step's title","extractionState":"manual","localizations":{"ar":{"variations":{"plural":{"zero":{"stringUnit":{"state":"needs_review","value":"{action} و{n} خطوات أخرى"}},"one":{"stringUnit":{"state":"needs_review","value":"{action} و{n} خطوات أخرى"}},"two":{"stringUnit":{"state":"needs_review","value":"{action} و{n} خطوات أخرى"}},"few":{"stringUnit":{"state":"needs_review","value":"{action} و{n} خطوات أخرى"}},"many":{"stringUnit":{"state":"needs_review","value":"{action} و{n} خطوات أخرى"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} و{n} خطوات أخرى"}}}}},"bs":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{action} i još {n} korak"}},"few":{"stringUnit":{"state":"needs_review","value":"{action} i još {n} koraka"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} i još {n} koraka"}}}}},"da":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{action} og {n} trin mere"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} og {n} trin mere"}}}}},"de":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{action} und {n} weiterer Schritt"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} und {n} weitere Schritte"}}}}},"en":{"variations":{"plural":{"one":{"stringUnit":{"state":"translated","value":"{action} and {n} more step"}},"other":{"stringUnit":{"state":"translated","value":"{action} and {n} more steps"}}}}},"es":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{action} y {n} paso más"}},"many":{"stringUnit":{"state":"needs_review","value":"{action} y {n} pasos más"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} y {n} pasos más"}}}}},"fr":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{action} et {n} autre étape"}},"many":{"stringUnit":{"state":"needs_review","value":"{action} et {n} autres étapes"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} et {n} autres étapes"}}}}},"it":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{action} e {n} altro passaggio"}},"many":{"stringUnit":{"state":"needs_review","value":"{action} e altri {n} passaggi"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} e altri {n} passaggi"}}}}},"ja":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"{action}、ほか {n} 件のステップ"}}}}},"km":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"{action} និងជំហាន {n} ទៀត"}}}}},"ko":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"{action} 외 {n}단계"}}}}},"nb":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{action} og {n} trinn til"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} og {n} trinn til"}}}}},"pl":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{action} i {n} inny krok"}},"few":{"stringUnit":{"state":"needs_review","value":"{action} i {n} inne kroki"}},"many":{"stringUnit":{"state":"needs_review","value":"{action} i {n} innych kroków"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} i {n} innego kroku"}}}}},"pt-BR":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{action} e mais {n} etapa"}},"many":{"stringUnit":{"state":"needs_review","value":"{action} e mais {n} etapas"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} e mais {n} etapas"}}}}},"ru":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{action} и ещё {n} шаг"}},"few":{"stringUnit":{"state":"needs_review","value":"{action} и ещё {n} шага"}},"many":{"stringUnit":{"state":"needs_review","value":"{action} и ещё {n} шагов"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} и ещё {n} шага"}}}}},"th":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"{action} และอีก {n} ขั้นตอน"}}}}},"tr":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{action} ve {n} adım daha"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} ve {n} adım daha"}}}}},"uk":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"{action} і ще {n} крок"}},"few":{"stringUnit":{"state":"needs_review","value":"{action} і ще {n} кроки"}},"many":{"stringUnit":{"state":"needs_review","value":"{action} і ще {n} кроків"}},"other":{"stringUnit":{"state":"needs_review","value":"{action} і ще {n} кроку"}}}}},"vi":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"{action} và {n} bước khác"}}}}},"zh-Hans":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"{action},另有 {n} 个步骤"}}}}},"zh-Hant":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"{action},另有 {n} 個步驟"}}}}}}},
-    "tools.cmux.script": {"comment":"Agent pane: a cmux_exec script's (or a cmux MCP tool's) transcript row title, a finished script that called tools the row has no words for; {n} is how many calls it made, {first} the first tool's name","extractionState":"manual","localizations":{"ar":{"variations":{"plural":{"zero":{"stringUnit":{"state":"needs_review","value":"تم تشغيل نص cmux ({n} استدعاء): {first}"}},"one":{"stringUnit":{"state":"needs_review","value":"تم تشغيل نص cmux ({n} استدعاء): {first}"}},"two":{"stringUnit":{"state":"needs_review","value":"تم تشغيل نص cmux ({n} استدعاء): {first}"}},"few":{"stringUnit":{"state":"needs_review","value":"تم تشغيل نص cmux ({n} استدعاء): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"تم تشغيل نص cmux ({n} استدعاء): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"تم تشغيل نص cmux ({n} استدعاء): {first}"}}}}},"bs":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Pokrenuta cmux skripta ({n} poziv): {first}"}},"few":{"stringUnit":{"state":"needs_review","value":"Pokrenuta cmux skripta ({n} poziva): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Pokrenuta cmux skripta ({n} poziva): {first}"}}}}},"da":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Kørte cmux-script ({n} kald): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Kørte cmux-script ({n} kald): {first}"}}}}},"de":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"cmux-Skript ausgeführt ({n} Aufruf): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"cmux-Skript ausgeführt ({n} Aufrufe): {first}"}}}}},"en":{"variations":{"plural":{"one":{"stringUnit":{"state":"translated","value":"Ran cmux script ({n} call): {first}"}},"other":{"stringUnit":{"state":"translated","value":"Ran cmux script ({n} calls): {first}"}}}}},"es":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Se ejecutó un script de cmux ({n} llamada): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Se ejecutó un script de cmux ({n} llamadas): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Se ejecutó un script de cmux ({n} llamadas): {first}"}}}}},"fr":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Script cmux exécuté ({n} appel) : {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Script cmux exécuté ({n} appels) : {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Script cmux exécuté ({n} appels) : {first}"}}}}},"it":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Eseguito script cmux ({n} chiamata): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Eseguito script cmux ({n} chiamate): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Eseguito script cmux ({n} chiamate): {first}"}}}}},"ja":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"cmux スクリプトを実行しました ({n} 件の呼び出し): {first}"}}}}},"km":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"បានដំណើរការស្គ្រីប cmux ({n} ការហៅ)៖ {first}"}}}}},"ko":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"cmux 스크립트 실행함 (호출 {n}개): {first}"}}}}},"nb":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Kjørte cmux-skript ({n} kall): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Kjørte cmux-skript ({n} kall): {first}"}}}}},"pl":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Uruchomiono skrypt cmux ({n} wywołanie): {first}"}},"few":{"stringUnit":{"state":"needs_review","value":"Uruchomiono skrypt cmux ({n} wywołania): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Uruchomiono skrypt cmux ({n} wywołań): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Uruchomiono skrypt cmux ({n} wywołania): {first}"}}}}},"pt-BR":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Script do cmux executado ({n} chamada): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Script do cmux executado ({n} chamadas): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Script do cmux executado ({n} chamadas): {first}"}}}}},"ru":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Выполнен скрипт cmux ({n} вызов): {first}"}},"few":{"stringUnit":{"state":"needs_review","value":"Выполнен скрипт cmux ({n} вызова): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Выполнен скрипт cmux ({n} вызовов): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Выполнен скрипт cmux ({n} вызова): {first}"}}}}},"th":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"เรียกใช้สคริปต์ cmux แล้ว ({n} การเรียก): {first}"}}}}},"tr":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"cmux betiği çalıştırıldı ({n} çağrı): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"cmux betiği çalıştırıldı ({n} çağrı): {first}"}}}}},"uk":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Виконано скрипт cmux ({n} виклик): {first}"}},"few":{"stringUnit":{"state":"needs_review","value":"Виконано скрипт cmux ({n} виклики): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Виконано скрипт cmux ({n} викликів): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Виконано скрипт cmux ({n} виклику): {first}"}}}}},"vi":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"Đã chạy tập lệnh cmux ({n} lệnh gọi): {first}"}}}}},"zh-Hans":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"已运行 cmux 脚本({n} 次调用):{first}"}}}}},"zh-Hant":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"已執行 cmux 指令碼({n} 次呼叫):{first}"}}}}}}}
+    "tools.cmux.script": {"comment":"Agent pane: a cmux_exec script's (or a cmux MCP tool's) transcript row title, a finished script that called tools the row has no words for; {n} is how many calls it made, {first} the first tool's name","extractionState":"manual","localizations":{"ar":{"variations":{"plural":{"zero":{"stringUnit":{"state":"needs_review","value":"تم تشغيل نص cmux ({n} استدعاء): {first}"}},"one":{"stringUnit":{"state":"needs_review","value":"تم تشغيل نص cmux ({n} استدعاء): {first}"}},"two":{"stringUnit":{"state":"needs_review","value":"تم تشغيل نص cmux ({n} استدعاء): {first}"}},"few":{"stringUnit":{"state":"needs_review","value":"تم تشغيل نص cmux ({n} استدعاء): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"تم تشغيل نص cmux ({n} استدعاء): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"تم تشغيل نص cmux ({n} استدعاء): {first}"}}}}},"bs":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Pokrenuta cmux skripta ({n} poziv): {first}"}},"few":{"stringUnit":{"state":"needs_review","value":"Pokrenuta cmux skripta ({n} poziva): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Pokrenuta cmux skripta ({n} poziva): {first}"}}}}},"da":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Kørte cmux-script ({n} kald): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Kørte cmux-script ({n} kald): {first}"}}}}},"de":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"cmux-Skript ausgeführt ({n} Aufruf): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"cmux-Skript ausgeführt ({n} Aufrufe): {first}"}}}}},"en":{"variations":{"plural":{"one":{"stringUnit":{"state":"translated","value":"Ran cmux script ({n} call): {first}"}},"other":{"stringUnit":{"state":"translated","value":"Ran cmux script ({n} calls): {first}"}}}}},"es":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Se ejecutó un script de cmux ({n} llamada): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Se ejecutó un script de cmux ({n} llamadas): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Se ejecutó un script de cmux ({n} llamadas): {first}"}}}}},"fr":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Script cmux exécuté ({n} appel) : {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Script cmux exécuté ({n} appels) : {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Script cmux exécuté ({n} appels) : {first}"}}}}},"it":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Eseguito script cmux ({n} chiamata): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Eseguito script cmux ({n} chiamate): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Eseguito script cmux ({n} chiamate): {first}"}}}}},"ja":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"cmux スクリプトを実行しました ({n} 件の呼び出し): {first}"}}}}},"km":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"បានដំណើរការស្គ្រីប cmux ({n} ការហៅ)៖ {first}"}}}}},"ko":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"cmux 스크립트 실행함 (호출 {n}개): {first}"}}}}},"nb":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Kjørte cmux-skript ({n} kall): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Kjørte cmux-skript ({n} kall): {first}"}}}}},"pl":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Uruchomiono skrypt cmux ({n} wywołanie): {first}"}},"few":{"stringUnit":{"state":"needs_review","value":"Uruchomiono skrypt cmux ({n} wywołania): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Uruchomiono skrypt cmux ({n} wywołań): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Uruchomiono skrypt cmux ({n} wywołania): {first}"}}}}},"pt-BR":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Script do cmux executado ({n} chamada): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Script do cmux executado ({n} chamadas): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Script do cmux executado ({n} chamadas): {first}"}}}}},"ru":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Выполнен скрипт cmux ({n} вызов): {first}"}},"few":{"stringUnit":{"state":"needs_review","value":"Выполнен скрипт cmux ({n} вызова): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Выполнен скрипт cmux ({n} вызовов): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Выполнен скрипт cmux ({n} вызова): {first}"}}}}},"th":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"เรียกใช้สคริปต์ cmux แล้ว ({n} การเรียก): {first}"}}}}},"tr":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"cmux betiği çalıştırıldı ({n} çağrı): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"cmux betiği çalıştırıldı ({n} çağrı): {first}"}}}}},"uk":{"variations":{"plural":{"one":{"stringUnit":{"state":"needs_review","value":"Виконано скрипт cmux ({n} виклик): {first}"}},"few":{"stringUnit":{"state":"needs_review","value":"Виконано скрипт cmux ({n} виклики): {first}"}},"many":{"stringUnit":{"state":"needs_review","value":"Виконано скрипт cmux ({n} викликів): {first}"}},"other":{"stringUnit":{"state":"needs_review","value":"Виконано скрипт cmux ({n} виклику): {first}"}}}}},"vi":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"Đã chạy tập lệnh cmux ({n} lệnh gọi): {first}"}}}}},"zh-Hans":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"已运行 cmux 脚本({n} 次调用):{first}"}}}}},"zh-Hant":{"variations":{"plural":{"other":{"stringUnit":{"state":"needs_review","value":"已執行 cmux 指令碼({n} 次呼叫):{first}"}}}}}}},
+    "cloudStartup.title": {"comment":"Agent pane: Cloud startup checklist","extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Initializing session"}},"ar":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"bs":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"da":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"de":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"es":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"fr":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"it":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"ja":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"km":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"ko":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"nb":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"pl":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"pt-BR":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"ru":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"th":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"tr":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"uk":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"vi":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"zh-Hans":{"stringUnit":{"state":"needs_review","value":"Initializing session"}},"zh-Hant":{"stringUnit":{"state":"needs_review","value":"Initializing session"}}}},
+    "cloudStartup.initialized": {"comment":"Agent pane: Cloud startup checklist","extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Initialized session"}},"ar":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"bs":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"da":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"de":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"es":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"fr":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"it":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"ja":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"km":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"ko":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"nb":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"pl":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"pt-BR":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"ru":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"th":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"tr":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"uk":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"vi":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"zh-Hans":{"stringUnit":{"state":"needs_review","value":"Initialized session"}},"zh-Hant":{"stringUnit":{"state":"needs_review","value":"Initialized session"}}}},
+    "cloudStartup.machine": {"comment":"Agent pane: Cloud startup checklist","extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Set up a Cloud machine"}},"ar":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"bs":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"da":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"de":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"es":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"fr":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"it":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"ja":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"km":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"ko":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"nb":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"pl":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"pt-BR":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"ru":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"th":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"tr":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"uk":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"vi":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"zh-Hans":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}},"zh-Hant":{"stringUnit":{"state":"needs_review","value":"Set up a Cloud machine"}}}},
</file context>

.acpmux-cloud-start__row { display: grid; grid-template-columns: 20px max-content max-content 1fr; align-items: start; gap: 7px; min-height: 28px; color: var(--agent-text); }
.acpmux-cloud-start__row[data-status="pending"], .acpmux-cloud-start__row[data-status="skipped"] { color: var(--agent-muted); }
.acpmux-cloud-start__row[data-status="error"] { color: var(--agent-danger, #f87171); }
.acpmux-cloud-start__mark { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 20px; color: var(--agent-accent, #4ade80); }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This .acpmux-cloud-start__mark rule conflicts with the existing rule further down the file, which sets width: 14px. The later rule wins, so the width: 18px here is dead and the mark renders 14×20. Merge the two into one rule and keep a single width value.

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 webviews/src/agent-session/acpmux/cloudStart.css, line 40:

<comment>This `.acpmux-cloud-start__mark` rule conflicts with the existing rule further down the file, which sets `width: 14px`. The later rule wins, so the `width: 18px` here is dead and the mark renders 14×20. Merge the two into one rule and keep a single width value.</comment>

<file context>
@@ -13,6 +13,41 @@
+.acpmux-cloud-start__row { display: grid; grid-template-columns: 20px max-content max-content 1fr; align-items: start; gap: 7px; min-height: 28px; color: var(--agent-text); }
+.acpmux-cloud-start__row[data-status="pending"], .acpmux-cloud-start__row[data-status="skipped"] { color: var(--agent-muted); }
+.acpmux-cloud-start__row[data-status="error"] { color: var(--agent-danger, #f87171); }
+.acpmux-cloud-start__mark { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 20px; color: var(--agent-accent, #4ade80); }
+.acpmux-cloud-start__row[data-status="pending"] .acpmux-cloud-start__mark, .acpmux-cloud-start__row[data-status="skipped"] .acpmux-cloud-start__mark { color: var(--agent-muted); }
+.acpmux-cloud-start__row[data-status="error"] .acpmux-cloud-start__mark { color: inherit; }
</file context>

const startedAt = number(record.startedAt ?? record.started_at);
const finishedAt = number(record.finishedAt ?? record.finished_at);
const hasScript = typeof record.hasScript === "boolean" ? record.hasScript : typeof record.has_script === "boolean" ? record.has_script : undefined;
const logTail = logLine(record.logTail ?? record.log_tail, 1200);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: logLine keeps the start of logTail and drops its end. The newest setup output is the part worth showing, so truncate from the front and keep the last characters instead.

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 webviews/src/agent-session/acpmux/cloudStartProgress.ts, line 268:

<comment>`logLine` keeps the start of `logTail` and drops its end. The newest setup output is the part worth showing, so truncate from the front and keep the last characters instead.</comment>

<file context>
@@ -89,9 +165,117 @@ export function cloudStartPushed(
+  const startedAt = number(record.startedAt ?? record.started_at);
+  const finishedAt = number(record.finishedAt ?? record.finished_at);
+  const hasScript = typeof record.hasScript === "boolean" ? record.hasScript : typeof record.has_script === "boolean" ? record.has_script : undefined;
+  const logTail = logLine(record.logTail ?? record.log_tail, 1200);
+  return {
+    ...(base ?? { state: "skipped" as const }),
</file context>

stack.push(entry.path());
} else {
let relative = entry.path().strip_prefix(root).unwrap().display().to_string();
found.insert(relative, std::fs::read_to_string(entry.path()).unwrap_or_default());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: files() swallows read errors with unwrap_or_default(), so unreadable or binary files compare as equal empty strings. Use .unwrap() so the content comparison fails loudly.

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/tests/link_seed.rs, line 201:

<comment>`files()` swallows read errors with `unwrap_or_default()`, so unreadable or binary files compare as equal empty strings. Use `.unwrap()` so the content comparison fails loudly.</comment>

<file context>
@@ -0,0 +1,373 @@
+                stack.push(entry.path());
+            } else {
+                let relative = entry.path().strip_prefix(root).unwrap().display().to_string();
+                found.insert(relative, std::fs::read_to_string(entry.path()).unwrap_or_default());
+            }
+        }
</file context>
Suggested change
found.insert(relative, std::fs::read_to_string(entry.path()).unwrap_or_default());
found.insert(relative, std::fs::read_to_string(entry.path()).unwrap());

</ol>
);
{failed && <output className="acpmux-cloud-start__status" role="alert">{start.message ?? t("sandbox.failed")}</output>}
{known.length > 0 && <ul className="acpmux-cloud-start__chips" data-look={arm}>{known.map((fact) => <li key={fact.id} data-fact={fact.id}>{fact.id === "folder" ? <Folder size={12} /> : <span className="acpmux-cloud-start__label">{fact.label}</span>}<span>{fact.value}</span></li>)}</ul>}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The rows experiment arm now renders the same chips as the default arm, so its description no longer matches what it shows. Either restore the fact-row rendering for that arm or retire the arm and its CSS.

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 webviews/src/agent-session/acpmux/CloudStartView.tsx, line 139:

<comment>The `rows` experiment arm now renders the same chips as the default arm, so its description no longer matches what it shows. Either restore the fact-row rendering for that arm or retire the arm and its CSS.</comment>

<file context>
@@ -1,129 +1,142 @@
-    </ol>
-  );
+    {failed && <output className="acpmux-cloud-start__status" role="alert">{start.message ?? t("sandbox.failed")}</output>}
+    {known.length > 0 && <ul className="acpmux-cloud-start__chips" data-look={arm}>{known.map((fact) => <li key={fact.id} data-fact={fact.id}>{fact.id === "folder" ? <Folder size={12} /> : <span className="acpmux-cloud-start__label">{fact.label}</span>}<span>{fact.value}</span></li>)}</ul>}
+    {arm === "steps" && !failed && <ol className="acpmux-cloud-start__legacy-steps" aria-hidden>{CLOUD_START_STEPS.map((name, index) => { const current = start.step ? CLOUD_START_STEPS.indexOf(start.step) : -1; const state = index < current ? "done" : index === current ? "current" : "next"; return <li key={name} data-step={state}>{name}</li>; })}</ol>}
+  </section>;
</file context>

{!failed && !start.initialized && <output className="acpmux-cloud-start__status"><Spinner size={14} loading /><span>{t("cloudStart.title")}</span></output>}
<div className="acpmux-cloud-start__card">
<button type="button" className="acpmux-cloud-start__summary" aria-expanded={expanded} onClick={() => setExpanded((value) => !value)}><span>{start.initialized ? t("cloudStartup.initialized") : t("cloudStartup.title")}</span>{expanded ? <ChevronDown size={14} /> : start.initialized ? <span aria-hidden>›</span> : <ChevronRight size={14} />}</button>
{expanded && <div className="acpmux-cloud-start__checklist" aria-label="Cloud startup checklist">{rows.map((step) => <div key={step.id} className="acpmux-cloud-start__row" data-status={step.status} data-step-id={step.id}><span className="acpmux-cloud-start__mark">{mark(step, t)}</span><span className="acpmux-cloud-start__row-label">{step.label}</span>{step.duration && <time className="acpmux-cloud-start__time">{step.duration}</time>}{step.id === "setup" && step.action ? <span className="acpmux-cloud-start__detail">{onOpenEnvironment ? <button type="button" className="acpmux-cloud-start__link" onClick={openEnvironment}>{t("cloudStartup.setupHint")}</button> : t("cloudStartup.setupHint")}</span> : step.detail ? <span className={`acpmux-cloud-start__detail${step.logTail ? " acpmux-cloud-start__log-tail" : ""}`}>{step.detail}</span> : null}{step.link && <a className="acpmux-cloud-start__link" href={step.link.href} target="_blank" rel="noreferrer">{step.link.label}</a>}</div>)}</div>}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This hardcoded English aria-label is not localized, and a plain div with no role ignores it. Remove the attribute, or give the container a role and a localized label.

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 webviews/src/agent-session/acpmux/CloudStartView.tsx, line 136:

<comment>This hardcoded English `aria-label` is not localized, and a plain div with no role ignores it. Remove the attribute, or give the container a role and a localized label.</comment>

<file context>
@@ -1,129 +1,142 @@
+    {!failed && !start.initialized && <output className="acpmux-cloud-start__status"><Spinner size={14} loading /><span>{t("cloudStart.title")}</span></output>}
+    <div className="acpmux-cloud-start__card">
+      <button type="button" className="acpmux-cloud-start__summary" aria-expanded={expanded} onClick={() => setExpanded((value) => !value)}><span>{start.initialized ? t("cloudStartup.initialized") : t("cloudStartup.title")}</span>{expanded ? <ChevronDown size={14} /> : start.initialized ? <span aria-hidden>›</span> : <ChevronRight size={14} />}</button>
+      {expanded && <div className="acpmux-cloud-start__checklist" aria-label="Cloud startup checklist">{rows.map((step) => <div key={step.id} className="acpmux-cloud-start__row" data-status={step.status} data-step-id={step.id}><span className="acpmux-cloud-start__mark">{mark(step, t)}</span><span className="acpmux-cloud-start__row-label">{step.label}</span>{step.duration && <time className="acpmux-cloud-start__time">{step.duration}</time>}{step.id === "setup" && step.action ? <span className="acpmux-cloud-start__detail">{onOpenEnvironment ? <button type="button" className="acpmux-cloud-start__link" onClick={openEnvironment}>{t("cloudStartup.setupHint")}</button> : t("cloudStartup.setupHint")}</span> : step.detail ? <span className={`acpmux-cloud-start__detail${step.logTail ? " acpmux-cloud-start__log-tail" : ""}`}>{step.detail}</span> : null}{step.link && <a className="acpmux-cloud-start__link" href={step.link.href} target="_blank" rel="noreferrer">{step.link.label}</a>}</div>)}</div>}
     </div>
-  );
</file context>

}

fn now_millis() -> f64 {
SystemTime::now()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: A backward system-clock adjustment during a copy can make seed_finished_at earlier than seed_started_at, producing invalid clone timing and violating the new ordering assertion. Capture an Instant at the start and derive the finish timestamp from its monotonic elapsed duration.

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 156:

<comment>A backward system-clock adjustment during a copy can make `seed_finished_at` earlier than `seed_started_at`, producing invalid clone timing and violating the new ordering assertion. Capture an `Instant` at the start and derive the finish timestamp from its monotonic elapsed duration.</comment>

<file context>
@@ -148,6 +152,30 @@ fn refused(code: &str, error: impl std::fmt::Display) -> Value {
 }
 
+fn now_millis() -> f64 {
+    SystemTime::now()
+        .duration_since(UNIX_EPOCH)
+        .map(|value| value.as_secs_f64() * 1_000.0)
</file context>

Comment on lines +34 to 47
public init(name: String, folder: String? = nil, machine: String? = nil, size: String? = nil,
cloneState: String? = nil, clonePhase: String? = nil,
cloneStartedAt: Double? = nil, cloneFinishedAt: Double? = nil, cloneReceivedBytes: Int? = nil,
cloneObjects: Int? = nil, cloneTotalObjects: Int? = nil, setupStatus: String? = nil,
setupLogTail: String? = nil, machineStartedAt: Double? = nil, machineFinishedAt: Double? = nil,
harnessStartedAt: Double? = nil, harnessFinishedAt: Double? = nil) {
(self.name, self.folder, self.machine, self.size) = (name, folder, machine, size)
(self.cloneState, self.clonePhase, self.cloneReceivedBytes, self.cloneObjects, self.cloneTotalObjects) =
(cloneState, clonePhase, cloneReceivedBytes, cloneObjects, cloneTotalObjects)
(self.cloneStartedAt, self.cloneFinishedAt) = (cloneStartedAt, cloneFinishedAt)
(self.setupStatus, self.setupLogTail) = (setupStatus, setupLogTail)
(self.machineStartedAt, self.machineFinishedAt, self.harnessStartedAt, self.harnessFinishedAt) =
(machineStartedAt, machineFinishedAt, harnessStartedAt, harnessFinishedAt)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The public Step initializer omits the five newly added progress fields, forcing callers to construct the value and mutate it afterward. Add these fields to the initializer and assign them there.

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 Packages/macOS/CmuxNext/Sources/CmuxNextAgentPane/AgentPaneCloudStart+Cloud.swift, line 34:

<comment>The public `Step` initializer omits the five newly added progress fields, forcing callers to construct the value and mutate it afterward. Add these fields to the initializer and assign them there.</comment>

<file context>
@@ -10,15 +10,55 @@ extension AgentPaneCloudStart {
+        public var cloneInstallURL: String?
 
-        public init(name: String, folder: String? = nil, machine: String? = nil, size: String? = nil) {
+        public init(name: String, folder: String? = nil, machine: String? = nil, size: String? = nil,
+                    cloneState: String? = nil, clonePhase: String? = nil,
+                    cloneStartedAt: Double? = nil, cloneFinishedAt: Double? = nil, cloneReceivedBytes: Int? = nil,
</file context>
Suggested change
public init(name: String, folder: String? = nil, machine: String? = nil, size: String? = nil,
cloneState: String? = nil, clonePhase: String? = nil,
cloneStartedAt: Double? = nil, cloneFinishedAt: Double? = nil, cloneReceivedBytes: Int? = nil,
cloneObjects: Int? = nil, cloneTotalObjects: Int? = nil, setupStatus: String? = nil,
setupLogTail: String? = nil, machineStartedAt: Double? = nil, machineFinishedAt: Double? = nil,
harnessStartedAt: Double? = nil, harnessFinishedAt: Double? = nil) {
(self.name, self.folder, self.machine, self.size) = (name, folder, machine, size)
(self.cloneState, self.clonePhase, self.cloneReceivedBytes, self.cloneObjects, self.cloneTotalObjects) =
(cloneState, clonePhase, cloneReceivedBytes, cloneObjects, cloneTotalObjects)
(self.cloneStartedAt, self.cloneFinishedAt) = (cloneStartedAt, cloneFinishedAt)
(self.setupStatus, self.setupLogTail) = (setupStatus, setupLogTail)
(self.machineStartedAt, self.machineFinishedAt, self.harnessStartedAt, self.harnessFinishedAt) =
(machineStartedAt, machineFinishedAt, harnessStartedAt, harnessFinishedAt)
}
public init(name: String, folder: String? = nil, machine: String? = nil, size: String? = nil,
cloneState: String? = nil, clonePhase: String? = nil,
cloneStartedAt: Double? = nil, cloneFinishedAt: Double? = nil, cloneReceivedBytes: Int? = nil,
cloneObjects: Int? = nil, cloneTotalObjects: Int? = nil, setupStatus: String? = nil,
setupLogTail: String? = nil, machineStartedAt: Double? = nil, machineFinishedAt: Double? = nil,
harnessStartedAt: Double? = nil, harnessFinishedAt: Double? = nil,
cloneBytesTotal: Int? = nil, cloneFilesDone: Int? = nil, cloneFilesTotal: Int? = nil,
cloneFallback: String? = nil, cloneInstallURL: String? = nil) {
(self.name, self.folder, self.machine, self.size) = (name, folder, machine, size)
(self.cloneState, self.clonePhase, self.cloneReceivedBytes, self.cloneObjects, self.cloneTotalObjects) =
(cloneState, clonePhase, cloneReceivedBytes, cloneObjects, cloneTotalObjects)
(self.cloneStartedAt, self.cloneFinishedAt) = (cloneStartedAt, cloneFinishedAt)
(self.setupStatus, self.setupLogTail) = (setupStatus, setupLogTail)
(self.machineStartedAt, self.machineFinishedAt, self.harnessStartedAt, self.harnessFinishedAt) =
(machineStartedAt, machineFinishedAt, harnessStartedAt, harnessFinishedAt)
(self.cloneBytesTotal, self.cloneFilesDone, self.cloneFilesTotal, self.cloneFallback, self.cloneInstallURL) =
(cloneBytesTotal, cloneFilesDone, cloneFilesTotal, cloneFallback, cloneInstallURL)
}

@github-actions github-actions Bot added risk:normal Risk tier (docs/ci/risk-tiers.md) and removed risk:high Risk tier (docs/ci/risk-tiers.md) labels Nov 1, 2026
@blacksmith-sh

blacksmith-sh Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Found 1 test failure on Blacksmith runners:

Failure

Test View Logs
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)/
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)
View Logs

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

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, router-review): BLOCK at c44944b

BLOCK at c44944b

Visual verdict: no images; Leo tries the build

  1. [P1][blocking] CloudStartView.tsx:132 suppresses the user's prompt whenever startup fails. The previous implementation kept the prompt bubble visible on failures; now the main Cloud start view shows only the checklist and error, so the failed request disappears from the conversation.

  2. [P2][follow-up] CloudStartView.tsx:126-129 dispatches cmux:open-cloud-environment when no callback is supplied, but neither production App.tsx call site passes onOpenEnvironment and no listener exists. Consequently, the “Add a setup script…” hint is plain, non-actionable text in the actual app despite the intended environment editor action.

@teamleaderleo teamleaderleo left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (W2-02 independent): BLOCK recommendation at 3fadf64

[P1 / introduced] A successful GitHub-backed Move to Cloud becomes impossible to Bring Back Local through the existing flow. This PR changes CloudMove.sync to link seed push and the post-freeze delta to --sync seed, but CloudBringBack still calls link sync pull before transferring the chat and again with --sync pull after freeze.

On true seed success, seed_cli::seed_full calls keep_seed, which writes the distinct <state>/link-seed/<key>.json record. It never calls sync_cli::push, so it neither writes the remote .git/cmux-sync.json nor saves <state>/link-sync/<key>.json. Conversely, sync_cli::pull requires the remote .git/cmux-sync.json and the matching local link-sync base via base::trusted; a fresh seeded move therefore returns sync_no_base (or sync_base_mismatch if an unrelated old base exists), and CloudBringBack.run stops before moving the chat. A fallback that uses the old streamed copy works, which hides this case in current tests.

This is a central product journey. The current Swift CloudMoveTests asserts arguments with a stand-in CLI; it never drives an actual successful git-seed-v1 result through a real Bring Back. The related #30633 provides only the machine-side git.seed.export; its description explicitly says the Mac-side cmux link seed pull is a follow-up. Therefore the return path is missing at this head.

Minimal safe route to land: retain link sync push and frozen --sync push for Move to Cloud until seed-aware pull (including three-way conflict/CAS) is implemented and wired through Bring Back; seed-based new-chat startup can proceed separately. Alternatively land both directions atomically in a reviewed stack, persisting the transfer mode for Bring Back. Test: two real local daemons with debug-only GitHub remote fixture; actual link seed push returns mode:seed; move the live chat, edit tracked and untracked files on the remote, then Bring Back. Assert exact chat/queue continuity and git diff return, and separately assert conflict refusal. The test should fail on this head and pass on the correction.

Evidence level: exact-head source review; Rust/Swift tests and live Cloud VM were not executed. Relevant source:

let remote = folder.remote(under: root)
do {
last = try await cli.syncPush(socket: socket, local: folder.root, remote: remote.folder)
last = try await cli.seedPush(socket: socket, local: folder.root, remote: remote.folder)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] True Git seed leaves a link-seed record and no cmux-sync.json / link-sync manifest. CloudBringBack.run still calls link sync pull before transfer (and --sync pull after freeze), so a seeded Move to Cloud cannot return: base::trusted fails with sync_no_base. Keep Move on sync push until the seed-aware return path lands, or pair this with the full link seed pull and a real two-daemon Move→Bring Back test. Fallback-copy cases and the current shell stand-in test conceal the regression.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at 3fadf64

Reviewer: codex gpt-6-astra high, fast tier.

Follow-ups: 2. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward.

SHIP at 3fadf64

Visual verdict: no images; Leo tries the build

  1. [P1][follow-up] Setup progress is never produced or actionable. CloudMoveCLI.Answer reads environment_status, but start_chat_cli only forwards seed/copy fields (start_chat_cli.rs:551), and both CloudStartView call sites omit onOpenEnvironment (App.tsx:12944, App.tsx:13359). The setup row therefore cannot show running/failed/cached status or open the environment editor.

  2. [P2][follow-up] Successful copies expose a literal complete detail. Rust reports seed_phase: "complete" for every successful copy, while cloneDetail has no complete case and falls through to displaying the raw phase (CloudStartView.tsx:51-66). During the interval before opening, users see “complete” instead of a localized completion state.

Follow-ups:

  • [P1] Wire environment/setup progress and the environment editor callback.
  • [P2] Handle the final complete clone phase with localized wording.

@cmux-bot cmux-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmux-bot approves 3fadf64: an independent review passed this exact head (router-review receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

cmux link seed push's stderr progress lines reach the startup
checklist's clone row while the copy runs: upload, clone, checkout and
the other phases, a fallback copy's files and bytes, and why a seed
copied instead with the cmux GitHub App's install link. The parsing,
the throttle (about 4 a second) and the main-actor feed live in
CmuxNextCloud (SeedProgress); ProcessRunner hands stderr over line by
line (StderrLines). CmuxNextApp does not grow; the page owns the words.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5
@teamleaderleo teamleaderleo changed the title Cloud start: copy the project with link seed push and show its progress on the clone row Cloud start: the clone row shows the seed's live progress Nov 1, 2026
@cursor

cursor Bot commented Nov 1, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at b03c375

Reviewer: codex gpt-6-astra high, fast tier.

Follow-ups: 1. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward.

SHIP at b03c375

Visual verdict: no images; Leo tries the build

  1. [P2][follow-up] No after screenshots or gallery artifact were available for visual verification.

Follow-ups: 1. Add or capture the post-change UI screenshots for visual review.

cmux-bot[bot]
cmux-bot Bot previously approved these changes Nov 1, 2026

@cmux-bot cmux-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmux-bot approves b03c375: an independent review passed this exact head (router-review receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent November 1, 2026 17:41 Inactive
@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent November 1, 2026 17:41 Inactive
@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent November 1, 2026 17:42 Inactive
@cmux-bot
cmux-bot Bot dismissed their stale review November 1, 2026 17:44

A newer verdict blocks a72d023 (no independent SHIP at the head).

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (next-review patch-id; carried): SHIP at a72d023

The independent SHIP at b03c375 carries to this head: the PR's own change (git diff $(git merge-base feat-cmux-next HEAD) HEAD) has the same git patch-id --verbatim (848e4065015ce1fd) at both heads, and no merge between them was resolved by hand. Nothing new to review. A newer BLOCK, or any change to the PR's own diff, ends the carry.

…ase wrote it (pane-english)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5
…ome and source trust)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5
@cursor

cursor Bot commented Nov 1, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at ece52d7

Reviewer: codex gpt-6.1-sol xhigh, fast tier.

Follow-ups: 1. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward.

SHIP at ece52d7
Visual verdict: no images; Leo tries the build

No correctness bugs found.

  1. [P2] [follow-up] CloudStartView.tsx:358: After screenshots are missing. Verify the progress text and install link at narrow pane widths.

Validation: 14 pure-logic tests passed through a Node/Babel harness. Concurrency, layer, and catalog checks passed. Swift and React rendering tests could not run with the available tooling.

Follow-ups:

  • Capture the live progress and fallback-link states at narrow and normal widths.

@cmux-bot cmux-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmux-bot approves ece52d7: an independent review passed this exact head (router-review receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

…de the clone progress)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at 4c24230

Reviewer: codex gpt-6-astra high, fast tier.

Follow-ups: 1. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward.

SHIP at 4c24230

Visual verdict: no images; Leo tries the build

No correctness findings.

Follow-ups:

  • [P2] [follow-up] No after screenshots or gallery artifact were available for visual comparison.

@cmux-bot cmux-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmux-bot approves 4c24230: an independent review passed this exact head (router-review receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

@teamleaderleo
teamleaderleo merged commit 1e33636 into feat-cmux-next Nov 1, 2026
183 of 189 checks passed
@teamleaderleo
teamleaderleo deleted the seed-start-copy branch November 1, 2026 19:03

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 4c242306 Deployed Nov 1, 2026 by teamleaderleo via wait for same-key tree publisher #97153
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant