Claude Hookbook

Hooks / testing

Full check before task completion

Blocks Claude from marking a task completed while your project check fails.

TaskCompletedblocking riskneeds manual check

What it does

Fires on TaskCompleted. The script runs your project's check command (tests, lint, build - you pick) and exits 2 with the output when it fails; Claude gets the failure as a tool error and keeps working. Schema note: TaskCompleted decision behavior is one of the newer event semantics - verify against your Claude Code version before relying on it, which is why this hook ships as needs-manual-check.

When it runs

EventTaskCompleted
Scopeproject
Platformsmacos, linux
Timeout600s
Failure modeblock
Verified againstClaude Code hooks reference, event/matcher schema checked 2026-09-10
Test statusneeds manual check - run the test steps below before relying on it

Config

Merge this into .claude/settings.json - or use the generator to combine hooks.

{
  "hooks": {
    "TaskCompleted": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/full-check-before-complete.sh",
            "timeout": 600
          }
        ]
      }
    ]
  }
}

Script

Save as .claude/hooks/full-check-before-complete.sh and chmod +x it.

#!/bin/bash
# full-check-before-complete: run the project check; block completion on failure.
# Set HOOKBOOK_CHECK_CMD to your project check (default: npm test).
set -u
cd "${CLAUDE_PROJECT_DIR:-$PWD}" || exit 0
check="${HOOKBOOK_CHECK_CMD:-npm test}"
if ! $check >/dev/null 2>&1; then
  echo "Project check failed ($check) - task is not done:" >&2
  $check 2>&1 | tail -30 >&2
  exit 2
fi
exit 0

Install

  1. Save the script to .claude/hooks/full-check-before-complete.sh and chmod +x it.
  2. Edit the HOOKBOOK_CHECK_CMD default at the top of the script to your real check (npm test, make check, pytest...), or export HOOKBOOK_CHECK_CMD via the env key in settings.json.
  3. Add the config fragment to .claude/settings.json, then run the manual test below before trusting it - TaskCompleted semantics are version-sensitive.

Test it

If it blocks something you wanted

The block only tells Claude the check failed, with output - it fixes and retries. To unblock yourself, fix the failure or remove the hook entry.

Sources

Related hooks

Run the nearest test after an edit

Finds the test file that belongs to the file Claude just edited and runs it, in the background.

PostToolUseEdit|Writereview riskneeds manual check

Typecheck after TypeScript changes

Runs tsc --noEmit in the background after Claude edits TypeScript, so type errors surface even when tests don't cover the file.

PostToolUseEdit|Writereview riskneeds manual check

Pro Pack (later)

Framework bundles, cross-platform scripts, tested blocking policies, and a test harness. Free recipes and the generator stay free.

Waitlist opens soon.