docs(agent playbooks): fix stale CI references and index committed skills

Corrects the react-doctor PR-check command and workflow filename, marks the
superseded hooks-tarball surprises now that bitsocial-react-hooks comes from
npm, rewrites hooks-setup.md around the real per-harness entry points and drops
its drifted inline script copies, points the Task Router translations row at
the translate skill, and adds a committed skills/subagents index so agents can
discover the tooling that already exists.
This commit is contained in:
Tommaso Casaburi
2026-07-03 13:58:38 +07:00
parent 1ac3e5883b
commit 2088c4b50d
7 changed files with 112 additions and 96 deletions
+25 -75
View File
@@ -1,89 +1,39 @@
# Agent Hooks Setup
If your AI coding assistant supports lifecycle hooks, configure these for this repo.
This repo ships lifecycle hooks shared across Claude Code, Cursor, and Codex. The implementations live in `scripts/agent-hooks/`; each harness has thin wrappers in `.claude/hooks/`, `.cursor/hooks/`, `.codex/hooks/` plus its own entry-point config. Run `yarn ai-workflow:check` after changing any of this.
## Recommended Hooks
## Hooks
| Hook | Command | Purpose |
| Edit-time / stop | Script | Purpose |
|---|---|---|
| `afterFileEdit` | `scripts/agent-hooks/format.sh` | Auto-format files after AI edits |
| `afterFileEdit` | `scripts/agent-hooks/yarn-install.sh` | Run `corepack yarn install` when `package.json` changes |
| `afterFileEdit` | `scripts/agent-hooks/react-pattern-review.sh` | When React UI source changes, remind the agent to run the React best-practice review skills; also flag new `useEffect`/memo primitives |
| `stop` | `scripts/agent-hooks/sync-git-branches.sh` | Prune stale refs and delete integrated temporary task branches |
| `stop` | `scripts/agent-hooks/react-pattern-review.sh` | Re-scan the current diff for React UI source changes and new React effects/memos before the final verify gate |
| `stop` | `scripts/agent-hooks/verify.sh` | Hard-gate build, lint, and type-check; keep `yarn audit` informational |
| edit-time | `scripts/agent-hooks/format.sh` | Auto-format JS/TS files after AI edits (`npx oxfmt`) |
| edit-time | `scripts/agent-hooks/yarn-install.sh` | Run `corepack yarn install` when the root `package.json` changes |
| edit-time + stop | `scripts/agent-hooks/react-pattern-review.sh` | When React UI source changes, remind the agent to run the React best-practice review skills; also flag new `useEffect`/memo primitives |
| stop | `scripts/agent-hooks/sync-git-branches.sh` | Prune stale refs and delete integrated temporary task branches |
| stop | `scripts/agent-hooks/code-quality-review-reminder.sh` | Remind the agent to run the advisory `code-quality-review` skill when the diff is non-trivial |
| stop | `scripts/agent-hooks/verify.sh` | Gate build, lint, and type-check; keep `yarn npm audit` informational |
| session start (Claude only) | `.claude/hooks/session-start.sh` | `corepack yarn install` when `node_modules` is missing (fresh worktrees) |
## Why
## Entry points (harness-specific formats)
- Consistent formatting
- Lockfile stays in sync
- React UI source changes get an explicit best-practices review reminder before the agent finishes
- New `useEffect`/memo additions get an additional effect-specific second look before the agent finishes
- Build/lint/type issues caught early
- Security visibility via `corepack yarn npm audit`
- One shared hook implementation for Codex, Cursor, and Claude
- Temporary task branches stay aligned with the repo's worktree workflow
The three harnesses wire the same scripts but use different config files and schemas. Do not copy one harness's schema to another.
## Example Hook Scripts
| Harness | Entry point | Schema | Edit event | Stop event |
|---|---|---|---|---|
| Claude Code | `hooks` key in `.claude/settings.json` | Claude hooks schema; a standalone `.claude/hooks.json` is **not** read | `PostToolUse` matcher `Edit\|Write\|MultiEdit\|NotebookEdit` | `Stop` |
| Cursor | `.cursor/hooks.json` | `{"version": 1, "hooks": {...}}` with Cursor event names | `afterFileEdit` | `stop` |
| Codex | `.codex/hooks.json` | Codex hooks schema (intentionally Claude-compatible: `matcher`, `type: "command"`) | `PostToolUse` matcher includes `apply_patch` | `Stop` |
### Format Hook
## How the scripts handle harness differences
```bash
#!/bin/bash
# Auto-format JS/TS files after AI edits
# Hook receives JSON via stdin with file_path
input=$(cat)
file_path=$(echo "$input" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*:.*"\([^"]*\)"/\1/')
case "$file_path" in
*.js|*.ts|*.tsx|*.mjs) npx oxfmt "$file_path" 2>/dev/null ;;
esac
exit 0
```
### Verify Hook
```bash
#!/bin/bash
# Run build, lint, type-check, and security audit when agent finishes
cat > /dev/null # consume stdin
status=0
corepack yarn build || status=1
corepack yarn lint || status=1
corepack yarn type-check || status=1
echo "=== corepack yarn npm audit ===" && (corepack yarn npm audit || true) # informational
exit $status
```
By default, `scripts/agent-hooks/verify.sh` exits non-zero when `corepack yarn build`, `corepack yarn lint`, or `corepack yarn type-check` fails. Set `AGENT_VERIFY_MODE=advisory` only when you intentionally need signal from a broken tree without blocking the hook.
- **Stdin shape**: Cursor sends `{"file_path": ...}`; Claude/Codex send `{"tool_input": {"file_path": ...}, "hook_event_name": ...}` with absolute paths. The shared scripts parse both and normalize absolute paths to repo-relative.
- **Surfacing output to the model**: in Claude/Codex, plain stdout from `PostToolUse`/`Stop` hooks with exit 0 is transcript-only and never reaches the model. `react-pattern-review.sh` therefore emits `hookSpecificOutput.additionalContext` JSON on `PostToolUse`. The stop-time reminders (`react-pattern-review.sh`, `code-quality-review-reminder.sh`) stay advisory: their output is visible to the contributor, not injected into the model.
- **Blocking**: `verify.sh` in strict mode exits **2** with a short reason on stderr — the only exit code that blocks the stop and feeds the failure back to the agent in Claude/Codex. It checks `stop_hook_active` to avoid infinite stop loops, and skips entirely when the working tree is clean (read-only sessions). Set `AGENT_VERIFY_MODE=advisory` only when you intentionally need signal from a broken tree without blocking the session.
Lifecycle hooks do not replace manual browser verification. For UI or visual changes, still run `playwright-cli` checks across `chrome`, `firefox`, and `webkit`, plus a mobile viewport flow in each engine when responsiveness or touch behavior changed.
### Yarn Install Hook
## Editing rules
```bash
#!/bin/bash
# Run Corepack-managed Yarn install when package.json is changed
# Hook receives JSON via stdin with file_path
input=$(cat)
file_path=$(echo "$input" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*:.*"\([^"]*\)"/\1/')
if [ -z "$file_path" ]; then
exit 0
fi
if [ "$file_path" = "package.json" ]; then
cd "$(dirname "$0")/../.." || exit 0
echo "package.json changed - running corepack yarn install to update yarn.lock..."
corepack yarn install
fi
exit 0
```
Configure hook wiring according to your agent tool docs (`hooks.json`, equivalent, etc.).
In this repo, `.codex/hooks/*.sh`, `.cursor/hooks/*.sh`, and `.claude/hooks/*.sh` should stay as thin wrappers that delegate to the shared implementations under `scripts/agent-hooks/`. Harness-specific startup hooks such as Claude's `SessionStart` can live alongside those wrappers when the other harnesses do not have an equivalent entry point.
- Change behavior in `scripts/agent-hooks/*.sh`; keep the per-harness wrappers as thin `exec` delegates (they pass harness-appropriate `--skill-dir`/`--scope-prefix` args).
- When adding a hook, wire it in **all three** entry points (or add a documented exemption in `scripts/validate-ai-workflow.mjs`, like Claude's `session-start.sh`). The validator checks that every entry point references the same set of `hooks/<name>.sh` scripts.
- Do not paste "example" hook implementations into docs — link the real scripts so they cannot drift.