Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

95 Commits

Repository files navigation

prefact

PyPI versionPython 3.10+License: Apache-2.0Code style: black

AI Cost Tracking

PyPIVersionPythonLicenseAI CostHuman TimeModel

  • 🤖 LLM usage: $21.3690 (81 commits)
  • 👤 Human dev: ~$3798 (38.0h @ $100/h, 30min dedup)

Generated on 2026-07-29 using openrouter/qwen/qwen3-coder-next


Automatic Python prefactoring toolkit — detect, fix, and validate common code issues introduced by LLMs and humans alike.

The Problem

img.png

When using LLMs for code generation, they often silently change import paths from absolute to deep relative:

# ❌ LLM introduces thisfrom ....llm.generatorimportgenerate_strategyfrom ....loaders.yaml_loaderimportsave_strategy_yaml# ✅ You wanted thisfromplanfile.llm.generatorimportgenerate_strategyfromplanfile.loaders.yaml_loaderimportsave_strategy_yaml

prefact automatically detects, fixes, and validates such issues in a three-phase pipeline.

Features

RuleIDAuto-fixDescription
Relative → Absolute importsrelative-importsConverts from ....x import y to from pkg.x import y
Unused importsunused-importsRemoves imports never referenced in the module
Duplicate importsduplicate-importsRemoves the same name imported twice
Wildcard importswildcard-imports🔍Flags from x import *
Unsorted importssorted-imports🔍Flags import blocks not ordered stdlib→3rd-party→local
String concatenationstring-concat🔍Flags "Hello " + name → suggests f-strings
Missing return typesmissing-return-type🔍Flags public functions without return type hints

✅ = auto-fix · 🔍 = scan-only (report)

Performance Improvements

  • Parallel Processing: Scans files in parallel when enabled
  • Smart Filtering: Automatically skips large files (>100KB) and empty files
  • Optimized Scanning: Excludes test directories and examples by default
  • Deduplication: Prevents duplicate tickets and TODO entries

Examples

The examples/ directory contains comprehensive examples for different use cases:

ExampleDescription
sample-projectRealistic project with all issues demonstrated
01-individual-rulesEach rule explained with before/after code
02-multiple-rulesCombining multiple rules for comprehensive cleanup
03-output-formatsConsole vs JSON output examples
04-custom-rulesWriting your own prefactoring rules
05-ci-cdGitHub Actions, GitLab CI, Azure DevOps configs
06-api-usageUsing prefact programmatically from Python

Quick Example

# Try the sample projectcd examples/sample-project
prefact scan --path . --config prefact.yaml
prefact fix --path . --config prefact.yaml

See examples/README.md for a detailed guide to all examples.

Installation

pip install -e .# with dev dependencies (pytest)
pip install -e ".[dev]"

Quick Start

# Generate config file
prefact init
# List all available rules
prefact rules
# Scan only (no changes)
prefact scan --path ./my_project --package mypackage
# Fix + validate (with backups)
prefact fix --path ./my_project --package mypackage
# Dry-run (show what would change)
prefact fix --path ./my_project --package mypackage --dry-run
# Check a single file
prefact check ./my_project/src/mypackage/core/service.py --package mypackage
# JSON output for CI
prefact fix --path . --format json -o report.json

📚 Want to see prefact in action? Check out our comprehensive examples with real-world scenarios!

Pipeline Architecture

┌─────────┐ ┌─────────┐ ┌────────────┐
│ SCAN │ ──→ │ FIX │ ──→ │ VALIDATE │
│ │ │ │ │ │
│ Detect │ │ Apply │ │ Syntax OK? │
│ issues │ │ fixes │ │ Regressions│
│ per rule│ │ + backup│ │ preserved? │
└─────────┘ └─────────┘ └────────────┘
  1. Scan — each rule walks the AST / CST and emits Issue objects
  2. Fix — rules with auto-fix transform the source (via libcst for formatting-safe changes)
  3. Validate — post-fix checks: syntax valid, no regressions, import counts preserved

Configuration

Create prefact.yaml (auto-generated via prefact init):

package_name: planfileinclude:
- "**/*.py"exclude:
- "**/venv/**"
- "**/build/**"
- "**/tests/**"
- "**/test*/**"
- "**/examples/**"tools:
parallel: truecache: trueperformance:
max_workers: 4rules:
relative-imports:
enabled: trueseverity: warningunused-imports:
enabled: trueseverity: infoduplicate-imports:
enabled: truewildcard-imports:
enabled: trueseverity: errorsorted-imports:
enabled: falsestring-concat:
enabled: truemissing-return-type:
enabled: false

