PyHerdr runs many shells and AI coding agents side by side in one terminal — workspaces, tabs, and split panes, each a real pseudo-terminal — with live agent-status tracking and a mouse-and-keyboard Textual UI. A token-authenticated background server owns the processes, so you can detach and reattach without losing a session.
✨ Features
- Workspaces · tabs · panes — split panes in a binary tree (side-by-side or stacked), zoom, resize by dragging the divider, drag-free keyboard navigation.
- Real terminals — every pane is a live PTY (ConPTY on Windows via
pywinpty, the stdlibptyon macOS/Linux) with scrollback. - Mouse and keyboard — click tabs/panes, right-click for context menus, a
clickable bottom action bar, plus a tmux-style
ctrl+bprefix for everything. - Command palette (
ctrl+b :) — fuzzy-run any action or your own commands. - Live agent status — per-pane working / blocked / done / idle rollups with animated spinners, surfaced in the sidebar and tab bar.
- 📊 Resource monitor — right-click a pane or workspace → resource usage, or open Resource monitor — a live task-manager of CPU% + RAM per process, biggest-first, for one pane, a whole workspace, or every session.
- Themes — many built-ins (Catppuccin, Tokyo Night, Gruvbox, One Dark, Solarized, Rosé Pine, Kanagawa, …) with live theme + accent switching.
- Detach / reattach — the background server keeps panes running; reopen the
TUI to re-attach. Named sessions via
PYHERDR_SESSION. - Client / server — newline-delimited JSON over a token-authed local socket; a full CLI/API mirrors the UI. Plus cron-scheduled pane commands and git worktree helpers.
📦 Install
pip install pyherdr
Requires Python 3.11+. Runtime deps install automatically: pydantic,
pyte, textual, psutil, and pywinpty (Windows only).
🚀 Quick start
pyherdr # launch the terminal UI (same as: pyherdr tui)
It starts the background server if needed, opens a workspace with a shell, and
drops you into the UI. From a source checkout, use python -m pyherdr instead.
🖥️ User Interface Layout
PyHerdr organizes your workspace into a clean, mouse-supported dashboard in your terminal:
┌────────────────────────────────────────────────────────────┐
│ workspace: backend ~/code/api [main] │
├────────────────────────────────┬───────────────────────────┤
│ SPACES │ 1:server 2:tests [+] │
│ backend running │ +-------+-------+ │
│ frontend idle │ |1-1 |1-2 | │
│ │ |$ _ |logs | │
│ AGENTS │ |shell |run 3% | │
│ python server 0.8% │ +-------+-------+ │
│ node frontend 2.1% │ │
├────────────────────────────────┴───────────────────────────┤
│ ? help : palette + tab theme detach quit │
└────────────────────────────────────────────────────────────┘
- Sidebar (Left): Manages active workspaces, shows agent status spinners, and displays real-time CPU/RAM resource rollups.
- Terminal Workspace (Right): Houses your tabs and split terminal panes (stacked or side-by-side) running live processes.
- Action Bar (Bottom): Clickable button hotkeys to trigger standard actions without memorizing keyboard prefix chords.
⌨️ Keybindings
Keys go to the focused pane. Press the prefix ctrl+b, then an action key:
| Key | Action | |
|---|---|---|
| Panes | v / - |
split right / down |
h j k l |
focus left / down / up / right | |
z · r |
zoom · resize mode (then h/l/j/k, esc) |
|
m · x |
pane menu · close pane | |
pgup / pgdn |
scroll the pane's scrollback | |
| Tabs | c · n/p · 1–9 |
new · next/prev · jump to N |
< / > · T · X |
move left/right · rename · close | |
| Workspaces | N · w · { / } |
new (folder picker) · next · move up/down |
| Global | : · g · s |
command palette · jump to pane · theme |
d · ? · q |
detach · help · quit |
Mouse: click tabs/panes, drag a divider to resize, right-click anything for a menu (including resource usage). The bottom action bar has clickable buttons for help, palette, new tab, split, terminal, stats, theme, detach, quit.
🧰 CLI
The UI is a client; everything it does is scriptable:
pyherdr status # server + session status
pyherdr workspace create --label api --cwd ~/code
pyherdr tab create --label tests
pyherdr pane create --title logs
pyherdr pane start 1-1 python -i
pyherdr pane send-text 1-1 "print('hi')\n"
pyherdr pane get 1-1 # pane details incl. live running flag
pyherdr schedule add --cron "*/5 * * * *" --pane 1-1 git fetch
pyherdr server stop
🗂️ Configuration & state
- Session state:
.pyherdr/session.json(override withPYHERDR_STATE_PATH). - Server runtime metadata:
.pyherdr/server.json(override withPYHERDR_RUNTIME_DIR). - Default shell:
PYHERDR_SHELL, orterminal.default_shellin config; extra env injected into every pane viaterminal.env. - Named sessions:
PYHERDR_SESSION=<name>isolates state + server per name.
The .pyherdr/ folder holds the auth token and is git-ignored — never commit it.
🛠️ Development
python -m venv .venv
# Windows: .\.venv\Scripts\Activate.ps1 | macOS/Linux: source .venv/bin/activate
python -m pip install -e ".[dev]"
Quality gate (all must pass — CI enforces the same):
python -m ruff check pyherdr tests
python -m mypy
python -m unittest discover -s tests
A pure-Python port of the Rust project herdr —
see ARCHITECTURE.md for the package structure.
🙏 Attribution & license
PyHerdr is a Python port/fork of herdr, released under the
GNU AGPL-3.0-or-later — the same copyleft terms. See LICENSE and
NOTICE for the original project's attribution.
Release files for pyherdr 0.0.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pyherdr-0.0.4.tar.gz | 139.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyherdr-0.0.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 242.6 kB
Release files / pyherdr-0.0.4.tar.gz
| Download URL | pyherdr-0.0.4.tar.gz |
|---|---|
| Size | 139.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bfd5f78ff55e00f3f0ba95c984695fba3ca0b3be6fbff0db296ebe2ab439e869
|
|
BLAKE2b-256 checksum How to use checksums |
c311095a19ab54e62db06269376f2d98f849471a81e1088de087b654937fd942
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 9, 2026.
Transparency logRelease files / pyherdr-0.0.4-py3-none-any.whl
| Download URL | pyherdr-0.0.4-py3-none-any.whl |
|---|---|
| Size | 103.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3620832f5157e503e603bb18febf86921848e2d3581c592159c6f27f026ff59a
|
|
BLAKE2b-256 checksum How to use checksums |
76d67a86ce09643701d6ccb0af407b2b15581f47f7024fc1f350c83884d12c9a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 9, 2026.
Transparency log