deno-debug-skill

内容来源:README.md(说明文档) · 原始地址 · 查看安装指南

原始内容

Deno Debugger Skill for Claude

Transform Claude into an interactive debugger for Deno/TypeScript applications.

This skill enables Claude to act as a debugging assistant that connects to Deno via the V8 Inspector Protocol, conducts systematic investigations, and generates comprehensive Markdown reports with evidence-based analysis.

🎯 What This Skill Does

Claude becomes your debugging partner that:

  1. Connects to your Deno app via Chrome DevTools Protocol
  2. Investigates using breakpoints, heap snapshots, and CPU profiling
  3. Tracks investigation reasoning with breadcrumbs (for complex cases)
  4. Analyzes data with native TypeScript (no external dependencies)
  5. Reports findings in clear Markdown with specific recommendations

🚀 Quick Start

1. Install the Skill

# Copy to Claude's skills directory
cp -r deno-debugger/ ~/.claude/skills/

# That's it! No dependencies to install - uses Deno stdlib only

2. Launch Your Deno App with Inspector

# Start with --inspect (attaches on port 9229)
deno run --inspect --allow-net --allow-read your-app.ts

# Or use --inspect-brk to pause at start
deno run --inspect-brk --allow-net --allow-read your-app.ts

3. Ask Claude to Debug

You: "My Deno app is leaking memory when processing file uploads. Can you investigate?"

Claude: *connects via CDP, systematically investigates, generates REPORT.md*

📖 Usage Examples

Memory Leak Investigation

You: "Memory grows with each upload and never gets released"

Claude will:
1. Connect to your Deno process (port 9229)
2. Capture baseline heap snapshot
3. Trigger the leak (asks you or does it programmatically)
4. Capture comparison snapshot
5. Calculate growth rate and project OOM timeline
6. Examine source code for retention patterns
7. Generate REPORT.md with:
   - Root cause analysis
   - Code snippets showing the bug
   - Named anti-pattern (e.g., "retain-and-forget")
   - Production impact ("OOM after 22,543 uploads")
   - Specific fix with reasoning

Performance Bottleneck

You: "My API responses are slow, can you profile it?"

Claude will:
1. Start CPU profiling
2. Exercise the slow endpoint
3. Identify hot functions
4. Analyze algorithm complexity
5. Generate REPORT.md with:
   - Performance measurements (2.5s → 0.02s)
   - Hot path analysis
   - Algorithm complexity comparison (O(n²) → O(n log n))
   - Optimized implementation
   - Speedup projection (~100x)

Race Condition / Async Bug

You: "Sometimes my async operations complete in wrong order"

Claude will:
1. Set breakpoints at async boundaries
2. Trace execution flow
3. Check for missing awaits
4. Identify the race condition
5. Generate REPORT.md with fix and synchronization strategy

📊 Output Artifacts

Every investigation generates output in a directory of your choice (commonly investigation_output/):

  • REPORT.md - Main investigation report (Markdown)
  • baseline.heapsnapshot - Heap before (for memory issues)
  • after.heapsnapshot - Heap after (for memory issues)
  • profile.cpuprofile - CPU profile data (for performance issues)
  • flamegraph.html - Interactive flamegraph visualization (optional)
  • investigation.json - Breadcrumb timeline (if used)

Example Report Structure

# Investigation Report

**Date**: 2025-11-08
**Issue**: Memory leak in file upload handler

## Summary
Upload handler retains ArrayBuffer objects in global array without cleanup.

## Root Cause
The `handleUpload()` function pushes buffers to `leakedBuffers[]` but never
removes them. Each upload adds ~47 KB that persists for the app lifetime.

## Details
[Code snippet showing the bug with context]
[Anti-pattern explanation]
[Production impact: "OOM after 22,543 uploads (~225 hours)"]

## Location
- File: `app.ts`
- Line: 22
- Function: `handleUpload()`

## Fix
[Optimized code with clear reasoning]
[Why this solution works]

## Data
- Growth: 47 KB per upload
- Projected OOM: After ~22,543 uploads

🏗️ Architecture

