Skip to content

Agent pane: the bottom stack on one edge as one glass, Stop in the tray row's menu - #28533

Merged
teamleaderleo merged 34 commits into
feat-cmux-nextfrom
lane/ux-bottom-stack
Nov 1, 2026
Merged

teamleaderleo merged 34 commits into
feat-cmux-nextfrom
lane/ux-bottom-stack

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Leo, 2026-10-30, on the agent pane's bottom stack:

"ugh it's so ugly
i almost hate having these running things all at the bottom but idk what we can do better
the session info bar is there i guess... maybe i just dont like the styling
and the fact that im still on the version with the stupid f***ing gap at the bottom plus the stupid right indent misalignemnt"

Scope ruling (coordinator, relaying Leo's "remove the things"): the compact "N PRs" control is dropped from this PR. #29614 (base) removed the per-message PR chips on Leo's "remove the chips they're so bad", and that removal stands. This PR brings back no PR chip or PR count anywhere.

What changed

  • One glass stack (bottomStack.css). The running tray stands on the composer card's two edges (--cv-inset, --cv-inset-end), --acpmux-stack-gap over the composer. In the selected look the gap is 0. Where the tray meets the composer neither corner rounds, and only the composer draws the hairline, the same way the queue meets the card. A settled tray draws no card, so the composer keeps its rounded top. The gallery's cards look (data-bottom-stack="cards") keeps separate cards 4px apart.
  • Stop is in a running tray row's right-click menu (subagents/SubagentTray.tsx), not a button on every row. A right-click (or Shift-F10) opens the menu on the click, and the row stays lit while its menu is open (subagents.css, [data-popup-open]). The gallery variant is row-menu in SubagentTray.gallery.ts.
  • .github/design-surfaces.json maps bottomStack.css to the composer surface and adds a running-tray surface.

Gallery (agent-pane.bottom-stack-styles)

Synthetic data: nine background subagents, one chat waiting on you, and the composer. Variants:

  • collapsed (selected): the tray folded.
  • no-tray.
  • expanded: the tray open.
  • cards: the alternative look with separate cards.

Tests

  • test/agent-pane-bottom-stack-edges.test.ts runs at 1100, 760 and 420 px. It checks that:
    • every card over the composer is within 1 px of the composer card's left and right edges;
    • every gap equals --acpmux-stack-gap;
    • the tray's header and line chevrons share one x;
    • no PR count or chip (.acpmux-pr-count, .acpmux-pr-stack, .acpmux-pr-dock, .acpmux-pr-chip) appears.
  • test/subagent-tray.test.tsx, subagent-tray-columns, subagent-tray-trailing, running-strip and session-info-dead-clicks cover the row menu's Stop and the tray's tracks with no Stop slot at rest.
  • bun run strings, CMUX_LOCAL_HEAVY_CHECKS=0 bun run check and check-default-cursor.py all pass.

Spec: design/composer.md, "Bottom stack" section.

Risk: normal. The change is web only. With no running tray the stack renders as before.

Changelog

Changed: the running tray and the composer share the same edges as one glass stack, and a running row's Stop moved into its right-click menu.

Agent session: agent session

🤖 Generated with Claude Code

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 30, 2026
teamleaderleo and others added 2 commits October 30, 2026 21:28
Add agent-pane.bottom-stack-styles, the whole bottom stack with synthetic
data (nine background subagents, one chat waiting, two PRs, the composer),
and a geometry test: every card over the composer takes the composer card's
left and right x to 1px, the cards stand one --acpmux-stack-gap apart, and
a one-line "N PRs" row opens on the click to chips at the card's width.
Red on base: no PR row, no stack gap token.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
…s, with its N PRs row back

Leo, 2026-10-30: "you guys fucking removed the # prs thing entirely instead
of just simply fucking doing it". cmux#26082 moved the PR pills into each
message's action row and dropped the dock's collapsed count. The count comes
back as one row in the bottom stack (summary/PullRequestStack.tsx): the PR
mark, "N PRs" and a disclosure on the tray header's columns, opening on the
click with no fade to one full-width chip per PR with the reply links' hover
card. The per-message pills stay.

Every card over the composer takes the composer card's two edges and stands
--acpmux-stack-gap over the next; the selected look is one glass stack (gap
0, squared joins, one hairline between parts). The gallery compares it with
separate cards 4px apart and a compact strip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
…the chips, each with ×

Keep the settled PR dock design (design/session-info.md, Leo 2026-10-26): the
count opens Session Info > Changes and counts what Changes counts; the
disclosure beside it opens the chips, and a chip's × hides that shortcut only,
in the dock's existing per-chat dismissal list. The disclosure's glyph centers
on the stack's trailing line, 22 from the card's right edge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
bottomStack.css and the PR stack join the composer surface (design/composer.md);
the running tray gets its own surface (design/running-tray.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
…ith the composer

agent-pane-dock-gutters lists the PR row among the stack's parts and checks its
gutter passes the wheel through as the tray's does; pr-dock-inline-layout lets
the dock and the PR row move up with a queued prompt that grows the form, their
own size unchanged. The styles gallery covers PullRequestStack.tsx only (a cover
names a component, not a sheet).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
@teamleaderleo teamleaderleo changed the title Agent pane: the bottom stack on one edge, with its N PRs row back Agent pane: the bottom stack on one edge as one glass, with its N PRs row back Oct 30, 2026
@teamleaderleo
teamleaderleo marked this pull request as ready for review October 30, 2026 21:59
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

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

Review 868e4f8: 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=pr28533 -f ref=lane/ux-bottom-stack -f platform=macos -f backend_mode=local

Gallery before/after for 868e4f8: 16 states rendered, 12 images differ, 1524 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 41276216714 -R manaflow-ai/cmux -n gallery-advisory-28533-868e4f89322e6f876a91886b17a07aeb25e0fe54 (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.background-activity/duration-columns Apple System Colors Light unchanged 0% own subagents.css
agent-pane.background-activity/duration-columns Apple System Colors unchanged 0% own subagents.css
agent-pane.background-activity/pinned-live-tail-light Apple System Colors Light unchanged 0% own subagents.css
agent-pane.background-activity/pinned-live-tail-light Apple System Colors unchanged 0% own subagents.css
agent-pane.background-activity/pinned-live-tail-dark Apple System Colors Light unchanged 0% own subagents.css
agent-pane.background-activity/pinned-live-tail-dark Apple System Colors unchanged 0% own subagents.css
agent-pane.background-activity/after-latest-message-light Apple System Colors Light unchanged 0% own subagents.css
agent-pane.background-activity/after-latest-message-light Apple System Colors unchanged 0% own subagents.css
agent-pane.background-activity/after-latest-message-dark Apple System Colors Light unchanged 0% own subagents.css
agent-pane.background-activity/after-latest-message-dark Apple System Colors unchanged 0% own subagents.css
agent-pane.background-activity/compact-pill-light Apple System Colors Light unchanged 0% own subagents.css
agent-pane.background-activity/compact-pill-light Apple System Colors unchanged 0% own subagents.css
agent-pane.background-activity/compact-pill-dark Apple System Colors Light unchanged 0% own subagents.css
agent-pane.background-activity/compact-pill-dark Apple System Colors unchanged 0% own subagents.css
agent-pane.background-activity/side-panel-light Apple System Colors Light unchanged 0% own subagents.css
agent-pane.background-activity/side-panel-light Apple System Colors unchanged 0% own subagents.css
agent-pane.bottom-stack-styles/collapsed Apple System Colors Light new 0% own bottomStack.css
agent-pane.bottom-stack-styles/collapsed Apple System Colors new 0% own bottomStack.css
agent-pane.bottom-stack-styles/no-tray Apple System Colors Light new 0% own bottomStack.css
agent-pane.bottom-stack-styles/no-tray Apple System Colors new 0% own bottomStack.css
agent-pane.bottom-stack-styles/expanded Apple System Colors Light new 0% own bottomStack.css
agent-pane.bottom-stack-styles/expanded Apple System Colors new 0% own bottomStack.css
agent-pane.bottom-stack-styles/cards Apple System Colors Light new 0% own bottomStack.css
agent-pane.bottom-stack-styles/cards Apple System Colors new 0% own bottomStack.css
agent-pane.streaming-text/claude Apple System Colors Light changed 0% own bottomStack.css
agent-pane.streaming-text/claude Apple System Colors changed 0% own bottomStack.css
agent-pane.streaming-text/codex Apple System Colors Light unchanged 0% own bottomStack.css
agent-pane.streaming-text/codex Apple System Colors unchanged 0% own bottomStack.css
agent-pane.streaming-text/jump-during-stream Apple System Colors Light changed 0.229% own bottomStack.css
agent-pane.streaming-text/jump-during-stream Apple System Colors changed 0.187% own bottomStack.css
agent-pane.subagent-retry/before Apple System Colors Light unchanged 0% own subagents.css
agent-pane.subagent-retry/before Apple System Colors unchanged 0% own subagents.css

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

Passes: CI passes on 868e4f8932.

CI passes on 868e4f8932 (run 41276216927 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.

red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base e51badc; does not block

Shipped in:

teamleaderleo and others added 2 commits October 30, 2026 22:04
The N PRs row's disclosure, the tray header's chevron and each tray line's
chevron must center within 1px of each other at 1100, 760 and 420px. Red at
7e9f7a6: the N PRs chevron sits about 25px right of the tray's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
--acpmux-stack-trail-end is the stack's one trailing chevron column, the
running tray's (row padding, Stop track, gap); the N PRs disclosure ends on it,
so the stacked rows' chevrons share one x. Once the tray moves its chevron past
Stop (#27930), this variable becomes the row padding alone, and the geometry
test fails until it does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
@blacksmith-sh

blacksmith-sh Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Found 9 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp22v_fk66/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmpa2rotrq7/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs
test_cmux_next_follows_the_committed_target_graph (main.FocusedTestMap.test_cmux_ne
xt_follows_the_committed_target_graph)/
test_cmux_next_follows_the_committed_target_graph (main.FocusedTestMap.test_cmux_ne
xt_follows_the_committed_target_graph)
View Logs
test_every_part_of_bun_run_check_runs_in_the_warn_branch (main.WebviewsWarnSplitCov
ersCheck.test_every_part_of_bun_run_check_runs_in_the_warn_branch)/
test_every_part_of_bun_run_check_runs_in_the_warn_branch (main.WebviewsWarnSplitCov
ersCheck.test_every_part_of_bun_run_check_runs_in_the_warn_branch)
View Logs

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

teamleaderleo and others added 2 commits October 30, 2026 22:15
…; no PRs without the composer

Leo, 2026-10-30: "BUT IF IT'S ONLY N PRS DON'T FUCKIGN TAKE THE ENTIRE ROW AND
FUCKING BLANK IT OUT". The edges test now holds the stack as tall with the
folded count as with no pull requests (with and without the tray), the count
to its content's width with its own highlight, the tray's chevrons to one x,
and the opened chips' × to their row's hover or focus (Tab reaches it, Delete
dismisses). agent-pane-pr-stack-gate reads App.tsx's syntax tree: the pull
requests live only inside the composer's element, so a handoff review or the
Sandboxed receipt shows none. The dock-gutter and inline-layout tests go back
to base: no row of the count stands in the stack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
…w, not a row

The folded count is one content-sized button beside the permission mode in the
composer's quiet row, a row already there, so it adds no row with or without
the tray; its pill lights only itself. It opens the chips on the click with no
fade, right over the composer at the card's width; a chip's × shows only on its
row's hover or focus, with no fade, and Delete or Backspace on a focused row
dismisses it. The count and the chips share one provider that is the composer
element's own `!reviewing` branch, so they cannot show without the composer.
The gallery compares the count on the tray's header line and over the
composer's left edge; the tray-line one falls back to the quiet row with no
tray.

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

cursor Bot commented Oct 30, 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.

The rule that turns the stack's ui-enter off for the chips came before the
ui-enter rule with the same specificity, so the chips still rose and faded in
on the click. It now comes after it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
@teamleaderleo teamleaderleo changed the title Agent pane: the bottom stack on one edge as one glass, with its N PRs row back Agent pane: the bottom stack on one edge as one glass, with a compact N PRs control back Oct 30, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

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

BLOCK

Visual verdict: SHIP. Viewed all 18 after screenshots and compared the before images. No new clipping or off-screen layout. The PR body records viewing an after image.

  1. Keyboard focus is lost when dismissing the final PR shortcut. PullRequestStack.tsx:115 tries to focus the count after removing the last row, but line 138 simultaneously disables that button. Disabled buttons cannot receive focus, so deleting the final focused row leaves keyboard users without a focused control. Focus the composer instead, or retain a focusable count with appropriate disabled semantics. Add an assertion for focus after the last dismissal.

Changed TypeScript/TSX and JSON passed syntax parsing. Runtime tests were unavailable: Bun, browser binaries, and dependencies are absent.

@teamleaderleo teamleaderleo removed the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 30, 2026
teamleaderleo and others added 2 commits November 1, 2026 02:53
…en it no longer can

Red at this commit: the line's ContextMenu host is dropped when nothing can be stopped, so React
remounts the focused row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
… can stop

A line that ends, or whose command's process id arrives, was rendered without its ContextMenu
wrapper, so React remounted the row and dropped its keyboard focus. The host now always wraps the
line, with no items when nothing can stop; ui/ContextMenu keeps the default right-click and opens
nothing for an empty list.

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

Copy link
Copy Markdown
Collaborator Author

Review (codex-review-box/gpt-6-astra high, lane-place): BLOCK at 3fff365

BLOCK at 3fff365

Visual verdict: BLOCK. Opened all 24 images; the expanded-tray after screenshots show repeated per-row Stop controls.

  1. [P1] [blocking] SubagentTray.tsx:393: A successful Stop leaves its agent ID permanently marked "stopping". If that subagent ends and resumes while the tray remains mounted, Stop stays disabled. Previously, the conditional StopButton unmounted on completion and reset on resumption. Clear the stored state when that run ends.

  2. [P1] [blocking] pr.body:85: Both selected expanded-tray after images (image-11.png, image-12.png) show a Stop square on every running row, triggering the explicit visual blocking rule. The head code removes these controls; replace these stale captures with images showing that result.

Tests could not run: Bun and project dependencies are absent.

@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.

5 issues found across 18 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=".github/design-surfaces.json">

<violation number="1" location=".github/design-surfaces.json:46">
P2: Remove the nonexistent `PullRequestDockLegacy.tsx` entry from the composer surface map. The design-spec checker warns on every run because this path is absent from both the base and PR trees.</violation>
</file>

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

<violation number="1" location="webviews/src/agent-session/acpmux/Localizable.xcstrings:16261">
P2: These count keys ship English text for every non-English locale. The strings generator uses `stringUnit.value` regardless of `needs_review`, so localized panes display English PR counts; provide translations for each locale.</violation>
</file>

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

<violation number="1" location="webviews/src/agent-session/acpmux/bottomStackStyles.gallery.ts:65">
P3: The no-PR variants still display an assistant reply saying both PRs are open, even though `prs: false` removes them. Make the reply depend on `prs` so these gallery states accurately represent the data they test.</violation>
</file>

<file name="webviews/test/running-strip.test.ts">

<violation number="1" location="webviews/test/running-strip.test.ts:118">
P2: This test never activates the Stop menu item: hovering only verifies highlighting, so a broken stop handler still passes despite the test claiming that the menu stops the command. Add an observable harness callback and click or keyboard-activate the item before asserting the callback.</violation>
</file>

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

<violation number="1" location="webviews/src/agent-session/acpmux/summary/PullRequestStack.tsx:90">
P2: This reverses first-discovery order instead of using each PR's latest `touched` position, so revisiting an older PR can place it below a newer one and disagree with Session Info. Sort with the shared Changes ordering so the shortcut follows most-recently-touched and open/ended ordering.</violation>
</file>

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

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

Comment thread .github/design-surfaces.json Outdated
Comment on lines +46 to +47
"webviews/src/agent-session/acpmux/summary/PullRequestStack.tsx",
"webviews/src/agent-session/acpmux/summary/PullRequestDockLegacy.tsx"

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: Remove the nonexistent PullRequestDockLegacy.tsx entry from the composer surface map. The design-spec checker warns on every run because this path is absent from both the base and PR trees.

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 .github/design-surfaces.json, line 46:

<comment>Remove the nonexistent `PullRequestDockLegacy.tsx` entry from the composer surface map. The design-spec checker warns on every run because this path is absent from both the base and PR trees.</comment>

<file context>
@@ -41,7 +41,18 @@
-        "webviews/src/agent-session/acpmux/hostRetry.ts"
+        "webviews/src/agent-session/acpmux/hostRetry.ts",
+        "webviews/src/agent-session/acpmux/bottomStack.css",
+        "webviews/src/agent-session/acpmux/summary/PullRequestStack.tsx",
+        "webviews/src/agent-session/acpmux/summary/PullRequestDockLegacy.tsx"
+      ]
</file context>
Suggested change
"webviews/src/agent-session/acpmux/summary/PullRequestStack.tsx",
"webviews/src/agent-session/acpmux/summary/PullRequestDockLegacy.tsx"
"webviews/src/agent-session/acpmux/summary/PullRequestStack.tsx"

}
}
},
"prDock.count": {"comment":"Agent pane: compact count of pull requests above the composer; {count} is the number (si-prpills)","extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"ar":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"bs":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"da":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"de":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"es":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"fr":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"it":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"ja":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"km":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"ko":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"nb":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"pl":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"pt-BR":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"ru":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"th":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"tr":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"uk":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"vi":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"zh-Hans":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"zh-Hant":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}}}},

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: These count keys ship English text for every non-English locale. The strings generator uses stringUnit.value regardless of needs_review, so localized panes display English PR counts; provide translations for each locale.

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

<comment>These count keys ship English text for every non-English locale. The strings generator uses `stringUnit.value` regardless of `needs_review`, so localized panes display English PR counts; provide translations for each locale.</comment>

<file context>
@@ -16258,6 +16258,140 @@
         }
       }
     },
