aeo-cli 0.2.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.
- aeo_cli-0.2.1/LICENSE +21 -0
- aeo_cli-0.2.1/PKG-INFO +302 -0
- aeo_cli-0.2.1/README.md +261 -0
- aeo_cli-0.2.1/pyproject.toml +96 -0
- aeo_cli-0.2.1/setup.cfg +4 -0
- aeo_cli-0.2.1/src/aeo_cli/__init__.py +8 -0
- aeo_cli-0.2.1/src/aeo_cli/core/__init__.py +0 -0
- aeo_cli-0.2.1/src/aeo_cli/core/auditor.py +564 -0
- aeo_cli-0.2.1/src/aeo_cli/core/cache.py +34 -0
- aeo_cli-0.2.1/src/aeo_cli/core/crawler.py +188 -0
- aeo_cli-0.2.1/src/aeo_cli/core/discovery.py +251 -0
- aeo_cli-0.2.1/src/aeo_cli/core/generate/__init__.py +15 -0
- aeo_cli-0.2.1/src/aeo_cli/core/generate/compiler.py +133 -0
- aeo_cli-0.2.1/src/aeo_cli/core/generate/llm.py +136 -0
- aeo_cli-0.2.1/src/aeo_cli/core/generate/profiles.py +85 -0
- aeo_cli-0.2.1/src/aeo_cli/core/generate/prompts.py +108 -0
- aeo_cli-0.2.1/src/aeo_cli/core/models.py +223 -0
- aeo_cli-0.2.1/src/aeo_cli/core/retry.py +78 -0
- aeo_cli-0.2.1/src/aeo_cli/formatters/__init__.py +1 -0
- aeo_cli-0.2.1/src/aeo_cli/formatters/ci_summary.py +79 -0
- aeo_cli-0.2.1/src/aeo_cli/formatters/csv.py +59 -0
- aeo_cli-0.2.1/src/aeo_cli/formatters/markdown.py +81 -0
- aeo_cli-0.2.1/src/aeo_cli/main.py +420 -0
- aeo_cli-0.2.1/src/aeo_cli/py.typed +0 -0
- aeo_cli-0.2.1/src/aeo_cli/server.py +62 -0
- aeo_cli-0.2.1/src/aeo_cli.egg-info/PKG-INFO +302 -0
- aeo_cli-0.2.1/src/aeo_cli.egg-info/SOURCES.txt +62 -0
- aeo_cli-0.2.1/src/aeo_cli.egg-info/dependency_links.txt +1 -0
- aeo_cli-0.2.1/src/aeo_cli.egg-info/entry_points.txt +2 -0
- aeo_cli-0.2.1/src/aeo_cli.egg-info/requires.txt +18 -0
- aeo_cli-0.2.1/src/aeo_cli.egg-info/top_level.txt +1 -0
- aeo_cli-0.2.1/tests/test_auditor.py +247 -0
- aeo_cli-0.2.1/tests/test_auditor_coverage.py +378 -0
- aeo_cli-0.2.1/tests/test_cache.py +80 -0
- aeo_cli-0.2.1/tests/test_ci_features.py +185 -0
- aeo_cli-0.2.1/tests/test_ci_summary.py +136 -0
- aeo_cli-0.2.1/tests/test_cli.py +141 -0
- aeo_cli-0.2.1/tests/test_cli_coverage.py +544 -0
- aeo_cli-0.2.1/tests/test_cli_errors.py +78 -0
- aeo_cli-0.2.1/tests/test_content_boundaries.py +100 -0
- aeo_cli-0.2.1/tests/test_crawler_coverage.py +221 -0
- aeo_cli-0.2.1/tests/test_crawler_errors.py +81 -0
- aeo_cli-0.2.1/tests/test_discovery.py +143 -0
- aeo_cli-0.2.1/tests/test_discovery_coverage.py +315 -0
- aeo_cli-0.2.1/tests/test_formatters.py +157 -0
- aeo_cli-0.2.1/tests/test_generate_cli.py +161 -0
- aeo_cli-0.2.1/tests/test_generate_compiler.py +268 -0
- aeo_cli-0.2.1/tests/test_generate_llm.py +174 -0
- aeo_cli-0.2.1/tests/test_generate_models.py +164 -0
- aeo_cli-0.2.1/tests/test_generate_profiles.py +111 -0
- aeo_cli-0.2.1/tests/test_generate_prompts.py +135 -0
- aeo_cli-0.2.1/tests/test_github_summary.py +91 -0
- aeo_cli-0.2.1/tests/test_llms_txt_edge_cases.py +93 -0
- aeo_cli-0.2.1/tests/test_mcp_server.py +149 -0
- aeo_cli-0.2.1/tests/test_models.py +100 -0
- aeo_cli-0.2.1/tests/test_page_weight_edges.py +63 -0
- aeo_cli-0.2.1/tests/test_retry.py +138 -0
- aeo_cli-0.2.1/tests/test_robots_edge_cases.py +100 -0
- aeo_cli-0.2.1/tests/test_schema_edge_cases.py +105 -0
- aeo_cli-0.2.1/tests/test_scoring_integration.py +114 -0
- aeo_cli-0.2.1/tests/test_site_audit.py +192 -0
- aeo_cli-0.2.1/tests/test_sitemap_parsing.py +109 -0
- aeo_cli-0.2.1/tests/test_spider.py +124 -0
- aeo_cli-0.2.1/tests/test_verbose_output.py +103 -0
aeo_cli-0.2.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 AEO-CLI Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
aeo_cli-0.2.1/PKG-INFO
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aeo-cli
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Agentic Engine Optimization CLI — audit URLs for AI crawler readiness
|
|
5
|
+
Author: Hansel Wahjono
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/hanselhansel/aeo-cli
|
|
8
|
+
Project-URL: Repository, https://github.com/hanselhansel/aeo-cli
|
|
9
|
+
Project-URL: Issues, https://github.com/hanselhansel/aeo-cli/issues
|
|
10
|
+
Keywords: aeo,seo,ai,llm,crawler,audit,robots-txt,schema-org
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
19
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: typer>=0.9
|
|
25
|
+
Requires-Dist: rich>=13.0
|
|
26
|
+
Requires-Dist: httpx>=0.27
|
|
27
|
+
Requires-Dist: beautifulsoup4>=4.12
|
|
28
|
+
Requires-Dist: pydantic>=2.0
|
|
29
|
+
Requires-Dist: crawl4ai>=0.4
|
|
30
|
+
Requires-Dist: fastmcp>=2.0
|
|
31
|
+
Provides-Extra: generate
|
|
32
|
+
Requires-Dist: litellm>=1.40; extra == "generate"
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
37
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
38
|
+
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
39
|
+
Requires-Dist: litellm>=1.40; extra == "dev"
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
|
|
42
|
+
# AEO-CLI
|
|
43
|
+
|
|
44
|
+
[](https://github.com/hanselhansel/aeo-cli/actions/workflows/test.yml)
|
|
45
|
+
[](https://www.python.org/downloads/)
|
|
46
|
+
[](LICENSE)
|
|
47
|
+
[](https://pypi.org/project/aeo-cli/)
|
|
48
|
+
|
|
49
|
+
**Audit any URL for AI crawler readiness. Get a 0-100 AEO score.**
|
|
50
|
+
|
|
51
|
+
## What is AEO?
|
|
52
|
+
|
|
53
|
+
Agentic Engine Optimization (AEO) is the practice of making your website discoverable and accessible to AI agents and LLM-powered search engines. As AI crawlers like GPTBot, ClaudeBot, and PerplexityBot become major traffic sources, AEO ensures your content is structured, permitted, and optimized for these systems.
|
|
54
|
+
|
|
55
|
+
AEO-CLI checks how well a URL is prepared for AI consumption and returns a structured score.
|
|
56
|
+
|
|
57
|
+
## Features
|
|
58
|
+
|
|
59
|
+
- **Robots.txt AI bot access** — checks whether major AI crawlers are allowed or blocked
|
|
60
|
+
- **llms.txt presence** — detects the emerging standard for LLM-specific site instructions
|
|
61
|
+
- **Schema.org JSON-LD** — extracts and evaluates structured data markup
|
|
62
|
+
- **Content density** — measures useful content vs. boilerplate via markdown conversion
|
|
63
|
+
- **Rich CLI output** — formatted tables and scores via Rich
|
|
64
|
+
- **JSON output** — machine-readable results for pipelines
|
|
65
|
+
- **MCP server** — expose the audit as a tool for AI agents via FastMCP
|
|
66
|
+
- **AEO Compiler** — LLM-powered `llms.txt` and `schema.jsonld` generation
|
|
67
|
+
- **CI/CD integration** — `--fail-under` threshold, `--fail-on-blocked-bots`, GitHub Step Summary
|
|
68
|
+
- **GitHub Action** — composite action for CI pipelines
|
|
69
|
+
|
|
70
|
+
## Installation
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install aeo-cli
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
AEO-CLI uses a headless browser for content extraction. After installing, run:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
crawl4ai-setup
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Development install
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
git clone https://github.com/your-org/aeo-cli.git
|
|
86
|
+
cd aeo-cli
|
|
87
|
+
pip install -e ".[dev]"
|
|
88
|
+
crawl4ai-setup
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Quick Start
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
aeo-cli audit example.com
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This runs a full audit and prints a Rich-formatted report with your AEO score.
|
|
98
|
+
|
|
99
|
+
## CLI Usage
|
|
100
|
+
|
|
101
|
+
### Single Page Audit
|
|
102
|
+
|
|
103
|
+
Audit only the specified URL (skip multi-page discovery):
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
aeo-cli audit example.com --single
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Multi-Page Site Audit (default)
|
|
110
|
+
|
|
111
|
+
Discover pages via sitemap/spider and audit up to 10 pages:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
aeo-cli audit example.com
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Limit Pages
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
aeo-cli audit example.com --max-pages 5
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### JSON Output
|
|
124
|
+
|
|
125
|
+
Get structured JSON for CI pipelines, dashboards, or scripting:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
aeo-cli audit example.com --json
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### CSV / Markdown Output
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
aeo-cli audit example.com --format csv
|
|
135
|
+
aeo-cli audit example.com --format markdown
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Verbose Mode
|
|
139
|
+
|
|
140
|
+
Show detailed per-pillar breakdown with scoring explanations:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
aeo-cli audit example.com --single --verbose
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### CI Mode
|
|
147
|
+
|
|
148
|
+
Fail the build if the AEO score is below a threshold:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
aeo-cli audit example.com --fail-under 60
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Fail if any AI bot is blocked:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
aeo-cli audit example.com --fail-on-blocked-bots
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Exit codes: 0 = pass, 1 = score below threshold, 2 = bots blocked.
|
|
161
|
+
|
|
162
|
+
When running in GitHub Actions, a markdown summary is automatically written to `$GITHUB_STEP_SUMMARY`.
|
|
163
|
+
|
|
164
|
+
### Quiet Mode
|
|
165
|
+
|
|
166
|
+
Suppress output, exit code 0 if score >= 50, 1 otherwise:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
aeo-cli audit example.com --quiet
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Use `--fail-under` with `--quiet` to override the default threshold:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
aeo-cli audit example.com --quiet --fail-under 70
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Start MCP server
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
aeo-cli mcp
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Launches a FastMCP stdio server exposing the audit as a tool for AI agents.
|
|
185
|
+
|
|
186
|
+
## MCP Integration
|
|
187
|
+
|
|
188
|
+
To use AEO-CLI as a tool in Claude Desktop, add this to your Claude Desktop config (`claude_desktop_config.json`):
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"mcpServers": {
|
|
193
|
+
"aeo-cli": {
|
|
194
|
+
"command": "aeo-cli",
|
|
195
|
+
"args": ["mcp"]
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Once configured, Claude can call the `audit_url` tool directly to check any URL's AEO readiness.
|
|
202
|
+
|
|
203
|
+
## AEO Compiler (Generate)
|
|
204
|
+
|
|
205
|
+
Generate `llms.txt` and `schema.jsonld` files from any URL using LLM analysis:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
pip install aeo-cli[generate]
|
|
209
|
+
aeo-cli generate example.com
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
This crawls the URL, sends the content to an LLM, and writes optimized files to `./aeo-output/`.
|
|
213
|
+
|
|
214
|
+
### BYOK (Bring Your Own Key)
|
|
215
|
+
|
|
216
|
+
The generate command auto-detects your LLM provider from environment variables:
|
|
217
|
+
|
|
218
|
+
| Priority | Env Variable | Model Used |
|
|
219
|
+
|----------|-------------|------------|
|
|
220
|
+
| 1 | `OPENAI_API_KEY` | gpt-4o-mini |
|
|
221
|
+
| 2 | `ANTHROPIC_API_KEY` | claude-3-haiku-20240307 |
|
|
222
|
+
| 3 | Ollama running locally | ollama/llama3.2 |
|
|
223
|
+
|
|
224
|
+
Override with `--model`:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
aeo-cli generate example.com --model gpt-4o
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Industry Profiles
|
|
231
|
+
|
|
232
|
+
Tailor the output with `--profile`:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
aeo-cli generate example.com --profile saas
|
|
236
|
+
aeo-cli generate example.com --profile ecommerce
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Available: `generic`, `cpg`, `saas`, `ecommerce`, `blog`.
|
|
240
|
+
|
|
241
|
+
## GitHub Action
|
|
242
|
+
|
|
243
|
+
Use AEO-CLI in your CI pipeline:
|
|
244
|
+
|
|
245
|
+
```yaml
|
|
246
|
+
- name: Run AEO Audit
|
|
247
|
+
uses: hanselhansel/aeo-cli@main
|
|
248
|
+
with:
|
|
249
|
+
url: 'https://your-site.com'
|
|
250
|
+
fail-under: '60'
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
The action sets up Python, installs aeo-cli, and runs the audit. Outputs `score` and `report-json` for downstream steps. See [docs/ci-integration.md](docs/ci-integration.md) for full documentation.
|
|
254
|
+
|
|
255
|
+
## Score Breakdown
|
|
256
|
+
|
|
257
|
+
AEO-CLI returns a score from 0 to 100, composed of four pillars:
|
|
258
|
+
|
|
259
|
+
| Pillar | Max Points | What it measures |
|
|
260
|
+
|---|---|---|
|
|
261
|
+
| Content density | 40 | Quality and depth of extractable text content |
|
|
262
|
+
| Robots.txt AI bot access | 25 | Whether AI crawlers are allowed in robots.txt |
|
|
263
|
+
| Schema.org JSON-LD | 25 | Structured data markup (Product, Article, FAQ, etc.) |
|
|
264
|
+
| llms.txt presence | 10 | Whether a /llms.txt file exists for LLM guidance |
|
|
265
|
+
|
|
266
|
+
### Scoring rationale (2026-02-18)
|
|
267
|
+
|
|
268
|
+
The weights reflect how AI search engines (ChatGPT, Perplexity, Claude) actually consume web content:
|
|
269
|
+
|
|
270
|
+
- **Content density (40 pts)** is weighted highest because it's what LLMs extract and cite when answering questions. Rich, well-structured content with headings and lists gives AI better material to work with.
|
|
271
|
+
- **Robots.txt (25 pts)** is the gatekeeper — if a bot is blocked, it literally cannot crawl. It's critical but largely binary (either you're blocking or you're not).
|
|
272
|
+
- **Schema.org (25 pts)** provides structured "cheat sheets" that help AI understand entities (products, articles, organizations). Valuable but not required for citation.
|
|
273
|
+
- **llms.txt (10 pts)** is an emerging standard. No major AI search engine heavily weights it yet, but it signals forward-thinking AI readiness.
|
|
274
|
+
|
|
275
|
+
## AI Bots Checked
|
|
276
|
+
|
|
277
|
+
AEO-CLI checks access rules for these AI crawlers:
|
|
278
|
+
|
|
279
|
+
- GPTBot
|
|
280
|
+
- ChatGPT-User
|
|
281
|
+
- Google-Extended
|
|
282
|
+
- ClaudeBot
|
|
283
|
+
- PerplexityBot
|
|
284
|
+
- Amazonbot
|
|
285
|
+
- OAI-SearchBot
|
|
286
|
+
|
|
287
|
+
## Development
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
# Install with dev dependencies
|
|
291
|
+
pip install -e ".[dev]"
|
|
292
|
+
|
|
293
|
+
# Run tests
|
|
294
|
+
pytest
|
|
295
|
+
|
|
296
|
+
# Lint
|
|
297
|
+
ruff check src/ tests/
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## License
|
|
301
|
+
|
|
302
|
+
MIT
|
aeo_cli-0.2.1/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# AEO-CLI
|
|
2
|
+
|
|
3
|
+
[](https://github.com/hanselhansel/aeo-cli/actions/workflows/test.yml)
|
|
4
|
+
[](https://www.python.org/downloads/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://pypi.org/project/aeo-cli/)
|
|
7
|
+
|
|
8
|
+
**Audit any URL for AI crawler readiness. Get a 0-100 AEO score.**
|
|
9
|
+
|
|
10
|
+
## What is AEO?
|
|
11
|
+
|
|
12
|
+
Agentic Engine Optimization (AEO) is the practice of making your website discoverable and accessible to AI agents and LLM-powered search engines. As AI crawlers like GPTBot, ClaudeBot, and PerplexityBot become major traffic sources, AEO ensures your content is structured, permitted, and optimized for these systems.
|
|
13
|
+
|
|
14
|
+
AEO-CLI checks how well a URL is prepared for AI consumption and returns a structured score.
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- **Robots.txt AI bot access** — checks whether major AI crawlers are allowed or blocked
|
|
19
|
+
- **llms.txt presence** — detects the emerging standard for LLM-specific site instructions
|
|
20
|
+
- **Schema.org JSON-LD** — extracts and evaluates structured data markup
|
|
21
|
+
- **Content density** — measures useful content vs. boilerplate via markdown conversion
|
|
22
|
+
- **Rich CLI output** — formatted tables and scores via Rich
|
|
23
|
+
- **JSON output** — machine-readable results for pipelines
|
|
24
|
+
- **MCP server** — expose the audit as a tool for AI agents via FastMCP
|
|
25
|
+
- **AEO Compiler** — LLM-powered `llms.txt` and `schema.jsonld` generation
|
|
26
|
+
- **CI/CD integration** — `--fail-under` threshold, `--fail-on-blocked-bots`, GitHub Step Summary
|
|
27
|
+
- **GitHub Action** — composite action for CI pipelines
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install aeo-cli
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
AEO-CLI uses a headless browser for content extraction. After installing, run:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
crawl4ai-setup
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Development install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
git clone https://github.com/your-org/aeo-cli.git
|
|
45
|
+
cd aeo-cli
|
|
46
|
+
pip install -e ".[dev]"
|
|
47
|
+
crawl4ai-setup
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
aeo-cli audit example.com
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This runs a full audit and prints a Rich-formatted report with your AEO score.
|
|
57
|
+
|
|
58
|
+
## CLI Usage
|
|
59
|
+
|
|
60
|
+
### Single Page Audit
|
|
61
|
+
|
|
62
|
+
Audit only the specified URL (skip multi-page discovery):
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
aeo-cli audit example.com --single
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Multi-Page Site Audit (default)
|
|
69
|
+
|
|
70
|
+
Discover pages via sitemap/spider and audit up to 10 pages:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
aeo-cli audit example.com
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Limit Pages
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
aeo-cli audit example.com --max-pages 5
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### JSON Output
|
|
83
|
+
|
|
84
|
+
Get structured JSON for CI pipelines, dashboards, or scripting:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
aeo-cli audit example.com --json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### CSV / Markdown Output
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
aeo-cli audit example.com --format csv
|
|
94
|
+
aeo-cli audit example.com --format markdown
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Verbose Mode
|
|
98
|
+
|
|
99
|
+
Show detailed per-pillar breakdown with scoring explanations:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
aeo-cli audit example.com --single --verbose
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### CI Mode
|
|
106
|
+
|
|
107
|
+
Fail the build if the AEO score is below a threshold:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
aeo-cli audit example.com --fail-under 60
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Fail if any AI bot is blocked:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
aeo-cli audit example.com --fail-on-blocked-bots
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Exit codes: 0 = pass, 1 = score below threshold, 2 = bots blocked.
|
|
120
|
+
|
|
121
|
+
When running in GitHub Actions, a markdown summary is automatically written to `$GITHUB_STEP_SUMMARY`.
|
|
122
|
+
|
|
123
|
+
### Quiet Mode
|
|
124
|
+
|
|
125
|
+
Suppress output, exit code 0 if score >= 50, 1 otherwise:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
aeo-cli audit example.com --quiet
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Use `--fail-under` with `--quiet` to override the default threshold:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
aeo-cli audit example.com --quiet --fail-under 70
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Start MCP server
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
aeo-cli mcp
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Launches a FastMCP stdio server exposing the audit as a tool for AI agents.
|
|
144
|
+
|
|
145
|
+
## MCP Integration
|
|
146
|
+
|
|
147
|
+
To use AEO-CLI as a tool in Claude Desktop, add this to your Claude Desktop config (`claude_desktop_config.json`):
|
|
148
|
+
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"mcpServers": {
|
|
152
|
+
"aeo-cli": {
|
|
153
|
+
"command": "aeo-cli",
|
|
154
|
+
"args": ["mcp"]
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Once configured, Claude can call the `audit_url` tool directly to check any URL's AEO readiness.
|
|
161
|
+
|
|
162
|
+
## AEO Compiler (Generate)
|
|
163
|
+
|
|
164
|
+
Generate `llms.txt` and `schema.jsonld` files from any URL using LLM analysis:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
pip install aeo-cli[generate]
|
|
168
|
+
aeo-cli generate example.com
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
This crawls the URL, sends the content to an LLM, and writes optimized files to `./aeo-output/`.
|
|
172
|
+
|
|
173
|
+
### BYOK (Bring Your Own Key)
|
|
174
|
+
|
|
175
|
+
The generate command auto-detects your LLM provider from environment variables:
|
|
176
|
+
|
|
177
|
+
| Priority | Env Variable | Model Used |
|
|
178
|
+
|----------|-------------|------------|
|
|
179
|
+
| 1 | `OPENAI_API_KEY` | gpt-4o-mini |
|
|
180
|
+
| 2 | `ANTHROPIC_API_KEY` | claude-3-haiku-20240307 |
|
|
181
|
+
| 3 | Ollama running locally | ollama/llama3.2 |
|
|
182
|
+
|
|
183
|
+
Override with `--model`:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
aeo-cli generate example.com --model gpt-4o
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Industry Profiles
|
|
190
|
+
|
|
191
|
+
Tailor the output with `--profile`:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
aeo-cli generate example.com --profile saas
|
|
195
|
+
aeo-cli generate example.com --profile ecommerce
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Available: `generic`, `cpg`, `saas`, `ecommerce`, `blog`.
|
|
199
|
+
|
|
200
|
+
## GitHub Action
|
|
201
|
+
|
|
202
|
+
Use AEO-CLI in your CI pipeline:
|
|
203
|
+
|
|
204
|
+
```yaml
|
|
205
|
+
- name: Run AEO Audit
|
|
206
|
+
uses: hanselhansel/aeo-cli@main
|
|
207
|
+
with:
|
|
208
|
+
url: 'https://your-site.com'
|
|
209
|
+
fail-under: '60'
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
The action sets up Python, installs aeo-cli, and runs the audit. Outputs `score` and `report-json` for downstream steps. See [docs/ci-integration.md](docs/ci-integration.md) for full documentation.
|
|
213
|
+
|
|
214
|
+
## Score Breakdown
|
|
215
|
+
|
|
216
|
+
AEO-CLI returns a score from 0 to 100, composed of four pillars:
|
|
217
|
+
|
|
218
|
+
| Pillar | Max Points | What it measures |
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| Content density | 40 | Quality and depth of extractable text content |
|
|
221
|
+
| Robots.txt AI bot access | 25 | Whether AI crawlers are allowed in robots.txt |
|
|
222
|
+
| Schema.org JSON-LD | 25 | Structured data markup (Product, Article, FAQ, etc.) |
|
|
223
|
+
| llms.txt presence | 10 | Whether a /llms.txt file exists for LLM guidance |
|
|
224
|
+
|
|
225
|
+
### Scoring rationale (2026-02-18)
|
|
226
|
+
|
|
227
|
+
The weights reflect how AI search engines (ChatGPT, Perplexity, Claude) actually consume web content:
|
|
228
|
+
|
|
229
|
+
- **Content density (40 pts)** is weighted highest because it's what LLMs extract and cite when answering questions. Rich, well-structured content with headings and lists gives AI better material to work with.
|
|
230
|
+
- **Robots.txt (25 pts)** is the gatekeeper — if a bot is blocked, it literally cannot crawl. It's critical but largely binary (either you're blocking or you're not).
|
|
231
|
+
- **Schema.org (25 pts)** provides structured "cheat sheets" that help AI understand entities (products, articles, organizations). Valuable but not required for citation.
|
|
232
|
+
- **llms.txt (10 pts)** is an emerging standard. No major AI search engine heavily weights it yet, but it signals forward-thinking AI readiness.
|
|
233
|
+
|
|
234
|
+
## AI Bots Checked
|
|
235
|
+
|
|
236
|
+
AEO-CLI checks access rules for these AI crawlers:
|
|
237
|
+
|
|
238
|
+
- GPTBot
|
|
239
|
+
- ChatGPT-User
|
|
240
|
+
- Google-Extended
|
|
241
|
+
- ClaudeBot
|
|
242
|
+
- PerplexityBot
|
|
243
|
+
- Amazonbot
|
|
244
|
+
- OAI-SearchBot
|
|
245
|
+
|
|
246
|
+
## Development
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
# Install with dev dependencies
|
|
250
|
+
pip install -e ".[dev]"
|
|
251
|
+
|
|
252
|
+
# Run tests
|
|
253
|
+
pytest
|
|
254
|
+
|
|
255
|
+
# Lint
|
|
256
|
+
ruff check src/ tests/
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## License
|
|
260
|
+
|
|
261
|
+
MIT
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "aeo-cli"
|
|
7
|
+
version = "0.2.1"
|
|
8
|
+
description = "Agentic Engine Optimization CLI — audit URLs for AI crawler readiness"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Hansel Wahjono" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["aeo", "seo", "ai", "llm", "crawler", "audit", "robots-txt", "schema-org"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Environment :: Console",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
25
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
26
|
+
"Typing :: Typed",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
dependencies = [
|
|
30
|
+
"typer>=0.9",
|
|
31
|
+
"rich>=13.0",
|
|
32
|
+
"httpx>=0.27",
|
|
33
|
+
"beautifulsoup4>=4.12",
|
|
34
|
+
"pydantic>=2.0",
|
|
35
|
+
"crawl4ai>=0.4",
|
|
36
|
+
"fastmcp>=2.0",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/hanselhansel/aeo-cli"
|
|
41
|
+
Repository = "https://github.com/hanselhansel/aeo-cli"
|
|
42
|
+
Issues = "https://github.com/hanselhansel/aeo-cli/issues"
|
|
43
|
+
|
|
44
|
+
[project.optional-dependencies]
|
|
45
|
+
generate = [
|
|
46
|
+
"litellm>=1.40",
|
|
47
|
+
]
|
|
48
|
+
dev = [
|
|
49
|
+
"pytest>=8.0",
|
|
50
|
+
"pytest-asyncio>=0.23",
|
|
51
|
+
"pytest-cov>=5.0",
|
|
52
|
+
"mypy>=1.10",
|
|
53
|
+
"ruff>=0.4",
|
|
54
|
+
"litellm>=1.40",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
[project.scripts]
|
|
58
|
+
aeo-cli = "aeo_cli.main:app"
|
|
59
|
+
|
|
60
|
+
[tool.setuptools.packages.find]
|
|
61
|
+
where = ["src"]
|
|
62
|
+
|
|
63
|
+
[tool.ruff]
|
|
64
|
+
line-length = 100
|
|
65
|
+
target-version = "py310"
|
|
66
|
+
|
|
67
|
+
[tool.ruff.lint]
|
|
68
|
+
select = ["E", "F", "I", "W"]
|
|
69
|
+
|
|
70
|
+
[tool.pytest.ini_options]
|
|
71
|
+
asyncio_mode = "auto"
|
|
72
|
+
testpaths = ["tests"]
|
|
73
|
+
addopts = "--cov=aeo_cli --cov-report=term-missing --cov-report=html"
|
|
74
|
+
|
|
75
|
+
[tool.coverage.run]
|
|
76
|
+
source = ["src/aeo_cli"]
|
|
77
|
+
omit = ["src/aeo_cli/__init__.py"]
|
|
78
|
+
|
|
79
|
+
[tool.coverage.report]
|
|
80
|
+
exclude_lines = [
|
|
81
|
+
"pragma: no cover",
|
|
82
|
+
"if __name__ == .__main__.",
|
|
83
|
+
"if TYPE_CHECKING:",
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
[tool.mypy]
|
|
87
|
+
python_version = "3.10"
|
|
88
|
+
warn_return_any = true
|
|
89
|
+
warn_unused_configs = true
|
|
90
|
+
disallow_untyped_defs = false
|
|
91
|
+
check_untyped_defs = true
|
|
92
|
+
plugins = ["pydantic.mypy"]
|
|
93
|
+
|
|
94
|
+
[[tool.mypy.overrides]]
|
|
95
|
+
module = ["crawl4ai.*", "bs4.*", "litellm.*"]
|
|
96
|
+
ignore_missing_imports = true
|
aeo_cli-0.2.1/setup.cfg
ADDED
|
File without changes
|