feat(typos-format): per-file typos autofix hook plugin#880
Closed
kyle-sexton wants to merge 1 commit into
Closed
Conversation
New plugin, mirroring the markdown-format/ruff-format hook shape: a PostToolUse hook runs `typos --force-exclude -w --format json` against every edited file (no extension filter — typos is a cross-language spell checker), auto-fixing every unambiguous typo and surfacing residual (ambiguous) findings via additionalContext, always advisory. Discovers the consuming repo's own optional _typos.toml the way typos itself does (anchored on the edited file, not the hook's cwd). Closes #831. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K1V3gkrfSf75isB8MiDy3o
This was referenced Jul 21, 2026
Contributor
Author
|
Superseded by #872, which independently implemented and merged the same Closing this PR without merging. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
New plugin —
plugins/typos-format/— a PostToolUse hook that runstypos -won everyedited file, auto-fixing unambiguous spelling mistakes and surfacing residual (ambiguous)
findings via
additionalContext. Zero-config: uses typos' built-in dictionary and theconsuming repo's own optional
_typos.tomlallowlist.Fix
PostToolUsehook onWrite|Edit, no extension filter (typos is a cross-language spellchecker, not a single-ecosystem formatter) —
typos --force-exclude -w --format json <file>runs against every edited file.--force-excludeis load-bearing, not cosmetic: verified empirically (typos-cli 1.44.0)that without it, an explicitly-named file bypasses BOTH the consumer's
[files] extend-excludeglobs AND typos' own binary-file detection — an unflagged hook wouldscan every binary edit for garbage "typos". With it, both are honored.
(verified: an absolute file path checked from an unrelated working directory still
resolves a
_typos.tomlseveral directories above it) — so, unlike markdownlint-cli2,this hook never needs to
cdto the repo root.typos -w --format jsonin one pass already yields exactly the residual findings —fixed typos never appear in that output (verified), so no separate fix-then-verify pass
is needed (simpler than the markdown-format/ruff-format two-pass shape).
--format jsonnote):0= clean,2= residual findings remain, anything else = thetool itself broke (bad config, internal error) rather than rendering a spelling judgment.
0. Kill switch:typos_format_enableduserConfigboolean (default
true)./typos-format:setupskill on the uniform check-centric contract (checkread-only,applyguidance-only — every prerequisite is aPATHbinary or the native toggle, sothere is no write path).
0.1.0— confirmed viagit logonbash-lint's (nowbash-format)founding commit that a brand-new plugin's first
plugin.jsonuses0.1.0with noCHANGELOG.mdentry at creation; the changelog only starts recording at the firstsubsequent change. No clearer format-hook precedent exists for a from-scratch plugin.
Verification
bash plugins/typos-format/hooks/typos-format.test.sh— 63/64 assertions pass. The onefailure (
telemetry/slow-sinkC1 fd1-leak timing, expects <2000ms) is a pre-existingplatform-specific flake on this Windows/Git Bash machine, not introduced by this
change:
plugins/markdown-format/hooks/markdown-format.test.sh(untouched, already onmain) fails the identical assertion on the same machine (5182ms vs. the 2000ms bound).scripts/sync-hook-utils.sh --check— pass (11/11 plugin copies matchlib/hook-utils.sh).scripts/check-silent-skips.sh— pass (missing-typos/missing-jqpaths usehook::notice_once+hook::emit_skip_notice).scripts/check-changelog-parity.sh --checkand--check-bump origin/main— pass.node scripts/validate-plugin-contracts.mjs— pass (1913 plugin files checked).node scripts/generate-catalog.mjs --check— pass (catalog in sync withmarketplace.json).claude plugin validate plugins/typos-format/— pass.--force-excludebehavior, exitcodes, ambiguous-correction handling) was independently re-derived by hand against a real
typos-cli 1.44.0binary before this PR touched any file — see prior turns in theauthoring session for the raw transcript.
Known gap, left as-is on purpose: CI's
plugin-gatejob does not installtypos(unlikeshellcheck/biome/ruff, which it does install), sotypos-format.test.shwill SKIPthere rather than execute its behavioral assertions — this mirrors the existing, documented
shfmt-optional precedent inscripts/run-plugin-tests.sh("an individual test SKIPs whenan optional tool it needs is absent"). Provisioning
typosonto the CI runner is aseparate, shared-
ci.ymlchange outside this PR's scope.Closes #831
Related
docs/topics/lint-static-analysis-gaps/PLAN.mdplugins/markdown-format/(issue-named primary template) andplugins/ruff-format/(closer analog for the config-driven exclude/discovery shape,e.g.
--force-excluderationale)Provenance note
This worktree was briefed as "completely clean, no prior work" but already contained a
complete, uncommitted implementation (hook script, tests, README, CHANGELOG, setup skill,
plus
marketplace.json/README.mdedits) from an untracked prior session. Before buildingon it, every non-trivial behavioral claim in the code/tests/docs was independently
re-verified by hand against a real
typosbinary (see Verification above) rather thantrusted as-is; nothing was taken on faith. It matched my own independent findings closely,
so it was kept rather than rewritten.