debugging-code
Interactively debug source code — set breakpoints, step through execution line by line, inspect live variable state, evaluate expressions against the running program, and navigate the call stack to trace root causes. Use when a program crashes, raises unexpected exceptions, produces wrong output, when you need to understand how execution reached a certain state, or when print-statement debugging isn't revealing enough.
What this skill does
# Interactive Debugger
Use when a program crashes, produces wrong output, or you need to understand exactly
how execution reached a particular state — and running it again with more print statements
won't give you the answer fast enough.
You can pause a running program at any point, read live variable values and the call stack
at that exact moment, step forward line by line or jump to the next breakpoint, and
evaluate arbitrary expressions against the live process — all without restarting.
## Setup
This skill uses `dap`, a CLI tool that background daemon to interact with the debugger via the DAP Protocol, maintain
the debugger state, so you can simply interact with it with multiple calls.
If `dap` isn't installed (check: `command -v dap`), install it NOW.
Ask/notify the user before proceeding to install it.
From Homebrew (macOS)
```bash
brew install AlmogBaku/tap/dap
```
Installer script:
```bash
bash scripts/install-dap.sh
```
Install from sources:
```bash
go install github.com/AlmogBaku/debug-skill/cmd/dap@latest
```
This tool is open-sourced and available on [GitHub](https://github.com/AlmogBaku/debug-skill), maintained and follows
best practices.
Supports natively Python, Go, Node.js/TypeScript, Rust, C/C++, and any other language that supports DAP.
If a debugger backend is missing or fails to start, see `references/installing-debuggers.md`
For all commands and flags: `dap --help` or `dap <cmd> --help`.
## Starting a Session
`dap debug <file>` launches the program under the debugger. Backend is auto-detected from the file extension.
Choose your starting strategy based on what you know:
- **Have a hypothesis** — set a breakpoint where you expect the bug: `dap debug script.py --break script.py:42`
- **Conditional breakpoint** — only stop when a condition is met: `dap debug script.py --break "script.py:42:x > 5"` (
always quote specs with conditions)
- **Multi-file app** — breakpoints across modules: `--break src/api/routes.py:55 --break src/models/user.py:30`
- **No hypothesis, small program** — walk from entry: `dap debug script.py --stop-on-entry` (avoid for large projects —
startup code is noisy; bisect with breakpoints instead)
- **Exception, location unknown** — `dap debug script.py --break-on-exception raised` (Python) / `all` (Go/JS)
- **Remote process** — `dap debug --attach host:port --backend <name>`
- **Process already running (stuck server, live issue)** — attach without restarting:
`dap debug --pid <PID> --backend <name>`
> **macOS + Go gotcha:** `dlv --pid` requires SIP disabled (`csrutil disable`).
> Prefer starting the program under the debugger instead or attaching to a remote debugger!
**Session isolation:** `--session <name>` keeps concurrent agents from interfering.
Tip: You might want to use your session id(${CLAUDE_SESSION_ID}) if available.
Run `dap debug --help` for all flags, backends, and examples.
## The Debugging Mindset
Reach for a debugger when reading source alone can't validate the root cause.
A debugger lets you *observe* what *does* happen: actual values, actual path, actual state.
When that diverges from what *should* happen, you've found your bug.
**Two strikes, rethink.** If two hypotheses fail at the same location, your mental model is wrong.
Re-read the code, form a *completely different* theory with different breakpoints.
**Escalate gradually.** Start with `dap eval` to test a quick hypothesis. Use conditional breakpoints
to filter noise. Fall back to full breakpoints + stepping only when you need interactive control.
**Mimic the user journey.** If you're debugging a user flow, set breakpoints along the path you expect the code to take.
If you expected `compute()` to be called, but it never is, then the bug is in the caller — not `compute()`, but whatever
was supposed to call it.
**Set breakpoints instead of prints.** When you feel the urge to print something, set a breakpoint instead.
## Know Your State
Every `dap` execution command returns full context automatically: current location, source, locals, call stack, and
output. At each stop, ask:
- Do the local variables have the values I expected?
- Is the call stack showing the code path I expected?
- Does the output so far reveal anything unexpected?
**Trace causation up the stack.** If a value is wrong at frame 0, check `dap eval "<expr>" --frame 1` to see what the
caller passed. Keep going up (`--frame 2`, `--frame 3`) until you find the frame where the value first became wrong —
that's the origin of the bug, not the symptom.
Example output at a stop:
```
Stopped at compute() · script.py:41
39: def compute(items):
40: result = None
> 41: return result
Locals: items=[] result=None
Stack: main [script.py:10] → compute [script.py:41]
Output: (none)
```
If the program exits before hitting your breakpoint:
```
Program terminated · Exit code: 1
```
→ Move breakpoints earlier, or restart with `--stop-on-entry`.
## Forming a Hypothesis
Before setting a breakpoint: *"I believe the bug is in X because Y."* A good hypothesis is falsifiable — your next
observation will confirm or disprove it. No hypothesis yet? Bisect with two breakpoints to narrow the search space, or
see starting strategies above.
## Setting Breakpoints Strategically
- Set where the problem *begins*, not where it *manifests*
- Exception at line 80? Root cause is upstream — start earlier
- Uncertain? Bisect: `--break f:20 --break f:60` — wrong state before or after halves the search space
**Where to break:**
- **Boundaries** — where data crosses a format, representation, or module boundary; state is cleanest here
- **State transitions** — the line that assigns or mutates the corrupted value
- **Wrong branch** — the condition whose inputs led to the bad path
- **Antipatterns** — don't break inside library code; break at the call site instead. Don't use unconditional breaks in
tight loops — use conditions.
### Managing Breakpoints Mid-Session
As you learn more, add breakpoints deeper in the suspect code and remove ones that have
served their purpose — progressive narrowing without restarting:
```bash
dap continue --break app.py:50 # add breakpoint deeper, then continue
dap continue --remove-break app.py:20 # drop a breakpoint you're done with
dap break add app.py:42 app.py:60 # add multiple breakpoints at once
dap break list # see what's set
dap break clear # start fresh
```
If a breakpoint is on an invalid line or the adapter adjusts it, `dap` warns you in the output.
### Conditional Breakpoints
Stop only when a condition is true — essential for loops, hot paths, and specific input values.
Syntax: `"file:line:condition"` (always quote).
```bash
dap debug app.py --break "app.py:42:i == 100" # skip 99 iterations, stop on the one that matters
dap debug app.py --break "app.py:30:user_id == 123" # reproduce a user-specific bug
dap continue --break "app.py:50:len(items) == 0" # catch the empty-list case mid-session
```
### Invariant Breakpoints
Conditional breakpoints as runtime assertions — stop the *moment* something goes wrong:
```bash
dap debug app.py --break "bank.py:68:balance < 0" # catch the overdraft
dap debug app.py --break "pipe.py:30:type(val) != int" # type violation
```
## Navigating Execution
At each stop, choose how to advance based on what you suspect:
If you're stepping more than 3 times in a row, you need a breakpoint, not more steps.
```bash
dap step # step over — trust this call, advance to next line
dap step in # step into — suspect what's inside this function
dap step out # step out — you're in the wrong place, return to caller
dap continue # jump to next breakpoint
dap continue --to file:line # run to line (temp breakpoint, auto-removed)
dap context # re-inspect cuRelated in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.