Repository navigation
Description
Summary
Bundle a self-contained tmux binary inside packaged Agent Code so terminal-persistence (the tmux-backed terminal pane mode) works on user machines without any Homebrew install. Sibling to #119 (mitmdump bundling); both use the same third_party/ + runtimeTools pattern.
Why
tmux is currently optional but it is the only reason terminal panes survive app restarts. Requiring Homebrew for it makes setup heavier and means packaged users on stock macOS lose terminal persistence silently. The Homebrew tmux binary also dynamically links three Homebrew dylibs (libevent_core, libncursesw, libutf8proc), so we cannot just copy /opt/homebrew/bin/tmux — it will fail on a clean machine.
Decision
Build a fully static tmux at release time. Final artifact is a single ~1.5–2 MB executable with no external dependencies.
The alternative — copying the Homebrew binary plus its dylibs and rewriting install_names — was considered. Rejected: bigger (~5 MB), more moving parts, easier to break under codesigning. Documented in this issue only as a fallback if the static build hits an unsolvable snag.
Repo layout
Committed:
third_party/tmux/
manifest.json # tmux version + dep versions + per-arch sha256
README.md
LICENSE.md # ISC
.gitignore # ignores cache/, build/
scripts/runtime-tools/
build-tmux.mjs # downloads pinned libevent/ncurses/utf8proc/tmux sources, builds static
verify-tmux.mjs
bump-tmux.mjs # optional
Not committed:
third_party/tmux/cache/ # final static tmux binary per arch
third_party/tmux/build/ # transient build inputs/outputs
Manifest shape
{
\"tool\": \"tmux\",
\"version\": \"3.6a\",
\"build\": \"static\",
\"deps\": {
\"libevent\": \"2.1.12-stable\",
\"ncurses\": \"6.5\",
\"utf8proc\": \"2.10.0\"
},
\"platforms\": {
\"darwin-arm64\": { \"sha256\": \"...\" },
\"darwin-x86_64\": { \"sha256\": \"...\" }
}
}Resolution order at runtime
process.env.AGENT_CODE_TMUX- Bundled static tmux copied from
out/main/runtime/tmux/<os>-<arch>/tmuxintouserData/runtime/tmux-<ver>/tmuxon first use (chmod +xon copy) - Setup-cached PATH path
- PATH lookup
- Typed error with diagnostics
Setup gate
When bundled tmux exists, setup must show it as Bundled with Agent Code and stop prompting for install. Homebrew install path stays available for dev.
Packaging
- Extend
scripts/copy-packaged-resources.mjsto copythird_party/tmux/cache/<os>-<arch>/tmuxintoout/main/runtime/tmux/<os>-<arch>/tmux. electron-builder.ymlkeepsout/main/runtime/**/*inasarUnpack(same line covers both tools).- CI release:
npm run runtime:build:tmuxruns on a macOS runner, cachesthird_party/tmux/cache/keyed by sha256 ofmanifest.json.
Acceptance
- Packaged Agent Code spawns tmux-backed terminal panes on a machine with no Homebrew and no tmux on PATH.
- Persistence across app restarts works as today.
- Setup gate stops asking for tmux in packaged builds.
tmux -Vfrom the bundled binary returns the pinned version.otool -L bundled/tmuxshows no Homebrew dylib references.
Size impact
Packaged app grows by ~2 MB total (one static binary per arch). Git repo size: unchanged.
Related
- Bundle mitmdump with packaged app #119 Bundle mitmdump with packaged app — same
third_party/andruntimeToolspattern.
Activity