aeo-audit 1.1.1__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.
Files changed (98) hide show
  1. aeo_audit-1.1.1/.github/workflows/ci.yml +101 -0
  2. aeo_audit-1.1.1/.gitignore +57 -0
  3. aeo_audit-1.1.1/CHANGELOG.md +52 -0
  4. aeo_audit-1.1.1/PKG-INFO +252 -0
  5. aeo_audit-1.1.1/README.md +185 -0
  6. aeo_audit-1.1.1/TODO.md +128 -0
  7. aeo_audit-1.1.1/aeo_audit/__init__.py +3 -0
  8. aeo_audit-1.1.1/aeo_audit/checks/__init__.py +1 -0
  9. aeo_audit-1.1.1/aeo_audit/checks/base.py +114 -0
  10. aeo_audit-1.1.1/aeo_audit/checks/capabilities.py +541 -0
  11. aeo_audit-1.1.1/aeo_audit/checks/commerce.py +405 -0
  12. aeo_audit-1.1.1/aeo_audit/checks/discovery.py +463 -0
  13. aeo_audit-1.1.1/aeo_audit/checks/identity.py +532 -0
  14. aeo_audit-1.1.1/aeo_audit/checks/trust.py +487 -0
  15. aeo_audit-1.1.1/aeo_audit/cli.py +857 -0
  16. aeo_audit-1.1.1/aeo_audit/config.yaml +111 -0
  17. aeo_audit-1.1.1/aeo_audit/core/__init__.py +1 -0
  18. aeo_audit-1.1.1/aeo_audit/core/crawler.py +336 -0
  19. aeo_audit-1.1.1/aeo_audit/core/models.py +191 -0
  20. aeo_audit-1.1.1/aeo_audit/core/registry.py +112 -0
  21. aeo_audit-1.1.1/aeo_audit/core/scoring.py +317 -0
  22. aeo_audit-1.1.1/aeo_audit/engine.py +204 -0
  23. aeo_audit-1.1.1/aeo_audit/reporters/__init__.py +8 -0
  24. aeo_audit-1.1.1/aeo_audit/reporters/html.py +60 -0
  25. aeo_audit-1.1.1/aeo_audit/reporters/json.py +59 -0
  26. aeo_audit-1.1.1/aeo_audit/reporters/pdf.py +44 -0
  27. aeo_audit-1.1.1/aeo_audit/reporters/terminal.py +188 -0
  28. aeo_audit-1.1.1/aeo_audit/templates/report.html.j2 +934 -0
  29. aeo_audit-1.1.1/aeo_audit/utils/__init__.py +1 -0
  30. aeo_audit-1.1.1/aeo_audit/utils/cache.py +77 -0
  31. aeo_audit-1.1.1/aeo_audit/utils/http.py +60 -0
  32. aeo_audit-1.1.1/aeo_audit/utils/validators.py +59 -0
  33. aeo_audit-1.1.1/aeo_audit.spec +82 -0
  34. aeo_audit-1.1.1/benchmarks/percentiles_v1.json +26 -0
  35. aeo_audit-1.1.1/claude.md +69 -0
  36. aeo_audit-1.1.1/docs/CI_RECIPES.md +86 -0
  37. aeo_audit-1.1.1/docs/CONFIG_REFERENCE.md +130 -0
  38. aeo_audit-1.1.1/docs/CUSTOM_CHECKS.md +84 -0
  39. aeo_audit-1.1.1/pyproject.toml +163 -0
  40. aeo_audit-1.1.1/scripts/gen_benchmark.py +59 -0
  41. aeo_audit-1.1.1/scripts/install.sh +48 -0
  42. aeo_audit-1.1.1/targets.txt +20 -0
  43. aeo_audit-1.1.1/tests/__init__.py +1 -0
  44. aeo_audit-1.1.1/tests/conftest.py +88 -0
  45. aeo_audit-1.1.1/tests/contract/__init__.py +1 -0
  46. aeo_audit-1.1.1/tests/contract/test_check_interface.py +37 -0
  47. aeo_audit-1.1.1/tests/fixtures/expected_scores.json +149 -0
  48. aeo_audit-1.1.1/tests/fixtures/mock_sites/broken_mcp/agent-delegation.json +20 -0
  49. aeo_audit-1.1.1/tests/fixtures/mock_sites/broken_mcp/agent-identity.json +6 -0
  50. aeo_audit-1.1.1/tests/fixtures/mock_sites/broken_mcp/config.yaml +62 -0
  51. aeo_audit-1.1.1/tests/fixtures/mock_sites/broken_mcp/did.json +19 -0
  52. aeo_audit-1.1.1/tests/fixtures/mock_sites/broken_mcp/index.html +12 -0
  53. aeo_audit-1.1.1/tests/fixtures/mock_sites/broken_mcp/oauth-authorization-server.json +9 -0
  54. aeo_audit-1.1.1/tests/fixtures/mock_sites/broken_mcp/openapi.json +51 -0
  55. aeo_audit-1.1.1/tests/fixtures/mock_sites/minimal/config.yaml +16 -0
  56. aeo_audit-1.1.1/tests/fixtures/mock_sites/minimal/index.html +12 -0
  57. aeo_audit-1.1.1/tests/fixtures/mock_sites/missing_manifest/config.yaml +30 -0
  58. aeo_audit-1.1.1/tests/fixtures/mock_sites/missing_manifest/index.html +12 -0
  59. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_pricing/agent-delegation.json +20 -0
  60. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_pricing/agent-identity.json +6 -0
  61. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_pricing/config.yaml +61 -0
  62. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_pricing/did.json +19 -0
  63. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_pricing/index.html +12 -0
  64. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_pricing/oauth-authorization-server.json +9 -0
  65. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_pricing/openapi.json +51 -0
  66. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_trust/agent-delegation.json +20 -0
  67. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_trust/agent-identity.json +6 -0
  68. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_trust/config.yaml +83 -0
  69. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_trust/did.json +19 -0
  70. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_trust/index.html +12 -0
  71. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_trust/oauth-authorization-server.json +9 -0
  72. aeo_audit-1.1.1/tests/fixtures/mock_sites/no_trust/openapi.json +51 -0
  73. aeo_audit-1.1.1/tests/fixtures/mock_sites/perfect/agent-delegation.json +20 -0
  74. aeo_audit-1.1.1/tests/fixtures/mock_sites/perfect/agent-identity.json +6 -0
  75. aeo_audit-1.1.1/tests/fixtures/mock_sites/perfect/agent-manifest.json +14 -0
  76. aeo_audit-1.1.1/tests/fixtures/mock_sites/perfect/agent-pricing.json +25 -0
  77. aeo_audit-1.1.1/tests/fixtures/mock_sites/perfect/config.yaml +109 -0
  78. aeo_audit-1.1.1/tests/fixtures/mock_sites/perfect/did.json +19 -0
  79. aeo_audit-1.1.1/tests/fixtures/mock_sites/perfect/index.html +44 -0
  80. aeo_audit-1.1.1/tests/fixtures/mock_sites/perfect/mcp.json +16 -0
  81. aeo_audit-1.1.1/tests/fixtures/mock_sites/perfect/oauth-authorization-server.json +9 -0
  82. aeo_audit-1.1.1/tests/fixtures/mock_sites/perfect/openapi.json +51 -0
  83. aeo_audit-1.1.1/tests/fixtures/server.py +539 -0
  84. aeo_audit-1.1.1/tests/integration/__init__.py +1 -0
  85. aeo_audit-1.1.1/tests/integration/test_capabilities_checks.py +130 -0
  86. aeo_audit-1.1.1/tests/integration/test_cli.py +135 -0
  87. aeo_audit-1.1.1/tests/integration/test_commerce_checks.py +135 -0
  88. aeo_audit-1.1.1/tests/integration/test_crawler.py +84 -0
  89. aeo_audit-1.1.1/tests/integration/test_discovery_checks.py +192 -0
  90. aeo_audit-1.1.1/tests/integration/test_identity_checks.py +142 -0
  91. aeo_audit-1.1.1/tests/integration/test_reporters.py +170 -0
  92. aeo_audit-1.1.1/tests/integration/test_trust_checks.py +135 -0
  93. aeo_audit-1.1.1/tests/unit/__init__.py +1 -0
  94. aeo_audit-1.1.1/tests/unit/test_discovery_checks.py +108 -0
  95. aeo_audit-1.1.1/tests/unit/test_models.py +79 -0
  96. aeo_audit-1.1.1/tests/unit/test_registry.py +102 -0
  97. aeo_audit-1.1.1/tests/unit/test_scoring.py +111 -0
  98. aeo_audit-1.1.1/tests/unit/test_utils.py +59 -0
