Agent Skills: Maintaining Claude Code

Validate and improve Claude Code configurations (CLAUDE.md, skills, commands, hooks). Use when auditing config quality, checking skill discoverability, organizing .claude directory, or deciding which entity type to use.

UncategorizedID: TrevorS/dot-claude/maintaining-claude-code

Install this agent skill to your local

pnpm dlx add-skill https://github.com/TrevorS/dot-claude/tree/HEAD/.claude/skills/maintaining-claude-code

Skill Files

Browse the full folder contents for maintaining-claude-code.

Download Skill

Loading file tree…

.claude/skills/maintaining-claude-code/SKILL.md

Skill Metadata

Name
maintaining-claude-code
Description
Audit and improve Claude Code hooks, rules, and settings.json. Use when adding/debugging a hook, organizing rules, auditing settings.json (permissions, env vars, stale flags), or deciding between hook vs skill vs rule vs CLAUDE.md. For SKILL.md authoring use the skill-creator plugin; for CLAUDE.md audits use the claude-md-improver plugin.

Maintaining Claude Code

Covers hooks, rules, settings.json, and the entity-type decision tree. Delegates to plugins for the things they do better.

Entity-type decision

Pick the right home before writing anything:

| Need | Use | | --- | --- | | Run automatically before/after a tool call | Hook | | Auto-detected capability for a recurring task | Skill (use skill-creator) | | Heavy isolated workflow | Skill with context: fork | | Always-on behavioral guidance | CLAUDE.md (use claude-md-improver) | | Path-specific rules | rules/ with paths: frontmatter | | External integration | MCP server |

Hooks

Hook events

Per-session: SessionStart, SessionEnd, Setup Per-turn: UserPromptSubmit, UserPromptExpansion, Stop, StopFailure Per-tool: PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, PermissionDenied, PostToolBatch Async: FileChanged, CwdChanged, ConfigChange, InstructionsLoaded, WorktreeCreate, WorktreeRemove, Notification, SubagentStart, SubagentStop, TaskCreated, TaskCompleted, PreCompact, PostCompact, TeammateIdle, Elicitation, ElicitationResult, MessageDisplay

Exit codes

  • 0 — success, continue
  • 2 — block action; stderr is shown to Claude
  • non-zero (other) — non-blocking warning

Hook command forms

Shell form (classic): "command": "shell command string" Exec form (new, avoids quoting issues): "args": ["program", "arg1", "arg2"]

Output shape

Inject context with JSON on stdout:

{
  "hookSpecificOutput": {
    "hookEventName": "<EventName>",
    "additionalContext": "..."
  }
}

Additional output fields: updatedToolOutput (replace tool output, all tools), terminalSequence (emit OSC sequences for desktop notifications), sessionTitle (set session title, SessionStart only), reloadSkills: true (re-scan skill dirs, SessionStart only). duration_ms is now included in hook input for all tool events.

Common pitfalls

  • Cache busting: minute-precision timestamps in UserPromptSubmit invalidate prompt cache. Round to the hour.
  • Hook script not executable: chmod +x and verify shebang.
  • Reading stdin twice: drain once, parse from a variable.
  • Forgetting set -euo pipefail in bash — silent failures otherwise.

Skills — frontmatter reference

name, description, when_to_use, argument-hint, arguments, disable-model-invocation, user-invocable, allowed-tools, disallowed-tools, model, effort, context, agent, hooks, paths, shell.

Dynamic context injection: !`command` inlines command output before Claude sees skill content. Multi-line: ```! \n cmd \n ```.

Variable substitutions: $ARGUMENTS, $ARGUMENTS[N], $N, $name, ${CLAUDE_SESSION_ID}, ${CLAUDE_EFFORT}, ${CLAUDE_SKILL_DIR}.

Visibility control in settings.json: skillOverrides — set per-skill to off, user-invocable-only, or name-only.

Rules

.claude/rules/*.md files. Each can have paths: frontmatter to load only when matching files are touched. Smaller, narrower files load less context per session.

---
paths:
  - "**/*.py"
---
# Python
- guidance...

When to keep something in CLAUDE.md instead: cross-cutting interaction style, project-wide commands, or rules that apply regardless of file path.

Settings.json

Audit checklist:

  • Env vars: verify each is referenced in the current claude binary (strings ~/.local/share/claude/versions/<v> | grep VAR). Undocumented does not mean dead — many flags are intentionally unlisted.
  • Permissions: prefer narrow over broad. Bash(<cmd>:*) allows everything; Bash(<cmd> <safe-args>) is tighter. Always carry a deny list for secrets (~/.ssh/**, **/*.pem, ~/.env*).
  • Plugin allow rules: Skill(<plugin-name>) must match the actual plugin/skill identifier; typos silently fail.
  • Hook wiring: matchers are regex against tool names — "" matches all, "Write|Edit|Bash" is the common write-side filter.

Audit a config

  1. Validate YAML frontmatter on every SKILL.md and rules/*.md
  2. Cross-check each Skill(...) and mcp__... permission rule against the installed plugins/servers
  3. Strings-grep the claude binary for env vars and settings keys to flag dead ones
  4. Test each hook script standalone with synthetic stdin before wiring