Skip to content
AI & Agents
Skill

/node-inspect-debugger

Debug Node.js via --inspect + Chrome DevTools Protocol CLI.

From plugin
hermes-agent
245k58 skills
Install
$ npx -y skills add NousResearch/hermes-agent --skill node-inspect-debugger --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/node-inspect-debugger

Context preview

The summary Claude sees to decide when to auto-load this skill.

Debug Node.js via --inspect + Chrome DevTools Protocol CLI.

SKILL.md

node-inspect-debugger.SKILL.md
name: node-inspect-debugger
description: "Debug Node.js via --inspect + Chrome DevTools Protocol CLI."
version: 1.0.0
author: Hermes Agent
license: MIT
platforms: [linux, macos, windows]
metadata:
  hermes:
    tags: [debugging, nodejs, node-inspect, cdp, breakpoints, ui-tui]
    related_skills: [systematic-debugging, python-debugpy]

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 via `chrome-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.log` can'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.ts

The `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:port

For TypeScript via tsx:

node --inspect-brk --import tsx script.ts
# or older tsx
node --inspect-brk -r tsx/cjs script.ts

Programmatic 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.js

Hermes-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.js

Debugging 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
Read more
Ships withhermes-agent

The self-improving AI agent built by Nous Research. It's the only agent with a built-in learning loop — it creates skills from experience, improves them during use, nudges itself to persist knowledge, searches its own past conversations, and builds a

Get the whole plugin
Stats
244,172
Stars
50,487
Forks
Active
Maintenance
Python
Language
MIT
License
4d ago
Last commit
1y ago
Created
14d ago
Added

Repo: NousResearch/hermes-agent

Other skills on hermes-agent.