feat(settings): every AI tool's login profiles in one Settings section, linked to the account pool
Settings → AI tools → Profiles holds one tab per tool: Claude Code (the cc-profiles panel, moved out of the Claude Code page's modal — its button now links here), Codex (the whole $CODEX_HOME/auth.json) and Oh My Pi (`omp auth export` / `omp auth import -`, secrets on stdin; omp's credential tables are emptied first because import merges, and a failed import puts the outgoing set back). Antigravity is listed as not switchable: agy keeps its login in the OS keyring. server/lib/tool-profiles.js + /api/tool-profiles keep cc-profiles' rules (one login = one profile, the outgoing login is re-saved before a switch, an unsaved one refuses it, the live login's profile is not deletable) and never return a token; /tool-profiles joins ADMIN_WRITE_PREFIXES and STAFF_ONLY_PREFIXES, writes are same-origin only. The account pool takes a saved Codex profile too (moved in like a Claude one, GET /api/accounts/profiles?tool=codex). Each Claude/Codex profile has a "Move to pool" link (/admin?poolAdd=&poolProfile= opens the pool's Add dialog on it), Settings shows the pool's size, and the pool card links back.
This commit is contained in:
@@ -72,7 +72,7 @@
|
||||
"quotaWrongAccount": "This sign-in belongs to another Claude account: log in as this account and save it again",
|
||||
"quotaActive": "in use",
|
||||
"quotaTokenExpired": "Sign-in expired: use the tool once so it signs in again",
|
||||
"quotaProfileExpired": "Sign-in expired: use Check quota in Claude Code → Profiles to refresh it",
|
||||
"quotaProfileExpired": "Sign-in expired: use Check quota in Settings → AI tools → Profiles to refresh it",
|
||||
"quotaSignInExpires": "Sign-in expires in {{time}}",
|
||||
"quotaSignInExpired": "Sign-in expired",
|
||||
"quotaWindow": {
|
||||
|
||||
@@ -1385,5 +1385,32 @@
|
||||
"signOutOthersBody": "Every browser signed in to your account except this one is signed out.",
|
||||
"signedOut_one": "Signed out {{count}} other device",
|
||||
"signedOut_other": "Signed out {{count}} other devices"
|
||||
},
|
||||
"toolProfiles": {
|
||||
"title": "Profiles",
|
||||
"description": "Every AI tool's saved logins in one place. Switching swaps only the login; config, skills, sessions and history stay as they are.",
|
||||
"poolCount_one": "The account pool holds {{count}} account for this tool.",
|
||||
"poolCount_other": "The account pool holds {{count}} accounts for this tool.",
|
||||
"openPool": "Open the account pool",
|
||||
"moveToPool": "Move to pool",
|
||||
"moveToPoolHint": "Administration → Users → Account pool, with this profile chosen. The pool becomes the login's only holder and the profile is removed.",
|
||||
"saveButton": "Save this login as a profile",
|
||||
"noActive": "{{tool}} holds no login on this machine.",
|
||||
"noProfiles": "Could not load the profiles.",
|
||||
"switchSuccess": "Switched {{tool}} to \"{{name}}\". Start a new session to use it.",
|
||||
"deleteConfirmBody": "This removes the saved {{tool}} login. To use it again, sign in from a terminal and save it once more.",
|
||||
"loginHint": "Add another {{tool}} login by signing in from a terminal first:",
|
||||
"subtitle": {
|
||||
"codex": "A profile is one Codex login (a ChatGPT account or an API key): the whole auth.json. config.toml, sessions, skills and history stay where they are.",
|
||||
"omp": "A profile is the full set of logins Oh My Pi stores (every provider), read with `omp auth export` and put back with `omp auth import`. Settings, models and sessions stay where they are. Running omp sessions pick up the switch on their own."
|
||||
},
|
||||
"unsupported": {
|
||||
"antigravity": "Antigravity keeps its login in the system keyring, which AgentHub does not read or write, so it cannot be switched from here. Sign in or out inside agy itself."
|
||||
},
|
||||
"kind": {
|
||||
"chatgpt": "ChatGPT login",
|
||||
"apikey": "API key",
|
||||
"credentials": "Logins"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,19 +177,20 @@
|
||||
},
|
||||
"source": "From",
|
||||
"sources": {
|
||||
"profile": "A saved login (Switch account profiles)",
|
||||
"profile": "A saved profile (Settings → AI tools → Profiles)",
|
||||
"credentials": "Paste .credentials.json / Keychain",
|
||||
"token": "claude setup-token"
|
||||
},
|
||||
"sourceHint": {
|
||||
"profile": "The login is moved into the pool: the profile leaves the switcher, and the server writes it into each user's home when their session starts.",
|
||||
"credentials": "From ~/.claude/.credentials.json, or on a Mac `security find-generic-password -s \"Claude Code-credentials\" -w`. Do not keep using that login where you copied it from — two copies log each other out.",
|
||||
"token": "A one-year token from `claude setup-token`, given to every session as an environment variable."
|
||||
"token": "A one-year token from `claude setup-token`, given to every session as an environment variable.",
|
||||
"codex": "An OpenAI API key (sk-…), or the whole ~/.codex/auth.json after `codex login` with a ChatGPT account."
|
||||
},
|
||||
"profile": "Profile",
|
||||
"profileHint": "Saved in Settings → Claude config → Switch account. The one this server's own Claude Code is logged into can be moved too: the server keeps running on it and refreshes it for everyone.",
|
||||
"profileHint": "Saved in Settings → AI tools → Profiles. The one this server's own CLI is logged into can be moved too: the server keeps running on it.",
|
||||
"chooseProfile": "Choose a saved login…",
|
||||
"noProfiles": "No saved logins — save one in Settings → Claude config → Switch account",
|
||||
"noProfiles": "No saved profiles — save one in Settings → AI tools → Profiles",
|
||||
"loadingProfiles": "Loading…",
|
||||
"activeHere": "in use on this server — keeps working",
|
||||
"nameFromProfile": "Leave blank to use the profile's name",
|
||||
@@ -216,7 +217,8 @@
|
||||
"users": "Users on this account",
|
||||
"noUsers": "No users yet.",
|
||||
"onAccount": "now on {{account}}",
|
||||
"editDone": "{{name}} saved"
|
||||
"editDone": "{{name}} saved",
|
||||
"profilesLink": "Profiles in Settings"
|
||||
},
|
||||
"delete": {
|
||||
"button": "Delete user",
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
"quotaWrongAccount": "Lượt đăng nhập này thuộc tài khoản Claude khác: đăng nhập lại đúng tài khoản này rồi lưu lại",
|
||||
"quotaActive": "đang dùng",
|
||||
"quotaTokenExpired": "Đăng nhập đã hết hạn: dùng công cụ một lần để nó đăng nhập lại",
|
||||
"quotaProfileExpired": "Đăng nhập đã hết hạn: bấm Kiểm tra quota trong Claude Code → Profiles để làm mới",
|
||||
"quotaProfileExpired": "Đăng nhập đã hết hạn: bấm Kiểm tra quota trong Cài đặt → AI tools → Hồ sơ đăng nhập để làm mới",
|
||||
"quotaSignInExpires": "Đăng nhập hết hạn sau {{time}}",
|
||||
"quotaSignInExpired": "Đăng nhập đã hết hạn",
|
||||
"quotaWindow": {
|
||||
|
||||
@@ -1385,5 +1385,32 @@
|
||||
"signOutOthersBody": "Mọi trình duyệt đang đăng nhập tài khoản của bạn, trừ trình duyệt này, sẽ bị đăng xuất.",
|
||||
"signedOut_one": "Đã đăng xuất {{count}} thiết bị khác",
|
||||
"signedOut_other": "Đã đăng xuất {{count}} thiết bị khác"
|
||||
},
|
||||
"toolProfiles": {
|
||||
"title": "Hồ sơ đăng nhập",
|
||||
"description": "Mọi đăng nhập đã lưu của các AI tool ở một nơi. Khi đổi chỉ phần đăng nhập được hoán đổi; config, skills, phiên làm việc và lịch sử vẫn giữ nguyên.",
|
||||
"poolCount_one": "Account pool đang có {{count}} tài khoản cho tool này.",
|
||||
"poolCount_other": "Account pool đang có {{count}} tài khoản cho tool này.",
|
||||
"openPool": "Mở account pool",
|
||||
"moveToPool": "Đưa vào pool",
|
||||
"moveToPoolHint": "Quản trị → Người dùng → Account pool, chọn sẵn hồ sơ này. Pool sẽ là nơi duy nhất giữ đăng nhập này và hồ sơ được xoá.",
|
||||
"saveButton": "Lưu đăng nhập này thành hồ sơ",
|
||||
"noActive": "{{tool}} chưa có đăng nhập nào trên máy này.",
|
||||
"noProfiles": "Không tải được danh sách hồ sơ.",
|
||||
"switchSuccess": "Đã chuyển {{tool}} sang \"{{name}}\". Mở phiên mới để dùng.",
|
||||
"deleteConfirmBody": "Thao tác này xoá đăng nhập {{tool}} đã lưu. Muốn dùng lại, hãy đăng nhập từ terminal và lưu lại lần nữa.",
|
||||
"loginHint": "Thêm đăng nhập {{tool}} khác bằng cách đăng nhập từ terminal trước:",
|
||||
"subtitle": {
|
||||
"codex": "Mỗi hồ sơ là một đăng nhập Codex (tài khoản ChatGPT hoặc API key): toàn bộ auth.json. config.toml, phiên, skills và lịch sử vẫn giữ nguyên.",
|
||||
"omp": "Mỗi hồ sơ là toàn bộ các đăng nhập Oh My Pi đang lưu (mọi provider), đọc bằng `omp auth export` và ghi lại bằng `omp auth import`. Settings, model và phiên vẫn giữ nguyên. Các phiên omp đang chạy tự nhận đăng nhập mới."
|
||||
},
|
||||
"unsupported": {
|
||||
"antigravity": "Antigravity lưu đăng nhập trong keyring của hệ điều hành, AgentHub không đọc hay ghi vào đó nên không đổi được từ đây. Hãy đăng nhập/đăng xuất ngay trong agy."
|
||||
},
|
||||
"kind": {
|
||||
"chatgpt": "Đăng nhập ChatGPT",
|
||||
"apikey": "API key",
|
||||
"credentials": "Đăng nhập"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,19 +177,20 @@
|
||||
},
|
||||
"source": "Nguồn",
|
||||
"sources": {
|
||||
"profile": "Login đã lưu (profile Switch account)",
|
||||
"profile": "Hồ sơ đã lưu (Cài đặt → AI tools → Hồ sơ đăng nhập)",
|
||||
"credentials": "Dán .credentials.json / Keychain",
|
||||
"token": "claude setup-token"
|
||||
},
|
||||
"sourceHint": {
|
||||
"profile": "Login được chuyển vào pool: profile rời khỏi trình đổi tài khoản, và server ghi nó vào home của từng user khi phiên của họ bắt đầu.",
|
||||
"credentials": "Lấy từ ~/.claude/.credentials.json, hoặc trên Mac: `security find-generic-password -s \"Claude Code-credentials\" -w`. Đừng dùng tiếp login đó ở nơi đã copy — hai bản sẽ làm nhau bị đăng xuất.",
|
||||
"token": "Token 1 năm từ `claude setup-token`, đưa vào mọi phiên qua biến môi trường."
|
||||
"token": "Token 1 năm từ `claude setup-token`, đưa vào mọi phiên qua biến môi trường.",
|
||||
"codex": "OpenAI API key (sk-…), hoặc toàn bộ ~/.codex/auth.json sau khi `codex login` bằng tài khoản ChatGPT."
|
||||
},
|
||||
"profile": "Profile",
|
||||
"profileHint": "Lưu ở Settings → Claude config → Switch account. Profile mà Claude Code của server đang dùng cũng chuyển được: server vẫn chạy trên nó và tự làm mới cho mọi người.",
|
||||
"profileHint": "Lưu ở Cài đặt → AI tools → Hồ sơ đăng nhập. Hồ sơ mà CLI của server đang dùng cũng chuyển được: server vẫn chạy trên nó.",
|
||||
"chooseProfile": "Chọn login đã lưu…",
|
||||
"noProfiles": "Chưa có login nào — lưu ở Settings → Claude config → Switch account",
|
||||
"noProfiles": "Chưa có hồ sơ nào — lưu ở Cài đặt → AI tools → Hồ sơ đăng nhập",
|
||||
"loadingProfiles": "Đang tải…",
|
||||
"activeHere": "server đang dùng — vẫn chạy tiếp",
|
||||
"nameFromProfile": "Để trống để dùng tên profile",
|
||||
@@ -216,7 +217,8 @@
|
||||
"users": "User dùng tài khoản này",
|
||||
"noUsers": "Chưa có user nào.",
|
||||
"onAccount": "đang ở {{account}}",
|
||||
"editDone": "Đã lưu {{name}}"
|
||||
"editDone": "Đã lưu {{name}}",
|
||||
"profilesLink": "Hồ sơ trong Cài đặt"
|
||||
},
|
||||
"delete": {
|
||||
"button": "Xoá user",
|
||||
|
||||
Reference in New Issue
Block a user