# patchwork **Mine your codebase. Generate CONVENTIONS.md. Stop AI agents from making up your style.** [![PyPI](https://img.shields.io/pypi/v/patchwork-conventions)](https://pypi.org/project/patchwork-conventions/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/) [![agent-skills](https://img.shields.io/badge/agent--skills-compatible-brightgreen)](https://github.com/topics/agent-skills) [![MCP](https://img.shields.io/badge/MCP-server-blue)](https://github.com/topics/mcp) --- Every team that uses AI coding assistants hits the same wall: **Claude writes `getUserById` in a codebase that uses `get_user_by_id`. Cursor creates `components/userCard.tsx` in a project that uses `user-card.tsx`. The agent invented a response shape that doesn't match the rest of the API.** You write a `CLAUDE.md` manually. It goes stale in two weeks. You write it again. **patchwork automates this.** It scans your actual source code using AST analysis and detects what your team really does — not what you think you do. --- ## What it detects | Category | What's mined | |---|---| | **Naming** | Functions, classes, variables, constants, files — with confidence score and real examples | | **Imports** | Absolute vs relative, path aliases (`@/`, `src/`), barrel files, destructuring style | | **Structure** | Source root, test layout, feature vs layer organisation, monorepo detection | | **Error Handling** | try/except vs Result types, logging framework, custom exception naming, propagation style | | **Testing** | Framework, assertion style, mocking library, coverage tool, fixture patterns | | **API Patterns** | Response shape, route param style, ORM, async pattern, GraphQL/gRPC presence | | **Git Workflow** | Commit message style, branch naming, co-change file pairs | | **Tech Stack** | Frameworks, package manager, linters, formatters, type checker, build tool, scripts | --- ## Quick start ```bash pip install patchwork-conventions cd your-project patchwork scan ``` That's it. You'll get a `CONVENTIONS.md` like this: ```markdown # CONVENTIONS.md > Auto-generated by patchwork on 2026-06-25 ## Tech Stack **Language:** python **Runtime:** Python >=3.11 **Package Manager:** uv **Frameworks:** fastapi, sqlalchemy **Linters:** ruff **Formatters:** ruff, black ## Naming Conventions ### Python - **Functions:** `snake_case` (97% consistent) - Examples: `get_user`, `parse_response`, `create_session` - **Classes:** `PascalCase` (100% consistent) - Examples: `UserService`, `AuthHandler`, `DatabaseClient` - **Constants:** `SCREAMING_SNAKE` - Examples: `MAX_RETRIES`, `API_BASE_URL` - **Files:** `snake_case` - **Private prefix:** `_` - **Test functions:** prefix `test_` ## Project Structure **Source root:** `src/` **Organisation:** layer-based **Tests:** separate (`tests/`) **Key directories:** - `src/` — source root - `tests/` — test suite - `migrations/` — database migrations ## Error Handling ### Python - **Pattern:** try/except - **Propagation:** raise - **Logging:** `structlog` - **Custom exception naming:** Error suffix - `ValidationError`, `AuthError`, `NotFoundError` ## Testing Conventions ### Python - **Framework:** pytest - **Coverage:** 34 test files / 89 source files (38% ratio) - **Assertions:** `assert(...)` - **Coverage tool:** `pytest-cov` - **Patterns:** fixtures, factories ## Git Conventions - **Commit style:** conventional commits - **Examples:** `feat(auth): add JWT refresh`, `fix(api): handle null user` - **Branch naming:** feature/name + fix/name ``` --- ## Why not argus or sourcebook? | Feature | patchwork | argus | sourcebook | |---|---|---|---| | AST-based naming analysis | ✅ tree-sitter | ❌ filesystem only | ❌ not done | | Confidence scores | ✅ per-category | ❌ | ❌ | | Real examples from your code | ✅ | ❌ | ❌ | | Counter-examples (inconsistencies) | ✅ | ❌ | ❌ | | Error handling pattern mining | ✅ | ❌ | ❌ | | API response shape detection | ✅ | ❌ | ❌ | | Co-change file pairs | ✅ | ❌ | ✅ | | Convention checking (`check` cmd) | ✅ | ❌ | ❌ | | MCP server with 8 tools | ✅ | ❌ | ✅ (4 tools) | | Watch mode | ✅ | ✅ (`sync`) | ✅ | | Zero LLM required | ✅ | ✅ | ✅ (layer A) | | Open source / MIT | ✅ | ✅ | ❌ BSL | --- ## Commands ```bash # Generate CONVENTIONS.md patchwork scan # Generate for a specific path patchwork scan /path/to/project # Generate AGENTS.md patchwork scan --agents-md # Append to CLAUDE.md patchwork scan --claude-md # Output JSON (for programmatic use) patchwork scan --json # Print to stdout (don't write file) patchwork scan --stdout # Limit to specific languages patchwork scan --lang python --lang typescript # Re-scan and update, preserving manual edits patchwork update # Show what would change patchwork diff # Print detected conventions to terminal patchwork show # Auto-watch mode (regenerate on change) patchwork watch # Start MCP server patchwork serve --stdio # for Claude Code patchwork serve --port 3742 # HTTP mode ``` --- ## Claude Code integration ### Option 1: CONVENTIONS.md (recommended) ```bash patchwork scan # run once # CONVENTIONS.md is automatically read by Claude Code ``` ### Option 2: Append to CLAUDE.md ```bash patchwork scan --claude-md ``` ### Option 3: MCP server **Claude Code** — add to `~/.claude.json` (or run `claude mcp add` interactively): ```json { "mcpServers": { "patchwork": { "command": "patchwork", "args": ["serve", "/path/to/your/project", "--stdio"] } } } ``` **Claude Desktop** — add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows): ```json { "mcpServers": { "patchwork": { "command": "patchwork", "args": ["serve", "/path/to/your/project", "--stdio"] } } } ``` **Cursor** — add to `.cursor/mcp.json` in your project root: ```json { "mcpServers": { "patchwork": { "command": "patchwork", "args": ["serve", ".", "--stdio"] } } } ``` Then your AI agent can use 8 on-demand tools: | Tool | When to use | |---|---| | `patchwork_scan` | Get complete conventions overview | | `patchwork_naming` | Before writing new identifiers | | `patchwork_structure` | Before creating new files/directories | | `patchwork_stack` | When choosing libraries or commands | | `patchwork_errors` | Before writing error handling | | `patchwork_testing` | Before writing test files | | `patchwork_git` | Before writing commit messages | | `patchwork_check` | Validate a proposed name | ### Option 4: Claude Code skill (SKILL.md) Copy `SKILL.md` from this repo to `~/.claude/skills/patchwork/SKILL.md` to get `/patchwork` slash commands. --- ## Watch mode (CI/auto-update) ```bash # Keep CONVENTIONS.md updated as you code patchwork watch & # Or in CI — fail if conventions changed patchwork diff || (patchwork update && git add CONVENTIONS.md && git commit -m "chore: update conventions") ``` --- ## Python API ```python from patchwork import scan from patchwork.scanner import ScanOptions from pathlib import Path # Full scan report = scan(ScanOptions(root=Path("."))) # Render to markdown print(report.to_markdown()) # Render to JSON import json data = json.loads(report.to_json()) # Access specific results naming = report.naming.get("python") print(f"Functions: {naming.functions.style} ({naming.functions.confidence:.0%})") print(f"Examples: {naming.functions.examples}") structure = report.structure print(f"Source root: {structure.source_root}") print(f"Organisation: {structure.organisation}") ``` --- ## Supported languages | Language | AST (tree-sitter) | Fallback regex | |---|---|---| | Python | ✅ full | ✅ | | TypeScript | ✅ full | ✅ | | JavaScript | ✅ full | ✅ | | Go | ✅ (with `full` extra) | ✅ | | Rust | ✅ (with `full` extra) | ✅ | | Java | ✅ (with `full` extra) | ✅ | | Ruby, PHP, C#, C++ | ❌ | ✅ regex only | Install full language support: ```bash pip install 'patchwork-conventions[full]' ``` --- ## How it works ``` your codebase │ ▼ ConfigDetector ← reads package.json, pyproject.toml, go.mod, Cargo.toml │ ▼ File discovery ← respects .gitignore, skips node_modules etc. │ ▼ Per-language AST ← tree-sitter parses every file into a syntax tree │ ├── NamingMiner → extracts function/class/variable names, classifies style ├── ImportMiner → detects import patterns, aliases, barrel files ├── StructureMiner → analyses directory layout, test co-location ├── ErrorHandlingMiner → detects try/catch patterns, logging, custom exceptions ├── TestingMiner → identifies framework, assertion style, mocking ├── APIPatternMiner → finds response shapes, ORMs, route styles └── GitPatternMiner → mines commit history, branches, co-change pairs │ ▼ ConventionReport │ ├── CONVENTIONS.md (default) ├── AGENTS.md (--agents-md) ├── CLAUDE.md (--claude-md, appends) └── JSON (--json) ``` All analysis is **100% local** — no API calls, no telemetry, no data leaves your machine. --- ## Performance On a 1,000-file TypeScript monorepo: - Without tree-sitter: ~0.8s - With tree-sitter (full AST): ~2.1s On a 500-file Python project: - ~1.1s Results are deterministic — same codebase always produces the same output. --- ## Contributing ```bash git clone https://github.com/yourusername/patchwork cd patchwork pip install -e '.[dev]' pytest ``` Pull requests welcome. See [CONTRIBUTING.md](CONTRIBUTING.md). --- ## License MIT — free for personal and commercial use. --- ## Topics `claude-code` · `agent-skills` · `mcp` · `context-engineering` · `hallucination-detection` · `code-conventions` · `static-analysis` · `tree-sitter` · `developer-tools` · `ai-coding`