deno-debug-skill/
├── deno-debugger/           # The actual skill (copy this to ~/.claude/skills/)
│   ├── SKILL.md            # Instructions Claude reads (workflow + patterns)
│   ├── README.md           # Installation guide (for users)
│   ├── deno.json           # Deno configuration with tasks
│   └── scripts/            # Pre-written debugging infrastructure (TypeScript)
│       ├── cdp_client.ts   # Chrome DevTools Protocol client
│       ├── heap_analyzer.ts  # Heap snapshot parsing (fast mode for 900MB heaps)
│       ├── cpu_profiler.ts   # CPU profiling with O(n²) detection & flamegraphs
│       ├── concurrent_helper.ts  # Race condition testing utilities
│       ├── breadcrumbs.ts  # Investigation tracking (optional)
│       ├── report_gen.ts   # Markdown report generation
│       ├── types.ts        # V8 and CDP type definitions
│       └── deps.ts         # Deno stdlib dependencies
│
├── examples/
│   ├── scenarios/          # Interactive test scenarios (memory leak, performance)
│   └── breakfix/           # Debugging challenges (easy, medium, hard)
│
├── tests/                  # Test scripts and investigation examples
│   ├── investigate_easy_redesigned.ts  # Example investigation workflow
│   ├── test_cpu_profiling_analysis.ts  # CPU profiling test
│   └── test_race_condition_debugging.ts  # Race condition test
│
└── docs/                   # Implementation notes and analysis
    ├── breakfix-investigation.md      # Breakfix scenario evaluation
    ├── heap-performance.md            # Heap optimization analysis
    └── cpu-profiling-enhancements.md  # CPU profiling features

🔧 Core Components

CDP Client (cdp_client.ts)

Handles all communication with Deno's V8 Inspector:

import { CDPClient } from "./scripts/cdp_client.ts";

const client = new CDPClient("127.0.0.1", 9229);
await client.connect();
await client.enableDebugger();

// Set breakpoint
await client.setBreakpointByUrl("file:///app.ts", 42);

// Resume execution
await client.resume();

// When paused, inspect
const frames = client.getCallFrames();
const vars = await client.getScopeVariables(frames[0].callFrameId);

Features:

  • Native WebSocket API (no external dependencies)
  • Deno/Node runtime detection
  • Type-safe async/await API
  • Heap snapshot capture
  • CPU profiling
  • Breakpoint management

Heap Analyzer (heap_analyzer.ts)

Parse and analyze V8 heap snapshots:

import {
  loadSnapshot,
  compareSnapshots,
  compareSnapshotsFast
} from "./scripts/heap_analyzer.ts";

// Fast mode: 900MB snapshots in ~20 seconds (vs 3 hours!)
const comparison = await compareSnapshotsFast(
  "baseline.heapsnapshot",
  "after.heapsnapshot"
);
console.table(comparison.slice(0, 10));

// Full mode: When you need retaining paths
const snapshot = await loadSnapshot("heap.heapsnapshot");
const nodes = snapshot.getNodesByType("Array");
const paths = snapshot.getRetainingPath(nodes[0].id);

Features:

  • Fast mode for large heaps: 900MB in ~20s (540x faster than full mode)
  • Native Map/Array data structures (no pandas needed)
  • Fast node indexing and lookup
  • Retaining path analysis (full mode)
  • Growth comparison and leak detection

CPU Profiler (cpu_profiler.ts)

Profile CPU usage and find bottlenecks:

import {
  loadProfile,
  analyzeProfile,
  analyzeComplexity,
  saveFlamegraphHTML
} from "./scripts/cpu_profiler.ts";

const profile = await loadProfile("profile.cpuprofile");
const analysis = analyzeProfile(profile);

// Automatic O(n²) detection
const issues = analyzeComplexity(profile);
// Flags functions with >50% self time as critical

// Interactive flamegraph visualization
await saveFlamegraphHTML(profile, "flamegraph.html");

Features:

  • Hot function detection with self time vs total time analysis
  • Automatic O(n²) algorithmic complexity detection
  • Flamegraph HTML generation (speedscope compatible)
  • Common performance anti-pattern recognition
  • Call tree analysis
  • 10-30x faster bottleneck diagnosis

Breadcrumbs (breadcrumbs.ts)

Track investigation reasoning (optional, for complex investigations):

import { Breadcrumbs } from "./scripts/breadcrumbs.ts";

const bc = new Breadcrumbs();

// Track major milestones only
bc.addHypothesis("Memory leak in upload handler",
                 "User reports growth after uploads");

bc.addFinding("ArrayBuffer retention at line 22",
              { growth_mb: 0.05 },
              "critical");

bc.addDecision("Root cause identified",
               "Code shows missing cleanup");

await bc.save("investigation.json");

Use sparingly: Breadcrumbs track investigative reasoning, not every action. See SKILL.md for guidelines.

Report Generator (report_gen.ts)

Generate comprehensive Markdown reports:

import { MarkdownReport } from "./scripts/report_gen.ts";

const report = new MarkdownReport("Memory Leak Investigation", bc);

report.addSummary("Upload handler retains ArrayBuffer objects...");
report.addProblem("Memory grows continuously...");
report.addFinding({
  description: "ArrayBuffer objects not being released",
  severity: "critical",
  evidence: ["Heap snapshot shows 500+ retained ArrayBuffers"]
});
report.addRootCause("Global array retains all buffers", "...");
report.addFix("Remove the global array entirely", codeSnippet);

await report.save("REPORT.md");

🎓 Investigation Patterns

