@youdie006/swapdex 0.2.0 → 0.2.2

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 (2) hide show
  1. package/README.md +95 -7
  2. package/package.json +3 -2
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  <img src="https://raw.githubusercontent.com/youdie006/swapdex/main/docs/cli-banner.png" alt="swapdex - switch Claude Code and Codex login accounts, one command, all local" width="760" />
4
4
 
5
5
  [![CI](https://github.com/youdie006/swapdex/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/youdie006/swapdex/actions/workflows/ci.yml)
6
- [![license](https://img.shields.io/badge/license-MIT-1e1d1a.svg)](https://github.com/youdie006/swapdex/blob/main/LICENSE)
6
+ [![license](https://img.shields.io/badge/license-MIT-1e1d1a.svg)](LICENSE)
7
7
  [![local only](https://img.shields.io/badge/network-none-7a3be0.svg)](#what-it-will-not-do)
8
8
 
9
9
  </div>
@@ -12,6 +12,10 @@ One command to flip your Claude Code or Codex CLI from your work account to your
12
12
  personal one, and back. No re-login, no browser, no copying tokens around.
13
13
  100% local. Never touches the network.
14
14
 
15
+ <div align="center">
16
+ <img src="https://raw.githubusercontent.com/youdie006/swapdex/main/docs/demo.gif" alt="swapdex demo: ls, use personal, status, restore, doctor" width="760" />
17
+ </div>
18
+
15
19
  ---
16
20
 
17
21
  ## Why
@@ -26,6 +30,10 @@ It is a **switcher, not a rotator.** It manages accounts you already own for
26
30
  distinct purposes. It has no feature for cycling accounts to get around a rate
27
31
  limit -- see [What it will not do](#what-it-will-not-do).
28
32
 
33
+ Safety is the design center: swapdex captures the *live* login before it swaps,
34
+ so a switch can never lose or clobber an account, and it only ever hands the
35
+ official CLI its own credentials -- no wrapper, no proxy, no client spoofing.
36
+
29
37
  ## Concepts
30
38
 
31
39
  - **Profile** -- a named, point-in-time snapshot of a live login (the credential
@@ -51,9 +59,10 @@ npm install -g @youdie006/swapdex
51
59
  curl -fsSL https://raw.githubusercontent.com/youdie006/swapdex/main/install.sh | sh
52
60
  ```
53
61
 
54
- Linux / WSL first (macOS Keychain support is planned). Requires the Claude Code
62
+ Linux / WSL first; on macOS, Codex works today and Claude-via-Keychain is
63
+ [issue #1](https://github.com/youdie006/swapdex/issues/1). Requires the Claude Code
55
64
  and/or Codex CLI already installed and logged in. Full command, exit-code, and
56
- environment reference: [docs/COMMANDS.md](https://github.com/youdie006/swapdex/blob/main/docs/COMMANDS.md).
65
+ environment reference: [docs/COMMANDS.md](docs/COMMANDS.md).
57
66
 
58
67
  ## Use
59
68
 
@@ -68,11 +77,22 @@ swapdex status
68
77
 
69
78
  # Switch (takes effect on your next message -- no restart)
70
79
  swapdex use personal
80
+ swapdex use - # toggle back to the previous profile
81
+ swapdex use w # a unique prefix is enough
71
82
  swapdex use work --tool codex
72
83
  swapdex use work --dry-run # show what would change, write nothing
73
84
 
74
85
  # Sessions grouped by the account active when they ran (needs sessionwiki)
75
86
  swapdex sessions
87
+
88
+ # Recent local token usage per tool (5h/7d) -- tells you when to switch
89
+ swapdex usage
90
+
91
+ # Made a bad switch? Put back the login that was live before it
92
+ swapdex restore
93
+
94
+ # Anything off? Every finding comes with its fix
95
+ swapdex doctor
76
96
  ```
77
97
 
78
98
  `status` shows the live account per tool, matched back to a saved profile:
@@ -85,6 +105,40 @@ codex: you@personal.com (profile 'personal')
85
105
  The active account is always read from the **live** login, so if you `/login`
86
106
  directly in the CLI, swapdex reports the truth rather than a stale guess.
87
107
 
108
+ For your shell prompt or statusline, `status --short` prints one compact line:
109
+
110
+ ```sh
111
+ $ swapdex status --short
112
+ claude:work codex:personal
113
+ ```
114
+
115
+ e.g. in a starship prompt: `command = "swapdex status --short"` in a
116
+ [custom module](https://starship.rs/config/#custom-commands), or in `PS1`
117
+ via `$(swapdex status --short)`.
118
+
119
+ It also drops straight into **Claude Code's own status line**, so the active
120
+ account is always visible inside the tool you are switching
121
+ (`~/.claude/settings.json`):
122
+
123
+ ```json
124
+ {
125
+ "statusLine": { "type": "command", "command": "swapdex status --short" }
126
+ }
127
+ ```
128
+
129
+ `usage` reads your local session logs (no network) to gauge how heavily you've
130
+ been using each tool lately, so you know when to switch to a fresher account:
131
+
132
+ ```
133
+ Local usage - this machine, approximate (not the billed quota):
134
+ claude-code 5h: 8.2M tok / 12 sess 7d: 61.4M tok / 88 sess
135
+ codex 5h: 1.1M tok / 3 sess 7d: 9.7M tok / 24 sess
136
+ ```
137
+
138
+ It sums tokens from `~/.claude` and `~/.codex` transcripts, which are not tagged
139
+ by account, so this is a machine-wide activity gauge rather than a per-account
140
+ balance -- deliberately a hint, not a quota-dodging auto-rotator.
141
+
88
142
  ## How it works
89
143
 
90
144
  Each CLI keeps its login in a small on-disk file:
@@ -105,8 +159,11 @@ servers, and settings in that file are never touched.
105
159
  - Writes are atomic (temp file created `0600`, then renamed) so an interrupted
106
160
  switch can never leave a half-written credential that bricks the CLI.
107
161
  - Symlinked credential paths and running as root are refused.
108
- - `use` backs up the current login and verifies the backup before overwriting,
109
- so a switch can never lose an un-saved login.
162
+ - `use` writes a backup of the current login (fsynced, or the switch aborts)
163
+ before overwriting anything, and `swapdex restore` brings it back in one
164
+ command if the switch was a mistake. The store keeps the last 2 backups per
165
+ tool, and `use` warns when the outgoing login is not saved as a profile --
166
+ so save accounts you care about with `add`.
110
167
  - No token, refresh token, or home path is ever printed.
111
168
 
112
169
  **The store holds plaintext refresh tokens.** Protect `~/.local/share/swapdex`
@@ -124,11 +181,17 @@ cannot happen:
124
181
  - **No auto-rotation.** There is no `--auto`, `--next`, or
125
182
  `--when-rate-limited` flag. `use` only ever switches to a name you type.
126
183
  - **No token export.** There is no command that prints a saved credential.
184
+ - **No wrapper, no client spoofing.** swapdex swaps the credential file that the
185
+ official `claude` / `codex` binary already reads, then gets out of the way. It
186
+ never sits between the CLI and the API, never proxies requests, and never
187
+ presents itself as the official client. Your traffic is the real CLI's traffic.
127
188
 
128
189
  Anthropic and OpenAI both permit multiple accounts for genuinely different
129
190
  purposes but forbid using multiple accounts to get around a single workload's
130
- rate limit, and forbid using OAuth tokens outside the official CLI. swapdex is
131
- built for the former and structurally cannot do the latter. See
191
+ rate limit, and forbid routing subscription OAuth tokens through third-party
192
+ tools or spoofing the official client. swapdex is built for the former and
193
+ structurally cannot do the latter -- it only ever hands the real CLI its own
194
+ credentials. See
132
195
  [Anthropic Usage Policy](https://www.anthropic.com/legal/usage-policy) and
133
196
  [OpenAI Usage Policies](https://openai.com/policies/usage-policies/).
134
197
 
@@ -151,8 +214,33 @@ swapdex is the accounts layer of a small local AI-CLI stack:
151
214
  - [prodex](https://github.com/youdie006/prodex) -- share one logged-in ChatGPT
152
215
  Pro session across agents. swapdex coexists with it without touching its auth.
153
216
 
217
+ ## Alternatives
218
+
219
+ Good tools exist in this space; they make different trade-offs (each line from
220
+ that project's README, July 2026):
221
+
222
+ - [claude-swap](https://github.com/realiti4/claude-swap) -- Claude Code only,
223
+ a TUI with live usage bars, and *optional auto-switching* near your limit.
224
+ If you want auto-rotation, use it -- swapdex deliberately refuses to have
225
+ that feature.
226
+ - [aisw](https://github.com/burakdede/aisw) -- cross-tool including Gemini,
227
+ OS-keyring storage, Windows support. More features, bigger surface.
228
+ - [caam](https://github.com/Dicklesworthstone/coding_agent_account_manager) --
229
+ cross-tool with a shell wrapper and automatic rotation on rate limits; the
230
+ philosophical opposite of swapdex.
231
+
232
+ Pick swapdex if you want the smallest thing that switches Claude Code and
233
+ Codex together, can always undo (`restore`), diagnoses itself (`doctor`),
234
+ and structurally cannot rotate, proxy, or touch the network.
235
+
154
236
  ## Roadmap
155
237
 
238
+ - **Claude Code on macOS (Keychain).** On macOS, Claude Code keeps its login in
239
+ the Keychain rather than a file; swapdex detects this and refuses honestly
240
+ instead of half-switching, but switching it is not supported yet. Design and
241
+ constraints: [issue #1](https://github.com/youdie006/swapdex/issues/1) --
242
+ contributions from macOS users welcome (Codex already works on macOS).
243
+
156
244
  Being considered, explicitly opt-in and advisory-only:
157
245
 
158
246
  - **Per-directory hints (cross-tool).** Bind a directory to a profile and have
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@youdie006/swapdex",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Switch between multiple Claude Code and Codex login accounts, locally and safely.",
5
5
  "bin": {
6
6
  "swapdex": "bin/swapdex.js"
7
7
  },
8
8
  "scripts": {
9
- "postinstall": "node install.js"
9
+ "postinstall": "node install.js",
10
+ "prepublishOnly": "cp ../README.md ./README.md"
10
11
  },
11
12
  "files": [
12
13
  "README.md",