-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy path.pre-commit-config.yaml
More file actions
411 lines (371 loc) · 17.6 KB
/
Copy path.pre-commit-config.yaml
File metadata and controls
411 lines (371 loc) · 17.6 KB
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
# This pre-commit configuration is specifically designed for sanitizing
# generic template files in this repository. The majority of files are
# Markdown templates, so the hooks are focused on basic file hygiene
# and Markdown formatting.
# This configuration is NOT intended for use in production projects -
# it exists solely to maintain the consistency and quality of the template
# files in this repository.
ci:
autofix_prs: true
autoupdate_commit_msg: "[pre-commit.ci] bump ⬆ suggestions"
autoupdate_schedule: quarterly
skip: [lychee, gitlint] # lychee: no binary in CI; gitlint: commit-msg stage, not run in CI
# submodules: true
# Never lint/format the MkDocs build output — generated, gitignored, not source.
exclude: ^site/
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: end-of-file-fixer
name: "📄 end-of-file-fixer"
# Excludes identity-locked benchmark JSON owned by dedicated builders and tests.
exclude: ^benchmarks/(manifests|suites|tests/fixtures)/.*\.json$
- id: trailing-whitespace
name: "✂️ trailing-whitespace"
# Excludes identity-locked benchmark JSON owned by dedicated builders and tests.
exclude: ^benchmarks/(manifests|suites|tests/fixtures)/.*\.json$
- id: check-json
name: "🔍 check-json"
- id: check-yaml
name: "🔍 check-yaml"
- id: check-toml
name: "🔍 check-toml"
- id: check-executables-have-shebangs
name: "⚡ check-executables-have-shebangs"
- id: check-case-conflict
name: "🔤 check-case-conflict"
- id: check-added-large-files
name: "📦 check-added-large-files"
args: ["--maxkb=250", "--enforce-all"]
- id: detect-private-key
name: "🔐 detect-private-key"
- id: check-merge-conflict
name: "🔀 check-merge-conflict"
- id: mixed-line-ending
name: "↩️ mixed-line-ending"
args: ["--fix=lf"]
# Excludes identity-locked benchmark JSON owned by dedicated builders and tests.
exclude: ^benchmarks/(manifests|suites|tests/fixtures)/.*\.json$
- id: pretty-format-json
name: "✨ pretty-format-json"
args: ["--autofix"]
# Benchmark manifests, suites, and historical fixtures are identity-locked
# inputs/outputs. Their dedicated builders/tests own byte and hash validation.
exclude: ^benchmarks/(manifests|suites|tests/fixtures)/.*\.json$
- repo: https://github.com/JoC0de/pre-commit-prettier
rev: v3.9.4 # using tag; previously pinned SHA when tags were not persistent
hooks:
- id: prettier
name: "🎨 prettier"
# Coverage: HTML, YAML, TOML, and JavaScript source files.
files: \.(html|yml|yaml|toml|js)$
# https://prettier.io/docs/en/options.html#print-width
args: ["--print-width=120"]
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v10.6.0
hooks:
- id: eslint
name: "🛡️ eslint"
additional_dependencies:
- eslint@9.21.0
- globals@16.0.0
- "@eslint/js@9.21.0"
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.20
hooks:
- id: ruff-check
name: "🦀 ruff-check"
args: ["--fix"]
- id: ruff-format
name: "🦀 ruff-format"
- repo: https://github.com/PyCQA/docformatter
rev: v1.7.8
hooks:
- id: docformatter
name: "📚 docformatter"
args: ["--in-place", "--config=pyproject.toml"]
# docformatter needs tomli to parse pyproject.toml when pre-commit selects Python 3.10.
additional_dependencies: ["tomli"]
# Docformatter 1.7.8 crashes while tokenizing multiline f-strings in these files.
exclude: ^(?:benchmarks/tests/test_run_all\.py|plugins/codex-rig/tests/test_code_remediate_(?:final_outcome|work_bucket)_validation\.py)$
- repo: https://github.com/codespell-project/codespell
rev: v2.4.2
hooks:
- id: codespell
name: "✏️ codespell"
# ignore-words-list lives in pyproject.toml [tool.codespell]; tomli lets the
# isolated hook env parse pyproject on Python <3.11 (3.11+ uses stdlib tomllib).
args: ["--write-changes"]
additional_dependencies: ["tomli"]
- repo: https://github.com/executablebooks/mdformat
rev: 1.0.0
hooks:
- id: mdformat
name: "📝 mdformat (general)"
# Coverage: everything the two instances below do not own — repo-root and config Markdown
# (README, CLAUDE.md, AGENTS.md, .claude/, .codex/, benchmarks/) plus every plugin
# README.md and CHANGELOG.md, whose padded table alignment stays human-owned. The three
# instances are disjoint by construction, so no file is formatted twice with rival args:
# padding a table here that the plugin-sources hook compacts would never converge.
exclude: ^(plugins/(?!.*(?:README|CHANGELOG)\.md$)|docs/)
args: ["--number", "--wrap=no"]
additional_dependencies:
- mdformat-gfm
- mdformat-ruff
- mdformat-frontmatter
- mdformat-config
- mdformat-beautysh
- mdformat-admon
- mdformat-web
- id: mdformat
name: "📝 mdformat (plugin sources)"
# Coverage: every plugin Markdown source except README/CHANGELOG (handled above), so plugin
# tables and prose have exactly one owner. `--compact-tables` replaces the retired
# trim-plugin-tables hook; `--no-codeformatters` keeps beautysh away from fenced bash, whose
# bytes the blueprint manifest hashes, and keeps illustrative json/yaml fragments verbatim.
# Same dependency set as the general hook so both share one cached environment.
files: ^plugins/
exclude: (?:^|/)(README|CHANGELOG)\.md$
args: ["--number", "--wrap=no", "--compact-tables", "--no-codeformatters"]
additional_dependencies:
- mdformat-gfm
- mdformat-ruff
- mdformat-frontmatter
- mdformat-config
- mdformat-beautysh
- mdformat-admon
- mdformat-web
- id: mdformat
name: "📝 mdformat (docs)"
# Coverage: docs/ Markdown with the MkDocs-aware extension set; excluded from the general hook.
files: ^docs/
args: ["--number", "--wrap=no"]
additional_dependencies:
- mdformat-mkdocs
- mdformat-ruff
- mdformat-frontmatter
- mdformat-config
- mdformat-beautysh
- mdformat-web
- repo: https://github.com/lycheeverse/lychee.git
rev: lychee-v0.24.2
hooks:
- id: lychee
name: "🔗 lychee"
args:
- --offline
- --no-progress
#- --exclude=^https?://
types_or: [markdown, toml]
- repo: local
hooks:
- id: node-syntax-check
name: "🟩 node --check (hooks)"
language: system
entry: node --check
# Plugin hooks under plugins/*/hooks/ are the source of truth; .claude/hooks
# are symlinks to them. Scan both so a syntax error in plugin source is caught.
files: ^plugins/[^/]+/hooks/.*\.js$|^\.claude/hooks/.*\.js$|^\.codex/hooks/.*\.js$
types: [javascript]
- id: check-tag-symmetry-empty
name: "🏷️ XML empty structural blocks"
language: system
entry: python3 plugins/cc_foundry/bin/check_tag_symmetry.py --check empty-block
# Coverage: plugin agent cards and top-level SKILL.md instruction files.
files: ^plugins/[^/]+/(agents/[^/]+|skills/[^/]+/SKILL)\.md$
types: [markdown]
- id: check-tag-symmetry-unbalanced
name: "⚖️ XML unbalanced tag pairs"
language: system
entry: python3 plugins/cc_foundry/bin/check_tag_symmetry.py --check unbalanced
# Coverage: every plugin Markdown file. The check balances the registry plus whatever
# names each file uses as standalone tag lines, so a block invented in a reference or
# mode file is covered without being registered first — which is how a duplicated open
# tag once survived every gate. Unlike escaped-tag/empty-block below, nothing here
# depends on the registry, so the wider scope costs no extra false positives.
files: ^plugins/.*\.md$
types: [markdown]
- id: check-tag-symmetry-escaped
name: "🔖 XML escaped structural tags"
language: system
entry: python3 plugins/cc_foundry/bin/check_tag_symmetry.py --check escaped-tag
# Coverage: plugin agent cards and top-level SKILL.md instruction files — registry-driven,
# so widening it would need an escaped-form grammar for undiscovered names first.
files: ^plugins/[^/]+/(agents/[^/]+|skills/[^/]+/SKILL)\.md$
types: [markdown]
- id: check-tag-symmetry-underscore
name: "🔤 XML underscore tag names"
language: system
entry: python3 plugins/cc_foundry/bin/check_tag_symmetry.py --check underscore-tag
# Coverage: every plugin Markdown file, not just agents/SKILL — modes, templates, _shared
# and references carry structural tags too, and an underscore name breaks navigation
# wherever it lands (plugins/CLAUDE.md §Structural Tag Names).
files: ^plugins/.*\.md$
types: [markdown]
- id: check-orphaned-bin
name: "🔗 orphaned bin/ scripts"
language: system
entry: python3 plugins/cc_foundry/bin/check_orphaned_bin.py
pass_filenames: false
always_run: true
- id: check-cli-flag-drift
name: "🚩 SKILL.md flag drift vs argparse"
language: system
entry: python3 plugins/cc_foundry/bin/check_cli_flag_drift.py
pass_filenames: false
always_run: true
- id: check-plugin-module-docs
name: "📚 shipped plugin module documentation"
language: system
entry: python3 plugins/cc_foundry/bin/check_plugin_module_docs.py
# One whole-repository checker: every plugin needs a module overview; Codex
# Rig's published richer module contract is enforced in the same pass.
files: ^plugins/[^/]+/.*\.py$
pass_filenames: false
- id: check-readme-drift-version
name: "🔢 README version marker drift"
language: system
entry: python3 plugins/cc_foundry/bin/check_readme_drift.py --scan-dir plugins --check version
pass_filenames: false
always_run: true
- id: check-readme-drift-bin-refs
name: "📄 README bin/ script reference drift"
language: system
entry: python3 plugins/cc_foundry/bin/check_readme_drift.py --scan-dir plugins --check bin-refs
pass_filenames: false
always_run: true
- id: codex-rig-package-manifest
name: "🔐 Codex Rig package manifest update"
language: system
entry: python3 plugins/codex-rig/scripts/build_package.py --update
# Coverage: every source or metadata change under the Codex Rig plugin.
files: ^plugins/codex-rig/
pass_filenames: false
- id: blueprint-manifest-update
name: "🧾 blueprint manifest regeneration"
language: system
entry: python3 plugins/cc_foundry/bin/build_blueprint_manifest.py --scan-dir plugins --update
# Coverage: every Markdown file a plugin ships can carry a bash blueprint.
files: ^plugins/.*\.md$
pass_filenames: false
- id: check-fence-symmetry
name: "🚧 code fence symmetry"
language: system
entry: python3 plugins/cc_foundry/bin/check_fence_symmetry.py
# Coverage: all Markdown files shipped by plugins.
files: ^plugins/.*\.md$
types: [markdown]
- id: check-routing-links-r1
name: "🧭 R1 computed-path resolution"
language: system
entry: python3 plugins/cc_foundry/bin/check_routing_links.py --check R1
pass_filenames: false
always_run: true
- id: check-routing-links-r2
name: "🔗 R2 grep-visible referencing (orphan risk)"
language: system
entry: python3 plugins/cc_foundry/bin/check_routing_links.py --check R2
pass_filenames: false
always_run: true
- id: check-routing-links-r3
name: "🧰 R3 bin/ script reference integrity"
language: system
entry: python3 plugins/cc_foundry/bin/check_routing_links.py --check R3
pass_filenames: false
always_run: true
- id: check-spawn-prompt-vars
name: "🪧 unexpanded $VAR in spawn prompts"
language: system
entry: python3 plugins/cc_foundry/bin/check_spawn_prompt_vars.py --scan-dir plugins
pass_filenames: false
always_run: true
- id: check-mode-dispatch
name: "🧵 mode dispatch integrity"
language: system
entry: python3 plugins/cc_foundry/bin/check_mode_dispatch.py --scan-dir plugins
pass_filenames: false
always_run: true
- id: check-gitignored-refs
name: "🙈 No refs to repo-private gitignored files"
language: system
entry: python3 plugins/cc_foundry/bin/check_gitignored_refs.py
types: [text]
- id: check-shared-drift
name: "🔁 cross-plugin shared-file drift"
language: system
entry: python3 plugins/cc_foundry/bin/propagate_shared.py
pass_filenames: false
always_run: true
- id: check-plugin-version-sync
name: "🔀 dual-host plugin manifest version sync"
language: system
entry: python3 plugins/cc_foundry/bin/check_plugin_version_sync.py --scan-dir plugins
# General: any dir holding BOTH .claude-plugin and .codex-plugin must agree
# on version — one release, two host manifests (bridge, codemap-py today).
files: ^plugins/[^/]+/\.(claude|codex)-plugin/plugin\.json$
pass_filenames: false
- id: check-codemap-guard
name: "🗺️ unmanaged codemap index-guard copy"
language: system
entry: python3 plugins/cc_foundry/bin/check_codemap_guard.py
pass_filenames: false
always_run: true
- id: check-bash-persistence
name: "🫙 shell var persistence across Bash blocks"
language: system
entry: python3 plugins/cc_foundry/bin/check_bash_persistence.py --scan-dir plugins
pass_filenames: false
always_run: true
- id: no-hardcoded-user-paths
name: "🚫 No hardcoded user paths"
language: pygrep
# Matches /Users/<realname> or /home/<realname> — alphanumeric usernames only.
# Placeholder docs like /Users/<name>/ are not flagged (< is not alphanumeric).
# Case-insensitive, trailing slash optional: catches lowercase "/users/jirka/"
# and end-of-line "/Users/jirka" (no trailing slash) — both missed by the old
# strict form. Leading slash stays required — dropping it false-positived on
# prose like "users/endpoints", "users/devs", and "$HOME/path" doc mentions.
entry: (?i)/(users|home)/[a-zA-Z0-9_-]+/?
# Plugin source (agents/skills/rules/hooks + manifest json) is the real install
# surface; a hardcoded path there breaks on every other machine. .claude/state
# runtime dirs are gitignored and excluded from the pattern by not matching.
files: ^plugins/[^/]+/(agents|skills|rules|hooks)/.*\.(md|js)$|^plugins/[^/]+/\.claude-plugin/[^/]+\.json$|^\.claude/(agents|skills|rules)/.*\.md$|^\.claude/hooks/[^/]+\.js$|^\.claude/settings\.json$|^\.codex/(agents|skills|rules)/.*\.md$|^\.codex/hooks/[^/]+\.js$|^\.codex/settings\.json$
- id: no-literal-tmp-in-hooks
name: "🌡️ No literal /tmp/ in hook source"
language: pygrep
# Hooks must derive their temp base (os.tmpdir(), ${TMPDIR:-/tmp}, tempfile) rather than
# hardcode /tmp/ — see cc_foundry/rules/claude-config.md §TMPDIR Sentinel Scoping. Only a
# quoted or template-literal /tmp/ is a real path constant; prose mentions inside comments
# (commit-guard.js documents its sentinel path) carry no quote and stay unflagged.
entry: '["''`]/tmp/'
# Replaces tests/hooks/tmp-paths.test.js, which checked a hardcoded 6-file cc_foundry list
# and missed the other 16 plugin hooks; this glob picks up new hooks automatically.
# bin/ included for the same reason: the per-script test_no_tmp_literal_in_source copies
# covered 8 of 124 bin/ scripts. Doctests must avoid quoted /tmp/ too — a doctest's
# expected-output line is indistinguishable from a real path constant to a line matcher.
files: ^plugins/[^/]+/(hooks|bin)/.*\.(js|py)$|^\.claude/hooks/.*\.(js|py)$|^\.codex/hooks/.*\.(js|py)$
- id: check-benchmark-portable-paths
name: "🧳 No hardcoded machine paths in benchmark source"
language: system
entry: python3 benchmarks/check-portable-paths.py
# Coverage: maintained benchmark docs/scripts plus the tracked methodology policy; excludes generated, result, and test trees.
files: ^benchmarks/(?!manifests/|results/|tests/).*\.(md|py|sh)$|^benchmarks/policy/provider-parity-methodology\.json$
- repo: https://github.com/jorisroovers/gitlint
rev: v0.19.1 # run `pre-commit autoupdate --repo https://github.com/jorisroovers/gitlint` to set
hooks:
- id: gitlint
name: "✅ gitlint"
stages: [commit-msg]
- repo: https://github.com/tox-dev/pyproject-fmt
rev: v2.25.3
hooks:
- id: pyproject-fmt
name: "📐 pyproject-fmt"
additional_dependencies:
- "tomli>=2.0.1"
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.25
hooks:
- id: validate-pyproject
name: "🔍 validate-pyproject"