Python desktop and CLI fork of Herdr
Project description
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyherdr-0.0.3.tar.gz.
File metadata
- Download URL: pyherdr-0.0.3.tar.gz
- Upload date:
- Size: 139.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
543cd733ec6e6cd965fc632c8d14c5c0c13c6a712d8ac31aeba553226d9c91fa
|
|
| MD5 |
c545175131af7bd3ab691fd02b634f33
|
|
| BLAKE2b-256 |
87636fed0e3e63c388bed6ec562c240945802fab1bf4c3991e9536483b9ab182
|
Provenance
The following attestation bundles were made for pyherdr-0.0.3.tar.gz:
Publisher:
release.yml on joselrnz/pyherdr
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyherdr-0.0.3.tar.gz -
Subject digest:
543cd733ec6e6cd965fc632c8d14c5c0c13c6a712d8ac31aeba553226d9c91fa - Sigstore transparency entry: 1770452241
- Sigstore integration time:
-
Permalink:
joselrnz/pyherdr@d971081661a6248310d76e147905628581f079e6 -
Branch / Tag:
refs/tags/v0.0.3 - Owner: https://github.com/joselrnz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d971081661a6248310d76e147905628581f079e6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyherdr-0.0.3-py3-none-any.whl.
File metadata
- Download URL: pyherdr-0.0.3-py3-none-any.whl
- Upload date:
- Size: 103.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56df2c280b69bf387e4ed16c8b0e2cfa9b1c84d42693e726aeedd8268bf67b82
|
|
| MD5 |
2dee7977de33bc6d7c9b1b494f6063ee
|
|
| BLAKE2b-256 |
6e1262c049bd5cbec98c5adf372dcbd13e6ac4a72f4272d4563bc473df54ccad
|
Provenance
The following attestation bundles were made for pyherdr-0.0.3-py3-none-any.whl:
Publisher:
release.yml on joselrnz/pyherdr
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyherdr-0.0.3-py3-none-any.whl -
Subject digest:
56df2c280b69bf387e4ed16c8b0e2cfa9b1c84d42693e726aeedd8268bf67b82 - Sigstore transparency entry: 1770452380
- Sigstore integration time:
-
Permalink:
joselrnz/pyherdr@d971081661a6248310d76e147905628581f079e6 -
Branch / Tag:
refs/tags/v0.0.3 - Owner: https://github.com/joselrnz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d971081661a6248310d76e147905628581f079e6 -
Trigger Event:
push
-
Statement type: