Use this skill when executing, testing, linting, debugging, or validating code in course materials. Provides Docker-based isolated sandbox infrastructure for safe code execution. Trigger phrases include "run code", "test code", "lint", "debug", "validate examples", "sandbox", "execute", "compile".
/plugin marketplace add NathanJGaul/plugins/plugin install dev-course-builder@njg-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Isolated development environment for safely executing, testing, linting, and debugging code examples in course materials. Each course shares a single persistent Docker container as its sandbox.
The sandbox system provides:
┌─────────────────────────────────────────────────────────────┐
│ Host System │
│ │
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
│ │ Course Files │ │ Docker Container │ │
│ │ │◄──►│ ┌─────────────────────────────┐│ │
│ │ /courses/ │ │ │ /workspace (mounted) ││ │
│ │ cpp-fund/ │ │ │ - chapters/ ││ │
│ │ rust-intro/ │ │ │ - exercises/ ││ │
│ │ │ │ │ - projects/ ││ │
│ └─────────────────┘ │ │ - .sandbox/ ││ │
│ │ └─────────────────────────────┘│ │
│ │ │ │
│ │ Tools: gcc, clang, gdb, lldb │ │
│ │ Linters: clang-tidy, cppcheck │ │
│ │ Test: gtest, catch2 │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
course-sandbox-{course-id}
Example: course-sandbox-cpp-fundamentals
# Check if container exists and its state
docker ps -a --filter "name=course-sandbox-{course-id}" --format "{{.Names}}: {{.Status}}"
# Check if running
docker inspect -f '{{.State.Running}}' course-sandbox-{course-id}
# Build image from course-specific Dockerfile
docker build -t course-sandbox-{course-id}:latest -f .sandbox/Dockerfile .
# Create and start container with mounted workspace
docker run -d \
--name course-sandbox-{course-id} \
-v "$(pwd):/workspace" \
-w /workspace \
--cap-drop=ALL \
--security-opt=no-new-privileges \
--memory=2g \
--cpus=2 \
--network=none \
course-sandbox-{course-id}:latest \
tail -f /dev/null
# Run a command in the sandbox
docker exec course-sandbox-{course-id} <command>
# Run with timeout (prevents infinite loops)
timeout 30s docker exec course-sandbox-{course-id} <command>
# Run interactively (for debugging)
docker exec -it course-sandbox-{course-id} /bin/bash
# Stop to save resources
docker stop course-sandbox-{course-id}
# Start when needed again
docker start course-sandbox-{course-id}
# Remove and recreate for clean slate
docker rm -f course-sandbox-{course-id}
# Then run create steps again
# Compile
docker exec course-sandbox-cpp-fundamentals \
g++ -std=c++20 -Wall -Wextra -Werror -o /tmp/prog /workspace/example.cpp
# Run
docker exec course-sandbox-cpp-fundamentals /tmp/prog
# Or combined with timeout
docker exec course-sandbox-cpp-fundamentals \
bash -c "g++ -std=c++20 -Wall -Wextra -o /tmp/prog /workspace/example.cpp && timeout 10s /tmp/prog"
# Compile
docker exec course-sandbox-rust-intro \
rustc -o /tmp/prog /workspace/example.rs
# Run
docker exec course-sandbox-rust-intro /tmp/prog
# Or with cargo
docker exec course-sandbox-rust-intro \
bash -c "cd /workspace/project && cargo run"
docker exec course-sandbox-python-basics \
timeout 10s python3 /workspace/example.py
# C++ with Google Test
docker exec course-sandbox-cpp-fundamentals \
bash -c "cd /workspace && cmake -B build && cmake --build build && ctest --test-dir build --output-on-failure"
# Rust with cargo
docker exec course-sandbox-rust-intro \
bash -c "cd /workspace && cargo test"
# Python with pytest
docker exec course-sandbox-python-basics \
bash -c "cd /workspace && python -m pytest -v"
# C++ with clang-tidy
docker exec course-sandbox-cpp-fundamentals \
clang-tidy /workspace/example.cpp -- -std=c++20
# C++ with cppcheck
docker exec course-sandbox-cpp-fundamentals \
cppcheck --enable=all --std=c++20 /workspace/example.cpp
# Rust with clippy
docker exec course-sandbox-rust-intro \
bash -c "cd /workspace && cargo clippy -- -D warnings"
# Python with ruff
docker exec course-sandbox-python-basics \
ruff check /workspace/example.py
# Start GDB session (interactive)
docker exec -it course-sandbox-cpp-fundamentals \
gdb /tmp/prog
# Run with sanitizers (compile with flags)
docker exec course-sandbox-cpp-fundamentals \
bash -c "g++ -std=c++20 -fsanitize=address,undefined -g -o /tmp/prog /workspace/example.cpp && /tmp/prog"
# Valgrind memory check
docker exec course-sandbox-cpp-fundamentals \
valgrind --leak-check=full /tmp/prog
All sandbox containers run with restricted permissions:
| Constraint | Setting | Purpose |
|---|---|---|
| Capabilities | --cap-drop=ALL | Remove all Linux capabilities |
| Privileges | --security-opt=no-new-privileges | Prevent privilege escalation |
| Memory | --memory=2g | Limit memory usage |
| CPU | --cpus=2 | Limit CPU usage |
| Network | --network=none | Disable network access |
| Read-only | Optional --read-only | Prevent filesystem modifications |
# Capture output to variable
output=$(docker exec course-sandbox-{course-id} ./prog 2>&1)
# Capture with exit code
docker exec course-sandbox-{course-id} ./prog > output.txt 2>&1
exit_code=$?
# Separate stdout and stderr
docker exec course-sandbox-{course-id} ./prog > stdout.txt 2> stderr.txt
# Run and compare
actual=$(docker exec course-sandbox-{course-id} ./prog 2>&1)
expected="Hello, World!"
if [ "$actual" = "$expected" ]; then
echo "PASS: Output matches"
else
echo "FAIL: Expected '$expected', got '$actual'"
fi
Always use timeouts to prevent infinite loops:
# Command timeout (10 seconds)
timeout 10s docker exec course-sandbox-{course-id} ./prog
# Check timeout exit code
if [ $? -eq 124 ]; then
echo "ERROR: Execution timed out (possible infinite loop)"
fi
Use /tmp inside the container for compiled binaries:
# Compile to /tmp (always writable)
docker exec course-sandbox-{course-id} \
g++ -o /tmp/example /workspace/example.cpp
# Run from /tmp
docker exec course-sandbox-{course-id} /tmp/example
# Clean up (optional, /tmp clears on container restart)
docker exec course-sandbox-{course-id} rm /tmp/example
# Capture compiler output
compile_output=$(docker exec course-sandbox-{course-id} \
g++ -std=c++20 -Wall -Wextra -o /tmp/prog /workspace/example.cpp 2>&1)
compile_status=$?
if [ $compile_status -ne 0 ]; then
echo "Compilation failed:"
echo "$compile_output"
fi
# Capture runtime output with exit code
run_output=$(docker exec course-sandbox-{course-id} /tmp/prog 2>&1)
run_status=$?
case $run_status in
0) echo "Success" ;;
139) echo "Segmentation fault (signal 11)" ;;
134) echo "Abort (signal 6)" ;;
124) echo "Timeout" ;;
*) echo "Exit code: $run_status" ;;
esac
For validating all code examples in a course:
#!/bin/bash
# validate-all-examples.sh
course_id="cpp-fundamentals"
container="course-sandbox-$course_id"
# Find all code files
find /workspace -name "*.cpp" | while read file; do
echo "Testing: $file"
# Compile
if docker exec $container g++ -std=c++20 -Wall -o /tmp/test "$file" 2>&1; then
echo " Compile: PASS"
# Run with timeout
if timeout 10s docker exec $container /tmp/test > /dev/null 2>&1; then
echo " Execute: PASS"
else
echo " Execute: FAIL (exit code $?)"
fi
else
echo " Compile: FAIL"
fi
done
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.