A drop-in replacement for print() debugging. Colorized, per-file toggleable output with a visual web GUI to control it all.
pip install swarm-debugdebug() works like print(), but every call is:
- Colorized -- each file gets its own color so you can visually separate output
- Toggleable -- turn debug output on/off per file or entire directories without touching code
- Context-aware -- automatically shows the calling function, class, variable name, and indentation level
- Emoji-tagged -- assign emojis to files for instant visual scanning
- Error-aware -- exceptions are auto-highlighted in red with a dedicated emoji
All configuration is managed through a web GUI or the CLI. No config files to write, no decorators to add.
from swarm_debug import debug
x = 42
debug(x)
# β« [my_script.py] : x: int = 42
debug("loading config")
# β« [my_script.py] : loading config
def process(data):
debug(data, len(data))
# β« [MyClass.process] : (table with Name | Type | Value columns)Strings are rendered as italic labels. Everything else shows name: type = value. Multiple non-text args are auto-rendered as a Rich table. Errors are auto-detected and forced on in red regardless of toggle state.
debug(*args, mode='debug', override_max_chars=False, sep=<auto>, end='\n',
pretty=True, lang=None, table=<auto>)| Kwarg | Type | Default | Description |
|---|---|---|---|
mode |
str |
"debug" |
Log level. "all" (always), "debug" (default), "test" (high priority) |
override_max_chars |
bool |
False |
Bypass the 3000-char truncation limit |
sep |
str |
auto | Join all args with this separator (like print(sep=...)) |
pretty |
bool |
True |
Pretty-print dicts, lists, sets, tuples, dataclasses with Rich |
lang |
str|None |
None |
Syntax-highlight all args as this language (e.g. "sql", "json") |
table |
bool |
auto | Force table layout on/off. Auto-on when >1 non-text data args |
debug(my_dict) # dicts, lists, sets, dataclasses are pretty-printed with Rich
debug(my_dict, pretty=False) # opt out for flat single-line outputdebug(sql_query, lang="sql") # SQL keyword highlighting
debug(json_string, lang="json") # JSON syntax coloring
debug(html_body, lang="html") # HTML highlightingdebug(x, y, z) # 3 data args -> table with Name | Type | Value columns
debug(x) # single arg -> inline output
debug(x, y, z, table=False) # force per-line output
debug(x, table=True) # force table even for a single argdebug.diff(old_state, new_state) # unified diff, default label "diff"
debug.diff(old_state, new_state, label="state") # custom labelwith debug.time("database query"):
result = db.execute(query)
# prints: [func] : β± database query took 0.123s (green/yellow/red based on duration)- Clickable links -- function names in the output are OSC 8 hyperlinks (
file://path#line) in supported terminals (iTerm2, Windows Terminal) - Truncation -- values over 3000 chars are truncated (first 1500 +
...+ last 1500). Passoverride_max_chars=Trueto disable. - Indent bars --
debug()reads source indentation and renders nested output with visual indent bars
swarm-debug gui
swarm-debug gui --port 8080 # custom port
swarm-debug gui --verbose # show all server logsYour browser opens automatically to http://localhost:6969. You'll see a file tree of your project showing every file that calls debug(). From there you can:
- Toggle files/directories on and off
- Assign custom colors per file or directory (children inherit from parents)
- Assign emojis for visual tagging
- Push/pull configuration changes
- Reset colors or emojis to defaults
The server scans whichever directory you launched it from. To point it at a different project:
# Option A: cd into the project first
cd /path/to/my/project && swarm-debug gui
# Option B: set an env var
SWARM_DEBUG_ROOT=/path/to/my/project swarm-debug gui
# Option C: use the CLI
swarm-debug set-root /path/to/my/project
# Option D: use the API
curl -X POST http://localhost:6969/api/debugger/root_dir \
-H "Content-Type: application/json" \
-d '{"root_dir": "/path/to/my/project"}'The root dir persists across restarts (saved per-project to ~/.swarm-debug/projects/<hash>/root_dir.txt).
All commands work standalone (no server required). Paths are relative to project root.
# View current state
swarm-debug status # human-readable tree with [ON]/[OFF] tags
swarm-debug status --json # machine-readable JSON (pipe to jq, python, etc.)
swarm-debug stats # flat table of all files with path/status/color/emoji
# Toggle visibility
swarm-debug toggle on src/agents/planner.py # single file
swarm-debug toggle off src/agents/ # whole directory (recursive)
swarm-debug toggle on --all # everything
# Configuration
swarm-debug set-root /path/to/project
swarm-debug set-color src/agents/planner.py "#ff0000" # single file
swarm-debug set-color src/agents/ "#ff0000" # directory (children get lightened variant)
swarm-debug set-emoji src/agents/planner.py "π΄" # single file
swarm-debug set-emoji src/agents/ "π΄" # directory (propagates to children)
swarm-debug reset # reset all colors/emojis (with confirmation)
# Cursor AI skill
swarm-debug install-cursor-skill # copy SKILL.md to .cursor/skills/swarm-debug/
swarm-debug uninstall-cursor-skill # remove the skill directory
# Package management
swarm-debug --version # show version + check for updates
swarm-debug --upgrade # upgrade to latest version from PyPI
swarm-debug --help-all # detailed help for all commands + API-only endpointsAll runtime state lives in ~/.swarm-debug/projects/<hash>/ (where <hash> is the first 16 chars of the SHA-256 of the project root path):
| File | Purpose |
|---|---|
debug_toggles.json |
Per-file toggle, color, and emoji state |
root_dir.txt |
Persisted project root directory |
log_mode.txt |
Log output mode (all, debug, test) |
needs_resync.txt |
Internal flag for syncing state |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/health/check |
Health check |
| GET | /api/debugger/pull_structure |
Get file tree with toggle states |
| POST | /api/debugger/push_structure |
Save toggle/color/emoji config |
| POST | /api/debugger/reset_color |
Reset all colors to defaults |
| POST | /api/debugger/reset_emoji |
Reset all emojis to defaults |
| GET | /api/debugger/events |
SSE stream β emits events when toggles change on disk |
| GET | /api/debugger/root_dir |
Get current project root |
| POST | /api/debugger/root_dir |
Set project root (triggers resync) |
Full interactive docs at http://localhost:6969/docs.
- Python 3.9+
- Node.js 18+
Both services (backend on :6970, frontend dev server on :6969):
bash run.shIndividually:
bash backend/run.sh # Creates venv, installs package in editable mode, runs uvicorn on :6970
bash frontend/run.sh # npm install + webpack dev server on :6969| Layer | Tech |
|---|---|
| Frontend | React 18, TypeScript, Webpack 5, MUI v7, Redux Toolkit, Framer Motion |
| Backend | FastAPI, Uvicorn, Python 3.9+ |
| Runtime types | typeguard (@typechecked on endpoints) |
| CLI | Typer (built on Click) |
| Terminal rendering | Rich (Pretty, Syntax, Table, Panel, Console) |
Server (swarm_debug/server.py) uses a SubApp pattern -- each feature is a self-contained module with its own APIRouter and async lifespan, auto-mounted at /api/{name}/. SubApps are registered in swarm_debug/config/Apps.py and composed into the FastAPI app in swarm_debug/server.py.
Frontend uses a custom design token system layered on MUI, accessed via useClaudeTokens(). See frontend/DESIGN.md for the full spec.
Debugleton is a thread-safe singleton that holds the scanned project tree in memory and resyncs when the needs_resync flag is set (after any push from the GUI or CLI).
debugger/
βββ swarm_debug/ # The pip-installable Python package
β βββ __init__.py # The debug() function + debug.diff + debug.time
β βββ cli.py # Typer CLI app (swarm-debug command)
β βββ server.py # FastAPI + Uvicorn entrypoint
β βββ config/
β β βββ Apps.py # SubApp / MainApp framework
β βββ apps/
β β βββ health/health.py # GET /api/health/check
β β βββ debugger/debugger.py # All debugger API endpoints
β βββ core/
β β βββ data_dir.py # ~/.swarm-debug/ path management
β β βββ DEFAULTS.py # Default values, get/set_root_dir
β β βββ Debugleton.py # Thread-safe singleton for project state
β β βββ toggle_ops.py # CLI tree operations: toggle, color, emoji, reset
β β βββ models/
β β β βββ File.py # Base file class
β β β βββ DebugFile.py # File with color/toggle/emoji
β β β βββ Directory.py # Recursive directory tree
β β β βββ project_scanner.py # Scan project, merge with saved state
β β βββ log/
β β β βββ log_config.py # Custom logger with modes
β β β βββ log_mode.py # Read/write log mode
β β βββ utils/
β β βββ debug_arg_parser.py # Extract arg names from source code
β β βββ path_mngr.py # Absolute/relative path helpers
β βββ data/
β β βββ SKILL.md # Cursor AI skill (bundled in package)
β βββ debugger_gui_build/ # Pre-built React frontend (ships with pip package)
βββ backend/
β βββ run.sh # Dev script: venv + editable install + uvicorn
β βββ data/ # Seed defaults for local dev
β βββ debugger_gui_build/ # Copy of built frontend for local dev
βββ frontend/
β βββ package.json
β βββ webpack.config.js
β βββ DESIGN.md # Design system specification
β βββ run.sh # npm install + webpack dev server
β βββ src/
β βββ index.tsx
β βββ app/
β β βββ Main.tsx
β β βββ pages/Debugger/ # Debugger, DebuggerHeader
β β βββ components/ # Tree, SyncSection, EmojiPicker, SettingsModal
β βββ shared/
β βββ state/ # Redux store, slice, thunks
β βββ styles/ # Theme tokens
β βββ constants/ # Emoji list
βββ pyproject.toml # PyPI package config (swarm-debug)
βββ publish.sh # Build + publish to PyPI
βββ run.sh # Dev orchestrator: backend -> frontend
βββ ports.conf # Port configuration (backend=6970, frontend=6969)
Everything is handled by a single script:
# Publish to test.pypi.org (for testing)
./publish.sh --test
# Publish to pypi.org (for real)
./publish.sh --realThe script will:
- Clean previous build artifacts
- Build the React frontend (
npm ci && npm run build) - Bundle the build into
swarm_debug/debugger_gui_build/ - Build the Python sdist + wheel
- Upload via twine
pip install build twineYou'll need a PyPI account and API token. Configure ~/.pypirc or pass credentials when prompted by twine.
When installed from PyPI, the pre-built React frontend is bundled inside the wheel at swarm_debug/debugger_gui_build/. The FastAPI server serves these static files alongside the API, so end users get both the GUI and the API on a single port (default 6969) with zero Node.js dependency.
Users import the debug function from the swarm_debug package: from swarm_debug import debug. The CLI (swarm-debug gui) launches the server.
MIT