The Problem
Developers who want to drive LLM agents from a terminal must juggle a shell, a prompt editor, and ad‑hoc UI code. The result is fragmented workflows, duplicated tooling, and fragile scripts that break when the UI changes.
What This Does
toad delivers a single Textual‑based TUI that embeds a fully‑functional shell, a markdown prompt editor, a fuzzy file picker, and a diff viewer. Core UI components live under src/toad/widgets/ (e.g. conversation.py, diff_view.py, prompt.py). The agent‑client protocol implementation resides in src/toad/acp/ and the top‑level CLI lives in src/toad/cli.py. Running python -m toad launches src/toad/__main__.py, which parses command‑line flags and hands control to cli.run().
How It Is Wired
- Entry point –
src/toad/__main__.pycallscli.main()(defined insrc/toad/cli.pyat line 75). Therunsub‑command (line 114) is the most used path, reaching 60 functions.
- Application bootstrap –
cli.run()creates aToadApp(class insrc/toad/app.py). Theon_mounthook (line 588) is invoked by Textual during UI start‑up and reaches 52 functions. This hook wires the main screen (src/toad/screens/main.py) and registers callbacks that ultimately callpost_message,focus, andwait.
- Core message flow – The internal call graph shows
post_messageis invoked from 46 distinct callers (e.g.src/toad/widgets/flash.py,src/toad/widgets/command_pane.py). It propagates UI events to the agent layer.
- Agent interaction –
src/toad/acp/agent.pydefinesstart(line 171) which builds anAgentobject, writes a session file (self._log_file_path.parent.mkdir) and issues network calls viaclient.post(seesrc/toad/app.py→jsonrpc). The most‑connected agent functions (generate_datetime_filename,command) are called from 16 other modules.
- Side effects Filesystem – 28 functions open or write files; examples are
src/toad/history.py(open) andsrc/toad/db.py(db.execute). Network – 4 functions perform outbound HTTP (client.post) insrc/toad/jsonrpc.pyandsrc/toad/app.py. * Database – 6 functions interact with SQLite viasrc/toad/db.py.
- High‑impact modules –
src/toad/widgets/conversation.py(109 functions, 8 classes) touches files and is called from 5 other files, making it a change‑hotspot.src/toad/ansi/_ansi.py(56 functions, 25 classes) andsrc/toad/acp/agent.py(36 functions, 2 classes) also have wide reach.
No circular import cycles were detected, so the import graph is flat, but deep nesting (up to 8 levels) and oversized files (>1 k lines) increase cognitive load.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/toad
cd toad
# Install in editable mode (pyproject.toml defines the build)
pip install -e .
# Run the TUI
python -m toad # equivalent to `toad` if a console script is installed
# Or invoke a specific command, e.g. start an agent session
python -m toad --help # shows CLI flags defined in src/toad/cli.py
Configuration files for agents live under src/toad/data/agents/ (e.g. openai.com.toml). The application reads its settings from src/toad/settings.py and src/toad/settings_schema.py. No additional environment variables are required out‑of‑the‑box.
Real‑World Use
A developer can launch Toad, press @ in the prompt editor to open the fuzzy picker, select src/toad/data/agents/openai.com.toml, and then issue a shell command (!git status). The shell runs inside the TUI, preserving cd and environment changes, while the agent receives the full terminal output via the integrated JSON‑RPC layer.
Code Health & Issues
- High – Add a test suite – 100 source files, no tests.
- High – Commit a lockfile –
pyproject.tomlhas no lockfile; reproducibility is at risk. - High – Add CI workflow – No GitHub Actions or other CI configuration.
- Medium – Enable Dependabot/Renovate – No automated dependency updates.
- Medium – Pin vulnerable versions – Ranges include
gitpython@3.1.44(CVE‑2026‑42284) and 25 other advisories.
Additional observations from the static analysis:
- High – Duplicated code blocks across 20 files (e.g.
_loop.py,widgets/diff_view.py). - High – Deep nesting (max indentation depth 8) in
acp/agent.pyand others. - High – Oversized files (
ansi/_ansi.py,widgets/conversation.py,acp/agent.py). - Medium – Files opened without context manager in
agents.py,db.py,history.py. - Medium – Broad exception handling (bare
except) in several modules. - Low – Stale TODO/FIXME markers in
ansi/_ansi.py.
No CI, Dockerfile, or secret files were found; a license file (LICENSE) is present.
The Bottom Line
toad provides a feature‑rich terminal UI that unifies shell interaction, prompt editing, and LLM agent calls, but the codebase suffers from missing tests, lack of reproducible builds, and high cognitive complexity. It is suitable for teams comfortable with Python/TUI development who can invest in adding tests and CI before relying on it in production.