Skip to content

perf(desktop): run the CLI from the macOS app binary instead of shipping a second engine copy - #2762

Open
richiemcilroy wants to merge 1 commit into
mainfrom
perf/macos-single-engine-cli
Open

richiemcilroy wants to merge 1 commit into
mainfrom
perf/macos-single-engine-cli

Conversation

@richiemcilroy

@richiemcilroy richiemcilroy commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

What

The macOS bundle shipped the recording, rendering and export engine twice: in Cap (56 MB) and in cap-cli (36 MB), a separately linked build of the same crates.

Cap is now also the CLI on macOS:

  • Cap --cap-cli <args> hands the arguments to the cap crate as the very first thing main() does, before logging, single-instance, menus or any window.
  • Contents/MacOS/cap-cli becomes a small std-only launcher (crates/cli-launcher). It resolves its own path (through a shim symlink), then execs the sibling Cap with --cap-cli, keeping the caller's argv[0] so help and usage still read cap.
  • Existing shims (~/.cap/bin/cap -> …/Contents/MacOS/cap-cli), cap desktop install-cli, Settings → CLI and the Feedback self-test keep the same path.
  • The CLI runs in its own process, so it still gets the process main thread (the A/V self-test's winit window needs it).

Supporting changes:

  • apps/cli: main.rs moves verbatim to lib.rs. run_main(args) is the old main with Cli::parse_from, run_embedded marks the process as embedded, and the bin's main.rs calls run_main(std::env::args_os()).
  • record start --detach: it re-spawns the CLI, so that now goes through cli_command, which adds --cap-cli when embedded. Otherwise the detached worker would have launched the GUI.
  • Release build: scripts/build-desktop-binaries.sh builds the launcher as cap-cli on *-apple-darwin and no longer compiles the separate CLI binary there, which also shortens the macOS release build.
  • Windows and Linux are unchanged:
    • Windows: a GUI-subsystem Cap.exe has no console to print to, so it keeps the standalone CLI.
    • Linux: the AppImage already routes the CLI through its own --cap-cli launcher.

Proof

  • CI (build-gpui, both macOS runners), new step "Test the macOS CLI launcher":
    • builds cap-gpui and the launcher, laid out as Cap.app/Contents/MacOS/{Cap,cap-cli} with the FFmpeg framework;
    • runs cap-cli --version and project --help, then desktop install-cli into a throwaway HOME;
    • checks the shim points at cap-cli, cap --version works through it, and desktop status reports installed;
    • each command has a 60 s watchdog, so a dispatch that started the GUI would fail CI instead of hanging.
  • Release (desktop-release.yml): after verifying signatures, the signed bundle's cap-cli --version must print cap ….
  • The CLI's record tests moved from --bin cap to --lib.

Size (macOS, measured)

Release builds on a Blacksmith macOS runner (aarch64-apple-darwin, stripped exactly as the release does). Measured with a scratch workflow that built origin/main and this branch side by side; cap-cli --version ran through the launcher on both.

main this PR
Cap 58,745,600 B 71,846,208 B
cap-cli 37,559,296 B 352,608 B
cap-muxer 1,083,632 B 1,083,632 B
Cap + cap-cli 96,304,896 B 72,198,816 B (−24.1 MB, −25%)

Cap grows 13.1 MB with the CLI-only code (clap, the MCP server, keyring, the self-test window, the API client), which is still 24 MB less than shipping the engine twice.

@vercel

vercel Bot commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
cap-status Ready Ready Preview Oct 20, 2026 12:36pm UTC

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

Capy found no issues.

View 1 other finding in Capy.

Open in Capy

This branch was successfully deployed

2 active deployments
Preview – cap-web — 98dce350 Deployed Oct 20, 2026 by vercel[bot]
Preview – cap-status — 98dce350 Deployed Oct 20, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant