Metadata-Version: 2.4
Name: patchwork-conventions
Version: 0.1.2
Summary: Mine your codebase. Generate CONVENTIONS.md. Stop AI agents from making up your style.
Author: patchwork contributors
License: MIT
Project-URL: Homepage, https://github.com/yourusername/patchwork
Project-URL: Repository, https://github.com/yourusername/patchwork
Project-URL: Issues, https://github.com/yourusername/patchwork/issues
Keywords: ai,claude-code,conventions,code-style,context-engineering,mcp,agent-skills,static-analysis,tree-sitter
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.0
Requires-Dist: rich>=13.0
Requires-Dist: tree-sitter>=0.23
Requires-Dist: tree-sitter-python>=0.23
Requires-Dist: tree-sitter-javascript>=0.23
Requires-Dist: tree-sitter-typescript>=0.23
Requires-Dist: mcp>=1.0
Requires-Dist: gitpython>=3.1
Requires-Dist: pathspec>=0.11
Requires-Dist: toml>=0.10; python_version < "3.11"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Provides-Extra: full
Requires-Dist: tree-sitter-rust>=0.23; extra == "full"
Requires-Dist: tree-sitter-go>=0.23; extra == "full"
Requires-Dist: tree-sitter-java>=0.23; extra == "full"
Dynamic: license-file

# 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`
