Skip to main content

A multi-language code performance analyser with static analysis and AI-powered fix generation.

Project description

๐Ÿ”ง codewrench

Point it at your code. Get back what's slow and how to fix it.

Codewrench is a multi-language performance analyser that combines static analysis with AI-powered explanations. It finds real performance issues in your code โ€” nested loops, N+1 queries, inefficient patterns, bad practices โ€” then explains exactly why they're a problem and shows you the fix.

No cloud, no setup hell, no enterprise pricing. Just run it on a file.


Installation

pip install codewrench

Create a .env file in your project root:

GROQ_API_KEY=your_key_here

Get a free Groq API key at console.groq.com

AI analysis and fixes are optional. Static analysis and profiling work without an API key.


Usage

codewrench yourfile.py
codewrench app.js
codewrench main.go
codewrench ./myproject

Codewrench detects the language from the file extension automatically. Point it at a folder and it walks the entire project.

CLI flags

codewrench <file_or_folder>            # static analysis only
codewrench <file> --profile            # + profile original file
codewrench <file> --profile --fix      # + profile before/after AI fix
codewrench <file> --analyse            # + AI explanation of issues
codewrench <file> --fix                # + apply AI fixes to file
codewrench <file> --save-report        # + save codewrench_report.md
codewrench <file> --no-backup          # don't keep .bak when fixing
codewrench --revert <file>             # restore from .bak backup

Example output

========================================
         CODEWRENCH REPORT
========================================
Files Scanned  : 1
Languages      : python
Issues Found   : 8 across 1 files
========================================

--- Warnings ---
  Nested loop at line 19 โ€” potential O(nยฒ)
  String concatenation at line 22 โ€” use ''.join() instead
  re.compile() inside loop at line 31 โ€” move it outside, compile once and reuse
  Potential N+1 query โ€” 'User.objects.filter' called inside loop at line 45

--- Performance Profile ---

Top 5 slowest functions BEFORE fix:
  process_data                   cumtime: 2.341s
  build_string                   cumtime: 0.812s

Top 5 slowest functions AFTER fix:
  process_data                   cumtime: 0.421s
  build_string                   cumtime: 0.109s

--- AI Analysis ---

1. Nested loop at line 19
   Problem: Two nested loops over the same data gives you O(nยฒ) complexity.
   For 1000 items that's 1,000,000 iterations instead of 1,000.

What it catches

High priority

  • Nested loops โ€” O(nยฒ) and worse
  • N+1 queries โ€” ORM calls inside loops (Django, SQLAlchemy, general DB patterns)
  • Expensive I/O calls inside loops (open, requests, etc.)
  • re.compile() inside loops โ€” compile once, reuse
  • print() / logging inside loops โ€” I/O on every iteration
  • await inside loops โ€” use asyncio.gather() or Promise.all()
  • Repeated attribute access that should be cached
  • String concatenation with += in loops
  • String concatenation in nested loops โ€” quadratic complexity
  • Unnecessary object creation in loops (dict(), list(), etc.)
  • Generic expensive function calls inside loops
  • len() calls inside loops

Medium priority

  • Sorting inside loops โ€” O(n log n) per iteration
  • Linear search โ€” .index() and .count() on lists inside loops
  • List concat with + instead of .extend()
  • List appends inside nested loops
  • Unnecessary list(range(n)) creation
  • Bare except: and overly broad except Exception
  • try/except inside loops
  • Global variable access inside loops
  • Mutable default arguments
  • Import inside functions

Language-specific

  • JS/TS: for...in on arrays โ€” use for...of or .forEach()
  • Go: goroutine spawned inside loop โ€” use a worker pool
  • C++: large types passed by value โ€” use const T&

Supported languages

Language Extension
Python .py
JavaScript .js
TypeScript .ts
Go .go
C .c
C++ .cpp, .cc

.wrenchignore

Create a .wrenchignore file in your project root to skip files or folders:

migrations/
tests/
legacy_code.py
*.min.js

Works like .gitignore โ€” supports wildcards and directory patterns.


How it works

your file
    โ†“
Tree-sitter parses it into a syntax tree
    โ†“
