| name | scaffold |
| description | Component scaffolding toolkit for creating skills, context:fork worker skills, and hooks within the unified wicked-garden plugin.
Generates complete, valid structures that pass validation out-of-the-box.
Use when creating new domain components, setting up boilerplate, or ensuring proper structure from the start.
|
Scaffold Tool
Quick-start generator for wicked-garden components. The plugin is skills-only:
the former commands/ and agents/ trees were absorbed into skills/, so this
tool scaffolds skills, workers, and hooks — never a commands/ or agents/ file.
Purpose
Generates production-ready component structures within the unified plugin:
- Skills — a sub-skill
skills/{domain}/{name}/SKILL.md (Tier-2 navigation + refs/)
- Worker skills — a standalone
context: fork worker skills/{domain}-{role}/SKILL.md (the former "agent"), dispatched via Skill(skill="wicked-garden-{domain}-{role}")
- Hooks — hooks.json entries with Python scripts
Former commands are now actions of the consolidated per-domain router
skill (skills/{domain}/SKILL.md); the command subcommand is retired and only
prints guidance for adding an action.
All scaffolded components pass validation immediately.
Usage
Interactive Mode
python .claude/skills/scaffolding/scripts/scaffold.py
Command Line Mode
python .claude/skills/scaffolding/scripts/scaffold.py skill \
--name my-skill \
--domain crew \
--description "What this skill does" \
--use-when "trigger conditions"
python .claude/skills/scaffolding/scripts/scaffold.py worker \
--name my-worker \
--domain platform \
--description "What this worker does" \
--tools "Read,Write,Bash"
python .claude/skills/scaffolding/scripts/scaffold.py command \
--name my-action \
--domain engineering \
--description "What this action does"
python .claude/skills/scaffolding/scripts/scaffold.py hook \
--event PreToolUse \
--script validate-tool-use \
--description "Validates tool usage"
Generated Paths
Components are placed in the skills-only layout at the repo root:
wicked-garden/ # Plugin root
├── skills/{domain}/{name}/ # Sub-skills
│ └── SKILL.md
├── skills/{domain}-{role}/ # Worker skills (context:fork — former agents)
│ └── SKILL.md
├── hooks/scripts/{name}.py # Hook scripts
└── hooks/hooks.json # Hook bindings (updated)
There is no commands/ or agents/ tree.
Naming Conventions
- Sub-skill id: the leaf directory name, routed by its domain skill
- Worker skill name:
wicked-garden-{domain}-{role} (dash-separated), declared
in frontmatter name: and dispatched via Skill(skill="…")
- Domain router skill name:
wicked-garden-{domain}
Action stub (former command-with-agent)
A former "command that dispatched to an agent" is now an action of the domain
router skill that dispatches to a worker skill. Copy the stub in
templates/plugin/command-with-agent.md into the router body and wire it with:
Skill(skill="wicked-garden-{domain}-{role}", args="… | target: <target>")
Skill Template
---
name: {skill-name}
description: |
What this skill does (capabilities).
Use when [trigger conditions and keywords].
---
# {Skill Title}
Brief introduction to the skill's purpose.
## Purpose
What problem this skill solves.
## Usage
Examples.
## References
- Related docs / source files
Worker Skill Template (context:fork)
---
name: wicked-garden-{domain}-{role}
description: What this worker specializes in
context: fork
allowed-tools: ["Read", "Write", "Bash"]
model: sonnet
color: blue
---
# {Worker Title}
You are the {Worker Title} worker, specialized in {domain}. You run in an
isolated context:fork subagent, dispatched via Skill(skill="…").
## Expertise
- Capability 1 / 2 / 3
## Working Style
1. Step 1 / 2 / 3
## Quality Standards
- Standard 1 / 2
## Constraints
- Constraint 1 / 2
context: fork worker skills are exempt from the ≤200-line Tier-2 cap — they
load into an isolated subagent context, not the parent.
Hook Template
hooks.json
{
"hooks": [
{
"event": "{event}",
"script": "scripts/{script-name}.py",
"description": "{description}",
"enabled": true
}
]
}
Hook Script
"""
{Event} hook for {plugin-name}.
Exit codes:
0 - Success, continue
2 - Blocking error (message sent to Claude)
Other - Non-blocking error (logged)
"""
import sys
import json
def main():
try:
data = json.loads(sys.stdin.read())
except json.JSONDecodeError:
print("Error: Invalid JSON input", file=sys.stderr)
sys.exit(1)
if data.get('tool') == 'Bash':
command = data.get('arguments', {}).get('command', '')
if 'rm -rf /' in command:
print("Blocked dangerous command: rm -rf /")
sys.exit(2)
sys.exit(0)
if __name__ == "__main__":
main()
Valid Domains
Domains are discovered dynamically from .claude-plugin/components.json
("domains"), falling back to the top-level directories under skills/
(excluding the {domain}-{role} worker dirs). New domains are valid as soon as
they appear in the manifest / skills tree.
Current domains: agentic, crew, data, engineering, jam, mem, persona, platform,
product, qe, search, smaht.
Template Variables
| Variable | Description | Example |
|---|
{{name}} | Component name (kebab-case) | risk-assessor |
{{title}} | Component name (Title Case) | Risk Assessor |
{{skill_name}} | Worker skill dash name | wicked-garden-qe-risk-assessor |
{{description}} | Brief description | Assess project risks |
{{domain}} | Area of expertise / domain | qe |
{{tools}} | Allowed-tools list (rendered) | "Read", "Write" |
Best Practices
Naming
- Use kebab-case for all names, max 64 characters
- No reserved prefixes (
claude-code-, anthropic-, official-)
- Worker skills carry the dash-qualified
wicked-garden-{domain}-{role} name
Structure
- Put reusable logic in
scripts/
- Use
skills/{domain}/ for the domain router + its actions (former commands)
- Use
skills/{domain}-{role}/ for context:fork worker skills (former agents)
- Use
hooks/ for deterministic event automation
Documentation
- Write clear, concise descriptions and include usage examples
- Document dependencies and configuration options
Security
- All scripts should use
${CLAUDE_PLUGIN_ROOT} for paths
- Quote shell variables:
"$VAR"
- Validate input before processing; no hardcoded secrets
Examples
Sub-skill only
python .claude/skills/scaffolding/scripts/scaffold.py skill \
--name validation-patterns \
--domain engineering \
--description "Input validation patterns" \
--use-when "reviewing input handling"
Worker skill (context:fork)
python .claude/skills/scaffolding/scripts/scaffold.py worker \
--name risk-assessor \
--domain qe \
--description "Assesses release risk" \
--tools "Read,Bash"
Hook with Script
python .claude/skills/scaffolding/scripts/scaffold.py hook \
--event PreToolUse \
--script validate-tool-use \
--description "Validate tool use before execution"
References
- Naming conventions:
.claude/CLAUDE.md (Naming Conventions section)
- Component manifest:
.claude-plugin/components.json (domains + skills)
- Cross-tool context: Plugins that read project descriptor files should load
AGENTS.md before CLAUDE.md (general → specific). AGENTS.md is read-only.