# Hooks: auto-sync on commit

Install, check and remove the post-commit git hook that runs repowise update after every commit, and see hook stats on what your agent hooks fired.

The post-commit hook runs `repowise update` after every successful commit,
typically 3 to 10 pages in under 30 seconds. **`repowise init` installs it by
default.** An interactive run asks; `--yes` and non-interactive runs install it
and print how to undo it (`repowise hook uninstall`). `--no-hook` skips it, and
`--no-editor-setup` skips it too, since a git hook is a write outside
`.repowise/`. In workspace mode the choice applies to every selected repo, and
`repowise doctor` carries a row for it.

The commands below are for the cases `init` did not cover: you opted out and
changed your mind, you want to check the state of a checkout, or you want the
hook gone. Other sync options (file watcher, GitHub webhook, polling) live in
[Auto-sync](https://docs.repowise.dev/auto-sync).

> **Note**
>
> This page is about the **git post-commit hook**. For the unrelated Claude
> Code / Codex **agent hooks** that inject proactive context (decisions,
> freshness, distill nudges) into a coding session, see
> [Proactive agent hooks](https://docs.repowise.dev/intelligence/hooks).

## `repowise hook install`

Install the post-commit hook in the current repo (or every repo in a
workspace). Use this after a `--no-hook` install, or on a checkout that
predates the default.

```bash
repowise hook install [PATH] [OPTIONS]
```

| Name | Type | Default | Description |
|---|---|---|---|
| `--workspace / -w` | boolean | `false` | Install hooks for every repo in the workspace. |
| `--no-workspace` | boolean | `false` | Force single-repo mode even when invoked from a workspace. |
| `--security` | boolean | `false` | Also install a pre-commit hook that runs repowise security check --staged and blocks a commit adding a finding at or above high. Skip it once with git commit --no-verify. |

```bash
repowise hook install
repowise hook install --workspace
repowise hook install --security    # plus the pre-commit security check
```

---

## `repowise hook uninstall`

Remove the repowise post-commit hook.

```bash
repowise hook uninstall [PATH] [OPTIONS]
```

| Name | Type | Default | Description |
|---|---|---|---|
| `--workspace / -w` | boolean | `false` | Uninstall hooks from every repo in the workspace. |

---

## `repowise hook status`

Check whether the post-commit hook is installed.

```bash
repowise hook status [PATH] [OPTIONS]
```

| Name | Type | Default | Description |
|---|---|---|---|
| `--workspace / -w` | boolean | `false` | Check hooks for every repo in the workspace. |

> **Note**
>
> The hook is non-invasive: it appends to any existing `post-commit`
> hook rather than overwriting. `hook uninstall` removes only the
> repowise lines.

---

## `repowise hook stats`

Show what the agent hooks fired and whether the agent acted on it, per
surface, plus hook invocation counts and wall time. Reads the local ledger
in `.repowise/sessions/sessions.db`.

```bash
repowise hook stats [PATH] [OPTIONS]
```

| Name | Type | Default | Description |
|---|---|---|---|
| `--format` | string | `table` | Output: table or json (raw per-surface rows) |

```bash
repowise hook stats
repowise hook stats --format json
```

> **Note**
>
> A surface showing firings but no verdicts hasn't been classified yet, run
> `repowise hook backfill`. Notices that ask for nothing (stale-read, the
> silent read-after-served measurement) report `n/a` rather than a rate.

---

## `repowise hook backfill`

Replay Claude Code transcripts into the efficacy ledger, so `hook stats`
starts with history instead of only what has fired since you upgraded.
Local, single-pass, and safe to re-run: a firing is keyed by a hash of its
own text, so a replay settles the row it already owns.

```bash
repowise hook backfill [PATH] [OPTIONS]
```

| Name | Type | Default | Description |
|---|---|---|---|
| `--all-projects` | boolean | `false` | Also replay transcripts from this repo's worktrees, not just this checkout. |
| `--days` | number |  | Only replay transcripts modified in the last N days (default: all history). |
| `--reset` | boolean | `false` | Clear every transcript-classified surface's rows before replaying. Decision rows are never touched. |

```bash
repowise hook backfill                   # this checkout's transcripts
repowise hook backfill --all-projects    # include this repo's worktrees
repowise hook backfill --days 30         # only recent transcripts
repowise hook backfill --reset           # rebuild the hook surfaces from scratch
```

`repowise update` classifies recent sessions automatically, so a backfill is
normally a one-time catch-up. Use `--reset` once when upgrading from a
release that keyed rows by hook input rather than by emitted text.

---

## `repowise hook health-gate install|uninstall|status`

An **opt-in** Claude Code PreToolUse hook that runs
[`repowise health check`](https://docs.repowise.dev/cli/gates#repowise-health-check) before an
agent's `git commit` (on the staged change) or `git push` (on `@{u}...HEAD`,
else the default branch's merge-base) in this repo, and denies the command when
the gate fails.

```bash
repowise hook health-gate install     # hooks.health_gate: true + .claude/settings.local.json entry
repowise hook health-gate status
repowise hook health-gate uninstall   # removes both
```

It is off by default, and `init` and `upgrade` never turn it on. `--amend`,
pathspecs, merges in progress, other branches, tags, `--delete`, and anything
that keeps the check from finishing within 20 s let the command through. A
plain `git commit` in a terminal is not gated.

---

## `repowise hook rewrite install|uninstall|status`

A separate, **opt-in** agent hook (Claude Code + Codex PreToolUse) that
rewrites noisy agent commands (tests, builds, lint runs,
`git status`/`log`/`diff`, searches, listings) to
`repowise distill <command>`, so the agent sees a compact errors-first
rendering. Covers both Claude Code shell tools (Bash and, on Windows,
PowerShell).

> **Warning**
>
> The default posture is `allow`: a rewrite auto-runs, with no approval
> prompt. Set `permission: ask` under `distill.commands` in
> `.repowise/config.yaml` if you want the rewritten command shown before it
> runs. See [Distill](https://docs.repowise.dev/cli/distill).

```bash
repowise hook rewrite install        # writes ~/.claude/settings.json (idempotent)
repowise hook rewrite status
repowise hook rewrite uninstall      # removes only the repowise entries
```

| Name | Type | Default | Description |
|---|---|---|---|
| `--allow-rule / --no-allow-rule` | boolean |  | Seed Claude Code permission allow rules for the `repowise distill` prefix so existing allowlist entries keep working after rewrites. Prompts when omitted. |

`install` also re-enables the current repo's `distill.commands` config
if a prior `repowise init` opt-out had gated it off; `uninstall` removes
the global hook entries plus the repo's AGENTS.md awareness section and
leaves per-repo config untouched. Per-repo posture
(`permission: ask | allow`, per-family overrides) lives under
`distill.commands` in `.repowise/config.yaml`.

When `~/.codex` exists, `install` also writes a Codex hook entry to
`~/.codex/hooks.json` (Codex ≥ 0.137 only) and maintains an "Output
Distillation" section in the repo's `AGENTS.md` that works without any
hook. Codex cannot show a rewritten command for approval, so there
rewrites fire only for families set to `permission: allow`; `status`
reports exactly what your build supports. Full guide:
[Distill](https://docs.repowise.dev/cli/distill).
