cmux-next project picker: framework brand marks and a folder fallback

Merged
AU
10d ago
+588-110

What

The project pickers (composer folder menu, New Tab strip, folder popover) now show what kind of project each one is, the way Codex and Cursor do:

  1. The GitHub owner's avatar, so every clone and worktree of one repository wears the same picture (feat-cmux-next's order since Leo 2026-10-21; kept on merge).
  2. Otherwise the project's own favicon / app icon, in the folder or its repository's main checkout.
  3. Otherwise its framework or language, as the real brand mark in its brand color. The host now reads package.json dependencies (parsed as JSON, not substring-matched) and picks the most specific framework: Next.js, Nuxt, Remix, Astro, then the app shells Expo, Electron and Tauri (a React Native app without Expo shows React), then Svelte, Angular, Vue, React, then Vite. Without one of those it falls back to Bun, TypeScript or Node. Other projects are detected from their own files: Swift (Package.swift or an .xcodeproj/.xcworkspace), Rust, Deno, Flutter/Dart, Python, Go, Ruby, Zig, Elixir, PHP, Kotlin, Java and C++.
  4. Otherwise a muted folder icon instead of the colored two-letter tile ("CH", "FC", "A2"…).

Every badge now sits on the same neutral tile, and no badge wears a corner mark (feat-cmux-next's rule).

The marks are the Simple Icons paths (simple-icons 16.35.0, CC0 1.0), generated into projectGlyphs.tsx, except Rust and Next.js: their official marks blur at 14 px, so Rust is drawn as an 8-tooth gear around its R, and Next.js as a thin ring around its N instead of a filled disc. Black brand colors (Next.js, Bun, Rust, Deno) use the text color so they show up in both themes. Brand colors too dark for a dark tile (Java, Elixir, Flutter, C++) use the lighter color from their own logo.

Mac evidence: the new project-badges media tour (scripts/cmux-next/media/tours/project-badges.json) writes a Next.js app, a Rust crate, a folder with no manifest and a GitHub checkout, picks each in a real agent chat and opens the Location menu, in light and dark, on an owned Mac for the exact head; plus the gallery advisory run's agent-pane.composer-context/framework-marks and folder-favicons states. The Swift change is host detection logic with no UI of its own.

Takes back #22724: on purpose. Its glyph tile was tinted with the brand color, which left React's cyan faint on a light tile (visual review on this PR). Every badge now shares the neutral tile and the mark carries the brand color mixed toward the text color (https://github.com/manaflow-ai/cmux/pull/22724).

Gallery: agent-pane.composer-context/framework-marks, agent-pane.composer-context/folder-favicons, agent-pane.composer-context/repo-worktrees, agent-pane.composer-context/folder-menu, agent-pane.project-chooser

Tests

  • webviews/src/agent-session/acpmux/ProjectBadge.test.tsx: folder fallback, brand mark and color, an unknown glyph falls back to the folder (plus the existing favicon, remote and retry cases).
  • AgentPaneProjectRepoTests: theDependenciesNameTheFramework (Next over React, React over Vite, Vite alone, Vue, SvelteKit, Expo, prose that mentions "react" is not a dependency, Tauri, Bun, broken JSON, an Xcode project, Flutter, Zig, React Native without Expo shows React) and theOwnersAvatarComesWithTheFrameworkMark.
  • Gallery: new agent-pane.composer-context/framework-marks variant with one project per kind and one with no manifest.

šŸ¤– Generated with Claude Code