IR translator converts to language-agnostic representation
    โ†“
24 detectors run static analysis on the IR
    โ†“
Optional: profiling before/after fix (Python, Node.js, Go)
    โ†“
Optional: findings sent to Groq (Llama 3.3 70B)
    โ†“
Plain English explanation + fix

The static analysis layer is deterministic โ€” it either finds a nested loop or it doesn't. No hallucination. The AI layer explains what the detectors already confirmed exists.


Roadmap

  • Static analysis (Python, JS, TS, Go, C, C++)
  • AI-powered explanations and fixes
  • Multi-language IR architecture
  • Runtime profiling โ€” before/after benchmark (Python, Node.js, Go)
  • 24 detectors across high, medium, and language-specific priority
  • Folder support with recursive analysis
  • .wrenchignore support
  • Smart API batching โ€” one call per folder, not per file
  • pip install codewrench
  • Language-specific detectors (JS, Go, C++)
  • Git diff integration โ€” analyse only what changed
  • VS Code extension
  • Web UI

Project structure

codewrench/
โ”œโ”€โ”€ detectors/
โ”‚   โ”œโ”€โ”€ base.py           โ† depth tracking, core visitor
โ”‚   โ”œโ”€โ”€ high.py           โ† high priority detectors
โ”‚   โ”œโ”€โ”€ medium.py         โ† medium priority detectors
โ”‚   โ””โ”€โ”€ lang_detectors.py โ† language-specific detectors
โ”œโ”€โ”€ languages/
โ”‚   โ”œโ”€โ”€ python_rules.py   โ† Tree-sitter node mappings per language
โ”‚   โ”œโ”€โ”€ js_rules.py
โ”‚   โ”œโ”€โ”€ ts_rules.py
โ”‚   โ”œโ”€โ”€ go_rules.py
โ”‚   โ”œโ”€โ”€ c_rules.py
โ”‚   โ””โ”€โ”€ cpp_rules.py
โ”œโ”€โ”€ profilers/
โ”‚   โ””โ”€โ”€ profiler.py       โ† cProfile + Node.js + Go profiling
โ”œโ”€โ”€ ir.py                 โ† language-agnostic IR node
โ”œโ”€โ”€ ir_translator.py      โ† Tree-sitter โ†’ IR translation
โ”œโ”€โ”€ parser_engine.py      โ† language detection + parser setup
โ”œโ”€โ”€ ai_engine.py          โ† Groq integration
โ”œโ”€โ”€ report.py             โ† terminal + markdown output
โ”œโ”€โ”€ errors.py             โ† error handling
โ”œโ”€โ”€ wrenchignore.py       โ† .wrenchignore support
โ””โ”€โ”€ main.py               โ† entry point, CLI, orchestration

Contributing

Pull requests welcome. If you want to add a new language, add a rules file in languages/ mapping Tree-sitter node types to the generic IR types. That's it โ€” the detectors work on all languages automatically.

Open an issue first for anything major.


Built by Vishad Jain

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codewrench-0.2.0.tar.gz (19.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codewrench-0.2.0-py3-none-any.whl (22.8 kB view details)

Uploaded Python 3

File details

Details for the file codewrench-0.2.0.tar.gz.

File metadata

  • Download URL: codewrench-0.2.0.tar.gz
  • Upload date:
  • Size: 19.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for codewrench-0.2.0.tar.gz
Algorithm Hash digest
SHA256 c4829813b5d93c47a5e50ef99a8723796f0ed540659be8cb2b4261cd06a9be11
MD5 8e993107e317e1e69ffe9df1b30468d1
BLAKE2b-256 6a5c82af3a585274c83b4ac61702ecd61ff6151ca56e52a56de2318bdb4f99de

See more details on using hashes here.

File details

Details for the file codewrench-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: codewrench-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 22.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for codewrench-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6f934a37a7b43d0e780fd3934c21fc225ec6d2a49a67f6637abb0349fe4a90d3
MD5 4f4cffc29d444a678a1c60dd74b09b8b
BLAKE2b-256 0c649e8f539de0372273e5ef75b5bf8e8962b2c48d01ec80abec1d9cb11ee077

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page