瀏覽代碼

Add design document for format-on-save feature

Jesse Vincent 11 月之前
父節點
當前提交
1ef5758621
共有 1 個文件被更改,包括 105 次插入0 次删除
  1. 105 0
      docs/plans/2025-10-18-format-on-save.md

+ 105 - 0
docs/plans/2025-10-18-format-on-save.md

@@ -0,0 +1,105 @@
+# Format on Save Feature
+
+**Date:** 2025-10-18
+**Status:** Approved for Implementation
+
+## Problem Statement
+
+Users want files to be automatically formatted when Claude writes or modifies them, respecting project-specific formatters (Prettier, Black, gofmt, etc.). Currently, files written by Claude may not match the project's formatting standards, requiring manual formatting afterward.
+
+## Goals
+
+- Automatically format files when Claude saves them (via Write/Edit tools)
+- Detect formatters from project configuration files
+- Support common formatters: Prettier, Black, gofmt, rustfmt
+- Make formatting opt-in via `.claude/settings.json`
+- Gracefully handle missing formatters or formatting failures
+
+## Non-Goals
+
+- Real-time formatting during editing
+- Custom formatter configuration beyond project defaults
+- Formatting validation or enforcement
+- Integration with LSP/language servers
+
+## Design
+
+### Architecture
+
+```
+User enables formatOnSave in settings
+         ↓
+Claude uses Write/Edit tool
+         ↓
+File is written to disk
+         ↓
+Format detector checks for formatter config
+         ↓
+If formatter found and formatOnSave enabled:
+  Run formatter on file
+         ↓
+Return success/failure to Claude
+```
+
+### Components
+
+1. **Settings Schema** (`.claude/settings.schema.json`)
+   - Add `formatOnSave: boolean` option (default: false)
+
+2. **Format Detector** (`src/utils/formatDetector.ts`)
+   - Scans for config files: `.prettierrc`, `pyproject.toml`, etc.
+   - Returns formatter command based on file extension and detected config
+   - Caches detection results per session
+
+3. **Format Executor** (`src/utils/formatExecutor.ts`)
+   - Executes formatter command on file path
+   - Handles timeouts (5 second max)
+   - Returns success/failure without blocking
+
+4. **Integration Point**
+   - Modify Write/Edit tools to call formatter after file write
+   - Only format if `formatOnSave` is enabled
+   - Log formatting results but don't fail on formatting errors
+
+### Format Detection Rules
+
+| File Extension | Config Files to Check | Formatter Command |
+|----------------|----------------------|-------------------|
+| `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.md` | `.prettierrc*`, `prettier.config.*` | `prettier --write <file>` |
+| `.py` | `pyproject.toml` (with `[tool.black]`), `.black` | `black <file>` |
+| `.go` | (always available in Go projects) | `gofmt -w <file>` |
+| `.rs` | `rustfmt.toml`, `.rustfmt.toml` | `rustfmt <file>` |
+
+### Error Handling
+
+- If formatter not found: silently skip formatting
+- If formatter fails: log error but return success for file write
+- If formatter times out: kill process and log warning
+- Never fail a Write/Edit operation due to formatting issues
+
+## Implementation Plan
+
+1. Add `formatOnSave` setting to schema and types
+2. Implement format detector with tests
+3. Implement format executor with tests
+4. Hook into Write/Edit tools
+5. Add integration tests
+6. Update documentation
+
+## Testing Strategy
+
+- Unit tests for format detection logic
+- Unit tests for format execution with mock formatters
+- Integration tests with real formatter tools
+- Test error cases: missing formatter, timeout, failed formatting
+- Test that formatOnSave=false skips formatting
+
+## Open Questions
+
+None - ready for implementation.
+
+## Alternatives Considered
+
+1. **LSP Integration**: Too complex, requires language server setup
+2. **Pre-commit hooks**: Only works on git commits, not all file writes
+3. **Manual formatting command**: Requires user to remember to run it