sv-cli 0.3.0__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.
- sv_cli-0.3.0/.github/ISSUE_TEMPLATE/bug_report.md +20 -0
- sv_cli-0.3.0/.github/ISSUE_TEMPLATE/feature_request.md +12 -0
- sv_cli-0.3.0/.github/workflows/publish.yml +51 -0
- sv_cli-0.3.0/.github/workflows/release.yml +24 -0
- sv_cli-0.3.0/.github/workflows/test.yml +22 -0
- sv_cli-0.3.0/.gitignore +32 -0
- sv_cli-0.3.0/AGENT.md +391 -0
- sv_cli-0.3.0/CHANGELOG.md +33 -0
- sv_cli-0.3.0/CODE_OF_CONDUCT.md +5 -0
- sv_cli-0.3.0/CONTRIBUTING.md +32 -0
- sv_cli-0.3.0/LICENSE +21 -0
- sv_cli-0.3.0/PKG-INFO +338 -0
- sv_cli-0.3.0/PULL_REQUEST_TEMPLATE.md +15 -0
- sv_cli-0.3.0/README.md +303 -0
- sv_cli-0.3.0/SECURITY.md +24 -0
- sv_cli-0.3.0/docs/agent-usage.md +30 -0
- sv_cli-0.3.0/docs/api-definition-format.md +37 -0
- sv_cli-0.3.0/docs/authentication.md +33 -0
- sv_cli-0.3.0/docs/commands.md +36 -0
- sv_cli-0.3.0/docs/examples.md +45 -0
- sv_cli-0.3.0/docs/installation.md +24 -0
- sv_cli-0.3.0/docs/troubleshooting.md +49 -0
- sv_cli-0.3.0/pyproject.toml +66 -0
- sv_cli-0.3.0/src/sv_cli/__init__.py +3 -0
- sv_cli-0.3.0/src/sv_cli/adapters.py +323 -0
- sv_cli-0.3.0/src/sv_cli/api_client.py +82 -0
- sv_cli-0.3.0/src/sv_cli/commands/__init__.py +0 -0
- sv_cli-0.3.0/src/sv_cli/commands/auth.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/better_keywords.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/call.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/config.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/content_quality.py +5 -0
- sv_cli-0.3.0/src/sv_cli/commands/content_transformer.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/core_analysis.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/definitions.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/geo_audit.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/insight_igniter.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/marketplace_services.py +5 -0
- sv_cli-0.3.0/src/sv_cli/commands/options.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/preliminary_audit.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/ranklens.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/seo_image.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/seo_mapping.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/seogpt.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/seogpt2.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/seogpt_compare.py +4 -0
- sv_cli-0.3.0/src/sv_cli/commands/top_competitors.py +5 -0
- sv_cli-0.3.0/src/sv_cli/commands/topical_authority.py +4 -0
- sv_cli-0.3.0/src/sv_cli/config.py +216 -0
- sv_cli-0.3.0/src/sv_cli/definitions.py +283 -0
- sv_cli-0.3.0/src/sv_cli/errors.py +55 -0
- sv_cli-0.3.0/src/sv_cli/executor.py +188 -0
- sv_cli-0.3.0/src/sv_cli/formatter.py +227 -0
- sv_cli-0.3.0/src/sv_cli/main.py +905 -0
- sv_cli-0.3.0/src/sv_cli/renderers/__init__.py +0 -0
- sv_cli-0.3.0/src/sv_cli/renderers/csv_renderer.py +9 -0
- sv_cli-0.3.0/src/sv_cli/renderers/json_renderer.py +10 -0
- sv_cli-0.3.0/src/sv_cli/renderers/markdown_renderer.py +9 -0
- sv_cli-0.3.0/src/sv_cli/renderers/table_renderer.py +9 -0
- sv_cli-0.3.0/src/sv_cli/renderers/text_renderer.py +9 -0
- sv_cli-0.3.0/src/sv_cli/resolver.py +523 -0
- sv_cli-0.3.0/src/sv_cli/schemas/__init__.py +0 -0
- sv_cli-0.3.0/src/sv_cli/schemas/api_response.py +12 -0
- sv_cli-0.3.0/src/sv_cli/schemas/config.py +13 -0
- sv_cli-0.3.0/src/sv_cli/schemas/tool_definition.py +17 -0
- sv_cli-0.3.0/src/sv_cli/tasks.py +168 -0
- sv_cli-0.3.0/src/sv_cli/utils.py +204 -0
- sv_cli-0.3.0/tests/fixtures/api_root.json +10 -0
- sv_cli-0.3.0/tests/fixtures/better_keywords_response.json +6 -0
- sv_cli-0.3.0/tests/fixtures/seogpt_definitions.json +21 -0
- sv_cli-0.3.0/tests/test_config.py +55 -0
- sv_cli-0.3.0/tests/test_definitions.py +50 -0
- sv_cli-0.3.0/tests/test_executor.py +76 -0
- sv_cli-0.3.0/tests/test_formatter.py +20 -0
- sv_cli-0.3.0/tests/test_resolver.py +69 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report a reproducible issue
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## What happened?
|
|
7
|
+
|
|
8
|
+
## Expected behavior
|
|
9
|
+
|
|
10
|
+
## Reproduction steps
|
|
11
|
+
|
|
12
|
+
## Environment
|
|
13
|
+
|
|
14
|
+
- OS:
|
|
15
|
+
- Python version:
|
|
16
|
+
- sv-cli version:
|
|
17
|
+
|
|
18
|
+
## Logs
|
|
19
|
+
|
|
20
|
+
Paste logs with API keys removed or masked.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Publish Python package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
name: Build package
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v6
|
|
15
|
+
with:
|
|
16
|
+
persist-credentials: false
|
|
17
|
+
|
|
18
|
+
- name: Set up Python
|
|
19
|
+
uses: actions/setup-python@v6
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.x"
|
|
22
|
+
|
|
23
|
+
- name: Install build
|
|
24
|
+
run: python -m pip install --upgrade build
|
|
25
|
+
|
|
26
|
+
- name: Build wheel and source distribution
|
|
27
|
+
run: python -m build
|
|
28
|
+
|
|
29
|
+
- name: Store distributions
|
|
30
|
+
uses: actions/upload-artifact@v5
|
|
31
|
+
with:
|
|
32
|
+
name: python-package-distributions
|
|
33
|
+
path: dist/
|
|
34
|
+
|
|
35
|
+
publish-to-pypi:
|
|
36
|
+
name: Publish to PyPI
|
|
37
|
+
needs: build
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
environment: pypi
|
|
40
|
+
permissions:
|
|
41
|
+
id-token: write
|
|
42
|
+
|
|
43
|
+
steps:
|
|
44
|
+
- name: Download distributions
|
|
45
|
+
uses: actions/download-artifact@v6
|
|
46
|
+
with:
|
|
47
|
+
name: python-package-distributions
|
|
48
|
+
path: dist/
|
|
49
|
+
|
|
50
|
+
- name: Publish to PyPI
|
|
51
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*.*.*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
id-token: write
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: '3.12'
|
|
19
|
+
- run: python -m pip install --upgrade pip build twine
|
|
20
|
+
- run: python -m build
|
|
21
|
+
- run: twine check dist/*
|
|
22
|
+
- uses: softprops/action-gh-release@v2
|
|
23
|
+
with:
|
|
24
|
+
files: dist/*
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
strategy:
|
|
11
|
+
matrix:
|
|
12
|
+
python-version: ['3.10', '3.11', '3.12']
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: ${{ matrix.python-version }}
|
|
18
|
+
- run: python -m pip install --upgrade pip
|
|
19
|
+
- run: pip install -e '.[dev]'
|
|
20
|
+
- run: ruff check .
|
|
21
|
+
- run: pytest
|
|
22
|
+
- run: python -m build
|
sv_cli-0.3.0/.gitignore
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
.coverage
|
|
9
|
+
htmlcov/
|
|
10
|
+
.pytest_cache/
|
|
11
|
+
.mypy_cache/
|
|
12
|
+
.ruff_cache/
|
|
13
|
+
|
|
14
|
+
# Virtual environments
|
|
15
|
+
.venv/
|
|
16
|
+
venv/
|
|
17
|
+
env/
|
|
18
|
+
|
|
19
|
+
# Secrets and local config
|
|
20
|
+
.env
|
|
21
|
+
.env.*
|
|
22
|
+
!.env.example
|
|
23
|
+
*.pem
|
|
24
|
+
*.key
|
|
25
|
+
*.token
|
|
26
|
+
config.json
|
|
27
|
+
.sv/
|
|
28
|
+
|
|
29
|
+
# OS/editor
|
|
30
|
+
.DS_Store
|
|
31
|
+
.idea/
|
|
32
|
+
.vscode/
|
sv_cli-0.3.0/AGENT.md
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
# AGENT.md — SV CLI Agent Reference
|
|
2
|
+
|
|
3
|
+
SV CLI (`sv`) is a definition-driven command-line client for the SV AI API. It resolves human-friendly flags to live API field names and enum values at runtime. This file documents the patterns, tools, and response shapes an AI agent needs to call the CLI reliably.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Authentication
|
|
8
|
+
|
|
9
|
+
Set the API key as an environment variable before all calls:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
export SV_API_KEY="your-key-here"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Alternative — inline flag (avoid in shared environments):
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
sv seogpt generate --keyword "..." --type 18 --api-key "your-key-here" --format json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Never use `sv auth set` in agent context — it is interactive.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Standard Agent Invocation Pattern
|
|
26
|
+
|
|
27
|
+
Always include these flags on every call:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
sv TOOL ACTION --FLAG VALUE --strict --no-fuzzy --non-interactive --format json
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
| Flag | Purpose |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `--strict` | Require exact enum ID or slug — no guessing |
|
|
36
|
+
| `--no-fuzzy` | Disable fuzzy matching — prevents unintended matches |
|
|
37
|
+
| `--non-interactive` | Disable all prompts — never blocks waiting for input |
|
|
38
|
+
| `--format json` | Machine-readable output — always parseable |
|
|
39
|
+
|
|
40
|
+
**`--format` placement rule:**
|
|
41
|
+
- Tool action commands (`sv seogpt generate`, `sv keywords research`, etc.) — `--format` can go anywhere
|
|
42
|
+
- `sv call`, `sv task`, `sv TOOL raw` — `--format` MUST go before the subcommand:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
sv --format json call seogpt --json '{"action":"generate","kw":"...","type":18}'
|
|
46
|
+
sv --format json task status TASK_ID --tool geo-audit
|
|
47
|
+
sv --format json seogpt raw --json '{"action":"generate","kw":"...","type":18}'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Tool Index
|
|
53
|
+
|
|
54
|
+
All 16 available tools. Use exact command names — aliases are human shortcuts.
|
|
55
|
+
|
|
56
|
+
| Command | Alias | Default Action | API Required Fields | Async |
|
|
57
|
+
|---|---|---|---|---|
|
|
58
|
+
| `better-keywords` | `keywords` | `research` / `filter` | `--keyword` (`filter` also needs `--data`) | No |
|
|
59
|
+
| `content-transformer` | `transform` | `rewrite` | `--text` | No |
|
|
60
|
+
| `core-analysis` | `core` | `analyze` | *(none required)* | No |
|
|
61
|
+
| `geo-audit` | `audit` | `create-task` | `--url` `--keyword` | Yes |
|
|
62
|
+
| `insight-igniter` | `insights` | `entities` | `--url` | No |
|
|
63
|
+
| `preliminary-audit` | `prelim-audit` | `analyze` | `--url` | No |
|
|
64
|
+
| `ranklens` | — | `rank` | `--keyword` `--url` | No |
|
|
65
|
+
| `seo-image` | `image` | `generate` | `--keyword` | No |
|
|
66
|
+
| `seogpt` | `seo-gpt` | `generate` | `--keyword` `--type` | No |
|
|
67
|
+
| `seogpt2` | `seo-gpt2` | `create-task` | `--keyword` *(= Topic)* | Yes |
|
|
68
|
+
| `seogpt-compare` | `compare` | `create-task` | `--url` `--keyword` | Yes |
|
|
69
|
+
| `seo-mapping` | `mapping` | `create-task` | `--url` `--keyword` | Yes |
|
|
70
|
+
| `topical-authority` | `topical` | `topics` | `--keyword` | No |
|
|
71
|
+
| `top-competitors` | `competitors` | `analyze` | `--keyword` | No |
|
|
72
|
+
| `marketplace-services` | `marketplace` | `search` | `--search` | No |
|
|
73
|
+
| `content-quality` | `quality` | `analyze` | `--keyword` `--url` | No |
|
|
74
|
+
|
|
75
|
+
### All actions per tool
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
better-keywords: research, filter, raw
|
|
79
|
+
content-transformer: rewrite, raw
|
|
80
|
+
core-analysis: analyze, raw
|
|
81
|
+
geo-audit: create-task, get-task-status, get-result, raw
|
|
82
|
+
insight-igniter: entities, raw
|
|
83
|
+
preliminary-audit: analyze, raw
|
|
84
|
+
ranklens: rank, competitors, raw
|
|
85
|
+
seo-image: generate, raw
|
|
86
|
+
seogpt: generate, raw
|
|
87
|
+
seogpt2: create-task, get-task-status, get-result, raw
|
|
88
|
+
seogpt-compare: create-task, get-task-status, get-result, raw
|
|
89
|
+
seo-mapping: create-task, get-task-status, get-result, raw
|
|
90
|
+
topical-authority: topics, content, raw
|
|
91
|
+
top-competitors: analyze, raw
|
|
92
|
+
marketplace-services: search, raw
|
|
93
|
+
content-quality: analyze, raw
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Enum Discovery — Always Do This Before Calling
|
|
99
|
+
|
|
100
|
+
Never guess enum values for `--type`, `--language`, `--engine`, `--theme`, etc. Discover them first.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# List all option fields for a tool
|
|
104
|
+
sv options seogpt
|
|
105
|
+
|
|
106
|
+
# List all values for a specific field
|
|
107
|
+
sv options seogpt type
|
|
108
|
+
|
|
109
|
+
# Filter values by keyword
|
|
110
|
+
sv options seogpt type --search meta
|
|
111
|
+
|
|
112
|
+
# Shorthand subcommands (where available)
|
|
113
|
+
sv seogpt types
|
|
114
|
+
sv seogpt types --search meta
|
|
115
|
+
sv seogpt languages
|
|
116
|
+
sv seogpt engines
|
|
117
|
+
sv image types
|
|
118
|
+
sv image themes
|
|
119
|
+
sv image themes --search wild
|
|
120
|
+
sv seogpt2 types
|
|
121
|
+
sv seogpt2 lengths
|
|
122
|
+
sv seogpt2 languages
|
|
123
|
+
sv seogpt2 tones
|
|
124
|
+
sv seogpt2 engines
|
|
125
|
+
sv geo-audit types
|
|
126
|
+
sv geo-audit languages
|
|
127
|
+
sv seo-mapping types
|
|
128
|
+
sv better-keywords types
|
|
129
|
+
sv better-keywords languages
|
|
130
|
+
sv content-transformer types
|
|
131
|
+
sv content-transformer languages
|
|
132
|
+
sv ranklens languages
|
|
133
|
+
sv ranklens engines
|
|
134
|
+
sv topical-authority modes
|
|
135
|
+
sv topical-authority languages
|
|
136
|
+
sv marketplace-services series
|
|
137
|
+
sv marketplace-services categories
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Options output format (use `id` or `slug` with `--strict`):
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
label slug id
|
|
144
|
+
---------------- ---------------- ---
|
|
145
|
+
Meta Description meta-description 18
|
|
146
|
+
Meta Keywords meta-keywords 180
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
With `--strict --no-fuzzy`: use `--type 18` or `--type meta-description`. Never use label strings.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## JSON Response Structure
|
|
154
|
+
|
|
155
|
+
Every response follows this envelope:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"success": true,
|
|
160
|
+
"application": "seogpt",
|
|
161
|
+
"action": "generate",
|
|
162
|
+
"data": { ... },
|
|
163
|
+
"meta": { "upstream_http_code": 200, "duration_ms": 1234, "request_id": "..." },
|
|
164
|
+
"error": null
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
On failure:
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"success": false,
|
|
172
|
+
"data": null,
|
|
173
|
+
"error": { "code": "VALIDATION_ERROR", "message": "...", "field": "..." }
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Response data shapes by type
|
|
178
|
+
|
|
179
|
+
**Content response** (`seogpt generate`, `content-transformer rewrite`, `sv meta`, `sv title`):
|
|
180
|
+
```json
|
|
181
|
+
{ "data": { "text": "generated content here" } }
|
|
182
|
+
```
|
|
183
|
+
Parse: `response["data"]["text"]`
|
|
184
|
+
|
|
185
|
+
**List response** (`better-keywords research`, `top-competitors analyze`, `marketplace-services search`, `topical-authority topics`):
|
|
186
|
+
```json
|
|
187
|
+
{ "data": [ { "keyword": "...", "volume": 1000, ... }, ... ] }
|
|
188
|
+
```
|
|
189
|
+
Parse: `response["data"]` — array of objects
|
|
190
|
+
|
|
191
|
+
**Async task created** (`geo-audit create-task`, `seogpt2 create-task`, `seogpt-compare create-task`, `seo-mapping create-task`):
|
|
192
|
+
```json
|
|
193
|
+
{ "data": { "task_id": "wFEGe...", "status": "pending", "stage": "queued", "percent_complete": 1 } }
|
|
194
|
+
```
|
|
195
|
+
Parse: `response["data"]["task_id"]`
|
|
196
|
+
|
|
197
|
+
**Task status** (`get-task-status`):
|
|
198
|
+
```json
|
|
199
|
+
{ "data": { "task_id": "...", "status": "pending|processing|complete", "percent_complete": 75 } }
|
|
200
|
+
```
|
|
201
|
+
Done when: `status` is one of `done`, `complete`, `completed`, `success`, `finished`, `ready`
|
|
202
|
+
|
|
203
|
+
**Audit/analysis response** (`core-analysis`, `preliminary-audit`, `content-quality`, `ranklens`):
|
|
204
|
+
```json
|
|
205
|
+
{ "data": { ... nested object ... } }
|
|
206
|
+
```
|
|
207
|
+
Parse: `response["data"]`
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Async Task Workflow
|
|
212
|
+
|
|
213
|
+
Three patterns — choose one per use case.
|
|
214
|
+
|
|
215
|
+
### Pattern 1: `--wait` (simplest — blocks until done)
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
sv geo-audit create-task --url https://example.com --keyword "white label seo" --wait --strict --no-fuzzy --non-interactive --format json
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Returns the final result directly. Default timeout: 600s. Override:
|
|
222
|
+
```bash
|
|
223
|
+
--wait --timeout 300 --poll-interval 10
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Pattern 2: Create then poll via `sv task`
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# Step 1 — create
|
|
230
|
+
sv geo-audit create-task --url https://example.com --keyword "white label seo" --non-interactive --format json
|
|
231
|
+
|
|
232
|
+
# Step 2 — poll status (repeat until done)
|
|
233
|
+
sv --format json task status TASK_ID --tool geo-audit
|
|
234
|
+
|
|
235
|
+
# Step 3 — get result
|
|
236
|
+
sv --format json task result TASK_ID --tool geo-audit
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
`--tool` is required if the task was not created in the same session (local cache miss).
|
|
240
|
+
|
|
241
|
+
### Pattern 3: Direct tool polling
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
sv geo-audit get-task-status --task_id TASK_ID --format json
|
|
245
|
+
sv geo-audit get-result --task_id TASK_ID --format json
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Same for `seogpt2`, `seogpt-compare`, `seo-mapping` — replace `geo-audit` with the tool name.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Critical Field Exceptions
|
|
253
|
+
|
|
254
|
+
These differ from the standard pattern — get them wrong and the call fails.
|
|
255
|
+
|
|
256
|
+
### seogpt2 — `--keyword` maps to `Topic`, not `kw`
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
# CORRECT — --keyword sends value as "Topic" API field
|
|
260
|
+
sv seogpt2 create-task --keyword "White Label SEO for Agencies" --type on-page-blog-article --wait --strict --no-fuzzy --non-interactive --format json
|
|
261
|
+
|
|
262
|
+
# WRONG — no other flag maps to Topic
|
|
263
|
+
sv seogpt2 create-task --text "..." ... # also maps to Topic, use --keyword
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### better-keywords `filter` — requires `data` array from prior `research` call
|
|
267
|
+
|
|
268
|
+
The `filter` action AI-filters a keyword list for relevance. No CLI flag maps to the `data` field — must use a raw call.
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
# Step 1 — research to get keyword array
|
|
272
|
+
sv keywords research --keyword "white label seo" --non-interactive --format json
|
|
273
|
+
# → parse response["data"] (array of keyword objects)
|
|
274
|
+
|
|
275
|
+
# Step 2 — filter using that array via raw call
|
|
276
|
+
sv --format json call better-keywords --json '{"action":"filter","kw":"white label seo","data":[{"keyword":"...","volume":1000}]}'
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### seogpt — `--contenttype` is an alias for `--type`
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
sv seogpt generate --keyword "..." --contenttype meta-description --strict --no-fuzzy --non-interactive --format json
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### ranklens `competitors` — requires `mgptid` from prior `rank` response
|
|
286
|
+
|
|
287
|
+
No CLI flag exists for `mgptid`. Must use raw call:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
# Step 1 — get MGPTID from rank response
|
|
291
|
+
sv ranklens rank --keyword "white label seo" --url https://example.com --format json
|
|
292
|
+
# → parse response["data"]["MGPTID"]
|
|
293
|
+
|
|
294
|
+
# Step 2 — pass MGPTID via raw call
|
|
295
|
+
sv --format json call ranklens --json '{"action":"competitors","mgptid":"MGPTID_VALUE","web":"https://example.com","kw":"white label seo"}'
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### `sv task status/result` — `--format` must be global
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
# CORRECT
|
|
302
|
+
sv --format json task status TASK_ID --tool geo-audit
|
|
303
|
+
|
|
304
|
+
# WRONG — --format not accepted here
|
|
305
|
+
sv task status TASK_ID --tool geo-audit --format json
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Common Errors and Recovery
|
|
311
|
+
|
|
312
|
+
| Error message | Cause | Fix |
|
|
313
|
+
|---|---|---|
|
|
314
|
+
| `Could not resolve --type "X" in strict mode` | Value is not a valid slug or ID | Run `sv options TOOL type` → use `id` or `slug` column |
|
|
315
|
+
| `Could not resolve --type "X"` (no strict) | No match found at any level | Run `sv options TOOL type --search X` to find closest match |
|
|
316
|
+
| `Topic is required` | seogpt2 called without `--keyword` | Add `--keyword "your topic"` |
|
|
317
|
+
| `task_id is invalid` | Task has expired on the server | Create a new task |
|
|
318
|
+
| `No local tool mapping found for task` | Task not in `~/.sv/tasks.json` | Add `--tool TOOL_NAME` explicitly |
|
|
319
|
+
| `API authentication failed: HTTP 401` | Bad or missing API key | Check `SV_API_KEY` environment variable |
|
|
320
|
+
| `API rate limit exceeded` | Too many requests | Wait and retry — add delay between calls |
|
|
321
|
+
| `No such option: --format` | `--format` placed after `call`/`task`/`raw` | Move `--format` before the subcommand |
|
|
322
|
+
| `Action must be rewrite` | Wrong action for content-transformer | Only `rewrite` is supported, not `summarize` |
|
|
323
|
+
| `Data must be a JSON array` | `better-keywords filter` called without `data` | Pass keyword array from prior `research` call via raw JSON |
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Raw JSON Fallback
|
|
328
|
+
|
|
329
|
+
When friendly flags are insufficient, send the payload directly. The CLI injects the API key automatically.
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
sv --format json call seogpt --json '{"action":"generate","kw":"white label seo","type":18}'
|
|
333
|
+
sv --format json call geo-audit --json '{"action":"createTask","kw":"white label seo","URL":"https://example.com"}'
|
|
334
|
+
sv --format json call ranklens --json '{"action":"competitors","mgptid":"...","web":"https://example.com","kw":"white label seo"}'
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
From a file:
|
|
338
|
+
```bash
|
|
339
|
+
sv --format json call seogpt --file payload.json
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
From stdin:
|
|
343
|
+
```bash
|
|
344
|
+
cat payload.json | sv --format json call seogpt --stdin
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## Definitions and Schema Discovery
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
sv definitions list # all available tools + endpoints
|
|
353
|
+
sv definitions show seogpt # full schema for one tool (api_input fields)
|
|
354
|
+
sv definitions refresh # force refresh from live API
|
|
355
|
+
sv options list # all tools with option set counts
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Use `sv definitions show TOOL` to inspect all API input fields before building raw payloads.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Quick Reference — One Call Per Tool
|
|
363
|
+
|
|
364
|
+
Agent-safe examples with exact IDs. Replace values as needed.
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
sv keywords research --keyword "white label seo" --strict --no-fuzzy --non-interactive --format json
|
|
368
|
+
# better-keywords filter requires keyword data from a prior research call — use raw call:
|
|
369
|
+
sv --format json call better-keywords --json '{"action":"filter","kw":"white label seo","data":[{"keyword":"white label seo","volume":1000}]}'
|
|
370
|
+
sv content-transformer rewrite --text "SEO services for agencies" --keyword "white label seo" --strict --no-fuzzy --non-interactive --format json
|
|
371
|
+
sv core-analysis analyze --url https://example.com --keyword "white label seo" --strict --no-fuzzy --non-interactive --format json
|
|
372
|
+
sv geo-audit create-task --url https://example.com --keyword "white label seo" --wait --strict --no-fuzzy --non-interactive --format json
|
|
373
|
+
sv insight-igniter entities --url https://example.com --keyword "white label seo" --strict --no-fuzzy --non-interactive --format json
|
|
374
|
+
sv preliminary-audit analyze --url https://example.com --strict --no-fuzzy --non-interactive --format json
|
|
375
|
+
sv ranklens rank --keyword "white label seo" --url https://example.com --strict --no-fuzzy --non-interactive --format json
|
|
376
|
+
sv seo-image generate --keyword "white label seo" --type 33 --strict --no-fuzzy --non-interactive --format json
|
|
377
|
+
sv seogpt generate --keyword "white label seo" --type 18 --strict --no-fuzzy --non-interactive --format json
|
|
378
|
+
sv seogpt2 create-task --keyword "White Label SEO for Agencies" --type 0 --wait --strict --no-fuzzy --non-interactive --format json
|
|
379
|
+
sv seogpt-compare create-task --url https://example.com --keyword "white label seo" --wait --strict --no-fuzzy --non-interactive --format json
|
|
380
|
+
sv seo-mapping create-task --url https://example.com --keyword "white label seo" --wait --strict --no-fuzzy --non-interactive --format json
|
|
381
|
+
sv topical-authority topics --keyword "white label seo" --strict --no-fuzzy --non-interactive --format json
|
|
382
|
+
sv top-competitors analyze --keyword "white label seo" --strict --no-fuzzy --non-interactive --format json
|
|
383
|
+
sv marketplace-services search --search "seo audit" --category SEO --strict --no-fuzzy --non-interactive --format json
|
|
384
|
+
sv content-quality analyze --keyword "white label seo" --url https://example.com --strict --no-fuzzy --non-interactive --format json
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
Common enum IDs (verify with `sv options` — these are from live API at time of writing):
|
|
388
|
+
- `seogpt --type 18` = Meta Description
|
|
389
|
+
- `seogpt --type 8` = Page Title
|
|
390
|
+
- `seo-image --type 33` = Blog Header Image
|
|
391
|
+
- `seogpt2 --type 0` = On-Page Blog Article
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
- Renamed the distribution package from `seovendor-cli` to `sv-cli`.
|
|
6
|
+
- Renamed the console executable from `seovendor` to `sv`.
|
|
7
|
+
- Renamed the Python package from `seovendor_cli` to `sv_cli`.
|
|
8
|
+
- Updated documentation, examples, config paths, cache paths, and CI references for the SV brand.
|
|
9
|
+
- Changed the preferred environment variables to `SV_API_KEY` and `SV_HOME`.
|
|
10
|
+
- Retained `SEOVENDOR_API_KEY`, `SEOVENDOR_HOME`, and `~/.seovendor/config.json` as migration fallbacks.
|
|
11
|
+
|
|
12
|
+
## 0.2.0
|
|
13
|
+
|
|
14
|
+
- Added friendly command groups for `top-competitors`, `marketplace-services`, and `content-quality`.
|
|
15
|
+
- Added adapter fallback endpoint hints for newly released tools that are live before the API root advertises them.
|
|
16
|
+
- Added marketplace-friendly `--search`, `--price`, `--series`, and `--category` options.
|
|
17
|
+
- Added URL 1/URL 2 aliases for content quality comparisons.
|
|
18
|
+
- Added dynamic extraction of enum options from `Valid values:` descriptions in API definitions.
|
|
19
|
+
|
|
20
|
+
## 0.1.0
|
|
21
|
+
|
|
22
|
+
Initial public beta scaffold.
|
|
23
|
+
|
|
24
|
+
- Dynamic API root discovery and tool definitions cache
|
|
25
|
+
- Manual definitions refresh/list/show/clear commands
|
|
26
|
+
- API-key setup with auth commands and profile support
|
|
27
|
+
- Raw API call command
|
|
28
|
+
- Human-friendly enum resolver with strict/no-fuzzy modes
|
|
29
|
+
- Friendly command groups and aliases for 13 API tools
|
|
30
|
+
- Options discovery commands and tool-specific aliases
|
|
31
|
+
- Async task polling helpers
|
|
32
|
+
- JSON, pretty, table, CSV, markdown, and text output formatters
|
|
33
|
+
- Open-source repository files and CI scaffold
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
This project follows the Contributor Covenant spirit: be respectful, constructive, and inclusive.
|
|
4
|
+
|
|
5
|
+
Unacceptable behavior includes harassment, threats, discriminatory language, or publishing private information. Maintainers may remove comments, issues, commits, or contributors that violate these expectations.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for contributing to SV CLI.
|
|
4
|
+
|
|
5
|
+
## Development setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
python -m venv .venv
|
|
9
|
+
source .venv/bin/activate
|
|
10
|
+
pip install -e '.[dev]'
|
|
11
|
+
pytest
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Guidelines
|
|
15
|
+
|
|
16
|
+
- Keep API definitions as the source of truth.
|
|
17
|
+
- Add local adapters only for friendly command names, aliases, presets, and output polish.
|
|
18
|
+
- Do not hardcode API keys or real customer data in examples, fixtures, tests, or docs.
|
|
19
|
+
- Prefer strict, predictable behavior for agent-facing changes.
|
|
20
|
+
- Add tests for resolver, caching, auth/config, output formatting, and error handling changes.
|
|
21
|
+
|
|
22
|
+
## Pull requests
|
|
23
|
+
|
|
24
|
+
Before opening a PR:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
ruff check .
|
|
28
|
+
pytest
|
|
29
|
+
python -m build
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Describe user-facing behavior, backward compatibility, and any new commands.
|
sv_cli-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SV 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.
|