Virtual test environment for Claude Code hooks, plugins, and agents. Use when testing or validating plugin components without affecting production.
From forge-editornpx claudepluginhub chkim-su/forge-editor --plugin forge-editorThis skill uses the workspace's default tool permissions.
templates/create-test-env.shtemplates/e2e-test-runner.pytemplates/e2e-tests.yamltemplates/test-runner.pytemplates/tests/hook-tests.yamlSearches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides implementation of event-driven hooks in Claude Code plugins using prompt-based validation and bash commands for PreToolUse, Stop, and session events.
Create isolated virtual test environments to verify hooks, plugins, and agents work correctly.
# Create test environment
/forge-editor:test-env hook # Hook test environment
/forge-editor:test-env plugin # Full plugin test
/forge-editor:test-env agent # Agent test
# Run tests
/forge-editor:run-tests /tmp/test-env
/tmp/plugin-test-{uuid}/
├── .claude/
│ ├── settings.json # Hook configurations
│ └── hooks/
│ ├── *.sh # Hook scripts
│ └── logs/ # Execution logs
├── .claude-plugin/
│ └── plugin.json # Plugin metadata
├── commands/
│ └── *.md # Slash commands
├── skills/
│ └── */SKILL.md # Skills
├── agents/
│ └── *.md # Agent definitions
├── run-tests.sh # Test runner
└── TEST-RESULTS.md # Results
Verify hook scripts respond correctly to events.
Test Cases:
| Test | Input | Expected |
|---|---|---|
| Block dangerous command | rm -rf / | permissionDecision: "deny" |
| Modify input | npm publish | updatedInput with --dry-run |
| Auto-allow safe | echo hello | permissionDecision: "allow" |
| Log success | PostToolUse + success | success: true in log |
| Log failure | PostToolUse + error | success: false in log |
| Context inject | UserPromptSubmit | stdout becomes context |
| Stop control | Stop + incomplete | decision: "block" |
Hook Test JSON Format:
{
"session_id": "test-001",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {"command": "rm -rf /important"},
"cwd": "/tmp/test"
}
Verify plugin structure and component registration.
Validation Checks:
.claude-plugin/plugin.json exists and validcommands/*.md have correct frontmatterskills/*/SKILL.md have correct structureagents/*.md have correct formathooks/hooks.json is valid (if exists)Plugin Structure Validation:
# Check required fields in plugin.json
jq -e '.name and .description' .claude-plugin/plugin.json
# Validate command frontmatter
for cmd in commands/*.md; do
grep -q "^description:" "$cmd"
done
Verify agent definitions and tool access.
Agent Test Cases:
| Test | Check |
|---|---|
| Tool list valid | All tools exist in Claude Code |
| Description present | Non-empty description |
| Prompt template | Valid prompt structure |
| Model specification | Valid model (sonnet/opus/haiku) |
create_test_env() {
local TYPE="$1" # hook, plugin, agent, full
local TEST_DIR="/tmp/plugin-test-$(date +%s)"
mkdir -p "$TEST_DIR/.claude/hooks/logs"
mkdir -p "$TEST_DIR/.claude-plugin"
mkdir -p "$TEST_DIR/commands"
mkdir -p "$TEST_DIR/skills/test-skill"
mkdir -p "$TEST_DIR/agents"
# Generate based on type
case "$TYPE" in
hook) generate_hook_tests "$TEST_DIR" ;;
plugin) generate_plugin_tests "$TEST_DIR" ;;
agent) generate_agent_tests "$TEST_DIR" ;;
full) generate_all_tests "$TEST_DIR" ;;
esac
echo "$TEST_DIR"
}
run_tests() {
local TEST_DIR="$1"
local RESULTS="$TEST_DIR/TEST-RESULTS.md"
echo "# Test Results" > "$RESULTS"
echo "Date: $(date)" >> "$RESULTS"
# Hook tests
if [ -d "$TEST_DIR/.claude/hooks" ]; then
run_hook_tests "$TEST_DIR" >> "$RESULTS"
fi
# Plugin validation
if [ -f "$TEST_DIR/.claude-plugin/plugin.json" ]; then
validate_plugin "$TEST_DIR" >> "$RESULTS"
fi
# Agent validation
if [ -d "$TEST_DIR/agents" ]; then
validate_agents "$TEST_DIR" >> "$RESULTS"
fi
cat "$RESULTS"
}
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
# Block dangerous patterns
if echo "$COMMAND" | grep -qE "rm\s+-rf\s+/"; then
jq -n '{
"hookSpecificOutput": {
"permissionDecision": "deny"
},
"systemMessage": "Dangerous command blocked"
}'
exit 0
fi
exit 0
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
RESPONSE=$(echo "$INPUT" | jq -c '.tool_response // {}')
SUCCESS=true
echo "$RESPONSE" | grep -qiE "(error|failed)" && SUCCESS=false
jq -n --arg tool "$TOOL_NAME" --argjson success "$SUCCESS" \
'{tool: $tool, success: $success, timestamp: now|todate}'
#!/bin/bash
INPUT=$(cat)
# stdout becomes Claude context
echo "=== Test Context ==="
echo "Environment: TEST"
echo "Time: $(date)"
echo "==================="
exit 0
{
"name": "string (required)",
"description": "string (required)",
"version": "string (optional)",
"author": {
"name": "string",
"email": "string"
}
}
---
description: Required description
argument-hint: Optional hint
allowed-tools: ["Tool1", "Tool2"]
---
skills/skill-name/
├── SKILL.md # Required
└── references/ # Optional
└── *.md
---
description: Agent description
allowed-tools: ["Read", "Write", "Bash"]
model: haiku # or sonnet, opus
---
# Agent Name
Agent prompt content...
Read, Write, Edit, Bash, Glob, Grep, Task,
TodoWrite, WebFetch, WebSearch, AskUserQuestion,
NotebookEdit, NotebookRead, KillShell, Skill
# Simulate PreToolUse event
echo '{"hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"rm -rf /"}}' | \
./hook-script.sh
# Quick validation
test -f .claude-plugin/plugin.json && \
jq -e '.name' .claude-plugin/plugin.json && \
echo "Plugin valid"
# Check agent frontmatter
head -10 agents/my-agent.md | grep -E "^(description|allowed-tools|model):"
# Test Results
Date: 2026-01-02
## Hook Tests
- ✅ Block dangerous rm
- ✅ Modify npm publish
- ✅ Auto-allow safe commands
- ✅ Log tool usage
## Plugin Validation
- ✅ plugin.json valid
- ✅ Commands have frontmatter
- ✅ Skills structured correctly
## Agent Validation
- ✅ All agents have descriptions
- ✅ Tool lists valid
## Summary
- Passed: 10/10
- Failed: 0/10
# .github/workflows/test-plugin.yml
name: Plugin Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create test environment
run: ./scripts/create-test-env.sh
- name: Run tests
run: ./scripts/run-tests.sh
- name: Upload results
uses: actions/upload-artifact@v4
with:
name: test-results
path: TEST-RESULTS.md