Repository navigation
Cloud start: the clone row shows the seed's live progress - #30655
Conversation
|
Owned by an agent session · session |
|
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)
Gallery before/after for
States
Pick other states with a Passes: CI passes on CI passes on Written by web and size checks: green Default changesThis pull request changes 2 defaults at
Signed off on this commit by Merge receipt: merged as Regenerate the snapshot with Shipped in:
|
There was a problem hiding this comment.
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 } } }, |
There was a problem hiding this comment.
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>
| 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 } }, |
There was a problem hiding this comment.
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>
| 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} 個分頁"}}}}}}}, | |||
There was a problem hiding this comment.
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); } |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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>
| 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>} |
There was a problem hiding this comment.
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>} |
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
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>
| 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) | ||
| } |
There was a problem hiding this comment.
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>
| 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) | |
| } |
|
Found 1 test failure on Blacksmith runners: Failure
|
|
Review (codex gpt-6-astra high, router-review): BLOCK at c44944b BLOCK at c44944b Visual verdict: no images; Leo tries the build
|
teamleaderleo
left a comment
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
[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.
|
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
Follow-ups:
|
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
3fadf64 to
5aa263c
Compare
…NextCloud) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5
Bugbot needs on-demand usage enabledBugbot 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. |
|
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
Follow-ups: 1. Add or capture the post-change UI screenshots for visual review. |
A newer verdict blocks a72d023 (no independent SHIP at the head).
|
Review (next-review patch-id; carried): SHIP at a72d023 The independent SHIP at b03c375 carries to this head: the PR's own change ( |
…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
Bugbot needs on-demand usage enabledBugbot 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. |
|
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 No correctness bugs found.
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:
|
…de the clone progress) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5
|
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:
|
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
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:#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, newcloudStartup.*keys in every locale; non-English copies marked needs_review):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.progressgainsbytesTotal,filesDoneandfilesTotal;clonegainsfallbackandinstallUrl;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. ADispatchSourcevnode watch on adup'd descriptor reads appended bytes withpread.finish(). It drains to EOF on the reader's queue, delivers the last partial line, then cancels the source.defer { cancel() }covers every throw or timeout, and the cancel handler closes the dup'd descriptor.CmuxNextCloud/Move/SeedProgress.swift:{"progress":{...}}lines;feedruns 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.cloneProgressandAgentPaneCloudStart.fieldsmap a progress value to the page's clone fields.CloudStartChatwraps its existing copy inSeedProgress.feed, andCloudMoveCLI.startChatCopypassesstderrLinethrough. There is noas!.The CSS is unchanged: the link reuses the row's detail and link classes, so there are no new design-token rows.
Tests
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.SeedProgressTests(parse, throttle, feed, field names) andcmux-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