diff --git a/explain/claude_code_plugin/.claude-plugin/plugin.json b/explain/claude_code_plugin/.claude-plugin/plugin.json index 9c8794c..e887532 100644 --- a/explain/claude_code_plugin/.claude-plugin/plugin.json +++ b/explain/claude_code_plugin/.claude-plugin/plugin.json @@ -12,5 +12,18 @@ "command": "${CLAUDE_PLUGIN_ROOT}/run.sh", "args": [] } + }, + "hooks": { + "PreToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/explain/claude_code_plugin/hooks/check_debugger_usage.sh" + } + ] + } + ] } } diff --git a/explain/claude_code_plugin/hooks/check_debugger_usage.sh b/explain/claude_code_plugin/hooks/check_debugger_usage.sh new file mode 100755 index 0000000..aa8876b --- /dev/null +++ b/explain/claude_code_plugin/hooks/check_debugger_usage.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# +# Block direct invocation of `udb`, `live-record`, `undo`, or opening `.undo` files. +# These should only be used via the plugin's MCP tools. + +set -euo pipefail + +# Check if `jq` is available; if not, skip checks and allow the command. +if ! command -v jq &> /dev/null; then + exit 0 +fi + +# Read JSON input from stdin. +input=$(cat) +command=$(echo "$input" | jq -r '.tool_input.command // ""') + +# Block direct `udb` invocation. +if echo "$command" | grep -qE '\budb\b'; then + echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Use the /debug command or MCP debugging tools instead of invoking udb directly."}}' + exit 0 +fi + +# Block direct `live-record` invocation (including architecture-specific variants like `live-record_x64`). +if echo "$command" | grep -qE '\blive-record(_[a-z0-9]+)?\b'; then + echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Use the /record command or the record MCP tool instead of invoking live-record directly."}}' + exit 0 +fi + +# Block direct access to `.undo` recording files (check before `undo` to get the right message). +if echo "$command" | grep -qE '\.undo\b'; then + echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Do not access Undo recordings directly. Use the /debug command or MCP debugging tools."}}' + exit 0 +fi + +# Block direct `undo` invocation. +if echo "$command" | grep -qE '\bundo\b'; then + echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Use the plugin commands (/debug, /record) or MCP tools instead of invoking undo directly."}}' + exit 0 +fi + +# Allow other commands. +exit 0 diff --git a/skills/debugging-with-undo/SKILL.md b/skills/debugging-with-undo/SKILL.md new file mode 100644 index 0000000..e8bc7ad --- /dev/null +++ b/skills/debugging-with-undo/SKILL.md @@ -0,0 +1,46 @@ +--- +name: debugging-with-undo +description: > + Debug programs using Undo time travel debugging. Record flaky tests, intermittent failures, + race conditions, or bugs that don't reproduce reliably. Analyze recordings by traveling + backwards through execution history. Use when the user mentions debugging, flaky tests, + intermittent bugs, race conditions, `.undo` files (Undo recordings), or asks why something + happened in an actual run. This can provide similar results as adding logging statements, + but without modifying the code or needing to re-run the program multiple times. +--- + +# Debugging with Undo time travel debugger + +Undo provides time travel debugging for Linux programs. This Skill guides you to: +1. **Record** program execution to capture failures (especially intermittent ones) +2. **Debug** recordings by traveling backwards through execution history + +## When to record (use `record` MCP tool) + +Record program execution when the user: +- Has a **flaky test** or **intermittent failure** that doesn't reproduce reliably +- Mentions **race conditions**, **threading issues**, or **concurrency bugs** +- Wants to **capture a failure** for later analysis +- Needs **deterministic replay** of a bug + +Undo captures the exact execution including thread interleavings, making even race conditions +reproducible. + +## When to debug (use debugging MCP tools) + +Debug a recording when the user: +- Has a **`.undo` recording file** to investigate +- Asks **"why did this happen"** or **"how did this value get set"** +- Wants **root cause analysis** on a captured failure +- Needs to understand execution **backwards** from a crash or assertion + +## Workflow + +1. **If no recording exists**: Use `record` MCP tool to capture the failure +2. **If recording exists**: Use debugging MCP tools to analyze it +3. **Work backwards**: Start at the end (where the bug manifested), trace backwards + +## Important + +- **Never access `.undo` files directly** - they are opaque binary recordings +- **Never invoke `udb`, `live-record`, or `undo` via Bash** - use the Undo MCP tools