@youdie006/swapdex 0.155.0 → 0.158.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 +55 -3
  2. package/man/swapdex.1 +12 -6
  3. package/package.json +5 -5
package/README.md CHANGED
@@ -148,15 +148,27 @@ so it can't be logged out), `swapdex restore` undoes the last swap, and `swapdex
148
148
  ui` is the full-screen picker. `swapdex migrate` matches Claude and Codex
149
149
  profiles to slots by account and creates spaces only for accounts without one.
150
150
 
151
- `status` shows the live account per tool, matched back to a saved profile:
151
+ `status` shows the active account per tool, matched back to a saved profile:
152
152
 
153
153
  ```
154
154
  claude-code: you@work.com [max] (profile 'work')
155
155
  codex: you@personal.com [chatgpt] (profile 'personal')
156
156
  ```
157
157
 
158
- The active account is always read from the **live** login, so if you `/login`
159
- directly in the CLI, swapdex reports the truth rather than a stale guess.
158
+ The active account is read from the **pointer** a switch sets, and falls back
159
+ to the live login on a machine that has no slots. Where the tool's own config
160
+ dir holds a different account -- you signed in directly without the shim, or an
161
+ old copy-model switch left one behind -- that gets its own line rather than
162
+ being shown as the active account:
163
+
164
+ ```
165
+ codex: you@work.com (profile 'work')
166
+ (a plain `codex` would launch on 'personal' instead - `swapdex shim`
167
+ makes it follow your switches)
168
+ ```
169
+
170
+ Both are true and they answer different questions, so swapdex prints both
171
+ instead of picking one. A machine sat in exactly that state for six days.
160
172
 
161
173
  For your shell prompt or statusline, `status --short` prints one compact line:
162
174
 
@@ -228,6 +240,36 @@ setup is one keystroke and a name.
228
240
  <img src="https://raw.githubusercontent.com/youdie006/swapdex/main/docs/ui-demo.gif" alt="swapdex ui on a fresh machine: it finds the Claude Code and Codex logins already present, saves them as a profile named main, and shows the account with its 5h and 7d usage bars" width="760" />
229
241
  </div>
230
242
 
243
+ ## Keeping accounts from expiring
244
+
245
+ An account nobody opens dies on its own. These refresh tokens go stale when
246
+ they are not exercised -- measured across two machines, an idle Codex slot
247
+ stops working about ten days after its last run -- and once the refresh token
248
+ is gone only a browser sign-in brings the account back.
249
+
250
+ swapdex renews idle accounts for you, but **only while its proxy is running**,
251
+ because that is the process holding the timer:
252
+
253
+ ```sh
254
+ swapdex service install --tool claude
255
+ swapdex service install --tool codex
256
+ ```
257
+
258
+ That installs a launchd/systemd unit per tool. The proxy then sweeps every
259
+ thirty minutes and renews anything approaching its deadline, including slots
260
+ nobody has opened. A slot the tool is running in is never touched: its own
261
+ session holds the refresh token, and renewing from outside would retire the one
262
+ that session is about to use.
263
+
264
+ Without the service, nothing is on a timer. You can sweep by hand:
265
+
266
+ ```sh
267
+ swapdex refresh --keep-alive # renew every account heading for expiry
268
+ swapdex refresh <name> # renew one that has already lapsed
269
+ ```
270
+
271
+ `swapdex doctor` reports whether the service is installed and running.
272
+
231
273
  ## How it works
232
274
 
233
275
  **Slots (the model swapdex uses now).** Each account gets its own
@@ -280,6 +322,16 @@ their own slots, retiring the shared homes.
280
322
  like `~/.ssh`, and do not sync it across machines (it is single-machine,
281
323
  single-user by design).
282
324
 
325
+ **Do not copy a credential out of the store for something else to use.** These
326
+ refresh tokens are single-use: the server retires the outgoing one whenever a
327
+ holder renews, so two programs holding one account's credential silently
328
+ retire each other's. The copy that missed a renewal keeps working until its
329
+ access token lapses, which is why the failure arrives hours or days after the
330
+ change that caused it -- one such split cost a scheduled job 42 hours. A
331
+ program that needs its own Codex or Claude access should sign in for itself;
332
+ `swapdex` is for accounts a person switches between, not a credential source
333
+ for other software.
334
+
283
335
  ### What it will not do
284
336
 
285
337
  These are structural properties, not promises -- the code is built so they
package/man/swapdex.1 CHANGED
@@ -1,6 +1,6 @@
1
1
  .ie \n(.g .ds Aq \(aq
2
2
  .el .ds Aq '
3
- .TH swapdex 1 "swapdex 0.155.0"
3
+ .TH swapdex 1 "swapdex 0.158.0"
4
4
  .SH NAME
5
5
  swapdex \- Switch Claude Code / Codex / Gemini / Antigravity login accounts, locally and safely.
6
6
  .SH SYNOPSIS
@@ -23,7 +23,7 @@ swapdex\-use(1)
23
23
  Switch the active login to a saved profile
24
24
  .TP
25
25
  swapdex\-run(1)
26
- Launch Claude in an account\*(Aqs own permanent slot (concurrent\-safe)
26
+ Launch a tool in an account\*(Aqs own permanent slot (concurrent\-safe)
27
27
  .TP
28
28
  swapdex\-whereis(1)
29
29
  Find which account holds a conversation (searches every account\*(Aqs store)
@@ -41,7 +41,7 @@ swapdex\-slots(1)
41
41
  List the permanent account slots
42
42
  .TP
43
43
  swapdex\-shim(1)
44
- Install the `claude` shim so a plain `claude` follows `swapdex use`
44
+ Install the shims so a plain `claude` or `codex` follows `swapdex use`
45
45
  .TP
46
46
  swapdex\-adopt(1)
47
47
  Register an existing CLAUDE_CONFIG_DIR directory as a slot (in place)
@@ -56,11 +56,17 @@ swapdex\-sync\-mcp(1)
56
56
  Share MCP servers (from ~/.claude.json) into every account slot
57
57
  .TP
58
58
  swapdex\-ls(1)
59
- List saved profiles (active marked from the live login)
59
+ List accounts, marking the one each tool is pointed at
60
60
  .TP
61
61
  swapdex\-status(1)
62
62
  Show the active account per tool
63
63
  .TP
64
+ swapdex\-pause(1)
65
+ Keep an account out of the proxy\*(Aqs AUTOMATIC rotation (`use`/`serve` still work)
66
+ .TP
67
+ swapdex\-resume(1)
68
+ Put a paused account back in rotation
69
+ .TP
64
70
  swapdex\-rm(1)
65
71
  Remove a saved profile (never touches a live login)
66
72
  .TP
@@ -89,7 +95,7 @@ swapdex\-share\-history(1)
89
95
  Make every conversation reachable from every account (one\-time repair)
90
96
  .TP
91
97
  swapdex\-slash(1)
92
- Install a `/sx` slash command for Claude Code (switch without leaving the chat)
98
+ Install a `/swap` command for Claude Code and Codex (switch inside the chat)
93
99
  .TP
94
100
  swapdex\-threshold(1)
95
101
  Step off an account at this much used (e.g. 0.9 or 90%), or `off`
@@ -130,4 +136,4 @@ Print the man page (roff) to stdout
130
136
  swapdex\-help(1)
131
137
  Print this message or the help of the given subcommand(s)
132
138
  .SH VERSION
133
- v0.155.0
139
+ v0.158.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@youdie006/swapdex",
3
- "version": "0.155.0",
3
+ "version": "0.158.0",
4
4
  "description": "Switch between multiple Claude Code, Codex, Gemini, and Antigravity login accounts, locally and safely.",
5
5
  "bin": {
6
6
  "swapdex": "bin/swapdex.js"
@@ -12,10 +12,10 @@
12
12
  "man/swapdex.1"
13
13
  ],
14
14
  "optionalDependencies": {
15
- "@youdie006/swapdex-darwin-arm64": "0.155.0",
16
- "@youdie006/swapdex-darwin-x64": "0.155.0",
17
- "@youdie006/swapdex-linux-x64": "0.155.0",
18
- "@youdie006/swapdex-linux-arm64": "0.155.0"
15
+ "@youdie006/swapdex-darwin-arm64": "0.158.0",
16
+ "@youdie006/swapdex-darwin-x64": "0.158.0",
17
+ "@youdie006/swapdex-linux-x64": "0.158.0",
18
+ "@youdie006/swapdex-linux-arm64": "0.158.0"
19
19
  },
20
20
  "keywords": [
21
21
  "cli",