# ai-refactor-cli
> Rule-based legacy code refactoring CLI. **Complement, not competitor**, to general AI coding agents (Claude Code / Codex / Cursor).
   
> **Stability note:** v0.x releases may include breaking changes. The CLI surface and rule IDs aim to stay stable; internal APIs are not yet stabilized.
## What it does
`ai-refactor` scans a codebase for **well-known legacy patterns** and optionally rewrites them. v0.2.0 adds real `--apply` support (backed by tree-sitter AST) for Django FBV → CBV conversion.
| `typescript-no-any` | `*.ts`, `*.tsx` | `: any`, `<any>`, `any[]`, `Array<any>` | planned |
| `python-missing-typing` | `*.py` | `def foo(x):` without parameter type hints (AST-based)| planned |
| `django-fbv` | `*.py` (Django) | Top-level FBV `def view(request, ...)` (AST-based) | v0.2.0 |
### Why tree-sitter?
v0.1.0 used regex. v0.2.0 switches Python detection to **tree-sitter AST queries**, which means:
- Zero false positives for patterns inside comments (`# def home(request):`)
- Zero false positives for patterns inside string literals
- Correct scope resolution (class methods are not flagged as FBVs)
## Why a separate tool?
It is **not** an AI coding agent. It is a deterministic, rule-based pre/post-processor that fits into CI:
| Claude Code / Codex | Interactive agent | Generate & edit code with broad context |
| Cursor / Windsurf | IDE-embedded AI | Inline pair programming |
| **`ai-refactor`** | Rule-based regularizer | "Make this repo conform to our standards" |
Returns a non-zero exit code when findings exist — slots straight into a PR gate.
## Installation
```bash
# From crates.io (v0.2.0+)
cargo install ai-refactor-cli
# From source (development)
cargo install --git https://gitlab.com/locallab1/ai-refactor-cli
```
Minimum Rust version: **1.75**.
## Quick Start
```bash
# Scan everything (all rules)
ai-refactor scan ./src
# Scan a single rule only
ai-refactor scan ./src --rule django-fbv
# Emit JSON for CI pipelines
ai-refactor scan ./src --format json
# Dry-run: detect FBVs, do not write
ai-refactor fix ./views.py --rule django-fbv
# Actually convert FBVs to CBVs (creates .bak backup)
ai-refactor fix ./views.py --rule django-fbv --apply
```
Exit codes:
| `0` | No findings |
| `1` | Findings present (CI gate fails) |
| `2` | Invocation error (unknown rule, bad path) |
## Examples
### Scanning for Django FBVs
```
$ ai-refactor scan examples/
ai-refactor: 2 finding(s)
[django-fbv] examples/views.py:1
def home(request):
[python-missing-typing] examples/views.py:1
def home(request):
```
### Applying FBV → CBV conversion
```
$ cat examples/views.py
def home(request):
return HttpResponse("hello")
$ ai-refactor fix examples/views.py --rule django-fbv --apply
ai-refactor: 1 finding(s)
[django-fbv] examples/views.py:1
def home(request):
[ai-refactor] Applied: `def home()` → `class HomeView(View)` at byte 0
[ai-refactor] Backup written to examples/views.py.bak
$ cat examples/views.py
class HomeView(View):
def get(self, request):
return HttpResponse("hello")
```
### JSON output (CI-friendly)
```bash
## Using as a library
```rust
use ai_refactor_cli::scanner::scan_path;
let findings = scan_path("./src", Some("django-fbv"))?;
for f in &findings {
println!("[{}] {}:{} — {}", f.rule_id, f.file, f.line, f.snippet);
}
```
## CI Integration
```yaml
# GitLab CI
refactor-check:
stage: lint
image: rust:1-slim
script:
- cargo install ai-refactor-cli
- ai-refactor scan ./src
```
```yaml
# GitHub Actions
- name: Check legacy patterns
run: |
cargo install ai-refactor-cli
ai-refactor scan ./src
```
## Roadmap
- **v0.1.0** — detection for 3 rules, regex-backed.
- **v0.2.0 (this release)** — tree-sitter AST for Python, real `--apply` for `django-fbv`, benchmark harness, crates.io package.
- **v0.3.0** — tree-sitter-typescript integration. `--apply` for `python-missing-typing` and `typescript-no-any`.
- **v0.4.0** — Custom rule DSL (`refactor.toml`). AI fallback via OpenRouter for ambiguous transformations.
## Contributing
This is an early alpha owned by [合同会社ジモラボ](https://locallab.jp). External contributions are welcome but the rule set is currently driven by **internal dogfooding** on locatax / realingo / lookupai. Open an issue before sending a PR.
See [`docs/architecture.md`](docs/architecture.md) for the internal module layout and design rationale.
## License
Apache-2.0 © 合同会社ジモラボ / Masaaki Ito