6.2 KiB
name, description, version, author, license, platforms, metadata
| name | description | version | author | license | platforms | metadata | |||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| debugging | Debugging methodology and tools: systematic root-cause analysis, Python pdb/debugpy, Node.js inspect/CDP, Hermes TUI slash commands. | 2.0.0 | Hermes Agent | MIT |
|
|
Debugging — Methodology & Tools
Four-layer debugging: systematic root-cause methodology first, then language-specific tooling for Python (pdb/debugpy), Node.js (inspect/CDP), and Hermes TUI slash commands.
Section 1: Systematic Debugging (Methodology)
Core principle: ALWAYS find root cause before attempting fixes. Symptom fixes are failure.
The Four Phases
Phase 1: Root Cause Investigation
- Read error messages carefully — they often contain the exact solution
- Reproduce consistently — can you trigger it reliably?
- Check recent changes —
git log --oneline -10,git diff - Gather evidence in multi-component systems — log at each boundary
- Trace data flow — where does the bad value originate?
Phase 2: Pattern Analysis
- Find working examples in the same codebase
- Compare against reference implementations
- Identify every difference between working and broken
- Map dependencies and assumptions
Phase 3: Hypothesis and Testing
- Form a SINGLE hypothesis: "I think X is the root cause because Y"
- Make the SMALLEST possible change to test it
- Verify BEFORE continuing — did it work?
Phase 4: Implementation
- Create failing test case first (RED)
- Implement single fix addressing root cause (GREEN)
- Verify fix with full test suite
- If fix doesn't work: Rule of Three — after 3 failed fixes, question the architecture
Iron Law
NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST
Red Flags — Stop and Follow Process
- "Quick fix for now, investigate later"
- "Just try changing X and see if it works"
- "One more fix attempt" (after 2+ failures)
- Each fix reveals a new problem in a different place
See references/systematic-debugging.md for the full methodology with rationalizations table and Hermes tool integration patterns.
Section 2: Python Debugging (pdb + debugpy)
Quick Reference: When to Use What
| Tool | When |
|---|---|
breakpoint() + pdb |
Local, interactive, simplest |
python -m pdb |
Launch existing script under pdb, no source edits |
debugpy |
Remote/headless/attach to running process (DAP protocol) |
remote-pdb |
Cleanest agent-friendly remote pdb over TCP |
pdb Inside the REPL
| Command | Action |
|---|---|
n |
next line (step over) |
s |
step into |
c |
continue |
b file:line |
set breakpoint |
p expr / pp expr |
print / pretty-print |
w |
where (stack trace) |
!stmt |
execute arbitrary Python |
interact |
full Python REPL in current scope |
Debugging pytest
pytest tests/test_foo.py::test_bar --pdb -p no:xdist # xdist breaks pdb
Remote Debug with debugpy
import debugpy
debugpy.listen(("127.0.0.1", 5678))
debugpy.wait_for_client() # blocks until IDE attaches
Remote Debug with remote-pdb (simpler)
from remote_pdb import set_trace
set_trace(host="127.0.0.1", port=4444) # then: nc 127.0.0.1 4444
Key Pitfalls
- pdb under pytest-xdist silently hangs — always use
-p no:xdist breakpoint()in CI/non-TTY hangs — never commit itPYTHONBREAKPOINT=0disables all breakpoint() calls- debugpy.listen only blocks if wait_for_client() is also called
- ptrace_scope=1 (Ubuntu default) may block attach-to-PID
See references/python-debugpy.md for full recipes (post-mortem, Hermes subprocess debugging, one-shot patterns).
Section 3: Node.js Debugging (inspect + CDP)
Quick Reference
| Tool | When |
|---|---|
node inspect |
Built-in CLI REPL, quick poking |
ndb / CDP via chrome-remote-interface |
Scriptable automation, many breakpoints |
Launch and Attach
node --inspect-brk script.js # pause on first line
node inspect -p <pid> # attach to running process
kill -SIGUSR1 <pid> # enable inspector on existing process
The debug> REPL
sb('file.js', 42)— set breakpointcont/next/step/out— navigaterepl— drop into JS REPL in paused scopebt— backtraceexec expr— evaluate once
Debugging Hermes ui-tui
# Build first, then debug the built output
cd ui-tui && npm run build
node --inspect-brk dist/entry.js
# In another terminal: node inspect -p <pid>
Key Pitfalls
node inspectCLI does NOT follow TypeScript sourcemaps — break in builtdist/*.js--inspectvs--inspect-brk: former doesn't pause, your breakpoints may race- Port 9229 is default; use
--inspect=0for random port when multiple processes --inspecton parent does NOT inspect children — useNODE_OPTIONS='--inspect-brk'
See references/node-inspect-debugger.md for CDP scripting, heap snapshots, CPU profiles, and Vitest debugging.
Section 4: Debugging Hermes TUI Slash Commands
Hermes slash commands span three layers:
Python backend (hermes_cli/commands.py) ← COMMAND_REGISTRY
│
TUI gateway (tui_gateway/server.py) ← slash.exec / command.dispatch
│
TUI frontend (ui-tui/src/app/slash/) ← local handlers + fallthrough
Common Issues
- Command in TUI but not autocomplete → missing from
COMMAND_REGISTRYincommands.py - Command in autocomplete but doesn't work → check both gateway handler and TUI local handler
- Behavior differs CLI vs TUI → different implementations exist; check both
- Config persists but UI doesn't update → need
patchUiState(...)alongsideconfig.set - Gateway silently ignores → command not in
GATEWAY_KNOWN_COMMANDSor iscli_only
Investigation Steps
search_files --pattern "/commandname" --file_glob "*.ts" --path ui-tui/
search_files --pattern "commandname" --path hermes_cli/commands.py
search_files --pattern "complete.slash|slash.exec" --path tui_gateway/
See references/debugging-hermes-tui-commands.md for the full investigation guide, fix patterns, and verification checklist.