hezaohezao/node-inspect-debugger
Debug Node.js via --inspect + Chrome DevTools Protocol.
npx skills add https://github.com/HezaoHezao/poirot --skill node-inspect-debugger
When console.log isn't enough, drive Node's built-in V8 inspector
programmatically from the terminal. Real breakpoints, step in/over/out,
call-stack walking, scope dumps, and arbitrary expression evaluation.
Prefer node inspect first. It's always available and the REPL is fast.
console.log can't reachDon't use for: things console.log solves in under a minute.
node inspect REPLLaunch paused on first line:
node inspect path/to/script.js
# or with tsx
node --inspect-brk $(which tsx) path/to/script.ts
The debug> prompt accepts:
| Command | Action |
|---------|--------|
| c | continue |
| n | next line (step over) |
| s | step into |
| o | step out |
| sb('file.js', line) | set breakpoint |
| cb('file.js', line) | clear breakpoint |
| watch('expr') | watch expression |
| exec('expr') | evaluate in paused frame |
| backtrace / bt | show call stack |
| list(N) | show N lines around current |
For automated debugging (many breakpoints, collect state across runs):
# Install
npm install chrome-remote-interface
# Launch node with inspect
node --inspect-brk=9229 path/to/script.js &
# Attach via script
node -e "
const CDP = require('chrome-remote-interface');
(async () => {
const client = await CDP({port: 9229});
const {Debugger, Runtime} = client;
await Debugger.enable();
await Runtime.enable();
Debugger.paused(({callFrames}) => {
console.log('Paused at:', callFrames[0].location);
// Inspect scope, evaluate expressions, etc.
});
// Set breakpoint
await Debugger.setBreakpointByUrl({lineNumber: 10, url: 'file:///path/to/script.js'});
await Debugger.resume();
})();
"
# Start with --inspect (no brk = doesn't pause on start)
node --inspect=9229 path/to/server.js
# Attach from another terminal
node inspect localhost:9229
# Start with inspect
node --inspect path/to/script.js
# In another terminal, capture profile
node -e "
const CDP = require('chrome-remote-interface');
(async () => {
const client = await CDP({port: 9229});
const {Profiler} = client;
await Profiler.enable();
await Profiler.start();
// Wait for workload...
await new Promise(r => setTimeout(r, 10000));
const {profile} = await Profiler.stop();
require('fs').writeFileSync('profile.cpuprofile', JSON.stringify(profile));
})();
"
# Load profile.cpuprofile in Chrome DevTools > Performance
--inspect doesn't pause; --inspect-brkpauses on first line. Use brk when you need to catch early code.
--inspect=9230.node inspect works with both, but ESM may show differentcall stack formatting.
--enable-source-maps for accurate mapping.
Take hezaohezao/node-inspect-debugger from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npm.
Without those the skill loads but fails at the first command.