agentlinter 0.3.2__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentlinter-0.3.3/.github/workflows/changelog.yml +32 -0
- agentlinter-0.3.3/.github/workflows/docker.yml +60 -0
- agentlinter-0.3.3/.github/workflows/pricing-update.yml +29 -0
- agentlinter-0.3.3/.github/workflows/release.yml +39 -0
- {agentlinter-0.3.2/src/agentlinter.egg-info → agentlinter-0.3.3}/PKG-INFO +32 -3
- {agentlinter-0.3.2 → agentlinter-0.3.3}/README.md +30 -1
- {agentlinter-0.3.2 → agentlinter-0.3.3}/STATUS.md +9 -4
- agentlinter-0.3.3/docs/api/formatters.md +34 -0
- agentlinter-0.3.3/docs/api/models.md +55 -0
- agentlinter-0.3.3/docs/api/parsers.md +34 -0
- agentlinter-0.3.3/docs/api/rules.md +34 -0
- agentlinter-0.3.3/docs/config.md +44 -0
- agentlinter-0.3.3/docs/contributing.md +54 -0
- agentlinter-0.3.3/docs/install.md +35 -0
- agentlinter-0.3.3/docs/quickstart.md +39 -0
- agentlinter-0.3.3/docs/rules/budget.md +28 -0
- agentlinter-0.3.3/docs/rules/efficiency.md +28 -0
- agentlinter-0.3.3/docs/rules/resilience.md +35 -0
- agentlinter-0.3.3/docs/rules/security.md +28 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/pyproject.toml +5 -2
- agentlinter-0.3.3/scripts/fetch-pricing.py +121 -0
- agentlinter-0.3.3/scripts/generate-changelog.py +139 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/__init__.py +1 -1
- agentlinter-0.3.3/src/agent_lint/cli/__init__.py +42 -0
- agentlinter-0.3.3/src/agent_lint/cli/compare.py +45 -0
- agentlinter-0.3.3/src/agent_lint/cli/estimate.py +46 -0
- agentlinter-0.3.3/src/agent_lint/cli/lint.py +99 -0
- agentlinter-0.3.3/src/agent_lint/cli/stats.py +83 -0
- agentlinter-0.3.3/src/agent_lint/cli/status.py +29 -0
- agentlinter-0.3.3/src/agent_lint/cli.py +10 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/data/providers.yaml +9 -1
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/estimator.py +8 -7
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/models.py +10 -2
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/parsers/__init__.py +30 -18
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/parsers/crewai.py +2 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/parsers/generic.py +2 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/parsers/gorgon.py +2 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/parsers/langchain.py +2 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3/src/agentlinter.egg-info}/PKG-INFO +32 -3
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agentlinter.egg-info/SOURCES.txt +8 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_coverage_pro.py +5 -5
- agentlinter-0.3.2/.github/workflows/changelog.yml +0 -33
- agentlinter-0.3.2/.github/workflows/pricing-update.yml +0 -47
- agentlinter-0.3.2/.github/workflows/release.yml +0 -41
- agentlinter-0.3.2/docs/api/formatters.md +0 -0
- agentlinter-0.3.2/docs/api/models.md +0 -0
- agentlinter-0.3.2/docs/api/parsers.md +0 -0
- agentlinter-0.3.2/docs/api/rules.md +0 -0
- agentlinter-0.3.2/docs/config.md +0 -0
- agentlinter-0.3.2/docs/contributing.md +0 -0
- agentlinter-0.3.2/docs/install.md +0 -0
- agentlinter-0.3.2/docs/quickstart.md +0 -0
- agentlinter-0.3.2/docs/rules/budget.md +0 -0
- agentlinter-0.3.2/docs/rules/efficiency.md +0 -0
- agentlinter-0.3.2/docs/rules/resilience.md +0 -0
- agentlinter-0.3.2/docs/rules/security.md +0 -0
- agentlinter-0.3.2/scripts/fetch-pricing.py +0 -91
- agentlinter-0.3.2/src/agent_lint/cli.py +0 -328
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.agent-lint.toml.example +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.github/actions/agent-lint/action.yml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.github/dependabot.yml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.github/pull_request_template.md +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.github/workflows/ci.yml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.github/workflows/codeql.yml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.github/workflows/docs.yml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.github/workflows/publish.yml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.github/workflows/secret-scan.yml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.github/workflows/security.yml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.gitignore +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.gitleaks.toml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.pre-commit-config.yaml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/.pre-commit-hooks.yaml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/CHANGELOG.md +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/CLAUDE.md +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/CONTRIBUTING.md +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/Dockerfile +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/LICENSE +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/PRICING.md +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/SECURITY.md +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/docker-bake.hcl +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/docs/changelog.md +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/docs/ci.md +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/docs/index.md +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/mkdocs.yml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/scripts/benchmark-accuracy.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/scripts/benchmark-performance.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/scripts/fetch-corpus.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/scripts/stripe_setup_agent_lint.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/scripts/test-sarif-upload.sh +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/setup.cfg +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/__main__.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/autofix.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/comparator.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/config.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/config_file.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/exceptions.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/formatters.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/gates.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/github_formatter.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/licensing.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/linter.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/pricing.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/rules/__init__.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/rules/budget.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/rules/efficiency.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/rules/resilience.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/rules/security.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/sarif_formatter.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agent_lint/telemetry.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agentlinter.egg-info/dependency_links.txt +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agentlinter.egg-info/entry_points.txt +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agentlinter.egg-info/requires.txt +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/src/agentlinter.egg-info/top_level.txt +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/__init__.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/conftest.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/fixtures/benchmarks/minimal-budget.json +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/fixtures/benchmarks/minimal-budget.yaml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/fixtures/benchmarks/resilience-retry.json +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/fixtures/benchmarks/resilience-retry.yaml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/fixtures/workflows/sample-agent-workflow.yaml +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_autofix.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_cli.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_comparator.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_config_file.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_coverage_push_90.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_estimator.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_formatters.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_gates.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_github_formatter.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_licensing.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_licensing_server.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_linter.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_models.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_parsers.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_pricing.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_rules.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_sarif_formatter.py +0 -0
- {agentlinter-0.3.2 → agentlinter-0.3.3}/tests/test_telemetry.py +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Generate Changelog
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
changelog:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
|
|
23
|
+
- name: Generate changelog
|
|
24
|
+
run: python scripts/generate-changelog.py
|
|
25
|
+
env:
|
|
26
|
+
OUTPUT: CHANGELOG.md
|
|
27
|
+
|
|
28
|
+
- name: Upload changelog artifact
|
|
29
|
+
uses: actions/upload-artifact@v4
|
|
30
|
+
with:
|
|
31
|
+
name: changelog
|
|
32
|
+
path: CHANGELOG.md
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
name: Build and Push Docker Image
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
tags:
|
|
8
|
+
- "v*"
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
packages: write
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
docker:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Set up QEMU
|
|
22
|
+
uses: docker/setup-qemu-action@v3
|
|
23
|
+
|
|
24
|
+
- name: Set up Docker Buildx
|
|
25
|
+
uses: docker/setup-buildx-action@v3
|
|
26
|
+
|
|
27
|
+
- name: Log in to GHCR
|
|
28
|
+
uses: docker/login-action@v3
|
|
29
|
+
with:
|
|
30
|
+
registry: ghcr.io
|
|
31
|
+
username: ${{ github.actor }}
|
|
32
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
33
|
+
|
|
34
|
+
- name: Extract metadata
|
|
35
|
+
id: meta
|
|
36
|
+
uses: docker/metadata-action@v5
|
|
37
|
+
with:
|
|
38
|
+
images: ghcr.io/${{ github.repository_owner }}/agent-lint
|
|
39
|
+
tags: |
|
|
40
|
+
type=semver,pattern={{version}}
|
|
41
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
42
|
+
type=ref,event=branch
|
|
43
|
+
type=sha
|
|
44
|
+
|
|
45
|
+
- name: Build and push
|
|
46
|
+
uses: docker/build-push-action@v6
|
|
47
|
+
with:
|
|
48
|
+
context: .
|
|
49
|
+
platforms: linux/amd64,linux/arm64
|
|
50
|
+
push: true
|
|
51
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
52
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
53
|
+
cache-from: type=gha
|
|
54
|
+
cache-to: type=gha,mode=max
|
|
55
|
+
|
|
56
|
+
- name: Smoke test Docker image
|
|
57
|
+
run: |
|
|
58
|
+
short_sha="${GITHUB_SHA::7}"
|
|
59
|
+
tag="ghcr.io/${{ github.repository_owner }}/agent-lint:sha-${short_sha}"
|
|
60
|
+
docker run --rm "$tag" --version
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Pricing Data Update
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
# Weekly on Sundays at 05:00 UTC
|
|
6
|
+
- cron: "0 5 * * 0"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
pull-requests: write
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
update-pricing:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.12"
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: pip install pyyaml
|
|
26
|
+
|
|
27
|
+
- name: Validate pricing YAML
|
|
28
|
+
id: validate
|
|
29
|
+
run: python scripts/fetch-pricing.py
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_run:
|
|
5
|
+
workflows: ["Publish to PyPI"]
|
|
6
|
+
types: [completed]
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
release:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
if: github.event.workflow_run.conclusion == 'success'
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
ref: ${{ github.event.workflow_run.head_sha }}
|
|
19
|
+
fetch-depth: 0
|
|
20
|
+
|
|
21
|
+
- name: Download artifacts from publish workflow
|
|
22
|
+
uses: actions/download-artifact@v4
|
|
23
|
+
with:
|
|
24
|
+
name: dist
|
|
25
|
+
path: dist/
|
|
26
|
+
run-id: ${{ github.event.workflow_run.id }}
|
|
27
|
+
|
|
28
|
+
- name: Extract tag name
|
|
29
|
+
id: tag
|
|
30
|
+
run: |
|
|
31
|
+
tag=$(git describe --tags --exact-match 2>/dev/null || echo "")
|
|
32
|
+
echo "tag=$tag" >> "$GITHUB_OUTPUT"
|
|
33
|
+
|
|
34
|
+
- name: Create GitHub Release
|
|
35
|
+
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
|
|
36
|
+
with:
|
|
37
|
+
tag_name: ${{ steps.tag.outputs.tag }}
|
|
38
|
+
generate_release_notes: true
|
|
39
|
+
files: dist/*
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentlinter
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Estimate costs and lint agent workflow YAML files
|
|
5
5
|
Author: AreteDriver
|
|
6
|
-
License:
|
|
6
|
+
License: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/AreteDriver/agent-lint
|
|
8
8
|
Project-URL: Repository, https://github.com/AreteDriver/agent-lint
|
|
9
9
|
Project-URL: Issues, https://github.com/AreteDriver/agent-lint/issues
|
|
@@ -78,6 +78,9 @@ agent-lint estimate workflow.yaml --provider anthropic
|
|
|
78
78
|
|
|
79
79
|
# Generate a full audit report
|
|
80
80
|
agent-lint lint workflows/ --format markdown
|
|
81
|
+
|
|
82
|
+
# Suggest autofixes as a diff patch
|
|
83
|
+
agent-lint lint workflow.yaml --fix
|
|
81
84
|
```
|
|
82
85
|
|
|
83
86
|
---
|
|
@@ -116,6 +119,29 @@ Treat your agent configs like production code. Gate them the same way.
|
|
|
116
119
|
|
|
117
120
|
---
|
|
118
121
|
|
|
122
|
+
## Licensing & Tiers
|
|
123
|
+
|
|
124
|
+
`agent-lint` is available in two tiers:
|
|
125
|
+
|
|
126
|
+
**Free** — Always free, no license key required:
|
|
127
|
+
- `lint` — anti-pattern detection
|
|
128
|
+
- `estimate` — token/cost estimation
|
|
129
|
+
- `status` — show version and tier info
|
|
130
|
+
|
|
131
|
+
**Pro** — Unlock additional features with a license key:
|
|
132
|
+
- `compare` — compare costs across providers side-by-side
|
|
133
|
+
- Markdown export for audit reports
|
|
134
|
+
- Custom pricing tables
|
|
135
|
+
- Custom rule packs
|
|
136
|
+
- Historical tracking and trend analysis
|
|
137
|
+
|
|
138
|
+
Activate Pro with an environment variable:
|
|
139
|
+
```bash
|
|
140
|
+
export AGENT_LINT_LICENSE=ALNT-XXXX-XXXX-XXXX
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
119
145
|
## Why Static Analysis
|
|
120
146
|
|
|
121
147
|
No LLM dependency. No API calls. No variance between runs.
|
|
@@ -129,9 +155,12 @@ Agent configs are deterministic artifacts — they should be audited determinist
|
|
|
129
155
|
- [x] Cost estimation (Claude, GPT-4)
|
|
130
156
|
- [x] CI integration with threshold gating
|
|
131
157
|
- [x] Markdown audit reports
|
|
158
|
+
- [x] SARIF output for GitHub Advanced Security
|
|
159
|
+
- [x] GitHub PR annotation format
|
|
160
|
+
- [x] Autofix diff generation (`--fix`)
|
|
161
|
+
- [x] Docker images (multi-arch)
|
|
132
162
|
- [ ] Gemini pricing model
|
|
133
163
|
- [ ] VS Code extension
|
|
134
|
-
- [ ] Auto-fix suggestions
|
|
135
164
|
|
|
136
165
|
---
|
|
137
166
|
|
|
@@ -40,6 +40,9 @@ agent-lint estimate workflow.yaml --provider anthropic
|
|
|
40
40
|
|
|
41
41
|
# Generate a full audit report
|
|
42
42
|
agent-lint lint workflows/ --format markdown
|
|
43
|
+
|
|
44
|
+
# Suggest autofixes as a diff patch
|
|
45
|
+
agent-lint lint workflow.yaml --fix
|
|
43
46
|
```
|
|
44
47
|
|
|
45
48
|
---
|
|
@@ -78,6 +81,29 @@ Treat your agent configs like production code. Gate them the same way.
|
|
|
78
81
|
|
|
79
82
|
---
|
|
80
83
|
|
|
84
|
+
## Licensing & Tiers
|
|
85
|
+
|
|
86
|
+
`agent-lint` is available in two tiers:
|
|
87
|
+
|
|
88
|
+
**Free** — Always free, no license key required:
|
|
89
|
+
- `lint` — anti-pattern detection
|
|
90
|
+
- `estimate` — token/cost estimation
|
|
91
|
+
- `status` — show version and tier info
|
|
92
|
+
|
|
93
|
+
**Pro** — Unlock additional features with a license key:
|
|
94
|
+
- `compare` — compare costs across providers side-by-side
|
|
95
|
+
- Markdown export for audit reports
|
|
96
|
+
- Custom pricing tables
|
|
97
|
+
- Custom rule packs
|
|
98
|
+
- Historical tracking and trend analysis
|
|
99
|
+
|
|
100
|
+
Activate Pro with an environment variable:
|
|
101
|
+
```bash
|
|
102
|
+
export AGENT_LINT_LICENSE=ALNT-XXXX-XXXX-XXXX
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
81
107
|
## Why Static Analysis
|
|
82
108
|
|
|
83
109
|
No LLM dependency. No API calls. No variance between runs.
|
|
@@ -91,9 +117,12 @@ Agent configs are deterministic artifacts — they should be audited determinist
|
|
|
91
117
|
- [x] Cost estimation (Claude, GPT-4)
|
|
92
118
|
- [x] CI integration with threshold gating
|
|
93
119
|
- [x] Markdown audit reports
|
|
120
|
+
- [x] SARIF output for GitHub Advanced Security
|
|
121
|
+
- [x] GitHub PR annotation format
|
|
122
|
+
- [x] Autofix diff generation (`--fix`)
|
|
123
|
+
- [x] Docker images (multi-arch)
|
|
94
124
|
- [ ] Gemini pricing model
|
|
95
125
|
- [ ] VS Code extension
|
|
96
|
-
- [ ] Auto-fix suggestions
|
|
97
126
|
|
|
98
127
|
---
|
|
99
128
|
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
| Attribute | Value |
|
|
4
4
|
|-----------|-------|
|
|
5
5
|
| Status | **OPERATIONAL** |
|
|
6
|
-
| Last verified | 2026-07-
|
|
6
|
+
| Last verified | 2026-07-19 |
|
|
7
7
|
| Installable? | Yes — `pip install agentlinter` |
|
|
8
8
|
| Tested? | CI green; see badge below |
|
|
9
|
-
| Documented? | README +
|
|
9
|
+
| Documented? | README + MkDocs site + inline help |
|
|
10
|
+
| Hosted docs | [aretedriver.github.io/agent-lint](https://aretedriver.github.io/agent-lint/) |
|
|
11
|
+
| Docker image | `ghcr.io/aretedriver/agent-lint:latest` |
|
|
10
12
|
| CI | [](https://github.com/AreteDriver/agent-lint/actions/workflows/ci.yml) |
|
|
11
13
|
|
|
12
14
|
## What Works
|
|
@@ -15,13 +17,16 @@
|
|
|
15
17
|
- **Linting:** Detects unbounded loops, missing cost guards, parallel branches without coordination, fragile retry patterns
|
|
16
18
|
- **Cost Estimation:** Token/cost exposure estimates per workflow, per provider
|
|
17
19
|
- **CI Integration:** `--fail-under` flag for gated deployments
|
|
18
|
-
- **Output Formats:** Terminal tables, JSON, Markdown audit reports
|
|
20
|
+
- **Output Formats:** Terminal tables, JSON, Markdown audit reports, SARIF, GitHub PR annotations
|
|
21
|
+
- **Autofix:** `--fix` generates diff patches for fixable findings
|
|
22
|
+
- **Hosted Docs:** MkDocs site deployed via GitHub Actions
|
|
23
|
+
- **Docker:** Multi-arch images (`linux/amd64`, `linux/arm64`) on GHCR
|
|
19
24
|
|
|
20
25
|
## What Doesn't Work Yet
|
|
21
26
|
|
|
22
27
|
- Dashboard for historical lint trends (not planned)
|
|
23
28
|
- Integration with Animus Forge as a native quality gate (roadmap)
|
|
24
|
-
-
|
|
29
|
+
- VS Code extension
|
|
25
30
|
|
|
26
31
|
## Install
|
|
27
32
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# API Reference — Formatters
|
|
2
|
+
|
|
3
|
+
## `format_lint_table(report: LintReport, console: Console) -> None`
|
|
4
|
+
|
|
5
|
+
Render a rich text table to the console.
|
|
6
|
+
|
|
7
|
+
## `format_lint_json(report: LintReport, console: Console) -> None`
|
|
8
|
+
|
|
9
|
+
Render JSON output to the console.
|
|
10
|
+
|
|
11
|
+
## `format_lint_markdown(report: LintReport, console: Console) -> None`
|
|
12
|
+
|
|
13
|
+
Render a Markdown summary to the console.
|
|
14
|
+
|
|
15
|
+
## `format_sarif(report: LintReport) -> str`
|
|
16
|
+
|
|
17
|
+
Generate SARIF v2.1.0 JSON string for GitHub Advanced Security upload.
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from agent_lint.sarif_formatter import format_sarif
|
|
21
|
+
|
|
22
|
+
sarif_json = format_sarif(report)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## `format_github_annotations(report: LintReport) -> str`
|
|
26
|
+
|
|
27
|
+
Generate GitHub Actions workflow command annotations.
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from agent_lint.github_formatter import format_github_annotations
|
|
31
|
+
|
|
32
|
+
annotations = format_github_annotations(report)
|
|
33
|
+
print(annotations)
|
|
34
|
+
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# API Reference — Models
|
|
2
|
+
|
|
3
|
+
## `ParsedWorkflow`
|
|
4
|
+
|
|
5
|
+
Represents a parsed agent workflow YAML.
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
class ParsedWorkflow(BaseModel):
|
|
9
|
+
name: str
|
|
10
|
+
version: str
|
|
11
|
+
token_budget: int | None
|
|
12
|
+
steps: list[ParsedStep]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## `ParsedStep`
|
|
16
|
+
|
|
17
|
+
Represents a single step in a workflow.
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
class ParsedStep(BaseModel):
|
|
21
|
+
id: str
|
|
22
|
+
step_type: StepType
|
|
23
|
+
model: str | None
|
|
24
|
+
estimated_tokens: int | None
|
|
25
|
+
on_failure: str | None
|
|
26
|
+
raw_params: dict[str, Any]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## `LintFinding`
|
|
30
|
+
|
|
31
|
+
Represents a single rule violation.
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
class LintFinding(BaseModel):
|
|
35
|
+
rule_id: str
|
|
36
|
+
category: RuleCategory
|
|
37
|
+
severity: Severity
|
|
38
|
+
message: str
|
|
39
|
+
step_id: str | None
|
|
40
|
+
suggestion: str | None
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## `LintReport`
|
|
44
|
+
|
|
45
|
+
Aggregated result of running all rules.
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
class LintReport(BaseModel):
|
|
49
|
+
workflow_name: str
|
|
50
|
+
score: int
|
|
51
|
+
findings: list[LintFinding]
|
|
52
|
+
error_count: int
|
|
53
|
+
warning_count: int
|
|
54
|
+
info_count: int
|
|
55
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# API Reference — Parsers
|
|
2
|
+
|
|
3
|
+
## `parse_workflow(path: Path) -> ParsedWorkflow`
|
|
4
|
+
|
|
5
|
+
Parse a workflow YAML file into a `ParsedWorkflow` object.
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
from agent_lint.parsers import parse_workflow
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
wf = parse_workflow(Path("workflow.yaml"))
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## `load_yaml(path: Path) -> dict[str, Any]`
|
|
15
|
+
|
|
16
|
+
Load a YAML file as a raw Python dict. Useful for autofix operations that mutate the raw structure.
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
from agent_lint.parsers import load_yaml
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
raw = load_yaml(Path("workflow.yaml"))
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Supported Workflow Formats
|
|
26
|
+
|
|
27
|
+
| Parser | File Patterns |
|
|
28
|
+
|--------|--------------|
|
|
29
|
+
| Generic YAML | Any `.yaml` / `.yml` |
|
|
30
|
+
| LangChain | `langchain_*.yaml` |
|
|
31
|
+
| CrewAI | `crewai_*.yaml` |
|
|
32
|
+
| Gorgon | `gorgon_*.yaml` |
|
|
33
|
+
|
|
34
|
+
The parser auto-detects format based on file content and naming.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# API Reference — Rules
|
|
2
|
+
|
|
3
|
+
## `@lint_rule(rule_id, category, severity, description)`
|
|
4
|
+
|
|
5
|
+
Decorator to register a lint rule function.
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
from agent_lint.models import LintFinding, ParsedWorkflow, RuleCategory, Severity
|
|
9
|
+
from agent_lint.rules import lint_rule
|
|
10
|
+
|
|
11
|
+
@lint_rule(
|
|
12
|
+
rule_id="X001",
|
|
13
|
+
category=RuleCategory.BUDGET,
|
|
14
|
+
severity=Severity.WARNING,
|
|
15
|
+
description="My custom rule",
|
|
16
|
+
)
|
|
17
|
+
def check_custom(workflow: ParsedWorkflow) -> list[LintFinding]:
|
|
18
|
+
findings: list[LintFinding] = []
|
|
19
|
+
# ... check logic ...
|
|
20
|
+
return findings
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Rule Function Signature
|
|
24
|
+
|
|
25
|
+
All rule functions must accept a `ParsedWorkflow` and return `list[LintFinding]`.
|
|
26
|
+
|
|
27
|
+
## Built-in Rule Modules
|
|
28
|
+
|
|
29
|
+
| Module | Rule IDs | Focus |
|
|
30
|
+
|--------|----------|-------|
|
|
31
|
+
| `rules.budget` | B001–B004 | Cost guards |
|
|
32
|
+
| `rules.resilience` | R001–R005 | Error handling |
|
|
33
|
+
| `rules.efficiency` | E001–E004 | Performance |
|
|
34
|
+
| `rules.security` | S001–S004 | Security |
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
## Config File Discovery
|
|
4
|
+
|
|
5
|
+
`agent-lint` loads config from the first source found, in order:
|
|
6
|
+
|
|
7
|
+
1. CLI flags (highest priority)
|
|
8
|
+
2. Environment variables (`AGENT_LINT_*`)
|
|
9
|
+
3. `.agent-lint.toml` in the current directory
|
|
10
|
+
4. `pyproject.toml` under `[tool.agent-lint]`
|
|
11
|
+
5. Built-in defaults
|
|
12
|
+
|
|
13
|
+
## Example `.agent-lint.toml`
|
|
14
|
+
|
|
15
|
+
```toml
|
|
16
|
+
fail_under = 80
|
|
17
|
+
category = "budget"
|
|
18
|
+
severity = "warning"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Example `pyproject.toml` Section
|
|
22
|
+
|
|
23
|
+
```toml
|
|
24
|
+
[tool.agent-lint]
|
|
25
|
+
fail_under = 80
|
|
26
|
+
category = "budget"
|
|
27
|
+
severity = "warning"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Environment Variables
|
|
31
|
+
|
|
32
|
+
| Variable | Maps To |
|
|
33
|
+
|----------|---------|
|
|
34
|
+
| `AGENT_LINT_FAIL_UNDER` | `fail_under` |
|
|
35
|
+
| `AGENT_LINT_CATEGORY` | `category` |
|
|
36
|
+
| `AGENT_LINT_SEVERITY` | `severity` |
|
|
37
|
+
|
|
38
|
+
## Full Option Reference
|
|
39
|
+
|
|
40
|
+
| Option | Type | Default | Description |
|
|
41
|
+
|--------|------|---------|-------------|
|
|
42
|
+
| `fail_under` | int | `None` | Minimum lint score to pass CI |
|
|
43
|
+
| `category` | string | `None` | Filter to one rule category |
|
|
44
|
+
| `severity` | string | `None` | Filter to one severity level |
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in `agent-lint`! This is a small but opinionated project. To keep quality high, please follow the guidelines below.
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/AreteDriver/agent-lint.git
|
|
9
|
+
cd agent-lint
|
|
10
|
+
pip install -e ".[dev]"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Running Tests
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pytest tests/ -v
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Coverage gate is 90%. PRs that drop coverage below this will fail CI.
|
|
20
|
+
|
|
21
|
+
## Linting and Formatting
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
ruff check src/ tests/
|
|
25
|
+
ruff format src/ tests/
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Type Checking
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
mypy src/
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Adding a New Rule
|
|
35
|
+
|
|
36
|
+
1. Add the rule function in the appropriate `src/agent_lint/rules/*.py` file.
|
|
37
|
+
2. Decorate it with `@lint_rule(rule_id=..., category=..., severity=..., description=...)`.
|
|
38
|
+
3. Add tests in `tests/test_rules.py`.
|
|
39
|
+
4. Update the relevant docs page under `docs/rules/`.
|
|
40
|
+
|
|
41
|
+
## Commit Messages
|
|
42
|
+
|
|
43
|
+
Use [Conventional Commits](https://www.conventionalcommits.org/):
|
|
44
|
+
|
|
45
|
+
- `feat:` — new feature or rule
|
|
46
|
+
- `fix:` — bug fix
|
|
47
|
+
- `docs:` — documentation changes
|
|
48
|
+
- `test:` — test-only changes
|
|
49
|
+
- `ci:` — CI/CD changes
|
|
50
|
+
- `chore:` — maintenance
|
|
51
|
+
|
|
52
|
+
## License
|
|
53
|
+
|
|
54
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Installation
|
|
2
|
+
|
|
3
|
+
## PyPI (Recommended)
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install agentlinter
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Requires Python 3.11 or newer.
|
|
10
|
+
|
|
11
|
+
## Docker
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
docker pull ghcr.io/aretedriver/agent-lint:latest
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Run the container:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
docker run --rm -v "$(pwd):/work" ghcr.io/aretedriver/agent-lint lint /work/workflows/
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## From Source
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
git clone https://github.com/AreteDriver/agent-lint.git
|
|
27
|
+
cd agent-lint
|
|
28
|
+
pip install -e .
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Verify Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
agent-lint --version
|
|
35
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Quick Start
|
|
2
|
+
|
|
3
|
+
## Lint a Single Workflow
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
agent-lint lint workflow.yaml
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Output is a table by default. Use `--format json` or `--format markdown` for machine-readable output.
|
|
10
|
+
|
|
11
|
+
## Estimate Cost
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
agent-lint estimate workflow.yaml --provider anthropic
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Supported providers: `openai`, `anthropic`, `google`, `ollama`.
|
|
18
|
+
|
|
19
|
+
## Compare Two Workflows
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
agent-lint compare workflow-a.yaml workflow-b.yaml
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## CI Gate with Threshold
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
agent-lint lint workflows/ --fail-under 80
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Exits with code 1 if the lint score is below 80.
|
|
32
|
+
|
|
33
|
+
## Get Auto-fix Suggestions
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
agent-lint lint workflow.yaml --fix
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Prints a unified diff patch for fixable findings.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Budget Rules (B001-B004)
|
|
2
|
+
|
|
3
|
+
Budget rules detect cost risks in agent workflows.
|
|
4
|
+
|
|
5
|
+
## B001: Missing Workflow Token Budget
|
|
6
|
+
|
|
7
|
+
**Severity:** Warning
|
|
8
|
+
**Autofix:** ✅ Yes — adds `token_budget: 50000`
|
|
9
|
+
|
|
10
|
+
Flags workflows that have no top-level `token_budget` declared. Without a budget cap, a runaway loop or oversized prompt can generate unlimited API costs.
|
|
11
|
+
|
|
12
|
+
## B002: Step Exceeds 50% of Budget
|
|
13
|
+
|
|
14
|
+
**Severity:** Warning
|
|
15
|
+
|
|
16
|
+
Flags individual steps whose `estimated_tokens` exceeds 50% of the workflow's total `token_budget`. This indicates a single step is disproportionately expensive.
|
|
17
|
+
|
|
18
|
+
## B003: Missing Step Token Estimate
|
|
19
|
+
|
|
20
|
+
**Severity:** Info
|
|
21
|
+
|
|
22
|
+
Flags LLM steps that lack an `estimated_tokens` field. Cost estimation requires either a declared value or a fallback archetype.
|
|
23
|
+
|
|
24
|
+
## B004: Budget Archetype Fallback
|
|
25
|
+
|
|
26
|
+
**Severity:** Info
|
|
27
|
+
|
|
28
|
+
Informational finding when a step's token estimate falls back to a role-based or step-type archetype because no explicit value was provided.
|