Autonomous Mode

Prefact includes an autonomous mode that automatically:

  • Scans your project for issues
  • Generates TODO.md with all found issues
  • Creates tickets in planfile.yaml for tracking
  • Updates CHANGELOG.md with fixes
  • Optionally runs TestQL scenarios and bridges failures into tickets
# Run full autonomous workflow
prefact -a
# Or skip tests/examples for faster runs
prefact -a --skip-tests --skip-examples
# Include TestQL validation as the final step
prefact -a --with-testql
# Use a custom directory for *.testql.toon.yaml scenarios
prefact -a --with-testql --testql-dir ./testql-scenarios

TestQL Integration

Prefact can run TestQL DSL validation scenarios and bridge failing checks directly into planfile tickets, TODO.md, and configured backends (GitHub, GitLab, Jira).

prefact testql — Run a Single Scenario

# Validate a scenario and create/sync tickets
prefact testql testql-scenarios/smoke.testql.toon.yaml
# Dry-run: validate without creating tickets
prefact testql testql-scenarios/smoke.testql.toon.yaml --dry-run
# Custom project root and strategy
prefact testql scenarios/api.testql.toon.yaml -p ./my-api -s my-api/planfile.yaml
# Limit ticket generation and disable sync
prefact testql scenarios/api.testql.toon.yaml --max-tickets 10 --no-sync

Options

OptionDefaultDescription
-p, --path.Project root directory
--urlhttp://localhost:8101TestQL service base URL
--dry-runFalseParse/validate only
-s, --strategy<project>/planfile.yamlTarget planfile YAML
--create-tickets / --no-create-ticketsTrueCreate tickets for failures
--sync / --no-syncTrueSync to TODO.md and integrations
--max-tickets25Max tickets per run
--testql-bintestqlTestQL CLI executable
--testql-repo-path/home/tom/github/oqlos/testqlFallback local repo path

Identity-Aware Deduplication

When creating tickets, prefact uses identity-aware deduplication based on:

  • Ticket id / ticket_id
  • Integration-specific IDs (github_id, gitlab_id, jira_id)
  • Keys (github_key, gitlab_key, jira_key)
  • URLs (github_url, gitlab_url, jira_url, external_url)
  • source and external_refs metadata

If a ticket already exists with any matching identity key, it is skipped to avoid duplicates.

Performance Improvements

Recent updates have significantly improved performance:

  • Parallel Processing: Scans files using multiple workers (configurable)
  • Smart Filtering: Skips large files (>100KB) and files with minimal content
  • Optimized Exclusions: Automatically excludes test directories and examples
  • Deduplication: Prevents duplicate tickets and TODO entries across runs

Python API

frompathlibimportPathfromprefact.configimportConfigfromprefact.engineimportRefactoringEngineconfig=Config(
project_root=Path("./my_project"),
package_name="planfile",
dry_run=False,
backup=True,
)
engine=RefactoringEngine(config)
result=engine.run()
print(f"Found {result.total_issues} issues")
print(f"Fixed {result.total_fixed}")
print(f"All valid: {result.all_valid}")

Writing Custom Rules

Extend BaseRule and use the @register decorator:

fromprefact.rulesimportBaseRule, registerfromprefact.modelsimportIssue, Fix, ValidationResult@registerclassMyCustomRule(BaseRule):
rule_id="my-custom-rule"description="Does something useful."defscan_file(self, path, source):
# Return list[Issue]
...
deffix(self, path, source, issues):
# Return (fixed_source, list[Fix])
...
defvalidate(self, path, original, fixed):
# Return ValidationResult
...

CI/CD Integration

# GitHub Actions
- name: prefact checkrun: | pip install ./prefact prefact scan --path . --format json -o prefact-report.json prefact fix --path . --dry-run

Running Tests

pip install -e ".[dev]"
pytest -v

License

Licensed under Apache-2.0.

Author

Tom Sapletta

Status

Last updated by taskill at 2026-04-25 13:43 UTC

MetricValue
HEAD0aac827
Coverage
Failing tests
Commits in last cycle50

Primarily documentation and refactoring work: the docs and README were updated, the code-analysis engine and configuration/CLI were refactored and improved, and Markdown output and example modules were added. Minor fixes include suppressing mypy errors with type: ignore and auto-fixing ruff formatting and imports.

About

Python code quality tool with LLM-aware rules, plugin system, and enterprise features

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages