Nullwire is a fast, terminal-native Codex harness for running and observing multiple Codex workloads from one WezTerm tab.
The left pane is a Ratatui workload hub. The right pane is the currently focused Codex terminal session. Each workload keeps its repository, resumed thread, and subagent activity separate behind its own loopback-only Codex app-server.
- One native binary with no Node.js runtime
- Deterministic full-frame terminal rendering
- Low idle overhead
- Explicit process and terminal cleanup
- Typed app-server protocol handling
- Rust 1.84 or newer
- Codex CLI 0.145 or newer
- WezTerm
- tmux 3.2 or newer
cargo build --releaseRun the binary from a WezTerm pane:
./target/release/nullwireAfter installation, the existing th Fish abbreviation launches Nullwire.
Nullwire remembers the exact workload set from the most recently closed run and the last Codex thread attached to each workspace. On the next launch, the restore screen lets you choose the workloads for the new harness:
| Key | Restore action |
|---|---|
↑ / ↓, j / k |
Select a workspace row |
Space |
Include or exclude the selected workspace |
r |
Toggle a workspace with a saved thread between RESUME and FRESH |
a |
Select or clear all workspaces |
Enter |
Open the selected workloads |
n |
Skip restoration and add a new workspace |
Esc |
Start with an empty hub |
Only one Codex pane remains visible. Restored background workloads stay in the hub and open their saved thread when you focus them.
Nullwire runs one private tmux server per harness process and one tmux session per opened workload. Tmux remains invisible: its status bar and prefix keys are disabled, and the existing right-hand WezTerm pane acts as the only client.
Switching workloads changes the tmux session displayed by that client instead of restarting Codex. Once a workload has been opened, its Codex process, MCP connections, draft input, scrollback, and active work continue while it is in the background. A restored workload starts its saved thread the first time it is focused during a new Nullwire run.
Removing a workload stops only its runtime session. Exiting Nullwire with
q, then q shuts down its private tmux server and every managed Codex
process; Codex thread history remains available for later restoration.
On macOS, state is stored at:
~/Library/Application Support/Nullwire/state.json
Set NULLWIRE_STATE_FILE to use a different path.
Nullwire supports Vim keybindings throughout the hub, restore screen, and agent
inspector: use j / k to move down / up. Ctrl+H / Ctrl+L follow the same
directional convention when moving focus between panes, and arrow keys remain
available as an alternative.
| Key | Action |
|---|---|
n |
Add a repository workload |
↑ / ↓, j / k |
Select |
Ctrl+J / Ctrl+K |
Switch directly to the next / previous workload |
Ctrl+H / Ctrl+L |
Focus the Nullwire / Codex pane |
Tab / → |
Descend through repository suggestions |
Enter |
Open or resume the selected workload |
a |
Inspect the selected workload's agents and activity |
x |
Remove a workload without deleting Codex history |
q, then q |
Exit Nullwire |
In the agent inspector, use ↑ / ↓ or j / k to select an agent and
h to include archived agents. The inspector shows the delegated task and
recorded commands, file changes, tools, progress messages, and available
reasoning summaries.
Completed or waiting subagents move into history after three minutes without activity. This only cleans up the dashboard: Nullwire does not terminate the underlying Codex thread, and an archived agent reappears automatically if it becomes active again. Lead and working agents are never auto-archived.
Ctrl+J and Ctrl+K work from the focused Codex pane and wrap through the
workload list. Ctrl+H focuses the hub and Ctrl+L returns to Codex. You can
still use Ctrl+Shift+Left Arrow and
Ctrl+Shift+Right Arrow with the current WezTerm keymap.
Nullwire starts one persistent server per workload:
codex app-server --listen ws://127.0.0.1:<free-port>
Each observer performs the JSON-RPC initialization handshake, observes only its
workload's root and descendant threads, and uses thread/loaded/list to retain
sessions resumed inside that Codex TUI even when they have no new activity
timestamp. Per-workload servers prevent status, history, or subagents from one
Codex pane being attributed to another.
Observation is adaptive: Nullwire checks about once per second while any agent is working and backs off to every five seconds when all workloads are idle. Full thread histories are cached and fetched again only when their metadata changes, while active threads are always refreshed and idle entries are periodically revalidated. Background workloads remain observed; work started from an idle Codex pane can therefore take up to five seconds to appear before polling speeds up again.
The WebSocket listener is bound to loopback and is never exposed to the network.
Every Codex workload launched by Nullwire uses
--dangerously-bypass-approvals-and-sandbox, including resumed sessions. This
gives managed sessions unrestricted filesystem and network access without
approval prompts; run Nullwire only in repositories and environments you trust.

