Files
AgentHub/client/src/i18n/locales/en/users.json
T
nntrivi2001 c83ddf62a0 feat(server-s3): a member's tmux follows tmux upgrades — tmux-member + Users → Members' tmux
A member's tmux server keeps the version it started with until their last
pane closes, but the dashboard asked it with TMUX_BIN, the newest tmux: a
3.8 client on a 3.6 server spun it at 100% CPU (three members needed a
manual kill on 2026-10-15).

- /opt/agenthub/libexec/tmux-member (install-system, in sudoers): runs a
  member's tmux call with the binary of THEIR running server
  (/proc/<pid>/exe, found from the socket in /proc/net/unix), else
  TMUX_BIN. It runs as the member and execs only a process they own.
  sudoArgv uses it once installed (linux-accounts readConf), TMUX_BIN
  until then.
- Users → Members' tmux (GET /api/users/tmux): each member server's version
  beside the installed one, sessions, agents working. An admin restarts one
  (POST /api/users/:id/tmux-restart) or every idle outdated one
  (POST /api/users/tmux-restart-idle), with their password again, audited
  per member; a server that will not stop answers 409 ETMUXSTUCK naming
  its pid for root.
- server-s3-system.test.js: `delete` is a provision action since Delete
  user, so the "unknown action" case now uses `purge`.

Operators: run `sudo agenthub server install-system` once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 14:44:47 +07:00

