Metadata-Version: 2.4
Name: aicode-verify
Version: 0.2.0
Summary: Semantic checker for AI-generated Python code.
Author: Shrajesh
License: MIT
License-File: LICENSE
Keywords: ai,lint,security,semantic-checker,static-analysis
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
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: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.9
Requires-Dist: tomli>=2.0; python_version < '3.11'
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: hatchling>=1.21; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: twine>=5.0; extra == 'dev'
Description-Content-Type: text/markdown

# aicode-verify

![PyPI](https://img.shields.io/pypi/v/aicode-verify)
![Python](https://img.shields.io/pypi/pyversions/aicode-verify)
![License](https://img.shields.io/pypi/l/aicode-verify)
![Tests](https://github.com/Github-Rajesh/AiCode-Verify/actions/workflows/ci.yml/badge.svg)

Catch AI-generated Python that looks right but breaks at runtime.

`aicode-verify` checks Python code without executing it. It catches hallucinated imports, wrong keyword arguments, missing required arguments, and common unsafe patterns such as `eval`, `shell=True`, hardcoded secrets, unsafe pickle usage, weak hashes, and SQL f-strings.

It is not a formatter. It is not a style linter.

It is a semantic safety net for code written by LLMs, coding agents, and hurried humans.

## Why This Exists

AI-generated Python often fails in ways that style linters cannot see:

- imports that sound real but do not exist
- keyword arguments copied from old docs or imagined APIs
- helper functions called with missing arguments
- unsafe shell, SQL, pickle, or secret-handling snippets

`aicode-verify` focuses on that layer.

## Install

```bash
pip install aicode-verify
```

For local development:

```bash
pip install -e ".[dev]"
```

## Quickstart

```bash
aicode-verify .
aicode-verify src tests --fail-on high
aicode-verify script.py --format json
cat generated.py | aicode-verify --stdin
```

`--fail-on` accepts `error`, `high`, or `medium`.

## Examples

Wrong keyword argument:

```python
import math

math.sqrt(value=4)
```

Output:

```text
AV101 ERROR line 3: math.sqrt() does not accept keyword argument 'value'
Suggestion: This callable does not accept keyword arguments
```

Hallucinated import:

```python
from math import sqrtt
```

Output:

```text
AV002 ERROR line 1: 'sqrtt' does not exist in 'math'
Suggestion: Did you mean 'sqrt'?
```

Alias-aware unsafe subprocess usage:

```python
import subprocess as sp

sp.run(user_input, shell=True)
```

Output:

```text
AV202 HIGH line 3: subprocess with shell=True enables shell injection
Suggestion: Pass a list of arguments instead: subprocess.run(['cmd', 'arg'])
```

SQL f-string:

```python
query = f"SELECT * FROM users WHERE id = {user_id}"
```

Output:

```text
AV204 HIGH line 1: SQL query built with f-string; possible injection surface
Suggestion: Use parameterized queries
```

## Why Not Ruff, Mypy, Pyright, Bandit, or Pytest?

Use them. `aicode-verify` is designed to sit beside them.

Ruff keeps code clean. mypy and pyright reason about types. Bandit checks security smells. pytest proves behavior.

`aicode-verify` focuses on mistakes that are especially common in AI-generated Python: hallucinated imports, wrong function arguments, missing required parameters, and unsafe snippets.

## Configuration

Add configuration to `pyproject.toml`:

```toml
[tool.aicode-verify]
fail-on = "high"
format = "text"
ignore = ["AV206"]
exclude = ["tests/fixtures/**", "migrations/**"]
```

CLI flags override config values:

```bash
aicode-verify . --config pyproject.toml
aicode-verify . --ignore AV203
aicode-verify --explain AV101
```

## Ignore Comments

Suppress one finding on the next line:

```python
# aicode-verify: ignore-next-line AV203
TEST_API_KEY = "fake-key-for-tests"
```

Suppress the next line for all rules:

```python
# aicode-verify: ignore
eval(expr)
```

Inline ignores also work:

```python
eval(expr)  # aicode-verify: ignore AV201
```

## Rule Reference

| Rule | Meaning |
| ---- | ------- |
| AV001 | Imported module cannot be resolved |
| AV002 | Imported symbol does not exist |
| AV101 | Function call uses an unsupported keyword |
| AV102 | Function call is missing a required argument |
| AV201 | Unsafe `eval`, `exec`, or `compile` usage |
| AV202 | Shell command execution risk |
| AV203 | Possible hardcoded secret |
| AV204 | SQL built with an f-string |
| AV205 | Unsafe pickle deserialization |
| AV206 | Weak hash usage |

## Python API

```python
from aicode_verify import format_report, verify

source = "import math\nmath.sqrt(value=4)\n"
findings = verify(source, ignore=["AV203"])
print(format_report(findings, source))
```

## Pre-commit

Add this to `.pre-commit-config.yaml`:

```yaml
repos:
  - repo: https://github.com/Github-Rajesh/AiCode-Verify
    rev: v0.2.0
    hooks:
      - id: aicode-verify
        args: ["--fail-on", "high"]
```

## GitHub Actions

```yaml
name: aicode-verify

on:
  pull_request:
  push:

jobs:
  verify-ai-code:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install aicode-verify
      - run: aicode-verify . --fail-on high
```

## Limitations

`aicode-verify` does not perform full type inference. Chained calls like `df.groupby("x").agg(...)` are only checked where the root object can be resolved statically. That keeps the tool fast and practical while leaving room for future stub-based inference.
