node-inspect-debugger
Skill239 starsChanged 4 months agoMITView on GitHub
Debug Node.js via --inspect + Chrome DevTools Protocol CLI.
- Installs packages
We split this skill into the rules it gives an agent
8 rules. 0 are common, 2 are distinctive, and 6 are very specific to this project.
0
Common
Most of the 22 edited versions we read keep these.
2
Distinctive
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 18
When console.log isn't enough, drive Node's built-in V8 inspector programmatically from the terminal.
- Distinctive: line 75
When the process is already running (e.g.
- Very specific: line 106
When you want to automate — set many breakpoints, capture scope state, script a repro — use chrome-remote-interface:
- Very specific: line 200
When it pauses, repl → inspect props, state refs, useInput handler values, etc.
- Very specific: line 237
Use --no-file-parallelism (vitest) or --runInBand (jest) so only one worker exists — debugging a pool is painful.
- Very specific: line 268
Port collisions: Default is 9229. If multiple Node processes are inspecting, pass --inspect=0 (random port) and read the actual URL from …
- Very specific: line 275
Background kills: If you Ctrl+C out of node inspect while the target is paused, the target stays paused.
- Distinctive: line 283
After setting up a debug session, verify:
“Common” is measured: kept by at least 6 in 10 of the 22 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Node.js Inspect Debugger
Overview
When console.log isn't enough, drive Node's built-in V8 inspector programmatically from the terminal. You get real breakpoints, step in/over/out, call-stack walking, local/closure scope dumps, and arbitrary expression evaluation in the paused frame.
Two tools, pick one:
node inspect— built-in, zero install, CLI REPL. Best for quick poking.ndb/ CDP viachrome-remote-interface— scriptable from Node/Python; best when you want to automate many breakpoints, collect state across runs, or debug non-interactively from an agent loop.
Prefer node inspect first. It's always available and the REPL is fast.
When to Use
- A Node test fails and you need to see intermediate state
- ui-tui crashes or behaves wrong and you want to inspect React/Ink state pre-render
- tui_gateway child processes (
_SlashWorker, PTY bridge workers) misbehave - You need to inspect a value in a closure that
console.logcan't reach without patching - Perf: attach to a running process to capture a CPU profile or heap snapshot
Don't use for: things console.log solves in under a minute. Breakpoint-driven debugging is heavier; use it when the payoff is real.
Quick Reference: node inspect REPL
Launch paused on first line:
node inspect path/to/script.js
# or with tsx
node --inspect-brk $(which tsx) path/to/script.tsThe debug> prompt accepts:
| Command | Action |
c or cont | continue |
n or next | step over |
s or step | step into |
o or out | step out |
pause | pause running code |
sb('file.js', 42) | set breakpoint at file.js line 42 |
sb(42) | set breakpoint at line 42 of current file |
sb('functionName') | break when function is called |
cb('file.js', 42) | clear breakpoint |
breakpoints | list all breakpoints |
bt | backtrace (call stack) |
list(5) | show 5 lines of source around current position |
watch('expr') | evaluate expr on every pause |
watchers | show watched expressions |
repl | drop into REPL in current scope (Ctrl+C to exit REPL) |
exec expr | evaluate expression once |
restart | restart script |
kill | kill the script |
.exit | quit debugger |
In the repl sub-mode: type any JS expression, including access to locals/closure variables. Ctrl+C exits back to debug>.
Attaching to a Running Process
When the process is already running (e.g. a long-lived dev server or the TUI gateway):
# 1. Send SIGUSR1 to enable the inspector on an existing process
kill -SIGUSR1 <pid>
# Node prints: Debugger listening on ws://127.0.0.1:9229/<uuid>
# 2. Attach the debugger CLI
node inspect -p <pid>
# or by URL
node inspect ws://127.0.0.1:9229/<uuid>To start a process with the inspector from the beginning:
node --inspect script.js # listen on 127.0.0.1:9229, keep running
node --inspect-brk script.js # listen AND pause on first line
node --inspect=0.0.0.0:9230 script.js # custom host:portFor TypeScript via tsx:
node --inspect-brk --import tsx script.ts
# or older tsx
node --inspect-brk -r tsx/cjs script.tsProgrammatic CDP (scripting from terminal)
When you want to automate — set many breakpoints, capture scope state, script a repro — use chrome-remote-interface:
npm i -g chrome-remote-interface # or project-local
# Start your target:
node --inspect-brk=9229 target.js &Driver script (save as /tmp/cdp-debug.js):
const CDP = require('chrome-remote-interface');
(async () => {
const client = await CDP({ port: 9229 });
const { Debugger, Runtime } = client;
Debugger.paused(async ({ callFrames, reason }) => {
const top = callFrames[0];
console.log(`PAUSED: ${reason} @ ${top.url}:${top.location.lineNumber + 1}`);
// Walk scopes for locals
for (const scope of top.scopeChain) {
if (scope.type === 'local' || scope.type === 'closure') {
const { result } = await Runtime.getProperties({
objectId: scope.object.objectId,
ownProperties: true,
});
for (const p of result) {
console.log(` ${scope.type}.${p.name} =`, p.value?.value ?? p.value?.description);
}
}
}
// Evaluate an expression in the paused frame
const { result } = await Debugger.evaluateOnCallFrame({
callFrameId: top.callFrameId,
expression: 'typeof state !== "undefined" ? JSON.stringify(state) : "n/a"',
});
console.log('state =', result.value ?? result.description);
await Debugger.resume();
});
await Runtime.enable();
await Debugger.enable();
// Set a breakpoint by URL regex + line
await Debugger.setBreakpointByUrl({
urlRegex: '.*app\\.tsx$',
lineNumber: 119, // 0-indexed
columnNumber: 0,
});
await Runtime.runIfWaitingForDebugger();
})();Run it:
node /tmp/cdp-debug.jsHermes-specific note: chrome-remote-interface is NOT in ui-tui/package.json. Install it to a throwaway location if you don't want to dirty the project:
mkdir -p /tmp/cdp-tools && cd /tmp/cdp-tools && npm i chrome-remote-interface
NODE_PATH=/tmp/cdp-tools/node_modules node /tmp/cdp-debug.jsDebugging Hermes ui-tui
The TUI is built Ink + tsx. Two common scenarios:
Debugging a single Ink component under dev
ui-tui/package.json has npm run dev (tsx --watch). Add --inspect-brk by running tsx directly:
cd <hermes-agent-repo>/ui-tui
npm run build # produce dist/ once so transpile isn't needed on first load
node --inspect-brk dist/entry.js
# In another terminal:
node inspect -p <node pid>Then inside debug>:
sb('dist/app.js', 220) # or wherever the suspect render is
contWhen it pauses, repl → inspect props, state refs, useInput handler values, etc.
Debugging a running hermes --tui
The TUI spawns Node from the Python CLI. Easiest path:
# 1. Launch TUI
hermes --tui &
TUI_PID=$(pgrep -f 'ui-tui/dist/entry' | head -1)
# 2. Enable inspector on that Node PID
kill -SIGUSR1 "$TUI_PID"
# 3. Find the WS URL
curl -s http://127.0.0.1:9229/json/list | jq -r '.[0].webSocketDebuggerUrl'
# 4. Attach
node inspect ws://127.0.0.1:9229/<uuid>Interacting with the TUI (typing in its window) continues to advance execution; your debugger can pause it on a breakpoint at any sb(...).
Debugging _SlashWorker / PTY child processes
Those are Python, not Node — use the python-debugpy skill for them. Only Node portions (Ink UI, tui_gateway client, tsx-run tests under ui-tui/) use this skill.
Running Vitest Tests Under the Debugger
cd <hermes-agent-repo>/ui-tui
# Run a single test file paused on entry
node --inspect-brk ./node_modules/vitest/vitest.mjs run --no-file-parallelism src/app/foo.test.tsxIn another terminal: node inspect -p <pid>, then sb('src/app/foo.tsx', 42), cont.
Use --no-file-parallelism (vitest) or --runInBand (jest) so only one worker exists — debugging a pool is painful.
Heap Snapshots & CPU Profiles (Non-interactive)
From the CDP driver above, swap Debugger for HeapProfiler / Profiler:
// CPU profile for 5 seconds
await client.Profiler.enable();
await client.Profiler.start();
await new Promise(r => setTimeout(r, 5000));
const { profile } = await client.Profiler.stop();
require('fs').writeFileSync('/tmp/cpu.cpuprofile', JSON.stringify(profile));
// Open /tmp/cpu.cpuprofile in Chrome DevTools → Performance tab// Heap snapshot
await client.HeapProfiler.enable();
const chunks = [];
client.HeapProfiler.addHeapSnapshotChunk(({ chunk }) => chunks.push(chunk));
await client.HeapProfiler.takeHeapSnapshot({ reportProgress: false });
require('fs').writeFileSync('/tmp/heap.heapsnapshot', chunks.join(''));Common Pitfalls
- Wrong line numbers in TS source. Breakpoints hit the emitted JS, not the
.ts. Either (a) break in the builtdist/*.js, or (b) enable sourcemaps (node --enable-source-maps) and usesb('src/app.tsx', N)— but only with CDP clients that follow sourcemaps.node inspectCLI does not. --inspectvs--inspect-brk.--inspectstarts the inspector but doesn't pause; your script races past your first breakpoint if you attach too late. Use--inspect-brkwhen you need to set breakpoints before any code runs.- Port collisions. Default is
9229. If multiple Node processes are inspecting, pass--inspect=0(random port) and read the actual URL from/json/list:curl -s http://127.0.0.1:9229/json/list # lists all inspectable targets on the host - Child processes.
--inspecton a parent does NOT inspect its children. UseNODE_OPTIONS='--inspect-brk' node parent.jsto propagate to every child; be aware they all need unique ports (Node auto-increments whenNODE_OPTIONS='--inspect'is inherited). - Background kills. If you
Ctrl+Cout ofnode inspectwhile the target is paused, the target stays paused. Eithercontfirst, orkillthe target explicitly. - Running
node inspectthrough an agent terminal. It's a PTY-friendly REPL. In Hermes, launch it withterminal(pty=true)orbackground=true+process(action='submit', data='...'). Non-PTY foreground mode will work for one-shot commands but not for interactive stepping. - Security.
--inspect=0.0.0.0:9229exposes arbitrary code execution. Always bind to127.0.0.1(the default) unless you have an isolated network.
Verification Checklist
After setting up a debug session, verify:
curl -s http://127.0.0.1:9229/json/listreturns exactly the target you expect- First breakpoint actually hits (if it doesn't, you likely missed
--inspect-brkor attached after execution completed) - Source listing at pause shows the right file (mismatch = sourcemap issue, see pitfall 1)
exec process.pidinreplreturns the PID you meant to attach to
One-Shot Recipes
"Why is this variable undefined at line X?"
node --inspect-brk script.js &
node inspect -p $!
# debug>
sb('script.js', X)
cont
# paused. Now:
repl
> myVariable
> Object.keys(this)"What's the call path into this function?"
debug> sb('suspectFn')
debug> cont
# paused on entry
debug> bt"This async chain hangs — where?"
# Start with --inspect (no -brk), let it run to the hang, then:
debug> pause
debug> bt
# Now you see the stuck frameOther versions25 projects use a version of this.
Word for word · 3
- rmusser01/tldw-stuff★ 2100% same
- barzzly/BarzzLyp_Agent_Skills★ 1100% same
- nobodyohm-web/Thot★ 0100% same
Edited · 22
- clawdbot/clawdbot★ 394k15% same
- steipete/clawdis★ 394k15% same
- openclaw/openclaw★ 394k15% same
- moltbot/moltbot★ 393k15% same
- steipete/warelay★ 392k15% same
- moltbot/clawdbot★ 392k15% same
- molt-bot/clawdbot★ 391k15% same
- friuns2/openclaw-android-assistant★ 55615% same
- OpenClawAndroid/openclaw-android-assistant★ 55615% same
- bighamx/openclaw-android-node-apk★ 5915% same
12 more not listed
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
Used alongsideProjects with it also use discord-e2e, openclaw-repair-sweep and 7 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
molt-botSkilldiscord-e2e
Test Discord with Convex-leased QA bots: check credentials without a Gateway, exercise owned messages, or prove OpenClaw replies, files, threads, reactions, streaming, and typing. Distinguish API and Gateway evidence from manual user interactions.
Also in 8 projects that use this
molt-botSkillopenclaw-repair-sweep
Run scoped OpenClaw issue/PR repair campaigns: coordinate workers, prove root causes, and land or close verified work under the requested authority.
Also in 8 projects that use this
supermansuper563-opsSkillauto-qa
Continuously audit, live-test, and stress-test the current OpenClaw codebase across at least ten independently scoped subsystem lanes; default to 100 independently verified, landed root-cause fixes, maintain an evidence-backed report, and announce each merged pull request immediately. Use for OpenClaw-wide autonomous QA, live-provider campaigns, gateway, CLI, web, plugin, native-app, scenario, packaging, and extended soak testing.
Also in 8 projects that use this
clawsoulsSkillchannel-message-flows
Use when running QA Lab channel message flow evidence.
Also in 8 projects that use this
clawsoulsSkillclawdtributor
Use for OpenClaw clawtributors PR/issue triage: Discrawl discovery, live-open rechecks, deep review, topic grouping, and compact @handle/LOC/type/blast/verification summaries.
Also in 8 projects that use this
- +2 more from molt-bot
- +2 more from clawsouls
In this repository82 other files it gives its agents.
- AGENTS.mdAGENTS.md
- apple-notesSkill
- apple-remindersSkill
- findmySkill
- imessageSkill
- claude-codeSkill
- codexSkill
- computer-useSkill
- hermes-agentSkill
- merge-reconcilerSkill
- opencodeSkill
- architecture-diagramSkill
- ascii-artSkill
- ascii-videoSkill
- baoyu-infographicSkill
- claude-designSkill
- comfyuiSkill
- design-mdSkill
- excalidrawSkill
- humanizerSkill
- manim-videoSkill
- p5jsSkill
- popular-web-designsSkill
- pretextSkill
- sketchSkill
- songwriting-and-ai-musicSkill
- touchdesigner-mcpSkill
- sdlc-reviewSkill
- email-inbox-triageSkill
- himalayaSkill
- music-serverSkill
- portable-comfyuiSkill
- tts-serverSkill
- getting-startedSkill
- codebase-inspectionSkill
- github-authSkill
- github-code-reviewSkill
- github-issuesSkill
- github-issue-to-prSkill
- github-pr-workflowSkill
- github-repo-managementSkill
- lm-studioSkill
- gif-searchSkill
- songseeSkill
- youtube-contentSkill
- huggingface-hubSkill
- obsidianSkill
- airtableSkill
- boxSkill
- document-to-action-itemsSkill
- docxSkill
- google-workspaceSkill
- mapsSkill
- meeting-action-itemsSkill
- nano-pdfSkill
- notionSkill
- ocr-and-documentsSkill
- pdfSkill
- powerpointSkill
- product-price-monitorSkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

