@bjesuiter/codex-switcher 1.3.0 → 1.5.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.
Files changed (3) hide show
  1. package/README.md +146 -44
  2. package/cdx.mjs +1094 -111
  3. package/package.json +3 -1
package/README.md CHANGED
@@ -6,20 +6,27 @@ Switch the coding-agents [pi](https://pi.dev/), [codex](https://developers.opena
6
6
 
7
7
  ## Latest Changes
8
8
 
9
- ### 1.3.0
9
+ ### 1.5.0
10
10
 
11
11
  #### Features
12
12
 
13
- - Rename `cdx refresh` command to `cdx relogin`
13
+ - Add shell completion support via `cdx complete <shell>` (with parse-completion handling for shell integrations).
14
+ - Add configurable secret-store selection with `--secret-store <mode>` (`auto` or `legacy-keychain`) plus persisted config support.
15
+ - Switch macOS `auto` secret storage to cross-keychain backend selection (prefers native backend, falls back when needed).
16
+ - Add `cdx migrate-secrets` to migrate legacy macOS keychain entries to cross-keychain and update config.
17
+ - Add optional macOS keychain ACL diagnostics in `cdx doctor --check-keychain-acl` to verify trusted runtime access.
18
+ - Add doctor/runtime warnings when macOS keychain access is using legacy/CLI fallback paths where Touch ID prompts may not be offered.
19
+ - Increase cross-keychain max password length handling (default `16384`) to support larger stored credential payloads.
14
20
 
15
21
  #### Fixes
16
22
 
17
- - Fix `cdx relogin` selector flow exiting early after account selection (now continues into OAuth browser login)
23
+ - Keep `cdx doctor` fast by making keychain ACL checks opt-in and improving output with clearer guidance and progress feedback.
24
+ - Remove Windows credential payload chunking now that larger payloads are supported directly in the secure store backend.
18
25
 
19
26
  #### Internal
20
27
 
21
- - Modularize CLI command wiring by moving command handlers into per-command modules under `lib/commands/`, keeping `cdx.ts` as a thin composition entrypoint
22
- - Update package dependencies and lockfile (`@clack/prompts`, `commander`, `tsdown`, `@types/bun`, `@types/node`)
28
+ - Temporarily switch keyring dependency from `cross-keychain` to `@bjesuiter/cross-keychain@1.1.0-jb.0` until upstream support is available.
29
+ - Add Windows CI coverage including shell smoke checks and expanded secure-store integration tests (including Windows CRUD coverage).
23
30
 
24
31
  see full changelog here: https://github.com/bjesuiter/codex-switcher/blob/main/CHANGELOG.md
25
32
 
@@ -41,9 +48,15 @@ So: switching between two $20 plans is the poor man's $100 plan for OpenAI. ^^
41
48
 
42
49
  ## Requirements
43
50
 
44
- - macOS (uses Keychain via the `security` command)
51
+ - macOS (uses Keychain), Windows (uses Windows Credential Manager), **or** Linux (uses Secret Service/keyring)
45
52
  - [Bun](https://bun.sh) runtime
46
53
 
54
+ ## Platform Support Status
55
+
56
+ - **macOS:** stable
57
+ - **Windows:** beta
58
+ - **Linux:** beta
59
+
47
60
  ## Install
48
61
 
49
62
  ```bash
@@ -54,63 +67,102 @@ This exposes the `cdx` binary globally.
54
67
 
55
68
  ## Usage
56
69
 
57
- ### Add your first account
70
+ ### macOS (stable)
71
+
72
+ 1. Install [Bun](https://bun.sh)
73
+ 2. Install `cdx`
74
+ 3. Run and verify:
75
+ - `cdx login`
76
+ - `cdx status`
77
+ - `cdx switch`
78
+ - `cdx relogin <account-id-or-label>`
79
+ 4. Confirm auth files are written correctly after switching:
80
+ - `~/.local/share/opencode/auth.json` (or `$XDG_DATA_HOME/opencode/auth.json`)
81
+ - `~/.codex/auth.json`
82
+ - `~/.pi/agent/auth.json` (or `$PI_CODING_AGENT_DIR/auth.json`)
83
+ 5. Credentials are stored in macOS Keychain.
84
+
85
+ ### Windows (beta)
86
+
87
+ Windows support is **test-ready** and suitable for friend/beta testing, but is not yet production-proven by broad real-world testing.
88
+
89
+ 1. Install [Bun](https://bun.sh)
90
+ 2. Install `cdx`
91
+ 3. Run and verify:
92
+ - `cdx login`
93
+ - `cdx status`
94
+ - `cdx switch`
95
+ - `cdx relogin <account-id-or-label>`
96
+ 4. Confirm auth files are written correctly after switching:
97
+ - `%LOCALAPPDATA%\\opencode\\auth.json`
98
+ - `%USERPROFILE%\\.codex\\auth.json`
99
+ - `%USERPROFILE%\\.pi\\agent\\auth.json` (or `%PI_CODING_AGENT_DIR%\\auth.json`)
100
+ 5. If prompted about secure-store fallback, explicitly choose whether to allow it for testing.
101
+ - Non-interactive override (if you accept the risk): `CDX_ALLOW_SECURE_STORE_FALLBACK=1`
102
+
103
+ ### Linux (beta)
104
+
105
+ Linux support is **test-ready** and suitable for friend/beta testing, but is not yet production-proven by broad real-world testing.
106
+
107
+ 1. Install [Bun](https://bun.sh)
108
+ 2. Ensure a Secret Service backend is available (for example GNOME Keyring with `secret-tool`)
109
+ 3. Install `cdx`
110
+ 4. Run and verify:
111
+ - `cdx login`
112
+ - `cdx status`
113
+ - `cdx switch`
114
+ - `cdx relogin <account-id-or-label>`
115
+ 5. Confirm auth files are written correctly after switching:
116
+ - `~/.local/share/opencode/auth.json` (or `$XDG_DATA_HOME/opencode/auth.json`)
117
+ - `~/.codex/auth.json`
118
+ - `~/.pi/agent/auth.json` (or `$PI_CODING_AGENT_DIR/auth.json`)
119
+ 6. If prompted about secure-store fallback, explicitly choose whether to allow it for testing.
120
+ - Non-interactive override (if you accept the risk): `CDX_ALLOW_SECURE_STORE_FALLBACK=1`
121
+
122
+ Please report the full command output and platform info (`cdx status`) for any failures.
123
+
124
+ ### Common command examples (all platforms)
125
+
126
+ Add your first account:
58
127
 
59
128
  ```bash
60
129
  cdx login
61
130
  ```
62
131
 
63
- Opens your browser to authenticate with OpenAI. After successful login, your credentials are stored securely in macOS Keychain.
64
-
65
- ### Switch between accounts
132
+ Switch between accounts:
66
133
 
67
134
  ```bash
68
135
  cdx switch
69
- ```
70
-
71
- Interactive picker to select an account. Writes credentials to:
72
- - `~/.local/share/opencode/auth.json` (OpenCode)
73
- - `~/.pi/agent/auth.json` (Pi agent, or `$PI_CODING_AGENT_DIR/auth.json` when `PI_CODING_AGENT_DIR` is set)
74
- - `~/.codex/auth.json` (Codex CLI; requires `id_token`)
75
-
76
- ```bash
77
136
  cdx switch --next
137
+ cdx switch <account-id-or-label>
78
138
  ```
79
139
 
80
- Cycles to the next configured account without prompting.
140
+ Label accounts:
81
141
 
82
142
  ```bash
83
- cdx switch <account-id-or-label>
143
+ cdx label
144
+ cdx label <account> <new-label>
84
145
  ```
85
146
 
86
- Switch directly to a specific account by ID or label.
87
-
88
- ### Label accounts
147
+ Interactive mode:
89
148
 
90
149
  ```bash
91
- cdx label
150
+ cdx
92
151
  ```
93
152
 
94
- Interactive prompt to assign a friendly name to an account.
153
+ Use the legacy macOS keychain implementation (if needed):
95
154
 
96
155
  ```bash
97
- cdx label <account> <new-label>
156
+ cdx --secret-store legacy-keychain switch
157
+ cdx --secret-store legacy-keychain status
98
158
  ```
99
159
 
100
- Assign a label directly.
101
-
102
- ### Interactive mode
160
+ Migrate legacy macOS keychain entries to cross-keychain (`auto`) and update config:
103
161
 
104
162
  ```bash
105
- cdx
163
+ cdx migrate-secrets
106
164
  ```
107
165
 
108
- Running `cdx` without arguments opens an interactive menu to:
109
- - List all configured accounts
110
- - Switch to a different account
111
- - Add a new account (OAuth login)
112
- - Remove an account
113
-
114
166
  ## Commands
115
167
 
116
168
  | Command | Description |
@@ -124,22 +176,71 @@ Running `cdx` without arguments opens an interactive menu to:
124
176
  | `cdx switch <id>` | Switch to specific account |
125
177
  | `cdx label` | Label an account (interactive) |
126
178
  | `cdx label <account> <label>` | Assign label directly |
127
- | `cdx status` | Show account status, token expiry, usage, and auth file state |
179
+ | `cdx status` | Show account status, token expiry, and usage |
180
+ | `cdx migrate-secrets` | Migrate macOS legacy keychain entries to cross-keychain and switch config to `auto` |
181
+ | `cdx doctor` | Show auth file paths/state and runtime capabilities |
182
+ | `cdx doctor --check-keychain-acl` | Run additional macOS keychain trusted-app/ACL checks (slow) |
128
183
  | `cdx usage` | Show usage overview for all accounts |
129
184
  | `cdx usage <account>` | Show detailed usage for a specific account |
130
185
  | `cdx help [command]` | Show help for all commands or one command |
186
+ | `cdx complete <shell>` | Generate shell completion script (`zsh`, `bash`, `fish`, `powershell`) |
131
187
  | `cdx version` | Show CLI version |
132
188
  | `cdx --help` | Show help |
133
189
  | `cdx --version` | Show version |
190
+ | `cdx --secret-store legacy-keychain <command>` | Override configured backend for this run (macOS legacy keychain) |
191
+
192
+ ### Shell completion
193
+
194
+ Generate and source completion scripts:
195
+
196
+ ```bash
197
+ # zsh
198
+ source <(cdx complete zsh)
199
+
200
+ # bash
201
+ source <(cdx complete bash)
202
+ ```
203
+
204
+ `cdx` also supports shell parse completion requests via `cdx complete -- ...`.
134
205
 
135
206
  ## How It Works
136
207
 
137
- - OAuth credentials are stored securely in macOS Keychain
138
- - Account list is stored in `~/.config/cdx/accounts.json`
139
- - Active account credentials are written to:
140
- - `~/.local/share/opencode/auth.json`
141
- - `~/.pi/agent/auth.json` (or `$PI_CODING_AGENT_DIR/auth.json`)
142
- - `~/.codex/auth.json` (when `id_token` exists)
208
+ ### Secure credential storage
209
+
210
+ - **macOS:** macOS Keychain
211
+ - **Windows:** Windows Credential Manager
212
+ - **Linux:** Secret Service/keyring
213
+ - Default backend selection is automatic (`auto`).
214
+ - You can persist a preferred backend in `accounts.json` via optional `"secretStore"` (`"auto"` or `"legacy-keychain"`).
215
+ - `--secret-store <mode>` always overrides config for the current run.
216
+ - If only a fallback secure-store backend is available on your platform, `cdx` asks for one-time explicit consent before the first credential write and explains the security trade-off.
217
+ - Non-interactive override (if you accept the risk): set `CDX_ALLOW_SECURE_STORE_FALLBACK=1`
218
+ - On macOS, `cdx doctor --check-keychain-acl` performs an additional trusted-app/ACL check for configured account secrets. This check can be slow.
219
+ - Cross-keychain payload size policy:
220
+ - Default max password length override is `16384`.
221
+ - Optional override: set `CDX_CROSS_KEYCHAIN_MAX_PASSWORD_LENGTH=<integer-above-4096>`.
222
+ - This currently relies on `@bjesuiter/cross-keychain@1.1.0-jb.0` until upstream support is released.
223
+
224
+ ### Account list path
225
+
226
+ - **macOS/Linux:** `~/.config/cdx/accounts.json` (or `$XDG_CONFIG_HOME/cdx/accounts.json`)
227
+ - **Windows:** `%APPDATA%\\cdx\\accounts.json`
228
+
229
+ ### Auth file paths
230
+
231
+ #### macOS / Linux
232
+
233
+ - **OpenCode:** `~/.local/share/opencode/auth.json` (or `$XDG_DATA_HOME/opencode/auth.json`)
234
+ - **Codex CLI:** `~/.codex/auth.json`
235
+ - **Pi Agent:** `~/.pi/agent/auth.json` (or `$PI_CODING_AGENT_DIR/auth.json`)
236
+
237
+ #### Windows
238
+
239
+ - **OpenCode:** `%LOCALAPPDATA%\\opencode\\auth.json`
240
+ - **Codex CLI:** `%USERPROFILE%\\.codex\\auth.json`
241
+ - **Pi Agent:** `%USERPROFILE%\\.pi\\agent\\auth.json` (or `%PI_CODING_AGENT_DIR%\\auth.json`)
242
+
243
+ `cdx` writes Codex CLI auth only when `id_token` exists.
143
244
 
144
245
  ## For Developers
145
246
 
@@ -162,7 +263,7 @@ bun link
162
263
 
163
264
  ### Manual Configuration (Advanced)
164
265
 
165
- You can also manually add accounts to Keychain:
266
+ You can also manually add accounts to Keychain (macOS only):
166
267
 
167
268
  ```bash
168
269
  security add-generic-password -a "ACCOUNT_ID" -s "cdx-openai-ACCOUNT_ID" -w '{"refresh":"REFRESH","access":"ACCESS","expires":1234567890,"accountId":"ACCOUNT_ID"}' -U
@@ -173,6 +274,7 @@ And create the accounts list manually:
173
274
  ```json
174
275
  {
175
276
  "current": 0,
277
+ "secretStore": "auto",
176
278
  "accounts": [
177
279
  { "accountId": "ACCOUNT_ID", "keychainService": "cdx-openai-ACCOUNT_ID" }
178
280
  ]