# Project Hook Setup

> Use when setting up project-specific hooks for Claude Code enforcement. Load during INIT state when .claude/hooks/ is missing, or when creating new project. Installs 5 hooks that read from .claude/config/project.json (tests, health, dependencies).

- Skill: `majiayu000/project-hook-setup` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add majiayu000/project-hook-setup`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/project-hook-setup/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/project-hook-setup

---


# Project Hook Setup

Per-project setup for Claude Code hooks. These hooks read from `.claude/config/project.json` for project-specific settings.

## Purpose

Installs 5 project-specific hooks that enforce:

- Test verification before marking tested
- File existence before marking complete
- Health checks for API projects
- Dependency validation
- Session entry protocol

## When to Use

| Situation | Action |
| --------- | ------ |
| New project | Run during INIT |
| .claude/hooks/ missing | Run setup |
| Project config changed | Re-run setup |
| Adding dependencies | Update config, re-run |

## Quick Check

```bash
# Check if project hooks exist
ls .claude/hooks/

# Check if config exists
cat .claude/config/project.json
```

## Interactive Config

Setup prompts for project configuration:

| Setting | Description | Example |
| ------- | ----------- | ------- |
| Project type | Framework used | `fastapi`, `django`, `node` |
| Dev server port | Local development port | `8000` |
| Health check | Command to verify server | `curl -sf http://localhost:8000/health` |
| Test command | How to run tests | `pytest` |
| Required env | Environment variables needed | `DATABASE_URL`, `API_KEY` |
| Required services | Services to be running | `redis://localhost:6379` |

## Setup Steps

### 1. Install Hooks

```bash
# Interactive mode (prompts for config)
.skills/project-hook-setup/scripts/setup-project-hooks.sh

# Non-interactive mode (for agents/automation)
.skills/project-hook-setup/scripts/setup-project-hooks.sh --non-interactive

# Auto-confirm prompts
.skills/project-hook-setup/scripts/setup-project-hooks.sh --yes

# Use existing config
.skills/project-hook-setup/scripts/setup-project-hooks.sh --config /path/to/config.json

# Environment variable (agent mode)
CLAUDE_NON_INTERACTIVE=1 .skills/project-hook-setup/scripts/setup-project-hooks.sh
```

**Non-interactive flags:**

| Flag | Purpose |
| ---- | ------- |
| `--non-interactive` / `-n` | Skip all prompts (keeps existing config) |
| `--yes` / `-y` | Auto-confirm all prompts |
| `--config` / `-c` \<path\> | Use existing config file |

This:

- Creates `.claude/config/project.json` (or uses provided config)
- Copies 5 hook templates to `.claude/hooks/`
- Sets executable permissions

### 2. Verify Installation

```bash
.skills/project-hook-setup/scripts/verify-project-hooks.sh
```

## Hooks Installed

| Hook | Event | Purpose | Reads From |
| ---- | ----- | ------- | ---------- |
| `verify-tests.py` | PreToolUse | Run tests before tested | project.json → test_command |
| `verify-files-exist.py` | PreToolUse | Check files before complete | feature-list.json |
| `verify-health.py` | PreToolUse | Check server health | project.json → health_check |
| `require-dependencies.py` | PreToolUse | Validate env, services | project.json |
| `session-entry.sh` | CLI utility | Session entry protocol | project.json |

**Note**: `session-entry.sh` is a CLI utility. Use: `.claude/hooks/session-entry.sh`

## Settings.json Configuration

Setup script configures `.claude/settings.json`:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {"type": "command", "command": "python3 \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/verify-tests.py"},
          {"type": "command", "command": "python3 \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/verify-files-exist.py"},
          {"type": "command", "command": "python3 \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/verify-health.py"},
          {"type": "command", "command": "python3 \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/require-dependencies.py"}
        ]
      }
    ]
  }
}
```

**Note**: Uses `$CLAUDE_PROJECT_DIR` for project-relative paths.

## Exit Criteria (Code Verified)

```bash
# Config exists with required fields
[ -f ".claude/config/project.json" ]
jq -e '.project_type' .claude/config/project.json >/dev/null
jq -e '.health_check' .claude/config/project.json >/dev/null
jq -e '.test_command' .claude/config/project.json >/dev/null

# Hooks exist and executable
[ -d ".claude/hooks" ]
[ -x ".claude/hooks/verify-tests.py" ]
[ -x ".claude/hooks/verify-files-exist.py" ]
[ -x ".claude/hooks/verify-health.py" ]
[ -x ".claude/hooks/require-dependencies.py" ]
[ -x ".claude/hooks/session-entry.sh" ]

# Verify script passes
.skills/project-hook-setup/scripts/verify-project-hooks.sh
```

## Scripts

| Script | Purpose |
| ------ | ------- |
| `setup-project-hooks.sh` | Main setup (config + hooks + settings + validate) |
| `configure-project-settings.py` | Configure .claude/settings.json |
| `validate-settings.py` | Validate hooks configured in settings.json |
| `prompt-project-config.sh` | Interactive config creation |
| `verify-project-hooks.sh` | Verify hook files exist |
| `install-hooks.sh` | Copy templates to .claude/hooks/ |

## Project Config Schema

`.claude/config/project.json`:

```json
{
  "project_type": "fastapi|django|node|python|other",
  "dev_server_port": 8000,
  "health_check": "curl -sf http://localhost:8000/health",
  "test_command": "pytest",
  "required_env": ["DATABASE_URL", "API_KEY"],
  "required_services": ["redis://localhost:6379"]
}
```

## Troubleshooting

| Problem | Solution |
| ------- | -------- |
| Config missing | Run `setup-project-hooks.sh` to create |
| Hook can't read config | Check JSON syntax, verify required fields |
| Tests not found | Update test_command in project.json |
| Health check fails | Server not running or wrong port |
| Permission denied | Run: `chmod +x .claude/hooks/*` |

## Integration

This skill is called by the `initializer` skill during INIT state:

```markdown
5. Setup hooks:
   - Check: ~/.claude/hooks/verify-state-transition.py exists (global)
   - Check: .claude/hooks/verify-tests.py exists (project)
   - If missing, load respective setup skill
```

## Next Steps

After project hooks: Continue with feature breakdown and implementation.

