cmux-next project picker: worktrees fold under their repository; repo icons, avatars and language glyphs

Merged
TE
15d ago
+1573-90

The composer's folder popover listed every git worktree as its own project (agent-caller-…, issue-22273-…), each with a letter tile. Now it shows one row per repository, with that repository's other worktrees folded one level under it.

  • Host: project.list now carries repos: for each listed folder, its main checkout, repository name, branch and GitHub origin. They are read from the .git files directly (no git process) and pass the existing privacy check (AgentPaneProjectRepo.swift).
  • Popover: one row per repository. → or clicking the worktree count expands its worktrees. A search lists a worktree when the words match its name or branch (projectRepos.ts, FolderPopover.tsx).
  • Badges: use the folder's own icon, then the main checkout's icon, then the GitHub owner's avatar (cached for a week), then a language or framework glyph, and last the letters, colored from the repository name.
  • Gallery: new states for a repository with worktrees (collapsed, expanded, searched) and for the path-guess fallback.

Review fixes (e74e4d3):

  • A main checkout in a hidden folder (~/.dotfiles) is its own root; before, it took its parent's.
  • A submodule is rooted at its own folder, not at its Git folder inside .git/modules.
  • A folder inside a checkout is named by its path below it ("cmux · web"); before, it took the checkout's branch.
  • ← collapses worktrees only from the repository's own row, so the highlight never disappears.

Follow-ups (not in this PR):

  • A folder the host didn't list falls back to a guess from its path, and the guess can split one repository into two rows.
  • The GitHub owner avatar fetch (github.com only, owner name validated, off the main actor) has no setting to turn it off.
  • A checkout opened through a symlinked path doesn't group with its worktrees.

Before/after (Linux gallery, agent-pane.composer-context)

Left: merge-base 437fdda (each worktree is its own project). Right: this PR (worktrees grouped under their repo, branch dimmed, React/Rust glyphs).

before and after

Expanded cmux row, branches listed most recent first:

after expanded

Searching "unread" matches a worktree branch under its repository:

after search

Changelog

Changed: The agent composer's folder picker groups git worktrees under their repository and shows repository icons, owner avatars or language glyphs.

Observed / Not run

  • Observed: on big-red, the webviews/ typecheck passed and lint had 0 errors. The only format red also fails on the feat-cmux-next tip. The pre-push gates passed.
  • Observed: bun test src/agent-session/acpmux/projectRepos.test.ts 8 pass at e74e4d3.
  • Not run locally: the Swift build and AgentPaneProjectRepoTests/AgentPaneProjectIconTests (Mac compiles run on CI, not on this Mac). Also not run: projectRepos.test.ts, and the new browser test in composer-location-strip.test.ts, which needs CMUX_BROWSER_TESTS=1. CI on this head covers these.

Agent session: cosmic-gray

🤖 Generated with Claude Code