07 - Automating with Hooks and Skills

📋 Jump to Takeaways

🎁 You keep telling Claude "run the tests after you edit" every single session. What if it just did that on its own, every time, without being asked?

CLAUDE.md shapes how Claude behaves. But telling the model "always run the linter" is a request it can forget or skip. This lesson is about the four ways to make things happen reliably, whether the model remembers or not.

Memory vs Automation

There's a real split here. CLAUDE.md is instructions for the model. Hooks are instructions for the harness, the program running Claude.

If you write "run npm test after editing" in CLAUDE.md, the model might do it. It's guidance, and guidance gets dropped when context fills up or the model decides it's not relevant.

# CLAUDE.md: this is a request, not a guarantee
After changing any file in src/, run `npm test` and fix failures.

A hook is different. The harness runs it, not the model, so it fires whether the model "remembers" or not. Rule of thumb: if it must happen every time, it's a hook. If it's a preference, it's CLAUDE.md.

Hooks in settings.json

Hooks live in .claude/settings.json and run a shell command when a specific event fires, like after Claude edits a file. The classic use is running your formatter or tests automatically.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [{ "type": "command", "command": "npm run lint --silent" }]
      }
    ]
  }
}

That runs the linter every time Claude writes or edits a file. The output goes back to Claude as feedback, so if the lint fails, it sees the error and fixes it. You didn't have to ask.

Hooks are shell commands you control, so keep them fast and safe. A hook that runs your full e2e suite on every keystroke will make the session crawl.

Slash Commands

A slash command is a saved prompt you invoke by name. Instead of retyping "review the diff for security issues, check auth and input validation" every time, you save it once and type /security-review.

<!-- .claude/commands/security-review.md -->
Review the current git diff for security issues.
Focus on auth, input validation, and secret handling.
List findings by severity. Don't fix anything yet.

Now /security-review runs that prompt in the current session. Commands are checked into the repo, so your whole team gets the same ones. They're the fastest way to standardize a workflow everybody does slightly differently.

Skills

A skill is a packaged set of instructions the model loads on demand, only when the task calls for it. A slash command runs when you type it. A skill sits quietly until Claude decides it's relevant, then pulls in the full instructions.

<!-- .claude/skills/release-notes/SKILL.md -->
---
name: release-notes
description: Draft release notes from merged PRs since the last tag
---
Read git log since the last tag, group changes by type
(feat, fix, chore), and write user-facing release notes.

The description is what Claude sees by default. When you ask "write release notes for this version," it matches the description and loads the rest. This keeps your context lean, detailed instructions only show up when needed, instead of bloating every prompt.

Scheduled Agents

Some work shouldn't wait for you to open a terminal. Scheduled agents run a task on a recurring cadence, like a cron job that happens to be an AI.

# Run a triage prompt every weekday at 9am
claude schedule create "review open PRs and flag anything risky" \
  --cron "0 9 * * 1-5"

Good fits: nightly dependency checks, morning PR triage, a weekly "what changed" summary. The agent runs, does the work, and leaves you the result. Bad fits: anything that needs your judgment mid-task, since nobody's watching to answer its questions.

Built-In Commands

Not every command is one you write. Claude Code ships with built-ins, and two are worth your muscle memory.

/loop repeats a prompt while the session stays open, either on a fixed interval or self-paced. It's for watching something change without babysitting it.

/loop 5m check if the deploy finished and tests are green
# fixed 5-minute cadence

/loop watch the CI run and tell me when it passes
# no interval, Claude paces itself and checks more often as it gets close

This looks like a scheduled agent, but it isn't. /loop only runs while your session is open, so it's for active monitoring during work: a deploy, a build, a slow test run. For anything that must survive a closed laptop, use a scheduled agent instead.

/btw asks a quick side question about what you're already working on, without adding it to the conversation history. It has no tool access and gives a single answer, so it's cheap and doesn't derail the main task.

/btw what was the name of that config file we edited earlier?

Use it for the "wait, remind me" moments mid-task. The main thread keeps its focus, and you don't burn a full turn or clutter the context on a throwaway question.

Key Takeaways

  • CLAUDE.md is guidance the model might follow; hooks are commands the harness always runs. Must-happen-every-time means hook.
  • Hooks live in .claude/settings.json and fire on events like PostToolUse; use them for lint/test/format after edits.
  • Hook output feeds back to Claude, so a failing check gets seen and fixed automatically.
  • Slash commands are saved prompts invoked with /name; check them into the repo so the team shares workflows.
  • Skills are loaded on demand by their description; they keep context lean until the task actually needs them.
  • Scheduled agents run tasks on a cron cadence; great for triage and summaries, bad for anything needing your input mid-run.
  • /loop [interval] [prompt] repeats a prompt while the session stays open (fixed like 5m or self-paced); use it for live monitoring, not for work that must outlive the session.
  • /btw <question> answers a quick side question without polluting history or using tools; good for mid-task "remind me" moments.

🎁 Hooks and skills run your code and prompts. But what if Claude could reach straight into your issue tracker, your database, or your internal API, using tools you didn't have to build?

📝 Ready to test your knowledge?

Answer the quiz below to mark this lesson complete.

Spot something off? Report an issue

© 2026 ByteLearn.dev. Free courses for developers. · Privacy