cometapi-cli 0.1.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.
- cometapi_cli-0.1.0/.github/workflows/ci.yml +32 -0
- cometapi_cli-0.1.0/.github/workflows/publish.yml +30 -0
- cometapi_cli-0.1.0/.gitignore +20 -0
- cometapi_cli-0.1.0/AGENTS.md +486 -0
- cometapi_cli-0.1.0/CHANGELOG.md +46 -0
- cometapi_cli-0.1.0/LICENSE +21 -0
- cometapi_cli-0.1.0/PKG-INFO +228 -0
- cometapi_cli-0.1.0/README.md +190 -0
- cometapi_cli-0.1.0/SKILL.md +325 -0
- cometapi_cli-0.1.0/docs/README.md +42 -0
- cometapi_cli-0.1.0/docs/authentication.md +88 -0
- cometapi_cli-0.1.0/docs/commands/account.md +52 -0
- cometapi_cli-0.1.0/docs/commands/balance.md +70 -0
- cometapi_cli-0.1.0/docs/commands/chat.md +129 -0
- cometapi_cli-0.1.0/docs/commands/config.md +167 -0
- cometapi_cli-0.1.0/docs/commands/doctor.md +131 -0
- cometapi_cli-0.1.0/docs/commands/init.md +70 -0
- cometapi_cli-0.1.0/docs/commands/logs.md +457 -0
- cometapi_cli-0.1.0/docs/commands/models.md +60 -0
- cometapi_cli-0.1.0/docs/commands/repl.md +91 -0
- cometapi_cli-0.1.0/docs/commands/stats.md +61 -0
- cometapi_cli-0.1.0/docs/commands/tasks.md +277 -0
- cometapi_cli-0.1.0/docs/commands/tokens.md +78 -0
- cometapi_cli-0.1.0/docs/configuration.md +77 -0
- cometapi_cli-0.1.0/docs/errors.md +92 -0
- cometapi_cli-0.1.0/docs/installation.md +59 -0
- cometapi_cli-0.1.0/docs/output-formats.md +86 -0
- cometapi_cli-0.1.0/pyproject.toml +67 -0
- cometapi_cli-0.1.0/skills/live-test/SKILL.md +340 -0
- cometapi_cli-0.1.0/src/cometapi_cli/__init__.py +3 -0
- cometapi_cli-0.1.0/src/cometapi_cli/app.py +85 -0
- cometapi_cli-0.1.0/src/cometapi_cli/client.py +270 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/__init__.py +1 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/account.py +39 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/balance.py +56 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/chat.py +104 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/chat_repl.py +229 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/config_cmd.py +174 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/doctor.py +144 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/logs.py +326 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/models.py +44 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/repl.py +134 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/stats.py +39 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/tasks.py +130 -0
- cometapi_cli-0.1.0/src/cometapi_cli/commands/tokens.py +87 -0
- cometapi_cli-0.1.0/src/cometapi_cli/config.py +102 -0
- cometapi_cli-0.1.0/src/cometapi_cli/console.py +8 -0
- cometapi_cli-0.1.0/src/cometapi_cli/constants.py +55 -0
- cometapi_cli-0.1.0/src/cometapi_cli/errors.py +113 -0
- cometapi_cli-0.1.0/src/cometapi_cli/formatters.py +156 -0
- cometapi_cli-0.1.0/src/cometapi_cli/main.py +8 -0
- cometapi_cli-0.1.0/tests/__init__.py +1 -0
- cometapi_cli-0.1.0/tests/conftest.py +267 -0
- cometapi_cli-0.1.0/tests/test_account.py +19 -0
- cometapi_cli-0.1.0/tests/test_balance.py +53 -0
- cometapi_cli-0.1.0/tests/test_chat.py +49 -0
- cometapi_cli-0.1.0/tests/test_config.py +123 -0
- cometapi_cli-0.1.0/tests/test_doctor.py +40 -0
- cometapi_cli-0.1.0/tests/test_errors.py +28 -0
- cometapi_cli-0.1.0/tests/test_formatters.py +46 -0
- cometapi_cli-0.1.0/tests/test_help.py +65 -0
- cometapi_cli-0.1.0/tests/test_logs.py +237 -0
- cometapi_cli-0.1.0/tests/test_models.py +46 -0
- cometapi_cli-0.1.0/tests/test_stats.py +19 -0
- cometapi_cli-0.1.0/tests/test_tasks.py +120 -0
- cometapi_cli-0.1.0/tests/test_tokens.py +64 -0
- cometapi_cli-0.1.0/uv.lock +742 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v4
|
|
21
|
+
|
|
22
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
23
|
+
run: uv python install ${{ matrix.python-version }}
|
|
24
|
+
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: uv sync --extra dev
|
|
27
|
+
|
|
28
|
+
- name: Lint
|
|
29
|
+
run: uv run ruff check src/ tests/
|
|
30
|
+
|
|
31
|
+
- name: Test
|
|
32
|
+
run: uv run pytest -v --tb=short
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
publish:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
environment: pypi
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Install uv
|
|
21
|
+
uses: astral-sh/setup-uv@v4
|
|
22
|
+
|
|
23
|
+
- name: Set up Python
|
|
24
|
+
run: uv python install 3.13
|
|
25
|
+
|
|
26
|
+
- name: Build package
|
|
27
|
+
run: uv build
|
|
28
|
+
|
|
29
|
+
- name: Publish to PyPI
|
|
30
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
# CometAPI CLI — Agent Instructions
|
|
2
|
+
|
|
3
|
+
> This file covers CLI-specific details. For cross-cutting architecture, see the root [AGENTS.md](../AGENTS.md).
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The CLI is a Typer + Rich command-line tool that proxies all business logic through `cometapi-python`. It must **never** make direct HTTP requests — all network calls go through `CometClient` from the Python SDK.
|
|
8
|
+
|
|
9
|
+
## Project Layout
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
cometapi-cli/
|
|
13
|
+
├── pyproject.toml # Hatch build, deps, entry point
|
|
14
|
+
├── uv.lock # Lock file (committed)
|
|
15
|
+
├── SKILL.md # Agent capability description
|
|
16
|
+
├── skills/
|
|
17
|
+
│ └── live-test/
|
|
18
|
+
│ └── SKILL.md # Live testing SOP for Coding Agents
|
|
19
|
+
├── src/cometapi_cli/
|
|
20
|
+
│ ├── __init__.py # __version__
|
|
21
|
+
│ ├── app.py # Typer app, global options, command registration
|
|
22
|
+
│ ├── main.py # Backward compat shim → app.py
|
|
23
|
+
│ ├── config.py # Config file (~/.config/cometapi/config.toml), get_client()
|
|
24
|
+
│ ├── constants.py # Shared constants (QUOTA_PER_UNIT, helpers)
|
|
25
|
+
│ ├── console.py # Shared Rich Console instances
|
|
26
|
+
│ ├── errors.py # CometCLIError hierarchy, exit codes, handle_errors decorator
|
|
27
|
+
│ ├── formatters.py # Multi-format output (table/json/yaml/csv/markdown)
|
|
28
|
+
│ └── commands/
|
|
29
|
+
│ ├── __init__.py
|
|
30
|
+
│ ├── chat.py # chat send (streaming + JSON), REPL entry
|
|
31
|
+
│ ├── chat_repl.py # Multi-turn chat REPL with prompt_toolkit
|
|
32
|
+
│ ├── models.py # models list with search/limit
|
|
33
|
+
│ ├── balance.py # account balance
|
|
34
|
+
│ ├── account.py # user profile (access_token)
|
|
35
|
+
│ ├── stats.py # usage statistics (access_token)
|
|
36
|
+
│ ├── tokens.py # API key listing and search (access_token)
|
|
37
|
+
│ ├── logs.py # Usage logs browsing and filtering (access_token)
|
|
38
|
+
│ ├── tasks.py # Async task logs — Suno, MJ, Luma, Kling (access_token)
|
|
39
|
+
│ ├── config_cmd.py # init wizard + config show/set/unset/path
|
|
40
|
+
│ ├── doctor.py # connectivity & config diagnostics
|
|
41
|
+
│ └── repl.py # Full command REPL (interactive shell)
|
|
42
|
+
└── tests/
|
|
43
|
+
├── __init__.py
|
|
44
|
+
├── conftest.py # Shared fixtures, mock client factory
|
|
45
|
+
├── test_help.py # Version, help, command listing tests
|
|
46
|
+
├── test_chat.py # Chat command tests
|
|
47
|
+
├── test_config.py # Config read/write/CLI tests
|
|
48
|
+
├── test_doctor.py # Doctor diagnostics tests
|
|
49
|
+
├── test_errors.py # Error types and exit codes
|
|
50
|
+
├── test_formatters.py # Multi-format output tests
|
|
51
|
+
├── test_models.py # Models command tests
|
|
52
|
+
├── test_balance.py # Balance command tests (incl. --source)
|
|
53
|
+
├── test_account.py # Account command tests
|
|
54
|
+
├── test_stats.py # Stats command tests
|
|
55
|
+
├── test_tokens.py # Tokens command tests
|
|
56
|
+
├── test_logs.py # Logs command tests
|
|
57
|
+
└── test_tasks.py # Tasks command tests
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Key Design Decisions
|
|
61
|
+
|
|
62
|
+
- **Self-contained client.** `cometapi_cli/client.py` contains `CometClient` (inherits `openai.OpenAI`). The CLI has **no dependency** on the `cometapi` Python SDK package.
|
|
63
|
+
- **No direct HTTP for OpenAI-compatible endpoints.** Always use inherited methods via `CometClient`. Only CometAPI-specific endpoints use `self._client.request()` directly.
|
|
64
|
+
|
|
65
|
+
## Model ID Policy
|
|
66
|
+
|
|
67
|
+
The default model constant lives in `config.py:get_default_model()`. All examples, defaults, and test fixtures MUST use current model IDs — see the root [AGENTS.md](../AGENTS.md) for the authoritative list.
|
|
68
|
+
|
|
69
|
+
## Security & Credential Policy
|
|
70
|
+
|
|
71
|
+
All user-facing messages involving missing or invalid credentials MUST include the relevant creation URL:
|
|
72
|
+
- API Key: https://www.cometapi.com/console/token
|
|
73
|
+
- Access Token: https://www.cometapi.com/console/personal
|
|
74
|
+
|
|
75
|
+
See the root [AGENTS.md](../AGENTS.md) for the full security policy.
|
|
76
|
+
- **Entry point:** `cometapi = "cometapi_cli.app:app"` — the command name is `cometapi`.
|
|
77
|
+
|
|
78
|
+
## Publishing to PyPI
|
|
79
|
+
|
|
80
|
+
Package name: `cometapi-cli`. Triggered automatically by pushing a `v*` tag to GitHub.
|
|
81
|
+
|
|
82
|
+
### Release SOP
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# 1. Bump version in TWO places (must match):
|
|
86
|
+
# - pyproject.toml: version = "X.Y.Z"
|
|
87
|
+
# - src/cometapi_cli/__init__.py: __version__ = "X.Y.Z"
|
|
88
|
+
|
|
89
|
+
# 2. Commit and push
|
|
90
|
+
git add -A
|
|
91
|
+
git commit -m "release: vX.Y.Z"
|
|
92
|
+
git push origin main
|
|
93
|
+
|
|
94
|
+
# 3. Tag and push — triggers publish.yml automatically
|
|
95
|
+
git tag vX.Y.Z
|
|
96
|
+
git push origin vX.Y.Z
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Verify
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
open https://pypi.org/project/cometapi-cli/
|
|
103
|
+
pip install cometapi-cli==X.Y.Z
|
|
104
|
+
cometapi --version
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Version sync rule
|
|
108
|
+
|
|
109
|
+
`pyproject.toml` `version` and `src/cometapi_cli/__init__.py` `__version__` **must always match**.
|
|
110
|
+
|
|
111
|
+
## Configuration
|
|
112
|
+
- **Output formats:** Every data command supports `--json` (per-command) and global `--format/-f` (table/json/yaml/csv/markdown). Persistent default can be set via `output_format` in config.toml.
|
|
113
|
+
- **Error handling:** All commands wrapped with `@handle_errors` decorator that catches SDK/network errors and maps to user-friendly messages + Unix exit codes.
|
|
114
|
+
- **Exit codes:** sysexits.h compatible: 0=success, 1=error, 2=usage, 64=config missing, 69=service unavailable, 77=auth error, 78=config error.
|
|
115
|
+
|
|
116
|
+
## Commands — Complete Reference
|
|
117
|
+
|
|
118
|
+
> **Maintenance rule:** Any CLI interface change (new command, renamed flag, new option) **must** update this section. This is the single source of truth for what the CLI exposes.
|
|
119
|
+
|
|
120
|
+
### Global Options
|
|
121
|
+
|
|
122
|
+
These options apply to **every** command via the root Typer callback.
|
|
123
|
+
|
|
124
|
+
| Option | Alias | Type | Default | Description |
|
|
125
|
+
|--------|-------|------|---------|-------------|
|
|
126
|
+
| `--version` | `-V` | flag | — | Print version (`cli`, `sdk`, `python`) and exit |
|
|
127
|
+
| `--format` | `-f` | `table\|json\|yaml\|csv\|markdown` | `table` | Global output format (overridden by per-command `--format` or `--json`) |
|
|
128
|
+
| `--json` | — | flag | `false` | Shortcut for `--format json` |
|
|
129
|
+
| `--help` | `-h` | flag | — | Show help for any command |
|
|
130
|
+
| `--install-completion` | — | flag | — | Install shell completion (bash/zsh/fish/powershell) |
|
|
131
|
+
| `--show-completion` | — | flag | — | Print the completion script |
|
|
132
|
+
|
|
133
|
+
**Output format resolution priority:** per-command `--json` > per-command `--format` > global `--format` > `table`.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### `chat` — Send a chat message or start interactive REPL
|
|
138
|
+
|
|
139
|
+
**Auth:** `COMETAPI_KEY`
|
|
140
|
+
|
|
141
|
+
| Parameter | Alias | Type | Default | Description |
|
|
142
|
+
|-----------|-------|------|---------|-------------|
|
|
143
|
+
| `MESSAGE` | — | argument (positional, optional) | `None` | Message to send. Omit to enter interactive multi-turn REPL. |
|
|
144
|
+
| `--model` | `-m` | `str` | config `default_model` or `gpt-5.4` | Model to use |
|
|
145
|
+
| `--system` | `-s` | `str` | `None` | System prompt prepended to conversation |
|
|
146
|
+
| `--temperature` | `-t` | `float` | API default | Sampling temperature (0.0–2.0) |
|
|
147
|
+
| `--max-tokens` | — | `int` | API default | Maximum tokens in the response |
|
|
148
|
+
| `--stream/--no-stream` | — | flag | `--stream` | Enable/disable streaming output |
|
|
149
|
+
| `--format` | `-f` | `OutputFormat` | inherits global | Per-command output format override |
|
|
150
|
+
| `--json` | — | flag | `false` | Output structured JSON (disables streaming) |
|
|
151
|
+
|
|
152
|
+
**Behavior:**
|
|
153
|
+
- With `MESSAGE`: sends a single request, streams response to stdout. With `--json`, returns `{"model", "role", "content", "usage"}`.
|
|
154
|
+
- Without `MESSAGE`: enters interactive multi-turn Chat REPL (see [Chat REPL Slash Commands](#chat-repl-slash-commands) below).
|
|
155
|
+
- Model resolved via: `--model` flag > config `default_model` > `gpt-5.4`.
|
|
156
|
+
|
|
157
|
+
**JSON output schema:**
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"model": "gpt-5.4",
|
|
161
|
+
"role": "assistant",
|
|
162
|
+
"content": "...",
|
|
163
|
+
"usage": { "prompt_tokens": 9, "completion_tokens": 10, "total_tokens": 19 }
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
### `models` — List available models
|
|
170
|
+
|
|
171
|
+
**Auth:** `COMETAPI_KEY`
|
|
172
|
+
|
|
173
|
+
| Parameter | Alias | Type | Default | Description |
|
|
174
|
+
|-----------|-------|------|---------|-------------|
|
|
175
|
+
| `--search` | `-s` | `str` | `None` | Filter models by name (case-insensitive substring match) |
|
|
176
|
+
| `--limit` | `-l` | `int` | `None` (show all) | Maximum number of models to display |
|
|
177
|
+
| `--format` | `-f` | `OutputFormat` | inherits global | Per-command output format override |
|
|
178
|
+
| `--json` | — | flag | `false` | Output as JSON |
|
|
179
|
+
|
|
180
|
+
**Behavior:** Fetches all models via `client.models.list()`, sorts alphabetically by `id`, applies `--search` filter, then `--limit` truncation.
|
|
181
|
+
|
|
182
|
+
**Table columns:** `id` (cyan), `owned_by` (green).
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
### `balance` — Show account balance
|
|
187
|
+
|
|
188
|
+
**Auth:** `COMETAPI_KEY` (always), `COMETAPI_ACCESS_TOKEN` (for account-level view)
|
|
189
|
+
|
|
190
|
+
| Parameter | Alias | Type | Default | Description |
|
|
191
|
+
|-----------|-------|------|---------|-------------|
|
|
192
|
+
| `--source` | `-s` | `str` (`account` or `token`) | `None` (auto-detect) | Force data source: `account` = full account balance via `/api/user/self`; `token` = per-API-key billing via `/v1/dashboard/billing/*` |
|
|
193
|
+
| `--format` | `-f` | `OutputFormat` | inherits global | Per-command output format override |
|
|
194
|
+
| `--json` | — | flag | `false` | Output raw balance dict as JSON |
|
|
195
|
+
|
|
196
|
+
**Auto-detection logic** (when `--source` is omitted):
|
|
197
|
+
1. If `COMETAPI_ACCESS_TOKEN` is available → uses `account` source.
|
|
198
|
+
2. Otherwise → falls back to `token` (per-key billing) source.
|
|
199
|
+
|
|
200
|
+
**Display — `account` source:**
|
|
201
|
+
| Field | Description |
|
|
202
|
+
|-------|-------------|
|
|
203
|
+
| Available Balance | Current remaining balance (USD) |
|
|
204
|
+
| Used | Total amount consumed (USD) |
|
|
205
|
+
| Total Topped Up | Lifetime top-up amount (USD) |
|
|
206
|
+
|
|
207
|
+
**Display — `token` (billing) source:**
|
|
208
|
+
| Field | Description |
|
|
209
|
+
|-------|-------------|
|
|
210
|
+
| Limit | Spending cap (`Unlimited` if no cap set) |
|
|
211
|
+
| Used | Amount consumed through this API key (USD) |
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### `account` — Show account profile
|
|
216
|
+
|
|
217
|
+
**Auth:** `COMETAPI_ACCESS_TOKEN` (required)
|
|
218
|
+
|
|
219
|
+
| Parameter | Alias | Type | Default | Description |
|
|
220
|
+
|-----------|-------|------|---------|-------------|
|
|
221
|
+
| `--format` | `-f` | `OutputFormat` | inherits global | Per-command output format override |
|
|
222
|
+
| `--json` | — | flag | `false` | Output full profile as JSON |
|
|
223
|
+
|
|
224
|
+
**Display fields:** `id`, `username`, `display_name`, `email`, `role`, `status`.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
### `stats` — Show usage statistics
|
|
229
|
+
|
|
230
|
+
**Auth:** `COMETAPI_ACCESS_TOKEN` (required)
|
|
231
|
+
|
|
232
|
+
| Parameter | Alias | Type | Default | Description |
|
|
233
|
+
|-----------|-------|------|---------|-------------|
|
|
234
|
+
| `--format` | `-f` | `OutputFormat` | inherits global | Per-command output format override |
|
|
235
|
+
| `--json` | — | flag | `false` | Output raw stats as JSON |
|
|
236
|
+
|
|
237
|
+
**Display fields:** `requests`, `request_rate_change`, `usage` (USD), `usage_rate_change`, `success_rate`, `predicted_days_left`.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
### `tokens` — List and search API keys
|
|
242
|
+
|
|
243
|
+
**Auth:** `COMETAPI_ACCESS_TOKEN` (required)
|
|
244
|
+
|
|
245
|
+
| Parameter | Alias | Type | Default | Description |
|
|
246
|
+
|-----------|-------|------|---------|-------------|
|
|
247
|
+
| `--search` | `-s` | `str` | `None` | Search tokens by name or key substring (uses `/api/token/search`) |
|
|
248
|
+
| `--page` | `-p` | `int` | `1` | Page number for paginated results |
|
|
249
|
+
| `--limit` | `-l` | `int` | `20` | Results per page |
|
|
250
|
+
| `--format` | `-f` | `OutputFormat` | inherits global | Per-command output format override |
|
|
251
|
+
| `--json` | — | flag | `false` | Output raw token list as JSON |
|
|
252
|
+
|
|
253
|
+
**Behavior:**
|
|
254
|
+
- Without `--search`: calls `client.list_tokens(page=, page_size=)` — paginated, returns `data.items`.
|
|
255
|
+
- With `--search`: calls `client.search_tokens(keyword=)` — flat `data` list, ignores `--page`/`--limit`.
|
|
256
|
+
|
|
257
|
+
**Table columns:** `id` (cyan), `name` (green), `key` (yellow, masked), `status` (green — active/disabled/expired/exhausted), `balance` (green, USD or "Unlimited"), `used` (red, USD), `created` (dim), `accessed` (dim), `expires` (dim, "Never" if -1).
|
|
258
|
+
|
|
259
|
+
**Key masking:** Only the last 4 characters are shown, e.g., `****abcd`.
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
### `logs` — Show usage logs
|
|
264
|
+
|
|
265
|
+
**Auth:** `COMETAPI_ACCESS_TOKEN` (required)
|
|
266
|
+
|
|
267
|
+
| Parameter | Alias | Type | Default | Description |
|
|
268
|
+
|-----------|-------|------|---------|-------------|
|
|
269
|
+
| `--model` | `-m` | `str` | `None` | Filter by model name |
|
|
270
|
+
| `--token-name` | `-t` | `str` | `None` | Filter by token name |
|
|
271
|
+
| `--type` | — | `str` | `None` | Filter by log type (see values below) |
|
|
272
|
+
| `--search` | `-s` | `str` | `None` | Search logs by keyword (uses `/api/log/self/search`) |
|
|
273
|
+
| `--start` | — | `str` | `None` | Start date (`YYYY-MM-DD`, ISO 8601, or Unix timestamp) |
|
|
274
|
+
| `--end` | — | `str` | `None` | End date (`YYYY-MM-DD`, ISO 8601, or Unix timestamp) |
|
|
275
|
+
| `--group` | `-g` | `str` | `None` | Filter by API key group |
|
|
276
|
+
| `--page` | `-p` | `int` | `1` | Page number |
|
|
277
|
+
| `--limit` | `-l` | `int` | `20` | Results per page |
|
|
278
|
+
| `--export` | — | flag | `false` | Export logs as server-side CSV to stdout |
|
|
279
|
+
| `--format` | `-f` | `OutputFormat` | inherits global | Per-command output format override |
|
|
280
|
+
| `--json` | — | flag | `false` | Output raw log list as JSON |
|
|
281
|
+
|
|
282
|
+
**Valid `--type` values:**
|
|
283
|
+
|
|
284
|
+
| Value | Backend code | Description |
|
|
285
|
+
|-------|-------------|-------------|
|
|
286
|
+
| `unknown` | 0 | Unknown log type |
|
|
287
|
+
| `topup` | 1 | Balance top-up |
|
|
288
|
+
| `consume` | 2 | API consumption |
|
|
289
|
+
| `manage` | 3 | Management action |
|
|
290
|
+
| `system` | 4 | System event |
|
|
291
|
+
| `error` | 5 | Error log |
|
|
292
|
+
| `refund` | 6 | Refund |
|
|
293
|
+
|
|
294
|
+
Invalid `--type` values produce an error message with valid options and exit code 2.
|
|
295
|
+
|
|
296
|
+
**Behavior:**
|
|
297
|
+
- Without `--search` or `--export`: calls `client.list_logs(page=, page_size=, log_type=, model_name=, token_name=, start_timestamp=, end_timestamp=, group=)` — paginated, `data.items`.
|
|
298
|
+
- With `--search`: calls `client.search_logs(keyword=)` — flat `data` list, ignores other filter flags.
|
|
299
|
+
- With `--export`: calls `client.export_logs(...)` — writes server-side CSV bytes to stdout. Honors `--model`, `--token-name`, `--type`, `--start`, `--end`, `--group`. Pipe-friendly (no Rich formatting).
|
|
300
|
+
|
|
301
|
+
**Date parsing:** `--start` and `--end` accept `YYYY-MM-DD`, `YYYY-MM-DDTHH:MM:SS` (ISO 8601), or raw Unix timestamps. Dates are interpreted as UTC.
|
|
302
|
+
|
|
303
|
+
**Table columns:** `time` (dim), `type` (cyan), `model` (green), `token` (yellow), `prompt` (tokens count), `completion` (tokens count), `cost` (red, USD), `duration_ms`, `stream` (Yes/No).
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
### `tasks` — Show async task logs
|
|
308
|
+
|
|
309
|
+
**Auth:** `COMETAPI_ACCESS_TOKEN` (required)
|
|
310
|
+
|
|
311
|
+
| Parameter | Alias | Type | Default | Description |
|
|
312
|
+
|-----------|-------|------|---------|-------------|
|
|
313
|
+
| `--platform` | `-p` | `str` | `None` | Filter by platform (see values below) |
|
|
314
|
+
| `--task-id` | — | `str` | `None` | Filter by task ID |
|
|
315
|
+
| `--status` | `-s` | `str` | `None` | Filter by status (see values below) |
|
|
316
|
+
| `--action` | `-a` | `str` | `None` | Filter by action type (e.g., `MUSIC`, `generate`) |
|
|
317
|
+
| `--start` | — | `str` | `None` | Start date (`YYYY-MM-DD`, ISO 8601, or Unix timestamp) |
|
|
318
|
+
| `--end` | — | `str` | `None` | End date (`YYYY-MM-DD`, ISO 8601, or Unix timestamp) |
|
|
319
|
+
| `--page` | — | `int` | `1` | Page number |
|
|
320
|
+
| `--limit` | `-l` | `int` | `20` | Results per page |
|
|
321
|
+
| `--format` | `-f` | `OutputFormat` | inherits global | Per-command output format override |
|
|
322
|
+
| `--json` | — | flag | `false` | Output raw task list as JSON |
|
|
323
|
+
|
|
324
|
+
**Valid `--platform` values:** `suno`, `mj`, `luma`, `replicate`, `kling`, `runwayml`, `runway`, `jimeng`, `volcengine`, `sora`, `bria`, `flux`
|
|
325
|
+
|
|
326
|
+
**Valid `--status` values:** `SUBMITTED`, `QUEUED`, `IN_PROGRESS`, `FAILURE`, `SUCCESS`, `UNKNOWN` (case-insensitive input, sent as uppercase)
|
|
327
|
+
|
|
328
|
+
Invalid `--platform` or `--status` values produce an error message with valid options and exit code 2.
|
|
329
|
+
|
|
330
|
+
**Behavior:** Calls `client.list_tasks(page=, page_size=, platform=, task_id=, status=, action=, start_timestamp=, end_timestamp=)` — paginated response via `GET /api/task/self`.
|
|
331
|
+
|
|
332
|
+
**Table columns:** `time` (dim), `platform` (magenta), `task_id` (cyan), `action` (yellow), `status` (green), `model` (green), `progress` (dim), `cost` (red, USD), `duration` (dim, submit-to-finish).
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
### `init` — Interactive setup wizard
|
|
337
|
+
|
|
338
|
+
**Auth:** None (creates auth config)
|
|
339
|
+
|
|
340
|
+
No options. Launches an interactive Rich prompt that:
|
|
341
|
+
1. Collects `api_key` (with connectivity test).
|
|
342
|
+
2. Optionally collects `access_token`.
|
|
343
|
+
3. Sets `default_model`.
|
|
344
|
+
4. Saves to `~/.config/cometapi/config.toml` with 0600 permissions.
|
|
345
|
+
5. Displays security disclaimer and credential creation URLs.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
### `doctor` — Run diagnostics and health checks
|
|
350
|
+
|
|
351
|
+
**Auth:** None (inspects current config)
|
|
352
|
+
|
|
353
|
+
| Parameter | Alias | Type | Default | Description |
|
|
354
|
+
|-----------|-------|------|---------|-------------|
|
|
355
|
+
| `--format` | `-f` | `OutputFormat` | inherits global | Per-command output format override |
|
|
356
|
+
| `--json` | — | flag | `false` | Output diagnostics as JSON |
|
|
357
|
+
|
|
358
|
+
**Checks performed:**
|
|
359
|
+
1. Config file existence (`~/.config/cometapi/config.toml`)
|
|
360
|
+
2. API key presence and source (environment / config / none)
|
|
361
|
+
3. API connectivity (calls `client.models.list()`)
|
|
362
|
+
4. Access token presence
|
|
363
|
+
5. SDK installation
|
|
364
|
+
6. Version info (Python, SDK, CLI)
|
|
365
|
+
|
|
366
|
+
Exits with code 64 if any critical check fails.
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
### `repl` — Interactive command shell
|
|
371
|
+
|
|
372
|
+
**Auth:** None (individual commands within REPL check auth as needed)
|
|
373
|
+
|
|
374
|
+
No options. Starts a `prompt_toolkit` session with:
|
|
375
|
+
- Tab completion for all commands and common flags (`--json`, `--format`, `--model`, `--system`, `--search`, `--limit`, `--page`, `--type`, `--token-name`, `--help`).
|
|
376
|
+
- Persistent history in `~/.config/cometapi/repl_history`.
|
|
377
|
+
- Dispatches typed commands through the Typer app (no `cometapi` prefix needed).
|
|
378
|
+
- Built-in `help` and `exit`/`quit` commands.
|
|
379
|
+
- Prevents recursive `repl` invocation.
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
### `config` — Manage CLI configuration
|
|
384
|
+
|
|
385
|
+
A subcommand group with four subcommands:
|
|
386
|
+
|
|
387
|
+
#### `config show` — Display current configuration
|
|
388
|
+
|
|
389
|
+
| Parameter | Alias | Type | Default | Description |
|
|
390
|
+
|-----------|-------|------|---------|-------------|
|
|
391
|
+
| `--format` | `-f` | `OutputFormat` | inherits global | Per-command output format override |
|
|
392
|
+
| `--json` | — | flag | `false` | Output as JSON |
|
|
393
|
+
|
|
394
|
+
Secrets (`api_key`, `access_token`) are always masked in output.
|
|
395
|
+
|
|
396
|
+
#### `config set` — Set a configuration value
|
|
397
|
+
|
|
398
|
+
| Parameter | Type | Description |
|
|
399
|
+
|-----------|------|-------------|
|
|
400
|
+
| `KEY` | argument (required) | Configuration key (see valid keys below) |
|
|
401
|
+
| `VALUE` | argument (required) | Value to set |
|
|
402
|
+
|
|
403
|
+
#### `config unset` — Remove a configuration value
|
|
404
|
+
|
|
405
|
+
| Parameter | Type | Description |
|
|
406
|
+
|-----------|------|-------------|
|
|
407
|
+
| `KEY` | argument (required) | Configuration key to remove |
|
|
408
|
+
|
|
409
|
+
#### `config path` — Show the configuration file path
|
|
410
|
+
|
|
411
|
+
No options. Prints the absolute path to `config.toml`.
|
|
412
|
+
|
|
413
|
+
**Valid config keys:** `api_key`, `access_token`, `base_url`, `default_model`, `output_format`.
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
### Chat REPL Slash Commands
|
|
418
|
+
|
|
419
|
+
When `cometapi chat` is started without a message, these slash commands are available inside the REPL:
|
|
420
|
+
|
|
421
|
+
| Command | Description |
|
|
422
|
+
|---------|-------------|
|
|
423
|
+
| `/model <name>` | Switch model mid-conversation. Without arg: show current model. |
|
|
424
|
+
| `/system <prompt>` | Set system prompt. Without arg: show current system prompt. |
|
|
425
|
+
| `/clear` | Clear conversation history (preserves system prompt). |
|
|
426
|
+
| `/history` | Display all messages in the conversation. |
|
|
427
|
+
| `/save <file.json\|file.md>` | Export conversation to JSON or Markdown file. |
|
|
428
|
+
| `/tokens` | Show approximate token count and message count. |
|
|
429
|
+
| `/help` | List all slash commands. |
|
|
430
|
+
| `/exit` | Exit the chat REPL (also Ctrl+D, `/quit`, `/q`). |
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
### Exit Codes
|
|
435
|
+
|
|
436
|
+
| Code | Constant | Meaning |
|
|
437
|
+
|------|----------|---------|
|
|
438
|
+
| `0` | `SUCCESS` | Command completed successfully |
|
|
439
|
+
| `1` | `ERROR` | General runtime error |
|
|
440
|
+
| `2` | `USAGE` | Invalid usage (bad arguments, unknown `--type` value, etc.) |
|
|
441
|
+
| `64` | `CONFIG_MISSING` | Required configuration (API key) not set |
|
|
442
|
+
| `69` | `SERVICE_UNAVAILABLE` | API endpoint unreachable |
|
|
443
|
+
| `77` | `AUTH_ERROR` | Authentication failed (invalid key or token) |
|
|
444
|
+
| `78` | `CONFIG_ERROR` | Configuration file corrupt or unreadable |
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## Build & Test
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
uv sync # Install deps (links local cometapi-python)
|
|
452
|
+
uv run cometapi --version # Verify CLI version
|
|
453
|
+
uv run cometapi -h # List all commands
|
|
454
|
+
uv run cometapi doctor # Check configuration health
|
|
455
|
+
uv run pytest -v # Run tests (98 tests)
|
|
456
|
+
uv run ruff check src/ tests/ # Lint
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
## Architecture Conventions
|
|
460
|
+
|
|
461
|
+
- Framework: **Typer** with `rich_markup_mode="rich"` and `no_args_is_help=True`.
|
|
462
|
+
- UI: **Rich** for tables, panels, markdown rendering, and console formatting.
|
|
463
|
+
- Module name: `cometapi_cli` (underscore). Package name: `cometapi-cli` (hyphen).
|
|
464
|
+
- All commands use `typer.Option()` with `Annotated` type hints.
|
|
465
|
+
- Error messages via `err_console.print()` (stderr) with `[red bold]Error:[/]` markup.
|
|
466
|
+
- Config file: TOML format at `~/.config/cometapi/config.toml`, 0600 permissions.
|
|
467
|
+
- Valid config keys: `api_key`, `access_token`, `base_url`, `default_model`, `output_format`.
|
|
468
|
+
- Client creation via `config.get_client()` — resolves auth from env vars + config file.
|
|
469
|
+
|
|
470
|
+
## Environment Variables
|
|
471
|
+
|
|
472
|
+
| Variable | Required | Purpose |
|
|
473
|
+
|----------|----------|---------|
|
|
474
|
+
| `COMETAPI_KEY` | Yes (for chat/balance/models) | API key for AI relay |
|
|
475
|
+
| `COMETAPI_ACCESS_TOKEN` | Yes (for account/stats/tokens/logs) | Access token for account mgmt |
|
|
476
|
+
| `COMETAPI_BASE_URL` | No | Override default base URL |
|
|
477
|
+
|
|
478
|
+
## Dependencies
|
|
479
|
+
|
|
480
|
+
- `cometapi` — CometAPI Python SDK (local editable in dev)
|
|
481
|
+
- `typer>=0.12` — CLI framework
|
|
482
|
+
- `rich>=13.0` — Terminal UI
|
|
483
|
+
- `tomli>=2.0` — TOML reading (Python 3.10 only; 3.11+ uses stdlib `tomllib`)
|
|
484
|
+
- `tomli-w>=1.0` — TOML writing
|
|
485
|
+
- `pyyaml>=6.0` — YAML output format
|
|
486
|
+
- `prompt-toolkit>=3.0` — REPL line editing, history, completion
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.2.0] — 2026-04-09
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **12 commands**: `chat`, `models`, `balance`, `account`, `stats`, `tokens`, `logs`, `tasks`, `init`, `doctor`, `repl`, `config`
|
|
13
|
+
- **Chat REPL**: multi-turn interactive chat with slash commands (`/model`, `/system`, `/clear`, `/history`, `/save`, `/tokens`)
|
|
14
|
+
- **Command REPL**: interactive shell with tab completion and persistent history
|
|
15
|
+
- **Multi-format output**: table, JSON, YAML, CSV, Markdown via `--format` / `--json`
|
|
16
|
+
- **Logs**: date range filtering (`--start`, `--end`), group filtering (`--group`), CSV export (`--export`), request detail (`--request-id --detail`)
|
|
17
|
+
- **Tasks**: async task logs for Suno, Midjourney, Luma, Kling, and other platforms
|
|
18
|
+
- **Config management**: `config show/set/unset/path` subcommands, TOML config at `~/.config/cometapi/config.toml`
|
|
19
|
+
- **Persistent output_format**: set default output format in `config.toml`
|
|
20
|
+
- **Doctor diagnostics**: connectivity, auth, SDK, and config health checks
|
|
21
|
+
- **Setup wizard**: `cometapi init` with API key validation
|
|
22
|
+
- **Shell completion**: bash, zsh, fish, powershell
|
|
23
|
+
- **Error handling**: structured exit codes (sysexits.h compatible), user-friendly messages
|
|
24
|
+
- **Security**: credential masking, 0600 file permissions, creation URL guidance
|
|
25
|
+
- **CI/CD**: GitHub Actions for testing (Python 3.10–3.13) and PyPI publishing
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- **Config priority**: `CLI flags > config.toml > env vars > defaults` (config file takes precedence over environment variables)
|
|
30
|
+
- Shared constants module — extracted `QUOTA_PER_UNIT`, `quota_to_usd`, `format_ts`, `parse_date`, `extract_items` from duplicated command code
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- `chat` command now supports `--format` option (was only `--json`)
|
|
35
|
+
- `tokens --search` now applies `--limit` for client-side truncation
|
|
36
|
+
- `logs --search` warns when other filters are silently ignored
|
|
37
|
+
- Corrupt config files now raise `ConfigError` (exit code 78) instead of silently returning empty config
|
|
38
|
+
- `get_default_model()` now respects `COMETAPI_DEFAULT_MODEL` environment variable
|
|
39
|
+
|
|
40
|
+
## [0.1.0] — 2026-04-07
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- Initial release
|
|
45
|
+
- Core commands: `chat`, `models`, `balance`, `init`, `doctor`
|
|
46
|
+
- Basic config file support
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CometAPI
|
|
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.
|