№ 0751GitHub
polyforge
A vim-modal multi-tab Rust TUI for coding agents where each tab is a session, fronting Muse Spark via muse serve alongside Codex, Antigravity and Grok backends.
polyforge
Vim-modal multi-tab TUI for coding agents.
One tab = one agent session. Built with Rust (ratatui + crossterm +tokio). Fronts five stdio backends:
| backend | wire |
|---|---|
muse |
Muse Spark via muse serve (MSP JSON-RPC) |
codex |
OpenAI Codex via codex app-server |
agy |
Antigravity via agy stream-json |
grok |
Grok via grok agent stdio (ACP) |
mock |
Offline fake for UI work (no quota) |
Prototype. Interaction model and agent wiring are the focus — not a
production client.
Full operator guide: docs/USER-MANUAL.md.
Run
cargo run
Needs a real tty (alternate screen + mouse). Inside tmux: wheel andCtrl-u/d scroll the TUI viewport — tmux copy-mode is never involved.
Keys
| mode | keys |
|---|---|
| NORMAL (default keys) | arrows line · PgUp/PgDn half-page · Home/End top/bottom · / search · n/N next/prev · Space/Enter insert · digits/Tab tabs · P provider · R fresh session · m mouse toggle · q quit |
NORMAL·vim (/vim) |
j/k line · Ctrl-u/d half-page · g/G top/bottom · Space/i/a insert (rest as above; Enter does nothing) |
| INSERT | type · ←/→ move · Enter send · Esc/Ctrl-[ normal · /sessions /new /tab new /tab close /vim /help commands |
| SEARCH | Enter find · Esc cancel |
| PICKER | j/k move · Enter switch · 1-5 quick · Esc cancel |
| SESSIONS | j/k move · Enter view + continue · d delete · 1-9 quick · Esc cancel |
| DIFF modal | y approve · n reject · a approve-all · q/Esc later |
Mouse: wheel = 3 lines, Shift+wheel = page. Drag across the transcript
to highlight; releasing copies via native clipboard + tmux buffer + OSC 52
(grok-CLI parity, always backed up to last-copy.txt). ● tab = busy
(streams in background), bell rings on done.
Config
~/.config/polyforge/config.toml (defaults to muse when absent):
[polyforge]
provider = "muse" # default backend: muse | codex | agy | grok | mock
# workspace = "/path" # default: cwd
# vim = false # vim keymap (j/k/g/G/i/a); toggled live with /vim (saves here)
[muse]
# bin = "muse"
# provider_id = "meta" # or "echo" for offline dev
# model = "muse-spark-1.2" # omitted = server default
[codex]
# bin = "codex"
# model = "gpt-5.6" # omitted = server default
[agy]
# bin = "agy"
#