239 lines
11 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"title": "Users",
"description": "Every account on this server, with its workspaces, sessions and recent usage.",
"name": "User",
"role": "Role",
"workspaces": "Workspaces",
"sessions": "Sessions",
"last7d": "7 days",
"last30d": "30 days",
"storage": "Storage",
"storageHint": "{{files}} files · measured {{at}}",
"storagePartial": "at least — part of the folder could not be read in time",
"storageNone": "No home folder of their own",
"storageMeasuring": "Measuring…",
"disabled": "disabled",
"you": "you",
"tokens": "{{n}} tokens",
"actions": "Actions",
"roles": {
"admin": "Admin",
"analyst": "Analyst",
"developer": "Developer"
},
"roleHint": {
"admin": "Everything, including this server's configuration and every user's data",
"analyst": "Sees every user's data; works only in their own workspaces, changes no settings",
"developer": "Only their own workspaces; changes no settings"
},
"add": "Add user",
"username": "Username",
"usernameHint": "Letters, digits, '.', '_' or '-'",
"password": "Password",
"passwordHint": "No minimum length",
"newPassword": "New password",
"changeRole": "Change role",
"disable": "Disable",
"enable": "Enable",
"resetPassword": "Reset password",
"assignWorkspace": "Give a workspace",
"workspace": "Workspace",
"noOwner": "no owner",
"ownedBy": "owned by {{name}}",
"noWorkspaces": "There are no workspaces yet.",
"yourPassword": "Your password",
"yourPasswordHint": "Type your own password to confirm this change.",
"save": "Save",
"dialog": {
"add": "Add a user",
"role": "Change {{name}}'s role",
"disable": "Disable {{name}}?",
"disableBody": "{{name}} is signed out everywhere and cannot sign in until enabled again. Their workspaces and history stay.",
"enable": "Enable {{name}}?",
"password": "Reset {{name}}'s password",
"passwordBody": "{{name}} is signed out everywhere and signs in with the new password.",
"workspace": "Give {{name}} a workspace",
"workspaceBody": "The workspace's sessions and costs move to {{name}}. A developer sees only their own workspaces."
},
"done": {
"created": "{{name}} added",
"role": "{{name}} is now {{role}}",
"disabled": "{{name}} disabled",
"enabled": "{{name}} enabled",
"password": "{{name}}'s password reset",
"workspace": "Workspace given to {{name}}",
"updated": "{{name}} updated",
"deleted": "{{name}} was deleted."
},
"errors": {
"EBADIMAGE": "Only a PNG, JPEG, GIF or WebP picture",
"ETOOBIG": "The picture must be at most 1 MB",
"EREAUTH": "Your password is wrong.",
"ETOOMANY": "Too many wrong passwords. Try again in 15 minutes.",
"ESELF": "You cannot change your own role or disable yourself.",
"EEXISTS": "That username is taken.",
"EBADUSER": "Username: letters, digits, '.', '_' or '-' (up to 64).",
"EBADPASSWORD": "Password cannot be empty.",
"EBADEMAIL": "That email address does not look valid.",
"EBADFIELD": "One of the values is not valid.",
"ENOLANE": "That workspace no longer exists.",
"ENOTOWNED": "That workspace is not this user's any more.",
"EOWNERFOLDER": "That workspace's folder belongs to another user's account.",
"EBADROLE": "Unknown role.",
"ELOCALMODE": "Accounts are managed in server mode only.",
"ELASTADMIN": "The last admin cannot be deleted."
},
"readOnly": "Analysts can view accounts but not change them.",
"auditTitle": "Audit log",
"auditDescription": "Account changes made here, and each time an admin or analyst opened a session a developer owns.",
"auditEmpty": "Nothing recorded yet.",
"activeCount": "{{n}} active",
"cost30d": "Cost · 30 days",
"displayName": "Display name",
"displayNameHint": "Shown beside the username. Optional.",
"email": "Email",
"edit": {
"button": "Edit user",
"title": "Edit {{name}}",
"created": "Created",
"lastLogin": "Last sign-in",
"never": "Never",
"logins": "Active sign-ins",
"profile": "Profile",
"access": "Access",
"status": "Status",
"active": "Active",
"statusHint": "A disabled user cannot sign in; their workspaces and history stay.",
"selfRole": "You cannot change your own role.",
"selfDisable": "You cannot disable yourself.",
"password": "Password",
"passwordHint": "Leave blank to keep the current one. A new one signs them out everywhere.",
"show": "Show password",
"hide": "Hide password",
"copy": "Copy password",
"generate": "Generate",
"loading": "Loading…",
"noOwned": "Owns no workspace.",
"undo": "Undo",
"removeWorkspace": "Remove {{name}}",
"removeWorkspaceHint": "The workspace is left with no owner",
"addWorkspace": "Add workspace",
"chooseWorkspace": "Choose a workspace…",
"sessions": "Sign-ins",
"signOut": "Sign out everywhere",
"signOutHint": "Ends this user's {{n}} active sign-in(s); they sign in again with their password.",
"noChanges": "No changes yet."
},
"pool": {
"title": "Account pool",
"description": "Claude and Codex accounts every user's new sessions run on — the least-used one is picked, and a login is written into the user's home by the server, so nobody signs in per user.",
"refresh": "Re-read quotas",
"add": "Add account",
"empty": "No accounts yet. Until you add one, each user's session needs that user's own sign-in.",
"account": "Account",
"tool": "Tool",
"livePanes": "Live",
"quota": "Quota",
"spend": "5 hours",
"spend7d": "{{cost}} · {{tokens}} tokens in 7 days",
"tokens": "{{tokens}} tokens",
"added": "added {{at}}",
"expired": "expired",
"full": "full",
"kind": {
"token": "Claude · setup-token",
"login": "Claude · login",
"apikey": "Codex · API key",
"chatgpt": "Codex · ChatGPT"
},
"name": "Name",
"nameHint": "Any label you will recognise: letters, digits, '.', '_' or '-'",
"remove": "Remove {{name}}",
"removeHint": "New sessions stop using this account. Sessions already running on it keep running.",
"removeButton": "Remove",
"done": {
"added": "{{name}} added to the pool",
"removed": "{{name}} removed from the pool"
},
"errors": {
"EREAUTH": "Your password is wrong.",
"ETOOMANY": "Too many wrong passwords. Try again in 15 minutes.",
"EBADNAME": "Name: 1–64 letters, digits, '.', '_' or '-'.",
"EBADTOKEN": "That is not a valid token for this tool.",
"EEXISTS": "An account with that name is already in the pool.",
"ENOACCOUNT": "That account is no longer in the pool.",
"ELOCALMODE": "In local mode the pool is changed from the host's shell (agenthub accounts).",
"EACTIVE": "This server's Claude Code keeps that login in the macOS Keychain. Switch it to another profile first.",
"ENOTFOUND": "That saved login no longer exists.",
"ESTALE": "That login was already refreshed elsewhere. Log in again and save it anew.",
"EUPSTREAM": "Anthropic could not be reached. Try again."
},
"source": "From",
"sources": {
"profile": "A saved login (Switch account 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."
},
"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.",
"chooseProfile": "Choose a saved login…",
"noProfiles": "No saved logins — save one in Settings → Claude config → Switch account",
"loadingProfiles": "Loading…",
"activeHere": "in use on this server — keeps working",
"nameFromProfile": "Leave blank to use the profile's name",
"secret": {
"credentials": "Credentials JSON",
"token": "Token",
"codex": "API key or auth.json"
},
"secretHint": {
"credentials": "The whole file: {\"claudeAiOauth\": {…}}",
"token": "The sk-ant-… that `claude setup-token` printed.",
"codex": "An OpenAI API key (sk-…), or the whole ~/.codex/auth.json after `codex login` with a ChatGPT account."
},
"refreshFailed": "refresh failed"
},
"delete": {
"button": "Delete user",
"title": "Delete {{name}}?",
"body": "This deletes {{name}} for good: their login, {{count}} workspace(s), and their Linux account with the whole home folder (/srv/agenthub/users/{{user}}) — every file and all source code in it. It cannot be undone. Session history and the audit log stay.",
"confirm": "Delete for good",
"needsPassword": "Enter your own password below first."
},
"tmux": {
"title": "Members' tmux",
"description": "Each member's own tmux server keeps the version it started with until its last pane closes. Installed: tmux {{version}}.",
"refresh": "Refresh",
"notMatched": "Run `sudo agenthub server install-system` once: until then an older member server is asked with the installed tmux, which can leave it stuck at 100% CPU.",
"empty": "No member has a tmux server running.",
"user": "User",
"version": "tmux",
"sessions": "Sessions",
"agents": "Agents",
"stuck": "not answering",
"outdated": "older than installed",
"since": "since {{at}}",
"working_one": "{{count}} working",
"working_other": "{{count}} working",
"idle": "idle",
"restart": "Restart {{name}}'s tmux",
"restartIdle_one": "Restart {{count}} idle member",
"restartIdle_other": "Restart {{count}} idle members",
"restartIdleTitle": "Restart idle members' tmux",
"restartHint": "Every pane of {{name}} closes ({{count}} sessions). Their Claude sessions resume from the workspace, and the next start runs the installed tmux.",
"restartHintBusy": "An agent of {{name}} is working right now and will be stopped. Every pane of theirs closes ({{count}} sessions); their Claude sessions resume from the workspace.",
"restartIdleHint": "Restarts the tmux of every member on an older version with no agent working: {{names}}. Their panes close; their Claude sessions resume from the workspace.",
"restartButton": "Restart",
"done": "{{name}}'s tmux restarted",
"doneIdle": "Restarted: {{names}}",
"errors": {
"ETMUXSTUCK": "The server did not stop. Run the `sudo kill -9` command shown, as root, on the server."
}
}
}