Add composable multi-language linting and formatting system

PostToolUse hook auto-formats files after Edit/Write/MultiEdit with
git-blob checkpoints for safe revert. Pre-commit hook for staged files.
Canonical formatter scripts for py, sh, ts, sql, json (+ symlinks for
js, yaml, md). Install and setup scripts for project opt-in.

Includes best-practices/linting.md, HOOKS.md docs, README.md, and
session log.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Paul O'Reilly
2026-03-13 11:50:36 +13:00
parent a463dc0793
commit d3a92326de
18 changed files with 700 additions and 5 deletions

View File

@@ -0,0 +1,22 @@
# Session Log — 2026-03-13
## Summary
Implemented the composable multi-language linting and formatting system for Claude Code. Created formatter scripts, PostToolUse/pre-commit hooks, install scripts, `/linter` skill, best-practices documentation, and a README with project opt-in instructions.
## Decisions
- Decision: Formatter scripts exit 1 on lint errors, dispatcher hook decides exit code (exit 2 for PostToolUse feedback) — Rationale: separates formatter logic from hook semantics; same scripts work for both PostToolUse and pre-commit
- Decision: Checkpoint uses `git hash-object -w` with `.pre-lint` sidecar file — Rationale: fast (~1ms), no commits/stash, orphan blobs auto-GC'd; falls back to `cp` outside git repos
- Decision: Projects opt in via symlinks in `formatters/` rather than config — Rationale: zero-config, visible in `ls`, no parsing needed; hook walks up directory tree to find `formatters/`
- Decision: Symlinked README.md into `~/dev/claude/` for visibility — Rationale: makes setup guide discoverable from the top-level working directory
## Key Context
- claude-foundations lives at `~/dev/claude/projects/claude-foundations/` (not `~/dev/claude/claude-foundations/`)
- PostToolUse exit code 2 feeds stderr back to Claude as feedback without blocking the edit
- Agent-type hooks are read-only (no Edit/Write) — lint fixing must happen via Agent tool subagent, not hooks
- All hooks in an array run in parallel, not sequentially
- Formatter contract: `$1` = absolute path, format in place, stderr for errors, exit 0/1, no `set -e`, silent on missing tools
## Process Notes
- Plan was thorough and complete — implementation was straightforward with minimal deviation
- Smoke tests confirmed all four paths: clean file, missing tools, no formatters dir, no extension
- No actual lint errors were triggered during testing since test files were already clean