+    "prDock.count": {"comment":"Agent pane: compact count of pull requests above the composer; {count} is the number (si-prpills)","extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"ar":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"bs":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"da":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"de":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"es":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"fr":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"it":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"ja":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"km":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"ko":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"nb":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"pl":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"pt-BR":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"ru":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"th":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"tr":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"uk":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"vi":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"zh-Hans":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}},"zh-Hant":{"stringUnit":{"state":"needs_review","value":"{count} PRs"}}}},
+    "prDock.countOne": {"comment":"Agent pane: compact count of one pull request above the composer (si-prpills)","extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"ar":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"bs":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"da":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"de":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"es":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"fr":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"it":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"ja":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"km":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"ko":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"nb":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"pl":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"pt-BR":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"ru":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"th":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"tr":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"uk":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"vi":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"zh-Hans":{"stringUnit":{"state":"needs_review","value":"1 PR"}},"zh-Hant":{"stringUnit":{"state":"needs_review","value":"1 PR"}}}},
+    "prDock.label": {
</file context>

const item = page.locator('[role="menu"] [role="menuitem"]');
await item.waitFor();
expect(await item.allTextContents()).toEqual(["Stop only this command"]);
await item.hover();

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 test never activates the Stop menu item: hovering only verifies highlighting, so a broken stop handler still passes despite the test claiming that the menu stops the command. Add an observable harness callback and click or keyboard-activate the item before asserting the callback.

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/test/running-strip.test.ts, line 118:

<comment>This test never activates the Stop menu item: hovering only verifies highlighting, so a broken stop handler still passes despite the test claiming that the menu stops the command. Add an observable harness callback and click or keyboard-activate the item before asserting the callback.</comment>

<file context>
@@ -91,27 +92,30 @@ await requireBrowserLane("running-strip.test.ts", async () => {
+      const item = page.locator('[role="menu"] [role="menuitem"]');
+      await item.waitFor();
+      expect(await item.allTextContents()).toEqual(["Stop only this command"]);
+      await item.hover();
       expect(await filled(page)).toEqual(["acpmux-agent-line"]);
     } finally {
</file context>

parsed.current = { key, repository, prs: transcriptPullRequests(rows, { folder: repository, replies: false }) };
}
const all = parsed.current.prs;
return useMemo(() => visibleChanges(all, headerStatus(live)).reverse(), [all, live]);

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 reverses first-discovery order instead of using each PR's latest touched position, so revisiting an older PR can place it below a newer one and disagree with Session Info. Sort with the shared Changes ordering so the shortcut follows most-recently-touched and open/ended ordering.

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/summary/PullRequestStack.tsx, line 90:

<comment>This reverses first-discovery order instead of using each PR's latest `touched` position, so revisiting an older PR can place it below a newer one and disagree with Session Info. Sort with the shared Changes ordering so the shortcut follows most-recently-touched and open/ended ordering.</comment>

<file context>
@@ -0,0 +1,291 @@
+    parsed.current = { key, repository, prs: transcriptPullRequests(rows, { folder: repository, replies: false }) };
+  }
+  const all = parsed.current.prs;
+  return useMemo(() => visibleChanges(all, headerStatus(live)).reverse(), [all, live]);
+}
+
</file context>

Comment on lines +65 to +67
tray
? "Both PRs are open. Nine subagents are still checking in the background."
: "Both PRs are open and the checks are done.",

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 no-PR variants still display an assistant reply saying both PRs are open, even though prs: false removes them. Make the reply depend on prs so these gallery states accurately represent the data they test.

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/bottomStackStyles.gallery.ts, line 65:

<comment>The no-PR variants still display an assistant reply saying both PRs are open, even though `prs: false` removes them. Make the reply depend on `prs` so these gallery states accurately represent the data they test.</comment>

<file context>
@@ -0,0 +1,190 @@
+        : []),
+      ...(tray ? [row(SUBAGENTS, 12, { subagents: agents })] : []),
+      assistant(
+        tray
+          ? "Both PRs are open. Nine subagents are still checking in the background."
+          : "Both PRs are open and the checks are done.",
</file context>
Suggested change
tray
? "Both PRs are open. Nine subagents are still checking in the background."
: "Both PRs are open and the checks are done.",
prs
? tray
? "Both PRs are open. Nine subagents are still checking in the background."
: "Both PRs are open and the checks are done."
: tray
? "Nine subagents are still checking in the background."
: "The checks are done.",

teamleaderleo and others added 2 commits November 1, 2026 03:17
…d again

Red at this commit: the tray keeps the line's taken Stop as "stopping" after the run ends, so the
resumed run's Stop stays off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
…top again

The tray kept a line's Stop as "stopping" after its run ended, so a subagent that ended and resumed
while the tray stayed mounted had its Stop off for good. When the tray's lines change, a Stop whose
line no longer can stop (it ended, or left) is dropped. One stopKey names a line's Stop for both.

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

@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.

1 issue found across 2 files (changes from recent commits).

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/subagents/SubagentTray.tsx">

<violation number="1" location="webviews/src/agent-session/acpmux/subagents/SubagentTray.tsx:217">
P2: A late failure from an earlier Stop request can update a resumed run because both runs reuse the same `stopKey`. Track the stop request/run generation and ignore completions from prior runs before calling `mark("failed")`.</violation>
</file>

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

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

if (stops.size > 0) {
const stoppable = new Set(items.map(stopKey).filter((key): key is string => key !== undefined));
if ([...stops.keys()].some((key) => !stoppable.has(key)))
setStops((current) => new Map([...current].filter(([key]) => stoppable.has(key))));

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: A late failure from an earlier Stop request can update a resumed run because both runs reuse the same stopKey. Track the stop request/run generation and ignore completions from prior runs before calling mark("failed").

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/subagents/SubagentTray.tsx, line 217:

<comment>A late failure from an earlier Stop request can update a resumed run because both runs reuse the same `stopKey`. Track the stop request/run generation and ignore completions from prior runs before calling `mark("failed")`.</comment>

<file context>
@@ -198,6 +209,13 @@ export const SubagentTray = memo(function SubagentTray({
+    if (stops.size > 0) {
+      const stoppable = new Set(items.map(stopKey).filter((key): key is string => key !== undefined));
+      if ([...stops.keys()].some((key) => !stoppable.has(key)))
+        setStops((current) => new Map([...current].filter(([key]) => stoppable.has(key))));
+    }
     const keys = new Set([...items.map(itemKey), ...finished.map(itemKey)]);
</file context>

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex-review-box/gpt-6-astra high, lane-place): SHIP at 8cb59b1

SHIP at 8cb59b1

Visual verdict: SHIP. Viewed all 16 after/alternative images. Against Claude’s compact composer layout, the selected design is restrained and aligned; no repeated row controls, bloated menus, or off-screen layout appear.

  1. [P2] [follow-up] webviews/src/agent-session/acpmux/subagents/SubagentTray.gallery.ts:389 — Supply current-head screenshots of the expanded tray and row-menu state. Existing images omit the latest Stop-menu changes.

No blocking code findings. All 14 changed TypeScript files parse; diff consistency and catalog checks pass. Runtime tests were unavailable because Bun and dependencies are absent.

Follow-ups:

  • Capture the current-head expanded tray and Stop menu.

…rrow line

9e2dc28 moved the tray line's Stop into its context menu, so the short-dock test now measures the
running line's button instead of the Stop button. A narrow line is two rows (56px at scale 1: its
time and state wrap under its name), but the test grew the dock by two header heights, of which
the squeezed composer took back ~31px, leaving the list a one-row (27px) viewport. The old 22px
Stop fit in it; the whole line cannot, so scrollIntoViewIfNeeded could not bring it inside the
list and its center (the right-click point) sat over View all. The tray layout is unchanged from
before 9e2dc28; the test now grows the dock until the list holds the whole running line and
asserts that before measuring.

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

teamleaderleo commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator Author

Review (the owner lane's independent review, at its land request): SHIP at 1f99ce0

Recorded by lane-gh-broker from this PR's owner lane, which asked to land this exact head after its independent review. next-autoland lands it once every red is the base's; a BLOCK at this head, a HOLD line or a hold label still stops it.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Awareness note from an agent lane that does not own this PR; it is not a review or a request to take the PR over.


Settled (claude-sr2-coord, 2026-11-01): Leo answered "remove the things", so #29614 stands. This PR should drop the compact "N PRs" chip control from its scope and keep only the bottom-stack glass. Owner: please remove that part before landing.

teamleaderleo and others added 2 commits November 1, 2026 05:10
The coordinator's ruling relays Leo: "remove the things", so the removal in
#29614 stands. This takes the compact "N PRs" count, its chip list
(summary/PullRequestStack.tsx), the prDock.count/countOne/label strings,
their CSS, gallery variants and tests out of this PR. What stays is the
glass that joins the running tray and the composer, plus Stop in a tray
row's right-click menu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
@teamleaderleo teamleaderleo changed the title Agent pane: the bottom stack on one edge as one glass, with a compact N PRs control back Agent pane: the bottom stack on one edge as one glass, Stop in the tray row's menu Nov 1, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex-review-box/gpt-6-astra high, lane-place): SHIP at 868e4f8

SHIP at 868e4f8

Visual verdict: reviewed all 20 images against ChatGPT/Claude’s compact composer layout. Supplied after images pass; current-head screenshots are missing. Leo tries the build.

  1. [P2] [follow-up] review/pr.body:22 — Refresh the description and screenshots: they advertise PR controls removed at this head and omit the new Stop context menu. Capture the current collapsed, expanded, and menu states.

No blocking code findings. All 13 changed files passed syntax parsing. Runtime tests were unavailable because Bun and project dependencies aren’t installed.

Follow-ups:

  • Refresh the PR description and screenshots for this head, including the Stop menu.

@teamleaderleo
teamleaderleo merged commit fe81446 into feat-cmux-next Nov 1, 2026
184 of 193 checks passed
@teamleaderleo
teamleaderleo deleted the lane/ux-bottom-stack branch November 1, 2026 09:44
teamleaderleo added a commit that referenced this pull request Nov 1, 2026
…Session Info (carry #28580) (#28617)

* cmux NEXT: the mode menu lists only the modes; grants are revoked in Session Info

Leo, 2026-10-29: "What the hell is this? Why the fuck is this? Grant access,
trust this. What is this bottom fucking bullshit? ... It's not fucking good."

The composer's permission-mode menu drew a "Granted access" section under the
modes (a "Trusted <folder>" row and an "Allow for this chat" row, each with an
x), added in #20339. The menu now lists the modes alone. The two grants move
to Session Info's Environment section as rows with Revoke, through the same
callbacks (folder trust undo, chat.permission_chat.revoke). Chats that offer
no modes no longer draw a lock-only Access chip for a grant.

Removes access-grants-columns.test.ts (#27579), which measured only the
section's columns, and the LockIcon left without a caller.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Agent-Session: https://cmux.com/deeplink/agent?id=aid-f2206f5448805d85f14b

* cmux NEXT: Environment gallery shows grants with Revoke; drop stale grant comments

Adds the Environment gallery's granted variant (folder trust and a chat
allowance, each with Revoke), updates three comments that still placed grants
in the mode menu, and removes the now-unused permission.grants string.

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

* cmux NEXT: grants stay revocable from the chat menu; Session Info's Revoke shows on its row's hover

Review of #28617 at 617a991 (P1): with default settings Session Info is off (Debug Settings
`agent.inspector`), and once trust is decided the trust bar is gone, so a trusted folder had no
visible way back. The chat menu (…), in every chat, now ends its tools rows with Revoke Granted
Access when the chat has grants: a submenu naming each one (the folder's trust, a chat-wide
allowance), whose pick revokes it through the same callbacks. Never the composer's mode menu
(Leo, 2026-10-29: "What is this bottom fucking bullshit?").

header/grantsMenu.ts builds the grants once for both places. chat-menu-revoke-access.test.tsx:
with Session Info off and a decided trust grant, the chat menu lists the grant and picking it
revokes (red with no row, green with it).

P2: Session Info's Environment shows a grant's Revoke only while that row is hovered or holds
focus, at once with no fade, as the pull request chips' x does (#28533); it stays in the Tab order.

Gallery: header-tools `menu-revoke-access`; environment-save `granted-hover`. The design-token
baseline shrinks by the access-grants height the first commit removed.

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

* test(session info): only the hovered or focused grant row shows its Revoke

Pins inspector.css: a grant's Revoke is transparent at rest and lights only on
its own row's :hover/:focus-within (456cd87), so a list of grants never
repeats a lit Revoke on every row.

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

* style(test): format inspector-grant-revoke-hover.test.ts (vp fmt)

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

* fix(next): exempt the grant row's plain Revoke from the popup hover-reveal check

Revoke is a plain button that revokes on click and opens no popup, so it needs no
:has([data-popup-open]) twin; check:popup-hover-reveals was red at 2dc4161.

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

* test(session info): the grants test calls renderSessionInfo after the rename (#29921)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: cmux-bot[bot] <348531757+cmux-bot[bot]@users.noreply.github.com>

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 868e4f89 Deployed Nov 1, 2026 by teamleaderleo via wait for same-key tree publisher #93848
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