debug-mode
This skill should be used when debugging frontend/UI bugs that need runtime evidence. USE THIS SKILL (instead of adding console.log) when you're about to say "add console.log and ask user to check", "open DevTools and tell me what you see", "reproduce the bug and share the output", "check the browser console". Triggers: "debug this", "fix this bug", "why isn't this working", "investigate this issue", "trace the problem", "figure out why X happens", "UI not updating", "state is wrong", "value is null/undefined", "click doesn't work", "modal not showing". Automates log collection server-side - you read logs directly, no user copy-paste needed.
Best use case
debug-mode is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
This skill should be used when debugging frontend/UI bugs that need runtime evidence. USE THIS SKILL (instead of adding console.log) when you're about to say "add console.log and ask user to check", "open DevTools and tell me what you see", "reproduce the bug and share the output", "check the browser console". Triggers: "debug this", "fix this bug", "why isn't this working", "investigate this issue", "trace the problem", "figure out why X happens", "UI not updating", "state is wrong", "value is null/undefined", "click doesn't work", "modal not showing". Automates log collection server-side - you read logs directly, no user copy-paste needed.
Teams using debug-mode should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/debug-mode/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How debug-mode Compares
| Feature / Agent | debug-mode | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
This skill should be used when debugging frontend/UI bugs that need runtime evidence. USE THIS SKILL (instead of adding console.log) when you're about to say "add console.log and ask user to check", "open DevTools and tell me what you see", "reproduce the bug and share the output", "check the browser console". Triggers: "debug this", "fix this bug", "why isn't this working", "investigate this issue", "trace the problem", "figure out why X happens", "UI not updating", "state is wrong", "value is null/undefined", "click doesn't work", "modal not showing". Automates log collection server-side - you read logs directly, no user copy-paste needed.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Debug Mode
Fix bugs with **runtime evidence**, not guesses.
```
Don't guess → Hypothesize → Instrument → Reproduce → Analyze → Fix → Verify
```
## When to Use
**Trigger signals** (if you're about to do any of these, use this skill instead):
- "Open DevTools Console and check for..."
- "Reproduce the bug and tell me what you see"
- "Add console.log and let me know the output"
- "Click X, open Y, check if Z appears in console"
**Example scenario that should trigger this skill:**
```
❌ Without skill (manual, slow):
"I added debug logging. Please:
1. Open the app in browser
2. Open DevTools Console (F12)
3. Open the defect modal and select a defect
4. Check console for [DEBUG] logs
5. Tell me what you see"
✅ With skill (automated):
Logs are captured server-side → you read them directly → no user copy-paste needed
```
**Use when debugging:**
- State/value issues (null, undefined, wrong type)
- Conditional logic (which branch was taken)
- Async timing (race conditions, load order)
- User interaction flows (modals, forms, clicks)
## Arguments
```
/debug /path/to/project
```
If no path provided, use current working directory.
## Workflow
### Phase 1: Start Log Server
**Step 1: Ensure server is running** (starts if needed, no-op if already running):
```bash
node skills/debug/scripts/debug_server.js /path/to/project &
```
Server outputs JSON:
- `{"status":"started",...}` - new server started
- `{"status":"already_running",...}` - server was already running (this is fine!)
**Step 2: Create session** (server generates unique ID from your description):
```bash
curl -s -X POST http://localhost:8787/session -d '{"name":"fix-null-userid"}'
```
Response:
```json
{"session_id":"fix-null-userid-a1b2c3","log_file":"/path/to/project/.debug/debug-fix-null-userid-a1b2c3.log"}
```
**Save the `session_id` from the response** - use it in all subsequent steps.
**Server endpoints:**
- POST `/session` with `{"name": "description"}` → creates session, returns `{session_id, log_file}`
- POST `/log` with `{"sessionId": "...", "msg": "..."}` → writes to log file
- GET `/` → returns status and log directory
**If port 8787 busy:** `lsof -ti :8787 | xargs kill -9` then restart
──────────
### Phase 2: Generate Hypotheses
**Before instrumenting**, generate 3-5 specific hypotheses:
```
Hypothesis H1: userId is null when passed to calculateScore()
Expected: number (e.g., 5)
Actual: null
Test: Log userId at function entry
Hypothesis H2: score is string instead of number
Expected: 85 (number)
Actual: "85" (string)
Test: Log typeof score
```
Each hypothesis must be:
- **Specific** (not "something is wrong")
- **Testable** (can confirm/reject with logs)
- **Cover different subsystems** (don't cluster)
──────────
### Phase 3: Instrument Code
Add logging calls to test all hypotheses.
**JavaScript/TypeScript:**
```javascript
// #region debug
const SESSION_ID = 'REPLACE_WITH_SESSION_ID'; // e.g. 'fix-null-userid-a1b2c3'
const DEBUG_LOG_URL = 'http://localhost:8787/log';
const debugLog = (msg, data = {}, hypothesisId = null) => {
const payload = JSON.stringify({
sessionId: SESSION_ID,
msg,
data,
hypothesisId,
loc: new Error().stack?.split('\n')[2],
});
if (navigator.sendBeacon?.(DEBUG_LOG_URL, payload)) return;
fetch(DEBUG_LOG_URL, { method: 'POST', body: payload }).catch(() => {});
};
// #endregion
// Usage
debugLog('Function entry', { userId, score, typeScore: typeof score }, 'H1,H2');
```
**Python:**
```python
# #region debug
import requests, traceback
SESSION_ID = 'REPLACE_WITH_SESSION_ID' # e.g. 'fix-null-userid-a1b2c3'
def debug_log(msg, data=None, hypothesis_id=None):
try:
requests.post('http://localhost:8787/log', json={
'sessionId': SESSION_ID, 'msg': msg, 'data': data,
'hypothesisId': hypothesis_id, 'loc': traceback.format_stack()[-2].strip()
}, timeout=0.5)
except: pass
# #endregion
# Usage
debug_log('Function entry', {'user_id': user_id, 'type': type(user_id)}, 'H1')
```
**Guidelines:**
- 3-8 instrumentation points
- Cover: entry/exit, before/after critical ops, branch paths
- Tag each log with `hypothesisId`
- Wrap in `// #region debug` ... `// #endregion`
- **High-frequency events** (mousemove, scroll): log only on **state change**
- Log both **intent** and **result**
──────────
### Phase 4: Clear and Reproduce
1. Clear logs:
```bash
: > /path/to/project/.debug/debug-$SESSION_ID.log
```
2. Provide reproduction steps:
```xml
<reproduction_steps>
1. Start app: yarn dev
2. Navigate to /users
3. Click "Calculate Score"
4. Observe NaN displayed
</reproduction_steps>
```
3. User reproduces bug
──────────
### Phase 5: Analyze Logs
Read and evaluate:
```bash
cat /path/to/project/.debug/debug-$SESSION_ID.log
```
For each hypothesis:
```
Hypothesis H1: userId is null
Status: CONFIRMED
Evidence: {"msg":"Function entry","data":{"userId":null}}
Hypothesis H2: score is string
Status: REJECTED
Evidence: {"data":{"typeScore":"number"}}
```
**Status options:**
- **CONFIRMED**: Logs prove it
- **REJECTED**: Logs disprove it
- **INCONCLUSIVE**: Need more instrumentation
**If all INCONCLUSIVE/REJECTED**: Generate new hypotheses, add more logs, iterate.
──────────
### Phase 6: Fix
**Only fix when logs confirm root cause.**
Keep instrumentation active (don't remove yet).
Tag verification logs with `runId: "post-fix"`:
```javascript
debugLog('Function entry', { userId, runId: 'post-fix' }, 'H1');
```
──────────
### Phase 7: Verify
1. Clear logs
2. User reproduces (bug should be gone)
3. Compare before/after:
```
Before: {"data":{"userId":null},"runId":"run1"}
After: {"data":{"userId":5},"runId":"post-fix"}
```
4. Confirm with log evidence
**If still broken**: New hypotheses, more logs, iterate.
──────────
### Phase 8: Five Whys (Optional)
**When to run:** Recurring bug, prod incident, security issue, or "this keeps happening".
After fixing, ask "Why did this bug exist?" to find systemic causes:
```
Bug: API returns NaN
Why 1: userId was null → Code fix: null check
Why 2: No input validation → Add validation
Why 3: No test for null case → Add test
Why 4: Review didn't catch → (one-off, acceptable)
```
**Categories:**
| Type | Action |
|------|--------|
| CODE | Fix immediately |
| TEST | Add test |
| PROCESS | Update checklist/review |
| SYSTEMIC | Document patterns |
**Skip if:** Simple one-off bug, low impact, not recurring.
──────────
### Phase 9: Clean Up
Remove instrumentation only after:
- Post-fix logs prove success
- User confirms resolved
Search for `#region debug` and remove all debug code.
## Log Format
Each line is NDJSON:
```json
{"ts":"2024-01-03T12:00:00.000Z","msg":"Button clicked","data":{"id":5},"hypothesisId":"H1","loc":"app.js:42"}
```
## Critical Rules
1. **NEVER fix without runtime evidence** - Always collect logs first
2. **NEVER remove instrumentation before verification** - Keep until fix confirmed
3. **NEVER guess** - If unsure, add more logs
4. **If all hypotheses rejected** - Generate new ones from different subsystems
## Troubleshooting
| Issue | Solution |
|-------|----------|
| Server won't start | Check port 8787 not in use: `lsof -i :8787` |
| Logs empty | Check browser blocks (mixed content/CSP/CORS), firewall |
| Wrong log file | Verify session ID matches |
| Too many logs | Filter by hypothesisId, use state-change logging |
| Can't reproduce | Ask user for exact steps, check environment |
### CORS / Mixed Content Workarounds
If logs aren't arriving, it’s usually one of:
- **Mixed content**: HTTPS app → `http://localhost:8787` is blocked. Use a dev-server proxy (same origin) or serve the log endpoint over HTTPS.
- **CSP**: `connect-src` blocks the log URL. Use a dev-server proxy or update CSP.
- **CORS preflight**: `Content-Type: application/json` triggers `OPTIONS`. Use a “simple” request (`text/plain`) or `sendBeacon`.
**1. `sendBeacon` (avoids preflight; fire-and-forget)**:
```javascript
const DEBUG_LOG_URL = 'http://localhost:8787/log';
const debugLog = (msg, data = {}, hypothesisId = null) => {
const payload = JSON.stringify({ sessionId: SESSION_ID, msg, data, hypothesisId });
if (navigator.sendBeacon?.(DEBUG_LOG_URL, payload)) return;
fetch(DEBUG_LOG_URL, { method: 'POST', body: payload }).catch(() => {});
};
```
Note: still blocked by mixed content + CSP.
**2. Dev server proxy (Vite example)** - same-origin `/__log` → `http://localhost:8787/log`:
```javascript
// vite.config.js
export default {
server: {
proxy: {
'/__log': {
target: 'http://localhost:8787',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/__log/, '/log'),
},
},
},
};
// Then POST to /__log instead of localhost:8787/log
```
**3. Last resort (local only)** - allow insecure content / disable mixed-content blocking in browser settings
### Chrome Extension Debugging
Content scripts run in an **isolated world** with strict CSP - they **cannot** directly fetch to `localhost:8787`. The solution is to relay logs through the background script (service worker).
**Content Script (sender):**
```javascript
// #region debug
const DEBUG_SESSION_ID = 'your-session-id-here';
const debugLog = (msg, data = {}, hypothesisId = null) => {
chrome.runtime.sendMessage({
type: 'DEBUG_LOG',
payload: {
sessionId: DEBUG_SESSION_ID,
msg,
data,
hypothesisId,
loc: new Error().stack?.split('\n')[2]?.trim(),
},
}).catch(() => {});
};
// #endregion
// Usage
debugLog('handleMouseMove', { target: target.tagName, rect }, 'H1');
```
**Background Script (relay):**
```javascript
// #region debug - relay logs to debug server
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'DEBUG_LOG') {
fetch('http://localhost:8787/log', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(message.payload),
}).catch(() => {});
sendResponse({ ok: true });
return true;
}
});
// #endregion
```
**Why this works:**
- Background scripts (service workers) have relaxed CSP and can fetch to localhost
- `chrome.runtime.sendMessage` is the bridge between content script and background
- Keep both debug regions tagged for easy cleanup
**Injected scripts (MAIN world):**
If debugging code injected via `<script>` into the page context, use `window.postMessage` to relay to content script, which then relays to background:
```javascript
// In MAIN world (injected script)
window.postMessage({ type: 'DEBUG_LOG_RELAY', payload: { ... } }, '*');
// In content script
window.addEventListener('message', (e) => {
if (e.data?.type === 'DEBUG_LOG_RELAY') {
chrome.runtime.sendMessage({ type: 'DEBUG_LOG', payload: e.data.payload });
}
});
```
## Checklist
- [ ] Server running (started or already_running)
- [ ] Session created via `POST /session` - save the returned `session_id`
- [ ] 3-5 hypotheses generated
- [ ] 3-8 logs added, tagged with hypothesisId
- [ ] Logs cleared before reproduction
- [ ] Reproduction steps provided
- [ ] Each hypothesis evaluated (CONFIRMED/REJECTED/INCONCLUSIVE)
- [ ] Fix based on evidence only
- [ ] Before/after comparison done
- [ ] Instrumentation removed after confirmationRelated Skills
debug
Systematic root-cause debugging for any bug — backend, frontend, logic, integration. Hypothesis-driven investigation with evidence collection. Use when the user says 'debug', 'investigate', 'why is this broken', 'root cause', 'trace this bug', 'figure out why', 'this doesn't work', or 'unexpected behavior'. For frontend-specific runtime debugging with a log server, use /debug-mode instead.
ship-it
Create a GitHub PR with conventional format and AI session context. Use when user says 'create PR', 'open PR', 'submit changes', 'send to dev', 'ship it', or is done with their task.
roast-my-code
Brutally honest code review with comedic flair. Roasts the sins, then redeems the sinner. Use when the user says "roast my code", "roast this", "tear this apart", "be brutal", "savage review", "destroy my code", "flame this", or wants entertaining but actionable code feedback. Also triggers on "what's wrong with this code" with a casual tone, "how bad is this", or "rate my code".
roast-my-agents-md
Brutally honest AGENTS.md/CLAUDE.md review backed by real A/B test evidence. Not just opinions — actual proof that your rules are dead weight. Roasts instruction files for bloat, slop, and redundancy, then proves it by running evals. Use when user says "roast my agents.md", "roast my CLAUDE.md", "prove my rules are useless", "eval roast", or wants entertaining evidence-based feedback on their AI config files. Also triggers on "audit my instructions" or "are my rules helping".
rfc-research
Research a technical topic and produce an RFC document backed by real code evidence from GitHub. Use when user says 'write an RFC', 'RFC research', 'create RFC for', 'technical proposal', 'design doc', 'investigate X', 'research X and write a proposal', 'architecture decision record', 'ADR', or needs a structured technical decision document with prior art analysis.
retro
Weekly engineering retrospective. Analyzes commit history, work patterns, and code quality metrics with persistent trend tracking. Team-aware: per-person contributions with praise and growth areas. Use when asked to 'weekly retro', 'what did we ship', 'engineering retrospective', 'how was this week', or 'show me the commit stats'. Proactively suggest at the end of a work week or sprint.
hetzner-codex-remote
Prepare a Hetzner Cloud VPS for secure Codex remote SSH access. Use when the user wants to create or configure a Hetzner server for Codex remote control, fix "No codex found in PATH" on a remote machine, install agent development tooling on a VPS, harden SSH access to a Hetzner server, or connect the server through Codex Settings, Connections, Add SSH.
grill-me
Structured adversarial review that pushes back on a plan, challenges the premise, compares alternatives, and stress-tests the design until the main risks are explicit. Use when the user asks to "grill me", stress-test a plan, poke holes in an approach, challenge assumptions, pressure-test a design, or validate an early-stage idea before building ("I have an idea", "is this worth building", "grill me on this idea").
fix-pr-comments
Handle feedback from PR reviewers. For each inline thread: reply on-thread and resolve after user approves. Use when developers left comments on your PR and you need to address them. Triggers on 'address comments', 'fix PR feedback', 'what did the reviewer say', 'handle review', 'resolve comments', 'comments from dev', 'dev feedback'.
design-review
Designer's eye visual audit of a live site — finds typography issues, spacing violations, AI slop patterns, hierarchy problems, interaction state gaps — then fixes them with atomic commits and before/after screenshots. Use when asked to 'audit the design', 'visual QA', 'design polish', 'does this look good', 'check the UI', or 'fix the design'. Proactively suggest when the user mentions visual inconsistencies or wants to polish a live site before shipping.
chat-history
Search previous AI chat conversations from Cursor IDE and Claude Code by content, affected file, or project. Use when the user asks about previous conversations, wants to find how they solved something before, or needs to recall past AI interactions.
batch
Parallel work orchestration — decompose large changes into 5-30 worktree agents that each open a PR. Use when the user says 'batch', 'do this in parallel', 'split into PRs', 'bulk change', 'mass refactor', or wants a sweeping mechanical change across many files.