cdx-manager 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.
- cdx_manager-0.3.0/LICENSE +21 -0
- cdx_manager-0.3.0/PKG-INFO +296 -0
- cdx_manager-0.3.0/README.md +269 -0
- cdx_manager-0.3.0/cdx_manager.egg-info/PKG-INFO +296 -0
- cdx_manager-0.3.0/cdx_manager.egg-info/SOURCES.txt +27 -0
- cdx_manager-0.3.0/cdx_manager.egg-info/dependency_links.txt +1 -0
- cdx_manager-0.3.0/cdx_manager.egg-info/entry_points.txt +2 -0
- cdx_manager-0.3.0/cdx_manager.egg-info/top_level.txt +1 -0
- cdx_manager-0.3.0/pyproject.toml +44 -0
- cdx_manager-0.3.0/setup.cfg +4 -0
- cdx_manager-0.3.0/src/__init__.py +17 -0
- cdx_manager-0.3.0/src/claude_refresh.py +72 -0
- cdx_manager-0.3.0/src/claude_usage.py +84 -0
- cdx_manager-0.3.0/src/cli.py +192 -0
- cdx_manager-0.3.0/src/cli_commands.py +369 -0
- cdx_manager-0.3.0/src/cli_render.py +131 -0
- cdx_manager-0.3.0/src/config.py +8 -0
- cdx_manager-0.3.0/src/errors.py +4 -0
- cdx_manager-0.3.0/src/health.py +125 -0
- cdx_manager-0.3.0/src/notify.py +138 -0
- cdx_manager-0.3.0/src/provider_runtime.py +290 -0
- cdx_manager-0.3.0/src/repair.py +121 -0
- cdx_manager-0.3.0/src/session_service.py +563 -0
- cdx_manager-0.3.0/src/session_store.py +244 -0
- cdx_manager-0.3.0/src/status_source.py +572 -0
- cdx_manager-0.3.0/src/status_view.py +270 -0
- cdx_manager-0.3.0/test/test_cli_py.py +1135 -0
- cdx_manager-0.3.0/test/test_runtime_py.py +115 -0
- cdx_manager-0.3.0/test/test_session_service_py.py +724 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexandre Agostini
|
|
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.
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cdx-manager
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Terminal session manager for Codex and Claude accounts.
|
|
5
|
+
Author: Alexandre Agostini
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/AlexAgo83/cdx-manager
|
|
8
|
+
Project-URL: Repository, https://github.com/AlexAgo83/cdx-manager.git
|
|
9
|
+
Project-URL: Issues, https://github.com/AlexAgo83/cdx-manager/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/AlexAgo83/cdx-manager/tree/main/changelogs
|
|
11
|
+
Keywords: codex,claude,cli,terminal,session-manager,ai-tools
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development
|
|
22
|
+
Classifier: Topic :: Terminals
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# CDX Manager
|
|
29
|
+
|
|
30
|
+
**Run multiple Codex and Claude sessions from one terminal. Switch between accounts instantly.**
|
|
31
|
+
|
|
32
|
+
If you use AI coding tools at scale ; multiple accounts, multiple providers : you know the friction: re-authenticating, losing context, juggling environment variables. `cdx` removes all of that.
|
|
33
|
+
|
|
34
|
+
One command to launch any session. Zero auth juggling.
|
|
35
|
+
|
|
36
|
+
[](LICENSE)  
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Table of Contents
|
|
41
|
+
|
|
42
|
+
- [What it does](#what-it-does)
|
|
43
|
+
- [Technical Overview](#technical-overview)
|
|
44
|
+
- [Getting Started](#getting-started)
|
|
45
|
+
- [All Commands](#all-commands)
|
|
46
|
+
- [Available Scripts](#available-scripts)
|
|
47
|
+
- [Project Structure](#project-structure)
|
|
48
|
+
- [Data Layout](#data-layout)
|
|
49
|
+
- [Troubleshooting](#troubleshooting)
|
|
50
|
+
- [Contributing](#contributing)
|
|
51
|
+
- [License](#license)
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## What it does
|
|
56
|
+
|
|
57
|
+
- **Multiple accounts, one tool.** Register as many Codex or Claude sessions as you need. Each one gets its own isolated auth environment — no cross-contamination between accounts.
|
|
58
|
+
- **Instant launch.** `cdx work` opens your "work" session. `cdx personal` opens another. No config files to edit mid-flow.
|
|
59
|
+
- **Auth guardrails.** `cdx` checks authentication before launching. If a session is not logged in, it tells you exactly what to run — no silent failures.
|
|
60
|
+
- **Usage at a glance.** `cdx status` shows token usage, 5-hour window quota, weekly quota, and last-updated timestamps for every session in one aligned table.
|
|
61
|
+
- **Passive status resolution.** If a session has no recorded status, `cdx` reads it directly from the provider's session logs and JSONL history — no manual sync required.
|
|
62
|
+
- **Session transcript capture.** Every launch is recorded to a local log file via `script`, giving you a full terminal transcript for each session.
|
|
63
|
+
- **Clean removal.** `cdx rmv` wipes a session and its entire auth directory. No orphaned files, no stale credentials.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Technical Overview
|
|
68
|
+
|
|
69
|
+
- Python 3.9+, zero runtime dependencies.
|
|
70
|
+
- Environment isolation per session:
|
|
71
|
+
- Codex sessions override `CODEX_HOME` to a dedicated profile directory.
|
|
72
|
+
- Claude sessions override `HOME` to a dedicated profile directory.
|
|
73
|
+
- Persistence:
|
|
74
|
+
- Session registry at `~/.cdx/sessions.json` (versioned JSON store).
|
|
75
|
+
- Per-session state at `~/.cdx/state/<name>.json`.
|
|
76
|
+
- Auth and provider data under `~/.cdx/profiles/<name>/`.
|
|
77
|
+
- All paths are URL-encoded to support arbitrary session names.
|
|
78
|
+
- Status resolution pipeline:
|
|
79
|
+
- Primary source: recorded status fields on the session record.
|
|
80
|
+
- Fallback: `status-source` scans provider JSONL history files and terminal log transcripts, strips ANSI/OSC sequences, and extracts `usage%`, `5h remaining%`, and `week remaining%` via pattern matching.
|
|
81
|
+
- Claude status refreshes are cached briefly by default; pass `--refresh` to force a live rate-limit probe.
|
|
82
|
+
- If `script` is unavailable, Codex launch falls back to running without transcript capture.
|
|
83
|
+
- Auth probe: synchronous subprocess call to `codex login status` or `claude auth status` before any interactive launch.
|
|
84
|
+
- Signal forwarding: `SIGINT`, `SIGTERM`, and `SIGHUP` are forwarded to the child process and produce clean exit codes.
|
|
85
|
+
- Test stack: Python built-in `unittest` runner with no test framework dependency.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Getting Started
|
|
90
|
+
|
|
91
|
+
### Prerequisites
|
|
92
|
+
|
|
93
|
+
- Python 3.9+
|
|
94
|
+
- npm
|
|
95
|
+
- `codex` and/or `claude` CLI installed and available in your PATH
|
|
96
|
+
|
|
97
|
+
### Install
|
|
98
|
+
|
|
99
|
+
From npm:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npm install -g cdx-manager
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
With pipx:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
pipx install cdx-manager
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
With uv:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
uv tool install cdx-manager
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
With the standalone GitHub installer:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
curl -fsSL https://raw.githubusercontent.com/AlexAgo83/cdx-manager/main/install.sh | sh
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
For a specific version:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
curl -fsSL https://raw.githubusercontent.com/AlexAgo83/cdx-manager/main/install.sh | CDX_VERSION=v0.3.0 sh
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
From source:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
git clone <repo>
|
|
133
|
+
cd cdx-manager
|
|
134
|
+
make install
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
`cdx` is now available globally. Changes to the source take effect immediately — no reinstall needed.
|
|
138
|
+
|
|
139
|
+
To uninstall:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
make uninstall
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Alternatively, for a non-symlinked global source install:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npm install -g .
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Environment
|
|
152
|
+
|
|
153
|
+
By default, `cdx` stores all data under `~/.cdx/`. Override with:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
export CDX_HOME=/path/to/custom/dir
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Optional runtime knobs:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
export CDX_CLAUDE_STATUS_MODEL=claude-haiku-4-5-20251001
|
|
163
|
+
export CDX_SCRIPT_BIN=script
|
|
164
|
+
export CDX_SCRIPT_ARGS='-q -F {transcript}'
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Quick Start
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Register a Codex session
|
|
171
|
+
cdx add work
|
|
172
|
+
|
|
173
|
+
# Register a Claude session
|
|
174
|
+
cdx add claude personal
|
|
175
|
+
|
|
176
|
+
# List all sessions
|
|
177
|
+
cdx
|
|
178
|
+
|
|
179
|
+
# Launch a session
|
|
180
|
+
cdx work
|
|
181
|
+
|
|
182
|
+
# Check usage across all sessions
|
|
183
|
+
cdx status
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## All Commands
|
|
189
|
+
|
|
190
|
+
| Command | Description |
|
|
191
|
+
|---|---|
|
|
192
|
+
| `cdx` | List all sessions with last-updated timestamps |
|
|
193
|
+
| `cdx <name>` | Launch a session (checks auth first) |
|
|
194
|
+
| `cdx add [provider] <name>` | Register a new session (`provider`: `codex` or `claude`, default: `codex`) |
|
|
195
|
+
| `cdx cp <source> <dest>` | Copy a session into another session name, overwriting the destination if it exists |
|
|
196
|
+
| `cdx ren <source> <dest>` | Rename a session and move its auth data |
|
|
197
|
+
| `cdx login <name>` | Re-authenticate a session (logout + login) |
|
|
198
|
+
| `cdx logout <name>` | Log out of a session |
|
|
199
|
+
| `cdx rmv <name> [--force]` | Remove a session and its auth data (prompts for confirmation unless `--force`) |
|
|
200
|
+
| `cdx clean [name]` | Clear launch transcript logs for one session or all sessions |
|
|
201
|
+
| `cdx doctor [--json]` | Inspect CLI dependencies, CDX_HOME permissions, missing state, orphan profiles, and pending quarantines |
|
|
202
|
+
| `cdx repair [--dry-run] [--force] [--json]` | Plan or apply safe repairs for missing state files, quarantines, and orphan profiles |
|
|
203
|
+
| `cdx notify <name> --at-reset [--poll seconds] [--once]` | Wait for a session reset time and send a desktop notification when due |
|
|
204
|
+
| `cdx notify --next-ready [--poll seconds] [--once]` | Wait until the recommended session is usable or needs a refresh after reset |
|
|
205
|
+
| `cdx status [--json] [--refresh]` | Show token usage table for all sessions; JSON keeps the same row-array shape and writes live Claude refresh warnings to stderr |
|
|
206
|
+
| `cdx status --small [--refresh]` / `cdx status -s [--refresh]` | Show compact token usage table without provider, blocking quota, credits, and updated columns |
|
|
207
|
+
| `cdx status <name> [--json] [--refresh]` | Show detailed usage breakdown for one session |
|
|
208
|
+
| `cdx --help` | Show usage |
|
|
209
|
+
| `cdx --version` | Show version |
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Available Scripts
|
|
214
|
+
|
|
215
|
+
- `npm test`: run the Python test suite
|
|
216
|
+
- `npm run test:py`: run the Python unit tests directly
|
|
217
|
+
- `npm run lint`: byte-compile the Python sources and tests
|
|
218
|
+
- `npm run link`: link `cdx` globally for local development (`npm link`)
|
|
219
|
+
- `npm run unlink`: remove the global link
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Project Structure
|
|
224
|
+
|
|
225
|
+
```text
|
|
226
|
+
bin/
|
|
227
|
+
cdx # Entry point — shebang + main() call
|
|
228
|
+
|
|
229
|
+
src/
|
|
230
|
+
cli.py # Top-level command router
|
|
231
|
+
cli_commands.py # Command handlers and argument handling
|
|
232
|
+
cli_render.py # Terminal formatting, tables, colors, and errors
|
|
233
|
+
status_view.py # Status table/detail rendering and priority ranking
|
|
234
|
+
provider_runtime.py # Provider launch/auth commands, transcripts, signals
|
|
235
|
+
claude_refresh.py # Claude usage refresh orchestration
|
|
236
|
+
session_service.py # Session lifecycle: create, copy, rename, launch, remove, status
|
|
237
|
+
# resolution, auth state management
|
|
238
|
+
session_store.py # JSON persistence layer: sessions.json + per-session
|
|
239
|
+
# state files
|
|
240
|
+
status_source.py # Status artifact discovery: scans JSONL history files
|
|
241
|
+
# and terminal log transcripts, strips ANSI sequences,
|
|
242
|
+
# extracts usage metrics via pattern matching
|
|
243
|
+
config.py # CDX_HOME resolution (env override or ~/.cdx)
|
|
244
|
+
errors.py # CdxError with optional exit code
|
|
245
|
+
__init__.py # Public Python exports
|
|
246
|
+
|
|
247
|
+
test/
|
|
248
|
+
test_cli_py.py # CLI command dispatch tests
|
|
249
|
+
test_session_service_py.py # Session service unit tests
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Data Layout
|
|
255
|
+
|
|
256
|
+
All session data lives under `CDX_HOME` (default: `~/.cdx/`):
|
|
257
|
+
|
|
258
|
+
```text
|
|
259
|
+
~/.cdx/
|
|
260
|
+
sessions.json # Session registry (versioned, all sessions)
|
|
261
|
+
state/
|
|
262
|
+
<encoded-name>.json # Per-session rehydration state
|
|
263
|
+
profiles/
|
|
264
|
+
<encoded-name>/ # Codex session: CODEX_HOME points here
|
|
265
|
+
log/
|
|
266
|
+
cdx-session.log # Terminal transcript (written by script(1))
|
|
267
|
+
<encoded-name>/
|
|
268
|
+
claude-home/ # Claude session: HOME points here
|
|
269
|
+
log/
|
|
270
|
+
cdx-session.log
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Session names are URL-encoded when used as directory or file names. CLI command names such as `add`, `status`, and `login` are reserved and cannot be used as session names.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Troubleshooting
|
|
278
|
+
|
|
279
|
+
- **`cdx <name>` fails with "not authenticated"** — run `cdx login <name>` first.
|
|
280
|
+
- **`cdx add` succeeds but the session does not appear** — check that `CDX_HOME` is consistent between calls; a mismatch creates two separate registries.
|
|
281
|
+
- **Status shows `n/a` for all fields** — the session has not been launched yet, or the provider has not written any status output to its history files. Launch the session and run `/status` inside it at least once.
|
|
282
|
+
- **`cdx rmv` says "Removal requires confirmation in an interactive terminal"** — pass `--force` to bypass the prompt in non-interactive environments (scripts, CI).
|
|
283
|
+
- **`cdx login` hangs** — the provider's login flow requires a browser or device code. Follow the on-screen instructions in the terminal that opened.
|
|
284
|
+
- **`make install` says `npm link` is not found** — ensure Node.js and npm are installed and in your PATH.
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Contributing
|
|
289
|
+
|
|
290
|
+
Contribution guidelines are available in [`CONTRIBUTING.md`](CONTRIBUTING.md).
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## License
|
|
295
|
+
|
|
296
|
+
This project is licensed under the MIT License. See [`LICENSE`](LICENSE).
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# CDX Manager
|
|
2
|
+
|
|
3
|
+
**Run multiple Codex and Claude sessions from one terminal. Switch between accounts instantly.**
|
|
4
|
+
|
|
5
|
+
If you use AI coding tools at scale ; multiple accounts, multiple providers : you know the friction: re-authenticating, losing context, juggling environment variables. `cdx` removes all of that.
|
|
6
|
+
|
|
7
|
+
One command to launch any session. Zero auth juggling.
|
|
8
|
+
|
|
9
|
+
[](LICENSE)  
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Table of Contents
|
|
14
|
+
|
|
15
|
+
- [What it does](#what-it-does)
|
|
16
|
+
- [Technical Overview](#technical-overview)
|
|
17
|
+
- [Getting Started](#getting-started)
|
|
18
|
+
- [All Commands](#all-commands)
|
|
19
|
+
- [Available Scripts](#available-scripts)
|
|
20
|
+
- [Project Structure](#project-structure)
|
|
21
|
+
- [Data Layout](#data-layout)
|
|
22
|
+
- [Troubleshooting](#troubleshooting)
|
|
23
|
+
- [Contributing](#contributing)
|
|
24
|
+
- [License](#license)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## What it does
|
|
29
|
+
|
|
30
|
+
- **Multiple accounts, one tool.** Register as many Codex or Claude sessions as you need. Each one gets its own isolated auth environment — no cross-contamination between accounts.
|
|
31
|
+
- **Instant launch.** `cdx work` opens your "work" session. `cdx personal` opens another. No config files to edit mid-flow.
|
|
32
|
+
- **Auth guardrails.** `cdx` checks authentication before launching. If a session is not logged in, it tells you exactly what to run — no silent failures.
|
|
33
|
+
- **Usage at a glance.** `cdx status` shows token usage, 5-hour window quota, weekly quota, and last-updated timestamps for every session in one aligned table.
|
|
34
|
+
- **Passive status resolution.** If a session has no recorded status, `cdx` reads it directly from the provider's session logs and JSONL history — no manual sync required.
|
|
35
|
+
- **Session transcript capture.** Every launch is recorded to a local log file via `script`, giving you a full terminal transcript for each session.
|
|
36
|
+
- **Clean removal.** `cdx rmv` wipes a session and its entire auth directory. No orphaned files, no stale credentials.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Technical Overview
|
|
41
|
+
|
|
42
|
+
- Python 3.9+, zero runtime dependencies.
|
|
43
|
+
- Environment isolation per session:
|
|
44
|
+
- Codex sessions override `CODEX_HOME` to a dedicated profile directory.
|
|
45
|
+
- Claude sessions override `HOME` to a dedicated profile directory.
|
|
46
|
+
- Persistence:
|
|
47
|
+
- Session registry at `~/.cdx/sessions.json` (versioned JSON store).
|
|
48
|
+
- Per-session state at `~/.cdx/state/<name>.json`.
|
|
49
|
+
- Auth and provider data under `~/.cdx/profiles/<name>/`.
|
|
50
|
+
- All paths are URL-encoded to support arbitrary session names.
|
|
51
|
+
- Status resolution pipeline:
|
|
52
|
+
- Primary source: recorded status fields on the session record.
|
|
53
|
+
- Fallback: `status-source` scans provider JSONL history files and terminal log transcripts, strips ANSI/OSC sequences, and extracts `usage%`, `5h remaining%`, and `week remaining%` via pattern matching.
|
|
54
|
+
- Claude status refreshes are cached briefly by default; pass `--refresh` to force a live rate-limit probe.
|
|
55
|
+
- If `script` is unavailable, Codex launch falls back to running without transcript capture.
|
|
56
|
+
- Auth probe: synchronous subprocess call to `codex login status` or `claude auth status` before any interactive launch.
|
|
57
|
+
- Signal forwarding: `SIGINT`, `SIGTERM`, and `SIGHUP` are forwarded to the child process and produce clean exit codes.
|
|
58
|
+
- Test stack: Python built-in `unittest` runner with no test framework dependency.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Getting Started
|
|
63
|
+
|
|
64
|
+
### Prerequisites
|
|
65
|
+
|
|
66
|
+
- Python 3.9+
|
|
67
|
+
- npm
|
|
68
|
+
- `codex` and/or `claude` CLI installed and available in your PATH
|
|
69
|
+
|
|
70
|
+
### Install
|
|
71
|
+
|
|
72
|
+
From npm:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npm install -g cdx-manager
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
With pipx:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pipx install cdx-manager
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
With uv:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
uv tool install cdx-manager
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
With the standalone GitHub installer:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
curl -fsSL https://raw.githubusercontent.com/AlexAgo83/cdx-manager/main/install.sh | sh
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
For a specific version:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
curl -fsSL https://raw.githubusercontent.com/AlexAgo83/cdx-manager/main/install.sh | CDX_VERSION=v0.3.0 sh
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
From source:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
git clone <repo>
|
|
106
|
+
cd cdx-manager
|
|
107
|
+
make install
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`cdx` is now available globally. Changes to the source take effect immediately — no reinstall needed.
|
|
111
|
+
|
|
112
|
+
To uninstall:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
make uninstall
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Alternatively, for a non-symlinked global source install:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
npm install -g .
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Environment
|
|
125
|
+
|
|
126
|
+
By default, `cdx` stores all data under `~/.cdx/`. Override with:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
export CDX_HOME=/path/to/custom/dir
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Optional runtime knobs:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
export CDX_CLAUDE_STATUS_MODEL=claude-haiku-4-5-20251001
|
|
136
|
+
export CDX_SCRIPT_BIN=script
|
|
137
|
+
export CDX_SCRIPT_ARGS='-q -F {transcript}'
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Quick Start
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Register a Codex session
|
|
144
|
+
cdx add work
|
|
145
|
+
|
|
146
|
+
# Register a Claude session
|
|
147
|
+
cdx add claude personal
|
|
148
|
+
|
|
149
|
+
# List all sessions
|
|
150
|
+
cdx
|
|
151
|
+
|
|
152
|
+
# Launch a session
|
|
153
|
+
cdx work
|
|
154
|
+
|
|
155
|
+
# Check usage across all sessions
|
|
156
|
+
cdx status
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## All Commands
|
|
162
|
+
|
|
163
|
+
| Command | Description |
|
|
164
|
+
|---|---|
|
|
165
|
+
| `cdx` | List all sessions with last-updated timestamps |
|
|
166
|
+
| `cdx <name>` | Launch a session (checks auth first) |
|
|
167
|
+
| `cdx add [provider] <name>` | Register a new session (`provider`: `codex` or `claude`, default: `codex`) |
|
|
168
|
+
| `cdx cp <source> <dest>` | Copy a session into another session name, overwriting the destination if it exists |
|
|
169
|
+
| `cdx ren <source> <dest>` | Rename a session and move its auth data |
|
|
170
|
+
| `cdx login <name>` | Re-authenticate a session (logout + login) |
|
|
171
|
+
| `cdx logout <name>` | Log out of a session |
|
|
172
|
+
| `cdx rmv <name> [--force]` | Remove a session and its auth data (prompts for confirmation unless `--force`) |
|
|
173
|
+
| `cdx clean [name]` | Clear launch transcript logs for one session or all sessions |
|
|
174
|
+
| `cdx doctor [--json]` | Inspect CLI dependencies, CDX_HOME permissions, missing state, orphan profiles, and pending quarantines |
|
|
175
|
+
| `cdx repair [--dry-run] [--force] [--json]` | Plan or apply safe repairs for missing state files, quarantines, and orphan profiles |
|
|
176
|
+
| `cdx notify <name> --at-reset [--poll seconds] [--once]` | Wait for a session reset time and send a desktop notification when due |
|
|
177
|
+
| `cdx notify --next-ready [--poll seconds] [--once]` | Wait until the recommended session is usable or needs a refresh after reset |
|
|
178
|
+
| `cdx status [--json] [--refresh]` | Show token usage table for all sessions; JSON keeps the same row-array shape and writes live Claude refresh warnings to stderr |
|
|
179
|
+
| `cdx status --small [--refresh]` / `cdx status -s [--refresh]` | Show compact token usage table without provider, blocking quota, credits, and updated columns |
|
|
180
|
+
| `cdx status <name> [--json] [--refresh]` | Show detailed usage breakdown for one session |
|
|
181
|
+
| `cdx --help` | Show usage |
|
|
182
|
+
| `cdx --version` | Show version |
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Available Scripts
|
|
187
|
+
|
|
188
|
+
- `npm test`: run the Python test suite
|
|
189
|
+
- `npm run test:py`: run the Python unit tests directly
|
|
190
|
+
- `npm run lint`: byte-compile the Python sources and tests
|
|
191
|
+
- `npm run link`: link `cdx` globally for local development (`npm link`)
|
|
192
|
+
- `npm run unlink`: remove the global link
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Project Structure
|
|
197
|
+
|
|
198
|
+
```text
|
|
199
|
+
bin/
|
|
200
|
+
cdx # Entry point — shebang + main() call
|
|
201
|
+
|
|
202
|
+
src/
|
|
203
|
+
cli.py # Top-level command router
|
|
204
|
+
cli_commands.py # Command handlers and argument handling
|
|
205
|
+
cli_render.py # Terminal formatting, tables, colors, and errors
|
|
206
|
+
status_view.py # Status table/detail rendering and priority ranking
|
|
207
|
+
provider_runtime.py # Provider launch/auth commands, transcripts, signals
|
|
208
|
+
claude_refresh.py # Claude usage refresh orchestration
|
|
209
|
+
session_service.py # Session lifecycle: create, copy, rename, launch, remove, status
|
|
210
|
+
# resolution, auth state management
|
|
211
|
+
session_store.py # JSON persistence layer: sessions.json + per-session
|
|
212
|
+
# state files
|
|
213
|
+
status_source.py # Status artifact discovery: scans JSONL history files
|
|
214
|
+
# and terminal log transcripts, strips ANSI sequences,
|
|
215
|
+
# extracts usage metrics via pattern matching
|
|
216
|
+
config.py # CDX_HOME resolution (env override or ~/.cdx)
|
|
217
|
+
errors.py # CdxError with optional exit code
|
|
218
|
+
__init__.py # Public Python exports
|
|
219
|
+
|
|
220
|
+
test/
|
|
221
|
+
test_cli_py.py # CLI command dispatch tests
|
|
222
|
+
test_session_service_py.py # Session service unit tests
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Data Layout
|
|
228
|
+
|
|
229
|
+
All session data lives under `CDX_HOME` (default: `~/.cdx/`):
|
|
230
|
+
|
|
231
|
+
```text
|
|
232
|
+
~/.cdx/
|
|
233
|
+
sessions.json # Session registry (versioned, all sessions)
|
|
234
|
+
state/
|
|
235
|
+
<encoded-name>.json # Per-session rehydration state
|
|
236
|
+
profiles/
|
|
237
|
+
<encoded-name>/ # Codex session: CODEX_HOME points here
|
|
238
|
+
log/
|
|
239
|
+
cdx-session.log # Terminal transcript (written by script(1))
|
|
240
|
+
<encoded-name>/
|
|
241
|
+
claude-home/ # Claude session: HOME points here
|
|
242
|
+
log/
|
|
243
|
+
cdx-session.log
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Session names are URL-encoded when used as directory or file names. CLI command names such as `add`, `status`, and `login` are reserved and cannot be used as session names.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Troubleshooting
|
|
251
|
+
|
|
252
|
+
- **`cdx <name>` fails with "not authenticated"** — run `cdx login <name>` first.
|
|
253
|
+
- **`cdx add` succeeds but the session does not appear** — check that `CDX_HOME` is consistent between calls; a mismatch creates two separate registries.
|
|
254
|
+
- **Status shows `n/a` for all fields** — the session has not been launched yet, or the provider has not written any status output to its history files. Launch the session and run `/status` inside it at least once.
|
|
255
|
+
- **`cdx rmv` says "Removal requires confirmation in an interactive terminal"** — pass `--force` to bypass the prompt in non-interactive environments (scripts, CI).
|
|
256
|
+
- **`cdx login` hangs** — the provider's login flow requires a browser or device code. Follow the on-screen instructions in the terminal that opened.
|
|
257
|
+
- **`make install` says `npm link` is not found** — ensure Node.js and npm are installed and in your PATH.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Contributing
|
|
262
|
+
|
|
263
|
+
Contribution guidelines are available in [`CONTRIBUTING.md`](CONTRIBUTING.md).
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## License
|
|
268
|
+
|
|
269
|
+
This project is licensed under the MIT License. See [`LICENSE`](LICENSE).
|