ai-refactor-cli 0.2.0

Rule-based legacy code refactoring CLI (TypeScript any / Python typing / Django FBV→CBV). Complement to general AI coding agents.
Documentation

ai-refactor-cli

Rule-based legacy code refactoring CLI. Complement, not competitor, to general AI coding agents (Claude Code / Codex / Cursor).

status: alpha license: Apache-2.0 rust 2021 crates.io

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.

Rule id Target What it catches --apply
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:

Tool Layer What it does
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

# 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

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

Code Meaning
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)

ai-refactor scan ./src --format json | jq '.[].rule_id'

Using as a library

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

# GitLab CI
refactor-check:
  stage: lint
  image: rust:1-slim
  script:
    - cargo install ai-refactor-cli
    - ai-refactor scan ./src
# 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 合同会社ジモラボ. 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 for the internal module layout and design rationale.

License

Apache-2.0 © 合同会社ジモラボ / Masaaki Ito