cdx-manager 0.20.14 → 0.21.0

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.
@@ -0,0 +1,183 @@
1
+ # Getting started
2
+
3
+ ## Prerequisites
4
+
5
+ - Node.js 18+ with npm
6
+ - Python 3.9+
7
+ - `codex`, `claude`, `agy`, and/or `ollama` CLI installed and available in your PATH
8
+
9
+ On Windows, the npm launcher looks for Python in this order: `py -3`, `python`, then `python3`. Make sure at least one of those commands resolves to Python 3.
10
+
11
+ ## Install
12
+
13
+ From npm:
14
+
15
+ ```bash
16
+ npm install -g cdx-manager
17
+ ```
18
+
19
+ With pipx:
20
+
21
+ ```bash
22
+ pipx install cdx-manager
23
+ ```
24
+
25
+ With uv:
26
+
27
+ ```bash
28
+ uv tool install cdx-manager
29
+ ```
30
+
31
+ On Windows with PowerShell:
32
+
33
+ ```powershell
34
+ npm install -g cdx-manager
35
+ ```
36
+
37
+ With the standalone PowerShell installer:
38
+
39
+ ```powershell
40
+ Invoke-WebRequest https://raw.githubusercontent.com/AlexAgo83/cdx-manager/main/install.ps1 -OutFile install.ps1
41
+ # Optional: set CDX_SHA256 before running if you have a trusted checksum.
42
+ # Set CDX_ALLOW_UNVERIFIED=1 only if you intentionally accept an unverified archive.
43
+ powershell -ExecutionPolicy Bypass -File .\install.ps1
44
+ ```
45
+
46
+ With the standalone GitHub installer:
47
+
48
+ ```bash
49
+ curl -fsSL https://raw.githubusercontent.com/AlexAgo83/cdx-manager/main/install.sh -o install.sh
50
+ # Optional: set CDX_SHA256 before running if you have a trusted checksum.
51
+ # Set CDX_ALLOW_UNVERIFIED=1 only if you intentionally accept an unverified archive.
52
+ sh install.sh
53
+ ```
54
+
55
+ For a specific version:
56
+
57
+ ```bash
58
+ curl -fsSL https://raw.githubusercontent.com/AlexAgo83/cdx-manager/main/install.sh -o install.sh
59
+ CDX_VERSION=v0.8.0 sh install.sh
60
+ ```
61
+
62
+ From source:
63
+
64
+ ```bash
65
+ git clone <repo>
66
+ cd cdx-manager
67
+ make install
68
+ ```
69
+
70
+ For local development, install the Python toolchain as well:
71
+
72
+ ```bash
73
+ python3 -m pip install -e ".[dev]"
74
+ ```
75
+
76
+ From source on Windows:
77
+
78
+ ```powershell
79
+ git clone <repo>
80
+ cd cdx-manager
81
+ npm install -g .
82
+ ```
83
+
84
+ `cdx` is now available globally. Changes to the source take effect immediately — no reinstall needed.
85
+
86
+ To update an installed copy later:
87
+
88
+ ```bash
89
+ cdx update
90
+ ```
91
+
92
+ To uninstall:
93
+
94
+ ```bash
95
+ make uninstall
96
+ ```
97
+
98
+ To uninstall on Windows after `npm install -g`:
99
+
100
+ ```powershell
101
+ npm uninstall -g cdx-manager
102
+ ```
103
+
104
+ Alternatively, for a non-symlinked global source install:
105
+
106
+ ```bash
107
+ npm install -g .
108
+ ```
109
+
110
+ Security note:
111
+
112
+ - The standalone installers resolve official release checksums from the tagged GitHub Release asset `release-archives.json`.
113
+ - You can still override verification explicitly through `CDX_SHA256`.
114
+ - If no checksum is available, standalone installers fail closed unless `CDX_ALLOW_UNVERIFIED=1` is set; that override prints a prominent warning before continuing.
115
+ - Prefer `npm`, `pipx`, or `uv` when you want registry-backed install flows.
116
+ - If you use the standalone script, download it first, inspect it, and prefer a release with the official checksum asset attached.
117
+
118
+
119
+ ## Environment
120
+
121
+ By default, `cdx` stores all data under `~/.cdx/`. Override with:
122
+
123
+ ```bash
124
+ export CDX_HOME=/path/to/custom/dir
125
+ ```
126
+
127
+ Optional runtime knobs:
128
+
129
+ ```bash
130
+ export CDX_CLAUDE_STATUS_MODEL=claude-haiku-4-5-20251001
131
+ export CDX_SCRIPT_BIN=script
132
+ export CDX_SCRIPT_ARGS='-q -F {transcript}'
133
+ ```
134
+
135
+ PowerShell equivalents:
136
+
137
+ ```powershell
138
+ $env:CDX_HOME = "C:\cdx-data"
139
+ $env:CDX_CLAUDE_STATUS_MODEL = "claude-haiku-4-5-20251001"
140
+ $env:CDX_SCRIPT_BIN = "script"
141
+ $env:CDX_SCRIPT_ARGS = "-q -F {transcript}"
142
+ ```
143
+
144
+ Command Prompt equivalents:
145
+
146
+ ```cmd
147
+ set CDX_HOME=C:\cdx-data
148
+ set CDX_CLAUDE_STATUS_MODEL=claude-haiku-4-5-20251001
149
+ set CDX_SCRIPT_BIN=script
150
+ set CDX_SCRIPT_ARGS=-q -F {transcript}
151
+ ```
152
+
153
+ ## Quick Start
154
+
155
+ ```bash
156
+ # Register a Codex session
157
+ cdx add work
158
+
159
+ # Register a Claude session
160
+ cdx add claude personal
161
+
162
+ # Register an Ollama session
163
+ cdx add ollama local --model llama3.2
164
+
165
+ # List all sessions
166
+ cdx
167
+
168
+ # Launch a session
169
+ cdx work
170
+
171
+ # Check usage across all sessions
172
+ cdx status
173
+
174
+ # Pick the best session using the same priority logic as status
175
+ cdx next
176
+
177
+ # Notify when the next cooling-down assistant is ready
178
+ cdx ready
179
+
180
+ # Inspect CDX_HOME and profile disk usage
181
+ cdx disk
182
+ cdx disk profiles --candidates
183
+ ```
@@ -0,0 +1,161 @@
1
+ # Operations
2
+
3
+ ## Backup And Restore
4
+
5
+ You can move sessions between machines with portable bundles:
6
+
7
+ ```bash
8
+ cdx export backup.cdx
9
+ cdx import backup.cdx
10
+ ```
11
+
12
+ To migrate auth and avoid logging in again, include auth data in an encrypted bundle:
13
+
14
+ ```bash
15
+ export CDX_BUNDLE_PASSPHRASE='choose-a-strong-passphrase'
16
+ cdx export backup-auth.cdx --include-auth --passphrase-env CDX_BUNDLE_PASSPHRASE
17
+ cdx import backup-auth.cdx --passphrase-env CDX_BUNDLE_PASSPHRASE
18
+ ```
19
+
20
+ Notes:
21
+
22
+ - `--include-auth` is encrypted, requires a passphrase, and exports only provider credential files rather than full profile caches, logs, or installed plugins.
23
+ - Keychain-backed Claude authentication cannot currently be exported. If any selected profile uses it, `--include-auth` exits non-zero before writing anything, including with `--force`; text and JSON errors identify the affected profiles. Export without `--include-auth` and log in after import, or select only profiles whose authentication is file-backed. An inaccessible keychain is an explicit error, not a successful incomplete export.
24
+ - Merge imports snapshot each existing profile before modification, preserving symlinks instead of following them. This temporarily needs space for a second copy of that profile. On failure, CDX restores the original files, record and state; if recovery also fails, the error gives the retained recovery directory containing the original metadata and any remaining profile snapshot.
25
+ - Without `--passphrase-env`, `cdx` prompts in an interactive terminal. Non-interactive callers can pass `--passphrase-stdin` to read the passphrase from stdin (one line) instead of exposing it in the child environment.
26
+ - `--sessions work,perso` exports or imports only a subset.
27
+ - `--force` allows overwriting existing destination sessions during import or replacing an existing bundle file during export. Import preserves detected local `plugins/` state when the bundle does not provide it, and refuses to overwrite existing sessions from a bundle without auth payloads unless `--allow-authless-force` is also passed.
28
+ - Auth bundles contain credentials. Treat them like secrets and delete them after transfer.
29
+
30
+ ## Release checklist
31
+
32
+ - Name the GitHub Release `CDX Manager X.Y.Z` (for example, `CDX Manager 0.21.0`); use `vX.Y.Z` for its tag and the checked-in versioned changelog for its notes.
33
+ - Before publishing npm or PyPI packages, run `npm run release:validate`.
34
+ - The release tag must match `package.json`, `pyproject.toml`, `src/cli.py`, and `VERSION`.
35
+ - `checksums/release-archives.json` must include the matching `vX.Y.Z` entry with both `github_tarball_sha256` and `github_zip_sha256`.
36
+ - Publishing a GitHub Release runs the checksum upload workflow: it regenerates `checksums/release-archives.json` for the release tag and uploads it as the `release-archives.json` asset with replacement enabled for safe reruns.
37
+ - If the asset is missing or stale, repair it with `python3 scripts/update_release_checksums.py --tag vX.Y.Z`, then `gh release upload vX.Y.Z checksums/release-archives.json --clobber`.
38
+ - Publish packages only after the checksum workflow succeeds and `npm run release:validate`, `npm run lint`, and `npm test` pass.
39
+
40
+ ## Available Scripts
41
+
42
+ - `npm test`: run the Python test suite with `pytest`
43
+ - `npm run test:py`: run `pytest` through the portable launcher
44
+ - `npm run test:coverage`: run `pytest` with terminal coverage reporting for `src/`
45
+ - `npm run lint`: check project guidance, the Node launcher, `ruff`, and byte-compile the Python sources, scripts, and tests
46
+ - `npm run release:validate`: verify version alignment and required GitHub release archive checksum metadata before publication
47
+ - `npm run link`: link `cdx` globally for local development (`npm link`)
48
+ - `npm run unlink`: remove the global link
49
+
50
+ ## Windows Support
51
+
52
+ - Supported install paths on Windows:
53
+ - `npm install -g cdx-manager`
54
+ - `pipx install cdx-manager`
55
+ - `uv tool install cdx-manager`
56
+ - `install.ps1`
57
+ - The npm launcher resolves Python via `py -3`, `python`, then `python3`, so a global npm install works even when `python3.exe` is missing.
58
+ - `install.sh` is Unix-only.
59
+ - `make install` and `make uninstall` are Unix-oriented convenience commands, not the default Windows path.
60
+ - `cdx` isolates Claude sessions on Windows by setting `HOME`, `USERPROFILE`, `HOMEDRIVE`, and `HOMEPATH`.
61
+ - Desktop notifications use PowerShell on Windows.
62
+ - Codex transcript capture is optional on Windows:
63
+ - if a compatible `script` command is available and exposed via `CDX_SCRIPT_BIN`, `cdx` uses it
64
+ - otherwise Codex launches without transcript capture and the session still works normally
65
+ - `cdx doctor` reports the transcript-capture fallback explicitly so missing `script` on Windows is visible without being treated as a hard failure.
66
+ - `cdx doctor --json` includes detected `codex --version` and `claude --version` output when available, plus conservative capability hints for recent provider memory, model, and headless diagnostic surfaces. These hints are informational; `cdx` does not edit provider-private memory stores.
67
+
68
+ ## Disk maintenance
69
+
70
+ Use `cdx disk` for a total `CDX_HOME` measurement, and `cdx disk profiles` for the `profiles/` total plus a per-profile breakdown.
71
+
72
+ In an interactive terminal, long scans report their current stage and per-profile progress on stderr. JSON and redirected output remain free of progress messages.
73
+
74
+ Text output uses aligned summary tables with profile size, share of total space, and reclaimable space. Candidate details are grouped by profile with separate size, type, risk, and evidence columns.
75
+
76
+ ```bash
77
+ cdx disk
78
+ cdx disk profiles
79
+ ```
80
+
81
+ To find cleanup candidates without deleting anything:
82
+
83
+ ```bash
84
+ cdx disk profiles --candidates
85
+ cdx disk profiles --candidates --json
86
+ ```
87
+
88
+ Candidate evidence includes profile name, path, size, risk, reason, and metadata such as modified time or old-log file counts. The current cleanup candidates are intentionally limited to:
89
+
90
+ - temporary marketplace/plugin staging caches under `profiles/*/.tmp/`
91
+ - `.log` files older than the requested age inside profile `log/` directories
92
+
93
+ `cdx` also runs a passive disk cleanup check at most once per day on advisory commands such as `cdx` and `cdx status`. It writes the check timestamp and latest measurements to `~/.cdx/state/disk-cleanup-check.json`. A warning is shown only when at least one threshold is met:
94
+
95
+ - `CDX_HOME` uses 10 GB or more
96
+ - cleanup candidates can reclaim 1 GB or more
97
+ - temporary cache candidates can reclaim 500 MB or more
98
+ - old log candidates can reclaim 500 MB or more
99
+ - one profile is 2 GB or more, or one profile is at least 25% of `profiles/` when `profiles/` is already 1 GB or more
100
+
101
+ The passive warning is read-only and points to `cdx disk profiles --candidates`; it never deletes files.
102
+
103
+ Apply cleanup only with explicit actions:
104
+
105
+ ```bash
106
+ cdx clean profiles --tmp
107
+ cdx clean profiles --old-logs 30d
108
+ ```
109
+
110
+ `--tmp` removes temporary marketplace/plugin clone/backup staging directories. `--old-logs 30d` removes only `.log` files older than 30 days. The commands do not remove `auth.json`, `config.toml`, `sessions/`, SQLite state, installed `plugins/`, `skills/`, or credentials.
111
+
112
+ All `cdx clean` actions require interactive confirmation before any deletion or log truncation begins. Non-interactive scripts must pass `--yes` explicitly.
113
+
114
+ The cleanup action is selected only when `--tmp` or `--old-logs` is present. This keeps `cdx clean profiles` available for an existing session named `profiles`. If any candidate or old log cannot be removed, cleanup stops with a non-zero error that identifies the affected path; it does not report the operation as successful.
115
+
116
+ ## Banked Codex resets
117
+
118
+ Eligible Codex accounts expose manually redeemable rate-limit resets through the Codex app-server. `cdx status` shows their available count in the `RESETS` column; `cdx status <name>` also shows the nearest known expiration, and JSON status includes the available reset details supplied by Codex.
119
+
120
+ Activation is always explicit:
121
+
122
+ ```bash
123
+ cdx reset <name>
124
+ cdx reset <name> --yes --json
125
+ ```
126
+
127
+ Without `--yes`, an interactive confirmation is required. `cdx` sends an idempotency key, consumes at most one available reset, and refreshes the session status after a successful activation. It never activates a reset from `cdx status` or any background check.
128
+
129
+ ## Troubleshooting
130
+
131
+ ### Codex credential refresh
132
+
133
+ `cdx auth refresh work` makes a provider-native, non-generation request for one
134
+ managed Codex profile. It can refresh an expiring access token, but never starts
135
+ an agent or submits a prompt. Use `cdx auth refresh all --json` when a scheduler
136
+ needs a stable result; CDX never installs or enables that scheduler for you.
137
+
138
+ For example, a user-owned daily cron entry can run:
139
+
140
+ ```sh
141
+ 0 6 * * * cdx auth refresh all --json
142
+ ```
143
+
144
+ `locked` means an interactive session owns the profile refresh lock and was left
145
+ untouched. If every selected profile is locked, the command is non-zero because
146
+ it verified no credential; a mix of valid and locked profiles remains successful.
147
+ Bulk refresh skips disabled profiles, while `cdx auth refresh <name>` still lets
148
+ an operator inspect one explicitly. `login_required` means the provider rejected
149
+ the local refresh token; run the supplied `cdx login <name>` command interactively.
150
+ Hosts keep independent rotating credentials, so copying an auth file is not ongoing
151
+ credential sync.
152
+
153
+ - **`cdx <name>` fails with "not authenticated"** — run `cdx login <name>` first. `cdx doctor` uses the same Codex app-server probe as `cdx auth refresh`, so a local auth file alone is never reported as live authentication; a rejected refresh token is reported as `login_required` with the matching login command.
154
+ - **One of two Codex accounts keeps asking for login** — run `cdx doctor --json` and inspect each Codex session's `codex_auth_file`, `codex_live_auth`, and `codex_stale_auth_logs` checks. If recent logs mention expired auth, repair only that isolated profile with `cdx login <name>`. Codex Business profiles can share the same `tokens.account_id`; `cdx doctor` reports `codex_shared_account_id` as a workspace-level clue, not proof that two profiles use the same user. Newly created sessions seed from the current global `~/.codex/auth.json` when one exists. For two separate Codex accounts, create or repair each session by running `cdx login <name>` for that session; `cdx login` does not log out first, so use `cdx logout <name>` explicitly only when you want to clear that isolated profile.
155
+ - **`cdx` says no compatible Python 3 interpreter was found** — install Python 3 and make `py -3`, `python`, or `python3` available on PATH.
156
+ - **`cdx add` succeeds but the session does not appear** — check that `CDX_HOME` is consistent between calls; a mismatch creates two separate registries.
157
+ - **Status shows `n/a` for all fields** — the Codex app-server rate-limit probe may be unavailable, the session may not be authenticated, and no legacy transcript/history status has been captured yet.
158
+ - **`cdx rmv` says "Removal requires confirmation in an interactive terminal"** — pass `--force` to bypass the prompt in non-interactive environments (scripts, CI).
159
+ - **`cdx login` hangs** — the provider's login flow requires a browser or device code. Follow the on-screen instructions in the terminal that opened.
160
+ - **`make install` says `npm link` is not found** — ensure Node.js and npm are installed and in your PATH.
161
+ - **On Windows, `doctor` warns that `script` is missing** — this is expected on many setups. Codex still launches, but transcript capture stays disabled unless you point `CDX_SCRIPT_BIN` to a compatible wrapper.
@@ -0,0 +1,138 @@
1
+ # Sessions and notifications
2
+
3
+ ## Agent notifications
4
+
5
+ When a session's agent finishes a turn, or stops to wait for you, cdx raises a
6
+ desktop notification naming the session and the repository:
7
+
8
+ ```text
9
+ ✓ work1 logics-manager · needs your attention
10
+ ✓ codex-a cdx-manager · turn complete
11
+ ```
12
+
13
+ CDX asks once at the first eligible interactive launch before writing a provider hook. Consent is installation-wide, but each profile receives its hook only when it is next launched. Alert delivery then starts muted; use `cdx tray alerts on` when you want banners. The older per-session commands remain compatible:
14
+
15
+ ```bash
16
+ cdx set work1 --notify on # turn it on for one session
17
+ cdx set --all --notify on # turn it on everywhere
18
+ cdx set work1 --notify off # and back off; cdx removes what it installed
19
+ cdx set work1 --notify-preview on # include a short final-response preview
20
+ ```
21
+
22
+ Turning it on records the setting. The wiring happens at that session's **next
23
+ launch**: cdx writes the hook into the session's own home and says so once.
24
+ Claude Code honours it straight away. Codex only runs hooks that come from an
25
+ installed plugin, so cdx generates one per session and installs it — and Codex
26
+ asks you to approve it once, which cdx leaves to you rather than writing that
27
+ trust on your behalf.
28
+
29
+ It is off by default because turning it on writes into the provider's own
30
+ configuration and, on Codex, puts an approval prompt in front of you. That is
31
+ not something to do to sessions you already own without being asked.
32
+
33
+ New sessions inherit response previews when agent alerts were accepted during
34
+ tray installation. A completion notification includes at most 180 characters
35
+ of the agent's final response, and a permission request may quote the
36
+ provider's own one-line description of what it wants to do. That text can be
37
+ visible on a lock screen; disable it per session with
38
+ `cdx set <name> --notify-preview off`. Previews never read transcripts, and the
39
+ command a permission request is about is never included.
40
+
41
+ Both providers are subscribed to the same two hooks: `Stop` when a turn ends and
42
+ `PermissionRequest` when one blocks on your approval. Claude Code is also
43
+ subscribed to `Notification`, for the "still waiting for you" states that no
44
+ other hook reports; the permission notifications it also sends are dropped,
45
+ because `PermissionRequest` already reported the same call immediately and by
46
+ name.
47
+
48
+ Claude Code additionally reports a turn that ended on a provider error rather
49
+ than on an answer — a rate limit, an overload, an authentication or billing
50
+ problem. Those alerts are marked apart from completions, name the error class,
51
+ and say whether the failure is one that usually clears on its own or one that
52
+ needs you. Codex documents no equivalent hook, so a Codex turn killed by its
53
+ provider stays silent; that is a gap in what the provider publishes, not a
54
+ setting.
55
+
56
+ A running tray companion receives each alert as fields rather than as a
57
+ sentence, so its menu can name the session, the project and the tool, and
58
+ clicking a recent alert opens the session it came from. The tool's arguments,
59
+ the transcript path and the provider's own session identifiers are never part of
60
+ that — only what cdx already knew and what the providers document as safe
61
+ metadata.
62
+
63
+ `cdx notify` is the internal hook target, called by the provider; it is not the
64
+ setup command. `cdx ready` is separate: it notifies you when the next cooling-
65
+ down session becomes usable.
66
+
67
+ Per platform: macOS uses `osascript`, Linux `notify-send`, Windows a toast, and
68
+ WSL reaches the Windows notification centre through interop. On a host with no
69
+ way to deliver one — a headless or SSH Linux session, or WSL with interop
70
+ disabled — cdx installs no hooks at all rather than asking you to approve
71
+ something that could show you nothing. Headless `cdx run` never notifies: its
72
+ caller already learns of completion from the return value.
73
+
74
+ Use `cdx ready` when every useful assistant is cooling down and you want your terminal back. cdx picks the next known reset, registers a native OS notification, and exits immediately. If no future reset is known, it exits successfully and explains that no notification was scheduled.
75
+
76
+ ```bash
77
+ cdx ready
78
+ cdx ready --refresh
79
+ ```
80
+
81
+ ## Persistent Launch Settings
82
+
83
+ New sessions start with `power=medium` and `fast=off`, so launches are predictable without enabling fast mode. Set or override only the values you want to pin:
84
+
85
+ ```bash
86
+ cdx set work --power medium --permission full --fast off
87
+ cdx set personal --power low --permission review
88
+ cdx set --sessions all --permission auto
89
+ cdx set --provider ollama --model llama3.2
90
+ cdx set work --priority 80
91
+ cdx set work --rtk on
92
+ cdx set work --logics off
93
+ cdx power all low
94
+ cdx perm provider:claude review
95
+ cdx model provider:ollama llama3.2
96
+ cdx config work
97
+ cdx configs
98
+ ```
99
+
100
+ Those values are stored on the session and reapplied every time you run `cdx work`. Remove overrides to return to provider-native defaults:
101
+
102
+ ```bash
103
+ cdx unset work --power
104
+ cdx unset --sessions work,personal --fast
105
+ cdx unset --provider claude --permission
106
+ cdx unset work --priority
107
+ cdx unset work --rtk
108
+ cdx unset work --logics
109
+ cdx unset work --all
110
+ cdx power all default
111
+ cdx model provider:ollama default
112
+ ```
113
+
114
+ `--model` maps to Codex `--model`, Claude `--model`, and Ollama `ollama run <model>`. `--power` maps to Codex `model_reasoning_effort` and Claude `--effort`; supported values are `minimal`, `low`, `medium`, `high`, and `xhigh`. `--permission` maps to provider-native permission flags. Codex Fast mode is separate from reasoning effort: `--fast on` opts a Codex session into the Codex Fast service tier, while new sessions, `--fast off`, and default launches force the non-Fast `flex` tier. Use `--power low` when you want low reasoning effort without enabling Codex Fast credits. Existing legacy sessions that stored `fast=on` before this split continue to behave as low effort unless the user explicitly sets `--fast on` again. `--priority` is a 0..100 selector preference used as a tie-breaker after readiness and availability. `--rtk on` adds standing guidance that encourages assistants to use RTK (`rtk <command>`) for noisy terminal commands when RTK is available, while keeping raw commands for exact output. Logics guidance is auto-enabled when `logics-manager` is available; use `--logics off` to disable that guidance for a session, or `--logics on` to pin it explicitly. This guidance is passed as instructions, never as a first message: Claude receives it through `--append-system-prompt` and Codex through `-c developer_instructions=...`, appended after any `developer_instructions` already set in the profile's `config.toml` (on Python older than 3.11 without `tomli`, a profile that sets its own is left untouched and gets no cdx guidance). Launching or resuming a session therefore never submits a turn on your behalf. Antigravity and Ollama have no instruction channel and receive no guidance. If you also pass `--append-system-prompt` through `--extra-args`, Claude receives the option twice; prefer putting your own text in the profile's `CLAUDE.md`.
115
+
116
+ ## Terminal Titles
117
+
118
+ Interactive launches and resumes set the terminal window title to `session — folder`, where `folder` is the basename of the launch directory - for example `work — cdx-manager`. The convention is identical for Claude, Codex, and Antigravity: it comes from the shared launch runtime, not from provider flags, and cdx keeps re-asserting it so a provider TUI cannot take the title back mid-session.
119
+
120
+ The title is only written when stdout is a terminal. Nothing is emitted for `--json` launches, redirected or piped output, `cdx run` and other headless runs, login flows, or Ollama sessions. Session names and directories are stripped of escape and control characters before the title is emitted, and cdx does not restore the previous title when the session ends.
121
+
122
+ Claude Code writes its own animated title while an action runs, and it redraws far more often than cdx re-asserts the shared title. So interactive Claude launches and resumes started by cdx set the Claude-specific `CLAUDE_CODE_DISABLE_TERMINAL_TITLE=1` in the provider environment, which stops Claude from setting and clearing the title and leaves `session — folder` stable while Claude is busy. Claude's in-TUI activity indicator is unaffected, the value is forced so an ambient setting in your shell cannot hand the title back, and headless `cdx run`, Claude authentication flows, and every non-Claude provider keep their previous environment.
123
+
124
+ ## Launch History
125
+
126
+ Every interactive `cdx <name>` launch is recorded under `CDX_HOME`, including success/failure, duration, cwd, launch settings, and transcript path.
127
+
128
+ ```bash
129
+ cdx history
130
+ cdx history work
131
+ cdx history work --limit 5
132
+ cdx history work --json
133
+ cdx history --summary
134
+ cdx history --summary --since 7d
135
+ cdx history --summary --from 2026-05-01 --to 2026-05-28
136
+ ```
137
+
138
+ `cdx history --summary` aggregates total time per assistant. Add `--since`, `--from`, or `--to` to focus on a period.
@@ -0,0 +1,92 @@
1
+ # Technical reference
2
+
3
+ ## Technical Overview
4
+
5
+ - Python 3.9+.
6
+ - Environment isolation per session:
7
+ - Codex sessions override `CODEX_HOME` to a dedicated profile directory.
8
+ - Claude sessions override `HOME` to a dedicated profile directory and disable Claude Code commit co-author attribution by default.
9
+ - On macOS, Claude credentials use a profile-specific keychain entry. Quota refresh reads that entry before legacy credential files; `cdx cp` and `cdx ren` transfer only the profile's entry, never the system keychain directory. Rename refuses existing destination entries and reports any old-entry cleanup failure after the new session becomes usable; `cdx rm` deletes the profile's entry with the profile.
10
+ - Antigravity sessions launch `agy` with a dedicated `HOME` for file-based settings; Google account credentials may still be stored in the OS keyring by Antigravity itself.
11
+ - Ollama sessions use the local Ollama server and launch `ollama run <model>`; set a model with `cdx set <name> --model <model>`.
12
+ - New Codex sessions seed their auth home from your existing global `~/.codex/auth.json` when available, so an already logged-in Codex CLI can be reused without giving up per-session isolation afterward.
13
+ - Persistence:
14
+ - Session registry at `~/.cdx/sessions.json` (versioned JSON store).
15
+ - Per-session state at `~/.cdx/state/<name>.json`.
16
+ - Per-workspace shared context at `~/.cdx/contexts/<workspace-hash>/context.md`.
17
+ - Auth and provider data under `~/.cdx/profiles/<name>/`.
18
+ - All paths are URL-encoded to support arbitrary session names.
19
+ - Status resolution pipeline:
20
+ - Primary source: recorded status fields on the session record.
21
+ - Codex live source: `codex app-server` JSON-RPC `account/rateLimits/read`, normalized into 5-hour, weekly, reset, credit, and plan fields.
22
+ - 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.
23
+ - Status latency controls: use `cdx status --cached` to skip live probes, `cdx status --timeout SECONDS` for one command, or `CDX_STATUS_TIMEOUT_SECONDS` to lower the default Codex live-probe timeout.
24
+ - Claude status refreshes are cached briefly by default; pass `--refresh` to force a live rate-limit probe.
25
+ - On Linux, transcript capture uses the `util-linux` `script -c` command form.
26
+ - If `script` is unavailable, Codex launch falls back to running without transcript capture.
27
+ - On Windows, transcript capture is optional. If no compatible `script` wrapper is installed, Codex still launches normally without transcript capture.
28
+ - Auth probe: synchronous subprocess call to `codex login status` or `claude auth status` before any interactive launch.
29
+ - Signal forwarding: `SIGINT`, `SIGTERM`, and `SIGHUP` are forwarded to the child process and produce clean exit codes.
30
+ - Test stack: `pytest`, `pytest-cov`, and `ruff` via the documented `dev` dependency extra.
31
+
32
+ ## Project Structure
33
+
34
+ ```text
35
+ bin/
36
+ cdx.js # Node launcher used by npm
37
+ python-runner.js # Shared Python resolver and process wrapper
38
+ cdx # Python entrypoint invoked by the launcher
39
+
40
+ src/
41
+ cli.py # Top-level command router
42
+ cli_commands.py # Command handlers and argument handling
43
+ cli_render.py # Terminal formatting, tables, colors, and errors
44
+ backup_bundle.py # Portable session bundle encoding/decoding + auth encryption
45
+ status_view.py # Status table/detail rendering and priority ranking
46
+ provider_runtime.py # Provider launch/auth commands, transcripts, signals
47
+ claude_refresh.py # Claude usage refresh orchestration
48
+ session_service.py # Session lifecycle: create, copy, rename, launch, remove, status
49
+ # resolution, auth state management
50
+ session_store.py # JSON persistence layer: sessions.json + per-session
51
+ # state files
52
+ status_source.py # Status artifact discovery: scans JSONL history files
53
+ # and terminal log transcripts, strips ANSI sequences,
54
+ # extracts usage metrics via pattern matching
55
+ config.py # CDX_HOME resolution (env override or ~/.cdx)
56
+ errors.py # CdxError with optional exit code
57
+ __init__.py # Public Python exports
58
+
59
+ test/
60
+ test_cli_py.py # CLI command dispatch tests
61
+ test_session_service_py.py # Session service unit tests
62
+ ```
63
+
64
+ ## Data Layout
65
+
66
+ All session data lives under `CDX_HOME` (default: `~/.cdx/`):
67
+
68
+ ```text
69
+ ~/.cdx/
70
+ sessions.json # Session registry (versioned, all sessions)
71
+ state/
72
+ <encoded-name>.json # Per-session rehydration state
73
+ launch_history.jsonl # Append-only launch history
74
+ contexts/
75
+ <workspace-hash>/context.md # Current-workspace shared context / memory
76
+ global/context.md # Global cdx memory
77
+ projects/<encoded-name>/context.md # Named project memory from cdx memory --project NAME
78
+ profiles/
79
+ <encoded-name>/ # Codex session: CODEX_HOME points here
80
+ log/
81
+ cdx-session.log # Terminal transcript (written by script(1))
82
+ <encoded-name>/
83
+ claude-home/ # Claude session: HOME points here
84
+ log/
85
+ cdx-session.log
86
+ ```
87
+
88
+ Session names are URL-encoded when used as directory or file names. CLI command names such as `add`, `disk`, `status`, and `login` are reserved and cannot be used as new session names.
89
+
90
+ `cdx memory` is the user-facing interface for explicit memory. `--project NAME` uses a stable free-form project name; `--project /path/to/repo` resolves to the same workspace-hash memory that repo would use as the current workspace. `append` adds the text as-is with a clean newline boundary; it does not add dates or headings. `list` reports global memory, named project memories, and the current workspace memory when present; it does not scan your filesystem for repos.
91
+
92
+ Provider-private memory files, such as Codex SQLite memory databases or Claude Code project memory files, are not edited by `cdx memory`.