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:
2026-10-19 10:23:44 +07:00
parent 9c98638ec0
commit 776ad6466f
16 changed files with 208 additions and 89 deletions
+12 -9
View File
@@ -198,21 +198,24 @@
"codex": "An OpenAI API key (sk-…), or the whole ~/.codex/auth.json after `codex login` with a ChatGPT account."
},
"refreshFailed": "refresh failed",
"pinned": "Pinned: {{users}}",
"pinUser": "Pin a user",
"pinTitle": "Pin a user to an account",
"pinHint": "That user's new sessions always run on the chosen account instead of the least-used one — even when it is full. Sessions already running keep their account; a login waits until the user's sessions on another login have ended.",
"pinButton": "Save pin",
"pinned": "Used by: {{users}}",
"pinUser": "Switch a user's account",
"pinTitle": "Switch a user's account",
"pinHint": "That user's sessions run on the chosen account instead of the least-used one — even when it is full. A Claude login is written into their home at once: sessions already running move to it at their next login check, with no restart. A setup-token or Codex account applies to new sessions.",
"pinButton": "Switch",
"user": "User",
"chooseUser": "Choose a user…",
"loadingUsers": "Loading…",
"pinAccount": "Account",
"noPin": "None — the least-used account",
"pinsTitle": "Pinned users",
"unpin": "Unpin {{name}}",
"noPin": "Automatic — the least-used account",
"pinsTitle": "Switched users",
"unpin": "Back to automatic for {{name}}",
"pinDone": {
"pinned": "{{user}} now runs on {{account}}",
"unpinned": "{{user}} is back on the least-used account"
"unpinned": "{{user}} is back on the least-used account",
"switched": "{{user}} switched to {{account}} — running sessions follow at their next login check",
"own-login": "{{user}} signed in with their own login, which was left alone",
"expired": "{{account}} has expired — {{user}}'s new sessions fall back to the least-used account"
},
"toolName": {
"claude": "Claude",