Skip to content

openswarm-ai/swarm-debug

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

57 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

swarm-debug

A drop-in replacement for print() debugging. Colorized, per-file toggleable output with a visual web GUI to control it all.

pip install swarm-debug

What it does

debug() 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.

Usage

1. Add debug() calls to your code

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.

Full signature

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

Pretty-printed data structures (on by default)

debug(my_dict)                 # dicts, lists, sets, dataclasses are pretty-printed with Rich
debug(my_dict, pretty=False)   # opt out for flat single-line output

Syntax-highlighted strings (explicit lang=)

debug(sql_query, lang="sql")       # SQL keyword highlighting
debug(json_string, lang="json")    # JSON syntax coloring
debug(html_body, lang="html")      # HTML highlighting

Table layout (auto when >1 non-text data args)

debug(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 arg

Diff output

debug.diff(old_state, new_state)                # unified diff, default label "diff"
debug.diff(old_state, new_state, label="state") # custom label

Timing

with debug.time("database query"):
    result = db.execute(query)
# prints: [func] : ⏱ database query took 0.123s  (green/yellow/red based on duration)

Other features

  • 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). Pass override_max_chars=True to disable.
  • Indent bars -- debug() reads source indentation and renders nested output with visual indent bars

2. Launch the GUI

swarm-debug gui
swarm-debug gui --port 8080     # custom port
swarm-debug gui --verbose       # show all server logs

Your 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).

3. CLI reference

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 endpoints

Configuration storage

All 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

API endpoints

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.


Development (source)

Prerequisites

  • Python 3.9+
  • Node.js 18+

Running locally

Both services (backend on :6970, frontend dev server on :6969):

bash run.sh

Individually:

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

Tech stack

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)

Architecture

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).

Project structure

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)

Publishing to PyPI

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 --real

The script will:

  1. Clean previous build artifacts
  2. Build the React frontend (npm ci && npm run build)
  3. Bundle the build into swarm_debug/debugger_gui_build/
  4. Build the Python sdist + wheel
  5. Upload via twine

Prerequisites for publishing

pip install build twine

You'll need a PyPI account and API token. Configure ~/.pypirc or pass credentials when prompted by twine.

How the pip package works

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.

License

MIT

About

A drop-in replacement for print() debugging. Colorized, per-file toggleable output with a visual web GUI for the human to control it all, and a skill.md for an agent to control it all.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors