Repository navigation
cmux-next sidebar: the footer becomes Back on a destination page - #18326
Conversation
Leo's T3 Code ref: while the window shows a full-page destination, the footer becomes one wide Back button in the same spot, and Back returns to the workspace the window showed. Home keeps the footer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
While the window shows a full-page destination (a top page other than Home), the sidebar's footer band gives way to one wide Back button in the same spot. Back leaves the page for the workspace the window showed. The window root reports each content swap, so Back follows pages, workspaces and a restored page alike. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Not verified: macOS jobs did not run: compile and app tests were skipped on CI passes on Written by |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 3d63ba6. Configure here.
| action = #selector(pressed) | ||
| refusesFirstResponder = true | ||
| _ = hover | ||
| } |
There was a problem hiding this comment.
Back button hover never appears
Low Severity
SidebarBackButton creates a ChromeHover for the chrome hover look, but it never installs tracking areas or forwards mouse entered, exited, or pressed into that hover. The fill stays idle, so the wide Back control has no hover or pressed feedback.
Reviewed by Cursor Bugbot for commit 3d63ba6. Configure here.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PaneController (all extensions) had grown to 1013 lines, over the 1000-line god-type budget, failing the cmux-next godfile check on feat-cmux-next. PaneBrowserTabOpener now owns opening a browser tab in a pane: engine resolution, opener placement, popup adoption and the session-local WebKit fallback guard (allowsSessionLocalTab). PaneController.newBrowserTab stays the entry point and forwards to it, so callers and behavior are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
updateLayer set the image and title, which marked the button for display again, so every Core Animation commit drew it again and the test run hung. Style it on init, window moves and appearance changes instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Red/green for the swift test hang on dacfb46:
The earlier fleet red step for this PR failed on the since-fixed base compile break in |
…calhost (red) browser.tab.open from the Cloud page: only CEF, only the local HTTP proxy on 127.0.0.1, only from the Cloud page, a derived store key, typed refusal codes, and the store kept across wake, reroute and relaunch. WebKit and the engine registry refuse a machine store with a typed error. C++: the per-profile proxy is fixed_servers on http://127.0.0.1:<port> with bypass_list exactly "<-loopback>" (scripts/cmux-next/test-context-proxy-cpp.sh). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nly through its proxy, only in CEF
- browser.tab.open, a host action of the Cloud page (cmux.app.action.run):
{url, machineStore: {machine, machineName, proxy: {kind, host, port}},
engine: "cef"}. Only the Cloud page may hand over a proxy (the page id
comes from the page host); only CEF; only an HTTP proxy on exactly
127.0.0.1 with a port 1..65535; only an http(s) loopback URL. The store
key is derived in the app: 16 lowercase hex digits of SHA-256 over
"cmux.cloud.browser-store.v1:" + machine id. Typed refusals:
cmux.browser.proxy_requires_cef, proxy_invalid, proxy_origin_refused,
cef_unavailable, invalid_url, no_window. No fallback: the Chromium page is
made with its store (navigation guard loopbackOnly), then a blank daemon tab
adopts it.
- ProxiedBrowserTabs keeps the store with the tab for its whole life: wake,
store reroute and history-page exit get it back through the cache's
configuration hook; popups with the same store are recorded; WebKit pages
of a proxied tab load nothing; Open in WebKit is refused; after a relaunch
(proxy gone) the tab stays blank.
- Fail closed in the engine layer: WebKitEngine.makeTab and
makeWebKitTab(_ configuration:) throw
BrowserEngineError.machineStoreRequiresChromium for a machine store, the
engine registry opens a machine store only in CEF, and the WebKit call
sites use makeWebKitTab(id:profile:initialURL:zoom:), which cannot carry
one.
- The shim's per-profile proxy values come from context_proxy_policy.h
(fixed_servers, http://127.0.0.1:<port>, bypass_list "<-loopback>").
Ported from feat-cmux-next-tabopen (cf70cac) onto the current
feat-cmux-next: shim_proxy.mm includes both agent_url_policy.h (added on
the trunk since) and context_proxy_policy.h. Test call sites the trunk added since
(CertificateRecheckBeforeCommit, CertificateWarningRevoke, LinkClickDisposition,
SaveAsFailure, WebKitFrameRate, WebKitPasskeyAuthorization) use
makeWebKitTab(id:profile:initialURL:zoom:), like the branch's own call sites.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…is Mac's localhost debug.page gains a `call` action: one call message through the page's router, exactly as the page's bridge sends it (the host sets the calling page's id); with page cmux.cloud and no live Cloud page, a hidden one is made first (the app has no Cloud page entry yet). DEBUG builds only. scripts/cmux-next/proxied-tab-e2e.py (fleet GUI host only) starts a listener on 127.0.0.1 and ::1 and a stand-in machine proxy, launches the tagged app without activation, checks the typed refusals, opens browser.tab.open on http://localhost:<listener port>/ through the proxy, and passes when the proxy saw the request and the listener saw no connection. Ported from feat-cmux-next-tabopen (8352bcd) onto the current feat-cmux-next: debug.page keeps the trunk's `click` and `type` actions beside the new `call` action. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rectly The bundled cmux CLI is the Rust binary and has no --socket option. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on from this Mac (red) The live check (scripts/cmux-next/proxied-tab-e2e.py on cmux-lawrence-2) saw GET /favicon.ico on this Mac's ::1 listener: the page and its favicon went through the machine proxy, then the app's own favicon fetch went to this Mac. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…is Mac BrowserFaviconPolicy: a tab with a machine store (remote localhost or a Cloud proxied tab) names loopback icons of that machine, so neither the CEF tab's own favicon fetch nor the tab strip's fetch loads them in the app process (the tab shows a globe). Other icons load as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…b.open Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: Recents filters its chats by project Leo's T3 Code ref: one filter button (a filter glyph) over Recents opens a menu with All projects, then each project with a colored two-letter badge, and no search field of its own. The filter applies before the chat limit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: Recents filters its chats by project Once Recents' chats span two projects, a filter row above them names the shown project, and its filter button (a filter glyph) opens a menu of All projects and each project with a colored two-letter badge. There is no search field of its own. The filter is per window, applies before the chat limit, and clears when its folder has no chats left. The feed now notifies on any chat change, so a filtered list stays current. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: retrigger cmux-next on the fixed base Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: import the agent pane module for Recents' chat type Release builds without member import visibility leaks; AgentRecentsSection names AcpmuxRecentChat, so it imports CmuxNextAgentPane itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…8178) * test(cmux-next): the agent pane has no chat search of its own Decision K1: one palette. The page's Search chats overlay still opens on the searchChats command, so this fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(cmux-next): remove the agent pane's own chat search; Show all opens the palette Decision K1, one palette: the page's Search chats overlay is gone, and its Show all chats buttons run agentPane.searchChats, the command palette's chats page. The unused AgentPaneView.showSearchChats goes too. The agent pane bundle is rebuilt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: drop the removed Search chats overlay from the web test lists SearchChats.tsx is gone, so it leaves the ui-rules pending list and the gallery coverage allowlist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: retrigger cmux-next Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: regenerate the agent pane bundle after merging feat-cmux-next Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: retrigger on the fixed base Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: regenerate the agent pane bundle after merging feat-cmux-next Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
…before a feat-cmux-next merge #18326 grew a type past the god-file limit while an unrelated lint red hid the god-file step. Before a feat-cmux-next merge, gh-merge-green now merges the PR head into the current base locally and runs, on that merged tree: - the Swift god-file check (--only swift --base <base>) when the PR changes Packages/macOS/CmuxNext, using the base branch's copy of the script and baseline so a PR cannot loosen its own check; - vp check in webviews/ (bun install --frozen-lockfile --ignore-scripts) when the PR changes webviews/. A fork PR, a failed fetch, a moved head or a merge conflict refuses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l for feat-cmux-next merges (#18378) * test(gh-merge-green): a feat-cmux-next merge must refuse frozen paths (red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(gh-merge-green): refuse feat-cmux-next merges into frozen paths Before merging into feat-cmux-next, gh-merge-green reads the coordinator's WINDOW (cmux-lawrence:~/agent-mailbox/WINDOW) and refuses a PR that changes a path under any `FREEZE: <prefix> token=<t>` line. Only the freeze's holder merges into it, with --freeze-token; --override never lifts a freeze. A WINDOW that cannot be read refuses and says to check with the coordinator. Tests read a local WINDOW through GH_MERGE_GREEN_WINDOW_FILE. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(gh-merge-green): the merged head must pass the god-file check and vp check (red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(gh-merge-green): check the merged head's god files and vp check before a feat-cmux-next merge #18326 grew a type past the god-file limit while an unrelated lint red hid the god-file step. Before a feat-cmux-next merge, gh-merge-green now merges the PR head into the current base locally and runs, on that merged tree: - the Swift god-file check (--only swift --base <base>) when the PR changes Packages/macOS/CmuxNext, using the base branch's copy of the script and baseline so a PR cannot loosen its own check; - vp check in webviews/ (bun install --frozen-lockfile --ignore-scripts) when the PR changes webviews/. A fork PR, a failed fetch, a moved head or a merge conflict refuses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(gh-merge-green): a vp check red already on the base must not block a web PR (red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(gh-merge-green): a vp check red the base already has does not block a web PR When the merged head fails vp check, gh-merge-green checks the base tree with the same install and refuses only for files the base does not flag. A red already on the base is printed as a note naming its files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(gh-merge-green): a WINDOW token merge must mail RELEASE with the landed SHA (red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(gh-merge-green): mail RELEASE <AREA> with the landed SHA after a WINDOW token merge --window-token TOKEN (repeatable) and --freeze-token name the WINDOW tokens a merge lands under. Before merging, each must be current: an [AREA] section's token: or a hold line's token= (PKG ...). Right after the merge gh-merge-green reads the merge commit and writes a RELEASE <AREA>: #N landed <sha> mail to cmux-lawrence:~/agent-mailbox/inbox/lawrence-coordinator (atomic tmp + mv). If the mail fails, it exits non-zero and prints the text to send by hand. Lawrence's coordinator had missed a manual RELEASE mail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(gh-merge-green): a test run must never mail the real coordinator inbox (red) Two runs of the freeze-token test mailed fake RELEASE FREEZE: #42 into the real lawrence-coordinator inbox. Under test, or with a local WINDOW file, a token merge without GH_MERGE_GREEN_MAILBOX_DIR must refuse before merging and never run ssh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(gh-merge-green): tests can never mail the real coordinator inbox The freeze-token test ran with no mailbox override, so each run mailed a fake RELEASE FREEZE: #42 to the real lawrence-coordinator inbox over ssh. Now: - under GH_MERGE_GREEN_TEST, or with a local GH_MERGE_GREEN_WINDOW_FILE, a token merge without GH_MERGE_GREEN_MAILBOX_DIR refuses before merging, and the send site refuses again (fail closed); - under GH_MERGE_GREEN_TEST the WINDOW is never read over ssh; - the test module sets GH_MERGE_GREEN_TEST and a temp mailbox for every run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(gh-merge-green): a test helper crash the base also has is base-owned (red) A swift test whose test helper dies on a signal names different in-flight tests and crashed-thread frames each run, so the head's crash never matched the base's and gh-merge-green refused it without --override. Same signal on the base's latest verdict run means the base owns it; a crash the base lacks, another signal, or a pre-crash red the base lacks still blocks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(gh-merge-green): excuse a test helper crash the base also has base_red_excuse.py reads the signal a test helper died on from SwiftPM's "exited with unexpected signal code N" line or the hang sampler's "the test helper died on signal N" error. Those crash lines and the unfinished-test list are no longer compared, since they differ run to run; instead the base's job must have died on the same signal. Failed steps and any test red before the crash are still compared, and the audit line names the signal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>


Summary
While a window shows a full-page destination, the sidebar's footer becomes one wide Back button in the same spot, a universal way back to where you were (Leo's T3 Code reference).
How it works:
SidebarModel.showsBackandonBack. The sidebar view lays Back over the footer band's spot (SidebarView+Back).onContentChange).WindowControllersetsshowsBackfrom the shown top page, so Back follows pages, workspace switches and a restored page alike. Back runsleaveTopPage().Testing
SidebarFooterBackTests:onBack.SidebarFooterBackWiringTests:check-no-godfiles,check-concurrency,check-crash-safetyandcheck-l10npass locally.sidebar.footer.back("Back"), in all 21 locales, copied from the existing "Back" translations.Changelog
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Turns the sidebar footer into a wide "← Back" button while a window shows a full-page destination, giving a universal way back to where you were.
sidebar.footer.back, "Back") in all 21 locales, and tests cover layout, wiring, Home keeping the footer, and the button staying clean after drawing.Bug Fixes
updateLayer.Written for commit 1a93db0. Summary will update on new commits.
Note
Medium Risk
Proxy policy changes affect how remote browser profiles route traffic (including loopback); behavior is tested but still network-isolation sensitive. Removing Cmd-K search chats is a user-visible regression unless another entry point replaces it.
Overview
This PR bundles three unrelated areas: CEF remote-store proxy policy, recent-chat project scoping, and removal of the agent pane’s Cmd-K “Search chats” sheet.
CEF shim: Per-profile Chromium proxy settings (
fixed_serverstohttp://127.0.0.1:<port>withbypass_list<-loopback>) move into a CEF-freecontext_proxy_policy.h.shim_proxy.mmapplies that helper and usesContextProxyPortValidfor port checks. A standalonecontext_proxy_test.cpplocks the behavior in.Agent recents:
AcpmuxRecentChats.newestgains an optionalin project:filter (applied before the limit), plus aprojectslist derived from chat folders ordered by recent activity—supporting project-scoped recents in the app feed.Agent pane search: The dedicated search-chats overlay is dropped:
showSearchChats()/searchChatsbridge command, ~160 lines of.acpmux-search*CSS inindex.html, andsearch.*strings from locale bundles. Native action catalog entries for search chats may still exist elsewhere in the repo.Reviewed by Cursor Bugbot for commit 1a93db0. Bugbot is set up for automated code reviews on this repo. Configure here.