@@ -0,0 +1,101 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ release:
8
+ types: [published]
9
+
10
+ jobs:
11
+ test:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v6
15
+ - uses: actions/setup-python@v6
16
+ with:
17
+ python-version: '3.11'
18
+ - name: Install system deps
19
+ run: |
20
+ sudo apt-get update
21
+ sudo apt-get install -y libpango-1.0-0 libcairo2 libgdk-pixbuf-2.0-0 libffi-dev
22
+ npx playwright install-deps chromium
23
+ - name: Install deps
24
+ run: pip install hatch && hatch env create
25
+ - name: Install Playwright Browsers
26
+ run: hatch run playwright install chromium
27
+ - name: Run tests
28
+ run: hatch run pytest -x -v --cov=aeo_audit --cov-fail-under=80
29
+ - name: Type check
30
+ run: hatch run mypy --strict aeo_audit/
31
+ - name: Lint
32
+ run: hatch run ruff check aeo_audit/
33
+
34
+ build-binary:
35
+ needs: test
36
+ runs-on: ${{ matrix.os }}
37
+ strategy:
38
+ matrix:
39
+ os: [ubuntu-latest, macos-latest]
40
+ steps:
41
+ - uses: actions/checkout@v6
42
+ - name: Setup Python
43
+ uses: actions/setup-python@v6
44
+ with:
45
+ python-version: '3.11'
46
+ - name: Install system deps
47
+ run: |
48
+ if [ "${{ runner.os }}" = "Linux" ]; then
49
+ sudo apt-get update && sudo apt-get install -y libpango-1.0-0 libcairo2 libgdk-pixbuf-2.0-0 upx
50
+ else
51
+ brew install pango cairo gdk-pixbuf upx
52
+ fi
53
+ npx playwright install-deps chromium
54
+ - name: Build binary
55
+ run: |
56
+ pip install pyinstaller
57
+ pyinstaller --clean aeo_audit.spec
58
+ - name: Upload binary
59
+ uses: actions/upload-artifact@v7
60
+ with:
61
+ name: aeo-audit-${{ runner.os }}
62
+ path: dist/aeo-audit
63
+
64
+ release:
65
+ needs: [test, build-binary]
66
+ if: github.event_name == 'release'
67
+ runs-on: ubuntu-latest
68
+ permissions:
69
+ id-token: write
70
+ contents: write
71
+ env:
72
+ # Empty when no PyPI token is configured, so the publish step self-skips
73
+ # and the release still ships binaries instead of failing.
74
+ HAS_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN != '' }}
75
+ steps:
76
+ - uses: actions/checkout@v6
77
+ - name: Setup Python
78
+ uses: actions/setup-python@v6
79
+ with:
80
+ python-version: '3.11'
81
+ - name: Install Hatch
82
+ run: pip install hatch
83
+ - name: Build PyPI Package
84
+ run: hatch build
85
+ - name: Download artifacts
86
+ uses: actions/download-artifact@v8
87
+ with:
88
+ path: dist-binaries/
89
+ - name: Upload binaries to GitHub Release
90
+ env:
91
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
92
+ run: |
93
+ cp dist-binaries/aeo-audit-Linux/aeo-audit dist-binaries/aeo-audit-linux-x64
94
+ cp dist-binaries/aeo-audit-macOS/aeo-audit dist-binaries/aeo-audit-macos-arm64
95
+ gh release upload "${{ github.event.release.tag_name }}" dist-binaries/aeo-audit-linux-x64 dist-binaries/aeo-audit-macos-arm64 --clobber
96
+ - name: Publish to PyPI
97
+ if: env.HAS_PYPI_TOKEN == 'true'
98
+ uses: pypa/gh-action-pypi-publish@release/v1
99
+ with:
100
+ password: ${{ secrets.PYPI_API_TOKEN }}
101
+ continue-on-error: true
@@ -0,0 +1,57 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+
7
+ # Virtualenv
8
+ .env
9
+ .env.*
10
+ .venv/
11
+ venv/
12
+ ENV/
13
+
14
+ # Build
15
+ build/
16
+ dist/
17
+ *.egg-info/
18
+ .eggs/
19
+
20
+ # Testing
21
+ .pytest_cache/
22
+ .coverage
23
+ htmlcov/
24
+ .tox/
25
+ .mypy_cache/
26
+ .ruff_cache/
27
+
28
+ # IDE
29
+ .vscode/
30
+ .idea/
31
+
32
+ # macOS
33
+ .DS_Store
34
+
35
+ # Logs
36
+ *.log
37
+
38
+ # SQLite
39
+ *.sqlite
40
+ *.sqlite3
41
+ *.db
42
+
43
+ # Playwright
44
+ playwright-report/
45
+ test-results/
46
+
47
+ # Local configs
48
+ config.local.yaml
49
+ .env.local
50
+
51
+ # Cache
52
+ .cache/
53
+
54
+ # Scan outputs — scraped page data may contain secrets/PII; keep out of VCS
55
+ results.jsonl
56
+ *.results.jsonl
57
+ case-studies/
@@ -0,0 +1,52 @@
1
+ # Changelog
2
+
3
+ All notable changes to `aeo-audit` are documented here. The format is based on
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
5
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [1.1.1] - 2026-06-10
8
+
9
+ ### Changed
10
+ - CI: bumped GitHub Actions to their Node 24 majors (`checkout@v6`,
11
+ `setup-python@v6`, `upload-artifact@v7`, `download-artifact@v8`).
12
+ - Refreshed the benchmark corpus under the fixed scoring so percentile grades
13
+ rank sites against a field measured the same way.
14
+
15
+ ### Added
16
+ - First release published to PyPI (`pip install aeo-audit`).
17
+
18
+ ## [1.1.0] - 2026-06-09
19
+
20
+ Launch-readiness release: makes the score a usable feedback loop and fixes
21
+ reliability and install blockers.
22
+
23
+ ### Changed
24
+ - **Foundation-weighted scoring.** Category and per-check weights now favour the
25
+ signals well-run APIs already expose today (Trust, Capabilities, Discovery)
26
+ so the score differentiates real sites instead of collapsing every site to F.
27
+ - **Percentile-relative overall grading.** Grades rank a site against a
28
+ benchmark corpus (A = top 10%), with absolute-threshold fallback when no
29
+ corpus is loaded. Category grades remain absolute.
30
+ - **Crawler wait strategy is now `load`** (was `networkidle`, which never
31
+ settles on long-polling sites); default timeout raised 30s → 45s. Both are
32
+ config-driven.
33
+
34
+ ### Fixed
35
+ - **`robots_agent` always failed in production.** The crawler never populated
36
+ `context.robots_txt`, so the check scored 0 for every site. Added a self-fetch
37
+ fallback and tiered scoring (explicit allow / allow-all / blocked / missing).
38
+ - **Install paths.** Corrected repository-owner references, documented
39
+ `pipx install git+https://…` and the standalone binary's Chromium runtime
40
+ requirement, and fixed broken documentation links.
41
+
42
+ ### Added
43
+ - `scripts/gen_benchmark.py` to (re)generate the percentile benchmark corpus
44
+ from a results file under the current weights.
45
+ - Robust benchmark-path resolution that works from the repo, an installed
46
+ package, and the bundled binary.
47
+
48
+ ## [1.0.0] - 2026-06-07
49
+
50
+ - Initial release: 26 checks across 5 dimensions, 4 reporters (terminal, HTML,
51
+ PDF, JSON), SQLite cache, CLI (scan, batch, diff, config, monitor), and
52
+ Hatch / PyInstaller / Homebrew packaging.
@@ -0,0 +1,252 @@
1
+ Metadata-Version: 2.4
2
+ Name: aeo-audit
3
+ Version: 1.1.1
4
+ Summary: CLI tool to scan websites and score their Agent/Engine Optimization (AEO) readiness.
5
+ Project-URL: Homepage, https://github.com/AJ-EN/aeo-audit
6
+ Project-URL: Repository, https://github.com/AJ-EN/aeo-audit
7
+ Project-URL: Issues, https://github.com/AJ-EN/aeo-audit/issues
8
+ Author: Ayush Jangid
9
+ License: MIT
10
+ Keywords: aeo,agent,audit,cli,seo
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.11
21
+ Requires-Dist: aiofiles<25,>=23.0
22
+ Requires-Dist: base58<3,>=2.1
23
+ Requires-Dist: click<9,>=8.1
24
+ Requires-Dist: cryptography<44,>=42.0
25
+ Requires-Dist: dnspython<3,>=2.4
26
+ Requires-Dist: eth-utils<5,>=4.0
27
+ Requires-Dist: extruct<1,>=0.17
28
+ Requires-Dist: httpx<1,>=0.27
29
+ Requires-Dist: jinja2<4,>=3.1
30
+ Requires-Dist: jsonschema<5,>=4.20
31
+ Requires-Dist: multiformats<1,>=0.2
32
+ Requires-Dist: openapi-spec-validator<1,>=0.7
33
+ Requires-Dist: playwright<2,>=1.40
34
+ Requires-Dist: pydantic-settings<3,>=2.0
35
+ Requires-Dist: pydantic<3,>=2.0
36
+ Requires-Dist: python-jose[cryptography]<4,>=3.3
37
+ Requires-Dist: pyyaml<7,>=6.0
38
+ Requires-Dist: rich<14,>=13.0
39
+ Provides-Extra: all
40
+ Requires-Dist: hypothesis<7,>=6.90; extra == 'all'
41
+ Requires-Dist: mypy<2,>=1.8; extra == 'all'
42
+ Requires-Dist: pydyf<0.11.0; extra == 'all'
43
+ Requires-Dist: pyinstaller<7,>=6.0; extra == 'all'
44
+ Requires-Dist: pytest-asyncio<1,>=0.23; extra == 'all'
45
+ Requires-Dist: pytest-cov<6,>=5.0; extra == 'all'
46
+ Requires-Dist: pytest-mock<4,>=3.12; extra == 'all'
47
+ Requires-Dist: pytest<9,>=8.0; extra == 'all'
48
+ Requires-Dist: ruff<1,>=0.3; extra == 'all'
49
+ Requires-Dist: types-aiofiles>=23.0; extra == 'all'
50
+ Requires-Dist: types-pyyaml>=6.0; extra == 'all'
51
+ Requires-Dist: weasyprint<62,>=60; extra == 'all'
52
+ Provides-Extra: dev
53
+ Requires-Dist: hypothesis<7,>=6.90; extra == 'dev'
54
+ Requires-Dist: mypy<2,>=1.8; extra == 'dev'
55
+ Requires-Dist: pyinstaller<7,>=6.0; extra == 'dev'
56
+ Requires-Dist: pytest-asyncio<1,>=0.23; extra == 'dev'
57
+ Requires-Dist: pytest-cov<6,>=5.0; extra == 'dev'
58
+ Requires-Dist: pytest-mock<4,>=3.12; extra == 'dev'
59
+ Requires-Dist: pytest<9,>=8.0; extra == 'dev'
60
+ Requires-Dist: ruff<1,>=0.3; extra == 'dev'
61
+ Requires-Dist: types-aiofiles>=23.0; extra == 'dev'
62
+ Requires-Dist: types-pyyaml>=6.0; extra == 'dev'
63
+ Provides-Extra: pdf
64
+ Requires-Dist: pydyf<0.11.0; extra == 'pdf'
65
+ Requires-Dist: weasyprint<62,>=60; extra == 'pdf'
66
+ Description-Content-Type: text/markdown
67
+
68
+ # AEO Auditor CLI
69
+
70
+ [![Build Status](https://github.com/AJ-EN/aeo-audit/actions/workflows/ci.yml/badge.svg)](https://github.com/AJ-EN/aeo-audit/actions)
71
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
72
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)
73
+
74
+ **PageSpeed for AI agents.** Scan any website and score its **Agent/Engine Optimization (AEO) readiness** across 5 dimensions — Discovery, Identity, Capabilities, Commerce, and Trust — then get a graded report with prioritized, actionable fixes.
75
+
76
+ Grades are **relative**: a site is ranked against a benchmark corpus (A = top tier of agent-readiness today), so the score stays a meaningful, movable target while agent-native standards are still emerging.
77
+
78
+ ---
79
+
80
+ ## Architecture Overview
81
+
82
+ ```mermaid
83
+ graph TD
84
+ CLI[CLI: aeo-audit] --> Engine[ScanEngine]
85
+ Engine --> Config[ConfigLoader]
86
+ Engine --> Crawler[Playwright Crawler]
87
+ Engine --> Registry[CheckRegistry]
88
+ Crawler --> Fetch[Fetch URL & Render DOM]
89
+ Registry --> Run[Run 26 Audit Checks]
90
+ Run --> Score[Scoring Pipeline]
91
+ Score --> Reporter[ReporterFactory]
92
+ Reporter --> Terminal[Rich Terminal]
93
+ Reporter --> HTML[HTML Report]
94
+ Reporter --> PDF[WeasyPrint PDF]
95
+ Reporter --> JSON[JSON Metadata]
96
+ ```
97
+
98
+ ---
99
+
100
+ ## Installation
101
+
102
+ ### 1. System Dependencies (Required for WeasyPrint PDF)
103
+
104
+ PDF reports require external layout libraries installed on your OS:
105
+
106
+ - **macOS (Homebrew)**:
107
+
108
+ ```bash
109
+ brew install pango cairo gdk-pixbuf upx
110
+ ```
111
+
112
+ - **Ubuntu/Debian**:
113
+
114
+ ```bash
115
+ sudo apt-get update
116
+ sudo apt-get install -y libpango-1.0-0 libcairo2 libgdk-pixbuf-2.0-0 upx
117
+ ```
118
+
119
+ ### 2. Install Methods
120
+
121
+ #### Method A: Via `pipx` (Recommended for Python CLI apps)
122
+
123
+ ```bash
124
+ # From GitHub (works today):
125
+ pipx install git+https://github.com/AJ-EN/aeo-audit.git
126
+
127
+ # From PyPI (once published):
128
+ # pipx install aeo-audit
129
+ ```
130
+
131
+ After installing, download the headless browser Playwright needs:
132
+
133
+ ```bash
134
+ playwright install chromium
135
+ ```
136
+
137
+ #### Method B: Standalone Binary Installer (No Python Needed)
138
+
139
+ Run the automated installation script:
140
+
141
+ ```bash
142
+ curl -fsSL https://raw.githubusercontent.com/AJ-EN/aeo-audit/main/scripts/install.sh | bash
143
+ ```
144
+
145
+ > [!IMPORTANT]
146
+ > The binary still needs a Chromium runtime. If a scan reports a missing browser,
147
+ > install one with `playwright install chromium` and point the binary at it:
148
+ > `export PLAYWRIGHT_BROWSERS_PATH="$HOME/Library/Caches/ms-playwright"` (macOS)
149
+ > or the equivalent cache path on your OS.
150
+
151
+ #### Method C: Source installation
152
+
153
+ ```bash
154
+ git clone https://github.com/AJ-EN/aeo-audit.git
155
+ cd aeo-audit
156
+ pip install -e .
157
+ playwright install chromium
158
+ ```
159
+
160
+ > [!NOTE]
161
+ > If WeasyPrint throws rendering or font warnings on Python 3.14+, we recommend pinning `pydyf==0.10.0`.
162
+
163
+ ---
164
+
165
+ ## Quick Start
166
+
167
+ Scan a site and generate reports using the `scan` command:
168
+
169
+ ```bash
170
+ # Terminal report (default)
171
+ aeo-audit scan https://api.example.com --format terminal
172
+
173
+ # Premium HTML report with embedded graphs
174
+ aeo-audit scan https://api.example.com --format html --output report.html
175
+
176
+ # Accessible PDF report
177
+ aeo-audit scan https://api.example.com --format pdf --output report.pdf
178
+
179
+ # Machine-readable JSON report
180
+ aeo-audit scan https://api.example.com --format json --output report.json
181
+ ```
182
+
183
+ ---
184
+
185
+ ## Scoring & Grading
186
+
187
+ Each of the 26 checks returns a raw score (`0.0`–`1.0`). Checks roll up into 5 weighted category scores, which roll up into a single `0–100` overall score. The grade is then assigned **by percentile rank against a benchmark corpus** — so it reflects how a site compares to the field, not an absolute bar that nobody clears yet.
188
+
189
+ ### Category weights
190
+
191
+ `aeo-audit` is **foundation-weighted**: dimensions where well-run APIs already differ today (Trust, Capabilities, Discovery) carry the most weight, while emerging agent-native dimensions (Identity, parts of Commerce) contribute upside without dominating the score.
192
+
193
+ | Category | Weight | What it measures |
194
+ |----------|--------|------------------|
195
+ | **Discovery** | `0.25` | robots/agent access, sitemap, `.well-known`, DNS, and MCP discovery. |
196
+ | **Capabilities** | `0.25` | Interface docs — OpenAPI, JSON Schema, GraphQL, async webhooks. |
197
+ | **Trust** | `0.25` | SLA/status page, structured errors, health checks, audit logs. |
198
+ | **Commerce** | `0.15` | Agent transactions — pricing, Stripe/crypto hints, usage metering. |
199
+ | **Identity** | `0.10` | Ownership & auth — DID docs, OAuth metadata, wallet hints. |
200
+
201
+ ### Grade bands (percentile)
202
+
203
+ | Grade | Percentile | Meaning |
204
+ |-------|-----------|---------|
205
+ | **A** | top 10% | Leading the field on agent-readiness. |
206
+ | **B** | top 30% | Strong; a few high-leverage gaps. |
207
+ | **C** | top 60% | Foundational signals present, frontier gaps. |
208
+ | **D** | top 85% | Minimal agent-readiness. |
209
+ | **F** | bottom 15% | Not addressed. |
210
+
211
+ Weights, thresholds, and grade bands are all defined in `config.yaml` and overridable via a custom config. See [docs/CONFIG_REFERENCE.md](docs/CONFIG_REFERENCE.md).
212
+
213
+ ---
214
+
215
+ ## CI/CD Pipeline Integration
216
+
217
+ You can easily configure `aeo-audit` as a compliance block (exits with code `2` if scores drop below requirements). Here's a brief example for **GitHub Actions**:
218
+
219
+ ```yaml
220
+ - name: AEO Compliance Gate
221
+ run: aeo-audit scan https://preview.example.com --fail-on-grade B --format terminal
222
+ ```
223
+
224
+ See [docs/CI_RECIPES.md](docs/CI_RECIPES.md) for GitHub Actions, GitLab CI, and Git hooks code snippets.
225
+
226
+ ---
227
+
228
+ ## Extending: Custom Check Plugins
229
+
230
+ To implement custom checking rules, subclass `BaseCheck` and expose it under the `aeo_audit.checks` entrypoint.
231
+
232
+ See [docs/CUSTOM_CHECKS.md](docs/CUSTOM_CHECKS.md) for a complete template walkthrough.
233
+
234
+ ---
235
+
236
+ ## FAQ
237
+
238
+ #### 1. How do I install Playwright browser binaries?
239
+
240
+ If running the scanner for the first time, you may need to install Playwright's headless browser binaries:
241
+
242
+ ```bash
243
+ playwright install chromium
244
+ ```
245
+
246
+ #### 2. Where is the SQLite cache stored?
247
+
248
+ By default, the SQLite cache database is created in your working directory as `.aeo_cache.db` to speed up consecutive audit scans. This can be customized or disabled using `--no-cache`.
249
+
250
+ #### 3. Why are my PDF files empty or raising font errors?
251
+
252
+ Ensure you have installed the native `pango` and `cairo` system dependencies (see Step 1 of installation).
@@ -0,0 +1,185 @@
1
+ # AEO Auditor CLI
2
+
3
+ [![Build Status](https://github.com/AJ-EN/aeo-audit/actions/workflows/ci.yml/badge.svg)](https://github.com/AJ-EN/aeo-audit/actions)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)
6
+
7
+ **PageSpeed for AI agents.** Scan any website and score its **Agent/Engine Optimization (AEO) readiness** across 5 dimensions — Discovery, Identity, Capabilities, Commerce, and Trust — then get a graded report with prioritized, actionable fixes.
8
+
9
+ Grades are **relative**: a site is ranked against a benchmark corpus (A = top tier of agent-readiness today), so the score stays a meaningful, movable target while agent-native standards are still emerging.
10
+
11
+ ---
12
+
13
+ ## Architecture Overview
14
+
15
+ ```mermaid
16
+ graph TD
17
+ CLI[CLI: aeo-audit] --> Engine[ScanEngine]
18
+ Engine --> Config[ConfigLoader]
19
+ Engine --> Crawler[Playwright Crawler]
20
+ Engine --> Registry[CheckRegistry]
21
+ Crawler --> Fetch[Fetch URL & Render DOM]
22
+ Registry --> Run[Run 26 Audit Checks]
23
+ Run --> Score[Scoring Pipeline]
24
+ Score --> Reporter[ReporterFactory]
25
+ Reporter --> Terminal[Rich Terminal]
26
+ Reporter --> HTML[HTML Report]
27
+ Reporter --> PDF[WeasyPrint PDF]
28
+ Reporter --> JSON[JSON Metadata]
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Installation
34
+
35
+ ### 1. System Dependencies (Required for WeasyPrint PDF)
36
+
37
+ PDF reports require external layout libraries installed on your OS:
38
+
39
+ - **macOS (Homebrew)**:
40
+
41
+ ```bash
42
+ brew install pango cairo gdk-pixbuf upx
43
+ ```
44
+
45
+ - **Ubuntu/Debian**:
46
+
47
+ ```bash
48
+ sudo apt-get update
49
+ sudo apt-get install -y libpango-1.0-0 libcairo2 libgdk-pixbuf-2.0-0 upx
50
+ ```
51
+
52
+ ### 2. Install Methods
53
+
54
+ #### Method A: Via `pipx` (Recommended for Python CLI apps)
55
+
56
+ ```bash
57
+ # From GitHub (works today):
58
+ pipx install git+https://github.com/AJ-EN/aeo-audit.git
59
+
60
+ # From PyPI (once published):
61
+ # pipx install aeo-audit
62
+ ```
63
+
64
+ After installing, download the headless browser Playwright needs:
65
+
66
+ ```bash
67
+ playwright install chromium
68
+ ```
69
+
70
+ #### Method B: Standalone Binary Installer (No Python Needed)
71
+
72
+ Run the automated installation script:
73
+
74
+ ```bash
75
+ curl -fsSL https://raw.githubusercontent.com/AJ-EN/aeo-audit/main/scripts/install.sh | bash
76
+ ```
77
+
78
+ > [!IMPORTANT]
79
+ > The binary still needs a Chromium runtime. If a scan reports a missing browser,
80
+ > install one with `playwright install chromium` and point the binary at it:
81
+ > `export PLAYWRIGHT_BROWSERS_PATH="$HOME/Library/Caches/ms-playwright"` (macOS)
82
+ > or the equivalent cache path on your OS.
83
+
84
+ #### Method C: Source installation
85
+
86
+ ```bash
87
+ git clone https://github.com/AJ-EN/aeo-audit.git
88
+ cd aeo-audit
89
+ pip install -e .
90
+ playwright install chromium
91
+ ```
92
+
93
+ > [!NOTE]
94
+ > If WeasyPrint throws rendering or font warnings on Python 3.14+, we recommend pinning `pydyf==0.10.0`.
95
+
96
+ ---
97
+
98
+ ## Quick Start
99
+
100
+ Scan a site and generate reports using the `scan` command:
101
+
102
+ ```bash
103
+ # Terminal report (default)
104
+ aeo-audit scan https://api.example.com --format terminal
105
+
106
+ # Premium HTML report with embedded graphs
107
+ aeo-audit scan https://api.example.com --format html --output report.html
108
+
109
+ # Accessible PDF report
110
+ aeo-audit scan https://api.example.com --format pdf --output report.pdf
111
+
112
+ # Machine-readable JSON report
113
+ aeo-audit scan https://api.example.com --format json --output report.json
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Scoring & Grading
119
+
120
+ Each of the 26 checks returns a raw score (`0.0`–`1.0`). Checks roll up into 5 weighted category scores, which roll up into a single `0–100` overall score. The grade is then assigned **by percentile rank against a benchmark corpus** — so it reflects how a site compares to the field, not an absolute bar that nobody clears yet.
121
+
122
+ ### Category weights
123
+
124
+ `aeo-audit` is **foundation-weighted**: dimensions where well-run APIs already differ today (Trust, Capabilities, Discovery) carry the most weight, while emerging agent-native dimensions (Identity, parts of Commerce) contribute upside without dominating the score.
125
+
126
+ | Category | Weight | What it measures |
127
+ |----------|--------|------------------|
128
+ | **Discovery** | `0.25` | robots/agent access, sitemap, `.well-known`, DNS, and MCP discovery. |
129
+ | **Capabilities** | `0.25` | Interface docs — OpenAPI, JSON Schema, GraphQL, async webhooks. |
130
+ | **Trust** | `0.25` | SLA/status page, structured errors, health checks, audit logs. |
131
+ | **Commerce** | `0.15` | Agent transactions — pricing, Stripe/crypto hints, usage metering. |
132
+ | **Identity** | `0.10` | Ownership & auth — DID docs, OAuth metadata, wallet hints. |
133
+
134
+ ### Grade bands (percentile)
135
+
136
+ | Grade | Percentile | Meaning |
137
+ |-------|-----------|---------|
138
+ | **A** | top 10% | Leading the field on agent-readiness. |
139
+ | **B** | top 30% | Strong; a few high-leverage gaps. |
140
+ | **C** | top 60% | Foundational signals present, frontier gaps. |
141
+ | **D** | top 85% | Minimal agent-readiness. |
142
+ | **F** | bottom 15% | Not addressed. |
143
+
144
+ Weights, thresholds, and grade bands are all defined in `config.yaml` and overridable via a custom config. See [docs/CONFIG_REFERENCE.md](docs/CONFIG_REFERENCE.md).
145
+
146
+ ---
147
+
148
+ ## CI/CD Pipeline Integration
149
+
150
+ You can easily configure `aeo-audit` as a compliance block (exits with code `2` if scores drop below requirements). Here's a brief example for **GitHub Actions**:
151
+
152
+ ```yaml
153
+ - name: AEO Compliance Gate
154
+ run: aeo-audit scan https://preview.example.com --fail-on-grade B --format terminal
155
+ ```
156
+
157
+ See [docs/CI_RECIPES.md](docs/CI_RECIPES.md) for GitHub Actions, GitLab CI, and Git hooks code snippets.
158
+
159
+ ---
160
+
161
+ ## Extending: Custom Check Plugins
162
+
163
+ To implement custom checking rules, subclass `BaseCheck` and expose it under the `aeo_audit.checks` entrypoint.
164
+
165
+ See [docs/CUSTOM_CHECKS.md](docs/CUSTOM_CHECKS.md) for a complete template walkthrough.
166
+
167
+ ---
168
+
169
+ ## FAQ
170
+
171
+ #### 1. How do I install Playwright browser binaries?
172
+
173
+ If running the scanner for the first time, you may need to install Playwright's headless browser binaries:
174
+
175
+ ```bash
176
+ playwright install chromium
177
+ ```
178
+
179
+ #### 2. Where is the SQLite cache stored?
180
+
181
+ By default, the SQLite cache database is created in your working directory as `.aeo_cache.db` to speed up consecutive audit scans. This can be customized or disabled using `--no-cache`.
182
+
183
+ #### 3. Why are my PDF files empty or raising font errors?
184
+
185
+ Ensure you have installed the native `pango` and `cairo` system dependencies (see Step 1 of installation).