sellerclaw-cli 0.0.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.
- sellerclaw_cli-0.0.0/.gitignore +9 -0
- sellerclaw_cli-0.0.0/PKG-INFO +537 -0
- sellerclaw_cli-0.0.0/README.md +506 -0
- sellerclaw_cli-0.0.0/pyproject.toml +95 -0
- sellerclaw_cli-0.0.0/scripts/gen_cli_commands.py +370 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/__init__.py +10 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/__main__.py +6 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/_auth.py +78 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/_client.py +157 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/_config.py +82 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/_errors.py +39 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/_generated/.gitkeep +0 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/_output.py +79 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/_runtime.py +69 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/_spec.json +21413 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/_spec.py +70 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/cli.py +51 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/__init__.py +1 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/_auth_cli.py +111 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/_generic.py +94 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/_index.py +28 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_auth.py +48 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_chat.py +40 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_connection.py +79 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_context.py +46 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_goals.py +281 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_hooks.py +28 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_orders.py +52 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_products.py +51 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_sales_channels.py +39 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/ebay_listings.py +53 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/ebay_orders.py +48 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/ebay_shop.py +73 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/facebook_ads.py +225 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/google_ads.py +183 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/listing_sync.py +27 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/research_catalog.py +27 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/research_seo.py +126 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/research_social.py +158 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/research_trends.py +104 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/research_web_search.py +27 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/stores.py +533 -0
- sellerclaw_cli-0.0.0/sellerclaw_cli/commands/suppliers.py +171 -0
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sellerclaw-cli
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: Command-line client for the SellerClaw Agent API — LLM-friendly JSON output, device-flow auth, auto-generated from OpenAPI.
|
|
5
|
+
Project-URL: Homepage, https://sellerclaw.com
|
|
6
|
+
Project-URL: Repository, https://github.com/sellerclaw/sellerclaw
|
|
7
|
+
Project-URL: Issues, https://github.com/sellerclaw/sellerclaw/issues
|
|
8
|
+
Author: SellerClaw
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: agent,cli,ecommerce,llm,sellerclaw
|
|
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
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
20
|
+
Classifier: Topic :: Utilities
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: attrs>=24.2.0
|
|
23
|
+
Requires-Dist: httpx>=0.28.0
|
|
24
|
+
Requires-Dist: pydantic>=2.11.0
|
|
25
|
+
Requires-Dist: python-dateutil>=2.9.0
|
|
26
|
+
Requires-Dist: pyyaml>=6.0
|
|
27
|
+
Requires-Dist: tomli-w>=1.0.0
|
|
28
|
+
Requires-Dist: typer>=0.15.0
|
|
29
|
+
Provides-Extra: mcp
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# sellerclaw-cli
|
|
33
|
+
|
|
34
|
+
Command-line client for the [SellerClaw](https://sellerclaw.com) Agent API.
|
|
35
|
+
|
|
36
|
+
`sellerclaw-cli` is designed to be driven either directly from a terminal or, more commonly, as a subprocess by automation and LLM agents. Every command:
|
|
37
|
+
|
|
38
|
+
- returns structured **JSON on stdout** on success,
|
|
39
|
+
- returns structured **JSON on stderr** on failure,
|
|
40
|
+
- exits with a **stable, categorical exit code**,
|
|
41
|
+
- reads credentials only from env / config file — **never** from argv.
|
|
42
|
+
|
|
43
|
+
Every documented endpoint of the SellerClaw Agent API is reachable: the CLI's typed subcommands are generated from the API's OpenAPI schema, so there are no hand-written wrappers that can fall behind.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Table of contents
|
|
48
|
+
|
|
49
|
+
- [Requirements](#requirements)
|
|
50
|
+
- [Installation](#installation)
|
|
51
|
+
- [Quick start](#quick-start)
|
|
52
|
+
- [Configuration](#configuration)
|
|
53
|
+
- [Environment variables](#environment-variables)
|
|
54
|
+
- [Config file](#config-file)
|
|
55
|
+
- [Priority / resolution order](#priority--resolution-order)
|
|
56
|
+
- [Inspecting the current config](#inspecting-the-current-config)
|
|
57
|
+
- [Authentication](#authentication)
|
|
58
|
+
- [Device flow (recommended)](#device-flow-recommended)
|
|
59
|
+
- [Email + password](#email--password)
|
|
60
|
+
- [Manual token](#manual-token)
|
|
61
|
+
- [Logging out](#logging-out)
|
|
62
|
+
- [Using the CLI](#using-the-cli)
|
|
63
|
+
- [Command structure](#command-structure)
|
|
64
|
+
- [Typed commands (per tag)](#typed-commands-per-tag)
|
|
65
|
+
- [Generic `call` / `list-operations`](#generic-call--list-operations)
|
|
66
|
+
- [Passing request bodies](#passing-request-bodies)
|
|
67
|
+
- [Output formats](#output-formats)
|
|
68
|
+
- [Output contract](#output-contract)
|
|
69
|
+
- [Success shape](#success-shape)
|
|
70
|
+
- [Error shape](#error-shape)
|
|
71
|
+
- [Exit codes](#exit-codes)
|
|
72
|
+
- [Retry behavior](#retry-behavior)
|
|
73
|
+
- [Using from scripts and LLM agents](#using-from-scripts-and-llm-agents)
|
|
74
|
+
- [Environment variables reference](#environment-variables-reference)
|
|
75
|
+
- [Troubleshooting](#troubleshooting)
|
|
76
|
+
- [Uninstall](#uninstall)
|
|
77
|
+
- [Development](#development)
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Requirements
|
|
82
|
+
|
|
83
|
+
- Python **3.11+** (3.11, 3.12, 3.13 are all tested in CI).
|
|
84
|
+
- Linux, macOS, or Windows (POSIX file-permission handling applies only on Linux/macOS).
|
|
85
|
+
- Network access to your SellerClaw Agent API endpoint.
|
|
86
|
+
|
|
87
|
+
## Installation
|
|
88
|
+
|
|
89
|
+
Install from PyPI:
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
pip install sellerclaw-cli
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
or with [`uv`](https://docs.astral.sh/uv/):
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
uv pip install sellerclaw-cli
|
|
99
|
+
# or, to install as a tool you can run anywhere:
|
|
100
|
+
uv tool install sellerclaw-cli
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Verify the install:
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
sellerclaw --version
|
|
107
|
+
# 0.1.0
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The installed binary is `sellerclaw` (not `sellerclaw-cli`).
|
|
111
|
+
|
|
112
|
+
## Quick start
|
|
113
|
+
|
|
114
|
+
```sh
|
|
115
|
+
# 1. Install
|
|
116
|
+
pip install sellerclaw-cli
|
|
117
|
+
|
|
118
|
+
# 2. Authenticate (opens a URL + code you confirm in a browser)
|
|
119
|
+
sellerclaw auth login
|
|
120
|
+
|
|
121
|
+
# 3. Call an endpoint
|
|
122
|
+
sellerclaw stores list-listings <STORE_ID> --status active --limit 5
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
That's it. See below for details on configuration, other auth flows, and output conventions.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Configuration
|
|
130
|
+
|
|
131
|
+
The CLI needs two pieces of configuration:
|
|
132
|
+
|
|
133
|
+
- **`api_url`** — base URL of the Agent API (default: `https://api.sellerclaw.com`).
|
|
134
|
+
- **`token`** — your personal `sca_…` agent token used for `Authorization: Bearer …` on every request.
|
|
135
|
+
|
|
136
|
+
Both can be supplied either via environment variables or via a config file.
|
|
137
|
+
|
|
138
|
+
### Environment variables
|
|
139
|
+
|
|
140
|
+
| Variable | Purpose | Default |
|
|
141
|
+
| --- | --- | --- |
|
|
142
|
+
| `SELLERCLAW_TOKEN` | Agent token (`sca_…`). Always sent as `Authorization: Bearer <token>`. | *(none)* |
|
|
143
|
+
| `SELLERCLAW_API_URL` | Base URL of the Agent API. | `https://api.sellerclaw.com` |
|
|
144
|
+
| `XDG_CONFIG_HOME` | Base dir for the config file (standard XDG behavior). | `~/.config` |
|
|
145
|
+
|
|
146
|
+
Example:
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
export SELLERCLAW_TOKEN="sca_abc123..."
|
|
150
|
+
export SELLERCLAW_API_URL="https://api.example.com"
|
|
151
|
+
sellerclaw auth whoami
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Config file
|
|
155
|
+
|
|
156
|
+
The config file is a small TOML file stored at:
|
|
157
|
+
|
|
158
|
+
- `$XDG_CONFIG_HOME/sellerclaw/config.toml` if `XDG_CONFIG_HOME` is set, otherwise
|
|
159
|
+
- `~/.config/sellerclaw/config.toml`.
|
|
160
|
+
|
|
161
|
+
Format:
|
|
162
|
+
|
|
163
|
+
```toml
|
|
164
|
+
api_url = "https://api.example.com"
|
|
165
|
+
token = "sca_abc123..."
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Either key is optional. The file is created automatically by `sellerclaw auth login` / `sellerclaw auth logout`, with mode `0600` (owner read/write only) on POSIX systems.
|
|
169
|
+
|
|
170
|
+
You can also create or edit the file by hand:
|
|
171
|
+
|
|
172
|
+
```sh
|
|
173
|
+
mkdir -p ~/.config/sellerclaw
|
|
174
|
+
cat > ~/.config/sellerclaw/config.toml <<'EOF'
|
|
175
|
+
api_url = "https://api.example.com"
|
|
176
|
+
token = "sca_abc123..."
|
|
177
|
+
EOF
|
|
178
|
+
chmod 600 ~/.config/sellerclaw/config.toml
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Priority / resolution order
|
|
182
|
+
|
|
183
|
+
For each of `api_url` and `token`, the CLI picks the **first** non-empty source, resolved independently:
|
|
184
|
+
|
|
185
|
+
1. Environment variable (`SELLERCLAW_API_URL`, `SELLERCLAW_TOKEN`).
|
|
186
|
+
2. Key in `config.toml` (`api_url`, `token`).
|
|
187
|
+
3. Built-in default (`api_url = https://api.sellerclaw.com`; no default token).
|
|
188
|
+
|
|
189
|
+
This means you can, for example, keep `api_url` in the config file and inject the token only via env — handy for CI and container workflows:
|
|
190
|
+
|
|
191
|
+
```sh
|
|
192
|
+
# ~/.config/sellerclaw/config.toml has only api_url
|
|
193
|
+
SELLERCLAW_TOKEN="$CI_TOKEN" sellerclaw stores list-listings "$STORE_ID"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Inspecting the current config
|
|
197
|
+
|
|
198
|
+
```sh
|
|
199
|
+
sellerclaw auth whoami
|
|
200
|
+
# {"data":{"authenticated":true,"api_url":"https://api.example.com","config_path":"/home/you/.config/sellerclaw/config.toml"}}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`authenticated: true` means a token is configured (it is not validated against the server — make any real call to verify).
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Authentication
|
|
208
|
+
|
|
209
|
+
### Device flow (recommended)
|
|
210
|
+
|
|
211
|
+
Best for interactive use on your own machine:
|
|
212
|
+
|
|
213
|
+
```sh
|
|
214
|
+
sellerclaw auth login
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The CLI prints a URL and a short code **to stderr** (so it never pollutes a stdout pipeline):
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
Open https://sellerclaw.com/activate
|
|
221
|
+
Enter the code: ABCD-1234
|
|
222
|
+
(waiting up to 600s, polling every 5s...)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Open the URL in a browser, paste the code, confirm. The CLI polls the API until the token is granted, then writes it to the config file. On success, stdout gets:
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
{"data":{"authenticated":true,"api_url":"https://api.sellerclaw.com","config_path":"/home/you/.config/sellerclaw/config.toml"}}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Email + password
|
|
232
|
+
|
|
233
|
+
```sh
|
|
234
|
+
sellerclaw auth login --password
|
|
235
|
+
# Email: you@example.com
|
|
236
|
+
# Password: ********
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
When stdin is not a TTY (e.g. piped), supply two lines — email, then password:
|
|
240
|
+
|
|
241
|
+
```sh
|
|
242
|
+
printf '%s\n%s\n' "you@example.com" "$PASSWORD" \
|
|
243
|
+
| sellerclaw auth login --password
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Password is never echoed and never appears in argv or environment.
|
|
247
|
+
|
|
248
|
+
### Manual token
|
|
249
|
+
|
|
250
|
+
If you already have an `sca_…` token (for example, provisioned by a backoffice tool), just put it into the config file or export the env var:
|
|
251
|
+
|
|
252
|
+
```sh
|
|
253
|
+
export SELLERCLAW_TOKEN="sca_abc123..."
|
|
254
|
+
# OR
|
|
255
|
+
echo 'token = "sca_abc123..."' >> ~/.config/sellerclaw/config.toml
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Logging out
|
|
259
|
+
|
|
260
|
+
```sh
|
|
261
|
+
sellerclaw auth logout
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Removes the `token` key from the config file. The `api_url` setting (and anything else in the file) is preserved.
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Using the CLI
|
|
269
|
+
|
|
270
|
+
### Command structure
|
|
271
|
+
|
|
272
|
+
```
|
|
273
|
+
sellerclaw [GLOBAL OPTIONS] <group> <command> [COMMAND ARGS]
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Discover what's available:
|
|
277
|
+
|
|
278
|
+
```sh
|
|
279
|
+
sellerclaw --help # list top-level groups
|
|
280
|
+
sellerclaw <group> --help # list commands in a group
|
|
281
|
+
sellerclaw <group> <command> --help # show args + options for one command
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Typed commands (per tag)
|
|
285
|
+
|
|
286
|
+
Each OpenAPI **tag** becomes a top-level group (`stores`, `ebay-listings`, `research-seo`, `agent-goals`, …), and each **operation** within that tag becomes a subcommand. Path parameters are positional, query parameters are flags:
|
|
287
|
+
|
|
288
|
+
```sh
|
|
289
|
+
# GET /agent/stores/{store_id}/listings?status=...&limit=...
|
|
290
|
+
sellerclaw stores list-listings <STORE_ID> --status active --limit 10
|
|
291
|
+
|
|
292
|
+
# GET /agent/ebay/listings/{listing_id}
|
|
293
|
+
sellerclaw ebay-listings get <LISTING_ID>
|
|
294
|
+
|
|
295
|
+
# POST /agent/research/seo/keyword-ideas
|
|
296
|
+
sellerclaw research-seo keyword-ideas --seed widgets
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Use `--help` on any command to see its exact arguments — the help text comes straight from the OpenAPI summary and schema.
|
|
300
|
+
|
|
301
|
+
### Generic `call` / `list-operations`
|
|
302
|
+
|
|
303
|
+
If you know the OpenAPI `operationId` directly, or you're hitting an endpoint that hasn't been promoted to a typed subcommand, use the generic fallback:
|
|
304
|
+
|
|
305
|
+
```sh
|
|
306
|
+
# List every operation in the bundled OpenAPI snapshot
|
|
307
|
+
sellerclaw list-operations
|
|
308
|
+
|
|
309
|
+
# Filter by tag
|
|
310
|
+
sellerclaw list-operations --tag stores
|
|
311
|
+
|
|
312
|
+
# Invoke by operation_id, supply path/query/body manually
|
|
313
|
+
sellerclaw call list_listings \
|
|
314
|
+
--path-param store_id=<STORE_ID> \
|
|
315
|
+
--query-param status=active \
|
|
316
|
+
--query-param limit=10
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
`--path-param` and `--query-param` are repeatable; both use `KEY=VALUE` syntax.
|
|
320
|
+
|
|
321
|
+
### Passing request bodies
|
|
322
|
+
|
|
323
|
+
Any command whose OpenAPI operation has a `requestBody` accepts `--json-body` (short: `-b`). It supports three sources:
|
|
324
|
+
|
|
325
|
+
```sh
|
|
326
|
+
# 1. Literal JSON on the command line
|
|
327
|
+
sellerclaw stores publish-shopify-products <STORE_ID> \
|
|
328
|
+
--json-body '{"ids": ["l1", "l2"]}'
|
|
329
|
+
|
|
330
|
+
# 2. File
|
|
331
|
+
sellerclaw stores create-shopify-products <STORE_ID> \
|
|
332
|
+
--json-body @./product.json
|
|
333
|
+
|
|
334
|
+
# 3. Stdin (use @- as the value)
|
|
335
|
+
cat product.json | sellerclaw stores create-shopify-products <STORE_ID> \
|
|
336
|
+
--json-body @-
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
The body is validated as JSON locally before any network call; invalid JSON exits with a `user_error` (exit 1).
|
|
340
|
+
|
|
341
|
+
### Output formats
|
|
342
|
+
|
|
343
|
+
`--format` is a **global** option (before the subcommand), defaulting to `json`:
|
|
344
|
+
|
|
345
|
+
| Value | Description |
|
|
346
|
+
| --- | --- |
|
|
347
|
+
| `json` (default) | Compact, single-line JSON. Ideal for pipelines (`jq`, LLM tools, scripts). |
|
|
348
|
+
| `pretty` | Indented JSON (2 spaces). Still valid JSON. |
|
|
349
|
+
| `yaml` | YAML. |
|
|
350
|
+
| `table` | ASCII table when the payload is a list of flat dicts; falls back to pretty JSON otherwise. |
|
|
351
|
+
|
|
352
|
+
```sh
|
|
353
|
+
sellerclaw --format pretty stores list-listings <STORE_ID>
|
|
354
|
+
sellerclaw --format yaml stores list-listings <STORE_ID>
|
|
355
|
+
sellerclaw --format table stores list-listings <STORE_ID>
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
**Errors are always compact JSON on stderr**, regardless of `--format`. Downstream error parsers can rely on a single stable shape.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Output contract
|
|
363
|
+
|
|
364
|
+
### Success shape
|
|
365
|
+
|
|
366
|
+
On exit code `0`, stdout contains exactly one JSON value (plus a trailing newline):
|
|
367
|
+
|
|
368
|
+
```json
|
|
369
|
+
{"data": <payload>}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
`<payload>` is whatever the API returned for that endpoint — a single object, a list, a primitive, or `null`.
|
|
373
|
+
|
|
374
|
+
### Error shape
|
|
375
|
+
|
|
376
|
+
On any non-zero exit, stderr contains exactly one JSON value:
|
|
377
|
+
|
|
378
|
+
```json
|
|
379
|
+
{
|
|
380
|
+
"error": {
|
|
381
|
+
"code": "auth_error",
|
|
382
|
+
"message": "Unauthorized",
|
|
383
|
+
"status": 401,
|
|
384
|
+
"details": { /* optional, parsed from the API response body */ },
|
|
385
|
+
"hint": "Run `sellerclaw auth login` to authenticate."
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Field presence:
|
|
391
|
+
|
|
392
|
+
- `code` and `message` — always present.
|
|
393
|
+
- `status` — present when the error originated from an HTTP response.
|
|
394
|
+
- `details` — present when the API returned a structured error body.
|
|
395
|
+
- `hint` — present for `auth_error` (currently always points at `sellerclaw auth login`).
|
|
396
|
+
|
|
397
|
+
### Exit codes
|
|
398
|
+
|
|
399
|
+
| Code | Meaning | Typical triggers |
|
|
400
|
+
| --- | --- | --- |
|
|
401
|
+
| `0` | Success | any 2xx |
|
|
402
|
+
| `1` | User error | invalid CLI args, invalid JSON body, 4xx (non-auth), unknown `operation_id` |
|
|
403
|
+
| `2` | Server / network error | 5xx after retries, connection refused, timeout |
|
|
404
|
+
| `3` | Auth error | 401, 403, missing token |
|
|
405
|
+
|
|
406
|
+
These are stable and categorical — scripts can switch on them without parsing stderr.
|
|
407
|
+
|
|
408
|
+
### Retry behavior
|
|
409
|
+
|
|
410
|
+
The CLI transparently retries up to **3 attempts** on these conditions:
|
|
411
|
+
|
|
412
|
+
- HTTP status `429`, `502`, `503`, `504`
|
|
413
|
+
- Transient transport errors: `ConnectError`, `ReadError`, `WriteError`, timeouts
|
|
414
|
+
|
|
415
|
+
Backoff between retries is exponential with a small jitter, capped at 10 seconds. When the server sends a `Retry-After` header (seconds), the CLI honors it exactly (no extra jitter on top). All other statuses and unknown httpx errors are returned immediately — no retries.
|
|
416
|
+
|
|
417
|
+
Requests time out after **30 seconds** by default.
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Using from scripts and LLM agents
|
|
422
|
+
|
|
423
|
+
The CLI was designed specifically to be wrapped as a subprocess. Conventions that make that robust:
|
|
424
|
+
|
|
425
|
+
- **Pure JSON on stdout.** No progress bars, no log lines, no `rich` decoration leaking from stdout. Anything human-facing (login prompts, device-flow URL) is on stderr only.
|
|
426
|
+
- **Pure JSON on stderr** on failure, with a stable shape.
|
|
427
|
+
- **Categorical exit codes.** You can branch on `returncode` without touching stderr.
|
|
428
|
+
- **No credentials in argv.** Even if you see a new CLI flag in the future, credentials will never be one of them. Pass them via env.
|
|
429
|
+
- **No interactive prompts in non-TTY mode.** `auth login --password` reads from piped stdin; every other command just runs.
|
|
430
|
+
|
|
431
|
+
Minimal Python wrapper:
|
|
432
|
+
|
|
433
|
+
```python
|
|
434
|
+
import json, os, subprocess
|
|
435
|
+
|
|
436
|
+
def run(*args, token=None, timeout=60):
|
|
437
|
+
env = {**os.environ}
|
|
438
|
+
if token:
|
|
439
|
+
env["SELLERCLAW_TOKEN"] = token
|
|
440
|
+
r = subprocess.run(
|
|
441
|
+
["sellerclaw", *args],
|
|
442
|
+
env=env,
|
|
443
|
+
capture_output=True,
|
|
444
|
+
text=True,
|
|
445
|
+
timeout=timeout,
|
|
446
|
+
)
|
|
447
|
+
if r.returncode == 0:
|
|
448
|
+
return json.loads(r.stdout)["data"]
|
|
449
|
+
|
|
450
|
+
err = json.loads(r.stderr)["error"]
|
|
451
|
+
if r.returncode == 3:
|
|
452
|
+
raise AuthError(err["message"]) # refresh token, retry
|
|
453
|
+
if r.returncode == 2:
|
|
454
|
+
raise TransientError(err["message"]) # safe to retry with backoff
|
|
455
|
+
raise UserError(err["message"], details=err.get("details"))
|
|
456
|
+
|
|
457
|
+
stores = run("stores", "list-listings", store_id, "--status", "active", token=my_token)
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
Minimal shell wrapper:
|
|
461
|
+
|
|
462
|
+
```sh
|
|
463
|
+
if out=$(sellerclaw stores list-listings "$STORE_ID" --status active 2>err.json); then
|
|
464
|
+
echo "$out" | jq '.data'
|
|
465
|
+
else
|
|
466
|
+
code=$?
|
|
467
|
+
jq '.error' err.json
|
|
468
|
+
case $code in
|
|
469
|
+
3) echo "auth failed — refresh token" ;;
|
|
470
|
+
2) echo "transient — retry later" ;;
|
|
471
|
+
*) echo "fatal" ;;
|
|
472
|
+
esac
|
|
473
|
+
exit $code
|
|
474
|
+
fi
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## Environment variables reference
|
|
480
|
+
|
|
481
|
+
| Variable | Read by | Purpose |
|
|
482
|
+
| --- | --- | --- |
|
|
483
|
+
| `SELLERCLAW_TOKEN` | every command | Agent token, sent as `Authorization: Bearer <token>`. Highest priority. |
|
|
484
|
+
| `SELLERCLAW_API_URL` | every command | Base URL of the Agent API. Overrides config file and default. |
|
|
485
|
+
| `XDG_CONFIG_HOME` | `auth *`, `whoami` | Base dir for the config file. Defaults to `~/.config`. |
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
## Troubleshooting
|
|
490
|
+
|
|
491
|
+
**`{"error":{"code":"auth_error",…,"status":401,…}}` / exit 3**
|
|
492
|
+
No token found, or token is wrong / expired. Run `sellerclaw auth login`, or check `sellerclaw auth whoami` to see which sources are in play and what `api_url` the CLI is targeting.
|
|
493
|
+
|
|
494
|
+
**`{"error":{"code":"network_error",…}}` / exit 2**
|
|
495
|
+
Can't reach the API. Verify `SELLERCLAW_API_URL` / config `api_url`, DNS, firewall. The CLI already retries transient failures 3× with backoff — a persistent `network_error` usually indicates a misconfigured URL or blocked egress.
|
|
496
|
+
|
|
497
|
+
**`{"error":{"code":"server_error",…,"status":5xx}}` / exit 2**
|
|
498
|
+
API itself returned 5xx after the CLI retried. If it persists, the platform is having an incident; otherwise retry later.
|
|
499
|
+
|
|
500
|
+
**`{"error":{"code":"user_error","message":"unknown operation_id: …"}}`**
|
|
501
|
+
The generic `sellerclaw call <id>` can't find that `operation_id` in the bundled OpenAPI snapshot. Use `sellerclaw list-operations` to see what's available in your installed version; upgrade the package if the endpoint is newer.
|
|
502
|
+
|
|
503
|
+
**`{"error":{"code":"user_error","message":"missing required path parameter(s): …"}}`**
|
|
504
|
+
You invoked `sellerclaw call` without supplying all `--path-param KEY=VALUE` entries required by the URL template.
|
|
505
|
+
|
|
506
|
+
**`sellerclaw: command not found` after `pip install`**
|
|
507
|
+
The install directory isn't on `PATH`. On many systems `pip install --user` installs into `~/.local/bin`; add that to `PATH` or use `pipx install sellerclaw-cli` / `uv tool install sellerclaw-cli` which handle it for you.
|
|
508
|
+
|
|
509
|
+
**My config file keeps getting ignored**
|
|
510
|
+
Check `sellerclaw auth whoami` — the `config_path` it prints is the one it reads. Common causes: `XDG_CONFIG_HOME` pointing somewhere unexpected, or a typo in the TOML (it must be `api_url` and `token`, lowercase, at the top level).
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## Uninstall
|
|
515
|
+
|
|
516
|
+
```sh
|
|
517
|
+
pip uninstall sellerclaw-cli
|
|
518
|
+
# optional — remove config + token
|
|
519
|
+
rm -rf ~/.config/sellerclaw
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## Development
|
|
525
|
+
|
|
526
|
+
This package lives in [`packages/sellerclaw-cli/`](.) of the main SellerClaw monorepo. Commands and the OpenAPI snapshot bundled into the package are **generated** from the backend's `openapi/agent.json`; do not hand-edit files under `sellerclaw_cli/commands/` or `sellerclaw_cli/_spec.json`.
|
|
527
|
+
|
|
528
|
+
From the repo root:
|
|
529
|
+
|
|
530
|
+
```sh
|
|
531
|
+
make cli-sync # regenerate commands/*.py + _spec.json from openapi/agent.json
|
|
532
|
+
make cli-lint # ruff + pyright
|
|
533
|
+
make cli-test # unit tests (pytest + respx)
|
|
534
|
+
make cli-build # build wheel + sdist
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
CI enforces zero drift between `openapi/agent.json` and the generated files. Releases are triggered by pushing a `cli-X.Y.Z` tag.
|