Keyboard-first Zellij dashboard for active Codex panes across local Zellij sessions.
zj-codex adds no layout and no permanent sidebar. It installs one hidden
collector role per Zellij session and registers c in Zellij's normal mode.
Press Ctrl+a, then c, to open the floating dashboard.
Each live Codex pane reports its current lifecycle through official Codex hooks. The dashboard combines that pushed status with Zellij's pushed tab and pane topology, then shows:
- Zellij session, tab, and terminal pane ID.
- Running, pending, done, error, or idle state.
- Current activity and the latest substantial user task.
- Repository and branch when available.
The dashboard covers live Codex processes hosted by Zellij. It does not list archived or offline Codex conversations.
Requirements: Zellij 0.44.3 or newer, a current Codex CLI with hooks enabled,
and Rust with the wasm32-wasip1 target.
Setup requires a locked-mode Ctrl+a prefix and a free c binding in Normal
mode. Stock Zellij's Normal default mode is intentionally rejected: installing
plain c there would steal normal terminal input. The relevant configuration
must have this shape:
default_mode "locked"
keybinds {
locked {
bind "Ctrl a" { SwitchToMode "normal"; }
}
}Remove any existing Normal-mode c binding or global unbind "c" before
setup. The installer never changes your prefix binding.
cargo build --release --target wasm32-wasip1 -p zj-codex-plugin
cargo install --path crates/cli
zj-codex setup
zj-codex setup --checkBare setup finds the workspace artifact through cargo metadata. Release
archives can place zj_codex.wasm beside the zj-codex executable. Use
--wasm PATH only to override those locations.
The dashboard key defaults to c. To change the second key in the chord,
create ~/.config/zj-codex/config.kdl, then rerun setup:
key "z"The key must be one non-whitespace character.
ZJ_CODEX_CONFIG_FILE overrides that path; XDG_CONFIG_HOME is honored. A
configured file is validated before anything is changed. Ctrl+a remains the
existing Zellij prefix, so the example shortcut is Ctrl+a, then z.
Setup is merge-safe and idempotent. It:
- Copies the WASM to Zellij's configured plugin directory.
- Adds a plugin alias, hidden collector, and
normal-mode dashboard binding toconfig.kdl. - Pre-authorizes the three required Zellij permissions in
permissions.kdl. - Creates Zellij's URL-scoped plugin cache with owner-only permissions on Unix.
- Adds nine lifecycle handlers to
~/.codex/hooks.jsonwithout replacing existing hooks.
It does not create or modify a Zellij layout. Zellij's ZELLIJ_CONFIG_FILE and
ZELLIJ_CONFIG_DIR overrides are honored.
Start a new Zellij session, or restart existing sessions, so load_plugins
can start the collector. In Codex, open /hooks, review the zj-codex notify
handlers, and trust them. Codex intentionally skips changed command hooks until
their current definition is trusted.
Ctrl+a,c: open or focus the dashboard.j/kor arrows: select a Codex pane.Home,End,PgUp,PgDn: move through longer lists.Enteror left click: jump to the exact pane, including another Zellij session.Escorq: close the dashboard.
The installer adds the configured key to normal mode; Ctrl+a remains your
existing prefix binding.
Zellij 0.44's built-in status bar only labels mode-switch and quit actions. It
does not expose an extension point for naming plugin bindings, so it cannot
show a native c CODEX tile. Replacing that bar would also replace its mode
hints and is deliberately outside normal setup.
Rows become stale after 90 seconds without a collector heartbeat. They stay visible for diagnosis but cannot be activated. Abandoned inventory files are removed after six hours.
zj-codex setup --check
zj-codex uninstallUninstall removes only marked zj-codex configuration and hook entries. It
preserves foreign configuration and leaves the copied WASM and private cache in
place. Zellij rewrites permissions.kdl without comments; if that removes the
ownership marker, uninstall leaves the harmless cached permission grant behind.
setup --check validates the installed hook definitions and Codex's effective
global hooks feature. It cannot prove per-handler trust or enablement, or
profile/session managed-hook restrictions. Codex's /hooks view remains the
authoritative check for those states.
Codex hook -> zellij pipe -> hidden per-session collector -> inventory file
|
Ctrl+a,c -> floating panel ------------------------------------+
|
+-> focus pane / switch session with pane focus
Codex hook messages are not replayed to plugins launched later. The hidden collector is therefore the durable receiver; the floating panel is only a view. Zellij may create one collector clone per attached client, so a sticky per-session election allows only one clone to write while every clone stays current. The elected background instance survives client detach; a replacement hydrates the matching inventory before its first write when Zellij reuses a client ID. Collection is push-driven—there are no blocking pane-command or pane-content polls.
Normal setup keeps inventories under Zellij's owner-only plugin cache. Manually
wired plugins can fall back to /tmp/zj-codex; that compatibility fallback does
not provide the same privacy guarantee.
See the design for the contracts and failure boundaries.
just test
just build-wasm
just ciDo not run cargo fmt; match the compact local style.