HookStackGitHub
Back to catalogue
ValidationStopStopWhen the agent finishes its task· non-blocking

Run pytest at end of response

When the agent finishes, runs the full pytest suite via uv. If tests fail, Claude re-enters and receives the failure output as context to fix the regressions.

Use cases

  • Regression safety net on every agent turn
  • TDD loop: write code until tests go green
  • Catch side-effects of refactors before control returns to the user

Providers & tags

Claude Code
#validation#pytest#uv#python#tests#ci

settings.json fragment

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/pytest.mjs",
            "type": "command"
          }
        ]
      }
    ]
  }
}

Script · .claude/hooks/pytest.mjs

#!/usr/bin/env node
import { execSync } from 'child_process';
import { existsSync } from 'fs';

const cwd = process.env.CLAUDE_PROJECT_DIR ?? process.cwd();

const isPython = ['pyproject.toml', 'setup.py', 'pytest.ini', 'setup.cfg']
  .some(f => existsSync(`${cwd}/${f}`));
if (!isPython) process.exit(0);

try {
  execSync('uv run pytest --tb=short -q', {
    encoding: 'utf8',
    timeout: 120_000,
    cwd,
    stdio: 'inherit',
  });
} catch (e) {
  process.exit(e.status ?? 1);
}