Self-contained Claude Code plugin that automatically formats and lints edited files. Drop it into any Claude Code plugin marketplace and enable it — no other plugins required.
Three-phase pipeline that runs transparently during your Claude Code session:
- Collect (PostToolUse on Edit/Write) — Records which files Claude edits
- Format (Stop hook) — Batch-formats all edited files when Claude finishes responding
- Lint (Stop hook) — Batch-lints all edited files and surfaces warnings as context
Additionally validates JSON, JSONC, YAML, and TOML syntax immediately after each edit.
All phases are non-blocking. Missing tools are silently skipped. The plugin always exits cleanly — it will never interrupt Claude.
Install the tools for the languages you work with. Everything is optional — the plugin gracefully skips any tool that isn't found.
| Language | Formatter | Linter(s) | Install |
|---|---|---|---|
| Python | ruff | pyright, ruff check | pip install ruff / npm i -g pyright |
| Python (fallback) | black | — | pip install black |
| Go | gofmt (bundled with Go) | go vet (bundled with Go) | Install Go |
| JS/TS/CSS/GraphQL/HTML | biome | biome lint | npm i -D @biomejs/biome or npm i -g @biomejs/biome |
| Shell | shfmt | shellcheck | brew install shfmt shellcheck |
| Markdown/YAML/TOML | dprint | — | brew install dprint |
| Dockerfile | dprint | hadolint | brew install hadolint |
| Rust | rustfmt (bundled with Rust) | clippy (bundled with Rust) | Install Rust |
| JSON/JSONC/YAML/TOML | — | syntax-validator (Python stdlib) | No extra install needed |
The dprint formatter looks for a config file at /usr/local/share/dprint/dprint.json. If this file doesn't exist, dprint formatting is skipped. Create one with your preferred settings, or use a minimal config:
{
"markdown": {},
"toml": {},
"yaml": {}
}Biome is resolved in this order:
- Project-local: walks up from the edited file looking for
node_modules/.bin/biome - Global: checks PATH via
which biome
Pre-installed and activated automatically — no setup needed.
Use this plugin in any Claude Code setup:
-
Clone the CodeForge repository:
git clone https://github.com/AnExiledDev/CodeForge.git
-
Enable the plugin in your
.claude/settings.json:{ "enabledPlugins": { "auto-code-quality@<clone-path>/.devcontainer/plugins/devs-marketplace": true } }Replace
<clone-path>with the absolute path to your CodeForge clone.
You edit a file (Edit/Write tool)
│
├─→ collect-edited-files.py Appends path to temp files
└─→ syntax-validator.py Validates JSON/YAML/TOML syntax immediately
│
│ ... Claude keeps working ...
│
Claude stops responding (Stop event)
│
├─→ format-on-stop.py Reads temp file, formats each file by extension
└─→ lint-file.py Reads temp file, lints each file, injects warnings
Edited file paths are stored in session-scoped temp files:
/tmp/claude-cq-edited-{session_id}— consumed by the formatter/tmp/claude-cq-lint-{session_id}— consumed by the linter
Both are always cleaned up after processing (even on error).
| Hook | Timeout |
|---|---|
| File collection | 3s |
| Syntax validation | 5s |
| Batch formatting | 15s total |
| Batch linting | 60s total |
| Individual tool | 10-12s each |
This plugin bundles functionality that may overlap with other plugins. If you're using any of the following, disable them before enabling this plugin to avoid duplicate processing:
auto-formatter— formatting is included hereauto-linter— linting is included herecode-directivecollect-edited-files.pyhook — file collection is included here
All pipelines use the claude-cq-* temp file prefix, so enabling both won't corrupt data — but files would be formatted and linted twice.
auto-code-quality/
├── .claude-plugin/
│ └── plugin.json # Plugin metadata
├── hooks/
│ └── hooks.json # Hook registrations (PostToolUse + Stop)
├── scripts/
│ ├── collect-edited-files.py # File path collector (PostToolUse)
│ ├── syntax-validator.py # JSON/YAML/TOML validator (PostToolUse)
│ ├── format-on-stop.py # Batch formatter (Stop)
│ └── lint-file.py # Batch linter (Stop)
└── README.md # This file
- Python 3.11+ (for
tomllibsupport in syntax validation; older Python skips TOML) - Claude Code with plugin hook support