feat(pool): an admin's switch moves a user's Claude login at once
PUT /api/accounts/pins (and agenthub accounts pin) now writes a pinned Claude login into the user's home right away (claude-pool.switchHome): every home's newer pair is copied back first, the member's own login is never written over, and no pane is restarted — running sessions take the new pair at their next credentials read. A live home stays on the login it holds, so unpinning does not flip it back. The Users page calls it "Switch a user's account" and says what happened.
This commit is contained in:
+21
-14
@@ -355,7 +355,7 @@ claude setup-token
|
||||
agenthub accounts add team-1
|
||||
agenthub accounts list # live panes, $ and tokens in the last 5 h / 7 d, quota, state
|
||||
agenthub accounts remove team-1
|
||||
agenthub accounts pin team-1 mia # mia's new sessions always run on team-1 (unpin mia to undo)
|
||||
agenthub accounts pin team-1 mia # switch mia to team-1 (unpin mia = automatic again)
|
||||
```
|
||||
|
||||
In server mode an admin can do the same on the **Users** page, in the
|
||||
@@ -424,19 +424,26 @@ How a new session picks its account (`server/lib/claude-pool.js`):
|
||||
pane still needs that member's own `/login`.
|
||||
- A token more than a year old is skipped.
|
||||
- A resumed session picks an account again, like a new one.
|
||||
- **Pinning a user to one account.** An admin can skip the ranking for one
|
||||
user: **Pin a user** in the Account pool card (or
|
||||
`agenthub accounts pin <account> <user> [--tool codex]`, `unpin <user>` to
|
||||
undo; their own password again, audited). Every new session in a workspace
|
||||
that user OWNS then runs on that account, even when it is full — other users
|
||||
are not affected, and the account is not reserved for them. The pin is a
|
||||
preference the pool still bounds: an expired account, or a login a host pane
|
||||
may not take, falls back to the ranking; and since a home holds one
|
||||
`.credentials.json`, a pinned login waits until that user's panes on another
|
||||
pool login have ended (a setup-token or API key pin goes in by env and
|
||||
applies at once). Running sessions keep their account. Removing the account
|
||||
drops its pins; deleting the user drops theirs. Pins apply in server mode only
|
||||
(`server/lib/account-pins.js`).
|
||||
- **Switching a user to one account.** An admin can take one user off the
|
||||
ranking: **Switch a user's account** in the Account pool card (or
|
||||
`agenthub accounts pin <account> <user> [--tool codex]`, `unpin <user>` for
|
||||
automatic again; their own password again, audited). Every session in a
|
||||
workspace that user OWNS then runs on that account, even when it is full;
|
||||
other users are not affected, and the account is not reserved for them.
|
||||
- **A Claude login switches at once, without a restart.** The server first
|
||||
copies every home's newer pair back into the pool (so the login leaving
|
||||
the home keeps its only live refresh token), then writes the new login
|
||||
into the user's `~/.claude/.credentials.json` as them. New sessions start
|
||||
on it; sessions already running keep their process and move to it the
|
||||
next time Claude Code re-reads its credentials (it does so before it
|
||||
refreshes its access token, so at the latest when that token expires).
|
||||
A login the user made themselves (`/login`) is never written over — the
|
||||
card says so. Their sessions are booked to the account they started on.
|
||||
- A setup-token, a Codex account, or a host pane gets the account at its
|
||||
next spawn; running ones keep theirs.
|
||||
- An expired account falls back to the ranking. Removing the account drops
|
||||
the switch; deleting the user drops theirs. Server mode only
|
||||
(`server/lib/account-pins.js`).
|
||||
- Quota is read with each account's own token, in the background, at most every
|
||||
5 minutes. If the usage endpoint refuses a setup-token, the state column shows
|
||||
`no quota (…)` and ranking uses spend alone.
|
||||
|
||||
Reference in New Issue
Block a user