cmux NEXT project picker: a lane's worktree folds under its repository; the agent chat's picker in the gallery with app icons
Leo, on the agent chat's project picker: "why is this all misaligned in the agent chat project selectin"
His picker (the new chat hero's "Choose project", EmptyState -> ProjectChooser) had two problems: the ā and + glyphs and their titles were off the project rows' icon and text columns, and two lanes' worktrees (~/wt/lanes/<lane>/cmux) were listed as two more "cmux" projects.
Alignment: already fixed by #28590. The hero uses the same ProjectChooser and the same .acpmux-project-menu popup that #28590 fixed (one 16px icon box at 8 for every row, no tile, every title at 32). His nightly was about 30h old, from before #28590. This PR adds the screenshot's state to the gallery, with app icons, and holds it to picker-row-geometry.test.ts.
Worktree noise: fixed here. No row and no option is removed.
wt/lanes/<lane>/<repo>is now a worktree home the pickers know (guessProjectRepo, beside.cmux/worktrees,checkouts/,-worktrees/, Conductor and Codex). A lane folder the host read no repository for now joins its repository, as a linked worktree the host did read already does.ProjectChooserbuilds its rows withchooserRows(projectRepos.ts):- with no search, one row per repository, its lead, as
projectRowsdoes for the other flat pickers (the current folder, else the main checkout, else the newest). The home folder and scratch folders are left out unless current; - with a search, a repository's other folders show when the words name them (
shownRepoRows): "cmux" lists cmux once, "next-reds" finds that lane's worktree. So a hidden worktree is one search away; - another machine's folders are never folded (this Mac reads none of their repositories) and come last, as before.
- with no search, one row per repository, its lead, as
- The hero now hands the chooser every folder instead of pre-folding them with
projectRows, so the search can find them. The New Tab page's and headline's choosers get the same folding. - Neither design/composer.md nor design/new-tab.md says how the project picker treats worktrees, so per the brief they're hidden and reachable by search. The composer strip's folder popover (
FolderPopover, its expandable worktrees) is unchanged.
Measured (gallery agent-pane.project-chooser, CSS px from the menu's left edge)
Every row of the agent chat's picker, at base and at this head, light and dark (open-app-icons: Do not work in a project checked, New project, three projects with 16px app icons):
| Row | Icon box (left + width) | App icon image | Text starts at |
|---|---|---|---|
| ā Do not work in a project | 8 + 16 | 32 | |
| + New project | 8 + 16 | 32 | |
| atlas-web | 8 + 16 | 8 + 16 x 16, no tile | 32 |
| relay | 8 + 16 | 8 + 16 x 16, no tile | 32 |
| Projects | 8 + 16 | 8 + 16 x 16, no tile | 32 |
Base and head are pixel-identical for this state (same PNG bytes), so #28590 covers the alignment and this PR doesn't change it.
Lane worktrees (lane-worktrees): at base the list showed cmux /Users/sample/wt/lanes/lane-adopt/cmux, cmux /Users/sample/wt/lanes/next-reds/cmux, cmux /Users/sample/Projects/cmux and Projects. At this head it shows cmux /Users/sample/Projects/cmux and Projects. Typing next-reds lists cmux /Users/sample/wt/lanes/next-reds/cmux. Every row in both states: icon 8 + 16, text 32.
Stills (2x, light and dark, synthetic /Users/sample/... paths)
| State | Light | Dark |
|---|---|---|
| App icons, at this head (same as base) | ||
| Lane worktrees, before (base) | ![]() | ![]() |
| Lane worktrees, after | ![]() | ![]() |
| Search "next-reds", after | ![]() | ![]() |
Viewed after image: in app icons light, ā, +, and the blue, orange and dark app icons sit in one column, and every title starts on one line, with a hairline under New project. In lane worktrees dark, only cmux (/Users/sample/Projects/cmux) and Projects are listed under the actions. In search light, "next-reds" lists only the next-reds cmux worktree, highlighted.
Tests
webviews/src/agent-session/acpmux/projectRepos.test.ts: the chooser lists one cmux row for twowt/lanesworktrees and the main checkout; the current worktree leads its row; "cmux" lists it once, "next-reds" finds the lane, "wt/lanes" finds both; a linked worktree the host read folds wherever it lives; another machine's folder stays.webviews/test/picker-row-geometry.test.ts: adds the agent chat's picker with app icons (open-app-icons) and with lane worktrees (lane-worktrees), light and dark, at fail level.
On the org's Linux runners at 078b5796b49747f6ea8a62542c0d4cddb8cb283e (run 41159705056, exit 0): bun test test/picker-row-geometry.test.ts src/agent-session/acpmux/projectRepos.test.ts test/composer-location-strip.test.ts: 70 pass, 0 fail, including the four new agent chat picker cases and every sibling picker case.
Observed / Not run
- Observed locally:
bun testfor projectRepos, project-chooser-empty, composer-searchable-pickers, project-suffix and new-tab-minimal-default (58 pass);vp checktype check clean;vp fmtandvp linton the changed files. - Not run: WebKit stills, a native build (webview-only change).
Spec: neither leo-workspace design/composer.md nor design/new-tab.md covers worktrees in this picker; the row geometry follows design/grid.md 5.3, as #28590 does.
Prior art: #28590 (merged, the alignment: this PR builds on it and doesn't touch its CSS), #23892 and #22724 (merged: one row per repository, worktrees fold under it; this extends that to the chooser itself), #26636 (closed, unmerged: a scratch-folder rework of groupByRepo), #27616 (draft: the shared menu grid; no overlap with these lines).
Risk: low. Which rows a project chooser lists with no search; every folder is still reachable by search, and Browse and New project are unchanged.
Changelog
- Fixed: The agent chat's project picker no longer lists each lane worktree of a repository as a separate project; search finds them.
Agent session: agent session
š¤ Generated with Claude Code





