From claude-mods
Explains Claude Code internals: hooks, skills, headless mode, and debugging. Use when hooks don't fire, skills don't trigger, or you need to design an extension.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-mods:claude-code-opsWhen to use
Use for questions about Claude Code itself — e.g. 'my hook isn't firing', 'why won't this skill trigger', 'run claude headless in CI', 'plugin fails to validate', 'which settings file wins', 'should this be an agent or a skill', 'how do I design this extension'.
This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
One skill for the machinery of Claude Code itself: the **hook system**, the **skill format**, **headless/programmatic use**, and **debugging your configuration**. Replaces the former claude-code-hooks / claude-code-headless / claude-code-debug skills, refreshed against the June 2026 docs.
One skill for the machinery of Claude Code itself: the hook system, the skill format, headless/programmatic use, and debugging your configuration. Replaces the former claude-code-hooks / claude-code-headless / claude-code-debug skills, refreshed against the June 2026 docs.
Written against Claude Code ~v2.1.17x. These surfaces move fast — when precision matters, confirm against the live docs (links per section). Two contracts from older guides are dead: the
$TOOL_INPUTenv-var hook contract (hooks read stdin JSON now) and standalone command files as a separate system (commands merged into skills).
| You're doing | Load |
|---|---|
| Writing/fixing a hook; event contracts; blocking tools; audit logging | references/hooks-reference.md |
Authoring a skill; frontmatter fields; $ARGUMENTS; !`cmd` injection; triggering problems | references/skills-reference.md |
claude -p; CI scripts; output parsing; stream-json; structured output; background agents | references/headless-reference.md |
| Anything configured isn't taking effect; plugin validation; /doctor | references/debugging-reference.md |
| Designing a new extension — which surface to build, where to scope it, how to author the description/prompt | references/extension-architecture.md |
| Resource | Use |
|---|---|
| scripts/validate-hooks-json.py | Lint a hooks.json (or a settings.json "hooks" block) against the 30-event contract before trusting it |
| assets/hooks.json.template | Starter hooks.json — one of each common pattern (PreToolUse Bash, PostToolUse Edit|Write, SessionStart), ${CLAUDE_PLUGIN_ROOT}-rooted |
Validate a hooks file (offline, structural — catches the unknown-event and matcher-as-array footguns the docs warn about):
# Lint this repo's own plugin hooks file (default target if no path given):
python skills/claude-code-ops/scripts/validate-hooks-json.py hooks/hooks.json
# → exit 0 clean, 10 findings (lists them), 4 malformed JSON, 3 not-found.
# Machine-readable for CI:
python skills/claude-code-ops/scripts/validate-hooks-json.py --json hooks/hooks.json | jq '.data[]'
# --strict makes portability warnings (unrooted command paths) count as findings.
Start a new hooks file from assets/hooks.json.template — copy it, strip the // comment lines (the live hooks.json must be strict JSON), then validate the result with the script above.
claude -p (Agent SDK under the CLI).skills/, agents/, hooks/hooks.json, .mcp.json), manifest at .claude-plugin/plugin.json.Configure under the "hooks" key in ~/.claude/settings.json, .claude/settings.json, .claude/settings.local.json, plugin hooks/hooks.json, or skill/agent frontmatter:
{
"hooks": {
"PreToolUse": [
{ "matcher": "Bash",
"hooks": [{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/check.sh" }] }
]
}
}
Contract: JSON payload on stdin → respond with exit code (0 ok, 2 block + stderr feedback) and optional stdout JSON (continue, systemMessage, hookSpecificOutput.permissionDecision/updatedInput/additionalContext/...).
Events (full catalog + per-event schemas in the reference): SessionStart, SessionEnd, Setup, UserPromptSubmit, UserPromptExpansion, PreToolUse, PermissionRequest, PermissionDenied, PostToolUse, PostToolUseFailure, PostToolBatch, Stop, StopFailure, SubagentStart, SubagentStop, TaskCreated, TaskCompleted, TeammateIdle, Notification, MessageDisplay, ConfigChange, CwdChanged, FileChanged, PreCompact, PostCompact, InstructionsLoaded, WorktreeCreate, WorktreeRemove, Elicitation, ElicitationResult.
Hook types: command (sync/async/asyncRewake), http, mcp_tool, prompt, agent. Matchers are case-sensitive strings ("Edit|Write", regex allowed); if filters add permission-rule conditions like Bash(git *).
.claude/skills/<name>/SKILL.md (project) or ~/.claude/skills/<name>/SKILL.md (personal). Frontmatter fields beyond name/description: when_to_use, argument-hint, arguments, disable-model-invocation, user-invocable, allowed-tools, disallowed-tools, model, effort, context: fork + agent, hooks, paths, shell.
$ARGUMENTS, $ARGUMENTS[N], $N (0-based!), $name, ${CLAUDE_SKILL_DIR}, ${CLAUDE_SESSION_ID}, ${CLAUDE_EFFORT}.!`command` runs at load time and inlines output (dynamic context injection).when_to_use capped at 1,536 chars in the listing; listing budget = 1% of context window — /doctor reports overflow.claude --bare -p "query" --allowedTools "Read,Grep" --output-format json | jq -r '.result'
--bare for reproducible CI runs (skips hooks/skills/plugins/MCP/CLAUDE.md; auth via ANTHROPIC_API_KEY or claude setup-token).--output-format json → .result, .session_id, .is_error, .total_cost_usd, .num_turns; add --json-schema '<schema>' → .structured_output.stream-json (+ --verbose --include-partial-messages) for token streaming; system/init event lists loaded plugins/plugin_errors (assert in CI).--continue, --resume <id|name>, --fork-session; caps: --max-turns, --max-budget-usd.claude --bg "task", then claude agents --json / logs / attach / stop.Something configured isn't working
├─ What loaded? /context → then /memory /skills /agents /hooks /mcp /permissions
├─ Config valid? /doctor (invalid keys, schema errors, skill budget overflow)
├─ Which scope won? /status (managed > local > project > user; flags/env on top)
├─ Watch it live: claude --debug hooks | --debug mcp | --debug "api,hooks"
└─ Bisect: claude --safe-mode (customizations off)
└─ still broken → CLAUDE_CONFIG_DIR=/tmp/clean claude (nothing loads)
Fast classics: hooks belong in settings.json not ~/.claude.json; matcher is a case-sensitive string, not an array; skills need a folder + SKILL.md; .mcp.json at repo root; settings.local.json overrides settings.json; agent files on disk load at session start; claude plugin validate --strict in CI.
Markdown + YAML frontmatter in .claude/agents/ / ~/.claude/agents/ / plugin agents/ / --agents '<json>'. Required: name (the identity — filename doesn't matter), description. Optional: tools, disallowedTools, model (default inherit), permissionMode, maxTurns, skills (preloads full skill content), mcpServers, hooks, memory (user|project|local), background, effort, isolation: worktree, color, initialPrompt. Plugin agents ignore hooks/mcpServers/permissionMode. Built-in Explore/Plan skip CLAUDE.md. The Task tool was renamed Agent (v2.1.63; Task(...) rules still alias).
--help doesn't list them all)claude -p patternsclaude plugin CLInpx claudepluginhub 0xdarkmatter/claude-mods --plugin claude-modsQuick-reference for editing Claude Code skills, agents, slash commands, hooks, plugins, and configs. Triggers on YAML frontmatter, .claude/ files, Task tools, hook debugging.
Claude Code extensibility and configuration reference: plugins, hooks, skills, subagents, MCP servers, output styles, memory, settings, and model configuration. Invoke whenever Claude Code itself is the subject — questions, configuration, building extensions, debugging, or understanding internals.
Knowledge base on Claude Code formats, patterns, and configurations for commands, agents, skills, hooks, memory, plugins, settings. Use for creating, improving, auditing components.