Metadata-Version: 2.4
Name: emergentlinters
Version: 0.1.0
Summary: Hybrid lint runtime that wraps Ruff and a few source checks behind one result format.
Project-URL: Homepage, https://github.com/emergentbase/emergentlinters
Project-URL: Issues, https://github.com/emergentbase/emergentlinters/issues
Project-URL: Changelog, https://github.com/emergentbase/emergentlinters/blob/main/CHANGELOG.md
Author: Emergent Team
License: Apache-2.0
License-File: LICENSE
Keywords: emergent,lint,linter,ruff,static-analysis
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
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: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Requires-Dist: ruff>=0.8
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: pytest<10,>=8.0; extra == 'dev'
Requires-Dist: ruff<1,>=0.8; extra == 'dev'
Description-Content-Type: text/markdown

# emergentlinters

A hybrid lint runtime. It runs [Ruff](https://github.com/astral-sh/ruff) for Python and returns
every finding in one result object, so callers don't parse a different output format per tool.
JavaScript/TypeScript linting runs through the Node toolchain (ESLint plus the bundled rules in
`rules/`); the Python entry points expose the same result object.

## Install

```bash
pip install emergentlinters
```

## Quick start

```python
from emergentlinters import run_python_linter

result = run_python_linter(["src/"])

print(result.success)          # True when there are no blocking findings
print(result.blocking_count)   # number of blocking findings
print(result.advisory_count)   # number of advisory findings
print(result.raw_output)       # human-readable, tiered summary (see below)
```

For JavaScript/TypeScript:

```python
import asyncio
from emergentlinters import run_javascript_linter

result = asyncio.run(run_javascript_linter(["app/"]))
print(result.to_payload())
```

## The result object

Every entry point returns a `DeterministicLintResult`:

| Field | Type | Meaning |
|---|---|---|
| `success` | `bool` | `True` when `blocking_count == 0` (and the engine ran). |
| `files_checked` | `list[str]` | Files that were actually examined. |
| `errors` | `list[str]` | Blocking findings, one per line. |
| `warnings` | `list[str]` | Advisory findings, one per line. |
| `raw_output` | `str` | Tiered, human-readable summary. |
| `engine_success` | `bool` | `False` only when the underlying tool crashed. |
| `blocking_count` | `int` | Count of blocking findings. |
| `advisory_count` | `int` | Count of advisory findings. |

Call `result.to_payload()` to get a plain `dict` for serialization.

## Output format

`raw_output` is a directive line plus two optional fenced sections:

```
<directive level="blocking" blocking="2" advisory="1">...</directive>

**BLOCKING (2)**

```
[ruff] app.py:3:1: F401 'os' imported but unused
[checks] app.py:9:5: EL001 returned value may need review before use
```

**ADVISORY (1)**

```
[ruff] app.py:12:80: E501 line too long
```
```

Findings are prefixed by their source (`[ruff]`, `[eslint]`, `[oxlint]`, `[checks]`), and the
same finding across many files is collapsed into one entry with the locations listed beneath it.

## Source checks

Alongside Ruff, two line-based checks run on Python files and surface under the `[checks]`
source:

- `EL001` — flags `return <name>` statements.
- `EL002` — flags modules that declare several decorated handlers.

`run_javascript_internal` adds a relative-import check under the same `[checks]` source. These
are coarse by design — enable the ones that fit your codebase.

## JavaScript dependencies

The JS path expects ESLint to be available. Install the bundled dev dependencies with:

```bash
emergentlinters-install-js
```

## License

Apache-2.0. See [LICENSE](LICENSE).
