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.
Files changed (43) hide show
  1. sellerclaw_cli-0.0.0/.gitignore +9 -0
  2. sellerclaw_cli-0.0.0/PKG-INFO +537 -0
  3. sellerclaw_cli-0.0.0/README.md +506 -0
  4. sellerclaw_cli-0.0.0/pyproject.toml +95 -0
  5. sellerclaw_cli-0.0.0/scripts/gen_cli_commands.py +370 -0
  6. sellerclaw_cli-0.0.0/sellerclaw_cli/__init__.py +10 -0
  7. sellerclaw_cli-0.0.0/sellerclaw_cli/__main__.py +6 -0
  8. sellerclaw_cli-0.0.0/sellerclaw_cli/_auth.py +78 -0
  9. sellerclaw_cli-0.0.0/sellerclaw_cli/_client.py +157 -0
  10. sellerclaw_cli-0.0.0/sellerclaw_cli/_config.py +82 -0
  11. sellerclaw_cli-0.0.0/sellerclaw_cli/_errors.py +39 -0
  12. sellerclaw_cli-0.0.0/sellerclaw_cli/_generated/.gitkeep +0 -0
  13. sellerclaw_cli-0.0.0/sellerclaw_cli/_output.py +79 -0
  14. sellerclaw_cli-0.0.0/sellerclaw_cli/_runtime.py +69 -0
  15. sellerclaw_cli-0.0.0/sellerclaw_cli/_spec.json +21413 -0
  16. sellerclaw_cli-0.0.0/sellerclaw_cli/_spec.py +70 -0
  17. sellerclaw_cli-0.0.0/sellerclaw_cli/cli.py +51 -0
  18. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/__init__.py +1 -0
  19. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/_auth_cli.py +111 -0
  20. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/_generic.py +94 -0
  21. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/_index.py +28 -0
  22. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_auth.py +48 -0
  23. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_chat.py +40 -0
  24. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_connection.py +79 -0
  25. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_context.py +46 -0
  26. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_goals.py +281 -0
  27. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_hooks.py +28 -0
  28. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_orders.py +52 -0
  29. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_products.py +51 -0
  30. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/agent_sales_channels.py +39 -0
  31. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/ebay_listings.py +53 -0
  32. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/ebay_orders.py +48 -0
  33. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/ebay_shop.py +73 -0
  34. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/facebook_ads.py +225 -0
  35. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/google_ads.py +183 -0
  36. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/listing_sync.py +27 -0
  37. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/research_catalog.py +27 -0
  38. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/research_seo.py +126 -0
  39. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/research_social.py +158 -0
  40. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/research_trends.py +104 -0
  41. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/research_web_search.py +27 -0
  42. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/stores.py +533 -0
  43. sellerclaw_cli-0.0.0/sellerclaw_cli/commands/suppliers.py +171 -0
@@ -0,0 +1,9 @@
1
+ .venv/
2
+ dist/
3
+ build/
4
+ *.egg-info/
5
+ __pycache__/
6
+ *.pyc
7
+ .pytest_cache/
8
+ .ruff_cache/
9
+ uv.lock
@@ -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.