1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
default_install_hook_types:
- pre-commit
- commit-msg
default_stages:
- pre-commit
exclude: ^target/|\.basemind/
repos:
- repo: https://github.com/Goldziher/gitfluff
rev: v0.8.0
hooks:
- id: gitfluff-lint
args:
- --write
stages:
- commit-msg
- repo: https://github.com/xberg-io/pre-commit-hooks
rev: v3.0.0
hooks:
# File safety
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-merge-conflict
- id: check-added-large-files
# Demo recordings are intentionally large (the committed CLI/MCP gifs run
# 0.7–2.6 MB). Keep the 500 KB guard for stray binaries/data, but exclude the
# curated demo gif directories.
exclude: ^docs/(media|demos)/.*\.gif$
- id: detect-private-key
# src/textcompress/{safety,mod}.rs hold the credential-detection regexes
# and their tests — they intentionally contain PEM header patterns (no key
# material) so the output compressor never leaks a real key.
exclude: ^src/textcompress/(safety|mod)\.rs$
- id: check-case-conflict
- id: check-executables-have-shebangs
# run-hook.cmd is an intentional cmd/bash polyglot: executable on Unix
# (no shebang — sh runs it as a script) and a .cmd batch file on Windows.
exclude: \.cmd$
- id: check-shebang-scripts-are-executable
- id: mixed-line-ending
- id: typos
args:
- --force-exclude
- id: check-json
- id: check-yaml
- id: check-toml
# Shell
- id: shfmt
args:
- -w
- -i
- "2"
- id: shellcheck
# Markdown
- id: rumdl-fmt
- id: markdownlint-rumdl-strict
# .ai-rulez/ content is rendered into many tool-native formats; long
# prose lines are expected and respected by ai-rulez's own templates.
exclude: ^\.ai-rulez/
# Rust
- id: cargo-fmt
args:
- --all
- id: cargo-clippy
args:
- --fix
- --allow-dirty
- --allow-staged
- --all-targets
- --
- -D
- warnings
- id: cargo-sort
- id: cargo-machete
- id: cargo-deny
args:
- check
- id: rustdoc-lint
# 1,000 LOC ceiling per .rs file — split early; expand exclusions only as
# a deliberate, time-boxed remediation backlog.
- id: rust-max-lines
args:
- --max=1000
# JSON formatting. Exclude the generated config schema — it is the
# byte-exact `schemars::to_string_pretty` snapshot asserted by
# tests/config_schema.rs, and oxfmt's style would drift it out of sync.
- id: oxfmt
exclude: ^schema/.*\.schema\.json$
- repo: local
hooks:
- id: statusline-smoke
name: statusline smoke test
language: system
entry: bash tests/statusline_smoke.sh
files: ^(\.claude-plugin/statusline\.sh|tests/statusline_smoke\.sh)$
pass_filenames: false
- id: sync-plugin-skills
name: sync canonical skills + commands into all plugin trees
language: system
entry: bash scripts/sync-plugin-skills.sh
files: ^(skills/(basemind|basemind-cli|basemind-comms|basemind-stats)/SKILL\.md|commands/(bm|bm-stats)\.md|hooks/(session-start|inbox-notify|run-hook\.cmd)|scripts/sync-plugin-skills\.sh)$
pass_filenames: false