The skill includes three pre-defined patterns in SKILL.md:

Pattern A: Memory Leak

  1. Capture baseline heap
  2. Trigger leak
  3. Capture comparison
  4. Analyze growth
  5. Examine code
  6. Generate report

Pattern B: Performance Bottleneck

  1. Start CPU profiling
  2. Trigger slow operation
  3. Analyze hot functions
  4. Examine slow code
  5. Generate report with optimizations

Pattern C: Race Condition

  1. Set breakpoints at async boundaries
  2. Set pause on exceptions
  3. Trigger race
  4. Inspect state when paused
  5. Examine code for missing awaits

🎯 What Makes This Unique?

Pre-written Infrastructure

  • Robust CDP client, heap analyzer, profiler already implemented
  • Claude uses existing scripts, doesn't write custom debugging code
  • Focus on investigation logic, not protocol details

TypeScript/Deno Native

  • Zero external dependencies (Deno stdlib only)
  • Type-safe V8 data structures
  • Same runtime as apps being debugged
  • Simpler installation (no pip, no virtualenv)

Evidence-Based Reports

  • Every claim backed by data
  • Code snippets with line numbers
  • Production impact calculations (e.g., "OOM after 22,543 uploads")
  • Named anti-patterns (e.g., "brute-force", "retain-and-forget")

Confident Recommendations

  • Shows THE best solution (not "Option 1 vs Option 2")
  • Explains WHY the fix works
  • Includes complexity analysis for performance fixes

Quality Guidelines

SKILL.md enforces report quality:

  • Each section answers a different question (no repetition)
  • Specific metrics, not vague terms ("0.24s" not "slow")
  • Show the work (code snippets, calculations, reasoning)

🧪 Testing

Try the Skill with Scenarios

Test the skill with realistic debugging scenarios:

# Run a complete scenario
cd examples/scenarios/1_memory_leak/
./run.sh

# The script will:
# 1. Start a buggy Deno app with --inspect
# 2. Show you a prompt to give Claude
# 3. Let Claude investigate the bug end-to-end

Available scenarios:

  • 1_memory_leak/ - ArrayBuffer accumulation in upload handler
  • 2_performance/ - Inefficient algorithms needing optimization

See examples/scenarios/README.md for details.

Run Automated Tests

# Run all tests with Deno
cd deno-debugger
deno task test

# Or run specific tests
deno test scripts/heap_analyzer_test.ts -v

Test coverage:

  • ✅ CDP connection
  • ✅ Heap snapshot parsing
  • ✅ CPU profiling
  • ✅ Breadcrumb tracking
  • ✅ All analysis functions

🛠️ Advanced Usage

Custom Conditional Breakpoints

// Break only when condition is true
await client.setBreakpointByUrl("file:///app.ts", 42, 0, "fileSize > 1000000");

Watch Expressions

// Monitor value changes
while (!done) {
  const value = await client.evaluate("myVariable");
  console.log("Variable value:", value);
  await new Promise(resolve => setTimeout(resolve, 1000));
}

Manual Investigation

You can use the scripts directly for custom investigations:

import { CDPClient } from "./deno-debugger/scripts/cdp_client.ts";

async function investigate() {
  const client = new CDPClient("127.0.0.1", 9229);
  await client.connect();
  await client.enableDebugger();

  // Your custom investigation logic here

  await client.close();
}

await investigate();

📚 Documentation

User Documentation:

  • deno-debugger/SKILL.md - Complete workflow and patterns Claude follows
  • deno-debugger/README.md - Installation and usage guide
  • examples/scenarios/README.md - Interactive scenario guide
  • examples/breakfix/README.md - Debugging challenge scenarios
  • TESTING.md - Test suite documentation
  • CONTRIBUTING.md - Contribution guidelines

Implementation Notes (in docs/):

  • breakfix-investigation.md - Evaluation of breakfix scenarios and skill effectiveness
  • heap-performance.md - Analysis of heap snapshot optimization for large (900MB) heaps
  • cpu-profiling-enhancements.md - O(n²) detection and flamegraph implementation details

🤝 Contributing

Contributions welcome! You can:

  • Add new analysis functions to heap_analyzer.ts or cpu_profiler.ts
  • Create new investigation patterns in SKILL.md
  • Add more test scenarios to examples/scenarios/
  • Improve report quality guidelines
  • Add Deno tests for uncovered code paths

See CONTRIBUTING.md for details.

📄 License

MIT License - use freely for your debugging needs!

🎯 Next Steps

  1. Install the skill: Copy deno-debugger/ to ~/.claude/skills/
  2. No dependencies needed: Pure TypeScript using Deno stdlib
  3. Try a scenario: Run examples/scenarios/1_memory_leak/run.sh
  4. Debug your app: Start with --inspect and ask Claude!

Happy Debugging! 🐛🔍