# Building Skills and Agents — Reference Guide This is the reference for building new skills and agents in this project. Read this before creating any SKILL.md or agent definition. ## When to Use What | Need | Use | Why | |------|-----|-----| | Always-true project rules | `rules/` file | Auto-loaded every session | | Reference material for specific areas | `context/` file | Loaded on-demand, saves tokens | | Repeatable workflow triggered by user | Skill (`/name`) | Loaded only when invoked | | Repeatable workflow triggered by Claude | Skill (auto-triggered) | Description-matched | | Isolated multi-step task | Agent (subagent) | Own context window, clean separation | | Heavy research or file reading | Agent | Keeps main context clean | | Parallel independent work | Multiple agents | Run simultaneously | | Persistent knowledge across sessions | Agent with `memory: project` | Maintains MEMORY.md | **Rule of thumb:** If it's a workflow Carson triggers → skill. If it's a task Claude delegates → agent. If it's always relevant → rule. If it's sometimes relevant reference material → context file. --- ## Skill Format (SKILL.md) ### Directory Structure ``` .claude/skills/{skill-name}/ ├── SKILL.md ← Required. Frontmatter + instructions. ├── templates/ ← Optional. Template files the skill copies/fills. ├── schemas/ ← Optional. JSON schemas for structured output. └── reference/ ← Optional. Reference docs the skill reads. ``` ### Frontmatter Fields ```yaml --- name: skill-name # Lowercase, hyphens only. Max 64 chars. description: >- # What it does + when to trigger. Max 1024 chars. One-line description Claude uses to decide whether to auto-invoke. Write in third person. Be "pushy" — undertriggering is more common. user_invocable: true # true = appears in /menu. false = Claude-only. argument: "required arg" # Hint shown during autocomplete. # argument-hint: "[optional args]" # Alternative field name (both work). disable-model-invocation: true # true = ONLY manual /invoke, never auto-triggered. allowed-tools: Read, Grep, Bash # Tool allowlist. Omit = all tools available. model: opus # sonnet | opus | haiku. Omit = inherit. effort: high # low | medium | high | max. Opus 4.6 only. context: fork # fork = isolated subagent. Omit = inline (sees conversation). agent: general-purpose # Subagent type when context: fork. Can be custom agent name. paths: "src/api/**" # Glob patterns — auto-activate when working on matching files. --- ``` ### Variable Substitutions (available in skill body) | Variable | Description | |----------|-------------| | `$ARGUMENTS` | All arguments passed when invoking | | `$0`, `$1`, `$2` | Positional arguments (0-indexed) | | `${CLAUDE_SKILL_DIR}` | Absolute path to this skill's directory | | `` !`command` `` | Shell command output injected at load time (preprocessing) | ### Skill Body Structure The markdown body below the frontmatter IS the prompt. Structure it as clear instructions: ```markdown --- (frontmatter) --- ## Context What this skill does and why. ## Inputs What $ARGUMENTS contains and how to parse it. ## Steps 1. Step one... 2. Step two... ## Output What to display/save when done. ``` ### Key Behaviors - **Progressive loading:** Only name + description (~100 tokens) loaded at startup. Full content loaded when invoked. - **Description budget:** All skill descriptions share 1% of context window. Keep descriptions under 250 chars. - **"ultrathink":** Include this word anywhere in skill content to enable extended thinking. - **Chaining:** Skills can instruct Claude to invoke other skills (e.g., "Next, run `/draft-email`"). Claude decides whether to follow through. - **No nesting:** Subagents spawned by skills CANNOT spawn their own subagents. --- ## Agent Format (.claude/agents/) ### File Location ``` .claude/agents/{agent-name}.md ``` Single markdown file. No subdirectory needed (unlike skills). ### Frontmatter Fields ```yaml --- name: agent-name # REQUIRED. Lowercase, hyphens. description: >- # REQUIRED. When to delegate to this agent. Describe what this agent does. Include "use proactively" for eager delegation. tools: Read, Glob, Grep, Bash # Tool allowlist. Omit = all tools. disallowedTools: Write, Edit # Tool denylist (applied before allowlist). model: sonnet # sonnet | opus | haiku | inherit. maxTurns: 20 # Max agentic turns before stop. memory: project # user | project | local. Persistent MEMORY.md. skills: # Skills injected at startup (by name). - api-conventions isolation: worktree # Run in temp git worktree (isolated repo copy). background: false # true = always run as background task. effort: high # low | medium | high | max. permissionMode: default # default | acceptEdits | dontAsk | bypassPermissions. hooks: # Lifecycle hooks scoped to this agent. PreToolUse: - matcher: "Bash" hooks: - type: command command: "./scripts/validate.sh" --- The markdown body IS the agent's system prompt. The agent sees ONLY this + environment details. It does NOT see the main conversation history. ``` ### Key Behaviors - **Auto-delegation:** Claude reads `description` and delegates matching tasks automatically. - **Explicit invocation:** User says "use the {name} agent" or @-mentions it. - **Session-wide:** `claude --agent {name}` makes every interaction use this agent. - **No nesting:** Agents CANNOT spawn other subagents. Only the main thread can use the Agent tool. - **Memory:** `memory: project` creates `.claude/agent-memory/{name}/MEMORY.md` that persists across conversations. Useful for agents that build knowledge over time. - **Isolation:** `isolation: worktree` gives the agent an isolated copy of the repo. Auto-cleaned if no changes made. --- ## This Project's Patterns When building skills/agents for Rut'n Buck, follow these established patterns: ### Supabase Access (inline Node.js via Bash) Every skill that touches the database uses this boilerplate: ```javascript node -e " const fs = require('fs'); const env = fs.readFileSync('.env','utf8'); env.split('\\n').forEach(l => { const [k,...v] = l.split('='); if (k && v.length) process.env[k.trim()] = v.join('=').trim(); }); const { createClient } = require('@supabase/supabase-js'); const sb = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_SERVICE_ROLE_KEY); // ... your query here " ``` This runs server-side with the service role key (bypasses RLS). Used for reads and writes. ### Helper Scripts (stdin + CLI flags) Reusable Node.js scripts live in `/scripts/`: - `save-research.js` — `--find "Name"` or `--update `, reads JSON from stdin via heredoc - `google-places.js` — positional args: `"Business Name" "Bozeman, MT"` When building new skills that save data, consider adding a helper script rather than inline Node.js if the save logic will be reused. ### Parallel Agents For research-heavy skills, spawn 2-3 agents simultaneously with different focuses: ``` Launch 3 Agent tool calls in parallel: - Agent 1: Reviews & Location (WebSearch + WebFetch) - Agent 2: Website & Menu (WebFetch the site) - Agent 3: Social & Digital (WebSearch for social profiles) ``` Each agent gets specific instructions and the Google Places data as shared context. ### Interactive Save Pattern Skills that generate content (emails, analyses) should: 1. Display the output formatted in the terminal 2. Ask Carson which option to save (or whether to save at all) 3. Only then write to Supabase ### State Machine Use a status column (e.g., `research_status`) to track progress: `not_started` → `running` → `done` / `failed` Skills should check status before proceeding and update it on completion. ### Output Format All skills display a formatted markdown summary in the terminal. Data is saved to Supabase, not local files. The terminal output is for Carson to review — the database is the source of truth. ### Composability Skills can reuse other skills' steps. Example: `/refresh-research` delegates to `/research-lead` Steps 2-4 rather than duplicating the logic. --- ## After Creating a New Skill or Agent 1. **Update CLAUDE.md** — Add the skill/agent to the appropriate list with a one-line description 2. **Update this file** — If the new skill introduces a pattern worth replicating, add it to "This Project's Patterns" 3. **Update `context/site-map.md`** — Add the new files 4. **Test it** — Invoke the skill/agent with a real example before considering it done --- ## Common Mistakes to Avoid - **Vague descriptions** — Claude won't auto-trigger if the description is generic. Be specific about WHEN to use it. - **Too many tools** — Restrict tools to what's needed. Read-only agents shouldn't have Write/Edit. - **Forked context without enough info** — `context: fork` agents don't see conversation history. Include everything they need in the skill body. - **Giant SKILL.md** — Keep under 500 lines. Move reference material to separate files in the skill directory and read them with `${CLAUDE_SKILL_DIR}`. - **Duplicating Supabase boilerplate** — If you're writing the same inline Node.js pattern, consider a helper script. - **Forgetting to update context system** — New skills/agents should be reflected in CLAUDE.md and relevant context files.